1221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams/*
210913a5c37ba119bef335320d3e8be25212c05adTim Murray * Copyright (C) 2013 The Android Open Source Project
3221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
4221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * you may not use this file except in compliance with the License.
6221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * You may obtain a copy of the License at
7221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
8221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
10221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * Unless required by applicable law or agreed to in writing, software
11221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * See the License for the specific language governing permissions and
14221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * limitations under the License.
15221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams */
16221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
17221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "RenderScript.h"
1810913a5c37ba119bef335320d3e8be25212c05adTim Murray#include "rsCppInternal.h"
19221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2069cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsusing namespace android;
219eb7f4b90120ebe4be74343856e86b46495f72dfTim Murrayusing namespace RSC;
22221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
24221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid * Allocation::getIDSafe() const {
25221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return getID();
26221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
27221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2869cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsvoid Allocation::updateCacheInfo(sp<const Type> t) {
29221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimX = t->getX();
30221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimY = t->getY();
31221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimZ = t->getZ();
32221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentCount = mCurrentDimX;
33221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mCurrentDimY > 1) {
34221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mCurrentCount *= mCurrentDimY;
35221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
36221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mCurrentDimZ > 1) {
37221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mCurrentCount *= mCurrentDimZ;
38221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
39221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
40221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
4184bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayAllocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
42baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray    BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0),
43baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray    mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) {
4469cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
45221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
46221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
47221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
48221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
49221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
50221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_IO_INPUT |
5196267c2ff0133c20cc5643419a3ed3b1e75fe568Tim Murray                   RS_ALLOCATION_USAGE_IO_OUTPUT |
52cc169dee42a552746f8896c293143dfaab326263Jason Sams                   RS_ALLOCATION_USAGE_OEM |
5396267c2ff0133c20cc5643419a3ed3b1e75fe568Tim Murray                   RS_ALLOCATION_USAGE_SHARED)) != 0) {
54221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        ALOGE("Unknown usage specified.");
55221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
56221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
573522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams    if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
58221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mWriteAllowed = false;
593522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams        if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
60221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                       RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
61221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                       RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
62221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            ALOGE("Invalid usage combination.");
63221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
64221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
65221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
66221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mType = t;
67221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mUsage = usage;
68e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    mAutoPadding = false;
6944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (t != nullptr) {
70221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        updateCacheInfo(t);
71221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
7289daad6bae798779e57f252e9da4fe4e62337124Tim Murray
73221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
74221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
7589daad6bae798779e57f252e9da4fe4e62337124Tim Murray
76e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangvoid Allocation::validateIsInt64() {
77e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    RsDataType dt = mType->getElement()->getDataType();
78e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if ((dt == RS_TYPE_SIGNED_64) || (dt == RS_TYPE_UNSIGNED_64)) {
79e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        return;
80e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
81e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    ALOGE("64 bit integer source does not match allocation type %i", dt);
82e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang}
8389daad6bae798779e57f252e9da4fe4e62337124Tim Murray
84221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt32() {
85221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
86221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
87221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
88221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
89221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("32 bit integer source does not match allocation type %i", dt);
90221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
91221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
92221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt16() {
93221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
94221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
95221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
96221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
97221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("16 bit integer source does not match allocation type %i", dt);
98221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
99221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
100221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt8() {
101221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
102221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
103221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
104221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
105221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("8 bit integer source does not match allocation type %i", dt);
106221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
107221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
108221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsFloat32() {
109221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
110221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (dt == RS_TYPE_FLOAT_32) {
111221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
112221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
113221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("32 bit float source does not match allocation type %i", dt);
114221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
115221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
116e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangvoid Allocation::validateIsFloat64() {
117e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    RsDataType dt = mType->getElement()->getDataType();
118e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (dt == RS_TYPE_FLOAT_64) {
119e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        return;
120e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
121e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    ALOGE("64 bit float source does not match allocation type %i", dt);
122e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang}
123e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang
124221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsObject() {
125221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
126221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_ELEMENT) ||
127221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_TYPE) ||
128221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_ALLOCATION) ||
129221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_SAMPLER) ||
130221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_SCRIPT) ||
131221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_MESH) ||
132221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
133221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_VERTEX) ||
134221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_RASTER) ||
135221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_STORE)) {
136221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
137221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
138221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("Object source does not match allocation type %i", dt);
139221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
140221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
141221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::updateFromNative() {
142221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    BaseObj::updateFromNative();
143221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
144a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    const void *typeID = RS::dispatch->AllocationGetType(mRS->getContext(), getID());
14544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if(typeID != nullptr) {
14669cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams        sp<const Type> old = mType;
14769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams        sp<Type> t = new Type((void *)typeID, mRS);
148221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        t->updateFromNative();
149221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        updateCacheInfo(t);
150221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mType = t;
151221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
152221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
153221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
154221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::syncAll(RsAllocationUsageType srcLocation) {
155221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    switch (srcLocation) {
156221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_SCRIPT:
157221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
158221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
159221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
16010913a5c37ba119bef335320d3e8be25212c05adTim Murray    case RS_ALLOCATION_USAGE_SHARED:
161221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        break;
162221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    default:
16310913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Source must be exactly one usage type.");
16410913a5c37ba119bef335320d3e8be25212c05adTim Murray        return;
165221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
16610913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation));
167221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
168221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
169b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Samsvoid * Allocation::getPointer(size_t *stride) {
17044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *p = nullptr;
171b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    if (!(mUsage & RS_ALLOCATION_USAGE_SHARED)) {
172b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation does not support USAGE_SHARED.");
17344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
174b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
175b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
176b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    // FIXME: decide if lack of getPointer should cause compat mode
17744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (RS::dispatch->AllocationGetPointer == nullptr) {
178b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Can't use getPointer on older APIs");
17944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
180b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
181b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
182b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    p = RS::dispatch->AllocationGetPointer(mRS->getContext(), getIDSafe(), 0,
18394280f817b502caf0b4e40cbcbe300f5178b7473Miao Wang                                           RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, stride, sizeof(size_t));
184b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    if (mRS->getError() != RS_SUCCESS) {
185b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation lock failed");
18644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        p = nullptr;
187b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
188b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    return p;
189221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
190221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
191e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang// ---------------------------------------------------------------------------
192e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang//Functions needed for autopadding & unpadding
193e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangstatic void copyWithPadding(void* ptr, const void* srcPtr, int mSize, int count) {
194e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    int sizeBytesPad = mSize * 4;
195e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    int sizeBytes = mSize * 3;
196e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    uint8_t *dst = static_cast<uint8_t *>(ptr);
197e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    const uint8_t *src = static_cast<const uint8_t *>(srcPtr);
198e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    for (int i = 0; i < count; i++) {
199e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        memcpy(dst, src, sizeBytes);
200e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        dst += sizeBytesPad;
201e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        src += sizeBytes;
202e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
203e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang}
204e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang
205e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangstatic void copyWithUnPadding(void* ptr, const void* srcPtr, int mSize, int count) {
206e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    int sizeBytesPad = mSize * 4;
207e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    int sizeBytes = mSize * 3;
208e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    uint8_t *dst = static_cast<uint8_t *>(ptr);
209e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    const uint8_t *src = static_cast<const uint8_t *>(srcPtr);
210e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    for (int i = 0; i < count; i++) {
211e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        memcpy(dst, src, sizeBytes);
212e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        dst += sizeBytes;
213e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        src += sizeBytesPad;
214e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
215e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang}
216e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang// ---------------------------------------------------------------------------
217e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang
2180b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) {
21969cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
220221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if(count < 1) {
22110913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
222221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
223221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
224221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if((off + count) > mCurrentCount) {
225e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray        ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
22610913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
227221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
228221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
229e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
230e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
231e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * count);
232e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithPadding(ptr, data, eSize / 4, count);
233e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
234e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        count, ptr, count * mType->getElement()->getSizeBytes()));
235e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
236e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
237e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
238e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        count, data, count * mType->getElement()->getSizeBytes()));
239e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
240221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
241221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2420b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
243509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    if(count < 1) {
24410913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
245509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray        return;
246509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    }
247509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    if((off + count) > mCurrentCount) {
248e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray        ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
24910913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
250509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray        return;
251509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    }
252e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
253e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
254e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * count);
255e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
256e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        count, ptr, count * mType->getElement()->getSizeBytes()));
257e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithUnPadding(data, ptr, eSize / 4, count);
258e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
259e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
260e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
261e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        count, data, count * mType->getElement()->getSizeBytes()));
262e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
263509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray}
264509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray
265a4cbc2b0cf0f6fbdb21e84a3e17585eda1885e3eTim Murrayvoid Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data,
266a4cbc2b0cf0f6fbdb21e84a3e17585eda1885e3eTim Murray                                 uint32_t dataOff) {
26769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
26810913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
26910913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         mSelectedLOD, mSelectedFace,
27010913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         count, 1, data->getIDSafe(), dataOff, 0,
27110913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         data->mSelectedLOD, data->mSelectedFace));
272221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
273221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2740b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DFrom(const void* data) {
2750b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray    copy1DRangeFrom(0, mCurrentCount, data);
2760b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray}
2770b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
2780b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DTo(void* data) {
2790b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray    copy1DRangeTo(0, mCurrentCount, data);
2800b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray}
2810b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
2820b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
283221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
28444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mAdaptedAllocation != nullptr) {
285221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
286221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    } else {
287221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
28810913a5c37ba119bef335320d3e8be25212c05adTim Murray            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
289221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
290221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
291221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
292221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
293221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
2940b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray                                 const void *data) {
295221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    validate2DRange(xoff, yoff, w, h);
296e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
297e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
298e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * w * h);
299e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithPadding(ptr, data, eSize / 4, w * h);
300e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff,
301e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        yoff, mSelectedLOD, mSelectedFace,
302e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w, h, ptr, w * h * mType->getElement()->getSizeBytes(),
303e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
304e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
305e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
306e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff,
307e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        yoff, mSelectedLOD, mSelectedFace,
308e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w, h, data, w * h * mType->getElement()->getSizeBytes(),
309e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
310e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
311221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
312221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
313221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
3140b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray                                 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) {
315221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    validate2DRange(xoff, yoff, w, h);
31610913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
31710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         mSelectedLOD, mSelectedFace,
31810913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         w, h, data->getIDSafe(), dataXoff, dataYoff,
31910913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         data->mSelectedLOD, data->mSelectedFace));
320221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
321221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
3227b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murrayvoid Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
3237b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray                               void* data) {
3247b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray    validate2DRange(xoff, yoff, w, h);
325e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
326e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
327e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * w * h);
328e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
329e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, mSelectedFace, w, h, ptr,
330e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * mType->getElement()->getSizeBytes(),
331e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
332e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithUnPadding(data, ptr, eSize / 4, w * h);
333e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
334e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
335e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
336e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, mSelectedFace, w, h, data,
337e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * mType->getElement()->getSizeBytes(),
338e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
339e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
3407b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray}
3417b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray
342358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
343358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                                   const void *data, size_t stride) {
344358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    validate2DRange(xoff, yoff, w, h);
34510913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff,
34610913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    mSelectedLOD, mSelectedFace, w, h, data,
34710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * h * mType->getElement()->getSizeBytes(), stride));
348358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
349358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
350358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedFrom(const void* data, size_t stride) {
351358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    copy2DStridedFrom(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
352358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
353358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
354358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
355358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                                 void *data, size_t stride) {
356358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    validate2DRange(xoff, yoff, w, h);
35710913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
35810913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    mSelectedLOD, mSelectedFace, w, h, data,
35910913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * h * mType->getElement()->getSizeBytes(), stride));
360358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
361358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
362358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedTo(void* data, size_t stride) {
363358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
364358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
365358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
3669d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::validate3DRange(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
3679d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 uint32_t h, uint32_t d) {
36844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mAdaptedAllocation != nullptr) {
3699d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3709d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    } else {
3719d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray        if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
3729d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
3739d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray        }
3749d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    }
3759d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
3769d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3779d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
3789d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 uint32_t h, uint32_t d, const void* data) {
3799d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    validate3DRange(xoff, yoff, zoff, w, h, d);
380e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
381e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
382e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * w * h * d);
383e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithPadding(ptr, data, eSize / 4, w * h * d);
384e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation3DData(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
385e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, w, h, d, ptr,
386e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * d * mType->getElement()->getSizeBytes(),
387e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
388e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
389e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
390e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation3DData(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
391e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, w, h, d, data,
392e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * d * mType->getElement()->getSizeBytes(),
393e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
394e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
3959d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
3969d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3979d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w, uint32_t h, uint32_t d,
3989d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff, uint32_t dataZoff) {
399e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    validate3DRange(xoff, yoff, zoff, w, h, d);
4009d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy3DRange(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
4019d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                         mSelectedLOD, w, h, d, data->getIDSafe(),
4029d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                         dataXoff, dataYoff, dataZoff, data->mSelectedLOD));
4039d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
4049d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
405e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangvoid Allocation::copy3DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
406e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                 uint32_t h, uint32_t d, void* data) {
407e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    validate3DRange(xoff, yoff, zoff, w, h, d);
408e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
409e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        size_t eSize = mType->getElement()->getSizeBytes();
410e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        void *ptr = malloc(eSize * w * h * d);
411e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation3DRead(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
412e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, w, h, d, ptr,
413e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * d * mType->getElement()->getSizeBytes(),
414e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
415e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        copyWithUnPadding(data, ptr, eSize / 4, w * h * d);
416e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        free(ptr);
417e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    } else {
418e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        tryDispatch(mRS, RS::dispatch->Allocation3DRead(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
419e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        mSelectedLOD, w, h, d, data,
420e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * h * d * mType->getElement()->getSizeBytes(),
421e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang                                                        w * mType->getElement()->getSizeBytes()));
422e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    }
423e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang}
4249d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
42589daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
4268f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                    RsAllocationMipmapControl mipmaps, uint32_t usage) {
42710913a5c37ba119bef335320d3e8be25212c05adTim Murray    void *id = 0;
42810913a5c37ba119bef335320d3e8be25212c05adTim Murray    if (rs->getError() == RS_SUCCESS) {
4298f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines        id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage, 0);
43010913a5c37ba119bef335320d3e8be25212c05adTim Murray    }
431221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (id == 0) {
43210913a5c37ba119bef335320d3e8be25212c05adTim Murray        rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
43344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
434221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
435221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return new Allocation(id, rs, type, usage);
436221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
437221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
43889daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
4398f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                    RsAllocationMipmapControl mipmaps, uint32_t usage,
44089daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    void *pointer) {
44110913a5c37ba119bef335320d3e8be25212c05adTim Murray    void *id = 0;
44210913a5c37ba119bef335320d3e8be25212c05adTim Murray    if (rs->getError() == RS_SUCCESS) {
4438f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines        id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage,
44410913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                 (uintptr_t)pointer);
44510913a5c37ba119bef335320d3e8be25212c05adTim Murray    }
446221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (id == 0) {
44710913a5c37ba119bef335320d3e8be25212c05adTim Murray        rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
44844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
449221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
450221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return new Allocation(id, rs, type, usage);
451221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
452221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
45389daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
45489daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    uint32_t usage) {
455221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
456221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
457221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
45889daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
45989daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    size_t count, uint32_t usage) {
460221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    Type::Builder b(rs, e);
461221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    b.setX(count);
46269cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams    sp<const Type> t = b.create();
463221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
464684726cbbd177ee4ee9000e9422058547acd237fTim Murray    return createTyped(rs, t, usage);
465684726cbbd177ee4ee9000e9422058547acd237fTim Murray}
466684726cbbd177ee4ee9000e9422058547acd237fTim Murray
46789daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
46889daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                      size_t x, size_t y, uint32_t usage) {
469684726cbbd177ee4ee9000e9422058547acd237fTim Murray    Type::Builder b(rs, e);
470684726cbbd177ee4ee9000e9422058547acd237fTim Murray    b.setX(x);
471684726cbbd177ee4ee9000e9422058547acd237fTim Murray    b.setY(y);
472684726cbbd177ee4ee9000e9422058547acd237fTim Murray    sp<const Type> t = b.create();
473684726cbbd177ee4ee9000e9422058547acd237fTim Murray
474684726cbbd177ee4ee9000e9422058547acd237fTim Murray    return createTyped(rs, t, usage);
475221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
47609d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
47709d2dd26af70a16de928e7450ef500a61c5b810aMiao Wangvoid Allocation::ioSendOutput() {
47809d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#ifndef RS_COMPATIBILITY_LIB
47909d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
48009d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only send buffer if IO_OUTPUT usage specified.");
48109d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        return;
48209d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    }
48309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    tryDispatch(mRS, RS::dispatch->AllocationIoSend(mRS->getContext(), getID()));
48409d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#endif
48509d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang}
48609d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
48709d2dd26af70a16de928e7450ef500a61c5b810aMiao Wangvoid Allocation::ioGetInput() {
48809d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#ifndef RS_COMPATIBILITY_LIB
48909d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
49009d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only get buffer if IO_INPUT usage specified.");
49109d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        return;
49209d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    }
49309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    tryDispatch(mRS, RS::dispatch->AllocationIoReceive(mRS->getContext(), getID()));
49409d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#endif
49509d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang}
49609d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
49709d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
49809d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#include <gui/Surface.h>
49909d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
50009d2dd26af70a16de928e7450ef500a61c5b810aMiao WangRSC::sp<Surface> Allocation::getSurface() {
50109d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
50209d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only get Surface if IO_INPUT usage specified.");
50309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        return nullptr;
50409d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    }
50509d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    IGraphicBufferProducer *v = (IGraphicBufferProducer *)RS::dispatch->AllocationGetSurface(mRS->getContext(),
50609d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang                                                                                             getID());
50709d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    android::sp<IGraphicBufferProducer> bp = v;
50809d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    v->decStrong(nullptr);
50909d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
51009d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    return new Surface(bp, true);;
51109d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang}
51209d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
51309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wangvoid Allocation::setSurface(RSC::sp<Surface> s) {
51409d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
51509d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only set Surface if IO_OUTPUT usage specified.");
51609d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang        return;
51709d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    }
51809d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang    tryDispatch(mRS, RS::dispatch->AllocationSetSurface(mRS->getContext(), getID(),
51909d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang                                                        static_cast<ANativeWindow *>(s.get())));
52009d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang}
52109d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
52209d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang#endif
52309d2dd26af70a16de928e7450ef500a61c5b810aMiao Wang
524