rsAllocation.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  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. #include "rsAllocation.h"
  18. #include "rs_hal.h"
  19. #ifndef RS_COMPATIBILITY_LIB
  20. #include "rsGrallocConsumer.h"
  21. #endif
  22. namespace android {
  23. namespace renderscript {
  24. Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
  25. RsAllocationMipmapControl mc, void * ptr)
  26. : ObjectBase(rsc) {
  27. memset(&mHal, 0, sizeof(mHal));
  28. mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
  29. mHal.state.usageFlags = usages;
  30. mHal.state.mipmapControl = mc;
  31. mHal.state.userProvidedPtr = ptr;
  32. setType(type);
  33. updateCache();
  34. }
  35. Allocation::Allocation(Context *rsc, const Allocation *alloc, const Type *type)
  36. : ObjectBase(rsc) {
  37. memset(&mHal, 0, sizeof(mHal));
  38. mHal.state.baseAlloc = alloc;
  39. mHal.state.usageFlags = alloc->mHal.state.usageFlags;
  40. mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
  41. setType(type);
  42. updateCache();
  43. }
  44. void Allocation::operator delete(void* ptr) {
  45. if (ptr) {
  46. Allocation *a = (Allocation*) ptr;
  47. a->getContext()->mHal.funcs.freeRuntimeMem(ptr);
  48. }
  49. }
  50. Allocation * Allocation::createAllocationStrided(Context *rsc, const Type *type, uint32_t usages,
  51. RsAllocationMipmapControl mc, void * ptr,
  52. size_t requiredAlignment) {
  53. // Allocation objects must use allocator specified by the driver
  54. void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
  55. if (!allocMem) {
  56. rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
  57. return nullptr;
  58. }
  59. bool success = false;
  60. Allocation *a = nullptr;
  61. if (usages & RS_ALLOCATION_USAGE_OEM) {
  62. if (rsc->mHal.funcs.allocation.initOem != nullptr) {
  63. a = new (allocMem) Allocation(rsc, type, usages, mc, nullptr);
  64. success = rsc->mHal.funcs.allocation.initOem(rsc, a, type->getElement()->getHasReferences(), ptr);
  65. } else {
  66. rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation Init called with USAGE_OEM but driver does not support it");
  67. return nullptr;
  68. }
  69. #ifdef RS_COMPATIBILITY_LIB
  70. } else if (usages & RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT){
  71. a = new (allocMem) Allocation(rsc, type, usages, mc, ptr);
  72. success = rsc->mHal.funcs.allocation.initStrided(rsc, a, type->getElement()->getHasReferences(), requiredAlignment);
  73. #endif
  74. } else {
  75. a = new (allocMem) Allocation(rsc, type, usages, mc, ptr);
  76. success = rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences());
  77. }
  78. if (!success) {
  79. rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
  80. delete a;
  81. return nullptr;
  82. }
  83. return a;
  84. }
  85. Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
  86. RsAllocationMipmapControl mc, void * ptr) {
  87. return Allocation::createAllocationStrided(rsc, type, usages, mc, ptr, kMinimumRSAlignment);
  88. }
  89. Allocation * Allocation::createAdapter(Context *rsc, const Allocation *alloc, const Type *type) {
  90. // Allocation objects must use allocator specified by the driver
  91. void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
  92. if (!allocMem) {
  93. rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
  94. return nullptr;
  95. }
  96. Allocation *a = new (allocMem) Allocation(rsc, alloc, type);
  97. if (!rsc->mHal.funcs.allocation.initAdapter(rsc, a)) {
  98. rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
  99. delete a;
  100. return nullptr;
  101. }
  102. return a;
  103. }
  104. void Allocation::adapterOffset(Context *rsc, const uint32_t *offsets, size_t len) {
  105. if (len >= sizeof(uint32_t) * 9) {
  106. mHal.state.originX = offsets[0];
  107. mHal.state.originY = offsets[1];
  108. mHal.state.originZ = offsets[2];
  109. mHal.state.originLOD = offsets[3];
  110. mHal.state.originFace = offsets[4];
  111. mHal.state.originArray[0] = offsets[5];
  112. mHal.state.originArray[1] = offsets[6];
  113. mHal.state.originArray[2] = offsets[7];
  114. mHal.state.originArray[3] = offsets[8];
  115. }
  116. rsc->mHal.funcs.allocation.adapterOffset(rsc, this);
  117. }
  118. void Allocation::updateCache() {
  119. const Type *type = mHal.state.type;
  120. mHal.state.yuv = type->getDimYuv();
  121. mHal.state.hasFaces = type->getDimFaces();
  122. mHal.state.hasMipmaps = type->getDimLOD();
  123. mHal.state.elementSizeBytes = type->getElementSizeBytes();
  124. mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
  125. }
  126. Allocation::~Allocation() {
  127. #ifndef RS_COMPATIBILITY_LIB
  128. if (mGrallocConsumer) {
  129. mGrallocConsumer->releaseIdx(mCurrentIdx);
  130. if (!mGrallocConsumer->isActive()) {
  131. delete mGrallocConsumer;
  132. }
  133. mGrallocConsumer = nullptr;
  134. }
  135. #endif
  136. freeChildrenUnlocked();
  137. mRSC->mHal.funcs.allocation.destroy(mRSC, this);
  138. }
  139. void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
  140. rsc->mHal.funcs.allocation.syncAll(rsc, this, src);
  141. }
  142. void * Allocation::getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face,
  143. uint32_t z, uint32_t array, size_t *stride) {
  144. if ((lod >= mHal.drvState.lodCount) ||
  145. (z && (z >= mHal.drvState.lod[lod].dimZ)) ||
  146. ((face != RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) && !mHal.state.hasFaces) ||
  147. (array != 0)) {
  148. return nullptr;
  149. }
  150. if (mRSC->mHal.funcs.allocation.getPointer != nullptr) {
  151. // Notify the driver, if present that the user is mapping the buffer
  152. mRSC->mHal.funcs.allocation.getPointer(rsc, this, lod, face, z, array);
  153. }
  154. size_t s = 0;
  155. if ((stride != nullptr) && mHal.drvState.lod[0].dimY) {
  156. *stride = mHal.drvState.lod[lod].stride;
  157. }
  158. return mHal.drvState.lod[lod].mallocPtr;
  159. }
  160. void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
  161. uint32_t count, const void *data, size_t sizeBytes) {
  162. const size_t eSize = mHal.state.type->getElementSizeBytes();
  163. if ((count * eSize) != sizeBytes) {
  164. char buf[1024];
  165. snprintf(buf, sizeof(buf),
  166. "Allocation::subData called with mismatched size expected %zu, got %zu",
  167. (count * eSize), sizeBytes);
  168. rsc->setError(RS_ERROR_BAD_VALUE, buf);
  169. mHal.state.type->dumpLOGV("type info");
  170. return;
  171. }
  172. rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes);
  173. sendDirty(rsc);
  174. }
  175. void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
  176. uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
  177. rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
  178. sendDirty(rsc);
  179. }
  180. void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
  181. uint32_t lod,
  182. uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
  183. rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
  184. sendDirty(rsc);
  185. }
  186. void Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod,
  187. uint32_t count, void *data, size_t sizeBytes) {
  188. const size_t eSize = mHal.state.type->getElementSizeBytes();
  189. if ((count * eSize) != sizeBytes) {
  190. char buf[1024];
  191. snprintf(buf, sizeof(buf),
  192. "Allocation::read called with mismatched size expected %zu, got %zu",
  193. (count * eSize), sizeBytes);
  194. rsc->setError(RS_ERROR_BAD_VALUE, buf);
  195. mHal.state.type->dumpLOGV("type info");
  196. return;
  197. }
  198. rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes);
  199. }
  200. void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
  201. uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
  202. const size_t eSize = mHal.state.elementSizeBytes;
  203. const size_t lineSize = eSize * w;
  204. if (!stride) {
  205. stride = lineSize;
  206. } else {
  207. if ((lineSize * h) != sizeBytes) {
  208. char buf[1024];
  209. snprintf(buf, sizeof(buf), "Allocation size mismatch, expected %zu, got %zu",
  210. (lineSize * h), sizeBytes);
  211. rsc->setError(RS_ERROR_BAD_VALUE, buf);
  212. return;
  213. }
  214. }
  215. rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
  216. }
  217. void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
  218. uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
  219. const size_t eSize = mHal.state.elementSizeBytes;
  220. const size_t lineSize = eSize * w;
  221. if (!stride) {
  222. stride = lineSize;
  223. }
  224. rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
  225. }
  226. void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
  227. const void *data, uint32_t cIdx, size_t sizeBytes) {
  228. if (x >= mHal.drvState.lod[0].dimX) {
  229. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
  230. return;
  231. }
  232. if (y > 0 && y >= mHal.drvState.lod[0].dimY) {
  233. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range.");
  234. return;
  235. }
  236. if (z > 0 && z >= mHal.drvState.lod[0].dimZ) {
  237. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range.");
  238. return;
  239. }
  240. if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
  241. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
  242. return;
  243. }
  244. const Element * e = mHal.state.type->getElement()->getField(cIdx);
  245. uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
  246. if (sizeBytes != e->getSizeBytes() * elemArraySize) {
  247. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
  248. return;
  249. }
  250. rsc->mHal.funcs.allocation.elementData(rsc, this, x, y, z, data, cIdx, sizeBytes);
  251. sendDirty(rsc);
  252. }
  253. void Allocation::elementRead(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
  254. void *data, uint32_t cIdx, size_t sizeBytes) {
  255. if (x >= mHal.drvState.lod[0].dimX) {
  256. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
  257. return;
  258. }
  259. if (y > 0 && y >= mHal.drvState.lod[0].dimY) {
  260. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range.");
  261. return;
  262. }
  263. if (z > 0 && z >= mHal.drvState.lod[0].dimZ) {
  264. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range.");
  265. return;
  266. }
  267. if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
  268. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
  269. return;
  270. }
  271. const Element * e = mHal.state.type->getElement()->getField(cIdx);
  272. uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
  273. if (sizeBytes != e->getSizeBytes() * elemArraySize) {
  274. rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
  275. return;
  276. }
  277. rsc->mHal.funcs.allocation.elementRead(rsc, this, x, y, z, data, cIdx, sizeBytes);
  278. }
  279. void Allocation::addProgramToDirty(const Program *p) {
  280. mToDirtyList.push_back(p);
  281. }
  282. void Allocation::removeProgramToDirty(const Program *p) {
  283. for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
  284. if (mToDirtyList[ct] == p) {
  285. mToDirtyList.erase(mToDirtyList.begin() + ct);
  286. return;
  287. }
  288. }
  289. rsAssert(0);
  290. }
  291. void Allocation::dumpLOGV(const char *prefix) const {
  292. ObjectBase::dumpLOGV(prefix);
  293. char buf[1024];
  294. if ((strlen(prefix) + 10) < sizeof(buf)) {
  295. snprintf(buf, sizeof(buf), "%s type ", prefix);
  296. if (mHal.state.type) {
  297. mHal.state.type->dumpLOGV(buf);
  298. }
  299. }
  300. ALOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x",
  301. prefix, mHal.drvState.lod[0].mallocPtr, mHal.state.usageFlags, mHal.state.mipmapControl);
  302. }
  303. uint32_t Allocation::getPackedSize() const {
  304. uint32_t numItems = mHal.state.type->getCellCount();
  305. return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
  306. }
  307. void Allocation::writePackedData(Context *rsc, const Type *type,
  308. uint8_t *dst, const uint8_t *src, bool dstPadded) {
  309. const Element *elem = type->getElement();
  310. uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
  311. uint32_t paddedBytes = elem->getSizeBytes();
  312. uint32_t numItems = type->getPackedSizeBytes() / paddedBytes;
  313. uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
  314. uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes;
  315. // no sub-elements
  316. uint32_t fieldCount = elem->getFieldCount();
  317. if (fieldCount == 0) {
  318. for (uint32_t i = 0; i < numItems; i ++) {
  319. memcpy(dst, src, unpaddedBytes);
  320. src += srcInc;
  321. dst += dstInc;
  322. }
  323. return;
  324. }
  325. // Cache offsets
  326. uint32_t *offsetsPadded = new uint32_t[fieldCount];
  327. uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
  328. uint32_t *sizeUnpadded = new uint32_t[fieldCount];
  329. for (uint32_t i = 0; i < fieldCount; i++) {
  330. offsetsPadded[i] = elem->getFieldOffsetBytes(i);
  331. offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
  332. sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
  333. }
  334. uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
  335. uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded;
  336. // complex elements, need to copy subelem after subelem
  337. for (uint32_t i = 0; i < numItems; i ++) {
  338. for (uint32_t fI = 0; fI < fieldCount; fI++) {
  339. memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
  340. }
  341. src += srcInc;
  342. dst += dstInc;
  343. }
  344. delete[] offsetsPadded;
  345. delete[] offsetsUnpadded;
  346. delete[] sizeUnpadded;
  347. }
  348. void Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) {
  349. const uint8_t *src = (const uint8_t*)data;
  350. uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this);
  351. writePackedData(rsc, getType(), dst, src, true);
  352. rsc->mHal.funcs.allocation.unlock1D(rsc, this);
  353. }
  354. void Allocation::packVec3Allocation(Context *rsc, OStream *stream) const {
  355. uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
  356. uint32_t numItems = mHal.state.type->getCellCount();
  357. const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this);
  358. uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
  359. writePackedData(rsc, getType(), dst, src, false);
  360. stream->addByteArray(dst, getPackedSize());
  361. delete[] dst;
  362. rsc->mHal.funcs.allocation.unlock1D(rsc, this);
  363. }
  364. void Allocation::serialize(Context *rsc, OStream *stream) const {
  365. // Need to identify ourselves
  366. stream->addU32((uint32_t)getClassId());
  367. stream->addString(getName());
  368. // First thing we need to serialize is the type object since it will be needed
  369. // to initialize the class
  370. mHal.state.type->serialize(rsc, stream);
  371. uint32_t dataSize = mHal.state.type->getPackedSizeBytes();
  372. // 3 element vectors are padded to 4 in memory, but padding isn't serialized
  373. uint32_t packedSize = getPackedSize();
  374. // Write how much data we are storing
  375. stream->addU32(packedSize);
  376. if (dataSize == packedSize) {
  377. // Now write the data
  378. stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize);
  379. rsc->mHal.funcs.allocation.unlock1D(rsc, this);
  380. } else {
  381. // Now write the data
  382. packVec3Allocation(rsc, stream);
  383. }
  384. }
  385. Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
  386. // First make sure we are reading the correct object
  387. RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
  388. if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
  389. rsc->setError(RS_ERROR_FATAL_DRIVER,
  390. "allocation loading failed due to corrupt file. (invalid id)\n");
  391. return nullptr;
  392. }
  393. const char *name = stream->loadString();
  394. Type *type = Type::createFromStream(rsc, stream);
  395. if (!type) {
  396. return nullptr;
  397. }
  398. type->compute();
  399. Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
  400. type->decUserRef();
  401. // Number of bytes we wrote out for this allocation
  402. uint32_t dataSize = stream->loadU32();
  403. // 3 element vectors are padded to 4 in memory, but padding isn't serialized
  404. uint32_t packedSize = alloc->getPackedSize();
  405. if (dataSize != type->getPackedSizeBytes() &&
  406. dataSize != packedSize) {
  407. rsc->setError(RS_ERROR_FATAL_DRIVER,
  408. "allocation loading failed due to corrupt file. (invalid size)\n");
  409. ObjectBase::checkDelete(alloc);
  410. ObjectBase::checkDelete(type);
  411. return nullptr;
  412. }
  413. alloc->assignName(name);
  414. if (dataSize == type->getPackedSizeBytes()) {
  415. uint32_t count = dataSize / type->getElementSizeBytes();
  416. // Read in all of our allocation data
  417. alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
  418. } else {
  419. alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize);
  420. }
  421. stream->reset(stream->getPos() + dataSize);
  422. return alloc;
  423. }
  424. void Allocation::sendDirty(const Context *rsc) const {
  425. #ifndef RS_COMPATIBILITY_LIB
  426. for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
  427. mToDirtyList[ct]->forceDirty();
  428. }
  429. #endif
  430. mRSC->mHal.funcs.allocation.markDirty(rsc, this);
  431. }
  432. void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
  433. mHal.state.type->incRefs(ptr, ct, startOff);
  434. }
  435. void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
  436. if (!mHal.state.hasReferences || !getIsScript()) {
  437. return;
  438. }
  439. mHal.state.type->decRefs(ptr, ct, startOff);
  440. }
  441. void Allocation::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
  442. if (rsc->mHal.funcs.allocation.updateCachedObject != nullptr) {
  443. rsc->mHal.funcs.allocation.updateCachedObject(rsc, this, (rs_allocation *)dstObj);
  444. } else {
  445. *((const void **)dstObj) = this;
  446. }
  447. }
  448. void Allocation::freeChildrenUnlocked () {
  449. void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this);
  450. decRefs(ptr, mHal.state.type->getCellCount(), 0);
  451. mRSC->mHal.funcs.allocation.unlock1D(mRSC, this);
  452. }
  453. bool Allocation::freeChildren() {
  454. if (mHal.state.hasReferences) {
  455. incSysRef();
  456. freeChildrenUnlocked();
  457. return decSysRef();
  458. }
  459. return false;
  460. }
  461. void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
  462. }
  463. void Allocation::resize1D(Context *rsc, uint32_t dimX) {
  464. uint32_t oldDimX = mHal.drvState.lod[0].dimX;
  465. if (dimX == oldDimX) {
  466. return;
  467. }
  468. ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
  469. if (dimX < oldDimX) {
  470. decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX);
  471. rsc->mHal.funcs.allocation.unlock1D(rsc, this);
  472. }
  473. rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
  474. setType(t.get());
  475. updateCache();
  476. }
  477. void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
  478. rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
  479. }
  480. void Allocation::setupGrallocConsumer(const Context *rsc, uint32_t numAlloc) {
  481. #ifndef RS_COMPATIBILITY_LIB
  482. // Configure GrallocConsumer to be in asynchronous mode
  483. if (numAlloc > MAX_NUM_ALLOC || numAlloc <= 0) {
  484. rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
  485. return;
  486. }
  487. mGrallocConsumer = new GrallocConsumer(rsc, this, numAlloc);
  488. mCurrentIdx = 0;
  489. mBufferQueueInited = true;
  490. #endif
  491. }
  492. void * Allocation::getSurface(const Context *rsc) {
  493. #ifndef RS_COMPATIBILITY_LIB
  494. // Configure GrallocConsumer to be in asynchronous mode
  495. if (!mBufferQueueInited) {
  496. // This case is only used for single frame processing,
  497. // since we will always call setupGrallocConsumer first in
  498. // multi-frame case.
  499. setupGrallocConsumer(rsc, 1);
  500. }
  501. return mGrallocConsumer->getNativeWindow();
  502. #else
  503. return nullptr;
  504. #endif
  505. }
  506. void Allocation::shareBufferQueue(const Context *rsc, const Allocation *alloc) {
  507. #ifndef RS_COMPATIBILITY_LIB
  508. mGrallocConsumer = alloc->mGrallocConsumer;
  509. mCurrentIdx = mGrallocConsumer->getNextAvailableIdx(this);
  510. if (mCurrentIdx >= mGrallocConsumer->mNumAlloc) {
  511. rsc->setError(RS_ERROR_DRIVER, "Maximum allocations attached to a BufferQueue");
  512. return;
  513. }
  514. mBufferQueueInited = true;
  515. #endif
  516. }
  517. void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
  518. ANativeWindow *nw = (ANativeWindow *)sur;
  519. rsc->mHal.funcs.allocation.setSurface(rsc, this, nw);
  520. }
  521. void Allocation::ioSend(const Context *rsc) {
  522. rsc->mHal.funcs.allocation.ioSend(rsc, this);
  523. }
  524. void Allocation::ioReceive(const Context *rsc) {
  525. void *ptr = nullptr;
  526. size_t stride = 0;
  527. #ifndef RS_COMPATIBILITY_LIB
  528. if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
  529. media_status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx);
  530. if (ret == AMEDIA_OK) {
  531. rsc->mHal.funcs.allocation.ioReceive(rsc, this);
  532. } else if (ret == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
  533. // No new frame, don't do anything
  534. } else {
  535. rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
  536. }
  537. }
  538. #endif
  539. }
  540. bool Allocation::hasSameDims(const Allocation *other) const {
  541. const Type *type0 = this->getType(),
  542. *type1 = other->getType();
  543. return (type0->getCellCount() == type1->getCellCount()) &&
  544. (type0->getDimLOD() == type1->getDimLOD()) &&
  545. (type0->getDimFaces() == type1->getDimFaces()) &&
  546. (type0->getDimYuv() == type1->getDimYuv()) &&
  547. (type0->getDimX() == type1->getDimX()) &&
  548. (type0->getDimY() == type1->getDimY()) &&
  549. (type0->getDimZ() == type1->getDimZ());
  550. }
  551. /////////////////
  552. //
  553. void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
  554. Allocation *a = static_cast<Allocation *>(va);
  555. a->sendDirty(rsc);
  556. a->syncAll(rsc, src);
  557. }
  558. void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
  559. Allocation *alloc = static_cast<Allocation *>(va);
  560. rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc);
  561. }
  562. void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
  563. Allocation *a = static_cast<Allocation *>(va);
  564. const Type * t = a->getType();
  565. a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
  566. t->getDimX(), t->getDimY(), data, sizeBytes, 0);
  567. }
  568. void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
  569. uint32_t count, const void *data, size_t sizeBytes) {
  570. Allocation *a = static_cast<Allocation *>(va);
  571. a->data(rsc, xoff, lod, count, data, sizeBytes);
  572. }
  573. void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x,
  574. uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) {
  575. Allocation *a = static_cast<Allocation *>(va);
  576. a->elementData(rsc, x, 0, 0, data, eoff, sizeBytes);
  577. }
  578. void rsi_AllocationElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
  579. uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) {
  580. Allocation *a = static_cast<Allocation *>(va);
  581. a->elementData(rsc, x, y, z, data, eoff, sizeBytes);
  582. }
  583. void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
  584. uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
  585. Allocation *a = static_cast<Allocation *>(va);
  586. a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
  587. }
  588. void rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
  589. uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
  590. Allocation *a = static_cast<Allocation *>(va);
  591. a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
  592. }
  593. void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
  594. Allocation *a = static_cast<Allocation *>(va);
  595. const Type * t = a->getType();
  596. if(t->getDimZ()) {
  597. a->read(rsc, 0, 0, 0, 0, t->getDimX(), t->getDimY(), t->getDimZ(),
  598. data, sizeBytes, 0);
  599. } else if(t->getDimY()) {
  600. a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
  601. t->getDimX(), t->getDimY(), data, sizeBytes, 0);
  602. } else {
  603. a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes);
  604. }
  605. }
  606. void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
  607. Allocation *a = static_cast<Allocation *>(va);
  608. a->resize1D(rsc, dimX);
  609. }
  610. void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
  611. Allocation *a = static_cast<Allocation *>(va);
  612. a->resize2D(rsc, dimX, dimY);
  613. }
  614. RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
  615. RsAllocationMipmapControl mipmaps,
  616. uint32_t usages, uintptr_t ptr) {
  617. Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mipmaps, (void*)ptr);
  618. if (!alloc) {
  619. return nullptr;
  620. }
  621. alloc->incUserRef();
  622. return alloc;
  623. }
  624. RsAllocation rsi_AllocationCreateStrided(Context *rsc, RsType vtype,
  625. RsAllocationMipmapControl mipmaps,
  626. uint32_t usages, uintptr_t ptr,
  627. size_t requiredAlignment) {
  628. Allocation * alloc = Allocation::createAllocationStrided(rsc, static_cast<Type *>(vtype), usages, mipmaps,
  629. (void*)ptr, requiredAlignment);
  630. if (!alloc) {
  631. return nullptr;
  632. }
  633. alloc->incUserRef();
  634. return alloc;
  635. }
  636. RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
  637. RsAllocationMipmapControl mipmaps,
  638. const void *data, size_t sizeBytes, uint32_t usages) {
  639. Type *t = static_cast<Type *>(vtype);
  640. RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
  641. Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
  642. if (texAlloc == nullptr) {
  643. ALOGE("Memory allocation failure");
  644. return nullptr;
  645. }
  646. texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
  647. t->getDimX(), t->getDimY(), data, sizeBytes, 0);
  648. if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
  649. rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
  650. }
  651. texAlloc->sendDirty(rsc);
  652. return texAlloc;
  653. }
  654. RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
  655. RsAllocationMipmapControl mipmaps,
  656. const void *data, size_t sizeBytes, uint32_t usages) {
  657. Type *t = static_cast<Type *>(vtype);
  658. // Cubemap allocation's faces should be Width by Width each.
  659. // Source data should have 6 * Width by Width pixels
  660. // Error checking is done in the java layer
  661. RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
  662. Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
  663. if (texAlloc == nullptr) {
  664. ALOGE("Memory allocation failure");
  665. return nullptr;
  666. }
  667. uint32_t faceSize = t->getDimX();
  668. uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
  669. uint32_t copySize = faceSize * t->getElementSizeBytes();
  670. uint8_t *sourcePtr = (uint8_t*)data;
  671. for (uint32_t face = 0; face < 6; face ++) {
  672. for (uint32_t dI = 0; dI < faceSize; dI ++) {
  673. texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face,
  674. t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0);
  675. }
  676. // Move the data pointer to the next cube face
  677. sourcePtr += copySize;
  678. }
  679. if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
  680. rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
  681. }
  682. texAlloc->sendDirty(rsc);
  683. return texAlloc;
  684. }
  685. void rsi_AllocationCopy2DRange(Context *rsc,
  686. RsAllocation dstAlloc,
  687. uint32_t dstXoff, uint32_t dstYoff,
  688. uint32_t dstMip, uint32_t dstFace,
  689. uint32_t width, uint32_t height,
  690. RsAllocation srcAlloc,
  691. uint32_t srcXoff, uint32_t srcYoff,
  692. uint32_t srcMip, uint32_t srcFace) {
  693. Allocation *dst = static_cast<Allocation *>(dstAlloc);
  694. Allocation *src= static_cast<Allocation *>(srcAlloc);
  695. rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip,
  696. (RsAllocationCubemapFace)dstFace,
  697. width, height,
  698. src, srcXoff, srcYoff,srcMip,
  699. (RsAllocationCubemapFace)srcFace);
  700. }
  701. void rsi_AllocationCopy3DRange(Context *rsc,
  702. RsAllocation dstAlloc,
  703. uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
  704. uint32_t dstMip,
  705. uint32_t width, uint32_t height, uint32_t depth,
  706. RsAllocation srcAlloc,
  707. uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
  708. uint32_t srcMip) {
  709. Allocation *dst = static_cast<Allocation *>(dstAlloc);
  710. Allocation *src= static_cast<Allocation *>(srcAlloc);
  711. rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip,
  712. width, height, depth,
  713. src, srcXoff, srcYoff, srcZoff, srcMip);
  714. }
  715. void rsi_AllocationSetupBufferQueue(Context *rsc, RsAllocation valloc, uint32_t numAlloc) {
  716. Allocation *alloc = static_cast<Allocation *>(valloc);
  717. alloc->setupGrallocConsumer(rsc, numAlloc);
  718. }
  719. void * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) {
  720. Allocation *alloc = static_cast<Allocation *>(valloc);
  721. void *s = alloc->getSurface(rsc);
  722. return s;
  723. }
  724. void rsi_AllocationShareBufferQueue(Context *rsc, RsAllocation valloc1, RsAllocation valloc2) {
  725. Allocation *alloc1 = static_cast<Allocation *>(valloc1);
  726. Allocation *alloc2 = static_cast<Allocation *>(valloc2);
  727. alloc1->shareBufferQueue(rsc, alloc2);
  728. }
  729. void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
  730. Allocation *alloc = static_cast<Allocation *>(valloc);
  731. alloc->setSurface(rsc, sur);
  732. }
  733. void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) {
  734. Allocation *alloc = static_cast<Allocation *>(valloc);
  735. alloc->ioSend(rsc);
  736. }
  737. int64_t rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) {
  738. Allocation *alloc = static_cast<Allocation *>(valloc);
  739. alloc->ioReceive(rsc);
  740. return alloc->getTimeStamp();
  741. }
  742. void *rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc,
  743. uint32_t lod, RsAllocationCubemapFace face,
  744. uint32_t z, uint32_t array, size_t *stride, size_t strideLen) {
  745. Allocation *alloc = static_cast<Allocation *>(valloc);
  746. rsAssert(strideLen == sizeof(size_t));
  747. return alloc->getPointer(rsc, lod, face, z, array, stride);
  748. }
  749. void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
  750. uint32_t count, void *data, size_t sizeBytes) {
  751. Allocation *a = static_cast<Allocation *>(va);
  752. rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes);
  753. }
  754. void rsi_AllocationElementRead(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
  755. uint32_t lod, void *data, size_t sizeBytes, size_t eoff) {
  756. Allocation *a = static_cast<Allocation *>(va);
  757. a->elementRead(rsc, x, y, z, data, eoff, sizeBytes);
  758. }
  759. void rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff,
  760. uint32_t lod, RsAllocationCubemapFace face, uint32_t w,
  761. uint32_t h, void *data, size_t sizeBytes, size_t stride) {
  762. Allocation *a = static_cast<Allocation *>(va);
  763. a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
  764. }
  765. void rsi_Allocation3DRead(Context *rsc, RsAllocation va,
  766. uint32_t xoff, uint32_t yoff, uint32_t zoff,
  767. uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
  768. void *data, size_t sizeBytes, size_t stride) {
  769. Allocation *a = static_cast<Allocation *>(va);
  770. a->read(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
  771. }
  772. RsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) {
  773. Allocation * alloc = Allocation::createAdapter(rsc,
  774. static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow));
  775. if (!alloc) {
  776. return nullptr;
  777. }
  778. alloc->incUserRef();
  779. return alloc;
  780. }
  781. void rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) {
  782. Allocation *a = static_cast<Allocation *>(va);
  783. a->adapterOffset(rsc, offsets, len);
  784. }
  785. } // namespace renderscript
  786. } // namespace android