rsAllocation.cpp revision 366c9c85196675437a8dd74c1cf6b63ddbde3d6a
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
34366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages) : ObjectBase(rsc) {
35fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
36fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
37366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUsageFlags = usages;
38366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
39fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = malloc(mType->getSizeBytes());
4010e5e570bab66a6cd543c857b26c576795eb240fJason Sams    if (mType->getElement()->getHasReferences()) {
4110e5e570bab66a6cd543c857b26c576795eb240fJason Sams        memset(mPtr, 0, mType->getSizeBytes());
4210e5e570bab66a6cd543c857b26c576795eb240fJason Sams    }
43fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (!mPtr) {
44fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        LOGE("Allocation::Allocation, alloc failure");
45fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
46fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
47fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
48fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason SamsAllocation::Allocation(Context *rsc, const Type *type, void *bmp,
49fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams                       void *callbackData, RsBitmapCallback_t callback)
50afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                       : ObjectBase(rsc) {
51fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
52fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
53366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUsageFlags = RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
54366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
55fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = bmp;
56fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = callback;
57fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = callbackData;
58fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
59fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
60afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::init(Context *rsc, const Type *type) {
61326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mPtr = NULL;
62326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
63326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuWrite = false;
64326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuRead = false;
65326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuWrite = false;
66326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuRead = false;
67326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
68326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mReadWriteRatio = 0;
69326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mUpdateSize = 0;
70326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
71326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mIsTexture = false;
72326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mTextureID = 0;
73326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mIsVertexBuffer = false;
74326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mBufferID = 0;
75cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = false;
76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
77fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = NULL;
78fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = NULL;
79fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mType.set(type);
81e5ffb879ae535a899a486285a23bea05e912480fJason Sams    rsAssert(type);
82fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
83fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = NULL;
84326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
85326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
86afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
87fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (mUserBitmapCallback != NULL) {
88fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
89fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    } else {
90fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        free(mPtr);
91fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
92bf3c14ebf456c745c084605dddeda08afdfc7987Jason Sams    mPtr = NULL;
93e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams
94e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mBufferID) {
95e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        // Causes a SW crash....
96e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //LOGV(" mBufferID %i", mBufferID);
97e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //glDeleteBuffers(1, &mBufferID);
98e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //mBufferID = 0;
99e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
100e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mTextureID) {
101e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        glDeleteTextures(1, &mTextureID);
102e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        mTextureID = 0;
103e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
105326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
106afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuWritable(bool) {
107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
109afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuWritable(bool) {
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
112afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuReadable(bool) {
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
115afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuReadable(bool) {
116326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
118afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Allocation::fixAllocation() {
119326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return false;
120326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
121326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
122afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset) {
123326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(lodOffset < mType->getLODCount());
124cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsTexture = true;
125cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mTextureLOD = lodOffset;
126cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
1277fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
128cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
129cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
13084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukuint32_t Allocation::getGLTarget() const {
13184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (mIsTexture) {
13284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        if (mType->getDimFaces()) {
13384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_CUBE_MAP;
13484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        } else {
13584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_2D;
13684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
13784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
13884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (mIsVertexBuffer) {
13984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return GL_ARRAY_BUFFER;
14084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
14184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return 0;
14284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
14384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
144366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
145366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
146366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
147366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    if (mIsTexture) {
148366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToTexture(rsc);
149366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
150366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    if (mIsVertexBuffer) {
151366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToBufferObject(rsc);
152366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
153366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
154366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    mUploadDefered = false;
155366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
15684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
157afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToTexture(const Context *rsc) {
158cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
159cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsTexture = true;
160d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum type = mType->getElement()->getComponent().getGLType();
161d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum format = mType->getElement()->getComponent().getGLFormat();
162565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
163565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    if (!type || !format) {
164565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        return;
165565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
166565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
16739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool isFirstUpload = false;
16839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
169326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mTextureID) {
170326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenTextures(1, &mTextureID);
17113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams
17213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        if (!mTextureID) {
17313e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // This should not happen, however, its likely the cause of the
17413e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // white sqare bug.
17513e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
17613e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            LOGE("Upload to texture failed to gen mTextureID");
17713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            rsc->dumpDebug();
178cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            mUploadDefered = true;
179cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            return;
18013e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        }
18139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        isFirstUpload = true;
182326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
18384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
18484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
18584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindTexture(target, mTextureID);
1865f0b4e19811e7e0ba59888939a3d0761297099fbJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
187326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
18884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (target == GL_TEXTURE_2D) {
18984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        upload2DTexture(isFirstUpload);
19084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    } else if (target == GL_TEXTURE_CUBE_MAP) {
19184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        uploadCubeTexture(isFirstUpload);
19284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
19384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
19484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (mTextureGenMipmap) {
19584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
19684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        glGenerateMipmap(target);
19784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
19884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
19984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
20084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    rsc->checkError("Allocation::uploadToTexture");
20184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
20284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
20384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukvoid Allocation::upload2DTexture(bool isFirstUpload) {
20484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum type = mType->getElement()->getComponent().getGLType();
20584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum format = mType->getElement()->getComponent().getGLFormat();
20684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
207e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    Adapter2D adapt(getContext(), this);
208afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
209cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        adapt.setLOD(lod+mTextureLOD);
210326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
211326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
212afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (isFirstUpload) {
21339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexImage2D(GL_TEXTURE_2D, lod, format,
21439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         adapt.getDimX(), adapt.getDimY(),
21539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         0, format, type, ptr);
21639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        } else {
21739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
21884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                            adapt.getDimX(), adapt.getDimY(),
21984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                            format, type, ptr);
22039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
221326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
22284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
2237fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
22484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukvoid Allocation::uploadCubeTexture(bool isFirstUpload) {
22584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum type = mType->getElement()->getComponent().getGLType();
22684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum format = mType->getElement()->getComponent().getGLFormat();
22784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
22884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum faceOrder[] = {
22984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_X,
23084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
23184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
23284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
23384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
23484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
23584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    };
23684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
23784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Adapter2D adapt(getContext(), this);
23884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    for (uint32_t face = 0; face < 6; face ++) {
23984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        adapt.setFace(face);
24084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
24184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
24284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            adapt.setLOD(lod+mTextureLOD);
24384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
24484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
24584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
24684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            if (isFirstUpload) {
24784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                glTexImage2D(faceOrder[face], lod, format,
24884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                             adapt.getDimX(), adapt.getDimY(),
24984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                             0, format, type, ptr);
25084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            } else {
25184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                glTexSubImage2D(faceOrder[face], lod, 0, 0,
25284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                                adapt.getDimX(), adapt.getDimY(),
25384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk                                format, type, ptr);
25484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
25584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
25684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
257326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
258326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
259afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToBufferObject(const Context *rsc) {
260cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsVertexBuffer = true;
261cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
262cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
263cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
264afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToBufferObject(const Context *rsc) {
265326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimY());
266326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimZ());
267326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
268cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsVertexBuffer = true;
269cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
270326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mBufferID) {
271326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenBuffers(1, &mBufferID);
272326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
273cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!mBufferID) {
274cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        LOGE("Upload to buffer object failed");
275cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
276cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
277cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
27884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
27984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, mBufferID);
28084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
28184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, 0);
282c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToBufferObject");
283326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
284326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
285366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::uploadCheck(Context *rsc) {
286cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (mUploadDefered) {
287366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
288cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
289cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
290cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
291e5ffb879ae535a899a486285a23bea05e912480fJason Sams
292afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) {
2939397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = mType->getSizeBytes();
2949397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
2959397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
2969397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
2979397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
298e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
299e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
300e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
301e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
302e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
303e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
3049397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(mPtr, data, size);
3055c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
306cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
307326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
308326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
309afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
310e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    memcpy(data, mPtr, mType->getSizeBytes());
311e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
312e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
313afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
314326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
315326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
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);
321e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams        mType->dumpLOGV("type info");
3229397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3239397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
324e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
325e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
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
3355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
336afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
337326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
338326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t lineSize = eSize * w;
339326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t destW = mType->getDimX();
340326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
341326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    const uint8_t *src = static_cast<const uint8_t *>(data);
342326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t *dst = static_cast<uint8_t *>(mPtr);
343326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    dst += eSize * (xoff + yoff * destW);
3449397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
3459397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if ((lineSize * eSize * h) != sizeBytes) {
3469397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
3479397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3489397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
3499397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
350326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    for (uint32_t line=yoff; line < (yoff+h); line++) {
351e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mType->getElement()->getHasReferences()) {
352e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            incRefs(src, w);
353e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            decRefs(dst, w);
354e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
355326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        memcpy(dst, src, lineSize);
356326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        src += lineSize;
357326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        dst += destW * eSize;
358326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
3595c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
360cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
361326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
362326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
364afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
365326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
366326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3675f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
368afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
3695f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
3705f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
3715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * x;
3725f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3735f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
3745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
3755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3775f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3785f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3795f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
3805f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
3815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3825f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3835f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3845f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3855f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
3865f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
3875f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3885f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
3895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
3905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
3915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3925f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3935f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3945f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
3955f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
3965f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
3975f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3985f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4005f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4015f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4025f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4045f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
405afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
4065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
4075f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
4085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * (x + y * mType->getDimX());
4095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
4115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4125f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4135f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4145f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4155f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4165f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (y >= mType->getDimY()) {
4175f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4185f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4195f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
4235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
4245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
4255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
4295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
4305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
4325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
4335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4385f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4415f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
4455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
447afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
448fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
4495c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
4505c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
451afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
4525c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
4535c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
4545c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
4555c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
4565c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
4575c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
4585c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
4595c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
460326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
461afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
462c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
463c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
464c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
465c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
466c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    if (mType.get()) {
467c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams        mType->dumpLOGV(s.string());
468c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
469c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
470c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
471c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
472c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
47343999e7b320883dbb6eb306bbe22902ebd2fcebaJason Sams    LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
474c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams          prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);
475c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
476326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
477afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
478fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
479fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
480fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
481fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
482fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
483fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
484fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
485fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
486fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mType->serialize(stream);
487fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
488fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = mType->getSizeBytes();
489fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
490fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
491fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
492fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addByteArray(mPtr, dataSize);
493fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
494fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
495afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
496fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
497b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
498afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
499fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
500fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
501fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
502fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
503fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
504fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
505fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
506fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
507afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
508fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
509fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
510fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
511fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
512fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
513fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
514afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
515fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
516225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
517fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
518fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
519fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
520366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_ALL);
521fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
522fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
523fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
5245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
525e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
526fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
527fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
528fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
529fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
530afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::sendDirty() const {
5315c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5325c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
5335c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
5345c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
535326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
536afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
537e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
538e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
539e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
540e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
54196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
542e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
543e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
544e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
545e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
546e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
547e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
548e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
549afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
550e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
551e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
552e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
553e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
55496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
555e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
556e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
557e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
558e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
559e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
560e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
561e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
562afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
56396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
56496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
565afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
56696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Type *t = mType->cloneAndResize1D(rsc, dimX);
56796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
56896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    uint32_t oldDimX = mType->getDimX();
56996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
57096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
57196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
57296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
57396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
57496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        decRefs(mPtr, oldDimX - dimX, dimX);
57596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
57696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mPtr = realloc(mPtr, t->getSizeBytes());
57796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
57896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX > oldDimX) {
57996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        const Element *e = mType->getElement();
58096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        uint32_t stride = e->getSizeBytes();
58196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
58296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
58396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mType.set(t);
58496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
586afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
58796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
58896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
58996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
590326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
591565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
592326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
593326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
594326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
595326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
596326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
597afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
598326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
5997fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
600326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
601326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
602afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
603326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
604cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    alloc->deferedUploadToBufferObject(rsc);
605326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
606326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
607afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
608326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
609326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
610326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
611e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
612326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
613326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
614326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
615326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
616e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
617565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
618565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
619565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
620565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
621565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
622565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
623565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
624565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
625afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
626565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
627565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
628565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
629e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
630565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
631565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
632565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
633565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
634e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
635565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
636326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
637326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
638326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
639326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
640326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
641326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
642326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
643afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
6442f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
6452f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
6462f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6472f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
6482f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
6492f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
6502f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
6512f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
6522f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
6532f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
6542f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
6552f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
6562f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
6572f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
6582f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
6592f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
6602f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
661afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
662afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
663e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
664e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
665e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
666e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
667e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
668e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
6692f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
6702f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
6712f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
672e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
673e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
674326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
6756678e9b2568ad041429a2477177133fe4932159fJason Samstypedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
6766678e9b2568ad041429a2477177133fe4932159fJason Sams
677afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) {
6786678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count * 2);
6796678e9b2568ad041429a2477177133fe4932159fJason Sams}
680afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) {
6816678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count);
6826678e9b2568ad041429a2477177133fe4932159fJason Sams}
683afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) {
6846678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count * 4);
6856678e9b2568ad041429a2477177133fe4932159fJason Sams}
6866678e9b2568ad041429a2477177133fe4932159fJason Sams
687afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) {
6886678e9b2568ad041429a2477177133fe4932159fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
6896678e9b2568ad041429a2477177133fe4932159fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
6906678e9b2568ad041429a2477177133fe4932159fJason Sams
691afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    while (count--) {
6926678e9b2568ad041429a2477177133fe4932159fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
6936678e9b2568ad041429a2477177133fe4932159fJason Sams        d++;
6946678e9b2568ad041429a2477177133fe4932159fJason Sams        s+= 3;
6956678e9b2568ad041429a2477177133fe4932159fJason Sams    }
6966678e9b2568ad041429a2477177133fe4932159fJason Sams}
6976678e9b2568ad041429a2477177133fe4932159fJason Sams
698afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) {
6996678e9b2568ad041429a2477177133fe4932159fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
7006678e9b2568ad041429a2477177133fe4932159fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
7016678e9b2568ad041429a2477177133fe4932159fJason Sams
702afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    while (count--) {
7036678e9b2568ad041429a2477177133fe4932159fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
7046678e9b2568ad041429a2477177133fe4932159fJason Sams        d++;
7056678e9b2568ad041429a2477177133fe4932159fJason Sams        s+= 4;
7066678e9b2568ad041429a2477177133fe4932159fJason Sams    }
7076678e9b2568ad041429a2477177133fe4932159fJason Sams}
7086678e9b2568ad041429a2477177133fe4932159fJason Sams
709afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic ElementConverter_t pickConverter(const Element *dst, const Element *src) {
710d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum srcGLType = src->getComponent().getGLType();
711d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum srcGLFmt = src->getComponent().getGLFormat();
712d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum dstGLType = dst->getComponent().getGLType();
713d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum dstGLFmt = dst->getComponent().getGLFormat();
714a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams
715a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
716afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        switch (dst->getSizeBytes()) {
717a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 4:
718a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_32;
719a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 2:
720a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_16;
721a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 1:
722a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_8;
723a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        }
7246678e9b2568ad041429a2477177133fe4932159fJason Sams    }
7256678e9b2568ad041429a2477177133fe4932159fJason Sams
726a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
727a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        srcGLFmt == GL_RGB &&
728a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
72944b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams        dstGLFmt == GL_RGB) {
730a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams
7316678e9b2568ad041429a2477177133fe4932159fJason Sams        return elementConverter_888_to_565;
7326678e9b2568ad041429a2477177133fe4932159fJason Sams    }
7336678e9b2568ad041429a2477177133fe4932159fJason Sams
734a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
735a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        srcGLFmt == GL_RGBA &&
736a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
73744b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams        dstGLFmt == GL_RGB) {
7386678e9b2568ad041429a2477177133fe4932159fJason Sams
739a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        return elementConverter_8888_to_565;
740565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
7416678e9b2568ad041429a2477177133fe4932159fJason Sams
742a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
74344b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    LOGE("pickConverter, srcGLType = %x,  srcGLFmt = %x", srcGLType, srcGLFmt);
74444b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    LOGE("pickConverter, dstGLType = %x,  dstGLFmt = %x", dstGLType, dstGLFmt);
74544b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    src->dumpLOGV("SRC ");
74644b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    dst->dumpLOGV("DST ");
7476678e9b2568ad041429a2477177133fe4932159fJason Sams    return 0;
7486678e9b2568ad041429a2477177133fe4932159fJason Sams}
7496678e9b2568ad041429a2477177133fe4932159fJason Sams
750fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
751fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
752366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
753366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
754366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
755366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
756366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
757fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason SamsRsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
758afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                           void *bmp, void *callbackData,
759afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                           RsBitmapCallback_t callback) {
760fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    const Type * type = static_cast<const Type *>(vtype);
761fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
762fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    alloc->incUserRef();
763fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    return alloc;
764fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
7656678e9b2568ad041429a2477177133fe4932159fJason Sams
766afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va,
767afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                    RsElement _src, const void *data) {
76839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
76939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    const Element *src = static_cast<const Element *>(_src);
77039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    const Element *dst = texAlloc->getType()->getElement();
77139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    uint32_t w = texAlloc->getType()->getDimX();
77239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    uint32_t h = texAlloc->getType()->getDimY();
77339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool genMips = texAlloc->getType()->getDimLOD();
77439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
77539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    ElementConverter_t cvt = pickConverter(dst, src);
77639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    if (cvt) {
77739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        cvt(texAlloc->getPtr(), data, w * h);
77839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        if (genMips) {
77939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            Adapter2D adapt(rsc, texAlloc);
78039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            Adapter2D adapt2(rsc, texAlloc);
781afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
78239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                adapt.setLOD(lod);
78339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                adapt2.setLOD(lod + 1);
78439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                mip(adapt2, adapt);
78539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            }
78639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
78739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    } else {
78839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
78939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    }
79039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
79139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
792afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
793326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7945f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->data(rsc, data, sizeBytes);
795326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
796326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
797afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
798326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, count, data, sizeBytes);
8005f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
8015f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
802afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) {
8035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
8045f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, y, data, eoff, sizeBytes);
8055f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
8065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
807afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) {
8085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
8095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, data, eoff, sizeBytes);
810326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
811326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
812afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex 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) {
813326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
8145f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
815326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
816326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
817afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
818e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
819e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
820e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
821e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
822afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
82396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
82496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
82596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
82696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
827afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
82896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
82996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
83096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
83196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
832dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
833dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
834dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
835dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
836dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
837afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
838d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Allocation *a = static_cast<Allocation *>(va);
839d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    a->getType()->incUserRef();
840d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
841d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    return a->getType();
842d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
843d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
844366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
845366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                      RsAllocationMipmapGenerationControl mips,
846366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                      uint32_t usages) {
847f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Context *rsc = static_cast<Context *>(con);
848366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages);
849f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
850f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
851f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
852f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
853f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
854366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
855366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                           RsAllocationMipmapGenerationControl mips,
856366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                           const void *data, uint32_t usages) {
857366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Context *rsc = static_cast<Context *>(con);
858366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
859f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
860366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
861f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
862f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
863f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
864f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
865f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
866f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
867366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
868366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    if (mips == RS_MIPMAP_FULL) {
869366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D adapt(rsc, texAlloc);
870366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D adapt2(rsc, texAlloc);
871366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
872366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt.setLOD(lod);
873366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt2.setLOD(lod + 1);
874366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            mip(adapt2, adapt);
875f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        }
876f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
877f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
878f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
879f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
88084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
881366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason SamsRsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
882366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                               RsAllocationMipmapGenerationControl mips,
883366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                                               const void *data, uint32_t usages) {
88484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
885366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
88684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
88784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
88884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
88984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
890366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
89184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
89284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
89384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Memory allocation failure");
89484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
89584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
89684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
89784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
898366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
899366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
900366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
901366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
902366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        size_t cpySize = t->getDimX() * t->getDimX() * t->getElementSizeBytes();
903366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        memcpy(faceAdapter.getElement(0, 0), sourcePtr, cpySize);
904366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
905366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
906366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        sourcePtr += cpySize;
907366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
908366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        if (mips == RS_MIPMAP_FULL) {
909366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            Adapter2D adapt(rsc, texAlloc);
910366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            Adapter2D adapt2(rsc, texAlloc);
911366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt.setFace(face);
912366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            adapt2.setFace(face);
913366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
914366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                adapt.setLOD(lod);
915366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                adapt2.setLOD(lod + 1);
916366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams                mip(adapt2, adapt);
91784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
91884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
91984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
92084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
92184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
92284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
923