rsdAllocation.cpp revision 41e373d91a60043afa0f9abd026218b49cbc1201
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
13741e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
13841e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        if (!drv->textureID) {
13941e373d91a60043afa0f9abd026218b49cbc1201Jason Sams            RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
14041e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        }
14141e373d91a60043afa0f9abd026218b49cbc1201Jason Sams        return;
14241e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    }
14341e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
144a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    if (!drv->glType || !drv->glFormat) {
145eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
146eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
147eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
148eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!alloc->getPtr()) {
149eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
150eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
151eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
152eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    bool isFirstUpload = false;
153eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
154eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->textureID) {
1552382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
156eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        isFirstUpload = true;
157eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
158eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
159eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    Upload2DTexture(rsc, alloc, isFirstUpload);
160eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
161eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
162eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (drv->mallocPtr) {
163eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            free(drv->mallocPtr);
164eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->mallocPtr = NULL;
165eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
166eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
167eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToTexture");
168eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
169eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
170eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
171eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
172eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
173a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    if (!drv->glFormat) {
174eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
175eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
176eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
177eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->renderTargetID) {
1782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
179eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
180eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (!drv->renderTargetID) {
181eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            // This should generally not happen
182af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
183eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            rsc->dumpDebug();
184eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            return;
185eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
1862382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
1872382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
188eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
189eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
190eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "AllocateRenderTarget");
191eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
192eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
193eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsstatic void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
194eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
195eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
196eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimY());
197eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(!alloc->mHal.state.type->getDimZ());
198eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
199eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
200eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
201eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
2022382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
203eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
204eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv->bufferID) {
205af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Upload to buffer object failed");
206eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
207eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
208eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
2092382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
2102382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
211eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                 drv->mallocPtr, GL_DYNAMIC_DRAW);
2122382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
213eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsdGLCheckError(rsc, "UploadToBufferObject");
214eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
215eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
216eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsbool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
217eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
218eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!drv) {
219eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return false;
220eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
221eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
222179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    void * ptr = alloc->mHal.state.usrPtr;
223eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (!ptr) {
224179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        ptr = malloc(alloc->mHal.state.type->getSizeBytes());
225179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        if (!ptr) {
226179e9a457095fea4c9e6d366c269754b882d05ddJason Sams            free(drv);
227179e9a457095fea4c9e6d366c269754b882d05ddJason Sams            return false;
228179e9a457095fea4c9e6d366c269754b882d05ddJason Sams        }
229eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
230eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
231eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->glTarget = GL_NONE;
232eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
233eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.hasFaces) {
234eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_CUBE_MAP;
235eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        } else {
236eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_TEXTURE_2D;
237eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
238eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
239eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
240eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            drv->glTarget = GL_ARRAY_BUFFER;
241eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
242eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
243eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
244a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
245a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams    drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
246a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
247a614ae175bbf97201b5e18984d814a1d3e86faa8Jason Sams
248eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drvState.mallocPtr = ptr;
249eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)ptr;
250eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = drv;
251eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (forceZero) {
252eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
253eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
254eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
255eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
256eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
257eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
258a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
259a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    drv->readBackFBO = NULL;
260a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
261eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    return true;
262eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
263eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
264eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
265eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
266eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
267eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->bufferID) {
268eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        // Causes a SW crash....
2696598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        //ALOGV(" mBufferID %i", mBufferID);
270eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //glDeleteBuffers(1, &mBufferID);
271eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        //mBufferID = 0;
272eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
273eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->textureID) {
2742382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
275eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->textureID = 0;
276eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
277eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->renderTargetID) {
2782382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
279eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->renderTargetID = 0;
280eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
281eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
282179e9a457095fea4c9e6d366c269754b882d05ddJason Sams    if (drv->mallocPtr && !alloc->mHal.state.usrPtr) {
283eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        free(drv->mallocPtr);
284eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->mallocPtr = NULL;
285eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
286a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (drv->readBackFBO != NULL) {
287a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        delete drv->readBackFBO;
288a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO = NULL;
289a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
290eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    free(drv);
291eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    alloc->mHal.drv = NULL;
292eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
293eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
294eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationResize(const Context *rsc, const Allocation *alloc,
295eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const Type *newType, bool zeroNew) {
296eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
297eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
298eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes());
299eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
300eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    // fixme
301eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr;
302eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
303eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t oldDimX = alloc->mHal.state.dimensionX;
304eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t dimX = newType->getDimX();
305eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
306eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (dimX > oldDimX) {
307eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const Element *e = alloc->mHal.state.type->getElement();
308eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint32_t stride = e->getSizeBytes();
309eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
310eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
311eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
312eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
313a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukstatic void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
314a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!alloc->getIsScript()) {
315a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return; // nothing to sync
316a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
317a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
318a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
319a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
320a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
321a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
322a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!drv->textureID && !drv->renderTargetID) {
323a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return; // nothing was rendered here yet, so nothing to sync
324a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
325a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (drv->readBackFBO == NULL) {
326a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO = new RsdFrameBufferObj();
327a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO->setColorTarget(drv, 0);
328a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
329a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                        alloc->getType()->getDimY());
330a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
331a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
332a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Bind the framebuffer object so we can read back from it
333a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    drv->readBackFBO->setActive(rsc);
334a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
335a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Do the readback
3362382aba4a55c6ae74789c478eead8fbd96593321Jason Sams    RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
337a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                 drv->glFormat, drv->glType, alloc->getPtr());
338a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
339a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Revert framebuffer to its original
340a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    lastFbo->setActive(rsc);
341a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
342eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
343eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
344eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
345eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         RsAllocationUsageType src) {
346eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
347eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
348a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
349a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if(!alloc->getIsRenderTarget()) {
350a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsc->setError(RS_ERROR_FATAL_DRIVER,
351a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                          "Attempting to sync allocation from render target, "
352a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                          "for non-render target allocation");
353a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
354a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
355a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                                 "render target");
356a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else {
357a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            rsdAllocationSyncFromFBO(rsc, alloc);
358a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
359eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        return;
360eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
361eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
362eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
363eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
364eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
365eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToTexture(rsc, alloc);
366eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
367eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
368eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            AllocateRenderTarget(rsc, alloc);
369eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
370eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
371eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
372eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        UploadToBufferObject(rsc, alloc);
373eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
374eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
375eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = false;
376eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
377eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
378eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
379eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
380eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
381eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
382eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
38341e373d91a60043afa0f9abd026218b49cbc1201Jason Samsint32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
38441e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
38541e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    UploadToTexture(rsc, alloc);
38641e373d91a60043afa0f9abd026218b49cbc1201Jason Sams    return drv->textureID;
38741e373d91a60043afa0f9abd026218b49cbc1201Jason Sams}
38841e373d91a60043afa0f9abd026218b49cbc1201Jason Sams
389eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
390eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t lod, uint32_t count,
391eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         const void *data, uint32_t sizeBytes) {
392eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
393eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
394eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
395eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
396eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * xoff;
397eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t size = count * eSize;
398eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
399eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
400eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->incRefs(data, count);
401eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        alloc->decRefs(ptr, count);
402eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
403eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
404eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, size);
405eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
406eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
407eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
408eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
409eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
410eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
411eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
412eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
413eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
414eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t lineSize = eSize * w;
415eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t destW = alloc->mHal.state.dimensionX;
416eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
417eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (drv->mallocPtr) {
418eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        const uint8_t *src = static_cast<const uint8_t *>(data);
419eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        uint8_t *dst = drv->mallocPtr;
420eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
421eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
422eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        for (uint32_t line=yoff; line < (yoff+h); line++) {
423eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            if (alloc->mHal.state.hasReferences) {
424eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->incRefs(src, w);
425eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                alloc->decRefs(dst, w);
426eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            }
427eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            memcpy(dst, src, lineSize);
428eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            src += lineSize;
429eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams            dst += destW * eSize;
430eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        }
431eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        drv->uploadDeferred = true;
432eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    } else {
4332382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
434eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
435eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
436eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
437eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
438eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
439eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t lod, RsAllocationCubemapFace face,
440eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                         uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
441eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
442eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
443eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
44474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
44574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
44674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstLod, uint32_t count,
44774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
448a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcLod) {
449a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
450a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
451a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukuint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc,
452a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      uint32_t xoff, uint32_t yoff, uint32_t lod,
453a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      RsAllocationCubemapFace face) {
454a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr());
455a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    ptr += alloc->getType()->getLODOffset(lod, xoff, yoff);
456a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
457a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (face != 0) {
458a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint32_t totalSizeBytes = alloc->getType()->getSizeBytes();
459a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint32_t faceOffset = totalSizeBytes / 6;
460a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        ptr += faceOffset * (uint32_t)face;
461a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
462a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    return ptr;
463a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
464a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
465a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
466a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
467a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      const android::renderscript::Allocation *dstAlloc,
468a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
469a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
470a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      const android::renderscript::Allocation *srcAlloc,
471a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
472a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      RsAllocationCubemapFace srcFace) {
473a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
474a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    for (uint32_t i = 0; i < h; i ++) {
475a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
476a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
477a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        memcpy(dstPtr, srcPtr, w * elementSize);
478a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
479af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
4800a44ab45c739f00f457874418e7384492e4df979Stephen Hines        //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
481a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
48274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
48374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
48474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
48574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
48674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
48774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
48874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
48974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
49074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               RsAllocationCubemapFace srcFace) {
491a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
492a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
493a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                             "yet implemented.");
494a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return;
495a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
496a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
497a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                     dstLod, dstFace, w, h, srcAlloc,
498a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                     srcXoff, srcYoff, srcLod, srcFace);
49974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
50074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
50174a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchoukvoid rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
50274a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *dstAlloc,
50374a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
50474a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t dstLod, RsAllocationCubemapFace dstFace,
50574a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t w, uint32_t h, uint32_t d,
50674a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               const android::renderscript::Allocation *srcAlloc,
50774a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
50874a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk                               uint32_t srcLod, RsAllocationCubemapFace srcFace) {
50974a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk}
51074a827988567a9d65954bb0d825a3ba4a97e2947Alex Sakhartchouk
511eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
512eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x,
513eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
514eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
515eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
516eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
517eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
518eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * x;
519eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
520eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
521eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
522eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
523eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
524eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
525eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
526eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
527eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
528eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
529eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
530eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
531eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
532eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Samsvoid rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
533eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                uint32_t x, uint32_t y,
534eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                                const void *data, uint32_t cIdx, uint32_t sizeBytes) {
535eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
536eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
537eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
538eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    uint8_t * ptr = drv->mallocPtr;
539eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += eSize * (x + y * alloc->mHal.state.dimensionX);
540eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
541eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
542eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
543eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
544eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    if (alloc->mHal.state.hasReferences) {
545eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->incRefs(data);
546eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        e->decRefs(ptr);
547eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    }
548eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
549eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    memcpy(ptr, data, sizeBytes);
550eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    drv->uploadDeferred = true;
551eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams}
552eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
553eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
554