1d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams/*
2d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Copyright (C) 2009 The Android Open Source Project
3d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
4d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * you may not use this file except in compliance with the License.
6d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * You may obtain a copy of the License at
7d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
8d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
10d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Unless required by applicable law or agreed to in writing, software
11d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * See the License for the specific language governing permissions and
14d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * limitations under the License.
15d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams */
16d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
17d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "rsContext.h"
18d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
194b962e57a9a1fa923283f2d76855c1c68449564fJason Sams#include <GLES/gl.h>
20c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams#include <GLES2/gl2.h>
214b962e57a9a1fa923283f2d76855c1c68449564fJason Sams#include <GLES/glext.h>
224b962e57a9a1fa923283f2d76855c1c68449564fJason Sams
23d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android;
24d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android::renderscript;
25d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
26a9e7a05b84470257637c97d65f6562aa832c66efJason SamsAllocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
27d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
288a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    init(rsc, type);
298a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
308a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mPtr = malloc(mType->getSizeBytes());
318a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    if (!mPtr) {
328a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams        LOGE("Allocation::Allocation, alloc failure");
338a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    }
348a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams}
358a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
368a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason SamsAllocation::Allocation(Context *rsc, const Type *type, void *bmp,
378a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams                       void *callbackData, RsBitmapCallback_t callback)
388a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams: ObjectBase(rsc)
398a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams{
408a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    init(rsc, type);
418a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
428a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mPtr = bmp;
438a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mUserBitmapCallback = callback;
448a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mUserBitmapCallbackData = callbackData;
458a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams}
468a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
478a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Samsvoid Allocation::init(Context *rsc, const Type *type)
488a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams{
4961f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mAllocFile = __FILE__;
5061f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mAllocLine = __LINE__;
51d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mPtr = NULL;
52d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
53d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mCpuWrite = false;
54d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mCpuRead = false;
55d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mGpuWrite = false;
56d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mGpuRead = false;
57d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
58d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mReadWriteRatio = 0;
59d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mUpdateSize = 0;
60d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
61d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mIsTexture = false;
62d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mTextureID = 0;
63d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mIsVertexBuffer = false;
64d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mBufferID = 0;
653b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = false;
66d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
678a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mUserBitmapCallback = NULL;
688a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mUserBitmapCallbackData = NULL;
698a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
70d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mType.set(type);
711bada8cd6e4f340de93cff4a2439835fc3b1456cJason Sams    rsAssert(type);
728a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams
738a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    mPtr = NULL;
74d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
75d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
76d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsAllocation::~Allocation()
77d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
788a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    if (mUserBitmapCallback != NULL) {
798a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
808a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    } else {
818a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams        free(mPtr);
828a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    }
83b7a6c4340a35b7cc4ceeeccf6cc01ed82c99a8baJason Sams    mPtr = NULL;
849d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams
859d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams    if (mBufferID) {
869d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        // Causes a SW crash....
879d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        //LOGV(" mBufferID %i", mBufferID);
889d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        //glDeleteBuffers(1, &mBufferID);
899d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        //mBufferID = 0;
909d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams    }
919d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams    if (mTextureID) {
929d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        glDeleteTextures(1, &mTextureID);
939d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams        mTextureID = 0;
949d5e03db9929271f56ac4a0078d9474d7011efcdJason Sams    }
95d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
96d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
97d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Allocation::setCpuWritable(bool)
98d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
99d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
100d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
101d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Allocation::setGpuWritable(bool)
102d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
103d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
104d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
105d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Allocation::setCpuReadable(bool)
106d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
107d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
108d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
109d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Allocation::setGpuReadable(bool)
110d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
111d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
112d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
113d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsbool Allocation::fixAllocation()
114d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
115d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return false;
116d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
117d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
118c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Samsvoid Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset)
119d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
120d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    rsAssert(lodOffset < mType->getLODCount());
1213b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mIsTexture = true;
1223b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mTextureLOD = lodOffset;
1233b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = true;
124c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams    mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
1253b7d39bb51f851ddee441fa34884495217e477f9Jason Sams}
1263b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
1273b7d39bb51f851ddee441fa34884495217e477f9Jason Samsvoid Allocation::uploadToTexture(const Context *rsc)
1283b7d39bb51f851ddee441fa34884495217e477f9Jason Sams{
1293b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    //rsAssert(!mTextureId);
1303b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
1313b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mIsTexture = true;
1323b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    if (!rsc->checkDriver()) {
1333b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mUploadDefered = true;
1343b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        return;
1353b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    }
136d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
137718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum type = mType->getElement()->getComponent().getGLType();
138718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum format = mType->getElement()->getComponent().getGLFormat();
139e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams
140e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    if (!type || !format) {
141e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        return;
142e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    }
143e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams
144d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (!mTextureID) {
145d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        glGenTextures(1, &mTextureID);
1469dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams
1479dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams        if (!mTextureID) {
1489dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams            // This should not happen, however, its likely the cause of the
1499dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams            // white sqare bug.
1509dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
1519dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams            LOGE("Upload to texture failed to gen mTextureID");
1529dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams            rsc->dumpDebug();
1533b7d39bb51f851ddee441fa34884495217e477f9Jason Sams            mUploadDefered = true;
1543b7d39bb51f851ddee441fa34884495217e477f9Jason Sams            return;
1559dab667e03632181e487a04a8a170b3fa0bd5037Jason Sams        }
156d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
157d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    glBindTexture(GL_TEXTURE_2D, mTextureID);
1580e27b5cadbc9cff87258f14ac40d9c4b365849b3Jason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
159d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
160a9e7a05b84470257637c97d65f6562aa832c66efJason Sams    Adapter2D adapt(getContext(), this);
1613b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    for(uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
1623b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        adapt.setLOD(lod+mTextureLOD);
163d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
164d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
165e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        glTexImage2D(GL_TEXTURE_2D, lod, format,
166e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams                     adapt.getDimX(), adapt.getDimY(),
167e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams                     0, format, type, ptr);
168d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
169c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams    if (mTextureGenMipmap) {
170c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams        glGenerateMipmap(GL_TEXTURE_2D);
171c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams    }
172c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams
173d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
174d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
1753b7d39bb51f851ddee441fa34884495217e477f9Jason Samsvoid Allocation::deferedUploadToBufferObject(const Context *rsc)
1763b7d39bb51f851ddee441fa34884495217e477f9Jason Sams{
1773b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mIsVertexBuffer = true;
1783b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = true;
1793b7d39bb51f851ddee441fa34884495217e477f9Jason Sams}
1803b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
1813b7d39bb51f851ddee441fa34884495217e477f9Jason Samsvoid Allocation::uploadToBufferObject(const Context *rsc)
182d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
183d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    rsAssert(!mType->getDimY());
184d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    rsAssert(!mType->getDimZ());
185d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
1863b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mIsVertexBuffer = true;
1873b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    if (!rsc->checkDriver()) {
1883b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mUploadDefered = true;
1893b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        return;
1903b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    }
1913b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
192d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    if (!mBufferID) {
193d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        glGenBuffers(1, &mBufferID);
194d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
1953b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    if (!mBufferID) {
1963b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        LOGE("Upload to buffer object failed");
1973b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mUploadDefered = true;
1983b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        return;
1993b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    }
2003b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
201d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
202d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
203d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    glBindBuffer(GL_ARRAY_BUFFER, 0);
204d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
205d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
2063b7d39bb51f851ddee441fa34884495217e477f9Jason Samsvoid Allocation::uploadCheck(const Context *rsc)
2073b7d39bb51f851ddee441fa34884495217e477f9Jason Sams{
2083b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    if (mUploadDefered) {
2093b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mUploadDefered = false;
2103b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        if (mIsVertexBuffer) {
2113b7d39bb51f851ddee441fa34884495217e477f9Jason Sams            uploadToBufferObject(rsc);
2123b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        }
2133b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        if (mIsTexture) {
2143b7d39bb51f851ddee441fa34884495217e477f9Jason Sams            uploadToTexture(rsc);
2153b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        }
2163b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    }
2173b7d39bb51f851ddee441fa34884495217e477f9Jason Sams}
2183b7d39bb51f851ddee441fa34884495217e477f9Jason Sams
2191bada8cd6e4f340de93cff4a2439835fc3b1456cJason Sams
22007ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid Allocation::data(const void *data, uint32_t sizeBytes)
221d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
22207ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    uint32_t size = mType->getSizeBytes();
22307ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    if (size != sizeBytes) {
22407ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
22507ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        return;
22607ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    }
22707ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    memcpy(mPtr, data, size);
22883f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    sendDirty();
2293b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = true;
230d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
231d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
23240a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Samsvoid Allocation::read(void *data)
23340a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams{
23440a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    memcpy(data, mPtr, mType->getSizeBytes());
23540a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams}
23640a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams
23707ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
238d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
239d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t eSize = mType->getElementSizeBytes();
240d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
241d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    ptr += eSize * xoff;
24207ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    uint32_t size = count * eSize;
24307ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams
24407ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    if (size != sizeBytes) {
24507ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
2463c0dfbab807a459622aeade4940daddf482dec66Jason Sams        mType->dumpLOGV("type info");
24707ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        return;
24807ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    }
24907ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    memcpy(ptr, data, size);
25083f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    sendDirty();
2513b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = true;
252d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
253d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
254e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Samsvoid Allocation::subData(uint32_t xoff, uint32_t yoff,
25507ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
256d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
257d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t eSize = mType->getElementSizeBytes();
258d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t lineSize = eSize * w;
259d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t destW = mType->getDimX();
260d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
261d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    const uint8_t *src = static_cast<const uint8_t *>(data);
262d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint8_t *dst = static_cast<uint8_t *>(mPtr);
263d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    dst += eSize * (xoff + yoff * destW);
26407ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams
26507ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    if ((lineSize * eSize * h) != sizeBytes) {
26607ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        rsAssert(!"Allocation::subData called with mismatched size");
26707ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams        return;
26807ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    }
26907ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams
270d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    for (uint32_t line=yoff; line < (yoff+h); line++) {
271d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        uint8_t * ptr = static_cast<uint8_t *>(mPtr);
272d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        memcpy(dst, src, lineSize);
273d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        src += lineSize;
274d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        dst += destW * eSize;
275d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
27683f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    sendDirty();
2773b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    mUploadDefered = true;
278d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
279d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
280d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
28107ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams             uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes)
282d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
283d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
284d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
28583f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Samsvoid Allocation::addProgramToDirty(const Program *p)
28683f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams{
28783f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    mToDirtyList.add(p);
28883f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams}
28983f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams
29083f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Samsvoid Allocation::removeProgramToDirty(const Program *p)
29183f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams{
29283f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
29383f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams        if (mToDirtyList[ct] == p) {
29483f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams            mToDirtyList.removeAt(ct);
29583f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams            return;
29683f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams        }
29783f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    }
29883f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    rsAssert(0);
29983f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams}
300d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
301715333b832fb448c32165c7d97d408a3fa43f7cbJason Samsvoid Allocation::dumpLOGV(const char *prefix) const
302715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams{
303715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    ObjectBase::dumpLOGV(prefix);
304715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams
305715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    String8 s(prefix);
306715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    s.append(" type ");
307715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    if (mType.get()) {
308715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams        mType->dumpLOGV(s.string());
309715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    }
310715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams
311715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
312715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
313715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams
314361765361ae70a17fe4de64b8c1a3299a84e212dJason Sams    LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
315715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams          prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);
316715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams
317715333b832fb448c32165c7d97d408a3fa43f7cbJason Sams}
318d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
31983f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Samsvoid Allocation::sendDirty() const
32083f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams{
32183f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
32283f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams        mToDirtyList[ct]->forceDirty();
32383f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams    }
32483f1c63c56ed73e0dfcc4de67bc58a4df5b3fe69Jason Sams}
325d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
326d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams/////////////////
327e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams//
328d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
329d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
330d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsnamespace android {
331d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsnamespace renderscript {
332d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
333d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
334d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
335d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    const Type * type = static_cast<const Type *>(vtype);
336d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
337a9e7a05b84470257637c97d65f6562aa832c66efJason Sams    Allocation * alloc = new Allocation(rsc, type);
33807ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    alloc->incUserRef();
339d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return alloc;
340d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
341d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
342d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsRsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
343d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
344a9e7a05b84470257637c97d65f6562aa832c66efJason Sams    Type * type = new Type(rsc);
345d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    type->setDimX(count);
346d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    type->setElement(static_cast<Element *>(e));
347d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    type->compute();
348d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return rsi_AllocationCreateTyped(rsc, type);
349d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
350d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
351c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Samsvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel)
352d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
353d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Allocation *alloc = static_cast<Allocation *>(va);
354c2908e60c9b021fb4bb69acff8d49981dd4dade8Jason Sams    alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
355d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
356d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
357d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va)
358d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
359d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Allocation *alloc = static_cast<Allocation *>(va);
3603b7d39bb51f851ddee441fa34884495217e477f9Jason Sams    alloc->deferedUploadToBufferObject(rsc);
361d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
362d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
363e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Samsstatic void mip565(const Adapter2D &out, const Adapter2D &in)
364d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
365d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t w = out.getDimX();
366d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    uint32_t h = out.getDimY();
367d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
3686f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    for (uint32_t y=0; y < h; y++) {
369d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
370d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
371d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
372d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
3736f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        for (uint32_t x=0; x < w; x++) {
374e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
375e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams            oPtr ++;
376e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams            i1 += 2;
377e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams            i2 += 2;
378e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        }
379e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    }
380e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams}
381e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams
382e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Samsstatic void mip8888(const Adapter2D &out, const Adapter2D &in)
383e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams{
384e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    uint32_t w = out.getDimX();
385e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    uint32_t h = out.getDimY();
386e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams
3876f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    for (uint32_t y=0; y < h; y++) {
388e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
389e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
390e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
391e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams
3926f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        for (uint32_t x=0; x < w; x++) {
393e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
394d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            oPtr ++;
395d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            i1 += 2;
396d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            i2 += 2;
397d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        }
398d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
399d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
400d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
401e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Samsstatic void mip8(const Adapter2D &out, const Adapter2D &in)
402e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams{
403e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams    uint32_t w = out.getDimX();
404e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams    uint32_t h = out.getDimY();
405e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams
406e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams    for (uint32_t y=0; y < h; y++) {
407e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
408e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
409e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
410e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams
411e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        for (uint32_t x=0; x < w; x++) {
412e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
413e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams            oPtr ++;
414e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams            i1 += 2;
415e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams            i2 += 2;
416e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        }
417e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams    }
418e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams}
419e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams
4206f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Samsstatic void mip(const Adapter2D &out, const Adapter2D &in)
4216f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams{
4226f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    switch(out.getBaseType()->getElement()->getSizeBits()) {
4236f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    case 32:
4246f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        mip8888(out, in);
4256f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        break;
4266f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    case 16:
4276f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        mip565(out, in);
4286f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams        break;
429e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams    case 8:
430e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        mip8(out, in);
431e20e3b41db0bc8bb68f40e8a60b351933028ffd6Jason Sams        break;
4326f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams
4336f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams    }
4346f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams
4356f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams}
436d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
437fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samstypedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
438fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
439fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samsstatic void elementConverter_cpy_16(void *dst, const void *src, uint32_t count)
440fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
441fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    memcpy(dst, src, count * 2);
442fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
443fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samsstatic void elementConverter_cpy_8(void *dst, const void *src, uint32_t count)
444fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
445fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    memcpy(dst, src, count);
446fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
447fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samsstatic void elementConverter_cpy_32(void *dst, const void *src, uint32_t count)
448fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
449fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    memcpy(dst, src, count * 4);
450fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
451fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
452fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
453fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samsstatic void elementConverter_888_to_565(void *dst, const void *src, uint32_t count)
454fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
455fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
456fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
457fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
458fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    while(count--) {
459fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
460fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        d++;
461fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        s+= 3;
462fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
463fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
464fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
465fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Samsstatic void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count)
466fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
467fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    uint16_t *d = static_cast<uint16_t *>(dst);
468fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    const uint8_t *s = static_cast<const uint8_t *>(src);
469fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
470fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    while(count--) {
471fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        *d = rs888to565(s[0], s[1], s[2]);
472fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        d++;
473fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        s+= 4;
474fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
475fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
476fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
477ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Samsstatic ElementConverter_t pickConverter(const Element *dst, const Element *src)
478ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams{
479718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum srcGLType = src->getComponent().getGLType();
480718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum srcGLFmt = src->getComponent().getGLFormat();
481718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum dstGLType = dst->getComponent().getGLType();
482718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams    GLenum dstGLFmt = dst->getComponent().getGLFormat();
483ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams
484ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
485ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        switch(dst->getSizeBytes()) {
486ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        case 4:
487ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams            return elementConverter_cpy_32;
488ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        case 2:
489ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams            return elementConverter_cpy_16;
490ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        case 1:
491ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams            return elementConverter_cpy_8;
492ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        }
493fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
494fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
495ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
496ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        srcGLFmt == GL_RGB &&
497ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
498ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        dstGLType == GL_RGB) {
499ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams
500fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        return elementConverter_888_to_565;
501fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
502fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
503ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    if (srcGLType == GL_UNSIGNED_BYTE &&
504ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        srcGLFmt == GL_RGBA &&
505ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
506ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        dstGLType == GL_RGB) {
507fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
508ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        return elementConverter_8888_to_565;
509e2ae85fc5a07591cb27bfae93557f80c55bb259cJason Sams    }
510fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
511ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
512fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    return 0;
513fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
514fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
5158a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason SamsRsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
5168a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams                                           void *bmp, void *callbackData, RsBitmapCallback_t callback)
5178a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams{
5188a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    const Type * type = static_cast<const Type *>(vtype);
5198a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
5208a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    alloc->incUserRef();
5218a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams    return alloc;
5228a64743f37ed35af7c2204acd18bb3d62d8f66d5Jason Sams}
523fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
524ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data)
525fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams{
526ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    const Element *src = static_cast<const Element *>(_src);
527ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    const Element *dst = static_cast<const Element *>(_dst);
52874e02ef2000ff2783e526d6916e2f0b5d517593eJason Sams
52974e02ef2000ff2783e526d6916e2f0b5d517593eJason Sams    // Check for pow2 on pre es 2.0 versions.
53074e02ef2000ff2783e526d6916e2f0b5d517593eJason Sams    rsAssert(rsc->checkVersion2_0() || (!(w & (w-1)) && !(h & (h-1))));
531b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
532b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips);
533ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    rsi_TypeBegin(rsc, _dst);
534fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
535fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
536fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    if (genMips) {
537fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
538fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
539fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    RsType type = rsi_TypeCreate(rsc);
540fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
541fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
542fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
543fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    if (texAlloc == NULL) {
544fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        LOGE("Memory allocation failure");
545fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        return NULL;
546fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
547fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
548ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    ElementConverter_t cvt = pickConverter(dst, src);
549fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    cvt(texAlloc->getPtr(), data, w * h);
550fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
551fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    if (genMips) {
552a9e7a05b84470257637c97d65f6562aa832c66efJason Sams        Adapter2D adapt(rsc, texAlloc);
553a9e7a05b84470257637c97d65f6562aa832c66efJason Sams        Adapter2D adapt2(rsc, texAlloc);
554fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
555fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams            adapt.setLOD(lod);
556fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams            adapt2.setLOD(lod + 1);
5576f5c61c8df70273e3bbc7fd07412cc69b6ce1e76Jason Sams            mip(adapt2, adapt);
558fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams        }
559fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    }
560fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
561fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams    return texAlloc;
562fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams}
563fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams
564ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason SamsRsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
565b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams{
566ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    const Element *srcE = static_cast<const Element *>(_src);
567ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    const Element *dstE = static_cast<const Element *>(_dst);
568b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    uint32_t w2 = rsHigherPow2(w);
569b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    uint32_t h2 = rsHigherPow2(h);
570b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
571b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    if ((w2 == w) && (h2 == h)) {
572ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams        return rsi_AllocationCreateFromBitmap(rsc, w, h, _dst, _src, genMips, data);
573b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    }
574b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
575ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    uint32_t bpp = srcE->getSizeBytes();
576b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    size_t size = w2 * h2 * bpp;
577b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    uint8_t *tmp = static_cast<uint8_t *>(malloc(size));
578b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    memset(tmp, 0, size);
579b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
580b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    const uint8_t * src = static_cast<const uint8_t *>(data);
581b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    for (uint32_t y = 0; y < h; y++) {
582faf1520be77aa01903f9ad87990377f44e185224Jason Sams        uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp];
583911458a081e098b7b289ed7135e1719733d7e12dMarco Nelissen        memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp);
584faf1520be77aa01903f9ad87990377f44e185224Jason Sams        src += w * bpp;
585b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    }
586b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
587ea84a7c51790f9ba5f2194a66d6cf4ea8d879776Jason Sams    RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp);
588b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    free(tmp);
589b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams    return ret;
590b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams}
591b0ec1b46d6f5b5612e33fe43a828abea79b87a00Jason Sams
59207ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
593d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
594d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Allocation *a = static_cast<Allocation *>(va);
59507ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    a->data(data, sizeBytes);
596d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
597d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
59807ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
599d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
600d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Allocation *a = static_cast<Allocation *>(va);
60107ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    a->subData(xoff, count, data, sizeBytes);
602d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
603d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
60407ae40623737a6060b8a925fd2e6bba76780dcd4Jason Samsvoid rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
605d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
606d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    Allocation *a = static_cast<Allocation *>(va);
60707ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    a->subData(xoff, yoff, w, h, data, sizeBytes);
608d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
609d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
61040a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Samsvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
61140a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams{
61240a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    Allocation *a = static_cast<Allocation *>(va);
61340a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams    a->read(data);
61440a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams}
61540a29e8e28772b37ab0f9fe9708ecdcba24abb84Jason Sams
616d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
617d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
618d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
619