rsAllocation.cpp revision c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1777d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#include "rsContext.h"
1877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
191aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/gl.h>
207fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams#include <GLES2/gl2.h>
211aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams#include <GLES/glext.h>
2277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
2339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
25326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
26326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
27a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex SakhartchoukAllocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
28a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk                       RsAllocationMipmapControl mc)
29a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    : ObjectBase(rsc) {
30fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    init(rsc, type);
31fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags = usages;
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = mc;
34366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
35b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    allocScriptMemory();
36bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.type->getElement()->getHasReferences()) {
37bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes());
3810e5e570bab66a6cd543c857b26c576795eb240fJason Sams    }
39bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!mHal.state.mallocPtr) {
40fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        LOGE("Allocation::Allocation, alloc failure");
41fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
42fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams}
43fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
44fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
45afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::init(Context *rsc, const Type *type) {
46bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    memset(&mHal, 0, sizeof(mHal));
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
48326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
49326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuWrite = false;
50326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mCpuRead = false;
51326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuWrite = false;
52326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mGpuRead = false;
53326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
54326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mReadWriteRatio = 0;
55326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mUpdateSize = 0;
56326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
57326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mTextureID = 0;
58326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mBufferID = 0;
597d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mRenderTargetID = 0;
607d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = false;
61326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
62fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallback = NULL;
63fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    mUserBitmapCallbackData = NULL;
64fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type.set(type);
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
67bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
68fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams
69bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid Allocation::updateCache() {
70bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Type *type = mHal.state.type.get();
71bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionX = type->getDimX();
72bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionY = type->getDimY();
73bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.dimensionZ = type->getDimZ();
74bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasFaces = type->getDimFaces();
75bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasMipmaps = type->getDimLOD();
76bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.elementSizeBytes = type->getElementSizeBytes();
77bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
78326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
79326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
80afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation::~Allocation() {
81fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    if (mUserBitmapCallback != NULL) {
82fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams        mUserBitmapCallback(mUserBitmapCallbackData);
83bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.mallocPtr = NULL;
84fa84da2cbc271f855b3b1ec75bb688abdf1d1d01Jason Sams    }
85b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    freeScriptMemory();
8677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
87e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mBufferID) {
88e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        // Causes a SW crash....
89e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //LOGV(" mBufferID %i", mBufferID);
90e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //glDeleteBuffers(1, &mBufferID);
91e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        //mBufferID = 0;
92e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
93e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    if (mTextureID) {
94e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        glDeleteTextures(1, &mTextureID);
95e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams        mTextureID = 0;
96e402ed33486730f1d06f080cdfc48132bf612b3aJason Sams    }
977d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    if (mRenderTargetID) {
987d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        glDeleteRenderbuffers(1, &mRenderTargetID);
997d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        mRenderTargetID = 0;
1007d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    }
10177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
102326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
104afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuWritable(bool) {
105326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
107afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuWritable(bool) {
108326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
109326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
110afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setCpuReadable(bool) {
111326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
112326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
113afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::setGpuReadable(bool) {
114326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
115326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
116afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukbool Allocation::fixAllocation() {
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    return false;
118326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
119326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
1207d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchoukvoid Allocation::deferredUploadToTexture(const Context *rsc) {
121bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
1227d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
1237d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk}
1247d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk
1257d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchoukvoid Allocation::deferredAllocateRenderTarget(const Context *rsc) {
1267d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
1277d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
128cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
129cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
13084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchoukuint32_t Allocation::getGLTarget() const {
13177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
132ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
133bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        if (mHal.state.type->getDimFaces()) {
13484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_CUBE_MAP;
13584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        } else {
13684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            return GL_TEXTURE_2D;
13784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
13884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
139ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
14084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return GL_ARRAY_BUFFER;
14184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
14277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
14384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return 0;
14484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
14584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
146b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::allocScriptMemory() {
147bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.mallocPtr);
148bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes());
149b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
150b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
151b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Samsvoid Allocation::freeScriptMemory() {
152bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mallocPtr) {
153bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        free(mHal.state.mallocPtr);
154bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.mallocPtr = NULL;
155b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
156b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams}
157b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
158b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
159366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
160366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
161366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
162ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsTexture()) {
163366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToTexture(rsc);
164366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
165ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (getIsBufferObject()) {
166366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        uploadToBufferObject(rsc);
167366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    }
1687d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    if (getIsRenderTarget() && !getIsTexture()) {
1697d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        allocateRenderTarget(rsc);
1707d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    }
171366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
1727d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = false;
173366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
17484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
175afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToTexture(const Context *rsc) {
17677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
177bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
178bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
179bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
180565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
181565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    if (!type || !format) {
182565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        return;
183565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
184565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
185bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!mHal.state.mallocPtr) {
186b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        return;
187b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
188b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
18939f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    bool isFirstUpload = false;
19039f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
191326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mTextureID) {
192326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenTextures(1, &mTextureID);
19313e2634a71a30d289ed8d821aef61c7d1687460eJason Sams
19413e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        if (!mTextureID) {
19513e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // This should not happen, however, its likely the cause of the
19613e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // white sqare bug.
19713e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
19813e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            LOGE("Upload to texture failed to gen mTextureID");
19913e2634a71a30d289ed8d821aef61c7d1687460eJason Sams            rsc->dumpDebug();
2007d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk            mUploadDeferred = true;
201cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams            return;
20213e2634a71a30d289ed8d821aef61c7d1687460eJason Sams        }
20339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk        isFirstUpload = true;
204326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
20584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
206bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    upload2DTexture(isFirstUpload);
20784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
208bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
209b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams        freeScriptMemory();
210b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    }
211b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
21284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    rsc->checkError("Allocation::uploadToTexture");
21377d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
21484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
21584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
2167d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchoukvoid Allocation::allocateRenderTarget(const Context *rsc) {
2177d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
2187d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
2197d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk
2207d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
2217d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    if (!format) {
2227d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        return;
2237d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    }
2247d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk
2257d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    if (!mRenderTargetID) {
2267d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        glGenRenderbuffers(1, &mRenderTargetID);
2277d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk
2287d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        if (!mRenderTargetID) {
2297d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk            // This should generally not happen
2307d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk            LOGE("allocateRenderTarget failed to gen mRenderTargetID");
2317d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk            rsc->dumpDebug();
2327d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk            return;
2337d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        }
2347d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        glBindRenderbuffer(GL_RENDERBUFFER, mRenderTargetID);
2357d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        glRenderbufferStorage(GL_RENDERBUFFER, format,
2367d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk                              mHal.state.type->getDimX(),
2377d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk                              mHal.state.type->getDimY());
2387d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    }
2397d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
2407d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk}
2417d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk
24277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
243bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Samsconst static GLenum gFaceOrder[] = {
244bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
245bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
246bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
247bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
248bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
249bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
250bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams};
25177d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
252bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams
253236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
254236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                                 uint32_t lod, RsAllocationCubemapFace face,
255236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                                 uint32_t w, uint32_t h) {
25677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
257bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
258bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
259236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    GLenum target = (GLenum)getGLTarget();
260185b8b01f417488e2fbf6e6c00dfbd3d1d43d98aJason Sams    rsAssert(mTextureID);
261236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    glBindTexture(target, mTextureID);
262236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
263bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    GLenum t = GL_TEXTURE_2D;
264bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasFaces) {
265bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams        t = gFaceOrder[face];
266b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
267bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
26877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
26984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
2707fabe1a3bf8de37d86021bb7f744c791db81aed3Jason Sams
271bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Samsvoid Allocation::upload2DTexture(bool isFirstUpload) {
27277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
273bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
274bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
27584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
276b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    GLenum target = (GLenum)getGLTarget();
277b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glBindTexture(target, mTextureID);
278b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
279b89b0b7dd8199967502c92fe5c8f57c3bc255e1cJason Sams
280bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    uint32_t faceCount = 1;
281bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasFaces) {
282bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams        faceCount = 6;
283bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    }
28484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
285bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams    for (uint32_t face = 0; face < faceCount; face ++) {
286bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) {
287bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr;
288bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
28984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
290bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams            GLenum t = GL_TEXTURE_2D;
291bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            if (mHal.state.hasFaces) {
292bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                t = gFaceOrder[face];
293bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams            }
29484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
29584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            if (isFirstUpload) {
296bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                glTexImage2D(t, lod, format,
297bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                             mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
298bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                             0, format, type, p);
29984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            } else {
300bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                glTexSubImage2D(t, lod, 0, 0,
301bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                                mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
302bcac9340126b4b9fabf2015a2f6a984414d87c21Jason Sams                                format, type, p);
30384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk            }
30484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        }
30584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
306b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams
307bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
308b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams        glGenerateMipmap(target);
309b7e83bda41e66c966b98935b44140692bfe0c4caJason Sams    }
31077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
311326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
312326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3137d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchoukvoid Allocation::deferredUploadToBufferObject(const Context *rsc) {
314bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
3157d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
316cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
317cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
318afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::uploadToBufferObject(const Context *rsc) {
31977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
320bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.type->getDimY());
321bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsAssert(!mHal.state.type->getDimZ());
322326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
323bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
324cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
325326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    if (!mBufferID) {
326326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        glGenBuffers(1, &mBufferID);
327326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
328cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    if (!mBufferID) {
329cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        LOGE("Upload to buffer object failed");
3307d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        mUploadDeferred = true;
331cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams        return;
332cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
33384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    GLenum target = (GLenum)getGLTarget();
33484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, mBufferID);
335bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
33684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    glBindBuffer(target, 0);
337c1ed589021e280cda59a0521cb96b3e9eb629e1bJason Sams    rsc->checkError("Allocation::uploadToBufferObject");
33877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
339326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
340326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
341366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid Allocation::uploadCheck(Context *rsc) {
3427d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    if (mUploadDeferred) {
343366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
344cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams    }
345cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams}
346cf4c7c9b2f513be77a5b9853319ca82ac2b128edJason Sams
347afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::read(void *data) {
348bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes());
349e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
350e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
3514b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
3524b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                         uint32_t count, const void *data, uint32_t sizeBytes) {
353bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.type->getElementSizeBytes();
354bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
355326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    ptr += eSize * xoff;
3569397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    uint32_t size = count * eSize;
3579397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
3589397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    if (size != sizeBytes) {
3599397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
360bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV("type info");
3619397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3629397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
363e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
364bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.hasReferences) {
365e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        incRefs(data, count);
366e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        decRefs(ptr, count);
367e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
368e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
3699397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    memcpy(ptr, data, size);
3705c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    sendDirty();
3717d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
372326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
373326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
3744b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
375afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
376bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
377326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t lineSize = eSize * w;
378bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t destW = mHal.state.dimensionX;
379326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
380a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    //LOGE("data2d %p,  %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
3819397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
382a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    if ((lineSize * h) != sizeBytes) {
383a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        LOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
3849397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        rsAssert(!"Allocation::subData called with mismatched size");
3859397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams        return;
3869397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams    }
3879397e30ce5fe3f6af9212a93b490836b04fdfffaJason Sams
388bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.mallocPtr) {
389a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        const uint8_t *src = static_cast<const uint8_t *>(data);
390bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr);
391bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
392a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams
393a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        //LOGE("            %p  %p  %i  ", dst, src, eSize);
394a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        for (uint32_t line=yoff; line < (yoff+h); line++) {
395bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            if (mHal.state.hasReferences) {
396a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams                incRefs(src, w);
397a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams                decRefs(dst, w);
398a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            }
399a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            memcpy(dst, src, lineSize);
400a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            src += lineSize;
401a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams            dst += destW * eSize;
402e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        }
403a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams        sendDirty();
4047d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk        mUploadDeferred = true;
405a23715148f7bda74e904fc553b70c9a49fd52a6eJason Sams    } else {
406236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams        update2DTexture(data, xoff, yoff, lod, face, w, h);
407326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
408326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
409326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
410236385b73f21ae65e756b9cb5738f1514d95ea3eJason Samsvoid Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
411236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t lod, RsAllocationCubemapFace face,
412236385b73f21ae65e756b9cb5738f1514d95ea3eJason Sams                      uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
413326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
414326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
4154b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, const void *data,
416afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                uint32_t cIdx, uint32_t sizeBytes) {
417bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
418bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
4195f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    ptr += eSize * x;
4205f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
421bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
4225f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
4235f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
4245f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4255f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4265f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
427bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
4285f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4295f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4305f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4315f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4325f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
433bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
434bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
4355f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4365f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
437099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
4385f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4395f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4405f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4415f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4425f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4435f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4445f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4455f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4465f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4475f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4485f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4497d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
4505f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4515f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4524b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
453afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
454bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t eSize = mHal.state.elementSizeBytes;
455bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
456bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += eSize * (x + y * mHal.state.dimensionX);
4575f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
458bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (x >= mHal.state.dimensionX) {
4595f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4605f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4615f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4625f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4635f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
464bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (y >= mHal.state.dimensionY) {
4655f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
4665f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
4675f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4685f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4695f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
470bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
4715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
4725f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
4735f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4755f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
476bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element * e = mHal.state.type->getElement()->getField(cIdx);
477bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
4785f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4795f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (sizeBytes != e->getSizeBytes()) {
480099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk        LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
4815f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
4825f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        return;
4835f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4845f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4855f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    if (e->getHasReferences()) {
4865f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->incRefs(data);
4875f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams        e->decRefs(ptr);
4885f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    }
4895f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
4905f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    memcpy(ptr, data, sizeBytes);
4915f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    sendDirty();
4927d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    mUploadDeferred = true;
4935f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
4945f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
495afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::addProgramToDirty(const Program *p) {
49677d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
497fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    mToDirtyList.push(p);
49877d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
4995c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
5005c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams
501afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::removeProgramToDirty(const Program *p) {
50277d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
5035c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5045c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        if (mToDirtyList[ct] == p) {
5055c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            mToDirtyList.removeAt(ct);
5065c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams            return;
5075c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        }
5085c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
5095c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    rsAssert(0);
51077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
5115c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
512326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
513afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::dumpLOGV(const char *prefix) const {
514c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    ObjectBase::dumpLOGV(prefix);
515c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
516c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    String8 s(prefix);
517c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    s.append(" type ");
518bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (mHal.state.type.get()) {
519bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        mHal.state.type->dumpLOGV(s.string());
520c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    }
521c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
522c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
523bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams          prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
524c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams
525ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
526bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams          prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID);
527c21cf40f6ae69091bf24f87b5eeabc95e73dd271Jason Sams}
528326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
529afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::serialize(OStream *stream) const {
530fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Need to identify ourselves
531fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32((uint32_t)getClassId());
532fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
533fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name(getName());
534fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addString(&name);
535fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
536fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First thing we need to serialize is the type object since it will be needed
537fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // to initialize the class
538bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type->serialize(stream);
539fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
540bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t dataSize = mHal.state.type->getSizeBytes();
541fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Write how much data we are storing
542fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->addU32(dataSize);
543fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Now write the data
544bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    stream->addByteArray(mHal.state.mallocPtr, dataSize);
545fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
546fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
547afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukAllocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
548fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // First make sure we are reading the correct object
549b825f67adb5d1e1751fe108e6dbf9c6f2555c283Alex Sakhartchouk    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
550afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
551fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("allocation loading skipped due to invalid class id\n");
552fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
553fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
554fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
555fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    String8 name;
556fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    stream->loadString(&name);
557fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
558fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    Type *type = Type::createFromStream(rsc, stream);
559afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (!type) {
560fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
561fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
562fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    type->compute();
563fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
564fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Number of bytes we wrote out for this allocation
565fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    uint32_t dataSize = stream->loadU32();
566afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (dataSize != type->getSizeBytes()) {
567fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
568225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams        ObjectBase::checkDelete(type);
569fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk        return NULL;
570fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    }
571fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
572ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
573fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    alloc->setName(name.string(), name.size());
574fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
5754b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    uint32_t count = dataSize / type->getElementSizeBytes();
5764b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams
577fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    // Read in all of our allocation data
5784b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
579e6d9fbc31bef01219cc812e819c505ff01673c6fAlex Sakhartchouk    stream->reset(stream->getPos() + dataSize);
580fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
581fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return alloc;
582fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
583fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
584afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::sendDirty() const {
58577d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
5865c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
5875c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mToDirtyList[ct]->forceDirty();
5885c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
58977d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
5905c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams}
591326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
592afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
593e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
594bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
595e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
596e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
59796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
598e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
599e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->incRefs(p);
600e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
601e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
602e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
603e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
604e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
605afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
606e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    const uint8_t *p = static_cast<const uint8_t *>(ptr);
607bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    const Element *e = mHal.state.type->getElement();
608e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    uint32_t stride = e->getSizeBytes();
609e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
61096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    p += stride * startOff;
611e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    while (ct > 0) {
612e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        e->decRefs(p);
613e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        ct --;
614e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams        p += stride;
615e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams    }
616e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams}
617e3929c9bc6f3897e132304faf1b40c3cf1f47474Jason Sams
618afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
61996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
62096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
621afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize1D(Context *rsc, uint32_t dimX) {
622bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
62396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
624bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    uint32_t oldDimX = mHal.state.dimensionX;
62596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX == oldDimX) {
62696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        return;
62796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
62896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
62996abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX < oldDimX) {
630bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX);
63196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
632bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes());
63396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
63496abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    if (dimX > oldDimX) {
635bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        const Element *e = mHal.state.type->getElement();
63696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams        uint32_t stride = e->getSizeBytes();
637bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
63896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    }
639bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
640bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    mHal.state.type.set(t);
641bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    updateCache();
64296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
64396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
644afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
64596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    LOGE("not implemented");
64696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
64796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
648326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/////////////////
649565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams//
65077d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#ifndef ANDROID_RS_SERIALIZE
651326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
6526a121811e5d2e56e94747b36d15c7613ab2aedd4Stephen Hines
653326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
654326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
655326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
656c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
657c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
658afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
659326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
6607d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    alloc->deferredUploadToTexture(rsc);
661326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
662326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
663afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
664326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *alloc = static_cast<Allocation *>(va);
6657d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    alloc->deferredUploadToBufferObject(rsc);
666326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
667326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
668afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip565(const Adapter2D &out, const Adapter2D &in) {
669326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t w = out.getDimX();
670326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    uint32_t h = out.getDimY();
671326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
672e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
673326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
674326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
675326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
676326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
677e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
678565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
679565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            oPtr ++;
680565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i1 += 2;
681565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            i2 += 2;
682565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        }
683565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    }
684565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams}
685565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
686afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8888(const Adapter2D &out, const Adapter2D &in) {
687565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t w = out.getDimX();
688565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams    uint32_t h = out.getDimY();
689565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
690e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    for (uint32_t y=0; y < h; y++) {
691565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
692565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
693565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
694565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams
695e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        for (uint32_t x=0; x < w; x++) {
696565ac36ee479f9d7b83e2030ac9646a09cb886a1Jason Sams            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
697326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            oPtr ++;
698326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i1 += 2;
699326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams            i2 += 2;
700326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams        }
701326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    }
702326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
703326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
704afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip8(const Adapter2D &out, const Adapter2D &in) {
7052f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t w = out.getDimX();
7062f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    uint32_t h = out.getDimY();
7072f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
7082f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    for (uint32_t y=0; y < h; y++) {
7092f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
7102f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
7112f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
7122f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
7132f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        for (uint32_t x=0; x < w; x++) {
7142f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
7152f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            oPtr ++;
7162f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i1 += 2;
7172f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams            i2 += 2;
7182f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        }
7192f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    }
7202f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams}
7212f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams
722afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukstatic void mip(const Adapter2D &out, const Adapter2D &in) {
723afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    switch (out.getBaseType()->getElement()->getSizeBits()) {
724e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 32:
725e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip8888(out, in);
726e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
727e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    case 16:
728e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        mip565(out, in);
729e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams        break;
7302f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams    case 8:
7312f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        mip8(out, in);
7322f6d8617769b5fd6287404a31d4e10140ebdcf7eJason Sams        break;
733e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams    }
734e9f5c53929c6c46872c4e9ba7cc3d0e528f5ad01Jason Sams}
735326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
736366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Samsvoid rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
737366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Allocation *a = static_cast<Allocation *>(va);
738366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    a->syncAll(rsc, src);
73909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams    a->sendDirty();
740366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams}
741366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
742a23715148f7bda74e904fc553b70c9a49fd52a6eJason Samsvoid rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
74339f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
744c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    AllocationGenerateScriptMips(rsc, texAlloc);
74539f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk}
74639f2ef6fed00a99c5c389e12c4597884027d4858Alex Sakhartchouk
747837e388700a48084489ba59d1d8cc5ece68b1535Jason Samsvoid rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
748837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    Allocation *texAlloc = static_cast<Allocation *>(va);
749837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    const Type * t = texAlloc->getType();
750837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
751837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
752837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    if (s != dataLen) {
753837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
754837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams        return;
755837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    }
756837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
757837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams    memcpy(data, texAlloc->getPtr(), s);
758837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams}
759837e388700a48084489ba59d1d8cc5ece68b1535Jason Sams
7604b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
7614b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                          uint32_t count, const void *data, uint32_t sizeBytes) {
762326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7634b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, lod, count, data, sizeBytes);
7645f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7655f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
7664b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
7674b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                                 const void *data, uint32_t eoff, uint32_t sizeBytes) {
7685f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7694b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, y, data, eoff, sizeBytes);
7705f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams}
7715f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams
7724b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
7734b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                                 const void *data, uint32_t eoff, uint32_t sizeBytes) {
7745f0c84cf464dda719cef65fdc9b4d0980e86b98fJason Sams    Allocation *a = static_cast<Allocation *>(va);
7754b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->elementData(rsc, x, data, eoff, sizeBytes);
776326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
777326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
7784b45b8998e0d7038efaea80c70d23c086640b4e3Jason Samsvoid rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
7794b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams                          uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
780326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    Allocation *a = static_cast<Allocation *>(va);
7814b45b8998e0d7038efaea80c70d23c086640b4e3Jason Sams    a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
782326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
783326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
78470b83c111beceaf8fbb700580833e7fec99272cfAlex Sakhartchoukvoid rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t data_length) {
785e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    Allocation *a = static_cast<Allocation *>(va);
786e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams    a->read(data);
787e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams}
788e579df42e85d9e00f53c42ef1b78dbd209dba989Jason Sams
789afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
79096abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
79196abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize1D(rsc, dimX);
79296abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
79396abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
794afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
79596abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    Allocation *a = static_cast<Allocation *>(va);
79696abf819e50b59ba8cf886c13f894633eb0a24baJason Sams    a->resize2D(rsc, dimX, dimY);
79796abf819e50b59ba8cf886c13f894633eb0a24baJason Sams}
79896abf819e50b59ba8cf886c13f894633eb0a24baJason Sams
799c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsstatic void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
800f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Context *rsc = static_cast<Context *>(con);
801f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(va);
802f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
803f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    for (uint32_t face = 0; face < numFaces; face ++) {
804f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt(rsc, texAlloc);
805f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        Adapter2D adapt2(rsc, texAlloc);
806f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt.setFace(face);
807f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        adapt2.setFace(face);
808f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
809f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt.setLOD(lod);
810f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            adapt2.setLOD(lod + 1);
811f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk            mip(adapt2, adapt);
812f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk        }
813f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
814f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk}
815f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk
816c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
817c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       RsAllocationMipmapControl mips,
818c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                       uint32_t usages) {
819a2aab8be7a980791fc9d4e6c4d050d703b20bcf6Alex Sakhartchouk    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
820f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    alloc->incUserRef();
821f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return alloc;
822f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
823f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
824c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
825c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            RsAllocationMipmapControl mips,
826c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                            const void *data, size_t data_length, uint32_t usages) {
827366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
828f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
829c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
830f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
831f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    if (texAlloc == NULL) {
832f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        LOGE("Memory allocation failure");
833f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams        return NULL;
834f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
835f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
836366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
837ebc5019400a129b1f1e57bd1fe8200a21f8da00bJason Sams    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
838c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
839f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    }
840f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams
8417d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    texAlloc->deferredUploadToTexture(rsc);
842f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams    return texAlloc;
843f0c1df480304a72ce41e7d4b088319cbd7f0938aJason Sams}
84484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
845c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason SamsRsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
846c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                RsAllocationMipmapControl mips,
847c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams                                                const void *data, size_t data_length, uint32_t usages) {
848366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    Type *t = static_cast<Type *>(vtype);
84984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
85084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Cubemap allocation's faces should be Width by Width each.
85184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Source data should have 6 * Width by Width pixels
85284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    // Error checking is done in the java layer
853c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
85484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
85584e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    if (texAlloc == NULL) {
85684e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        LOGE("Memory allocation failure");
85784e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk        return NULL;
85884e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
85984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
8609f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t faceSize = t->getDimX();
8619f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
8629f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk    uint32_t copySize = faceSize * t->getElementSizeBytes();
8639f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk
86484e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint8_t *sourcePtr = (uint8_t*)data;
865366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams    for (uint32_t face = 0; face < 6; face ++) {
866366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        Adapter2D faceAdapter(rsc, texAlloc);
867366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        faceAdapter.setFace(face);
868366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
8699f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        for (uint32_t dI = 0; dI < faceSize; dI ++) {
8709f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk            memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
8719f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        }
872366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
873366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams        // Move the data pointer to the next cube face
8749f8bc4fb7e9e48088dc6b0496afb35b34fc4c5afAlex Sakhartchouk        sourcePtr += copySize;
875f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    }
876366c9c85196675437a8dd74c1cf6b63ddbde3d6aJason Sams
877f8aafcfad92fcf37d4b55c749601de22441ac9bfAlex Sakhartchouk    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
878c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams        AllocationGenerateScriptMips(rsc, texAlloc);
87984e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    }
88084e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk
8817d9c5ffccb7a5e682860f752403e5a03aed587beAlex Sakhartchouk    texAlloc->deferredUploadToTexture(rsc);
88284e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    return texAlloc;
88384e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk}
884099d7d33e55afeb3399f6e8cf8d665223ca94939Alex Sakhartchouk
885c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
886c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
887c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
888c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Samsconst void * rsaAllocationGetType(RsContext con, RsAllocation va) {
889c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    Allocation *a = static_cast<Allocation *>(va);
890c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    a->getType()->incUserRef();
891c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
892c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams    return a->getType();
893c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams}
894c975cf4a71b63ccbd20f1f3b3341c5f2e6025b45Jason Sams
89577d9f4bd05b2d2a161f30c12a2248f9c97eaac42Alex Sakhartchouk#endif //ANDROID_RS_SERIALIZE
896