1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2bc0ca6ba4e31239bf77060578d0bdf1a10e04168Jason Sams * Copyright (C) 2013 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
22b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
237ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams#include "system/window.h"
2458fd6a5f10480551786739280d56dfa620c80b39Andy McFadden#include "gui/GLConsumer.h"
250b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
2639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
27326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
28326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
29326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
30a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
31179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                       RsAllocationMipmapControl mc, void * ptr)
32a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
33fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
34eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memset(&mHal, 0, sizeof(mHal));
35eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
36bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
37bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
382e1a94df812f0caa42ff24eaefeba8f90fbdf1acTim Murray    mHal.state.userProvidedPtr = ptr;
39366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
40064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(type);
41eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    updateCache();
42fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
43fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
4434689388556747b52c3c2f1c894929fb44580898Tim Murrayvoid Allocation::operator delete(void* ptr) {
4534689388556747b52c3c2f1c894929fb44580898Tim Murray    if (ptr) {
4634689388556747b52c3c2f1c894929fb44580898Tim Murray        Allocation *a = (Allocation*) ptr;
4734689388556747b52c3c2f1c894929fb44580898Tim Murray        a->getContext()->mHal.funcs.freeRuntimeMem(ptr);
4834689388556747b52c3c2f1c894929fb44580898Tim Murray    }
4934689388556747b52c3c2f1c894929fb44580898Tim Murray}
5034689388556747b52c3c2f1c894929fb44580898Tim Murray
51eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason SamsAllocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
52179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                              RsAllocationMipmapControl mc, void * ptr) {
5334689388556747b52c3c2f1c894929fb44580898Tim Murray    // Allocation objects must use allocator specified by the driver
5434689388556747b52c3c2f1c894929fb44580898Tim Murray    void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
5534689388556747b52c3c2f1c894929fb44580898Tim Murray
5634689388556747b52c3c2f1c894929fb44580898Tim Murray    if (!allocMem) {
5734689388556747b52c3c2f1c894929fb44580898Tim Murray        rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
5834689388556747b52c3c2f1c894929fb44580898Tim Murray        return NULL;
5934689388556747b52c3c2f1c894929fb44580898Tim Murray    }
6034689388556747b52c3c2f1c894929fb44580898Tim Murray
6134689388556747b52c3c2f1c894929fb44580898Tim Murray    Allocation *a = new (allocMem) Allocation(rsc, type, usages, mc, ptr);
62fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
63eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) {
64eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
65eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        delete a;
66eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
67eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
687ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
69eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return a;
70bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
71fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
72bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
73064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    const Type *type = mHal.state.type;
74a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    mHal.state.yuv = type->getDimYuv();
75bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
76bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
77bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
78bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
79326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
81afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
82ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
83ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mGrallocConsumer.get()) {
84ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mGrallocConsumer->unlockBuffer();
85ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mGrallocConsumer = NULL;
86ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
87ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
88ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
89c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    freeChildrenUnlocked();
90eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.destroy(mRSC, this);
91326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
92326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
93366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
94eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.syncAll(rsc, this, src);
95cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
96cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
974b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
986ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                         uint32_t count, const void *data, size_t sizeBytes) {
996ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    const size_t eSize = mHal.state.type->getElementSizeBytes();
1009397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
101eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if ((count * eSize) != sizeBytes) {
1026ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Allocation::subData called with mismatched size expected %zu, got %zu",
103eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams             (count * eSize), sizeBytes);
104bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
1059397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
1069397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
107e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
108eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes);
109eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1124b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
113358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                      uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
114358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
115eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
116326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
118236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
1193bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t lod,
1203bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
1213bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
1223bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    sendDirty(rsc);
123326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
124326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
125807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod,
126358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                      uint32_t count, void *data, size_t sizeBytes) {
127807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t eSize = mHal.state.type->getElementSizeBytes();
128807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
129807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if ((count * eSize) != sizeBytes) {
130807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        ALOGE("Allocation::read called with mismatched size expected %zu, got %zu",
131807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams             (count * eSize), sizeBytes);
132807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        mHal.state.type->dumpLOGV("type info");
133807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        return;
134807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
135807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
136807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes);
137807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams}
138807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
139807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
1403bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
141807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t eSize = mHal.state.elementSizeBytes;
142807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t lineSize = eSize * w;
1433bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    if (!stride) {
1443bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        stride = lineSize;
1453bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    } else {
1463bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        if ((lineSize * h) != sizeBytes) {
1473bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            ALOGE("Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes);
1483bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            rsAssert(!"Allocation::read called with mismatched size");
1493bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            return;
1503bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        }
151807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
152807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
1533bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
154358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
155358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
1563bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
1573bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
158358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    const size_t eSize = mHal.state.elementSizeBytes;
159358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    const size_t lineSize = eSize * w;
160358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    if (!stride) {
161358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray        stride = lineSize;
162358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    }
163358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
1643bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
165807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
166807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams}
167807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
1684b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, const void *data,
1696ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                uint32_t cIdx, size_t sizeBytes) {
1706ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
1715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
172bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
173af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData component %i out of range.", cIdx);
1745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
1755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1775f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
178a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    if (x >= mHal.drvState.lod[0].dimX) {
179af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
1805f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
1815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1825f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1835f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
184bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
185769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
186769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
1876ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
1885f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
1895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
1905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
1915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
192eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes);
193eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
1945f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
1955f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
1964b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
1976ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                const void *data, uint32_t cIdx, size_t sizeBytes) {
1986ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
1995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
200a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    if (x >= mHal.drvState.lod[0].dimX) {
201af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
2025f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
2035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2045f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2055f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
206a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    if (y >= mHal.drvState.lod[0].dimY) {
207af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
2085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
2095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
212bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
213af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Error Allocation::subElementData component %i out of range.", cIdx);
2145f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
2155f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2165f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2175f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
218bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
219769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
220769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
2216ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines        ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
2225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
2235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
226eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, sizeBytes);
227eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
2285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
2295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
230afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
231fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
2325c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
2335c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
234afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
2355c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
2365c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
2375c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
2385c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
2395c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
2405c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
2415c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
2425c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
243326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
244afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
245c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
24648ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    char buf[1024];
247c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
24848ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    if ((strlen(prefix) + 10) < sizeof(buf)) {
24948ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        sprintf(buf, "%s type ", prefix);
25048ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        if (mHal.state.type) {
25148ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams            mHal.state.type->dumpLOGV(buf);
25248ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        }
253c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
2546598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
255709a0978ae141198018ca9769f8d96292a8928e6Jason Sams         prefix, mHal.drvState.lod[0].mallocPtr, mHal.state.usageFlags, mHal.state.mipmapControl);
256c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
257326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
2582d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchoukuint32_t Allocation::getPackedSize() const {
25961656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = mHal.state.type->getCellCount();
2602d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
2612d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
2622d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
263e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::writePackedData(Context *rsc, const Type *type,
2642d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk                                 uint8_t *dst, const uint8_t *src, bool dstPadded) {
2652d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const Element *elem = type->getElement();
2662d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
2672d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = elem->getSizeBytes();
26861656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = type->getPackedSizeBytes() / paddedBytes;
2692d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2702d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
2712d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t dstInc =  dstPadded ? paddedBytes : unpaddedBytes;
2722d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2732d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // no sub-elements
2742d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t fieldCount = elem->getFieldCount();
2752d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (fieldCount == 0) {
2762d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t i = 0; i < numItems; i ++) {
2772d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst, src, unpaddedBytes);
2782d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            src += srcInc;
2792d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            dst += dstInc;
2802d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
2812d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        return;
2822d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
2832d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2842d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // Cache offsets
2852d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsPadded = new uint32_t[fieldCount];
2862d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
2872d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *sizeUnpadded = new uint32_t[fieldCount];
2882d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2892d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < fieldCount; i++) {
2902d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsPadded[i] = elem->getFieldOffsetBytes(i);
2912d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
2922d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
2932d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
2942d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2952d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
2962d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *dstOffsets =  dstPadded ? offsetsPadded : offsetsUnpadded;
2972d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
2982d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // complex elements, need to copy subelem after subelem
2992d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < numItems; i ++) {
3002d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t fI = 0; fI < fieldCount; fI++) {
3012d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
3022d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
3032d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        src += srcInc;
3042d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dst += dstInc;
3052d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
3062d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3072d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsPadded;
3082d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsUnpadded;
3092d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] sizeUnpadded;
3102d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
3112d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
312e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) {
3132d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const uint8_t *src = (const uint8_t*)data;
31461a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this);
3152d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
316e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    writePackedData(rsc, getType(), dst, src, true);
31761a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, this);
3182d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
3192d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
320e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::packVec3Allocation(Context *rsc, OStream *stream) const {
3212d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
3222d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
32361656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = mHal.state.type->getCellCount();
3242d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
32561a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this);
3262d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
3272d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
328e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    writePackedData(rsc, getType(), dst, src, false);
3292d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addByteArray(dst, getPackedSize());
3302d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3312d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] dst;
33261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, this);
3332d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
3342d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
335e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::serialize(Context *rsc, OStream *stream) const {
336fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
337fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
33848ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    stream->addString(getName());
339fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
340fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
341fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
342e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    mHal.state.type->serialize(rsc, stream);
343fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
34461656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t dataSize = mHal.state.type->getPackedSizeBytes();
3452d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
3462d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = getPackedSize();
347fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
3482d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addU32(packedSize);
3492d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (dataSize == packedSize) {
3502d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
35161a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize);
35261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.unlock1D(rsc, this);
3532d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
3542d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
355e3150cfb3edb028407669e4a65e087eae77e718cJason Sams        packVec3Allocation(rsc, stream);
3562d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
357fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
358fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
359afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
360fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
361b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
362afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
363af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("allocation loading skipped due to invalid class id\n");
364fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
365fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
366fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
36748ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    const char *name = stream->loadString();
368fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
369fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
370afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
371fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
372fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
373fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
374fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
3752d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
3762d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    type->decUserRef();
3772d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
378fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
379fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
3802d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
3812d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = alloc->getPackedSize();
38261656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (dataSize != type->getPackedSizeBytes() &&
3832d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dataSize != packedSize) {
384af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
3852d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        ObjectBase::checkDelete(alloc);
386225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
387fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
388fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
389fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
39048ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    alloc->assignName(name);
39161656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (dataSize == type->getPackedSizeBytes()) {
3922d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        uint32_t count = dataSize / type->getElementSizeBytes();
3932d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Read in all of our allocation data
3942d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
3952d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
396e3150cfb3edb028407669e4a65e087eae77e718cJason Sams        alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize);
3972d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
398e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
399fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
400fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
401fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
402fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
403eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid Allocation::sendDirty(const Context *rsc) const {
40493eacc7ce0aad4314b4cb41a281f59ce54bb3286Jason Sams#ifndef RS_COMPATIBILITY_LIB
4055c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
4065c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
4075c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
40893eacc7ce0aad4314b4cb41a281f59ce54bb3286Jason Sams#endif
409eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.markDirty(rsc, this);
4105c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
411326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
412afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
4139f70a4e63825afe9f786483722e1669b3625f5e9Stephen Hines    mHal.state.type->incRefs(ptr, ct, startOff);
414e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
415e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
416afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
4175c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (!mHal.state.hasReferences || !getIsScript()) {
4185c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        return;
4195c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
4209f70a4e63825afe9f786483722e1669b3625f5e9Stephen Hines    mHal.state.type->decRefs(ptr, ct, startOff);
421e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
422e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
423c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid Allocation::freeChildrenUnlocked () {
42461a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this);
42561656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    decRefs(ptr, mHal.state.type->getCellCount(), 0);
42661a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    mRSC->mHal.funcs.allocation.unlock1D(mRSC, this);
427c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
428c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
429c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool Allocation::freeChildren() {
430c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (mHal.state.hasReferences) {
431c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        incSysRef();
432c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        freeChildrenUnlocked();
433c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        return decSysRef();
434c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
435c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
436c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
437c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
438afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
43996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
44096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
441afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
442a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    uint32_t oldDimX = mHal.drvState.lod[0].dimX;
44396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
44496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
44596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
44696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
447c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
44896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
44961a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX);
45061a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.unlock1D(rsc, this);
45196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
452c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
453064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(t.get());
454bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
45596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
45696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
457afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
458af12ac6a08651464f8d823add667c706f993b587Steve Block    ALOGE("not implemented");
45996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
46096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
461ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
462ddceab9a001f07a3395226c5e06e3b420720af0fJason Samsvoid Allocation::NewBufferListener::onFrameAvailable() {
463ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    intptr_t ip = (intptr_t)alloc;
464ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, ip, 0, true);
465ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
466ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
467ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
468733396b67724162844ea2785c7495115dc5ee8d8Jason Samsvoid * Allocation::getSurface(const Context *rsc) {
469ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
470ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // Configure GrallocConsumer to be in asynchronous mode
471ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    sp<BufferQueue> bq = new BufferQueue();
472ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mGrallocConsumer = new GrallocConsumer(this, bq);
473ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    sp<IGraphicBufferProducer> bp = bq;
474ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    bp->incStrong(NULL);
475ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
476ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mBufferListener = new NewBufferListener();
477ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mBufferListener->rsc = rsc;
478ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mBufferListener->alloc = this;
479ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
480ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mGrallocConsumer->setFrameAvailableListener(mBufferListener);
481ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return bp.get();
482ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#else
483ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    return NULL;
484ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
485ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //return rsc->mHal.funcs.allocation.getSurface(rsc, this);
48641e373d91a60043afa0f9abd026218b49cbc1201Jason Sams}
48741e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
4887ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
4897ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    ANativeWindow *nw = (ANativeWindow *)sur;
490733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    rsc->mHal.funcs.allocation.setSurface(rsc, this, nw);
4917ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
4927ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
4937ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioSend(const Context *rsc) {
4947ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    rsc->mHal.funcs.allocation.ioSend(rsc, this);
4957ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
4967ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
4977ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioReceive(const Context *rsc) {
498ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    void *ptr = NULL;
499ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    size_t stride = 0;
500ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
501ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
502ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        status_t ret = mGrallocConsumer->lockNextBuffer();
503ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
504ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (ret == OK) {
505ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            rsc->mHal.funcs.allocation.ioReceive(rsc, this);
506ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else if (ret == BAD_VALUE) {
507ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            // No new frame, don't do anything
508ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else {
509ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
510ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
511ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
512ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
513ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
5147ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
5157ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
5167ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
517326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
518565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
5196a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
520326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
521326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
522326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
523366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
524366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
525eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    a->sendDirty(rsc);
526366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
527366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
528366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
529a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
53061a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    Allocation *alloc = static_cast<Allocation *>(va);
53161a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc);
53239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
53339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
534807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
535807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    Allocation *a = static_cast<Allocation *>(va);
536807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const Type * t = a->getType();
537807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
5383bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            t->getDimX(), t->getDimY(), data, sizeBytes, 0);
539837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
540837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
5414b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
542b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t count, const void *data, size_t sizeBytes) {
543326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
5444b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
5455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
5465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
5474b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
5486ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                 const void *data, size_t sizeBytes, size_t eoff) {
5495f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
5504b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, y, data, eoff, sizeBytes);
5515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
5525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
5534b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
5546ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                                 const void *data, size_t sizeBytes, size_t eoff) {
5555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
5564b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, data, eoff, sizeBytes);
557326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
558326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
5594b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
560358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                          uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
561326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
562358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
563326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
564326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
5653bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
5663bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                          uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
5673bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *a = static_cast<Allocation *>(va);
5683bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
5693bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams}
5703bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
5713bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
572807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
573e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
574807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const Type * t = a->getType();
575807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if(t->getDimY()) {
576807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
5773bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                t->getDimX(), t->getDimY(), data, sizeBytes, 0);
578807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    } else {
579807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes);
580807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
581807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
582e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
583e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
584afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
58596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
58696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
58796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
589afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
59096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
59196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
59296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
59396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
594c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
595c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       RsAllocationMipmapControl mips,
596099bc262f862cdeb547cf8a78fe9e0e92560f437Tim Murray                                       uint32_t usages, uintptr_t ptr) {
597099bc262f862cdeb547cf8a78fe9e0e92560f437Tim Murray    Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips, (void*)ptr);
598eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc) {
599eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return NULL;
600eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
601f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
602f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
603f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
604f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
605c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
606c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            RsAllocationMipmapControl mips,
607807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                                            const void *data, size_t sizeBytes, uint32_t usages) {
608366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
609f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
610179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
611f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
612f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
613af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
614f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
615f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
616f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
617807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
61860c2796d821d9296003d4e5db025f8734d971a71Tim Murray                   t->getDimX(), t->getDimY(), data, sizeBytes, 0);
619ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
62061a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
621f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
622f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
623eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
624f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
625f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
62684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
627c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
628c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                RsAllocationMipmapControl mips,
629807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                                                const void *data, size_t sizeBytes, uint32_t usages) {
630366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
63184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
63284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
63384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
63484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
635179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
63684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
63784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
638af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
63984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
64084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
64184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
6429f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
6439f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
6449f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
6459f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
64684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
647366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
6489f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
649807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams            texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face,
65060c2796d821d9296003d4e5db025f8734d971a71Tim Murray                           t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0);
6519f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
652366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
653366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
6549f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
655f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
656366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
657f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
65861a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
65984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
66084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
661eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
66284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
66384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
664099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
66574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsi_AllocationCopy2DRange(Context *rsc,
66674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation dstAlloc,
66774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff,
66874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstMip, uint32_t dstFace,
66974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t width, uint32_t height,
67074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation srcAlloc,
67174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff,
67274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcMip, uint32_t srcFace) {
67374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *dst = static_cast<Allocation *>(dstAlloc);
67474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *src= static_cast<Allocation *>(srcAlloc);
67574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip,
67674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)dstFace,
67774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           width, height,
67874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           src, srcXoff, srcYoff,srcMip,
67974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)srcFace);
68074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
68174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
6823bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid rsi_AllocationCopy3DRange(Context *rsc,
6833bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               RsAllocation dstAlloc,
6843bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
6853bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t dstMip,
6863bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t width, uint32_t height, uint32_t depth,
6873bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               RsAllocation srcAlloc,
6883bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
6893bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t srcMip) {
6903bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *dst = static_cast<Allocation *>(dstAlloc);
6913bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *src= static_cast<Allocation *>(srcAlloc);
6923bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip,
6933bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                                           width, height, depth,
6943bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                                           src, srcXoff, srcYoff, srcZoff, srcMip);
6953bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams}
6963bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
6973bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
698733396b67724162844ea2785c7495115dc5ee8d8Jason Samsvoid * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) {
69941e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
700733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    void *s = alloc->getSurface(rsc);
701733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    return s;
7023522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams}
7033522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams
7047ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
7057ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7067ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->setSurface(rsc, sur);
7077ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7087ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
7097ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) {
7107ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7117ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioSend(rsc);
7127ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7137ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
7147ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) {
7157ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
7167ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioReceive(rsc);
7177ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
7187ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
719509ea5c832a865bc9083d53f1f058377a689bab3Tim Murrayvoid rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
720509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray                          uint32_t count, void *data, size_t sizeBytes) {
721509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    Allocation *a = static_cast<Allocation *>(va);
7223bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes);
723509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray}
724509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray
7257b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murrayvoid rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff,
7267b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray                          uint32_t lod, RsAllocationCubemapFace face, uint32_t w,
727358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                          uint32_t h, void *data, size_t sizeBytes, size_t stride) {
7287b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray    Allocation *a = static_cast<Allocation *>(va);
729358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
7307b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray}
7317b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray
732c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
733c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
734c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
735c2ce707a3d1a8eae79bcf1c749afc6d6e7969ad9Tim Murrayextern "C" const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
736c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    Allocation *a = static_cast<Allocation *>(va);
737c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    a->getType()->incUserRef();
738c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
739c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    return a->getType();
740c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
741