rsAllocation.cpp revision 5c4369a3a1b19eaeabb044af2cdeef05474f9069
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 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"
18eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rs_hal.h"
19eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
2039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
24a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
25a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk                       RsAllocationMipmapControl mc)
26a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
27fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
28eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memset(&mHal, 0, sizeof(mHal));
29eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
32366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
33eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mHal.state.type.set(type);
34eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    updateCache();
35fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
36fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
37eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason SamsAllocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
38eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              RsAllocationMipmapControl mc) {
39eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Allocation *a = new Allocation(rsc, type, usages, mc);
40fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
41eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) {
42eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
43eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        delete a;
44eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
45eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
46eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return a;
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
48fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
49bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
50bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Type *type = mHal.state.type.get();
51bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionX = type->getDimX();
52bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionY = type->getDimY();
53bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionZ = type->getDimZ();
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
55bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
59326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
60afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
615c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (mHal.state.hasReferences &&
625c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        (mHal.state.hasFaces || mHal.state.hasMipmaps)) {
635c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        LOGE("Cube/mip allocation with references unsupported, memory not cleaned up!");
645c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
655c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk
665c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    uint32_t elemCount = mHal.state.dimensionX;
675c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (mHal.state.dimensionY > 1) {
685c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        elemCount *= mHal.state.dimensionY;
695c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
705c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (mHal.state.dimensionZ > 1) {
715c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        elemCount *= mHal.state.dimensionZ;
725c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
735c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    decRefs(getPtr(), elemCount, 0);
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.destroy(mRSC, this);
75326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
77366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
78eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.syncAll(rsc, this, src);
79cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
80cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
81afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
82eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(data, getPtr(), mHal.state.type->getSizeBytes());
83e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
84e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
854b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
864b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                         uint32_t count, const void *data, uint32_t sizeBytes) {
87eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t eSize = mHal.state.type->getElementSizeBytes();
889397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
89eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if ((count * eSize) != sizeBytes) {
90eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i",
91eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams             (count * eSize), sizeBytes);
92bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
939397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
949397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
95e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
96eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes);
97eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
99326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1004b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
101afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
102eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t eSize = mHal.state.elementSizeBytes;
103eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t lineSize = eSize * w;
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
105a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    //LOGE("data2d %p,  %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
1069397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
107a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    if ((lineSize * h) != sizeBytes) {
108a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        LOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
1099397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
1109397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
1119397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
1129397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
113eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes);
114eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
115326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
116326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
117236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
118236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t lod, RsAllocationCubemapFace face,
119236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
120326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
121326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1224b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, const void *data,
123afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
124bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
1255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
126bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
1275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
1285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
1295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
132bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
1335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
1345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
138bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
1395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
140099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
1415f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
1425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes);
146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
1475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
1485f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
1494b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
150afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
151bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
1525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
153bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
1545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("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 (y >= mHal.state.dimensionY) {
1605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
1615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1645f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
165bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
1665f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
1675f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
1685f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1695f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1705f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
171bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
1725f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
1735f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
174099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
1755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
1765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1775f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1785f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
179eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, sizeBytes);
180eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
1815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
1825f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
183afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
184fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
1855c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
1865c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
187afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
1885c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
1895c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
1905c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
1915c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
1925c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
1935c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1945c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
1955c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
196326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
197afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
198c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
199c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
200c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
201c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
202bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.type.get()) {
203bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV(s.string());
204c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
205c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
206eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    LOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
207eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams         prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl);
208c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
209326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
210afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
211fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
212fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
213fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
214fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
215fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
216fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
217fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
218fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
219bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type->serialize(stream);
220fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
221bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t dataSize = mHal.state.type->getSizeBytes();
222fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
223fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
224fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
225eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    stream->addByteArray(getPtr(), dataSize);
226fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
227fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
228afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
229fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
230b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
231afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
232fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
233fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
234fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
235fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
236fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
237fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
238fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
239fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
240afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
241fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
242fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
243fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
244fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
245fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
246fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
247afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
248fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
249225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
250fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
251fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
252fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
253eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
254fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
255fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
2564b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    uint32_t count = dataSize / type->getElementSizeBytes();
2574b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams
258fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
2594b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
260e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
261fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
262fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
263fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
264fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
265eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid Allocation::sendDirty(const Context *rsc) const {
2665c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
2675c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
2685c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
269eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.markDirty(rsc, this);
2705c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
271326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
272afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
273e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
274bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
275e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
276e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
27796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
278e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
279e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
280e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
281e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
282e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
283e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
284e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
285afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
2865c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (!mHal.state.hasReferences || !getIsScript()) {
2875c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        return;
2885c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
289e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
290bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
291e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
292e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
29396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
294e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
295e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
296e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
297e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
298e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
299e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
300e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
301afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
30296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
30396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
304afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
305bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t oldDimX = mHal.state.dimensionX;
30696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
30796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
30896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
30996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
310eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
31196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
312eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        decRefs(getPtr(), oldDimX - dimX, dimX);
31396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
314eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.resize(rsc, this, t, mHal.state.hasReferences);
315bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type.set(t);
316bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
31796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
31896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
319afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
32096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
32196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
32296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
323326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
324565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
3256a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
326326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
327326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
328326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
329c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
330c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
331afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
332326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
333326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
334326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
335e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
336326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
337326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
338326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
339326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
340e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
341565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
342565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
343565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
344565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
345565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
346565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
347565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
348565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
349afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
350565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
351565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
352565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
353e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
354565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
355565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
356565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
357565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
358e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
359565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
360326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
361326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
362326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
363326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
364326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
365326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
366326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
367afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
3682f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
3692f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
3702f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
3712f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
3722f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
3732f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
3742f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
3752f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
3762f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
3772f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
3782f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
3792f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
3802f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
3812f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
3822f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
3832f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
3842f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
385afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
386afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
387e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
388e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
389e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
390e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
391e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
392e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
3932f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
3942f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
3952f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
396e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
397e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
398326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
399366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
400366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
401eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    a->sendDirty(rsc);
402366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
403366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
404366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
405a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
40639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
407c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    AllocationGenerateScriptMips(rsc, texAlloc);
40839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
40939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
410837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
411837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    Allocation *texAlloc = static_cast<Allocation *>(va);
412837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
413837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
414837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
415837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
416837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
417837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
418837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
419837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
420837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    memcpy(data, texAlloc->getPtr(), s);
421837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
422837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
4234b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
424b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t count, const void *data, size_t sizeBytes) {
425326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
4264b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
4275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4294b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
430b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                                 const void *data, size_t eoff, uint32_t sizeBytes) { // TODO: this seems wrong, eoff and sizeBytes may be swapped
4315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
4324b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, y, data, eoff, sizeBytes);
4335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4354b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
436b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                                 const void *data, size_t eoff, uint32_t sizeBytes) { // TODO: this seems wrong, eoff and sizeBytes may be swapped
4375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
4384b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, data, eoff, sizeBytes);
439326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
440326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
4414b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
442b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
443326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
4444b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
445326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
446326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
44770b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t data_length) {
448e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
449e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
450e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
451e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
452afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
45396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
45496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
45596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
45696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
457afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
45896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
45996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
46096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
46196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
462c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
463f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
464f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
465f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
466f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    for (uint32_t face = 0; face < numFaces; face ++) {
467f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt(rsc, texAlloc);
468f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt2(rsc, texAlloc);
469f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt.setFace(face);
470f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt2.setFace(face);
471f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
472f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt.setLOD(lod);
473f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt2.setLOD(lod + 1);
474f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            mip(adapt2, adapt);
475f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        }
476f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
477f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk}
478f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk
479c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
480c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       RsAllocationMipmapControl mips,
481c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       uint32_t usages) {
482eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips);
483eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc) {
484eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
485eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
486f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
487f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
488f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
489f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
490c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
491c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            RsAllocationMipmapControl mips,
492c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            const void *data, size_t data_length, uint32_t usages) {
493366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
494f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
495c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
496f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
497f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
498f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
499f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
500f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
501f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
502366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
503ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
504c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
505f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
506f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
507eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
508f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
509f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
51084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
511c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
512c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                RsAllocationMipmapControl mips,
513c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                const void *data, size_t data_length, uint32_t usages) {
514366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
51584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
51684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
51784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
51884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
519c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
52084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
52184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
52284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Memory allocation failure");
52384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
52484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
52584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
5269f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
5279f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
5289f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
5299f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
53084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
531366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
532366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
533366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
534366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
5359f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
5369f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk            memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
5379f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
538366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
539366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
5409f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
541f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
542366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
543f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
544c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
54584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
54684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
547eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
54884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
54984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
550099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
55174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsi_AllocationCopy2DRange(Context *rsc,
55274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation dstAlloc,
55374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff,
55474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstMip, uint32_t dstFace,
55574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t width, uint32_t height,
55674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation srcAlloc,
55774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff,
55874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcMip, uint32_t srcFace) {
55974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *dst = static_cast<Allocation *>(dstAlloc);
56074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *src= static_cast<Allocation *>(srcAlloc);
56174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip,
56274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)dstFace,
56374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           width, height,
56474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           src, srcXoff, srcYoff,srcMip,
56574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)srcFace);
56674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
56774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
568c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
569c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
570c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
571c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
572c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    Allocation *a = static_cast<Allocation *>(va);
573c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    a->getType()->incUserRef();
574c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
575c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    return a->getType();
576c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
577