Allocation.cpp revision 44bef6fba6244292b751387f3d6c31cca96c28ad
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
23221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid * Allocation::getIDSafe() const {
24221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return getID();
25221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
26221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2769cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsvoid Allocation::updateCacheInfo(sp<const Type> t) {
28221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimX = t->getX();
29221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimY = t->getY();
30221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentDimZ = t->getZ();
31221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mCurrentCount = mCurrentDimX;
32221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mCurrentDimY > 1) {
33221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mCurrentCount *= mCurrentDimY;
34221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
35221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mCurrentDimZ > 1) {
36221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mCurrentCount *= mCurrentDimZ;
37221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
38221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
39221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
4084bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayAllocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
41baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray    BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0),
42baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray    mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) {
4369cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
44221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
45221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
46221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
47221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
48221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
49221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                   RS_ALLOCATION_USAGE_IO_INPUT |
5096267c2ff0133c20cc5643419a3ed3b1e75fe568Tim Murray                   RS_ALLOCATION_USAGE_IO_OUTPUT |
5196267c2ff0133c20cc5643419a3ed3b1e75fe568Tim Murray                   RS_ALLOCATION_USAGE_SHARED)) != 0) {
52221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        ALOGE("Unknown usage specified.");
53221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
54221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
553522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams    if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
56221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mWriteAllowed = false;
573522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams        if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
58221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                       RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
59221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                       RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
60221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            ALOGE("Invalid usage combination.");
61221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
62221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
63221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
64221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mType = t;
65221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mUsage = usage;
66221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
6744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (t != nullptr) {
68221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        updateCacheInfo(t);
69221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
7089daad6bae798779e57f252e9da4fe4e62337124Tim Murray
71221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
72221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
7389daad6bae798779e57f252e9da4fe4e62337124Tim Murray
7489daad6bae798779e57f252e9da4fe4e62337124Tim Murray
75221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt32() {
76221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
77221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
78221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
79221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
80221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("32 bit integer source does not match allocation type %i", dt);
81221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
82221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
83221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt16() {
84221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
85221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
86221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
87221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
88221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("16 bit integer source does not match allocation type %i", dt);
89221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
90221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
91221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsInt8() {
92221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
93221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
94221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
95221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
96221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("8 bit integer source does not match allocation type %i", dt);
97221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
98221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
99221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsFloat32() {
100221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
101221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (dt == RS_TYPE_FLOAT_32) {
102221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
103221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
104221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("32 bit float source does not match allocation type %i", dt);
105221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
106221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
107221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validateIsObject() {
108221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    RsDataType dt = mType->getElement()->getDataType();
109221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((dt == RS_TYPE_ELEMENT) ||
110221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_TYPE) ||
111221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_ALLOCATION) ||
112221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_SAMPLER) ||
113221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_SCRIPT) ||
114221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_MESH) ||
115221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
116221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_VERTEX) ||
117221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_RASTER) ||
118221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        (dt == RS_TYPE_PROGRAM_STORE)) {
119221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
120221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
121221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    ALOGE("Object source does not match allocation type %i", dt);
122221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
123221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
124221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::updateFromNative() {
125221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    BaseObj::updateFromNative();
126221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
127a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    const void *typeID = RS::dispatch->AllocationGetType(mRS->getContext(), getID());
12844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if(typeID != nullptr) {
12969cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams        sp<const Type> old = mType;
13069cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams        sp<Type> t = new Type((void *)typeID, mRS);
131221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        t->updateFromNative();
132221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        updateCacheInfo(t);
133221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        mType = t;
134221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
135221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
136221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
137221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::syncAll(RsAllocationUsageType srcLocation) {
138221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    switch (srcLocation) {
139221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_SCRIPT:
140221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
141221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
142221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
14310913a5c37ba119bef335320d3e8be25212c05adTim Murray    case RS_ALLOCATION_USAGE_SHARED:
144221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        break;
145221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    default:
14610913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Source must be exactly one usage type.");
14710913a5c37ba119bef335320d3e8be25212c05adTim Murray        return;
148221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
14910913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation));
150221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
151221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
152221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::ioSendOutput() {
1530b575de8ed0b628d84d256f5846500b0385979bdTim Murray#ifndef RS_COMPATIBILITY_LIB
154221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
15510913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only send buffer if IO_OUTPUT usage specified.");
15610913a5c37ba119bef335320d3e8be25212c05adTim Murray        return;
157221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
15810913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationIoSend(mRS->getContext(), getID()));
1590b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
160221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
161221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
162221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::ioGetInput() {
1630b575de8ed0b628d84d256f5846500b0385979bdTim Murray#ifndef RS_COMPATIBILITY_LIB
164221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
16510913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only send buffer if IO_OUTPUT usage specified.");
16610913a5c37ba119bef335320d3e8be25212c05adTim Murray        return;
167221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
16810913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationIoReceive(mRS->getContext(), getID()));
1690b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
170221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
171221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
172b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Samsvoid * Allocation::getPointer(size_t *stride) {
17344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *p = nullptr;
174b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    if (!(mUsage & RS_ALLOCATION_USAGE_SHARED)) {
175b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation does not support USAGE_SHARED.");
17644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
177b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
178b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
179b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    // FIXME: decide if lack of getPointer should cause compat mode
18044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (RS::dispatch->AllocationGetPointer == nullptr) {
181b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Can't use getPointer on older APIs");
18244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
183b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
184b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams
185b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    p = RS::dispatch->AllocationGetPointer(mRS->getContext(), getIDSafe(), 0,
186b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams                                           RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, stride);
187b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    if (mRS->getError() != RS_SUCCESS) {
188b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation lock failed");
18944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        p = nullptr;
190b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    }
191b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4Jason Sams    return p;
192221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
193221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
1940b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) {
19569cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
196221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if(count < 1) {
19710913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
198221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
199221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
200221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if((off + count) > mCurrentCount) {
201e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray        ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
20210913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
203221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return;
204221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
205221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
20610913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
20710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    count, data, count * mType->getElement()->getSizeBytes()));
208221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
209221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2100b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
211509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    if(count < 1) {
21210913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
213509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray        return;
214509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    }
215509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    if((off + count) > mCurrentCount) {
216e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray        ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
21710913a5c37ba119bef335320d3e8be25212c05adTim Murray        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
218509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray        return;
219509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray    }
2200b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
22110913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
22210913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    count, data, count * mType->getElement()->getSizeBytes()));
223509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray}
224509ea5c832a865bc9083d53f1f058377a689bab3Tim Murray
225a4cbc2b0cf0f6fbdb21e84a3e17585eda1885e3eTim Murrayvoid Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data,
226a4cbc2b0cf0f6fbdb21e84a3e17585eda1885e3eTim Murray                                 uint32_t dataOff) {
22769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
22810913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
22910913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         mSelectedLOD, mSelectedFace,
23010913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         count, 1, data->getIDSafe(), dataOff, 0,
23110913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         data->mSelectedLOD, data->mSelectedFace));
232221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
233221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2340b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DFrom(const void* data) {
2350b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray    copy1DRangeFrom(0, mCurrentCount, data);
2360b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray}
2370b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
2380b93e30c8c64fb2f985218adfaceff777f62a42fTim Murrayvoid Allocation::copy1DTo(void* data) {
2390b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray    copy1DRangeTo(0, mCurrentCount, data);
2400b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray}
2410b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
2420b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray
243221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
24444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mAdaptedAllocation != nullptr) {
245221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
246221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    } else {
247221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
24810913a5c37ba119bef335320d3e8be25212c05adTim Murray            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
249221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
250221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
251221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
252221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
253221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
2540b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray                                 const void *data) {
255221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    validate2DRange(xoff, yoff, w, h);
25610913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff,
25710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    yoff, mSelectedLOD, mSelectedFace,
25810913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w, h, data, w * h * mType->getElement()->getSizeBytes(),
25910913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * mType->getElement()->getSizeBytes()));
260221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
261221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
262221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
2630b93e30c8c64fb2f985218adfaceff777f62a42fTim Murray                                 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) {
264221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    validate2DRange(xoff, yoff, w, h);
26510913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
26610913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         mSelectedLOD, mSelectedFace,
26710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         w, h, data->getIDSafe(), dataXoff, dataYoff,
26810913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                         data->mSelectedLOD, data->mSelectedFace));
269221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
270221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
2717b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murrayvoid Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
2727b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray                               void* data) {
2737b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray    validate2DRange(xoff, yoff, w, h);
27410913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
27510913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    mSelectedLOD, mSelectedFace, w, h, data,
27610913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * h * mType->getElement()->getSizeBytes(),
27710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * mType->getElement()->getSizeBytes()));
2787b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray}
2797b3e3093f745134345dadf89498ad16e1f9c0e71Tim Murray
280358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
281358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                                   const void *data, size_t stride) {
282358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    validate2DRange(xoff, yoff, w, h);
28310913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff,
28410913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    mSelectedLOD, mSelectedFace, w, h, data,
28510913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * h * mType->getElement()->getSizeBytes(), stride));
286358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
287358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
288358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedFrom(const void* data, size_t stride) {
289358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    copy2DStridedFrom(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
290358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
291358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
292358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
293358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray                                 void *data, size_t stride) {
294358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    validate2DRange(xoff, yoff, w, h);
29510913a5c37ba119bef335320d3e8be25212c05adTim Murray    tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
29610913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    mSelectedLOD, mSelectedFace, w, h, data,
29710913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                    w * h * mType->getElement()->getSizeBytes(), stride));
298358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
299358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
300358747a3118301c5faeee73c98dd5f839bbfb54aTim Murrayvoid Allocation::copy2DStridedTo(void* data, size_t stride) {
301358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray    copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
302358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray}
303358747a3118301c5faeee73c98dd5f839bbfb54aTim Murray
3049d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::validate3DRange(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
3059d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 uint32_t h, uint32_t d) {
30644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mAdaptedAllocation != nullptr) {
3079d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3089d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    } else {
3099d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray        if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
3109d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
3119d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray        }
3129d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    }
3139d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
3149d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3159d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
3169d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 uint32_t h, uint32_t d, const void* data) {
3179d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    validate3DRange(xoff, yoff, zoff, w, h, d);
3189d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    tryDispatch(mRS, RS::dispatch->Allocation3DData(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
3199d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                    mSelectedLOD, w, h, d, data,
3209d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                    w * h * d * mType->getElement()->getSizeBytes(),
3219d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                    w * mType->getElement()->getSizeBytes()));
3229d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
3239d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3249d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murrayvoid Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w, uint32_t h, uint32_t d,
3259d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff, uint32_t dataZoff) {
3269d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    validate3DRange(xoff, yoff, zoff, dataXoff, dataYoff, dataZoff);
3279d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray    tryDispatch(mRS, RS::dispatch->AllocationCopy3DRange(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
3289d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                         mSelectedLOD, w, h, d, data->getIDSafe(),
3299d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray                                                         dataXoff, dataYoff, dataZoff, data->mSelectedLOD));
3309d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray}
3319d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
3329d24ae621bdfdaf09406b099a2ae055e33d1089aTim Murray
33389daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
3348f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                    RsAllocationMipmapControl mipmaps, uint32_t usage) {
33510913a5c37ba119bef335320d3e8be25212c05adTim Murray    void *id = 0;
33610913a5c37ba119bef335320d3e8be25212c05adTim Murray    if (rs->getError() == RS_SUCCESS) {
3378f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines        id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage, 0);
33810913a5c37ba119bef335320d3e8be25212c05adTim Murray    }
339221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (id == 0) {
34010913a5c37ba119bef335320d3e8be25212c05adTim Murray        rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
34144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
342221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
343221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return new Allocation(id, rs, type, usage);
344221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
345221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
34689daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
3478f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines                                    RsAllocationMipmapControl mipmaps, uint32_t usage,
34889daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    void *pointer) {
34910913a5c37ba119bef335320d3e8be25212c05adTim Murray    void *id = 0;
35010913a5c37ba119bef335320d3e8be25212c05adTim Murray    if (rs->getError() == RS_SUCCESS) {
3518f615d682f9e7e2cd4de2e4478e0e76fc359922cStephen Hines        id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage,
35210913a5c37ba119bef335320d3e8be25212c05adTim Murray                                                 (uintptr_t)pointer);
35310913a5c37ba119bef335320d3e8be25212c05adTim Murray    }
354221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (id == 0) {
35510913a5c37ba119bef335320d3e8be25212c05adTim Murray        rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
35644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
357221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
358221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return new Allocation(id, rs, type, usage);
359221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
360221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
36189daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
36289daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    uint32_t usage) {
363221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
364221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
365221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
36689daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
36789daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                    size_t count, uint32_t usage) {
368221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    Type::Builder b(rs, e);
369221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    b.setX(count);
37069cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams    sp<const Type> t = b.create();
371221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
372684726cbbd177ee4ee9000e9422058547acd237fTim Murray    return createTyped(rs, t, usage);
373684726cbbd177ee4ee9000e9422058547acd237fTim Murray}
374684726cbbd177ee4ee9000e9422058547acd237fTim Murray
37589daad6bae798779e57f252e9da4fe4e62337124Tim Murraysp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e,
37689daad6bae798779e57f252e9da4fe4e62337124Tim Murray                                      size_t x, size_t y, uint32_t usage) {
377684726cbbd177ee4ee9000e9422058547acd237fTim Murray    Type::Builder b(rs, e);
378684726cbbd177ee4ee9000e9422058547acd237fTim Murray    b.setX(x);
379684726cbbd177ee4ee9000e9422058547acd237fTim Murray    b.setY(y);
380684726cbbd177ee4ee9000e9422058547acd237fTim Murray    sp<const Type> t = b.create();
381684726cbbd177ee4ee9000e9422058547acd237fTim Murray
382684726cbbd177ee4ee9000e9422058547acd237fTim Murray    return createTyped(rs, t, usage);
383221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
384