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