rsdAllocation.cpp revision 179e9a457095fea4c9e6d366c269754b882d05dd
1eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams/*
2eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Copyright (C) 2011 The Android Open Source Project
3eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
4eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * you may not use this file except in compliance with the License.
6eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * You may obtain a copy of the License at
7eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
8eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams *
10eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * Unless required by applicable law or agreed to in writing, software
11eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * See the License for the specific language governing permissions and
14eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams * limitations under the License.
15eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams */
16eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
17eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
18eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdCore.h"
19eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdBcc.h"
20eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdRuntime.h"
21eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h"
22a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include "rsdFrameBufferObj.h"
23eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
24eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsAllocation.h"
25eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
26eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES/gl.h>
27eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES2/gl2.h>
28eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include <GLES/glext.h>
29eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
30eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsusing namespace android;
31eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsusing namespace android::renderscript;
32eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
33eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
34eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
35eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsconst static GLenum gFaceOrder[] = {
36eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
37eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
38eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
39eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
40eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
41eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
42eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams};
43eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
44eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
45a614ae175bbf97201b5e18984d814a1d3e86faa8Jason SamsGLenum rsdTypeToGLType(RsDataType t) {
46a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    switch (t) {
47a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
48a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
49a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;
50a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
51a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
52a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
53a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
54a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
55a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_SIGNED_8:      return GL_BYTE;
56a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_TYPE_SIGNED_16:     return GL_SHORT;
57a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    default:    break;
58a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    }
59a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    return 0;
60a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams}
61a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
62a614ae175bbf97201b5e18984d814a1d3e86faa8Jason SamsGLenum rsdKindToGLFormat(RsDataKind k) {
63a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    switch (k) {
64a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
65a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_A: return GL_ALPHA;
66a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
67a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_RGB: return GL_RGB;
68a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
69a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
70a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    default: break;
71a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    }
72a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    return 0;
73a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams}
74a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
75a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
762382aba4a55c6ae74789c478eead8fbd96593321Jason Samsstatic void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
772382aba4a55c6ae74789c478eead8fbd96593321Jason Sams                            uint32_t xoff, uint32_t yoff, uint32_t lod,
782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams                            RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
79eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
80eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
81eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(drv->textureID);
822382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
832382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
84eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    GLenum t = GL_TEXTURE_2D;
85eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasFaces) {
86eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        t = gFaceOrder[face];
87eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
882382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
89eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
90eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
91eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
92eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
93eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
94eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
952382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
962382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
97eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
98eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t faceCount = 1;
99eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasFaces) {
100eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        faceCount = 6;
101eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
102eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
103eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "Upload2DTexture 1 ");
104eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    for (uint32_t face = 0; face < faceCount; face ++) {
105eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
106eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            const uint8_t *p = (const uint8_t *)drv->mallocPtr;
107eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            p += alloc->mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
108eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
109eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            GLenum t = GL_TEXTURE_2D;
110eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (alloc->mHal.state.hasFaces) {
111eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                t = gFaceOrder[face];
112eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
113eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
114eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (isFirstUpload) {
1152382aba4a55c6ae74789c478eead8fbd96593321Jason Sams                RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
116eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                             alloc->mHal.state.type->getLODDimX(lod),
117eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                             alloc->mHal.state.type->getLODDimY(lod),
118a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams                             0, drv->glFormat, drv->glType, p);
119eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            } else {
1202382aba4a55c6ae74789c478eead8fbd96593321Jason Sams                RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
121eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                alloc->mHal.state.type->getLODDimX(lod),
122eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                alloc->mHal.state.type->getLODDimY(lod),
123a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams                                drv->glFormat, drv->glType, p);
124eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
125eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
126eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
127eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
128eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
1292382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
130eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
131eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "Upload2DTexture");
132eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
133eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
134eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void UploadToTexture(const Context *rsc, const Allocation *alloc) {
135eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
136eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
137a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    if (!drv->glType || !drv->glFormat) {
138eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
139eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
140eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
141eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc->getPtr()) {
142eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
143eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
144eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    bool isFirstUpload = false;
146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
147eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->textureID) {
1482382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
149eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        isFirstUpload = true;
150eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
151eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
152eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Upload2DTexture(rsc, alloc, isFirstUpload);
153eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
154eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
155eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (drv->mallocPtr) {
156eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            free(drv->mallocPtr);
157eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->mallocPtr = NULL;
158eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
159eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
160eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToTexture");
161eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
162eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
163eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
164eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
165eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
166a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    if (!drv->glFormat) {
167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
168eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
169eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
170eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->renderTargetID) {
1712382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
173eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (!drv->renderTargetID) {
174eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            // This should generally not happen
175eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            LOGE("allocateRenderTarget failed to gen mRenderTargetID");
176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            rsc->dumpDebug();
177eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            return;
178eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
1792382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
1802382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
181eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
182eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
183eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "AllocateRenderTarget");
184eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
185eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
186eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
187eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
188eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
189eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimY());
190eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimZ());
191eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
192eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
193eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
194eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
1952382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
196eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
197eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
198eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        LOGE("Upload to buffer object failed");
199eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
200eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
201eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
2022382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
2032382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
204eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                 drv->mallocPtr, GL_DYNAMIC_DRAW);
2052382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
206eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToBufferObject");
207eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
208eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
209eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsbool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
210eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
211eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv) {
212eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return false;
213eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
214eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
215179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    void * ptr = alloc->mHal.state.usrPtr;
216eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!ptr) {
217179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        ptr = malloc(alloc->mHal.state.type->getSizeBytes());
218179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        if (!ptr) {
219179e9a457095fea4c9e6d366c269754b882d05ddJason Sams            free(drv);
220179e9a457095fea4c9e6d366c269754b882d05ddJason Sams            return false;
221179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        }
222eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
223eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
224eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->glTarget = GL_NONE;
225eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
226eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.hasFaces) {
227eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_CUBE_MAP;
228eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        } else {
229eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_2D;
230eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
231eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
232eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
233eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_ARRAY_BUFFER;
234eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
235eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
236eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
237a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
238a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
239a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
240a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
241eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drvState.mallocPtr = ptr;
242eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)ptr;
243eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = drv;
244eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (forceZero) {
245eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
246eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
247eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
248eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
249eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
250eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
251a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
252a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    drv->readBackFBO = NULL;
253a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
254eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return true;
255eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
256eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
257eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
258eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
259eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
260eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->bufferID) {
261eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        // Causes a SW crash....
2626598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        //ALOGV(" mBufferID %i", mBufferID);
263eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //glDeleteBuffers(1, &mBufferID);
264eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //mBufferID = 0;
265eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
266eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->textureID) {
2672382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
268eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->textureID = 0;
269eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
270eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->renderTargetID) {
2712382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
272eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->renderTargetID = 0;
273eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
274eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
275179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    if (drv->mallocPtr && !alloc->mHal.state.usrPtr) {
276eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        free(drv->mallocPtr);
277eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->mallocPtr = NULL;
278eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
279a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (drv->readBackFBO != NULL) {
280a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        delete drv->readBackFBO;
281a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO = NULL;
282a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
283eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    free(drv);
284eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = NULL;
285eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
286eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
287eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationResize(const Context *rsc, const Allocation *alloc,
288eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const Type *newType, bool zeroNew) {
289eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
290eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
291eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes());
292eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
293eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    // fixme
294eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr;
295eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
296eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t oldDimX = alloc->mHal.state.dimensionX;
297eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t dimX = newType->getDimX();
298eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
299eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (dimX > oldDimX) {
300eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const Element *e = alloc->mHal.state.type->getElement();
301eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint32_t stride = e->getSizeBytes();
302eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
303eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
304eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
305eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
306a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatic void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
307a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!alloc->getIsScript()) {
308a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return; // nothing to sync
309a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
310a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
311a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
312a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
313a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
314a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
315a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!drv->textureID && !drv->renderTargetID) {
316a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return; // nothing was rendered here yet, so nothing to sync
317a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
318a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (drv->readBackFBO == NULL) {
319a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO = new RsdFrameBufferObj();
320a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO->setColorTarget(drv, 0);
321a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
322a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                        alloc->getType()->getDimY());
323a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
324a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
325a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Bind the framebuffer object so we can read back from it
326a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    drv->readBackFBO->setActive(rsc);
327a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
328a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Do the readback
3292382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
330a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                 drv->glFormat, drv->glType, alloc->getPtr());
331a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
332a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Revert framebuffer to its original
333a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    lastFbo->setActive(rsc);
334a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
335eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
336eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
337eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
338eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         RsAllocationUsageType src) {
339eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
340eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
341a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
342a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if(!alloc->getIsRenderTarget()) {
343a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsc->setError(RS_ERROR_FATAL_DRIVER,
344a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                          "Attempting to sync allocation from render target, "
345a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                          "for non-render target allocation");
346a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
347a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
348a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                                 "render target");
349a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else {
350a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsdAllocationSyncFromFBO(rsc, alloc);
351a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
352eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
353eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
354eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
355eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
356eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
357eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
358eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToTexture(rsc, alloc);
359eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
360eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
361eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            AllocateRenderTarget(rsc, alloc);
362eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
363eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
364eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
365eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToBufferObject(rsc, alloc);
366eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
367eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
368eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = false;
369eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
370eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
371eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
372eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
373eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
374eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
375eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
376eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
377eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t lod, uint32_t count,
378eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const void *data, uint32_t sizeBytes) {
379eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
380eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
381eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
382eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
383eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * xoff;
384eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t size = count * eSize;
385eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
386eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
387eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->incRefs(data, count);
388eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->decRefs(ptr, count);
389eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
390eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
391eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, size);
392eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
393eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
394eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
395eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
396eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
397eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
398eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
399eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
400eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
401eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t lineSize = eSize * w;
402eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t destW = alloc->mHal.state.dimensionX;
403eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
404eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->mallocPtr) {
405eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const uint8_t *src = static_cast<const uint8_t *>(data);
406eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint8_t *dst = drv->mallocPtr;
407eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
408eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
409eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        for (uint32_t line=yoff; line < (yoff+h); line++) {
410eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (alloc->mHal.state.hasReferences) {
411eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->incRefs(src, w);
412eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->decRefs(dst, w);
413eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
414eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            memcpy(dst, src, lineSize);
415eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            src += lineSize;
416eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            dst += destW * eSize;
417eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
418eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
419eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
4202382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
421eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
422eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
423eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
424eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
425eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
426eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t lod, RsAllocationCubemapFace face,
427eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
428eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
429eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
430eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
43174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
43274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
43374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstLod, uint32_t count,
43474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
435a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcLod) {
436a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
437a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
438a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukuint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc,
439a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      uint32_t xoff, uint32_t yoff, uint32_t lod,
440a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      RsAllocationCubemapFace face) {
441a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr());
442a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    ptr += alloc->getType()->getLODOffset(lod, xoff, yoff);
443a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
444a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (face != 0) {
445a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint32_t totalSizeBytes = alloc->getType()->getSizeBytes();
446a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint32_t faceOffset = totalSizeBytes / 6;
447a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        ptr += faceOffset * (uint32_t)face;
448a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
449a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    return ptr;
450a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
451a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
452a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
453a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
454a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      const android::renderscript::Allocation *dstAlloc,
455a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
456a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
457a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      const android::renderscript::Allocation *srcAlloc,
458a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
459a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      RsAllocationCubemapFace srcFace) {
460a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
461a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    for (uint32_t i = 0; i < h; i ++) {
462a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
463a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
464a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        memcpy(dstPtr, srcPtr, w * elementSize);
465a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
4660a44ab45c739f00f457874418e7384492e4df979Stephen Hines        //LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
4670a44ab45c739f00f457874418e7384492e4df979Stephen Hines        //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
468a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
46974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
47074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
47174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
47274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
47374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
47474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
47574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
47674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
47774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocationCubemapFace srcFace) {
478a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
479a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
480a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                             "yet implemented.");
481a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return;
482a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
483a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
484a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                     dstLod, dstFace, w, h, srcAlloc,
485a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                     srcXoff, srcYoff, srcLod, srcFace);
48674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
48774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
48874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
48974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
49074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
49174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstLod, RsAllocationCubemapFace dstFace,
49274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t w, uint32_t h, uint32_t d,
49374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
49474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
49574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcLod, RsAllocationCubemapFace srcFace) {
49674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
49774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
498eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
499eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x,
500eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
501eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
502eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
503eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
504eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
505eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * x;
506eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
507eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
508eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
509eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
510eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
511eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
512eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
513eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
514eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
515eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
516eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
517eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
518eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
519eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
520eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x, uint32_t y,
521eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
522eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
523eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
524eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
525eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
526eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * (x + y * alloc->mHal.state.dimensionX);
527eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
528eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
529eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
530eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
531eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
532eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
533eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
534eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
535eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
536eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
537eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
538eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
539eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
540eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
541