rsType.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * Copyright (C) 2013 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. #ifndef RS_COMPATIBILITY_LIB
  18. #include "system/graphics.h"
  19. #else
  20. #include "rsCompatibilityLib.h"
  21. #endif
  22. namespace android {
  23. namespace renderscript {
  24. Type::Type(Context *rsc) : ObjectBase(rsc) {
  25. memset(&mHal, 0, sizeof(mHal));
  26. mDimLOD = false;
  27. }
  28. void Type::preDestroy() const {
  29. auto& types = mRSC->mStateType.mTypes;
  30. for (uint32_t ct = 0; ct < types.size(); ct++) {
  31. if (types[ct] == this) {
  32. types.erase(types.begin() + ct);
  33. break;
  34. }
  35. }
  36. }
  37. Type::~Type() {
  38. clear();
  39. }
  40. void Type::operator delete(void* ptr) {
  41. if (ptr) {
  42. Type *t = (Type*) ptr;
  43. t->getContext()->mHal.funcs.freeRuntimeMem(ptr);
  44. }
  45. }
  46. void Type::clear() {
  47. if (mHal.state.lodCount) {
  48. delete [] mHal.state.lodDimX;
  49. delete [] mHal.state.lodDimY;
  50. delete [] mHal.state.lodDimZ;
  51. }
  52. if (mHal.state.arrayCount > 0) {
  53. delete [] mHal.state.arrays;
  54. }
  55. mElement.clear();
  56. memset(&mHal, 0, sizeof(mHal));
  57. }
  58. TypeState::TypeState() {
  59. }
  60. TypeState::~TypeState() {
  61. rsAssert(!mTypes.size());
  62. }
  63. void Type::compute() {
  64. uint32_t oldLODCount = mHal.state.lodCount;
  65. if (mDimLOD) {
  66. uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1;
  67. uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1;
  68. uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1;
  69. mHal.state.lodCount = rsMax(l2x, l2y);
  70. mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z);
  71. } else {
  72. if (mHal.state.dimYuv) {
  73. mHal.state.lodCount = 3;
  74. } else {
  75. mHal.state.lodCount = 1;
  76. }
  77. }
  78. if (mHal.state.lodCount != oldLODCount) {
  79. if (oldLODCount) {
  80. delete [] mHal.state.lodDimX;
  81. delete [] mHal.state.lodDimY;
  82. delete [] mHal.state.lodDimZ;
  83. }
  84. mHal.state.lodDimX = new uint32_t[mHal.state.lodCount];
  85. mHal.state.lodDimY = new uint32_t[mHal.state.lodCount];
  86. mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount];
  87. }
  88. uint32_t tx = mHal.state.dimX;
  89. uint32_t ty = mHal.state.dimY;
  90. uint32_t tz = mHal.state.dimZ;
  91. mCellCount = 0;
  92. if (!mHal.state.dimYuv) {
  93. for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) {
  94. mHal.state.lodDimX[lod] = tx;
  95. mHal.state.lodDimY[lod] = ty;
  96. mHal.state.lodDimZ[lod] = tz;
  97. mCellCount += tx * rsMax(ty, 1u) * rsMax(tz, 1u);
  98. if (tx > 1) tx >>= 1;
  99. if (ty > 1) ty >>= 1;
  100. if (tz > 1) tz >>= 1;
  101. }
  102. }
  103. if (mHal.state.faces) {
  104. mCellCount *= 6;
  105. }
  106. // YUV only supports basic 2d
  107. // so we can stash the plane pointers in the mipmap levels.
  108. if (mHal.state.dimYuv) {
  109. mHal.state.lodDimX[0] = tx;
  110. mHal.state.lodDimY[0] = ty;
  111. mHal.state.lodDimZ[0] = tz;
  112. mHal.state.lodDimX[1] = mHal.state.lodDimX[0] / 2;
  113. mHal.state.lodDimY[1] = mHal.state.lodDimY[0] / 2;
  114. mHal.state.lodDimX[2] = mHal.state.lodDimX[0] / 2;
  115. mHal.state.lodDimY[2] = mHal.state.lodDimY[0] / 2;
  116. mCellCount += mHal.state.lodDimX[0] * mHal.state.lodDimY[0];
  117. mCellCount += mHal.state.lodDimX[1] * mHal.state.lodDimY[1];
  118. mCellCount += mHal.state.lodDimX[2] * mHal.state.lodDimY[2];
  119. switch(mHal.state.dimYuv) {
  120. case HAL_PIXEL_FORMAT_YV12:
  121. break;
  122. case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
  123. mHal.state.lodDimX[1] = mHal.state.lodDimX[0];
  124. break;
  125. #ifndef RS_COMPATIBILITY_LIB
  126. case HAL_PIXEL_FORMAT_YCbCr_420_888:
  127. break;
  128. #endif
  129. default:
  130. rsAssert(0);
  131. }
  132. }
  133. mHal.state.element = mElement.get();
  134. }
  135. void Type::dumpLOGV(const char *prefix) const {
  136. char buf[1024];
  137. ObjectBase::dumpLOGV(prefix);
  138. ALOGV("%s Type: x=%u y=%u z=%u mip=%i face=%i", prefix,
  139. mHal.state.dimX,
  140. mHal.state.dimY,
  141. mHal.state.dimZ,
  142. mHal.state.lodCount,
  143. mHal.state.faces);
  144. snprintf(buf, sizeof(buf), "%s element: ", prefix);
  145. mElement->dumpLOGV(buf);
  146. }
  147. void Type::serialize(Context *rsc, OStream *stream) const {
  148. // Need to identify ourselves
  149. stream->addU32((uint32_t)getClassId());
  150. stream->addString(getName());
  151. mElement->serialize(rsc, stream);
  152. stream->addU32(mHal.state.dimX);
  153. stream->addU32(mHal.state.dimY);
  154. stream->addU32(mHal.state.dimZ);
  155. stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0));
  156. stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0));
  157. }
  158. Type *Type::createFromStream(Context *rsc, IStream *stream) {
  159. // First make sure we are reading the correct object
  160. RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
  161. if (classID != RS_A3D_CLASS_ID_TYPE) {
  162. ALOGE("type loading skipped due to invalid class id\n");
  163. return nullptr;
  164. }
  165. const char *name = stream->loadString();
  166. Element *elem = Element::createFromStream(rsc, stream);
  167. if (!elem) {
  168. return nullptr;
  169. }
  170. RsTypeCreateParams p;
  171. memset(&p, 0, sizeof(p));
  172. p.dimX = stream->loadU32();
  173. p.dimY = stream->loadU32();
  174. p.dimZ = stream->loadU32();
  175. p.mipmaps = stream->loadU8();
  176. p.faces = stream->loadU8();
  177. Type *type = Type::getType(rsc, elem, &p, sizeof(p));
  178. elem->decUserRef();
  179. delete [] name;
  180. return type;
  181. }
  182. bool Type::getIsNp2() const {
  183. uint32_t x = getDimX();
  184. uint32_t y = getDimY();
  185. uint32_t z = getDimZ();
  186. if (x && (x & (x-1))) {
  187. return true;
  188. }
  189. if (y && (y & (y-1))) {
  190. return true;
  191. }
  192. if (z && (z & (z-1))) {
  193. return true;
  194. }
  195. return false;
  196. }
  197. ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
  198. const RsTypeCreateParams *params, size_t len) {
  199. ObjectBaseRef<Type> returnRef;
  200. TypeState * stc = &rsc->mStateType;
  201. ObjectBase::asyncLock();
  202. for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
  203. Type *t = stc->mTypes[ct];
  204. if (t->getElement() != e) continue;
  205. if (t->getDimX() != params->dimX) continue;
  206. if (t->getDimY() != params->dimY) continue;
  207. if (t->getDimZ() != params->dimZ) continue;
  208. if (t->getDimLOD() != params->mipmaps) continue;
  209. if (t->getDimFaces() != params->faces) continue;
  210. if (t->getDimYuv() != params->yuv) continue;
  211. if (t->getArray(0) != params->array0) continue;
  212. if (t->getArray(1) != params->array1) continue;
  213. if (t->getArray(2) != params->array2) continue;
  214. if (t->getArray(3) != params->array3) continue;
  215. returnRef.set(t);
  216. ObjectBase::asyncUnlock();
  217. return returnRef;
  218. }
  219. ObjectBase::asyncUnlock();
  220. // Type objects must use allocator specified by the driver
  221. void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Type), 0);
  222. if (!allocMem) {
  223. rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Type");
  224. return nullptr;
  225. }
  226. Type *nt = new (allocMem) Type(rsc);
  227. #ifdef RS_FIND_OFFSETS
  228. ALOGE("pointer for type: %p", nt);
  229. ALOGE("pointer for type.drv: %p", &nt->mHal.drv);
  230. #endif
  231. nt->mDimLOD = params->mipmaps;
  232. returnRef.set(nt);
  233. nt->mElement.set(e);
  234. nt->mHal.state.dimX = params->dimX;
  235. nt->mHal.state.dimY = params->dimY;
  236. nt->mHal.state.dimZ = params->dimZ;
  237. nt->mHal.state.faces = params->faces;
  238. nt->mHal.state.dimYuv = params->yuv;
  239. nt->mHal.state.arrayCount = 0;
  240. if (params->array0 > 0) nt->mHal.state.arrayCount ++;
  241. if (params->array1 > 0) nt->mHal.state.arrayCount ++;
  242. if (params->array2 > 0) nt->mHal.state.arrayCount ++;
  243. if (params->array3 > 0) nt->mHal.state.arrayCount ++;
  244. if (nt->mHal.state.arrayCount > 0) {
  245. nt->mHal.state.arrays = new uint32_t[nt->mHal.state.arrayCount];
  246. if (params->array0 > 0) nt->mHal.state.arrays[0] = params->array0;
  247. if (params->array1 > 1) nt->mHal.state.arrays[1] = params->array1;
  248. if (params->array2 > 2) nt->mHal.state.arrays[2] = params->array2;
  249. if (params->array3 > 3) nt->mHal.state.arrays[3] = params->array3;
  250. }
  251. nt->compute();
  252. ObjectBase::asyncLock();
  253. stc->mTypes.push_back(nt);
  254. ObjectBase::asyncUnlock();
  255. return returnRef;
  256. }
  257. ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
  258. RsTypeCreateParams p;
  259. memset(&p, 0, sizeof(p));
  260. p.dimX = dimX;
  261. p.dimY = getDimY();
  262. p.dimZ = getDimZ();
  263. p.mipmaps = getDimLOD();
  264. return getTypeRef(rsc, mElement.get(), &p, sizeof(p));
  265. }
  266. ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
  267. uint32_t dimX,
  268. uint32_t dimY) const {
  269. RsTypeCreateParams p;
  270. memset(&p, 0, sizeof(p));
  271. p.dimX = dimX;
  272. p.dimY = dimY;
  273. p.dimZ = getDimZ();
  274. p.mipmaps = getDimLOD();
  275. p.faces = getDimFaces();
  276. p.yuv = getDimYuv();
  277. return getTypeRef(rsc, mElement.get(), &p, sizeof(p));
  278. }
  279. void Type::incRefs(const void *ptr, size_t ct, size_t startOff) const {
  280. const uint8_t *p = static_cast<const uint8_t *>(ptr);
  281. const Element *e = mHal.state.element;
  282. uint32_t stride = e->getSizeBytes();
  283. p += stride * startOff;
  284. while (ct > 0) {
  285. e->incRefs(p);
  286. ct--;
  287. p += stride;
  288. }
  289. }
  290. void Type::decRefs(const void *ptr, size_t ct, size_t startOff) const {
  291. if (!mHal.state.element->getHasReferences()) {
  292. return;
  293. }
  294. const uint8_t *p = static_cast<const uint8_t *>(ptr);
  295. const Element *e = mHal.state.element;
  296. uint32_t stride = e->getSizeBytes();
  297. p += stride * startOff;
  298. while (ct > 0) {
  299. e->decRefs(p);
  300. ct--;
  301. p += stride;
  302. }
  303. }
  304. void Type::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
  305. if (rsc->mHal.funcs.type.updateCachedObject != nullptr) {
  306. rsc->mHal.funcs.type.updateCachedObject(rsc, this, (rs_type *)dstObj);
  307. } else {
  308. *((const void **)dstObj) = this;
  309. }
  310. }
  311. //////////////////////////////////////////////////
  312. //
  313. RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX,
  314. uint32_t dimY, uint32_t dimZ, bool mipmaps, bool faces, uint32_t yuv) {
  315. Element *e = static_cast<Element *>(_e);
  316. RsTypeCreateParams p;
  317. memset(&p, 0, sizeof(p));
  318. p.dimX = dimX;
  319. p.dimY = dimY;
  320. p.dimZ = dimZ;
  321. p.mipmaps = mipmaps;
  322. p.faces = faces;
  323. p.yuv = yuv;
  324. return Type::getType(rsc, e, &p, sizeof(p));
  325. }
  326. RsType rsi_TypeCreate2(Context *rsc, const RsTypeCreateParams *p, size_t len) {
  327. Element *e = static_cast<Element *>(p->e);
  328. return Type::getType(rsc, e, p, len);
  329. }
  330. } // namespace renderscript
  331. } // namespace android