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