rsAllocation.cpp revision bad807405b2b9764372af1ad24bcfd4fb1f33d8e
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include "rsContext.h"
1877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
191aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/gl.h>
207fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams#include <GLES2/gl2.h>
211aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/glext.h>
2277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
2339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
25326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
26326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
27a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
28a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk                       RsAllocationMipmapControl mc)
29a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
30fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
31fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
34366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
35b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    allocScriptMemory();
36bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.type->getElement()->getHasReferences()) {
37bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes());
3810e5e570bab66a6cd543c857b26c576795eb240fJason Sams    }
39bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!mHal.state.mallocPtr) {
40fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        LOGE("Allocation::Allocation, alloc failure");
41fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
42fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
43fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
44fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
45afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::init(Context *rsc, const Type *type) {
46bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    memset(&mHal, 0, sizeof(mHal));
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
48326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuWrite = false;
50326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuRead = false;
51326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuWrite = false;
52326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuRead = false;
53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
54326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mReadWriteRatio = 0;
55326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mUpdateSize = 0;
56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mTextureID = 0;
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mBufferID = 0;
59cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = false;
60326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
61fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = NULL;
62fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = NULL;
63fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
64bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type.set(type);
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
67fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
68bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
69bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Type *type = mHal.state.type.get();
70bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionX = type->getDimX();
71bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionY = type->getDimY();
72bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionZ = type->getDimZ();
73bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
74bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
75bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
76bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
77326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
78326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
79afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
80fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (mUserBitmapCallback != NULL) {
81fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
82bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.mallocPtr = NULL;
83fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
84b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    freeScriptMemory();
8577d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
86e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mBufferID) {
87e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        // Causes a SW crash....
88e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //LOGV(" mBufferID %i", mBufferID);
89e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //glDeleteBuffers(1, &mBufferID);
90e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //mBufferID = 0;
91e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
92e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mTextureID) {
93e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        glDeleteTextures(1, &mTextureID);
94e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        mTextureID = 0;
95e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
9677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
97326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
99afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuWritable(bool) {
100326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
101326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
102afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuWritable(bool) {
103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
105afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuReadable(bool) {
106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
108afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuReadable(bool) {
109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
111afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Allocation::fixAllocation() {
112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return false;
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
115b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::deferedUploadToTexture(const Context *rsc) {
116bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
117cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
118cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
119cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
12084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukuint32_t Allocation::getGLTarget() const {
12177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
122ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
123bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        if (mHal.state.type->getDimFaces()) {
12484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_CUBE_MAP;
12584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        } else {
12684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_2D;
12784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
12884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
129ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
13084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return GL_ARRAY_BUFFER;
13184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
13277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
13384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return 0;
13484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
13584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
136b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::allocScriptMemory() {
137bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.mallocPtr);
138bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes());
139b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
140b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
141b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::freeScriptMemory() {
142bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mallocPtr) {
143bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        free(mHal.state.mallocPtr);
144bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.mallocPtr = NULL;
145b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
146b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
147b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
148b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
149366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
150366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
151366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
152ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
153366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToTexture(rsc);
154366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
155ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
156366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToBufferObject(rsc);
157366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
158366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
159366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUploadDefered = false;
160366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
16184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
162afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToTexture(const Context *rsc) {
16377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
164bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
165bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
166bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
167565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
168565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    if (!type || !format) {
169565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        return;
170565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
171565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
172bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!mHal.state.mallocPtr) {
173b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        return;
174b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
175b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
17639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool isFirstUpload = false;
17739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
178326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mTextureID) {
179326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenTextures(1, &mTextureID);
18013e2634a71a30d289ed8d821aef61c7d1687460eJason Sams
18113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        if (!mTextureID) {
18213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // This should not happen, however, its likely the cause of the
18313e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // white sqare bug.
18413e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
18513e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            LOGE("Upload to texture failed to gen mTextureID");
18613e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            rsc->dumpDebug();
187cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            mUploadDefered = true;
188cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            return;
18913e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        }
19039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        isFirstUpload = true;
191326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
19284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
193bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    upload2DTexture(isFirstUpload);
19484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
195bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
196b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        freeScriptMemory();
197b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
198b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
19984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    rsc->checkError("Allocation::uploadToTexture");
20077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
20184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
20284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
20377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
204bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Samsconst static GLenum gFaceOrder[] = {
205bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
206bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
207bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
208bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
209bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
210bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
211bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams};
21277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
213bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams
214236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
215236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                                 uint32_t lod, RsAllocationCubemapFace face,
216236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                                 uint32_t w, uint32_t h) {
21777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
218bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
219bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
220236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    GLenum target = (GLenum)getGLTarget();
221185b8b01f417488e2fbf6e6c00dfbd3d1d43d98aJason Sams    rsAssert(mTextureID);
222236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    glBindTexture(target, mTextureID);
223236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
224bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GLenum t = GL_TEXTURE_2D;
225bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasFaces) {
226bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams        t = gFaceOrder[face];
227b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
228bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
22977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
23084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
2317fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
232bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Samsvoid Allocation::upload2DTexture(bool isFirstUpload) {
23377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
234bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
235bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
23684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
237b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    GLenum target = (GLenum)getGLTarget();
238b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glBindTexture(target, mTextureID);
239b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
240b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
241bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    uint32_t faceCount = 1;
242bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasFaces) {
243bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams        faceCount = 6;
244bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    }
24584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
246bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    for (uint32_t face = 0; face < faceCount; face ++) {
247bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) {
248bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr;
249bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
25084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
251bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams            GLenum t = GL_TEXTURE_2D;
252bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            if (mHal.state.hasFaces) {
253bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                t = gFaceOrder[face];
254bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams            }
25584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
25684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            if (isFirstUpload) {
257bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                glTexImage2D(t, lod, format,
258bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                             mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
259bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                             0, format, type, p);
26084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            } else {
261bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                glTexSubImage2D(t, lod, 0, 0,
262bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                                mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
263bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                                format, type, p);
26484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
26584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
26684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
267b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams
268bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
269b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams        glGenerateMipmap(target);
270b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
27177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
272326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
273326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
274afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToBufferObject(const Context *rsc) {
275bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
276cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
277cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
278cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
279afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToBufferObject(const Context *rsc) {
28077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
281bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.type->getDimY());
282bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.type->getDimZ());
283326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
284bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
285cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
286326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mBufferID) {
287326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenBuffers(1, &mBufferID);
288326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
289cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!mBufferID) {
290cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        LOGE("Upload to buffer object failed");
291cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
292cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
293cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
29484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
29584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, mBufferID);
296bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
29784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, 0);
298c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToBufferObject");
29977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
300326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
301326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
302366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::uploadCheck(Context *rsc) {
303cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (mUploadDefered) {
304366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
305cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
306cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
307cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
308afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
309bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes());
310e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
311e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
3124b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
3134b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                         uint32_t count, const void *data, uint32_t sizeBytes) {
314bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.type->getElementSizeBytes();
315bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
316326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    ptr += eSize * xoff;
3179397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = count * eSize;
3189397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
3199397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
3209397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
321bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
3229397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3239397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
324e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
325bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasReferences) {
326e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, count);
327e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(ptr, count);
328e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
329e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
3309397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(ptr, data, size);
3315c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
332cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
333326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
334326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3354b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
336afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
337bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
338326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t lineSize = eSize * w;
339bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t destW = mHal.state.dimensionX;
340326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
341a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    //LOGE("data2d %p,  %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
3429397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
343a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    if ((lineSize * h) != sizeBytes) {
344a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        LOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
3459397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
3469397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3479397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
3489397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
349bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mallocPtr) {
350a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        const uint8_t *src = static_cast<const uint8_t *>(data);
351bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr);
352bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
353a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams
354a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        //LOGE("            %p  %p  %i  ", dst, src, eSize);
355a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        for (uint32_t line=yoff; line < (yoff+h); line++) {
356bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            if (mHal.state.hasReferences) {
357a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams                incRefs(src, w);
358a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams                decRefs(dst, w);
359a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            }
360a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            memcpy(dst, src, lineSize);
361a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            src += lineSize;
362a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            dst += destW * eSize;
363e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
364a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        sendDirty();
365a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        mUploadDefered = true;
366a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    } else {
367236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams        update2DTexture(data, xoff, yoff, lod, face, w, h);
368326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
369326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
370326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
371236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
372236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t lod, RsAllocationCubemapFace face,
373236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
374326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
375326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3764b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, const void *data,
377afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
378bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
379bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
3805f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * x;
3815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
382bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
3835f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
3845f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3855f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3865f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3875f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
388bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
3895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
3905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3925f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3935f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
394bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
395bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
3965f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3975f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
398099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
3995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4005f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4015f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4025f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4045f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4055f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4075f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4125f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4134b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
414afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
415bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
416bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
417bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += eSize * (x + y * mHal.state.dimensionX);
4185f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
419bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
4205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
425bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (y >= mHal.state.dimensionY) {
4265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
431bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
4325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
4335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
4345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
437bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
438bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
4395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
441099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
4425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4485f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4495f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4505f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4535f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
456afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
45777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
458fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
45977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
4605c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
4615c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
462afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
46377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
4645c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
4655c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
4665c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
4675c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
4685c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
4695c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
4705c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
47177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
4725c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
473326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
474afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
475c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
476c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
477c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
478c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
479bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.type.get()) {
480bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV(s.string());
481c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
482c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
483c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
484bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams          prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
485c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
486ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
487bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams          prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID);
488c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
489326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
490afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
491fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
492fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
493fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
494fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
495fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
496fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
497fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
498fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
499bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type->serialize(stream);
500fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
501bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t dataSize = mHal.state.type->getSizeBytes();
502fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
503fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
504fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
505bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    stream->addByteArray(mHal.state.mallocPtr, dataSize);
506fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
507fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
508afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
509fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
510b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
511afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
512fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
513fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
514fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
515fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
516fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
517fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
518fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
519fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
520afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
521fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
522fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
523fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
524fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
525fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
526fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
527afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
528fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
529225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
530fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
531fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
532fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
533ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
534fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
535fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
5364b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    uint32_t count = dataSize / type->getElementSizeBytes();
5374b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams
538fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
5394b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
540e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
541fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
542fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
543fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
544fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
545afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::sendDirty() const {
54677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
5475c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5485c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
5495c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
55077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
5515c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
552326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
553afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
554e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
555bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
556e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
557e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
55896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
559e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
560e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
561e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
562e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
563e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
564e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
565e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
566afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
567e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
568bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
569e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
570e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
57196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
572e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
573e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
574e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
575e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
576e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
577e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
578e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
579afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
58096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
582afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
583bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
58496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
585bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t oldDimX = mHal.state.dimensionX;
58696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
58796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
58896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
58996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
59096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
591bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX);
59296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
593bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes());
59496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
59596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX > oldDimX) {
596bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        const Element *e = mHal.state.type->getElement();
59796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        uint32_t stride = e->getSizeBytes();
598bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
59996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
600bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
601bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type.set(t);
602bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
60396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
60496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
605afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
60696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
60796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
60896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
609326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
610565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
61177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
612326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
6136a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hinesstatic void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va);
6146a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
615326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
616326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
617326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
618afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
619326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
620b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    alloc->deferedUploadToTexture(rsc);
621326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
622326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
623afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
624326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
625cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    alloc->deferedUploadToBufferObject(rsc);
626326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
627326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
628afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
629326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
630326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
631326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
632e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
633326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
634326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
635326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
636326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
637e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
638565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
639565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
640565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
641565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
642565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
643565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
644565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
645565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
646afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
647565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
648565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
649565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
650e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
651565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
652565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
653565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
654565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
655e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
656565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
657326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
658326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
659326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
660326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
661326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
662326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
663326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
664afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
6652f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
6662f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
6672f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6682f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
6692f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
6702f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
6712f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
6722f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6732f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
6742f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
6752f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
6762f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
6772f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
6782f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
6792f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
6802f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
6812f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
682afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
683afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
684e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
685e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
686e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
687e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
688e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
689e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
6902f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
6912f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
6922f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
693e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
694e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
695326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
696366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
697366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
698366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
69909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams    a->sendDirty();
700366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
701366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
702a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
70339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
704a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    rsaAllocationGenerateScriptMips(rsc, texAlloc);
70539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
70639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
707837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
708837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    Allocation *texAlloc = static_cast<Allocation *>(va);
709837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
710837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
711837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
712837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
713837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
714837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
715837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
716837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
717837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    memcpy(data, texAlloc->getPtr(), s);
718837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
719837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
7204b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
7214b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                          uint32_t count, const void *data, uint32_t sizeBytes) {
722326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7234b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
7245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
7264b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
7274b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                                 const void *data, uint32_t eoff, uint32_t sizeBytes) {
7285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7294b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, y, data, eoff, sizeBytes);
7305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
7324b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
7334b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                                 const void *data, uint32_t eoff, uint32_t sizeBytes) {
7345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7354b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, data, eoff, sizeBytes);
736326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
737326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
7384b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
7394b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                          uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
740326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7414b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
742326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
743326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
744afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
745e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
746e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
747e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
748e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
749afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
75096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
75196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
75296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
75396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
754afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
75596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
75696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
75796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
75896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
759dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
760dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
761dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
762f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchoukstatic void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va) {
763f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
764f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
765f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
766f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    for (uint32_t face = 0; face < numFaces; face ++) {
767f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt(rsc, texAlloc);
768f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt2(rsc, texAlloc);
769f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt.setFace(face);
770f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt2.setFace(face);
771f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
772f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt.setLOD(lod);
773f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt2.setLOD(lod + 1);
774f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            mip(adapt2, adapt);
775f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        }
776f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
777f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk}
778f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk
779afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
780d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Allocation *a = static_cast<Allocation *>(va);
781d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    a->getType()->incUserRef();
782d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
783d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    return a->getType();
784d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
785d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
786366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
787ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                      RsAllocationMipmapControl mips,
788366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                      uint32_t usages) {
789f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Context *rsc = static_cast<Context *>(con);
790a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
791f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
792f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
793f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
794f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
795f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
796366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
797ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                           RsAllocationMipmapControl mips,
798366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                           const void *data, uint32_t usages) {
799366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Context *rsc = static_cast<Context *>(con);
800366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
801f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
802366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
803f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
804f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
805f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
806f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
807f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
808f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
809366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
810ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
811f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        rsaAllocationGenerateScriptMips(rsc, texAlloc);
812f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
813f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
814b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    texAlloc->deferedUploadToTexture(rsc);
815f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
816f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
81784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
818366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
819ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                               RsAllocationMipmapControl mips,
820366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                               const void *data, uint32_t usages) {
82184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
822366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
82384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
82484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
82584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
82684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
827366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
82884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
82984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
83084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Memory allocation failure");
83184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
83284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
83384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
8349f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
8359f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
8369f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
8379f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
83884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
839366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
840366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
841366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
842366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
8439f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
8449f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk            memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
8459f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
846366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
847366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
8489f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
849f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
850366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
851f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
852f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        rsaAllocationGenerateScriptMips(rsc, texAlloc);
85384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
85484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
855b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    texAlloc->deferedUploadToTexture(rsc);
85684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
85784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
858099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
85977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
860