rsAllocation.cpp revision a2aab8be7a980791fc9d4e6c4d050d703b20bcf6
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 */
16fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h"
18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
191aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/gl.h>
207fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams#include <GLES2/gl2.h>
211aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/glext.h>
22fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#else
23fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsContextHostStub.h"
24fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
25fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include <OpenGL/gl.h>
26fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include <OpenGl/glext.h>
27fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#endif
281aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams
2939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk#include "utils/StopWatch.h"
3039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
31326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
32326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
33326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
34a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
35a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk                       RsAllocationMipmapControl mc)
36a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
37fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
38fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
39366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUsageFlags = usages;
40a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    mMipmapControl = mc;
41366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
42b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    allocScriptMemory();
4310e5e570bab66a6cd543c857b26c576795eb240fJason Sams    if (mType->getElement()->getHasReferences()) {
4410e5e570bab66a6cd543c857b26c576795eb240fJason Sams        memset(mPtr, 0, mType->getSizeBytes());
4510e5e570bab66a6cd543c857b26c576795eb240fJason Sams    }
46fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (!mPtr) {
47fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        LOGE("Allocation::Allocation, alloc failure");
48fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
49fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
50fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
51fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
52afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::init(Context *rsc, const Type *type) {
53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mPtr = NULL;
54326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
55326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuWrite = false;
56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuRead = false;
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuWrite = false;
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuRead = false;
59326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
60326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mReadWriteRatio = 0;
61326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mUpdateSize = 0;
62ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mUsageFlags = 0;
63ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
64326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
65326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mTextureID = 0;
66326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mBufferID = 0;
67cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = false;
68326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
69fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = NULL;
70fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = NULL;
71fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
72326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mType.set(type);
73e5ffb879ae535a899a486285a23bea05e912480fJason Sams    rsAssert(type);
74fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
75fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = NULL;
76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
77326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
78afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
79fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (mUserBitmapCallback != NULL) {
80fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
81b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        mPtr = NULL;
82fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
83b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    freeScriptMemory();
84e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams
85e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mBufferID) {
86e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        // Causes a SW crash....
87e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //LOGV(" mBufferID %i", mBufferID);
88e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //glDeleteBuffers(1, &mBufferID);
89e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //mBufferID = 0;
90e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
91e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mTextureID) {
92e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        glDeleteTextures(1, &mTextureID);
93e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        mTextureID = 0;
94e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
95326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
96326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
97afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuWritable(bool) {
98326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
99326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
100afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuWritable(bool) {
101326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
102326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
103afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuReadable(bool) {
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
105326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
106afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuReadable(bool) {
107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
109afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Allocation::fixAllocation() {
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return false;
111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
113b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::deferedUploadToTexture(const Context *rsc) {
114ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
115cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
116cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
117cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
11884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukuint32_t Allocation::getGLTarget() const {
119ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
12084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        if (mType->getDimFaces()) {
12184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_CUBE_MAP;
12284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        } else {
12384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_2D;
12484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
12584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
126ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
12784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return GL_ARRAY_BUFFER;
12884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
12984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return 0;
13084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
13184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
132b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::allocScriptMemory() {
133b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    rsAssert(!mPtr);
134b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    mPtr = malloc(mType->getSizeBytes());
135b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
136b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
137b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::freeScriptMemory() {
138b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    rsAssert(!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT));
139b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    if (mPtr) {
140b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        free(mPtr);
141b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        mPtr = NULL;
142b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
143b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
144b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
145b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
146366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
147366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
148366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
149ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
150366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToTexture(rsc);
151366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
152ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
153366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToBufferObject(rsc);
154366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
155366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
156366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUploadDefered = false;
157366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
15884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
159afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToTexture(const Context *rsc) {
160cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
161ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
162d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum type = mType->getElement()->getComponent().getGLType();
163d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum format = mType->getElement()->getComponent().getGLFormat();
164565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
165565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    if (!type || !format) {
166565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        return;
167565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
168565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
169b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    if (!mPtr) {
170b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        return;
171b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
172b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
17339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool isFirstUpload = false;
17439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
175326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mTextureID) {
176326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenTextures(1, &mTextureID);
17713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams
17813e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        if (!mTextureID) {
17913e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // This should not happen, however, its likely the cause of the
18013e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // white sqare bug.
18113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
18213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            LOGE("Upload to texture failed to gen mTextureID");
18313e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            rsc->dumpDebug();
184cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            mUploadDefered = true;
185cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            return;
18613e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        }
18739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        isFirstUpload = true;
188326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
18984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
19084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
19184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (target == GL_TEXTURE_2D) {
192b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        upload2DTexture(isFirstUpload, mPtr);
19384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    } else if (target == GL_TEXTURE_CUBE_MAP) {
19484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        uploadCubeTexture(isFirstUpload);
19584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
19684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
197b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
198b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        freeScriptMemory();
199b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
200b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
20184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    rsc->checkError("Allocation::uploadToTexture");
20284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
20384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
204b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
20584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum type = mType->getElement()->getComponent().getGLType();
20684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum format = mType->getElement()->getComponent().getGLFormat();
20784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
208b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    GLenum target = (GLenum)getGLTarget();
209b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glBindTexture(target, mTextureID);
210b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
211b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
212b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
213b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        const uint8_t *p = (const uint8_t *)ptr;
214b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        p += mType->getLODOffset(lod);
215326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
216afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (isFirstUpload) {
21739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexImage2D(GL_TEXTURE_2D, lod, format,
218b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                         mType->getLODDimX(lod), mType->getLODDimY(lod),
219b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                         0, format, type, p);
22039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        } else {
22139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
222b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                            mType->getLODDimX(lod), mType->getLODDimY(lod),
223b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                            format, type, p);
22439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
225326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
226b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams
227b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
228b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams#ifndef ANDROID_RS_BUILD_FOR_HOST
229b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams        glGenerateMipmap(target);
230b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams#endif //ANDROID_RS_BUILD_FOR_HOST
231b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
23284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
2337fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
23484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukvoid Allocation::uploadCubeTexture(bool isFirstUpload) {
23584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum type = mType->getElement()->getComponent().getGLType();
23684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum format = mType->getElement()->getComponent().getGLFormat();
23784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
238b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    GLenum target = (GLenum)getGLTarget();
239b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glBindTexture(target, mTextureID);
240b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
241b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
24284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum faceOrder[] = {
24384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_X,
24484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
24584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
24684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
24784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
24884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
24984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    };
25084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
25184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Adapter2D adapt(getContext(), this);
25284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    for (uint32_t face = 0; face < 6; face ++) {
25384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        adapt.setFace(face);
25484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
255b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
256b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams            adapt.setLOD(lod);
25784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
25884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
25984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
26084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            if (isFirstUpload) {
26184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                glTexImage2D(faceOrder[face], lod, format,
26284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                             adapt.getDimX(), adapt.getDimY(),
26384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                             0, format, type, ptr);
26484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            } else {
26584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                glTexSubImage2D(faceOrder[face], lod, 0, 0,
26684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                                adapt.getDimX(), adapt.getDimY(),
26784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                                format, type, ptr);
26884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
26984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
27084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
271b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams
272b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
273b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams#ifndef ANDROID_RS_BUILD_FOR_HOST
274b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams        glGenerateMipmap(target);
275b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams#endif //ANDROID_RS_BUILD_FOR_HOST
276b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
277326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
278326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
279afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToBufferObject(const Context *rsc) {
280ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
281cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
282cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
283cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
284afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToBufferObject(const Context *rsc) {
285326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimY());
286326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimZ());
287326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
288ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
289cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
290326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mBufferID) {
291326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenBuffers(1, &mBufferID);
292326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
293cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!mBufferID) {
294cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        LOGE("Upload to buffer object failed");
295cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
296cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
297cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
29884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
29984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, mBufferID);
30084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
30184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, 0);
302c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToBufferObject");
303326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
304326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
305366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::uploadCheck(Context *rsc) {
306cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (mUploadDefered) {
307366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
308cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
309cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
310cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
311e5ffb879ae535a899a486285a23bea05e912480fJason Sams
312afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) {
3139397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = mType->getSizeBytes();
3149397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
3159397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
3169397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3179397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
318e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
319e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
320e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
321e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
322e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
323e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
3249397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(mPtr, data, size);
3255c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
326cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
327326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
328326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
329afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
330e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    memcpy(data, mPtr, mType->getSizeBytes());
331e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
332e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
333afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
334326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
335326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
336326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    ptr += eSize * xoff;
3379397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = count * eSize;
3389397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
3399397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
3409397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
341e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams        mType->dumpLOGV("type info");
3429397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3439397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
344e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
345e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
346e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, count);
347e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(ptr, count);
348e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
349e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
3509397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(ptr, data, size);
3515c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
352cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
353326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
354326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
356afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
357326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
358326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t lineSize = eSize * w;
359326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t destW = mType->getDimX();
360326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
361326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    const uint8_t *src = static_cast<const uint8_t *>(data);
362326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t *dst = static_cast<uint8_t *>(mPtr);
363326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    dst += eSize * (xoff + yoff * destW);
3649397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
3659397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if ((lineSize * eSize * h) != sizeBytes) {
3669397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
3679397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3689397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
3699397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
370326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    for (uint32_t line=yoff; line < (yoff+h); line++) {
371e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mType->getElement()->getHasReferences()) {
372e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            incRefs(src, w);
373e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            decRefs(dst, w);
374e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
375326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        memcpy(dst, src, lineSize);
376326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        src += lineSize;
377326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        dst += destW * eSize;
378326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
3795c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
380cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
381326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
382326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3835f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
384afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
385326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
386326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3875f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
388afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
3895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
3905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
3915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * x;
3925f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3935f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
3945f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
3955f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3965f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3975f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3985f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
4005f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4015f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4025f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4045f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4055f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
4065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
4075f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
4095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
4105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4125f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4135f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4145f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4155f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4165f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4175f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4185f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4195f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
425afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
4265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
4275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
4285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * (x + y * mType->getDimX());
4295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
4315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (y >= mType->getDimY()) {
4375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4385f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4415f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
4435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
4445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
4455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4485f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
4495f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
4505f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
4525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
4535f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4565f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4585f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4595f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4645f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4655f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4665f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
467afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
468fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
4695c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
4705c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
471afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
4725c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
4735c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
4745c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
4755c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
4765c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
4775c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
4785c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
4795c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
480326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
481afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
482c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
483c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
484c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
485c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
486c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    if (mType.get()) {
487c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams        mType->dumpLOGV(s.string());
488c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
489c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
490c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
491c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
492c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
493ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
494ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams          prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
495c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
496326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
497afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
498fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
499fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
500fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
501fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
502fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
503fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
504fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
505fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
506fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mType->serialize(stream);
507fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
508fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = mType->getSizeBytes();
509fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
510fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
511fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
512fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addByteArray(mPtr, dataSize);
513fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
514fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
515afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
516fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
517b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
518afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
519fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
520fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
521fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
522fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
523fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
524fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
525fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
526fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
527afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
528fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
529fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
530fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
531fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
532fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
533fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
534afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
535fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
536225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
537fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
538fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
539fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
540ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
541fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
542fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
543fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
5445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
545e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
546fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
547fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
548fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
549fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
550afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::sendDirty() const {
5515c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5525c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
5535c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
5545c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
555326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
556afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
557e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
558e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
559e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
560e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
56196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
562e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
563e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
564e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
565e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
566e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
567e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
568e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
569afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
570e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
571e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
572e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
573e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
57496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
575e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
576e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
577e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
578e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
579e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
580e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
581e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
582afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
58396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
585afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
58696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Type *t = mType->cloneAndResize1D(rsc, dimX);
58796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
58896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    uint32_t oldDimX = mType->getDimX();
58996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
59096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
59196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
59296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
59396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
59496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        decRefs(mPtr, oldDimX - dimX, dimX);
59596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
59696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mPtr = realloc(mPtr, t->getSizeBytes());
59796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
59896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX > oldDimX) {
59996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        const Element *e = mType->getElement();
60096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        uint32_t stride = e->getSizeBytes();
60196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
60296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
60396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mType.set(t);
60496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
60596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
606afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
60796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
60896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
60996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
610326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
611565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
612326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
613326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
614326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
615326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
616326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
617afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
618326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
619b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    alloc->deferedUploadToTexture(rsc);
620326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
621326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
622afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
623326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
624cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    alloc->deferedUploadToBufferObject(rsc);
625326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
626326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
627afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
628326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
629326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
630326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
631e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
632326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
633326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
634326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
635326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
636e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
637565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
638565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
639565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
640565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
641565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
642565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
643565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
644565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
645afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
646565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
647565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
648565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
649e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
650565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
651565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
652565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
653565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
654e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
655565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
656326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
657326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
658326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
659326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
660326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
661326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
662326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
663afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
6642f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
6652f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
6662f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6672f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
6682f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
6692f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
6702f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
6712f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6722f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
6732f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
6742f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
6752f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
6762f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
6772f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
6782f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
6792f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
6802f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
681afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
682afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
683e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
684e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
685e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
686e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
687e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
688e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
6892f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
6902f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
6912f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
692e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
693e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
694326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
695fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
696fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
697366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
698366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
699366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
700366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
701366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
702837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) {
70339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
704837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
705837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
706837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    uint32_t w = t->getDimX();
707837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    uint32_t h = t->getDimY();
708837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    bool genMips = t->getDimLOD();
709837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = w * h * t->getElementSizeBytes();
710837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
711837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
712837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
713837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
714837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
715b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    if (texAlloc->getIsScript()) {
716b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        memcpy(texAlloc->getPtr(), data, s);
717b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        if (genMips) {
718b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams            Adapter2D adapt(rsc, texAlloc);
719b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams            Adapter2D adapt2(rsc, texAlloc);
720b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
721b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                adapt.setLOD(lod);
722b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                adapt2.setLOD(lod + 1);
723b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams                mip(adapt2, adapt);
724b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams            }
72539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
726b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    } else {
727b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        texAlloc->upload2DTexture(false, data);
72839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    }
729b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
73039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
73139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
732837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
733837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    Allocation *texAlloc = static_cast<Allocation *>(va);
734837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
735837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
736837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
737837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
738837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
739837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
740837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
741837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
742837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    memcpy(data, texAlloc->getPtr(), s);
743837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
744837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
745afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
746326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->data(rsc, data, sizeBytes);
748326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
749326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
750afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
751326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, count, data, sizeBytes);
7535f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
755afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) {
7565f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, y, data, eoff, sizeBytes);
7585f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7595f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
760afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) {
7615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, data, eoff, sizeBytes);
763326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
764326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
765afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
766326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7675f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
768326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
769326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
770afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
771e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
772e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
773e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
774e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
775afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
77696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
77796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
77896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
77996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
780afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
78196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
78296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
78396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
78496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
785dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
786dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
787dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
788dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
789dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
790afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
791d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Allocation *a = static_cast<Allocation *>(va);
792d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    a->getType()->incUserRef();
793d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
794d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    return a->getType();
795d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
796d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
797366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
798ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                      RsAllocationMipmapControl mips,
799366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                      uint32_t usages) {
800f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Context *rsc = static_cast<Context *>(con);
801a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
802f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
803f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
804f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
805f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
806f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
807366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
808ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                           RsAllocationMipmapControl mips,
809366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                           const void *data, uint32_t usages) {
810366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Context *rsc = static_cast<Context *>(con);
811366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
812f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
813366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
814f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
815f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
816f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
817f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
818f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
819f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
820366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
821ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
822366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D adapt(rsc, texAlloc);
823366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D adapt2(rsc, texAlloc);
824366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
825366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt.setLOD(lod);
826366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt2.setLOD(lod + 1);
827366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            mip(adapt2, adapt);
828f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        }
829f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
830f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
831b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    texAlloc->deferedUploadToTexture(rsc);
832f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
833f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
83484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
835366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
836ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams                                               RsAllocationMipmapControl mips,
837366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                               const void *data, uint32_t usages) {
83884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
839366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
84084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
84184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
84284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
84384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
844366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
84584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
84684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
84784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Memory allocation failure");
84884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
84984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
85084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
85184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
852366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
853366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
854366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
855366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
856366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        size_t cpySize = t->getDimX() * t->getDimX() * t->getElementSizeBytes();
857366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        memcpy(faceAdapter.getElement(0, 0), sourcePtr, cpySize);
858366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
859366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
860366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        sourcePtr += cpySize;
861366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
862ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams        if (mips == RS_ALLOCATION_MIPMAP_FULL) {
863366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            Adapter2D adapt(rsc, texAlloc);
864366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            Adapter2D adapt2(rsc, texAlloc);
865366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt.setFace(face);
866366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt2.setFace(face);
867366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
868366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                adapt.setLOD(lod);
869366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                adapt2.setLOD(lod + 1);
870366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                mip(adapt2, adapt);
87184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
87284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
87384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
87484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
875b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    texAlloc->deferedUploadToTexture(rsc);
87684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
87784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
878