rsAllocation.cpp revision 4edf030cbb7c6ac08dc563335c2af73c20f6e2e5
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
26ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines * Copyright (C) 2009-2012 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include "rsContext.h"
184edf030cbb7c6ac08dc563335c2af73c20f6e2e5Alex Sakhartchouk#include "rsAllocation.h"
194edf030cbb7c6ac08dc563335c2af73c20f6e2e5Alex Sakhartchouk#include "rsAdapter.h"
20eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rs_hal.h"
21eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
227ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams#include "system/window.h"
2339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
25326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
26326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
27a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
28179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                       RsAllocationMipmapControl mc, void * ptr)
29a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
30fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
31eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memset(&mHal, 0, sizeof(mHal));
32eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
34bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
35179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    mHal.state.usrPtr = ptr;
36366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
37064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(type);
38eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    updateCache();
39fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
40fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
41eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason SamsAllocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
42179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                              RsAllocationMipmapControl mc, void * ptr) {
43179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    Allocation *a = new Allocation(rsc, type, usages, mc, ptr);
44fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
45eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) {
46eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
47eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        delete a;
48eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
49eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
507ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
51eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return a;
52bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
53fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
55064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    const Type *type = mHal.state.type;
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionX = type->getDimX();
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionY = type->getDimY();
58bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionZ = type->getDimZ();
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
60bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
61bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
62bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
63326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
64326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
65afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
66c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    freeChildrenUnlocked();
67eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.destroy(mRSC, this);
68326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
69326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
70366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.syncAll(rsc, this, src);
72cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
73cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
74afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
75eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(data, getPtr(), mHal.state.type->getSizeBytes());
76e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
77e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
784b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
796ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                         uint32_t count, const void *data, size_t sizeBytes) {
806ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    const size_t eSize = mHal.state.type->getElementSizeBytes();
819397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if ((count * eSize) != sizeBytes) {
836ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Allocation::subData called with mismatched size expected %zu, got %zu",
84eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams             (count * eSize), sizeBytes);
85bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
869397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
879397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
88e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
89eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes);
90eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
91326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
92326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
934b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
946ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines             uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
956ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    const size_t eSize = mHal.state.elementSizeBytes;
966ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    const size_t lineSize = eSize * w;
97326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
98af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("data2d %p,  %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
999397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
100a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    if ((lineSize * h) != sizeBytes) {
1016ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes);
1029397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
1039397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
1049397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
1059397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
106eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes);
107eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
110236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
111236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t lod, RsAllocationCubemapFace face,
1126ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                      uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes) {
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1154b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, const void *data,
1166ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                uint32_t cIdx, size_t sizeBytes) {
1176ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
1185f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
119bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
120af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData component %i out of range.", cIdx);
1215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
1225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
125bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
126af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
1275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
131bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
132769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
133769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
1346ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
1355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
1365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1385f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
139eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes);
140eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
1415f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
1425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
1434b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
1446ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                const void *data, uint32_t cIdx, size_t sizeBytes) {
1456ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
1465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
147bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
148af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
1495f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1505f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
153bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (y >= mHal.state.dimensionY) {
154af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
1555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1565f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1585f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
159bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
160af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData component %i out of range.", cIdx);
1615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
1625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1645f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
165bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
166769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
167769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
1686ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
1695f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
1705f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1725f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
173eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, sizeBytes);
174eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
1755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
1765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
177afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
178fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
1795c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
1805c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
181afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
1825c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
1835c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
1845c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
1855c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
1865c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
1875c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1885c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
1895c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
190326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
191afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
192c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
193c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
194c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
195c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
196064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    if (mHal.state.type) {
197bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV(s.string());
198c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
199c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
2006598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
201eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams         prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl);
202c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
203326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
2042d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchoukuint32_t Allocation::getPackedSize() const {
2052d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t numItems = mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes();
2062d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
2072d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
2082d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2092d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchoukvoid Allocation::writePackedData(const Type *type,
2102d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk                                 uint8_t *dst, const uint8_t *src, bool dstPadded) {
2112d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const Element *elem = type->getElement();
2122d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
2132d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = elem->getSizeBytes();
2142d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t numItems = type->getSizeBytes() / paddedBytes;
2152d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2162d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
2172d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t dstInc =  dstPadded ? paddedBytes : unpaddedBytes;
2182d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2192d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // no sub-elements
2202d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t fieldCount = elem->getFieldCount();
2212d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (fieldCount == 0) {
2222d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t i = 0; i < numItems; i ++) {
2232d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst, src, unpaddedBytes);
2242d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            src += srcInc;
2252d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            dst += dstInc;
2262d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
2272d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        return;
2282d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
2292d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2302d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // Cache offsets
2312d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsPadded = new uint32_t[fieldCount];
2322d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
2332d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *sizeUnpadded = new uint32_t[fieldCount];
2342d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2352d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < fieldCount; i++) {
2362d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsPadded[i] = elem->getFieldOffsetBytes(i);
2372d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
2382d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
2392d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
2402d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2412d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
2422d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *dstOffsets =  dstPadded ? offsetsPadded : offsetsUnpadded;
2432d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2442d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // complex elements, need to copy subelem after subelem
2452d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < numItems; i ++) {
2462d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t fI = 0; fI < fieldCount; fI++) {
2472d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
2482d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
2492d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        src += srcInc;
2502d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dst += dstInc;
2512d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
2522d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2532d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsPadded;
2542d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsUnpadded;
2552d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] sizeUnpadded;
2562d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
2572d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2586ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hinesvoid Allocation::unpackVec3Allocation(const void *data, size_t dataSize) {
2592d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const uint8_t *src = (const uint8_t*)data;
2602d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint8_t *dst = (uint8_t*)getPtr();
2612d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2622d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    writePackedData(getType(), dst, src, true);
2632d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
2642d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2652d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchoukvoid Allocation::packVec3Allocation(OStream *stream) const {
2662d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
2672d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
2682d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t numItems = mHal.state.type->getSizeBytes() / paddedBytes;
2692d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2702d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const uint8_t *src = (const uint8_t*)getPtr();
2712d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
2722d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2732d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    writePackedData(getType(), dst, src, false);
2742d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addByteArray(dst, getPackedSize());
2752d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2762d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] dst;
2772d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
2782d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
279afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
280fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
281fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
282fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
283fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
284fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
285fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
286fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
287fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
288bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type->serialize(stream);
289fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
290bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t dataSize = mHal.state.type->getSizeBytes();
2912d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
2922d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = getPackedSize();
293fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
2942d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addU32(packedSize);
2952d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (dataSize == packedSize) {
2962d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
2972d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        stream->addByteArray(getPtr(), dataSize);
2982d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
2992d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
3002d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        packVec3Allocation(stream);
3012d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
302fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
303fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
304afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
305fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
306b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
307afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
308af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("allocation loading skipped due to invalid class id\n");
309fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
310fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
311fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
312fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
313fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
314fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
315fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
316afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
317fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
318fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
319fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
320fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
3212d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
3222d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    type->decUserRef();
3232d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
324fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
325fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
3262d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
3272d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = alloc->getPackedSize();
3282d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (dataSize != type->getSizeBytes() &&
3292d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dataSize != packedSize) {
330af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
3312d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        ObjectBase::checkDelete(alloc);
332225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
333fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
334fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
335fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
336fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
3374b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams
3382d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (dataSize == type->getSizeBytes()) {
3392d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        uint32_t count = dataSize / type->getElementSizeBytes();
3402d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Read in all of our allocation data
3412d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
3422d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
3432d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        alloc->unpackVec3Allocation(stream->getPtr() + stream->getPos(), dataSize);
3442d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
345e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
346fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
347fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
348fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
349fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
350eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid Allocation::sendDirty(const Context *rsc) const {
3515c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
3525c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
3535c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
354eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.markDirty(rsc, this);
3555c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
356326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
357afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
358e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
359bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
360e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
361e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
36296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
363e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
364e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
365e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
366e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
367e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
368e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
369e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
370afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
3715c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (!mHal.state.hasReferences || !getIsScript()) {
3725c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        return;
3735c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
374e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
375bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
376e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
377e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
37896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
379e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
380e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
381e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
382e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
383e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
384e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
385e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
386c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid Allocation::freeChildrenUnlocked () {
387c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    decRefs(getPtr(), mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes(), 0);
388c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
389c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
390c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool Allocation::freeChildren() {
391c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (mHal.state.hasReferences) {
392c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        incSysRef();
393c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        freeChildrenUnlocked();
394c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        return decSysRef();
395c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
396c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
397c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
398c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
399afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
40096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
40196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
402afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
403bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t oldDimX = mHal.state.dimensionX;
40496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
40596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
40696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
40796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
408c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
40996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
410eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        decRefs(getPtr(), oldDimX - dimX, dimX);
41196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
412c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
413064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(t.get());
414bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
41596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
41696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
417afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
418af12ac6a08651464f8d823add667c706f993b587Steve Block    ALOGE("not implemented");
41996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
42096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
42141e373d91a60043afa0f9abd026218b49cbc1201Jason Samsint32_t Allocation::getSurfaceTextureID(const Context *rsc) {
42241e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    int32_t id = rsc->mHal.funcs.allocation.initSurfaceTexture(rsc, this);
42341e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    mHal.state.surfaceTextureID = id;
42441e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    return id;
42541e373d91a60043afa0f9abd026218b49cbc1201Jason Sams}
42641e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
4277ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
4287ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    ANativeWindow *nw = (ANativeWindow *)sur;
4297ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    ANativeWindow *old = mHal.state.wndSurface;
4307ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    if (nw) {
4317ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        nw->incStrong(NULL);
4327ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    }
4337ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    rsc->mHal.funcs.allocation.setSurfaceTexture(rsc, this, nw);
4347ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    mHal.state.wndSurface = nw;
4357ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    if (old) {
4367ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams        old->decStrong(NULL);
4377ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    }
4387ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
4397ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
4407ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioSend(const Context *rsc) {
4417ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    rsc->mHal.funcs.allocation.ioSend(rsc, this);
4427ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
4437ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
4447ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioReceive(const Context *rsc) {
4457ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    rsc->mHal.funcs.allocation.ioReceive(rsc, this);
4467ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
4477ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
4487ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
449326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
450565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
4516a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
452326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
453326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
454326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
455c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
456c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
457afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
458326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
459326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
460326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
461e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
462326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
463326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
464326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
465326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
466e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
467565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
468565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
469565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
470565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
471565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
472565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
473565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
474565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
475afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
476565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
477565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
478565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
479e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
480565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
481565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
482565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
483565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
484e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
485565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
486326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
487326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
488326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
489326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
490326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
491326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
492326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
493afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
4942f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
4952f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
4962f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
4972f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
4982f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
4992f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
5002f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
5012f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
5022f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
5032f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
5042f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
5052f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
5062f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
5072f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
5082f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
5092f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
5102f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
511afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
512afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
513e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
514e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
515e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
516e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
517e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
518e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
5192f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
5202f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
5212f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
522e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
523e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
524326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
525366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
526366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
527eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    a->sendDirty(rsc);
528366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
529366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
530366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
531a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
53239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
533c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    AllocationGenerateScriptMips(rsc, texAlloc);
53439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
53539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
536837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
537837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    Allocation *texAlloc = static_cast<Allocation *>(va);
538837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
539837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
540837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
541837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
542837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
543837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
544837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
545837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
546837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    memcpy(data, texAlloc->getPtr(), s);
547837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
548837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
5494b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
550b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t count, const void *data, size_t sizeBytes) {
551326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
5524b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
5535f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
5545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
5554b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
5566ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                 const void *data, size_t sizeBytes, size_t eoff) {
5575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
5584b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, y, data, eoff, sizeBytes);
5595f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
5605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
5614b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
5626ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                 const void *data, size_t sizeBytes, size_t eoff) {
5635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
5644b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, data, eoff, sizeBytes);
565326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
566326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
5674b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
568b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
569326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
5704b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
571326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
572326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
57370b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t data_length) {
574e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
575e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
576e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
577e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
578afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
57996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
58096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
58196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
583afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
58496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
58596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
58696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
588c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
589f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
590f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
591f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
592f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    for (uint32_t face = 0; face < numFaces; face ++) {
593f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt(rsc, texAlloc);
594f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt2(rsc, texAlloc);
595f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt.setFace(face);
596f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt2.setFace(face);
597f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
598f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt.setLOD(lod);
599f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt2.setLOD(lod + 1);
600f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            mip(adapt2, adapt);
601f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        }
602f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
603f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk}
604f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk
605c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
606c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       RsAllocationMipmapControl mips,
607179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                                       uint32_t usages, uint32_t ptr) {
608179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips, (void *)ptr);
609eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc) {
610eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
611eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
612f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
613f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
614f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
615f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
616c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
617c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            RsAllocationMipmapControl mips,
618c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            const void *data, size_t data_length, uint32_t usages) {
619366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
620f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
621179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
622f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
623f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
624af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
625f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
626f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
627f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
628366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
629ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
630c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
631f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
632f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
633eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
634f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
635f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
63684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
637c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
638c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                RsAllocationMipmapControl mips,
639c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                const void *data, size_t data_length, uint32_t usages) {
640366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
64184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
64284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
64384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
64484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
645179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
64684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
64784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
648af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
64984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
65084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
65184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
6529f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
6539f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
6549f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
6559f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
65684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
657366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
658366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
659366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
660366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
6619f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
6629f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk            memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
6639f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
664366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
665366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
6669f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
667f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
668366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
669f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
670c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
67184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
67284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
673eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
67484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
67584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
676099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
67774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsi_AllocationCopy2DRange(Context *rsc,
67874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation dstAlloc,
67974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff,
68074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstMip, uint32_t dstFace,
68174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t width, uint32_t height,
68274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation srcAlloc,
68374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff,
68474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcMip, uint32_t srcFace) {
68574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *dst = static_cast<Allocation *>(dstAlloc);
68674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *src= static_cast<Allocation *>(srcAlloc);
68774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip,
68874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)dstFace,
68974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           width, height,
69074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           src, srcXoff, srcYoff,srcMip,
69174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)srcFace);
69274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
69374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
69441e373d91a60043afa0f9abd026218b49cbc1201Jason Samsint32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) {
69541e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
69641e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    return alloc->getSurfaceTextureID(rsc);
69741e373d91a60043afa0f9abd026218b49cbc1201Jason Sams}
69841e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
6997ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
7007ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7017ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->setSurface(rsc, sur);
7027ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7037ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
7047ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) {
7057ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7067ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioSend(rsc);
7077ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7087ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
7097ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) {
7107ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7117ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioReceive(rsc);
7127ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7137ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
714c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
715c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
716c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
717c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
718c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    Allocation *a = static_cast<Allocation *>(va);
719c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    a->getType()->incUserRef();
720c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
721c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    return a->getType();
722c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
723