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"
19eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rs_hal.h"
20eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
21b0934b67b95cc27e2358c2aa4db5f7c1067c8f9bStephen Hines#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
227ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams#include "system/window.h"
2358fd6a5f10480551786739280d56dfa620c80b39Andy McFadden#include "gui/GLConsumer.h"
240b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
2539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
26326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
27326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
28326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
29a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
30179e9a457095fea4c9e6d366c269754b882d05ddJason Sams                       RsAllocationMipmapControl mc, void * ptr)
31a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
32fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
33eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memset(&mHal, 0, sizeof(mHal));
34eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
35bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
36bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
372e1a94df812f0caa42ff24eaefeba8f90fbdf1acTim Murray    mHal.state.userProvidedPtr = ptr;
38366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
39064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(type);
40eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    updateCache();
41fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
42fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
43cfea6c13075aa255712e5a09a54eccbc84b0b122Jason SamsAllocation::Allocation(Context *rsc, const Allocation *alloc, const Type *type)
44cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    : ObjectBase(rsc) {
45cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
46cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    memset(&mHal, 0, sizeof(mHal));
47cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    mHal.state.baseAlloc = alloc;
48cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    mHal.state.usageFlags = alloc->mHal.state.usageFlags;
49cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
50cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
51cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    setType(type);
52cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    updateCache();
53cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams}
54cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
5534689388556747b52c3c2f1c894929fb44580898Tim Murrayvoid Allocation::operator delete(void* ptr) {
5634689388556747b52c3c2f1c894929fb44580898Tim Murray    if (ptr) {
5734689388556747b52c3c2f1c894929fb44580898Tim Murray        Allocation *a = (Allocation*) ptr;
5834689388556747b52c3c2f1c894929fb44580898Tim Murray        a->getContext()->mHal.funcs.freeRuntimeMem(ptr);
5934689388556747b52c3c2f1c894929fb44580898Tim Murray    }
6034689388556747b52c3c2f1c894929fb44580898Tim Murray}
6134689388556747b52c3c2f1c894929fb44580898Tim Murray
6247a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao WangAllocation * Allocation::createAllocationStrided(Context *rsc, const Type *type, uint32_t usages,
6347a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                                 RsAllocationMipmapControl mc, void * ptr,
6447a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                                 size_t requiredAlignment) {
6534689388556747b52c3c2f1c894929fb44580898Tim Murray    // Allocation objects must use allocator specified by the driver
6634689388556747b52c3c2f1c894929fb44580898Tim Murray    void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
6734689388556747b52c3c2f1c894929fb44580898Tim Murray
6834689388556747b52c3c2f1c894929fb44580898Tim Murray    if (!allocMem) {
6934689388556747b52c3c2f1c894929fb44580898Tim Murray        rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
7044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
7134689388556747b52c3c2f1c894929fb44580898Tim Murray    }
7234689388556747b52c3c2f1c894929fb44580898Tim Murray
73f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    bool success = false;
74f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    Allocation *a = nullptr;
75f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    if (usages & RS_ALLOCATION_USAGE_OEM) {
76f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams        if (rsc->mHal.funcs.allocation.initOem != nullptr) {
77f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams            a = new (allocMem) Allocation(rsc, type, usages, mc, nullptr);
78f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams            success = rsc->mHal.funcs.allocation.initOem(rsc, a, type->getElement()->getHasReferences(), ptr);
79f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams        } else {
80f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams            rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation Init called with USAGE_OEM but driver does not support it");
81f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams            return nullptr;
82f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams        }
8347a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang#ifdef RS_COMPATIBILITY_LIB
8447a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    } else if (usages & RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT){
8547a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang        a = new (allocMem) Allocation(rsc, type, usages, mc, ptr);
8647a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang        success = rsc->mHal.funcs.allocation.initStrided(rsc, a, type->getElement()->getHasReferences(), requiredAlignment);
8747a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang#endif
88f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    } else {
89f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams        a = new (allocMem) Allocation(rsc, type, usages, mc, ptr);
90f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams        success = rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences());
91f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    }
92fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
93f82b626e0479ce4a23ebff1fc088e073dcabaa30Jason Sams    if (!success) {
94eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
95eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        delete a;
9644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
97eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
987ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
99eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return a;
100bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
101fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
10247a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao WangAllocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
10347a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                              RsAllocationMipmapControl mc, void * ptr) {
10447a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    return Allocation::createAllocationStrided(rsc, type, usages, mc, ptr, kMinimumRSAlignment);
10547a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang}
10647a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang
107cfea6c13075aa255712e5a09a54eccbc84b0b122Jason SamsAllocation * Allocation::createAdapter(Context *rsc, const Allocation *alloc, const Type *type) {
108cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    // Allocation objects must use allocator specified by the driver
109cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
110cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
111cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    if (!allocMem) {
112cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
113cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        return nullptr;
114cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    }
115cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
116cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    Allocation *a = new (allocMem) Allocation(rsc, alloc, type);
117cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
118cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    if (!rsc->mHal.funcs.allocation.initAdapter(rsc, a)) {
119cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
120cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        delete a;
121cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        return nullptr;
122cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    }
123cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
124cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    return a;
125cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams}
126cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
127442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Samsvoid Allocation::adapterOffset(Context *rsc, const uint32_t *offsets, size_t len) {
128442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams    if (len >= sizeof(uint32_t) * 9) {
129442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originX = offsets[0];
130442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originY = offsets[1];
131442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originZ = offsets[2];
132442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originLOD = offsets[3];
133442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originFace = offsets[4];
134442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originArray[0] = offsets[5];
135442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originArray[1] = offsets[6];
136442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originArray[2] = offsets[7];
137442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams        mHal.state.originArray[3] = offsets[8];
138442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams    }
139442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams
140442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams    rsc->mHal.funcs.allocation.adapterOffset(rsc, this);
141442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams}
142442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams
143442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams
144cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
145bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
146064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    const Type *type = mHal.state.type;
147a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    mHal.state.yuv = type->getDimYuv();
148bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
149bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
150bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
151bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
152326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
153326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
154afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
155ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
156ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mGrallocConsumer.get()) {
157754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        mGrallocConsumer->releaseIdx(mCurrentIdx);
15844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        mGrallocConsumer = nullptr;
159ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
160ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
161ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
162c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    freeChildrenUnlocked();
163eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.destroy(mRSC, this);
164326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
165326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
166366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.syncAll(rsc, this, src);
168cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
169cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
170b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Samsvoid * Allocation::getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face,
171b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams                          uint32_t z, uint32_t array, size_t *stride) {
172b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
173b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    if ((lod >= mHal.drvState.lodCount) ||
174b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        (z && (z >= mHal.drvState.lod[lod].dimZ)) ||
175b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        ((face != RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) && !mHal.state.hasFaces) ||
176b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        (array != 0)) {
17744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
178b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
179b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
1808ce12815675bfaeb2768959b092d6db293ba36c5Jason Sams    if (mRSC->mHal.funcs.allocation.getPointer != nullptr) {
1818ce12815675bfaeb2768959b092d6db293ba36c5Jason Sams        // Notify the driver, if present that the user is mapping the buffer
1828ce12815675bfaeb2768959b092d6db293ba36c5Jason Sams        mRSC->mHal.funcs.allocation.getPointer(rsc, this, lod, face, z, array);
1838ce12815675bfaeb2768959b092d6db293ba36c5Jason Sams    }
1848ce12815675bfaeb2768959b092d6db293ba36c5Jason Sams
185b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    size_t s = 0;
18644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if ((stride != nullptr) && mHal.drvState.lod[0].dimY) {
187b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        *stride = mHal.drvState.lod[lod].stride;
188b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
189b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    return mHal.drvState.lod[lod].mallocPtr;
190b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams}
191b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
1924b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
1936ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines                         uint32_t count, const void *data, size_t sizeBytes) {
1946ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    const size_t eSize = mHal.state.type->getElementSizeBytes();
1959397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
196eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if ((count * eSize) != sizeBytes) {
197a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        char buf[1024];
198a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        sprintf(buf, "Allocation::subData called with mismatched size expected %zu, got %zu",
199a273793e0958b0bde10f83725fbe778f3b92374fJason Sams                (count * eSize), sizeBytes);
200a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, buf);
201bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
2029397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
2039397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
204e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
205eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes);
206eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
207326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
208326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
2094b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
210358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                      uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
211358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
212eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
213326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
214326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
215236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
2163bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t lod,
2173bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
2183bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
2193bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    sendDirty(rsc);
220326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
221326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
222807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod,
223358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                      uint32_t count, void *data, size_t sizeBytes) {
224807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t eSize = mHal.state.type->getElementSizeBytes();
225807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
226807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if ((count * eSize) != sizeBytes) {
227a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        char buf[1024];
228a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        sprintf(buf, "Allocation::read called with mismatched size expected %zu, got %zu",
229a273793e0958b0bde10f83725fbe778f3b92374fJason Sams                (count * eSize), sizeBytes);
230a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, buf);
231807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        mHal.state.type->dumpLOGV("type info");
232807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        return;
233807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
234807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
235807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes);
236807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams}
237807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
238807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
2393bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
240807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t eSize = mHal.state.elementSizeBytes;
241807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const size_t lineSize = eSize * w;
2423bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    if (!stride) {
2433bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        stride = lineSize;
2443bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    } else {
2453bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        if ((lineSize * h) != sizeBytes) {
246a273793e0958b0bde10f83725fbe778f3b92374fJason Sams            char buf[1024];
247a273793e0958b0bde10f83725fbe778f3b92374fJason Sams            sprintf(buf, "Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes);
248a273793e0958b0bde10f83725fbe778f3b92374fJason Sams            rsc->setError(RS_ERROR_BAD_VALUE, buf);
2493bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            return;
2503bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams        }
251807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
252807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
2533bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
254358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
255358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
2563bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
2573bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                      uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
258358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    const size_t eSize = mHal.state.elementSizeBytes;
259358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    const size_t lineSize = eSize * w;
260358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    if (!stride) {
261358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray        stride = lineSize;
262358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    }
263358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
2643bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
265807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
266807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams}
267807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
268cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
269cc8cea7477352898921044483a6c803e25d02665Miao Wang                             const void *data, uint32_t cIdx, size_t sizeBytes) {
2706ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
2715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
272cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (x >= mHal.drvState.lod[0].dimX) {
273cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
2745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
277cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (y > 0 && y >= mHal.drvState.lod[0].dimY) {
278cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range.");
279cc8cea7477352898921044483a6c803e25d02665Miao Wang        return;
280cc8cea7477352898921044483a6c803e25d02665Miao Wang    }
281cc8cea7477352898921044483a6c803e25d02665Miao Wang
282cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (z > 0 && z >= mHal.drvState.lod[0].dimZ) {
283cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range.");
284cc8cea7477352898921044483a6c803e25d02665Miao Wang        return;
285cc8cea7477352898921044483a6c803e25d02665Miao Wang    }
286cc8cea7477352898921044483a6c803e25d02665Miao Wang
287cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
288cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
2895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
292bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
293769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
294769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
2955f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
2965f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
2975f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
2985f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
299cc8cea7477352898921044483a6c803e25d02665Miao Wang    rsc->mHal.funcs.allocation.elementData(rsc, this, x, y, z, data, cIdx, sizeBytes);
300eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    sendDirty(rsc);
3015f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
3025f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
303cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid Allocation::elementRead(Context *rsc, uint32_t x, uint32_t y, uint32_t z,
304cc8cea7477352898921044483a6c803e25d02665Miao Wang                             void *data, uint32_t cIdx, size_t sizeBytes) {
3056ae039baf797915d46f3b3901d1b7f5cc83feaceStephen Hines    size_t eSize = mHal.state.elementSizeBytes;
3065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
307a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    if (x >= mHal.drvState.lod[0].dimX) {
3085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
312cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (y > 0 && y >= mHal.drvState.lod[0].dimY) {
313cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range.");
314cc8cea7477352898921044483a6c803e25d02665Miao Wang        return;
315cc8cea7477352898921044483a6c803e25d02665Miao Wang    }
316cc8cea7477352898921044483a6c803e25d02665Miao Wang
317cc8cea7477352898921044483a6c803e25d02665Miao Wang    if (z > 0 && z >= mHal.drvState.lod[0].dimZ) {
318cc8cea7477352898921044483a6c803e25d02665Miao Wang        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range.");
3195f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
322bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
323b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
327bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
328b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni    uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx);
329769463262d655087ed39d9b823673e776a8af946Alex Sakhartchouk    if (sizeBytes != e->getSizeBytes() * elemArraySize) {
3305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
3315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
334cc8cea7477352898921044483a6c803e25d02665Miao Wang    rsc->mHal.funcs.allocation.elementRead(rsc, this, x, y, z, data, cIdx, sizeBytes);
3355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
3365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
337afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
338b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni    mToDirtyList.push(p);
3395c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
3405c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
341afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
342b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
343b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni        if (mToDirtyList[ct] == p) {
344b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni            mToDirtyList.removeAt(ct);
3455c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
3465c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
3475c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
3485c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
3495c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
350326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
351afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
352c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
35348ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    char buf[1024];
354c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
35548ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    if ((strlen(prefix) + 10) < sizeof(buf)) {
35648ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        sprintf(buf, "%s type ", prefix);
35748ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        if (mHal.state.type) {
35848ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams            mHal.state.type->dumpLOGV(buf);
35948ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams        }
360c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
3616598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block    ALOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
362b8353c5943f4038fd7f08db3d958390ce9418798Yang Ni         prefix, mHal.drvState.lod[0].mallocPtr, mHal.state.usageFlags, mHal.state.mipmapControl);
363c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
364326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3652d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchoukuint32_t Allocation::getPackedSize() const {
36661656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = mHal.state.type->getCellCount();
3672d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
3682d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
3692d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
370e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::writePackedData(Context *rsc, const Type *type,
3712d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk                                 uint8_t *dst, const uint8_t *src, bool dstPadded) {
3722d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const Element *elem = type->getElement();
3732d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
3742d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = elem->getSizeBytes();
37561656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = type->getPackedSizeBytes() / paddedBytes;
3762d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3772d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
3782d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t dstInc =  dstPadded ? paddedBytes : unpaddedBytes;
3792d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3802d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // no sub-elements
3812d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t fieldCount = elem->getFieldCount();
3822d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (fieldCount == 0) {
3832d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t i = 0; i < numItems; i ++) {
3842d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst, src, unpaddedBytes);
3852d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            src += srcInc;
3862d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            dst += dstInc;
3872d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
3882d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        return;
3892d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
3902d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3912d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // Cache offsets
3922d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsPadded = new uint32_t[fieldCount];
3932d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
3942d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *sizeUnpadded = new uint32_t[fieldCount];
3952d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
3962d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < fieldCount; i++) {
3972d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsPadded[i] = elem->getFieldOffsetBytes(i);
3982d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
3992d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
4002d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
4012d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
4022d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
4032d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t *dstOffsets =  dstPadded ? offsetsPadded : offsetsUnpadded;
4042d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
4052d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // complex elements, need to copy subelem after subelem
4062d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    for (uint32_t i = 0; i < numItems; i ++) {
4072d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        for (uint32_t fI = 0; fI < fieldCount; fI++) {
4082d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk            memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
4092d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        }
4102d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        src += srcInc;
4112d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dst += dstInc;
4122d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
4132d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
4142d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsPadded;
4152d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] offsetsUnpadded;
4162d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] sizeUnpadded;
4172d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
4182d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
419e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) {
4202d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    const uint8_t *src = (const uint8_t*)data;
42161a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this);
4222d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
423e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    writePackedData(rsc, getType(), dst, src, true);
42461a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, this);
4252d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
4262d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
427e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::packVec3Allocation(Context *rsc, OStream *stream) const {
4282d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
4292d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
43061656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t numItems = mHal.state.type->getCellCount();
4312d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
43261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this);
4332d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
4342d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
435e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    writePackedData(rsc, getType(), dst, src, false);
4362d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addByteArray(dst, getPackedSize());
4372d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
4382d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    delete[] dst;
43961a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, this);
4402d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk}
4412d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
442e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid Allocation::serialize(Context *rsc, OStream *stream) const {
443fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
444fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
44548ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    stream->addString(getName());
446fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
447fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
448fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
449e3150cfb3edb028407669e4a65e087eae77e718cJason Sams    mHal.state.type->serialize(rsc, stream);
450fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
45161656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    uint32_t dataSize = mHal.state.type->getPackedSizeBytes();
4522d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
4532d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = getPackedSize();
454fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
4552d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    stream->addU32(packedSize);
4562d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    if (dataSize == packedSize) {
4572d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
45861a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize);
45961a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.unlock1D(rsc, this);
4602d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
4612d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Now write the data
462e3150cfb3edb028407669e4a65e087eae77e718cJason Sams        packVec3Allocation(rsc, stream);
4632d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
464fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
465fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
466afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
467fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
468b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
469afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
470a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER,
471a273793e0958b0bde10f83725fbe778f3b92374fJason Sams                      "allocation loading failed due to corrupt file. (invalid id)\n");
47244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
473fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
474fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
47548ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    const char *name = stream->loadString();
476fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
477fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
478afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
47944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
480fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
481fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
482fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
4832d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
4842d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    type->decUserRef();
4852d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk
486fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
487fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
4882d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
4892d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    uint32_t packedSize = alloc->getPackedSize();
49061656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (dataSize != type->getPackedSizeBytes() &&
4912d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        dataSize != packedSize) {
492a273793e0958b0bde10f83725fbe778f3b92374fJason Sams        rsc->setError(RS_ERROR_FATAL_DRIVER,
493a273793e0958b0bde10f83725fbe778f3b92374fJason Sams                      "allocation loading failed due to corrupt file. (invalid size)\n");
4942d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        ObjectBase::checkDelete(alloc);
495225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
49644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
497fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
498fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
49948ecf6a5e85a9a832f41393ed2802385bb8b5db8Jason Sams    alloc->assignName(name);
50061656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    if (dataSize == type->getPackedSizeBytes()) {
5012d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        uint32_t count = dataSize / type->getElementSizeBytes();
5022d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        // Read in all of our allocation data
5032d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk        alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
5042d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    } else {
505e3150cfb3edb028407669e4a65e087eae77e718cJason Sams        alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize);
5062d1220c27ae91f0b307f283fe66cb767b63dfe38Alex Sakhartchouk    }
507e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
508fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
509fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
510fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
511fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
512eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid Allocation::sendDirty(const Context *rsc) const {
51393eacc7ce0aad4314b4cb41a281f59ce54bb3286Jason Sams#ifndef RS_COMPATIBILITY_LIB
5145c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5155c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
5165c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
51793eacc7ce0aad4314b4cb41a281f59ce54bb3286Jason Sams#endif
518eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    mRSC->mHal.funcs.allocation.markDirty(rsc, this);
5195c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
520326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
521afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
5229f70a4e63825afe9f786483722e1669b3625f5e9Stephen Hines    mHal.state.type->incRefs(ptr, ct, startOff);
523e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
524e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
525afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
5265c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    if (!mHal.state.hasReferences || !getIsScript()) {
5275c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk        return;
5285c4369a3a1b19eaeabb044af2cdeef05474f9069Alex Sakhartchouk    }
5299f70a4e63825afe9f786483722e1669b3625f5e9Stephen Hines    mHal.state.type->decRefs(ptr, ct, startOff);
530e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
531e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
532a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Samsvoid Allocation::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
53344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (rsc->mHal.funcs.allocation.updateCachedObject != nullptr) {
534a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams        rsc->mHal.funcs.allocation.updateCachedObject(rsc, this, (rs_allocation *)dstObj);
535a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    } else {
536a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams        *((const void **)dstObj) = this;
537a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams    }
538a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams}
539a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
540a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams
541c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsvoid Allocation::freeChildrenUnlocked () {
54261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this);
54361656a7c6fc13421679d0a1cdf8b5b861e286892Jason Sams    decRefs(ptr, mHal.state.type->getCellCount(), 0);
54461a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    mRSC->mHal.funcs.allocation.unlock1D(mRSC, this);
545c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
546c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
547c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Samsbool Allocation::freeChildren() {
548c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    if (mHal.state.hasReferences) {
549c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        incSysRef();
550c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        freeChildrenUnlocked();
551c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams        return decSysRef();
552c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    }
553c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams    return false;
554c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams}
555c7cec1e3577cc77a5a73d5bd5a82733b1b9936a1Jason Sams
556afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
55796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
55896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
559afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
560a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    uint32_t oldDimX = mHal.drvState.lod[0].dimX;
56196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
56296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
56396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
56496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
565c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
56696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
56761a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX);
56861a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.unlock1D(rsc, this);
56996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
570c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
571064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    setType(t.get());
572bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
57396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
57496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
575afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
576a273793e0958b0bde10f83725fbe778f3b92374fJason Sams    rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
57796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
57896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
579ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
580754746883bd46ec2fbdd23572cb6c90ab589346cMiao WangAllocation::NewBufferListener::NewBufferListener(uint32_t numAlloc) {
581754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    alloc = new const Allocation *[numAlloc];
582754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mNumAlloc = numAlloc;
583754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    for (uint32_t i = 0; i < numAlloc; i++) {
584754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        alloc[i] = nullptr;
585754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
586754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
587754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
588754746883bd46ec2fbdd23572cb6c90ab589346cMiao WangAllocation::NewBufferListener::~NewBufferListener() {
589754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    delete[] alloc;
590754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
591754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
592f0d7aa28bd4620030d9c54d983f607e3b0051df0Dan Stozavoid Allocation::NewBufferListener::onFrameAvailable(const BufferItem& /* item */) {
593754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    for (uint32_t i = 0; i < mNumAlloc; i++) {
594754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        if (alloc[i] != nullptr) {
595754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            intptr_t ip = (intptr_t)alloc[i];
596754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang            rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
597754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        }
598754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
599ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams}
600ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
601ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
602754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangvoid Allocation::setupGrallocConsumer(const Context *rsc, uint32_t numAlloc) {
603ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
604ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    // Configure GrallocConsumer to be in asynchronous mode
605754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (numAlloc > MAX_NUM_ALLOC || numAlloc <= 0) {
606754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
607754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return;
608754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
60903c155b6d20e99ee5c7abaae69a10c694106a83eDan Stoza    sp<IGraphicBufferConsumer> bc;
610754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    BufferQueue::createBufferQueue(&mGraphicBufferProducer, &bc);
611754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags, numAlloc);
612ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
613754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferListener = new NewBufferListener(numAlloc);
614ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mBufferListener->rsc = rsc;
615754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferListener->alloc[0] = this;
616754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mCurrentIdx = 0;
617754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferQueueInited = true;
618ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
619ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    mGrallocConsumer->setFrameAvailableListener(mBufferListener);
620754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang#endif
621754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
622754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
623754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangvoid * Allocation::getSurface(const Context *rsc) {
624754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang#ifndef RS_COMPATIBILITY_LIB
625754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    // Configure GrallocConsumer to be in asynchronous mode
626754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (!mBufferQueueInited) {
627754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        // This case is only used for single frame processing,
628754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        // since we will always call setupGrallocConsumer first in
629754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        // multi-frame case.
630754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        setupGrallocConsumer(rsc, 1);
631754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
632754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mGraphicBufferProducer->incStrong(nullptr);
633754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    return mGraphicBufferProducer.get();
634ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#else
63544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    return nullptr;
636ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
637ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    //return rsc->mHal.funcs.allocation.getSurface(rsc, this);
63841e373d91a60043afa0f9abd026218b49cbc1201Jason Sams}
63941e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
640754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangvoid Allocation::shareBufferQueue(const Context *rsc, const Allocation *alloc) {
641754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang#ifndef RS_COMPATIBILITY_LIB
642754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mGrallocConsumer = alloc->mGrallocConsumer;
643754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mCurrentIdx = mGrallocConsumer->getNextAvailableIdx(this);
644754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    if (mCurrentIdx >= mGrallocConsumer->mNumAlloc) {
645754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        rsc->setError(RS_ERROR_DRIVER, "Maximum allocations attached to a BufferQueue");
646754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        return;
647754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    }
648754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
649754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mGraphicBufferProducer = alloc->mGraphicBufferProducer;
650754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferListener = alloc->mBufferListener;
651754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferListener->alloc[mCurrentIdx] = this;
652754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    mBufferQueueInited = true;
653754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang#endif
654754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
655754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
656754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
6577ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
6587ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    ANativeWindow *nw = (ANativeWindow *)sur;
659733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    rsc->mHal.funcs.allocation.setSurface(rsc, this, nw);
6607ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
6617ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
6627ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioSend(const Context *rsc) {
6637ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    rsc->mHal.funcs.allocation.ioSend(rsc, this);
6647ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
6657ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
6667ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid Allocation::ioReceive(const Context *rsc) {
66744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *ptr = nullptr;
668ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    size_t stride = 0;
669ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#ifndef RS_COMPATIBILITY_LIB
670ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
671754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang        status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx);
672ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
673ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        if (ret == OK) {
674ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            rsc->mHal.funcs.allocation.ioReceive(rsc, this);
675ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else if (ret == BAD_VALUE) {
676ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            // No new frame, don't do anything
677ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        } else {
678ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams            rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
679ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        }
680ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams
681ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams    }
682ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams#endif
6837ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
6847ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
6854b3c34e6833e39bc89c2128002806b654b8e623dChris Wailesbool Allocation::hasSameDims(const Allocation *other) const {
6864b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    const Type *type0 = this->getType(),
6874b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes               *type1 = other->getType();
6884b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
6894b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    return (type0->getCellCount() == type1->getCellCount()) &&
6904b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimLOD()    == type1->getDimLOD())    &&
6914b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimFaces()  == type1->getDimFaces())  &&
6924b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimYuv()    == type1->getDimYuv())    &&
6934b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimX()      == type1->getDimX())      &&
6944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimY()      == type1->getDimY())      &&
6954b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes           (type0->getDimZ()      == type1->getDimZ());
6964b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
6974b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
6987ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
699326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
700565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
7016a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
702326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
703326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
704326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
705366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
706366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
707eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    a->sendDirty(rsc);
708366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
709366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
710366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
711a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
71261a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    Allocation *alloc = static_cast<Allocation *>(va);
71361a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams    rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc);
71439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
71539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
716807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
717807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    Allocation *a = static_cast<Allocation *>(va);
718807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const Type * t = a->getType();
719807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
7203bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams            t->getDimX(), t->getDimY(), data, sizeBytes, 0);
721837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
722837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
7234b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
724b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk                          uint32_t count, const void *data, size_t sizeBytes) {
725326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7264b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
7275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
729cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x,
730cc8cea7477352898921044483a6c803e25d02665Miao Wang                                 uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) {
7315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
732cc8cea7477352898921044483a6c803e25d02665Miao Wang    a->elementData(rsc, x, 0, 0, data, eoff, sizeBytes);
7335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
735cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid rsi_AllocationElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
736cc8cea7477352898921044483a6c803e25d02665Miao Wang                               uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) {
7375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
738cc8cea7477352898921044483a6c803e25d02665Miao Wang    a->elementData(rsc, x, y, z, data, eoff, sizeBytes);
739326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
740326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
7414b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
742358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                          uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
743326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
744358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
745326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
746326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
7473bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod,
7483bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                          uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) {
7493bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *a = static_cast<Allocation *>(va);
7503bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
7513bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams}
7523bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
7533bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
754807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) {
755e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
756807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    const Type * t = a->getType();
757cc8cea7477352898921044483a6c803e25d02665Miao Wang    if(t->getDimZ()) {
758cc8cea7477352898921044483a6c803e25d02665Miao Wang        a->read(rsc, 0, 0, 0, 0, t->getDimX(), t->getDimY(), t->getDimZ(),
759cc8cea7477352898921044483a6c803e25d02665Miao Wang                data, sizeBytes, 0);
760cc8cea7477352898921044483a6c803e25d02665Miao Wang    } else if(t->getDimY()) {
761807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
7623bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                t->getDimX(), t->getDimY(), data, sizeBytes, 0);
763807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    } else {
764807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes);
765807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
766807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
767e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
768e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
769afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
77096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
77196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
77296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
77396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
774afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
77596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
77696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
77796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
77896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
779c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
7808f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                       RsAllocationMipmapControl mipmaps,
781cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni                                       uint32_t usages, uintptr_t ptr) {
7828f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines    Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mipmaps, (void*)ptr);
783cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni    if (!alloc) {
784cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni        return nullptr;
785eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
786cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni    alloc->incUserRef();
787f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
788f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
789f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
79047a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao WangRsAllocation rsi_AllocationCreateStrided(Context *rsc, RsType vtype,
79147a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                         RsAllocationMipmapControl mipmaps,
79247a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                         uint32_t usages, uintptr_t ptr,
79347a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                         size_t requiredAlignment) {
79447a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    Allocation * alloc = Allocation::createAllocationStrided(rsc, static_cast<Type *>(vtype), usages, mipmaps,
79547a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang                                                             (void*)ptr, requiredAlignment);
79647a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    if (!alloc) {
79747a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang        return nullptr;
79847a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    }
79947a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    alloc->incUserRef();
80047a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang    return alloc;
80147a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang}
80247a5881b8f85d65c74f2471fe6261d4cdb3dce5eMiao Wang
803c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
8048f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                            RsAllocationMipmapControl mipmaps,
805cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni                                            const void *data, size_t sizeBytes, uint32_t usages) {
806366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
807f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
808cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
809f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
81044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (texAlloc == nullptr) {
811af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
81244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
813f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
814f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
815807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
81660c2796d821d9296003d4e5db025f8734d971a71Tim Murray                   t->getDimX(), t->getDimY(), data, sizeBytes, 0);
8178f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines    if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
81861a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
819f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
820f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
821eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
822f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
823f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
82484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
825c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
8268f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                                RsAllocationMipmapControl mipmaps,
827cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni                                                const void *data, size_t sizeBytes, uint32_t usages) {
828366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
82984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
83084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
83184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
83284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
833cc1b09fcd329392b0b4998963d2dfa83c6288173Yang Ni    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
83484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
83544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (texAlloc == nullptr) {
836af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Memory allocation failure");
83744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
83884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
83984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
8409f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
8419f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
8429f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
8439f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
84484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
845366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
8469f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
847807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams            texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face,
84860c2796d821d9296003d4e5db025f8734d971a71Tim Murray                           t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0);
8499f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
850366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
851366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
8529f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
853f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
854366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
8558f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines    if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
85661a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
85784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
85884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
859eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    texAlloc->sendDirty(rsc);
86084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
86184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
862099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
86374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsi_AllocationCopy2DRange(Context *rsc,
86474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation dstAlloc,
86574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff,
86674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstMip, uint32_t dstFace,
86774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t width, uint32_t height,
86874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocation srcAlloc,
86974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff,
87074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcMip, uint32_t srcFace) {
87174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *dst = static_cast<Allocation *>(dstAlloc);
87274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    Allocation *src= static_cast<Allocation *>(srcAlloc);
87374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk    rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip,
87474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)dstFace,
87574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           width, height,
87674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           src, srcXoff, srcYoff,srcMip,
87774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                                           (RsAllocationCubemapFace)srcFace);
87874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
87974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
8803bbc0fd40264ddae1592706d9023865b7b3e3195Jason Samsvoid rsi_AllocationCopy3DRange(Context *rsc,
8813bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               RsAllocation dstAlloc,
8823bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
8833bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t dstMip,
8843bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t width, uint32_t height, uint32_t depth,
8853bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               RsAllocation srcAlloc,
8863bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
8873bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                               uint32_t srcMip) {
8883bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *dst = static_cast<Allocation *>(dstAlloc);
8893bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    Allocation *src= static_cast<Allocation *>(srcAlloc);
8903bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip,
8913bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                                           width, height, depth,
8923bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams                                           src, srcXoff, srcYoff, srcZoff, srcMip);
8933bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams}
8943bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
895754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangvoid rsi_AllocationSetupBufferQueue(Context *rsc, RsAllocation valloc, uint32_t numAlloc) {
896754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    Allocation *alloc = static_cast<Allocation *>(valloc);
897754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    alloc->setupGrallocConsumer(rsc, numAlloc);
898754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
8993bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams
900733396b67724162844ea2785c7495115dc5ee8d8Jason Samsvoid * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) {
90141e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
902733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    void *s = alloc->getSurface(rsc);
903733396b67724162844ea2785c7495115dc5ee8d8Jason Sams    return s;
9043522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams}
9053522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams
906754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangvoid rsi_AllocationShareBufferQueue(Context *rsc, RsAllocation valloc1, RsAllocation valloc2) {
907754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    Allocation *alloc1 = static_cast<Allocation *>(valloc1);
908754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    Allocation *alloc2 = static_cast<Allocation *>(valloc2);
909754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    alloc1->shareBufferQueue(rsc, alloc2);
910754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang}
911754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang
9127ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
9137ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
9147ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->setSurface(rsc, sur);
9157ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
9167ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
9177ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Samsvoid rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) {
9187ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
9197ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioSend(rsc);
9207ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
9217ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
922754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wangint64_t rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) {
9237ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
9247ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams    alloc->ioReceive(rsc);
925754746883bd46ec2fbdd23572cb6c90ab589346cMiao Wang    return alloc->getTimeStamp();
9267ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams}
9277ac2a4dda4d20ca1f1b714e129a3a08f63178c18Jason Sams
928af7373fe53edba115746430553e8edfddd03ae9eStephen Hinesvoid *rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc,
929b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams                          uint32_t lod, RsAllocationCubemapFace face,
930b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams                          uint32_t z, uint32_t array, size_t *stride, size_t strideLen) {
931b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    Allocation *alloc = static_cast<Allocation *>(valloc);
9320e61af91ecd0d1276ddfc1c43bd61f6587e7026bTim Murray    rsAssert(strideLen == sizeof(size_t));
933b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
934af7373fe53edba115746430553e8edfddd03ae9eStephen Hines    return alloc->getPointer(rsc, lod, face, z, array, stride);
935b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams}
936b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
937509ea5c832a865bc9083d53f1f058377a689bab3Tim Murrayvoid rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
938509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray                          uint32_t count, void *data, size_t sizeBytes) {
939509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    Allocation *a = static_cast<Allocation *>(va);
9403bbc0fd40264ddae1592706d9023865b7b3e3195Jason Sams    rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes);
941509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray}
942509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray
943cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid rsi_AllocationElementRead(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z,
944cc8cea7477352898921044483a6c803e25d02665Miao Wang                                 uint32_t lod, void *data, size_t sizeBytes, size_t eoff) {
945cc8cea7477352898921044483a6c803e25d02665Miao Wang    Allocation *a = static_cast<Allocation *>(va);
946cc8cea7477352898921044483a6c803e25d02665Miao Wang    a->elementRead(rsc, x, y, z, data, eoff, sizeBytes);
947cc8cea7477352898921044483a6c803e25d02665Miao Wang}
948cc8cea7477352898921044483a6c803e25d02665Miao Wang
9497b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murrayvoid rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff,
9507b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray                          uint32_t lod, RsAllocationCubemapFace face, uint32_t w,
951358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                          uint32_t h, void *data, size_t sizeBytes, size_t stride) {
9527b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray    Allocation *a = static_cast<Allocation *>(va);
953358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
9547b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray}
9557b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray
956cc8cea7477352898921044483a6c803e25d02665Miao Wangvoid rsi_Allocation3DRead(Context *rsc, RsAllocation va,
957cc8cea7477352898921044483a6c803e25d02665Miao Wang                          uint32_t xoff, uint32_t yoff, uint32_t zoff,
958cc8cea7477352898921044483a6c803e25d02665Miao Wang                          uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
959cc8cea7477352898921044483a6c803e25d02665Miao Wang                          void *data, size_t sizeBytes, size_t stride) {
960cc8cea7477352898921044483a6c803e25d02665Miao Wang    Allocation *a = static_cast<Allocation *>(va);
961cc8cea7477352898921044483a6c803e25d02665Miao Wang    a->read(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride);
962cc8cea7477352898921044483a6c803e25d02665Miao Wang}
963cc8cea7477352898921044483a6c803e25d02665Miao Wang
964cfea6c13075aa255712e5a09a54eccbc84b0b122Jason SamsRsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) {
965cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
966cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
967cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    Allocation * alloc = Allocation::createAdapter(rsc,
968cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams            static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow));
969cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    if (!alloc) {
970cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams        return nullptr;
971cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    }
972cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    alloc->incUserRef();
973cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams    return alloc;
974cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams}
975cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
976cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Samsvoid rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) {
977442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams    Allocation *a = static_cast<Allocation *>(va);
978442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2Jason Sams    a->adapterOffset(rsc, offsets, len);
979cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams}
980cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
981cfea6c13075aa255712e5a09a54eccbc84b0b122Jason Sams
982c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
983c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
984