1 /* 2 * Copyright (C) 2009-2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "rsContext.h" 18 #include "rsScriptC.h" 19 #include "rsMatrix4x4.h" 20 #include "rsMatrix3x3.h" 21 #include "rsMatrix2x2.h" 22 #include "rsgApiStructs.h" 23 24 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 25 #include "utils/Timers.h" 26 #endif 27 28 #include <time.h> 29 30 using namespace android; 31 using namespace android::renderscript; 32 33 34 namespace android { 35 namespace renderscript { 36 37 38 ////////////////////////////////////////////////////////////////////////////// 39 // Math routines 40 ////////////////////////////////////////////////////////////////////////////// 41 42 #if 0 43 static float SC_sinf_fast(float x) { 44 const float A = 1.0f / (2.0f * M_PI); 45 const float B = -16.0f; 46 const float C = 8.0f; 47 48 // scale angle for easy argument reduction 49 x *= A; 50 51 if (fabsf(x) >= 0.5f) { 52 // argument reduction 53 x = x - ceilf(x + 0.5f) + 1.0f; 54 } 55 56 const float y = B * x * fabsf(x) + C * x; 57 return 0.2215f * (y * fabsf(y) - y) + y; 58 } 59 60 static float SC_cosf_fast(float x) { 61 x += float(M_PI / 2); 62 63 const float A = 1.0f / (2.0f * M_PI); 64 const float B = -16.0f; 65 const float C = 8.0f; 66 67 // scale angle for easy argument reduction 68 x *= A; 69 70 if (fabsf(x) >= 0.5f) { 71 // argument reduction 72 x = x - ceilf(x + 0.5f) + 1.0f; 73 } 74 75 const float y = B * x * fabsf(x) + C * x; 76 return 0.2215f * (y * fabsf(y) - y) + y; 77 } 78 #endif 79 80 ////////////////////////////////////////////////////////////////////////////// 81 // Time routines 82 ////////////////////////////////////////////////////////////////////////////// 83 84 time_t rsrTime(Context *rsc, time_t *timer) { 85 return time(timer); 86 } 87 88 tm* rsrLocalTime(Context *rsc, tm *local, time_t *timer) { 89 if (!local) { 90 return nullptr; 91 } 92 93 // The native localtime function is not thread-safe, so we 94 // have to apply locking for proper behavior in RenderScript. 95 pthread_mutex_lock(&rsc->gLibMutex); 96 tm *tmp = localtime(timer); 97 memcpy(local, tmp, sizeof(int)*9); 98 pthread_mutex_unlock(&rsc->gLibMutex); 99 return local; 100 } 101 102 int64_t rsrUptimeMillis(Context *rsc) { 103 #ifndef RS_SERVER 104 return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 105 #else 106 return 0; 107 #endif 108 } 109 110 int64_t rsrUptimeNanos(Context *rsc) { 111 #ifndef RS_SERVER 112 return systemTime(SYSTEM_TIME_MONOTONIC); 113 #else 114 return 0; 115 #endif 116 } 117 118 float rsrGetDt(Context *rsc, const Script *sc) { 119 #ifndef RS_SERVER 120 int64_t l = sc->mEnviroment.mLastDtTime; 121 sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC); 122 return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9; 123 #else 124 return 0.f; 125 #endif 126 } 127 128 ////////////////////////////////////////////////////////////////////////////// 129 // 130 ////////////////////////////////////////////////////////////////////////////// 131 132 static void SetObjectRef(const Context *rsc, const ObjectBase *dst, const ObjectBase *src) { 133 //ALOGE("setObjectRef %p,%p %p", rsc, dst, src); 134 if (src) { 135 CHECK_OBJ(src); 136 src->incSysRef(); 137 } 138 if (dst) { 139 CHECK_OBJ(dst); 140 dst->decSysRef(); 141 } 142 } 143 144 // Legacy, remove when drivers are updated 145 void rsrClearObject(const Context *rsc, void *dst) { 146 ObjectBase **odst = (ObjectBase **)dst; 147 if (ObjectBase::gDebugReferences) { 148 ALOGE("rsrClearObject %p,%p", odst, *odst); 149 } 150 if (odst[0]) { 151 CHECK_OBJ(odst[0]); 152 odst[0]->decSysRef(); 153 } 154 *odst = nullptr; 155 } 156 157 void rsrClearObject(rs_object_base *dst) { 158 if (ObjectBase::gDebugReferences) { 159 ALOGE("rsrClearObject %p,%p", dst, dst->p); 160 } 161 if (dst->p) { 162 CHECK_OBJ(dst->p); 163 dst->p->decSysRef(); 164 } 165 dst->p = nullptr; 166 } 167 168 // Legacy, remove when drivers are updated 169 void rsrClearObject(const Context *rsc, rs_object_base *dst) { 170 rsrClearObject(dst); 171 } 172 173 // Legacy, remove when drivers are updated 174 void rsrSetObject(const Context *rsc, void *dst, ObjectBase *src) { 175 if (src == nullptr) { 176 rsrClearObject(rsc, dst); 177 return; 178 } 179 180 ObjectBase **odst = (ObjectBase **)dst; 181 if (ObjectBase::gDebugReferences) { 182 ALOGE("rsrSetObject (base) %p,%p %p", dst, *odst, src); 183 } 184 SetObjectRef(rsc, odst[0], src); 185 src->callUpdateCacheObject(rsc, dst); 186 } 187 188 void rsrSetObject(const Context *rsc, rs_object_base *dst, const ObjectBase *src) { 189 if (src == nullptr) { 190 rsrClearObject(rsc, dst); 191 return; 192 } 193 194 ObjectBase **odst = (ObjectBase **)dst; 195 if (ObjectBase::gDebugReferences) { 196 ALOGE("rsrSetObject (base) %p,%p %p", dst, *odst, src); 197 } 198 SetObjectRef(rsc, odst[0], src); 199 src->callUpdateCacheObject(rsc, dst); 200 } 201 202 // Legacy, remove when drivers are updated 203 bool rsrIsObject(const Context *, ObjectBase* src) { 204 ObjectBase **osrc = (ObjectBase **)src; 205 return osrc != nullptr; 206 } 207 208 bool rsrIsObject(const Context *rsc, rs_object_base o) { 209 return o.p != nullptr; 210 } 211 212 213 214 uint32_t rsrToClient(Context *rsc, int cmdID, const void *data, int len) { 215 //ALOGE("SC_toClient %i %i %i", cmdID, len); 216 return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, false); 217 } 218 219 uint32_t rsrToClientBlocking(Context *rsc, int cmdID, const void *data, int len) { 220 //ALOGE("SC_toClientBlocking %i %i", cmdID, len); 221 return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, true); 222 } 223 224 // Keep these two routines (using non-const void pointers) so that we can 225 // still use existing GPU drivers. 226 uint32_t rsrToClient(Context *rsc, int cmdID, void *data, int len) { 227 return rsrToClient(rsc, cmdID, (const void *)data, len); 228 } 229 230 uint32_t rsrToClientBlocking(Context *rsc, int cmdID, void *data, int len) { 231 return rsrToClientBlocking(rsc, cmdID, (const void *)data, len); 232 } 233 234 void rsrAllocationIoSend(Context *rsc, Allocation *src) { 235 src->ioSend(rsc); 236 } 237 238 void rsrAllocationIoReceive(Context *rsc, Allocation *src) { 239 src->ioReceive(rsc); 240 } 241 242 void rsrForEach(Context *rsc, 243 Script *target, 244 uint32_t slot, 245 uint32_t numInputs, 246 Allocation **in, Allocation *out, 247 const void *usr, uint32_t usrBytes, 248 const RsScriptCall *call) { 249 target->runForEach(rsc, slot, (const Allocation**)in, numInputs, out, usr, usrBytes, call); 250 } 251 252 void rsrAllocationSyncAll(Context *rsc, Allocation *a, RsAllocationUsageType usage) { 253 a->syncAll(rsc, usage); 254 } 255 256 void rsrAllocationCopy1DRange(Context *rsc, Allocation *dstAlloc, 257 uint32_t dstOff, 258 uint32_t dstMip, 259 uint32_t count, 260 Allocation *srcAlloc, 261 uint32_t srcOff, uint32_t srcMip) { 262 rsi_AllocationCopy2DRange(rsc, dstAlloc, dstOff, 0, 263 dstMip, 0, count, 1, 264 srcAlloc, srcOff, 0, srcMip, 0); 265 } 266 267 void rsrAllocationCopy2DRange(Context *rsc, Allocation *dstAlloc, 268 uint32_t dstXoff, uint32_t dstYoff, 269 uint32_t dstMip, uint32_t dstFace, 270 uint32_t width, uint32_t height, 271 Allocation *srcAlloc, 272 uint32_t srcXoff, uint32_t srcYoff, 273 uint32_t srcMip, uint32_t srcFace) { 274 rsi_AllocationCopy2DRange(rsc, dstAlloc, dstXoff, dstYoff, 275 dstMip, dstFace, width, height, 276 srcAlloc, srcXoff, srcYoff, srcMip, srcFace); 277 } 278 279 RsElement rsrElementCreate(Context *rsc, RsDataType dt, RsDataKind dk, 280 bool norm, uint32_t vecSize) { 281 return rsi_ElementCreate(rsc, dt, dk, norm, vecSize); 282 } 283 284 RsType rsrTypeCreate(Context *rsc, const RsElement element, uint32_t dimX, 285 uint32_t dimY, uint32_t dimZ, bool mipmaps, bool faces, 286 uint32_t yuv) { 287 return rsi_TypeCreate(rsc, element, dimX, dimY, dimZ, mipmaps, faces, yuv); 288 } 289 290 RsAllocation rsrAllocationCreateTyped(Context *rsc, const RsType type, 291 RsAllocationMipmapControl mipmaps, 292 uint32_t usages, uintptr_t ptr) { 293 return rsi_AllocationCreateTyped(rsc, type, mipmaps, usages, ptr); 294 } 295 296 } 297 } 298