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