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