rsAllocation.cpp revision afb743aca56c18beb7ab924e75cb6e070ef3e55a
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
34afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc) {
35fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
36fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
37fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = malloc(mType->getSizeBytes());
3810e5e570bab66a6cd543c857b26c576795eb240fJason Sams    if (mType->getElement()->getHasReferences()) {
3910e5e570bab66a6cd543c857b26c576795eb240fJason Sams        memset(mPtr, 0, mType->getSizeBytes());
4010e5e570bab66a6cd543c857b26c576795eb240fJason Sams    }
41fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (!mPtr) {
42fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        LOGE("Allocation::Allocation, alloc failure");
43fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
44fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
45fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
46fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason SamsAllocation::Allocation(Context *rsc, const Type *type, void *bmp,
47fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams                       void *callbackData, RsBitmapCallback_t callback)
48afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                       : ObjectBase(rsc) {
49fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
50fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
51fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = bmp;
52fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = callback;
53fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = callbackData;
54fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
55fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
56afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::init(Context *rsc, const Type *type) {
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mPtr = NULL;
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
59326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuWrite = false;
60326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuRead = false;
61326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuWrite = false;
62326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuRead = false;
63326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
64326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mReadWriteRatio = 0;
65326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mUpdateSize = 0;
66326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
67326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mIsTexture = false;
68326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mTextureID = 0;
69326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mIsVertexBuffer = false;
70326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mBufferID = 0;
71cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = false;
72326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
73fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = NULL;
74fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = NULL;
75fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
76326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mType.set(type);
77e5ffb879ae535a899a486285a23bea05e912480fJason Sams    rsAssert(type);
78fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
79fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mPtr = NULL;
80326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
81326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
82afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
83fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (mUserBitmapCallback != NULL) {
84fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
85fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    } else {
86fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        free(mPtr);
87fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
88bf3c14ebf456c745c084605dddeda08afdfc7987Jason Sams    mPtr = NULL;
89e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams
90e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mBufferID) {
91e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        // Causes a SW crash....
92e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //LOGV(" mBufferID %i", mBufferID);
93e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //glDeleteBuffers(1, &mBufferID);
94e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //mBufferID = 0;
95e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
96e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mTextureID) {
97e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        glDeleteTextures(1, &mTextureID);
98e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        mTextureID = 0;
99e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
100326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
101326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
102afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuWritable(bool) {
103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
105afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuWritable(bool) {
106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
107326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
108afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuReadable(bool) {
109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
110326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
111afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuReadable(bool) {
112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
114afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Allocation::fixAllocation() {
115326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return false;
116326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
118afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset) {
119326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(lodOffset < mType->getLODCount());
120cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsTexture = true;
121cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mTextureLOD = lodOffset;
122cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
1237fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
124cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
125cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
126afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToTexture(const Context *rsc) {
127cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    //rsAssert(!mTextureId);
128cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
129cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsTexture = true;
130cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!rsc->checkDriver()) {
131cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
132cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
133cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
134326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
135d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum type = mType->getElement()->getComponent().getGLType();
136d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum format = mType->getElement()->getComponent().getGLFormat();
137565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
138565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    if (!type || !format) {
139565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        return;
140565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
141565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
14239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool isFirstUpload = false;
14339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
144326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mTextureID) {
145326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenTextures(1, &mTextureID);
14613e2634a71a30d289ed8d821aef61c7d1687460eJason Sams
14713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        if (!mTextureID) {
14813e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // This should not happen, however, its likely the cause of the
14913e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // white sqare bug.
15013e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
15113e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            LOGE("Upload to texture failed to gen mTextureID");
15213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            rsc->dumpDebug();
153cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            mUploadDefered = true;
154cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            return;
15513e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        }
15639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        isFirstUpload = true;
157326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
158326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    glBindTexture(GL_TEXTURE_2D, mTextureID);
1595f0b4e19811e7e0ba59888939a3d0761297099fbJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
160326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
161e514b45de8561fbc6ef6770845102ca10b0a69d7Jason Sams    Adapter2D adapt(getContext(), this);
162afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
163cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        adapt.setLOD(lod+mTextureLOD);
164326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
165326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
166afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        if (isFirstUpload) {
16739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexImage2D(GL_TEXTURE_2D, lod, format,
16839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         adapt.getDimX(), adapt.getDimY(),
16939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         0, format, type, ptr);
17039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        } else {
17139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
17239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         adapt.getDimX(), adapt.getDimY(),
17339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                         format, type, ptr);
17439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
175326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
1767fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    if (mTextureGenMipmap) {
177fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
1787fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams        glGenerateMipmap(GL_TEXTURE_2D);
179fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
1807fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    }
1817fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
182c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToTexture");
183326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
184326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
185afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::deferedUploadToBufferObject(const Context *rsc) {
186cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsVertexBuffer = true;
187cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
188cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
189cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
190afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToBufferObject(const Context *rsc) {
191326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimY());
192326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    rsAssert(!mType->getDimZ());
193326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
194cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mIsVertexBuffer = true;
195cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!rsc->checkDriver()) {
196cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
197cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
198cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
199cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
200326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mBufferID) {
201326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenBuffers(1, &mBufferID);
202326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
203cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!mBufferID) {
204cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        LOGE("Upload to buffer object failed");
205cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = true;
206cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
207cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
208cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
209326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
210326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
211326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    glBindBuffer(GL_ARRAY_BUFFER, 0);
212c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToBufferObject");
213326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
214326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
215afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadCheck(const Context *rsc) {
216cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (mUploadDefered) {
217cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        mUploadDefered = false;
218cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        if (mIsVertexBuffer) {
219cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            uploadToBufferObject(rsc);
220cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        }
221cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        if (mIsTexture) {
222cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            uploadToTexture(rsc);
223cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        }
224cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
225cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
226cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
227e5ffb879ae535a899a486285a23bea05e912480fJason Sams
228afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) {
2299397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = mType->getSizeBytes();
2309397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
2319397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
2329397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
2339397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
234e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
235e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
236e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
237e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
238e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
239e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
2409397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(mPtr, data, size);
2415c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
242cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
243326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
244326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
245afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
246e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    memcpy(data, mPtr, mType->getSizeBytes());
247e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
248e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
249afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
250326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
251326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
252326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    ptr += eSize * xoff;
2539397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = count * eSize;
2549397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
2559397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
2569397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
257e12c1c591b4219e80f29c6c0e0c62c9578b75450Jason Sams        mType->dumpLOGV("type info");
2589397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
2599397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
260e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
261e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    if (mType->getElement()->getHasReferences()) {
262e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, count);
263e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(ptr, count);
264e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
265e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
2669397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(ptr, data, size);
2675c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
268cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
269326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
270326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
2715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
272afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
273326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t eSize = mType->getElementSizeBytes();
274326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t lineSize = eSize * w;
275326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t destW = mType->getDimX();
276326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
277326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    const uint8_t *src = static_cast<const uint8_t *>(data);
278326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint8_t *dst = static_cast<uint8_t *>(mPtr);
279326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    dst += eSize * (xoff + yoff * destW);
2809397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
2819397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if ((lineSize * eSize * h) != sizeBytes) {
2829397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
2839397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
2849397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
2859397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
286326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    for (uint32_t line=yoff; line < (yoff+h); line++) {
287e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        if (mType->getElement()->getHasReferences()) {
288e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            incRefs(src, w);
289e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams            decRefs(dst, w);
290e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
291326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        memcpy(dst, src, lineSize);
292326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        src += lineSize;
293326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        dst += destW * eSize;
294326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
2955c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
296cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    mUploadDefered = true;
297326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
298326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
2995f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
300afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
301326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
302326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3035f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
304afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
3055f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
3065f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
3075f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * x;
3085f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3095f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
3105f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
3115f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3125f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3135f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3145f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3155f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
3165f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
3175f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3185f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3195f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3215f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
3225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
3235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
3255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
3265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
3275f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
3315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
3325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
3335f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
3365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
3375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
3385f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
3395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Samsvoid Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
341afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
3425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint32_t eSize = mType->getElementSizeBytes();
3435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
3445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * (x + y * mType->getDimX());
3455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (x >= mType->getDimX()) {
3475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
3485f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3495f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3505f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3525f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (y >= mType->getDimY()) {
3535f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
3545f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
3555f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3565f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3585f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (cIdx >= mType->getElement()->getFieldCount()) {
3595f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
3605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
3615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3645f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    const Element * e = mType->getElement()->getField(cIdx);
3655f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
3665f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3675f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
3685f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
3695f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
3705f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
3715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3725f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3735f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
3745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
3755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
3765f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
3775f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
3785f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
3795f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
3805f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    mUploadDefered = true;
3815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
3825f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
383afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
384fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
3855c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
3865c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
387afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
3885c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
3895c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
3905c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
3915c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
3925c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
3935c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
3945c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
3955c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
396326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
397afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
398c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
399c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
400c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
401c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
402c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    if (mType.get()) {
403c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams        mType->dumpLOGV(s.string());
404c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
405c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
406c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
407c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
408c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
40943999e7b320883dbb6eb306bbe22902ebd2fcebaJason Sams    LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
410c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams          prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);
411c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
412326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
413afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
414fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
415fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
416fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
417fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
418fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
419fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
420fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
421fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
422fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mType->serialize(stream);
423fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
424fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = mType->getSizeBytes();
425fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
426fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
427fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
428fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addByteArray(mPtr, dataSize);
429fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
430fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
431afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
432fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
433b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
434afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
435fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
436fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
437fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
438fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
439fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
440fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
441fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
442fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
443afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
444fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
445fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
446fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
447fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
448fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
449fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
450afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
451fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
452225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
453fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
454fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
455fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
456fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Allocation *alloc = new Allocation(rsc, type);
457fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
458fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
459fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
4605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
461e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
462fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
463fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
464fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
465fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
466afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::sendDirty() const {
4675c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
4685c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
4695c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
4705c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
471326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
472afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
473e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
474e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
475e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
476e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
47796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
478e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
479e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
480e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
481e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
482e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
483e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
484e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
485afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
486e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
487e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const Element *e = mType->getElement();
488e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
489e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
49096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
491e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
492e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
493e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
494e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
495e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
496e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
497e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
498afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
49996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
50096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
501afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
50296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Type *t = mType->cloneAndResize1D(rsc, dimX);
50396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
50496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    uint32_t oldDimX = mType->getDimX();
50596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
50696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
50796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
50896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
50996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
51096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        decRefs(mPtr, oldDimX - dimX, dimX);
51196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
51296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mPtr = realloc(mPtr, t->getSizeBytes());
51396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
51496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX > oldDimX) {
51596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        const Element *e = mType->getElement();
51696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        uint32_t stride = e->getSizeBytes();
51796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
51896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
51996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    mType.set(t);
52096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
52196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
522afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
52396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
52496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
52596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
526326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
527565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
528326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
529326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
530326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
531326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
532326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
533afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
534326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
5357fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams    alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
536326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
537326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
538afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
539326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
540cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    alloc->deferedUploadToBufferObject(rsc);
541326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
542326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
543afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
544326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
545326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
546326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
547e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
548326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
549326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
550326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
551326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
552e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
553565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
554565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
555565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
556565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
557565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
558565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
559565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
560565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
561afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
562565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
563565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
564565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
565e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
566565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
567565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
568565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
569565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
570e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
571565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
572326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
573326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
574326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
575326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
576326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
577326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
578326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
579afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
5802f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
5812f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
5822f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
5832f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
5842f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
5852f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
5862f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
5872f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
5882f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
5892f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
5902f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
5912f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
5922f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
5932f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
5942f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
5952f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
5962f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
597afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
598afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
599e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
600e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
601e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
602e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
603e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
604e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
6052f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
6062f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
6072f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
608e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
609e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
610326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
6116678e9b2568ad041429a2477177133fe4932159fJason Samstypedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
6126678e9b2568ad041429a2477177133fe4932159fJason Sams
613afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) {
6146678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count * 2);
6156678e9b2568ad041429a2477177133fe4932159fJason Sams}
616afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) {
6176678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count);
6186678e9b2568ad041429a2477177133fe4932159fJason Sams}
619afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) {
6206678e9b2568ad041429a2477177133fe4932159fJason Sams    memcpy(dst, src, count * 4);
6216678e9b2568ad041429a2477177133fe4932159fJason Sams}
6226678e9b2568ad041429a2477177133fe4932159fJason Sams
623afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) {
6246678e9b2568ad041429a2477177133fe4932159fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
6256678e9b2568ad041429a2477177133fe4932159fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
6266678e9b2568ad041429a2477177133fe4932159fJason Sams
627afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    while (count--) {
6286678e9b2568ad041429a2477177133fe4932159fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
6296678e9b2568ad041429a2477177133fe4932159fJason Sams        d++;
6306678e9b2568ad041429a2477177133fe4932159fJason Sams        s+= 3;
6316678e9b2568ad041429a2477177133fe4932159fJason Sams    }
6326678e9b2568ad041429a2477177133fe4932159fJason Sams}
6336678e9b2568ad041429a2477177133fe4932159fJason Sams
634afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) {
6356678e9b2568ad041429a2477177133fe4932159fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
6366678e9b2568ad041429a2477177133fe4932159fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
6376678e9b2568ad041429a2477177133fe4932159fJason Sams
638afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    while (count--) {
6396678e9b2568ad041429a2477177133fe4932159fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
6406678e9b2568ad041429a2477177133fe4932159fJason Sams        d++;
6416678e9b2568ad041429a2477177133fe4932159fJason Sams        s+= 4;
6426678e9b2568ad041429a2477177133fe4932159fJason Sams    }
6436678e9b2568ad041429a2477177133fe4932159fJason Sams}
6446678e9b2568ad041429a2477177133fe4932159fJason Sams
645afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic ElementConverter_t pickConverter(const Element *dst, const Element *src) {
646d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum srcGLType = src->getComponent().getGLType();
647d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum srcGLFmt = src->getComponent().getGLFormat();
648d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum dstGLType = dst->getComponent().getGLType();
649d01d970cf5973aa5186cc02c80fb2c143a69b0b1Jason Sams    GLenum dstGLFmt = dst->getComponent().getGLFormat();
650a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams
651a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
652afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk        switch (dst->getSizeBytes()) {
653a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 4:
654a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_32;
655a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 2:
656a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_16;
657a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        case 1:
658a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams            return elementConverter_cpy_8;
659a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        }
6606678e9b2568ad041429a2477177133fe4932159fJason Sams    }
6616678e9b2568ad041429a2477177133fe4932159fJason Sams
662a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
663a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        srcGLFmt == GL_RGB &&
664a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
66544b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams        dstGLFmt == GL_RGB) {
666a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams
6676678e9b2568ad041429a2477177133fe4932159fJason Sams        return elementConverter_888_to_565;
6686678e9b2568ad041429a2477177133fe4932159fJason Sams    }
6696678e9b2568ad041429a2477177133fe4932159fJason Sams
670a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
671a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        srcGLFmt == GL_RGBA &&
672a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
67344b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams        dstGLFmt == GL_RGB) {
6746678e9b2568ad041429a2477177133fe4932159fJason Sams
675a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams        return elementConverter_8888_to_565;
676565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
6776678e9b2568ad041429a2477177133fe4932159fJason Sams
678a57c0a72c3b3babc2757d081ff8146ebaa2caf4cJason Sams    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
67944b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    LOGE("pickConverter, srcGLType = %x,  srcGLFmt = %x", srcGLType, srcGLFmt);
68044b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    LOGE("pickConverter, dstGLType = %x,  dstGLFmt = %x", dstGLType, dstGLFmt);
68144b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    src->dumpLOGV("SRC ");
68244b289491a7e7e279b5c2134ea7a29f758df3621Jason Sams    dst->dumpLOGV("DST ");
6836678e9b2568ad041429a2477177133fe4932159fJason Sams    return 0;
6846678e9b2568ad041429a2477177133fe4932159fJason Sams}
6856678e9b2568ad041429a2477177133fe4932159fJason Sams
686fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST
687fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
688fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason SamsRsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
689afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                           void *bmp, void *callbackData,
690afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                           RsBitmapCallback_t callback) {
691fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    const Type * type = static_cast<const Type *>(vtype);
692fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
693fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    alloc->incUserRef();
694fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    return alloc;
695fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
6966678e9b2568ad041429a2477177133fe4932159fJason Sams
697afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va,
698afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                    RsElement _src, const void *data) {
69939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
70039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    const Element *src = static_cast<const Element *>(_src);
70139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    const Element *dst = texAlloc->getType()->getElement();
70239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    uint32_t w = texAlloc->getType()->getDimX();
70339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    uint32_t h = texAlloc->getType()->getDimY();
70439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool genMips = texAlloc->getType()->getDimLOD();
70539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
70639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    ElementConverter_t cvt = pickConverter(dst, src);
70739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    if (cvt) {
70839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        cvt(texAlloc->getPtr(), data, w * h);
70939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        if (genMips) {
71039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            Adapter2D adapt(rsc, texAlloc);
71139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            Adapter2D adapt2(rsc, texAlloc);
712afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
71339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                adapt.setLOD(lod);
71439f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                adapt2.setLOD(lod + 1);
71539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk                mip(adapt2, adapt);
71639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk            }
71739f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        }
71839f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    } else {
71939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
72039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    }
72139f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
72239f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
723afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
724326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->data(rsc, data, sizeBytes);
726326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
727326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
728afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
729326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, count, data, sizeBytes);
7315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
733afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) {
7345f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, y, data, eoff, sizeBytes);
7365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7375f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
738afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) {
7395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subElementData(rsc, x, data, eoff, sizeBytes);
741326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
742326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
743afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex 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) {
744326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
746326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
747326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
748afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
749e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
750e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
751e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
752e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
753afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
75496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
75596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
75696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
75796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
758afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
75996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
76096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
76196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
76296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
763dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk#endif //ANDROID_RS_BUILD_FOR_HOST
764dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
765dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
766dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk}
767dc763f345db3e796efc28dc4b4d8edffda5a803eAlex Sakhartchouk
768afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
769d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    Allocation *a = static_cast<Allocation *>(va);
770d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    a->getType()->incUserRef();
771d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
772d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk    return a->getType();
773d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk}
774d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk
775afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukRsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype) {
776f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Context *rsc = static_cast<Context *>(con);
777f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype));
778f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
779f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
780f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
781f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
782afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukRsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data) {
783f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Context *rsc = static_cast<Context *>(con);
784f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    const Element *src = static_cast<const Element *>(_src);
785f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    const Element *dst = static_cast<const Element *>(_dst);
786f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
787f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips);
788f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD};
789f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    uint32_t dimValues[] = {w, h, genMips};
790f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues);
791f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
792f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type);
793f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
794f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
795f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
796f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
797f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
798f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
799f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    ElementConverter_t cvt = pickConverter(dst, src);
800f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (cvt) {
801f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        cvt(texAlloc->getPtr(), data, w * h);
802f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        if (genMips) {
803f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams            Adapter2D adapt(rsc, texAlloc);
804f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams            Adapter2D adapt2(rsc, texAlloc);
805afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk            for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
806f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams                adapt.setLOD(lod);
807f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams                adapt2.setLOD(lod + 1);
808f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams                mip(adapt2, adapt);
809f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams            }
810f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        }
811f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    } else {
812f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
813b60d757354880b6a711840eb35cc381cf7172246Jason Sams        delete texAlloc;
814b60d757354880b6a711840eb35cc381cf7172246Jason Sams        return NULL;
815f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
816f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
817f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
818f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
819