rsScriptC_Lib.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. #include "rsContext.h"
  17. #include "rsScriptC.h"
  18. #include "rsMatrix4x4.h"
  19. #include "rsMatrix3x3.h"
  20. #include "rsMatrix2x2.h"
  21. #include "rsgApiStructs.h"
  22. #include <time.h>
  23. #include <sstream>
  24. namespace android {
  25. namespace renderscript {
  26. //////////////////////////////////////////////////////////////////////////////
  27. // Math routines
  28. //////////////////////////////////////////////////////////////////////////////
  29. #if 0
  30. static float SC_sinf_fast(float x) {
  31. const float A = 1.0f / (2.0f * M_PI);
  32. const float B = -16.0f;
  33. const float C = 8.0f;
  34. // scale angle for easy argument reduction
  35. x *= A;
  36. if (fabsf(x) >= 0.5f) {
  37. // argument reduction
  38. x = x - ceilf(x + 0.5f) + 1.0f;
  39. }
  40. const float y = B * x * fabsf(x) + C * x;
  41. return 0.2215f * (y * fabsf(y) - y) + y;
  42. }
  43. static float SC_cosf_fast(float x) {
  44. x += float(M_PI / 2);
  45. const float A = 1.0f / (2.0f * M_PI);
  46. const float B = -16.0f;
  47. const float C = 8.0f;
  48. // scale angle for easy argument reduction
  49. x *= A;
  50. if (fabsf(x) >= 0.5f) {
  51. // argument reduction
  52. x = x - ceilf(x + 0.5f) + 1.0f;
  53. }
  54. const float y = B * x * fabsf(x) + C * x;
  55. return 0.2215f * (y * fabsf(y) - y) + y;
  56. }
  57. #endif
  58. //////////////////////////////////////////////////////////////////////////////
  59. // Time routines
  60. //////////////////////////////////////////////////////////////////////////////
  61. time_t rsrTime(Context *rsc, time_t *timer) {
  62. return time(timer);
  63. }
  64. tm* rsrLocalTime(Context *rsc, tm *local, time_t *timer) {
  65. if (!local) {
  66. return nullptr;
  67. }
  68. // The native localtime function is not thread-safe, so we
  69. // have to apply locking for proper behavior in RenderScript.
  70. pthread_mutex_lock(&rsc->gLibMutex);
  71. tm *tmp = localtime(timer);
  72. memcpy(local, tmp, sizeof(int)*9);
  73. pthread_mutex_unlock(&rsc->gLibMutex);
  74. return local;
  75. }
  76. int64_t rsrUptimeMillis(Context *rsc) {
  77. return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
  78. }
  79. int64_t rsrUptimeNanos(Context *rsc) {
  80. return systemTime(SYSTEM_TIME_MONOTONIC);
  81. }
  82. float rsrGetDt(Context *rsc, const Script *sc) {
  83. int64_t l = sc->mEnviroment.mLastDtTime;
  84. sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC);
  85. return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9;
  86. }
  87. //////////////////////////////////////////////////////////////////////////////
  88. //
  89. //////////////////////////////////////////////////////////////////////////////
  90. static void SetObjectRef(const Context *rsc, const ObjectBase *dst, const ObjectBase *src) {
  91. //ALOGE("setObjectRef %p,%p %p", rsc, dst, src);
  92. if (src) {
  93. CHECK_OBJ(src);
  94. src->incSysRef();
  95. }
  96. if (dst) {
  97. CHECK_OBJ(dst);
  98. dst->decSysRef();
  99. }
  100. }
  101. // Legacy, remove when drivers are updated
  102. void rsrClearObject(const Context *rsc, void *dst) {
  103. ObjectBase **odst = (ObjectBase **)dst;
  104. if (ObjectBase::gDebugReferences) {
  105. ALOGE("rsrClearObject %p,%p", odst, *odst);
  106. }
  107. if (odst[0]) {
  108. CHECK_OBJ(odst[0]);
  109. odst[0]->decSysRef();
  110. }
  111. *odst = nullptr;
  112. }
  113. void rsrClearObject(rs_object_base *dst) {
  114. if (ObjectBase::gDebugReferences) {
  115. ALOGE("rsrClearObject %p,%p", dst, dst->p);
  116. }
  117. if (dst->p) {
  118. CHECK_OBJ(dst->p);
  119. dst->p->decSysRef();
  120. }
  121. dst->p = nullptr;
  122. }
  123. // Legacy, remove when drivers are updated
  124. void rsrClearObject(const Context *rsc, rs_object_base *dst) {
  125. rsrClearObject(dst);
  126. }
  127. // Legacy, remove when drivers are updated
  128. void rsrSetObject(const Context *rsc, void *dst, ObjectBase *src) {
  129. if (src == nullptr) {
  130. rsrClearObject(rsc, dst);
  131. return;
  132. }
  133. ObjectBase **odst = (ObjectBase **)dst;
  134. if (ObjectBase::gDebugReferences) {
  135. ALOGE("rsrSetObject (base) %p,%p %p", dst, *odst, src);
  136. }
  137. SetObjectRef(rsc, odst[0], src);
  138. src->callUpdateCacheObject(rsc, dst);
  139. }
  140. void rsrSetObject(const Context *rsc, rs_object_base *dst, const ObjectBase *src) {
  141. if (src == nullptr) {
  142. rsrClearObject(rsc, dst);
  143. return;
  144. }
  145. ObjectBase **odst = (ObjectBase **)dst;
  146. if (ObjectBase::gDebugReferences) {
  147. ALOGE("rsrSetObject (base) %p,%p %p", dst, *odst, src);
  148. }
  149. SetObjectRef(rsc, odst[0], src);
  150. src->callUpdateCacheObject(rsc, dst);
  151. }
  152. // Legacy, remove when drivers are updated
  153. bool rsrIsObject(const Context *, ObjectBase* src) {
  154. ObjectBase **osrc = (ObjectBase **)src;
  155. return osrc != nullptr;
  156. }
  157. bool rsrIsObject(const Context *rsc, rs_object_base o) {
  158. return o.p != nullptr;
  159. }
  160. uint32_t rsrToClient(Context *rsc, int cmdID, const void *data, int len) {
  161. //ALOGE("SC_toClient %i %i %i", cmdID, len);
  162. return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, false);
  163. }
  164. uint32_t rsrToClientBlocking(Context *rsc, int cmdID, const void *data, int len) {
  165. //ALOGE("SC_toClientBlocking %i %i", cmdID, len);
  166. return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, true);
  167. }
  168. // Keep these two routines (using non-const void pointers) so that we can
  169. // still use existing GPU drivers.
  170. uint32_t rsrToClient(Context *rsc, int cmdID, void *data, int len) {
  171. return rsrToClient(rsc, cmdID, (const void *)data, len);
  172. }
  173. uint32_t rsrToClientBlocking(Context *rsc, int cmdID, void *data, int len) {
  174. return rsrToClientBlocking(rsc, cmdID, (const void *)data, len);
  175. }
  176. void rsrAllocationIoSend(Context *rsc, Allocation *src) {
  177. src->ioSend(rsc);
  178. }
  179. void rsrAllocationIoReceive(Context *rsc, Allocation *src) {
  180. src->ioReceive(rsc);
  181. }
  182. void rsrForEach(Context *rsc,
  183. Script *target,
  184. uint32_t slot,
  185. uint32_t numInputs,
  186. Allocation **in, Allocation *out,
  187. const void *usr, uint32_t usrBytes,
  188. const RsScriptCall *call) {
  189. target->runForEach(rsc, slot, (const Allocation**)in, numInputs, out, usr, usrBytes, call);
  190. }
  191. void rsrAllocationSyncAll(Context *rsc, Allocation *a, RsAllocationUsageType usage) {
  192. a->syncAll(rsc, usage);
  193. }
  194. // Helper for validateCopyArgs() - initialize the error message; only called on
  195. // infrequently executed paths
  196. static void initializeErrorMsg(std::stringstream &ss, int expectDim, bool isSrc) {
  197. ss << (expectDim == 1 ? "rsAllocationCopy1DRange" : "rsAllocationCopy2DRange") << ": ";
  198. ss << (isSrc? "source" : "destination") << " ";
  199. }
  200. // We are doing the check even in a non-debug context, which is permissible because in that case
  201. // a failed bound check results in unspecified behavior.
  202. static bool validateCopyArgs(Context *rsc, bool isSrc, uint32_t expectDim,
  203. const Allocation *alloc, uint32_t xoff, uint32_t yoff,
  204. uint32_t lod, uint32_t w, uint32_t h) {
  205. std::stringstream ss;
  206. if (lod >= alloc->mHal.drvState.lodCount) {
  207. initializeErrorMsg(ss, expectDim, isSrc);
  208. ss << "Mip level out of range: ";
  209. ss << lod << " >= " << alloc->mHal.drvState.lodCount;
  210. rsc->setError(RS_ERROR_FATAL_DEBUG, ss.str().c_str());
  211. return false;
  212. }
  213. const uint32_t allocDimX = alloc->mHal.drvState.lod[lod].dimX;
  214. // Check both in case xoff + w overflows
  215. if (xoff >= allocDimX || (xoff + w) > allocDimX) {
  216. initializeErrorMsg(ss, expectDim, isSrc);
  217. ss << "X range: ";
  218. ss << "[" << xoff << ", " << xoff + w << ") outside ";
  219. ss << "[0, " << allocDimX << ")";
  220. rsc->setError(RS_ERROR_FATAL_DEBUG, ss.str().c_str());
  221. return false;
  222. }
  223. const uint32_t allocDimY = alloc->mHal.drvState.lod[lod].dimY;
  224. if (expectDim > 1) {
  225. if (allocDimY == 0) { // Copy2D was given an allocation of 1D
  226. initializeErrorMsg(ss, expectDim, isSrc);
  227. ss << "dimensionality invalid: expected 2D; given 1D rs_allocation";
  228. rsc->setError(RS_ERROR_FATAL_DEBUG, ss.str().c_str());
  229. return false;
  230. }
  231. // Check both in case yoff + h overflows
  232. if (yoff >= allocDimY || (yoff + h) > allocDimY) {
  233. initializeErrorMsg(ss, expectDim, isSrc);
  234. ss << "Y range: ";
  235. ss << "[" << yoff << ", " << yoff + h << ") outside ";
  236. ss << "[0, " << allocDimY << ")";
  237. rsc->setError(RS_ERROR_FATAL_DEBUG, ss.str().c_str());
  238. return false;
  239. }
  240. } else {
  241. if (allocDimY != 0) { // Copy1D was given an allocation of 2D
  242. initializeErrorMsg(ss, expectDim, isSrc);
  243. ss << "dimensionality invalid: expected 1D; given 2D rs_allocation";
  244. rsc->setError(RS_ERROR_FATAL_DEBUG, ss.str().c_str());
  245. return false;
  246. }
  247. }
  248. return true;
  249. }
  250. void rsrAllocationCopy1DRange(Context *rsc, Allocation *dstAlloc,
  251. uint32_t dstOff,
  252. uint32_t dstMip,
  253. uint32_t count,
  254. Allocation *srcAlloc,
  255. uint32_t srcOff, uint32_t srcMip) {
  256. if (!validateCopyArgs(rsc, false, 1, dstAlloc, dstOff, 0, dstMip, count, 1) ||
  257. !validateCopyArgs(rsc, true, 1, srcAlloc, srcOff, 0, srcMip, count, 1)) {
  258. return;
  259. }
  260. rsi_AllocationCopy2DRange(rsc, dstAlloc, dstOff, 0,
  261. dstMip, 0, count, 1,
  262. srcAlloc, srcOff, 0, srcMip, 0);
  263. }
  264. void rsrAllocationCopy2DRange(Context *rsc, Allocation *dstAlloc,
  265. uint32_t dstXoff, uint32_t dstYoff,
  266. uint32_t dstMip, uint32_t dstFace,
  267. uint32_t width, uint32_t height,
  268. Allocation *srcAlloc,
  269. uint32_t srcXoff, uint32_t srcYoff,
  270. uint32_t srcMip, uint32_t srcFace) {
  271. if (!validateCopyArgs(rsc, false, 2, dstAlloc, dstXoff, dstYoff, dstMip, width, height) ||
  272. !validateCopyArgs(rsc, true, 2, srcAlloc, srcXoff, srcYoff, srcMip, width, height)) {
  273. return;
  274. }
  275. rsi_AllocationCopy2DRange(rsc, dstAlloc, dstXoff, dstYoff,
  276. dstMip, dstFace, width, height,
  277. srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
  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. RsType rsrTypeCreate(Context *rsc, const RsElement element, uint32_t dimX,
  284. uint32_t dimY, uint32_t dimZ, bool mipmaps, bool faces,
  285. uint32_t yuv) {
  286. return rsi_TypeCreate(rsc, element, dimX, dimY, dimZ, mipmaps, faces, yuv);
  287. }
  288. RsAllocation rsrAllocationCreateTyped(Context *rsc, const RsType type,
  289. RsAllocationMipmapControl mipmaps,
  290. uint32_t usages, uintptr_t ptr) {
  291. return rsi_AllocationCreateTyped(rsc, type, mipmaps, usages, ptr);
  292. }
  293. } // namespace renderscript
  294. } // namespace android