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