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