blob: 249daa5070a3f9506e0dd9eb54e9b9d23b669ca1 [file] [log] [blame]
Jason Samseb4fe182011-05-26 16:33:01 -07001/*
Jason Samsbc0ca6b2013-02-15 18:13:43 -08002 * Copyright (C) 2013 The Android Open Source Project
Jason Samseb4fe182011-05-26 16:33:01 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jason Samseb4fe182011-05-26 16:33:01 -070017#include "rsdCore.h"
Jason Samseb4fe182011-05-26 16:33:01 -070018#include "rsdAllocation.h"
19
20#include "rsAllocation.h"
21
Miao Wang62237212017-02-27 15:19:36 -080022#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -080023#include "system/window.h"
Jason Sams7ac2a4d2012-02-15 12:04:24 -080024#include "ui/Rect.h"
25#include "ui/GraphicBufferMapper.h"
Tim Murray0b575de2013-03-15 15:56:43 -070026#endif
Jason Sams93eacc72012-12-18 14:26:57 -080027
Stephen Hines10f31702013-08-15 17:30:12 -070028#ifdef RS_COMPATIBILITY_LIB
29#include "rsCompatibilityLib.h"
30#else
Jason Sams93eacc72012-12-18 14:26:57 -080031#include "rsdFrameBufferObj.h"
Andy McFadden58fd6a52012-12-18 09:50:03 -080032#include "gui/GLConsumer.h"
Jason Sams733396b2013-02-22 12:46:18 -080033#include "gui/CpuConsumer.h"
34#include "gui/Surface.h"
Jason Sams93eacc72012-12-18 14:26:57 -080035#include "hardware/gralloc.h"
Jason Sams7ac2a4d2012-02-15 12:04:24 -080036
Jason Samseb4fe182011-05-26 16:33:01 -070037#include <GLES/gl.h>
38#include <GLES2/gl2.h>
39#include <GLES/glext.h>
Jason Sams93eacc72012-12-18 14:26:57 -080040#endif
Jason Samseb4fe182011-05-26 16:33:01 -070041
Chih-Hung Hsiehe939ce72016-11-15 16:27:11 -080042#ifndef RS_COMPATIBILITY_LIB
43using android::GraphicBufferMapper;
44using android::PIXEL_FORMAT_RGBA_8888;
45using android::Rect;
46#endif
47
48using android::renderscript::Allocation;
49using android::renderscript::Context;
50using android::renderscript::Element;
51using android::renderscript::Type;
52using android::renderscript::rs_allocation;
53using android::renderscript::rsBoxFilter565;
54using android::renderscript::rsBoxFilter8888;
55using android::renderscript::rsMax;
56using android::renderscript::rsRound;
Jason Samseb4fe182011-05-26 16:33:01 -070057
Jason Sams93eacc72012-12-18 14:26:57 -080058#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -070059const static GLenum gFaceOrder[] = {
60 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
61 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
62 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
63 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
64 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
65 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
66};
67
Jason Samsa614ae12011-05-26 17:05:51 -070068GLenum rsdTypeToGLType(RsDataType t) {
69 switch (t) {
70 case RS_TYPE_UNSIGNED_5_6_5: return GL_UNSIGNED_SHORT_5_6_5;
71 case RS_TYPE_UNSIGNED_5_5_5_1: return GL_UNSIGNED_SHORT_5_5_5_1;
72 case RS_TYPE_UNSIGNED_4_4_4_4: return GL_UNSIGNED_SHORT_4_4_4_4;
73
74 //case RS_TYPE_FLOAT_16: return GL_HALF_FLOAT;
75 case RS_TYPE_FLOAT_32: return GL_FLOAT;
76 case RS_TYPE_UNSIGNED_8: return GL_UNSIGNED_BYTE;
77 case RS_TYPE_UNSIGNED_16: return GL_UNSIGNED_SHORT;
78 case RS_TYPE_SIGNED_8: return GL_BYTE;
79 case RS_TYPE_SIGNED_16: return GL_SHORT;
80 default: break;
81 }
82 return 0;
83}
84
85GLenum rsdKindToGLFormat(RsDataKind k) {
86 switch (k) {
87 case RS_KIND_PIXEL_L: return GL_LUMINANCE;
88 case RS_KIND_PIXEL_A: return GL_ALPHA;
89 case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
90 case RS_KIND_PIXEL_RGB: return GL_RGB;
91 case RS_KIND_PIXEL_RGBA: return GL_RGBA;
92 case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
93 default: break;
94 }
95 return 0;
96}
Jason Sams93eacc72012-12-18 14:26:57 -080097#endif
Jason Samsa614ae12011-05-26 17:05:51 -070098
Jason Sams807fdc42012-07-25 17:55:39 -070099uint8_t *GetOffsetPtr(const android::renderscript::Allocation *alloc,
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700100 uint32_t xoff, uint32_t yoff, uint32_t zoff,
101 uint32_t lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -0800102 uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
103 ptr += face * alloc->mHal.drvState.faceOffset;
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700104 ptr += zoff * alloc->mHal.drvState.lod[lod].dimY * alloc->mHal.drvState.lod[lod].stride;
Jason Sams709a0972012-11-15 18:18:04 -0800105 ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
Jason Sams807fdc42012-07-25 17:55:39 -0700106 ptr += xoff * alloc->mHal.state.elementSizeBytes;
107 return ptr;
108}
109
Jason Samsa614ae12011-05-26 17:05:51 -0700110
Jason Sams2382aba2011-09-13 15:41:01 -0700111static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
112 uint32_t xoff, uint32_t yoff, uint32_t lod,
113 RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
Jason Sams93eacc72012-12-18 14:26:57 -0800114#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700115 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
116
Jason Samseb4fe182011-05-26 16:33:01 -0700117 rsAssert(drv->textureID);
Jason Sams2382aba2011-09-13 15:41:01 -0700118 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
119 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700120 GLenum t = GL_TEXTURE_2D;
121 if (alloc->mHal.state.hasFaces) {
122 t = gFaceOrder[face];
123 }
Jason Sams2382aba2011-09-13 15:41:01 -0700124 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
Jason Sams93eacc72012-12-18 14:26:57 -0800125#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700126}
127
128
Jason Sams93eacc72012-12-18 14:26:57 -0800129#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700130static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
131 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
132
Jason Sams2382aba2011-09-13 15:41:01 -0700133 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
134 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700135
136 uint32_t faceCount = 1;
137 if (alloc->mHal.state.hasFaces) {
138 faceCount = 6;
139 }
140
141 rsdGLCheckError(rsc, "Upload2DTexture 1 ");
142 for (uint32_t face = 0; face < faceCount; face ++) {
143 for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700144 const uint8_t *p = GetOffsetPtr(alloc, 0, 0, 0, lod, (RsAllocationCubemapFace)face);
Jason Samseb4fe182011-05-26 16:33:01 -0700145
146 GLenum t = GL_TEXTURE_2D;
147 if (alloc->mHal.state.hasFaces) {
148 t = gFaceOrder[face];
149 }
150
151 if (isFirstUpload) {
Jason Sams2382aba2011-09-13 15:41:01 -0700152 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
Jason Samseb4fe182011-05-26 16:33:01 -0700153 alloc->mHal.state.type->getLODDimX(lod),
154 alloc->mHal.state.type->getLODDimY(lod),
Jason Samsa614ae12011-05-26 17:05:51 -0700155 0, drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700156 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700157 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
Jason Samseb4fe182011-05-26 16:33:01 -0700158 alloc->mHal.state.type->getLODDimX(lod),
159 alloc->mHal.state.type->getLODDimY(lod),
Jason Samsa614ae12011-05-26 17:05:51 -0700160 drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700161 }
162 }
163 }
164
165 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700166 RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
Jason Samseb4fe182011-05-26 16:33:01 -0700167 }
168 rsdGLCheckError(rsc, "Upload2DTexture");
169}
Jason Sams93eacc72012-12-18 14:26:57 -0800170#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700171
172static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800173#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700174 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
175
Jason Sams3522f402012-03-23 11:47:26 -0700176 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
Jason Sams41e373d2012-01-13 14:01:20 -0800177 if (!drv->textureID) {
178 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
179 }
180 return;
181 }
182
Jason Samsa614ae12011-05-26 17:05:51 -0700183 if (!drv->glType || !drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700184 return;
185 }
186
Jason Sams709a0972012-11-15 18:18:04 -0800187 if (!alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700188 return;
189 }
190
191 bool isFirstUpload = false;
192
193 if (!drv->textureID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700194 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
Jason Samseb4fe182011-05-26 16:33:01 -0700195 isFirstUpload = true;
196 }
197
198 Upload2DTexture(rsc, alloc, isFirstUpload);
199
200 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Jason Sams709a0972012-11-15 18:18:04 -0800201 if (alloc->mHal.drvState.lod[0].mallocPtr) {
202 free(alloc->mHal.drvState.lod[0].mallocPtr);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700203 alloc->mHal.drvState.lod[0].mallocPtr = nullptr;
Jason Samseb4fe182011-05-26 16:33:01 -0700204 }
205 }
206 rsdGLCheckError(rsc, "UploadToTexture");
Jason Sams93eacc72012-12-18 14:26:57 -0800207#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700208}
209
210static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800211#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700212 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
213
Jason Samsa614ae12011-05-26 17:05:51 -0700214 if (!drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700215 return;
216 }
217
218 if (!drv->renderTargetID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700219 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
Jason Samseb4fe182011-05-26 16:33:01 -0700220
221 if (!drv->renderTargetID) {
222 // This should generally not happen
Steve Blockaf12ac62012-01-06 19:20:56 +0000223 ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
Jason Samseb4fe182011-05-26 16:33:01 -0700224 rsc->dumpDebug();
225 return;
226 }
Jason Sams2382aba2011-09-13 15:41:01 -0700227 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
228 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
Jason Samsa572aca2013-01-09 11:52:26 -0800229 alloc->mHal.drvState.lod[0].dimX, alloc->mHal.drvState.lod[0].dimY);
Jason Samseb4fe182011-05-26 16:33:01 -0700230 }
231 rsdGLCheckError(rsc, "AllocateRenderTarget");
Jason Sams93eacc72012-12-18 14:26:57 -0800232#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700233}
234
235static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800236#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700237 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
238
239 rsAssert(!alloc->mHal.state.type->getDimY());
240 rsAssert(!alloc->mHal.state.type->getDimZ());
241
242 //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
243
244 if (!drv->bufferID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700245 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
Jason Samseb4fe182011-05-26 16:33:01 -0700246 }
247 if (!drv->bufferID) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000248 ALOGE("Upload to buffer object failed");
Jason Samseb4fe182011-05-26 16:33:01 -0700249 drv->uploadDeferred = true;
250 return;
251 }
Jason Sams2382aba2011-09-13 15:41:01 -0700252 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
Jason Sams61656a72013-09-03 16:21:18 -0700253 RSD_CALL_GL(glBufferData, drv->glTarget,
254 alloc->mHal.state.type->getPackedSizeBytes(),
255 alloc->mHal.drvState.lod[0].mallocPtr, GL_DYNAMIC_DRAW);
Jason Sams2382aba2011-09-13 15:41:01 -0700256 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
Jason Samseb4fe182011-05-26 16:33:01 -0700257 rsdGLCheckError(rsc, "UploadToBufferObject");
Jason Sams93eacc72012-12-18 14:26:57 -0800258#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700259}
260
Tim Murray0b575de2013-03-15 15:56:43 -0700261
Jason Sams9d8e5af2013-02-28 14:00:08 -0800262static size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
Pirama Arumuga Nainarb010bc02015-06-18 10:32:21 -0700263#ifndef RS_COMPATIBILITY_LIB
264 // For the flexible YCbCr format, layout is initialized during call to
265 // Allocation::ioReceive. Return early and avoid clobberring any
266 // pre-existing layout.
267 if (yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
268 return 0;
269 }
270#endif
271
Jason Sams733396b2013-02-22 12:46:18 -0800272 // YUV only supports basic 2d
273 // so we can stash the plane pointers in the mipmap levels.
Jason Sams9d8e5af2013-02-28 14:00:08 -0800274 size_t uvSize = 0;
Jason Sams61656a72013-09-03 16:21:18 -0700275 state->lod[1].dimX = state->lod[0].dimX / 2;
276 state->lod[1].dimY = state->lod[0].dimY / 2;
277 state->lod[2].dimX = state->lod[0].dimX / 2;
278 state->lod[2].dimY = state->lod[0].dimY / 2;
279 state->yuv.shift = 1;
280 state->yuv.step = 1;
281 state->lodCount = 3;
282
Jason Sams733396b2013-02-22 12:46:18 -0800283 switch(yuv) {
284 case HAL_PIXEL_FORMAT_YV12:
Jason Sams4961cce2013-04-11 16:11:46 -0700285 state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
286 state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
Jason Sams733396b2013-02-22 12:46:18 -0800287 (state->lod[0].stride * state->lod[0].dimY);
Jason Sams9d8e5af2013-02-28 14:00:08 -0800288 uvSize += state->lod[2].stride * state->lod[2].dimY;
Jason Sams733396b2013-02-22 12:46:18 -0800289
Jason Sams4961cce2013-04-11 16:11:46 -0700290 state->lod[1].stride = state->lod[2].stride;
291 state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
292 (state->lod[2].stride * state->lod[2].dimY);
293 uvSize += state->lod[1].stride * state->lod[2].dimY;
Jason Sams733396b2013-02-22 12:46:18 -0800294 break;
295 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
Jason Sams61656a72013-09-03 16:21:18 -0700296 //state->lod[1].dimX = state->lod[0].dimX;
Jason Sams733396b2013-02-22 12:46:18 -0800297 state->lod[1].stride = state->lod[0].stride;
Jason Sams61656a72013-09-03 16:21:18 -0700298 state->lod[2].stride = state->lod[0].stride;
299 state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
Jason Sams733396b2013-02-22 12:46:18 -0800300 (state->lod[0].stride * state->lod[0].dimY);
Jason Sams61656a72013-09-03 16:21:18 -0700301 state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) + 1;
Jason Sams9d8e5af2013-02-28 14:00:08 -0800302 uvSize += state->lod[1].stride * state->lod[1].dimY;
Jason Sams61656a72013-09-03 16:21:18 -0700303 state->yuv.step = 2;
Jason Sams733396b2013-02-22 12:46:18 -0800304 break;
305 default:
306 rsAssert(0);
307 }
Jason Sams9d8e5af2013-02-28 14:00:08 -0800308 return uvSize;
Jason Sams733396b2013-02-22 12:46:18 -0800309}
310
Jason Sams463bfce2012-08-21 13:54:42 -0700311static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
Miao Wang47a58812015-07-23 21:59:16 -0700312 const Type *type, uint8_t *ptr, size_t requiredAlignment) {
Jason Sams709a0972012-11-15 18:18:04 -0800313 alloc->mHal.drvState.lod[0].dimX = type->getDimX();
314 alloc->mHal.drvState.lod[0].dimY = type->getDimY();
Jason Samsf2b611e2012-12-27 19:05:22 -0800315 alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
Jason Sams709a0972012-11-15 18:18:04 -0800316 alloc->mHal.drvState.lod[0].mallocPtr = 0;
Miao Wang47a58812015-07-23 21:59:16 -0700317 // Stride needs to be aligned to a boundary defined by requiredAlignment!
Stephen Hines94999c32013-02-05 16:58:22 -0800318 size_t stride = alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
Miao Wang47a58812015-07-23 21:59:16 -0700319 alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
Jason Sams709a0972012-11-15 18:18:04 -0800320 alloc->mHal.drvState.lodCount = type->getLODCount();
321 alloc->mHal.drvState.faceCount = type->getDimFaces();
Jason Sams807fdc42012-07-25 17:55:39 -0700322
323 size_t offsets[Allocation::MAX_LOD];
324 memset(offsets, 0, sizeof(offsets));
325
Jason Sams709a0972012-11-15 18:18:04 -0800326 size_t o = alloc->mHal.drvState.lod[0].stride * rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
327 rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
Jason Samsd06653c2014-08-01 16:18:33 -0700328 if (alloc->mHal.state.yuv) {
329 o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
330
331 for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
332 offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
333 }
334 } else if(alloc->mHal.drvState.lodCount > 1) {
Jason Sams709a0972012-11-15 18:18:04 -0800335 uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
336 uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
337 uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
338 for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
339 alloc->mHal.drvState.lod[lod].dimX = tx;
340 alloc->mHal.drvState.lod[lod].dimY = ty;
341 alloc->mHal.drvState.lod[lod].dimZ = tz;
Stephen Hines94999c32013-02-05 16:58:22 -0800342 alloc->mHal.drvState.lod[lod].stride =
Miao Wang47a58812015-07-23 21:59:16 -0700343 rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
Jason Sams807fdc42012-07-25 17:55:39 -0700344 offsets[lod] = o;
Jason Sams709a0972012-11-15 18:18:04 -0800345 o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
Jason Sams807fdc42012-07-25 17:55:39 -0700346 if (tx > 1) tx >>= 1;
347 if (ty > 1) ty >>= 1;
348 if (tz > 1) tz >>= 1;
349 }
350 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800351
Jason Sams709a0972012-11-15 18:18:04 -0800352 alloc->mHal.drvState.faceOffset = o;
Jason Sams807fdc42012-07-25 17:55:39 -0700353
Jason Sams709a0972012-11-15 18:18:04 -0800354 alloc->mHal.drvState.lod[0].mallocPtr = ptr;
355 for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
356 alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
Jason Sams463bfce2012-08-21 13:54:42 -0700357 }
Jason Sams463bfce2012-08-21 13:54:42 -0700358
Jason Sams709a0972012-11-15 18:18:04 -0800359 size_t allocSize = alloc->mHal.drvState.faceOffset;
360 if(alloc->mHal.drvState.faceCount) {
Jason Sams463bfce2012-08-21 13:54:42 -0700361 allocSize *= 6;
362 }
363
364 return allocSize;
365}
366
Miao Wang47a58812015-07-23 21:59:16 -0700367static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
368 const Type *type, uint8_t *ptr) {
369 return AllocationBuildPointerTable(rsc, alloc, type, ptr, Allocation::kMinimumRSAlignment);
370}
371
372static uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero, size_t requiredAlignment) {
373 // We align all allocations to a boundary defined by requiredAlignment.
374 uint8_t* ptr = (uint8_t *)memalign(requiredAlignment, allocSize);
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800375 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700376 return nullptr;
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800377 }
378 if (forceZero) {
379 memset(ptr, 0, allocSize);
380 }
381 return ptr;
382}
383
Miao Wang47a58812015-07-23 21:59:16 -0700384bool rsdAllocationInitStrided(const Context *rsc, Allocation *alloc, bool forceZero, size_t requiredAlignment) {
Jason Sams463bfce2012-08-21 13:54:42 -0700385 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
386 if (!drv) {
387 return false;
388 }
389 alloc->mHal.drv = drv;
390
Miao Wang47a58812015-07-23 21:59:16 -0700391 // Check if requiredAlignment is power of 2, also requiredAlignment should be larger or equal than kMinimumRSAlignment.
392 if ((requiredAlignment & (requiredAlignment-1)) != 0 || requiredAlignment < Allocation::kMinimumRSAlignment) {
393 ALOGE("requiredAlignment must be power of 2");
394 return false;
395 }
Jason Sams463bfce2012-08-21 13:54:42 -0700396 // Calculate the object size.
Miao Wang47a58812015-07-23 21:59:16 -0700397 size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), nullptr, requiredAlignment);
Jason Sams463bfce2012-08-21 13:54:42 -0700398
Chris Wailes44bef6f2014-08-12 13:51:10 -0700399 uint8_t * ptr = nullptr;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800400 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
Jason Sams733396b2013-02-22 12:46:18 -0800401
402 } else if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
403 // Allocation is allocated when the surface is created
404 // in getSurface
Miao Wang47a58812015-07-23 21:59:16 -0700405#ifdef RS_COMPATIBILITY_LIB
406 } else if (alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT | RS_ALLOCATION_USAGE_SHARED)) {
407 if (alloc->mHal.state.userProvidedPtr == nullptr) {
408 ALOGE("User-backed buffer pointer cannot be null");
409 return false;
410 }
411 if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
412 ALOGE("User-allocated buffers must not have multiple faces or LODs");
413 return false;
414 }
415
416 drv->useUserProvidedPtr = true;
417 ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
418#endif
Chris Wailes44bef6f2014-08-12 13:51:10 -0700419 } else if (alloc->mHal.state.userProvidedPtr != nullptr) {
Tim Murray2e1a94d2012-11-29 13:12:25 -0800420 // user-provided allocation
Tim Murrayba24d082013-04-09 17:31:11 -0700421 // limitations: no faces, no LOD, USAGE_SCRIPT or SCRIPT+TEXTURE only
422 if (!(alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED) ||
423 alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))) {
424 ALOGE("Can't use user-allocated buffers if usage is not USAGE_SCRIPT | USAGE_SHARED or USAGE_SCRIPT | USAGE_SHARED | USAGE_GRAPHICS_TEXTURE");
Tim Murray2e1a94d2012-11-29 13:12:25 -0800425 return false;
426 }
427 if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
428 ALOGE("User-allocated buffers must not have multiple faces or LODs");
429 return false;
430 }
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800431
Miao Wang47a58812015-07-23 21:59:16 -0700432 // rows must be aligned based on requiredAlignment.
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800433 // validate that here, otherwise fall back to not use the user-backed allocation
Miao Wang47a58812015-07-23 21:59:16 -0700434 if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % requiredAlignment) != 0) {
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800435 ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
436 drv->useUserProvidedPtr = false;
437
Miao Wang47a58812015-07-23 21:59:16 -0700438 ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800439 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700440 alloc->mHal.drv = nullptr;
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800441 free(drv);
442 return false;
443 }
444
445 } else {
446 drv->useUserProvidedPtr = true;
447 ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
448 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800449 } else {
Miao Wang47a58812015-07-23 21:59:16 -0700450 ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
Jason Sams179e9a42011-11-23 15:02:15 -0800451 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700452 alloc->mHal.drv = nullptr;
Jason Sams179e9a42011-11-23 15:02:15 -0800453 free(drv);
454 return false;
455 }
Jason Samseb4fe182011-05-26 16:33:01 -0700456 }
Jason Sams463bfce2012-08-21 13:54:42 -0700457 // Build the pointer tables
Miao Wang47a58812015-07-23 21:59:16 -0700458 size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr, requiredAlignment);
Jason Sams463bfce2012-08-21 13:54:42 -0700459 if(allocSize != verifySize) {
460 rsAssert(!"Size mismatch");
Jason Sams807fdc42012-07-25 17:55:39 -0700461 }
Jason Samseb4fe182011-05-26 16:33:01 -0700462
463 drv->glTarget = GL_NONE;
464 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
465 if (alloc->mHal.state.hasFaces) {
466 drv->glTarget = GL_TEXTURE_CUBE_MAP;
467 } else {
468 drv->glTarget = GL_TEXTURE_2D;
469 }
470 } else {
471 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
472 drv->glTarget = GL_ARRAY_BUFFER;
473 }
474 }
475
Jason Sams93eacc72012-12-18 14:26:57 -0800476#ifndef RS_COMPATIBILITY_LIB
Jason Samsa614ae12011-05-26 17:05:51 -0700477 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
478 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
Jason Sams93eacc72012-12-18 14:26:57 -0800479#else
480 drv->glType = 0;
481 drv->glFormat = 0;
482#endif
Jason Samsa614ae12011-05-26 17:05:51 -0700483
Jason Samseb4fe182011-05-26 16:33:01 -0700484 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
485 drv->uploadDeferred = true;
486 }
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700487
Jason Samsb3220332012-04-02 14:41:54 -0700488
Chris Wailes44bef6f2014-08-12 13:51:10 -0700489 drv->readBackFBO = nullptr;
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700490
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800491 // fill out the initial state of the buffer if we couldn't use the user-provided ptr and USAGE_SHARED was accepted
492 if ((alloc->mHal.state.userProvidedPtr != 0) && (drv->useUserProvidedPtr == false)) {
493 rsdAllocationData2D(rsc, alloc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, alloc->getType()->getDimX(), alloc->getType()->getDimY(), alloc->mHal.state.userProvidedPtr, allocSize, 0);
494 }
495
Tim Murraye3af53b2014-06-10 09:46:51 -0700496
497#ifdef RS_FIND_OFFSETS
498 ALOGE("pointer for allocation: %p", alloc);
499 ALOGE("pointer for allocation.drv: %p", &alloc->mHal.drv);
500#endif
501
502
Jason Samseb4fe182011-05-26 16:33:01 -0700503 return true;
504}
505
Miao Wang47a58812015-07-23 21:59:16 -0700506bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
507 return rsdAllocationInitStrided(rsc, alloc, forceZero, Allocation::kMinimumRSAlignment);
508}
509
Jason Samsbc9dc272015-02-09 12:50:22 -0800510void rsdAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
511 //ALOGE("rsdAllocationAdapterOffset");
512
513 // Get a base pointer to the new LOD
514 const Allocation *base = alloc->mHal.state.baseAlloc;
515 const Type *type = alloc->mHal.state.type;
516 if (base == nullptr) {
517 return;
518 }
519
Jason Samsbc9dc272015-02-09 12:50:22 -0800520 //ALOGE("rsdAllocationAdapterOffset %p %p", ptrA, ptrB);
521 //ALOGE("rsdAllocationAdapterOffset lodCount %i", alloc->mHal.drvState.lodCount);
522
523 const int lodBias = alloc->mHal.state.originLOD;
524 uint32_t lodCount = rsMax(alloc->mHal.drvState.lodCount, (uint32_t)1);
525 for (uint32_t lod=0; lod < lodCount; lod++) {
526 alloc->mHal.drvState.lod[lod] = base->mHal.drvState.lod[lod + lodBias];
Jason Sams2178d422015-03-24 15:51:27 -0700527 alloc->mHal.drvState.lod[lod].mallocPtr = GetOffsetPtr(alloc,
528 alloc->mHal.state.originX, alloc->mHal.state.originY, alloc->mHal.state.originZ,
529 lodBias, (RsAllocationCubemapFace)alloc->mHal.state.originFace);
Jason Samsbc9dc272015-02-09 12:50:22 -0800530 }
531}
532
533bool rsdAllocationAdapterInit(const Context *rsc, Allocation *alloc) {
534 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
535 if (!drv) {
536 return false;
537 }
538 alloc->mHal.drv = drv;
539
540 // We need to build an allocation that looks like a subset of the parent allocation
541 rsdAllocationAdapterOffset(rsc, alloc);
542
543 return true;
544}
545
Jason Samseb4fe182011-05-26 16:33:01 -0700546void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
547 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
548
Jason Samsbc9dc272015-02-09 12:50:22 -0800549 if (alloc->mHal.state.baseAlloc == nullptr) {
Jason Sams93eacc72012-12-18 14:26:57 -0800550#ifndef RS_COMPATIBILITY_LIB
Jason Samsbc9dc272015-02-09 12:50:22 -0800551 if (drv->bufferID) {
552 // Causes a SW crash....
553 //ALOGV(" mBufferID %i", mBufferID);
554 //glDeleteBuffers(1, &mBufferID);
555 //mBufferID = 0;
556 }
557 if (drv->textureID) {
558 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
559 drv->textureID = 0;
560 }
561 if (drv->renderTargetID) {
562 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
563 drv->renderTargetID = 0;
564 }
Jason Sams93eacc72012-12-18 14:26:57 -0800565#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700566
Jason Samsbc9dc272015-02-09 12:50:22 -0800567 if (alloc->mHal.drvState.lod[0].mallocPtr) {
568 // don't free user-allocated ptrs or IO_OUTPUT buffers
569 if (!(drv->useUserProvidedPtr) &&
570 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
571 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
572 free(alloc->mHal.drvState.lod[0].mallocPtr);
573 }
574 alloc->mHal.drvState.lod[0].mallocPtr = nullptr;
Tim Murray2e1a94d2012-11-29 13:12:25 -0800575 }
Jason Sams93eacc72012-12-18 14:26:57 -0800576
577#ifndef RS_COMPATIBILITY_LIB
Jason Samsbc9dc272015-02-09 12:50:22 -0800578 if (drv->readBackFBO != nullptr) {
579 delete drv->readBackFBO;
580 drv->readBackFBO = nullptr;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800581 }
Jason Samsbc9dc272015-02-09 12:50:22 -0800582
583 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
584 (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
585
586 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
587 ANativeWindow *nw = drv->wndSurface;
588 if (nw) {
589 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
590 mapper.unlock(drv->wndBuffer->handle);
Jason Samsabc1f942015-05-18 17:45:26 -0700591 int32_t r = nw->cancelBuffer(nw, drv->wndBuffer, -1);
Jason Samsbc9dc272015-02-09 12:50:22 -0800592
593 drv->wndSurface = nullptr;
594 native_window_api_disconnect(nw, NATIVE_WINDOW_API_CPU);
595 nw->decStrong(nullptr);
596 }
597 }
Jason Sams93eacc72012-12-18 14:26:57 -0800598#endif
Jason Samsbc9dc272015-02-09 12:50:22 -0800599 }
Jason Sams93eacc72012-12-18 14:26:57 -0800600
Jason Samseb4fe182011-05-26 16:33:01 -0700601 free(drv);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700602 alloc->mHal.drv = nullptr;
Jason Samseb4fe182011-05-26 16:33:01 -0700603}
604
605void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
606 const Type *newType, bool zeroNew) {
Jason Samsa572aca2013-01-09 11:52:26 -0800607 const uint32_t oldDimX = alloc->mHal.drvState.lod[0].dimX;
608 const uint32_t dimX = newType->getDimX();
609
Tim Murray9e2bda52012-12-18 12:05:46 -0800610 // can't resize Allocations with user-allocated buffers
611 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
612 ALOGE("Resize cannot be called on a USAGE_SHARED allocation");
613 return;
614 }
Jason Sams709a0972012-11-15 18:18:04 -0800615 void * oldPtr = alloc->mHal.drvState.lod[0].mallocPtr;
Jason Sams463bfce2012-08-21 13:54:42 -0700616 // Calculate the object size
Chris Wailes44bef6f2014-08-12 13:51:10 -0700617 size_t s = AllocationBuildPointerTable(rsc, alloc, newType, nullptr);
Jason Sams463bfce2012-08-21 13:54:42 -0700618 uint8_t *ptr = (uint8_t *)realloc(oldPtr, s);
619 // Build the relative pointer tables.
620 size_t verifySize = AllocationBuildPointerTable(rsc, alloc, newType, ptr);
621 if(s != verifySize) {
622 rsAssert(!"Size mismatch");
623 }
Jason Samseb4fe182011-05-26 16:33:01 -0700624
Jason Samseb4fe182011-05-26 16:33:01 -0700625
626 if (dimX > oldDimX) {
Tim Murray099bc262013-03-20 16:54:03 -0700627 size_t stride = alloc->mHal.state.elementSizeBytes;
Jason Sams709a0972012-11-15 18:18:04 -0800628 memset(((uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr) + stride * oldDimX,
Jason Sams2275e9c2012-04-16 17:01:26 -0700629 0, stride * (dimX - oldDimX));
Jason Samseb4fe182011-05-26 16:33:01 -0700630 }
631}
632
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700633static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800634#ifndef RS_COMPATIBILITY_LIB
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700635 if (!alloc->getIsScript()) {
636 return; // nothing to sync
637 }
638
639 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
640 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
641
642 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
643 if (!drv->textureID && !drv->renderTargetID) {
644 return; // nothing was rendered here yet, so nothing to sync
645 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700646 if (drv->readBackFBO == nullptr) {
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700647 drv->readBackFBO = new RsdFrameBufferObj();
648 drv->readBackFBO->setColorTarget(drv, 0);
649 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
650 alloc->getType()->getDimY());
651 }
652
653 // Bind the framebuffer object so we can read back from it
654 drv->readBackFBO->setActive(rsc);
655
656 // Do the readback
Jason Sams709a0972012-11-15 18:18:04 -0800657 RSD_CALL_GL(glReadPixels, 0, 0, alloc->mHal.drvState.lod[0].dimX,
658 alloc->mHal.drvState.lod[0].dimY,
659 drv->glFormat, drv->glType, alloc->mHal.drvState.lod[0].mallocPtr);
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700660
661 // Revert framebuffer to its original
662 lastFbo->setActive(rsc);
Jason Sams93eacc72012-12-18 14:26:57 -0800663#endif
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700664}
Jason Samseb4fe182011-05-26 16:33:01 -0700665
666
667void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
668 RsAllocationUsageType src) {
669 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
670
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700671 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
672 if(!alloc->getIsRenderTarget()) {
673 rsc->setError(RS_ERROR_FATAL_DRIVER,
674 "Attempting to sync allocation from render target, "
675 "for non-render target allocation");
676 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
677 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
678 "render target");
679 } else {
680 rsdAllocationSyncFromFBO(rsc, alloc);
681 }
Jason Samseb4fe182011-05-26 16:33:01 -0700682 return;
683 }
684
Jason Samsb8a94e22014-02-24 17:52:32 -0800685 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT || src == RS_ALLOCATION_USAGE_SHARED);
Jason Samseb4fe182011-05-26 16:33:01 -0700686
687 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
688 UploadToTexture(rsc, alloc);
689 } else {
Jason Samsb3220332012-04-02 14:41:54 -0700690 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
Jason Sams0dc66932012-04-10 17:05:49 -0700691 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
Jason Samseb4fe182011-05-26 16:33:01 -0700692 AllocateRenderTarget(rsc, alloc);
693 }
694 }
695 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
696 UploadToBufferObject(rsc, alloc);
697 }
698
Tim Murrayba24d082013-04-09 17:31:11 -0700699 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
Jason Samsb8a94e22014-02-24 17:52:32 -0800700
701 if (src == RS_ALLOCATION_USAGE_SHARED) {
702 // just a memory fence for the CPU driver
703 // vendor drivers probably want to flush any dirty cachelines for
704 // this particular Allocation
705 __sync_synchronize();
706 }
Tim Murrayba24d082013-04-09 17:31:11 -0700707 }
708
Jason Samseb4fe182011-05-26 16:33:01 -0700709 drv->uploadDeferred = false;
710}
711
712void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
713 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
714 drv->uploadDeferred = true;
715}
716
Jason Sams4961cce2013-04-11 16:11:46 -0700717#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800718static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
719 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
720
Jamie Genniscd919a12012-06-13 16:34:11 -0700721 int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800722 if (r) {
723 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
724 return false;
725 }
726
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800727 // Must lock the whole surface
728 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
729 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
730
Chris Wailes44bef6f2014-08-12 13:51:10 -0700731 void *dst = nullptr;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800732 mapper.lock(drv->wndBuffer->handle,
733 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
734 bounds, &dst);
Jason Sams709a0972012-11-15 18:18:04 -0800735 alloc->mHal.drvState.lod[0].mallocPtr = dst;
736 alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
Stephen Hines94999c32013-02-05 16:58:22 -0800737 rsAssert((alloc->mHal.drvState.lod[0].stride & 0xf) == 0);
Jason Samsb3220332012-04-02 14:41:54 -0700738
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800739 return true;
740}
Jason Sams93eacc72012-12-18 14:26:57 -0800741#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800742
Jason Sams733396b2013-02-22 12:46:18 -0800743void rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
Jason Sams93eacc72012-12-18 14:26:57 -0800744#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800745 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800746 ANativeWindow *old = drv->wndSurface;
747
748 if (nw) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700749 nw->incStrong(nullptr);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800750 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800751
Jason Samsb3220332012-04-02 14:41:54 -0700752 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
753 //TODO finish support for render target + script
754 drv->wnd = nw;
755 return;
756 }
757
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800758 // Cleanup old surface if there is one.
Tim Murray3a25fdd2013-02-22 17:56:56 -0800759 if (drv->wndSurface) {
760 ANativeWindow *old = drv->wndSurface;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800761 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
762 mapper.unlock(drv->wndBuffer->handle);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800763 old->cancelBuffer(old, drv->wndBuffer, -1);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700764 drv->wndSurface = nullptr;
Jason Sams9dae48e2013-09-23 15:56:11 -0700765
766 native_window_api_disconnect(old, NATIVE_WINDOW_API_CPU);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700767 old->decStrong(nullptr);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800768 }
769
Chris Wailes44bef6f2014-08-12 13:51:10 -0700770 if (nw != nullptr) {
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800771 int32_t r;
Jason Samsb3220332012-04-02 14:41:54 -0700772 uint32_t flags = 0;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800773
Jason Samsb3220332012-04-02 14:41:54 -0700774 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
775 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
776 }
777 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
778 flags |= GRALLOC_USAGE_HW_RENDER;
779 }
780
Jason Sams9dae48e2013-09-23 15:56:11 -0700781 r = native_window_api_connect(nw, NATIVE_WINDOW_API_CPU);
782 if (r) {
783 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
784 goto error;
785 }
786
Jason Samsb3220332012-04-02 14:41:54 -0700787 r = native_window_set_usage(nw, flags);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800788 if (r) {
789 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800790 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800791 }
792
Jason Samsa572aca2013-01-09 11:52:26 -0800793 r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
794 alloc->mHal.drvState.lod[0].dimY);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800795 if (r) {
796 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800797 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800798 }
799
Jason Sams733396b2013-02-22 12:46:18 -0800800 int format = 0;
801 const Element *e = alloc->mHal.state.type->getElement();
Jason Sams3b0efb62015-02-25 14:29:49 -0800802 if ((e->getType() != RS_TYPE_UNSIGNED_8) ||
803 (e->getVectorSize() != 4)) {
804 // We do not check for RGBA, RGBx, to allow for interop with U8_4
805
806 rsc->setError(RS_ERROR_DRIVER, "Surface passed to setSurface is not U8_4, RGBA.");
807 goto error;
808 }
Stephen Hines8b9b3aa2013-08-02 15:51:36 -0700809 format = PIXEL_FORMAT_RGBA_8888;
Jason Sams733396b2013-02-22 12:46:18 -0800810
811 r = native_window_set_buffers_format(nw, format);
812 if (r) {
813 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800814 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800815 }
816
817 IoGetBuffer(rsc, alloc, nw);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800818 drv->wndSurface = nw;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800819 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800820
821 return;
822
823 error:
824
825 if (nw) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700826 nw->decStrong(nullptr);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800827 }
828
829
Jason Sams93eacc72012-12-18 14:26:57 -0800830#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800831}
832
833void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800834#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800835 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800836 ANativeWindow *nw = drv->wndSurface;
Jason Samsb3220332012-04-02 14:41:54 -0700837 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
838 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
839 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800840 return;
841 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800842 if (nw) {
843 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
844 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
845 mapper.unlock(drv->wndBuffer->handle);
846 int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
847 if (r) {
848 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
849 return;
850 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800851
Tim Murray3a25fdd2013-02-22 17:56:56 -0800852 IoGetBuffer(rsc, alloc, nw);
Jason Samsb3220332012-04-02 14:41:54 -0700853 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800854 } else {
855 rsc->setError(RS_ERROR_DRIVER, "Sent IO buffer with no attached surface.");
856 return;
Jason Samsb3220332012-04-02 14:41:54 -0700857 }
Jason Sams93eacc72012-12-18 14:26:57 -0800858#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800859}
860
861void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800862#ifndef RS_COMPATIBILITY_LIB
Jason Sams3522f402012-03-23 11:47:26 -0700863 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Jason Samsddceab92013-08-07 13:02:32 -0700864 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Tim Murray3a25fdd2013-02-22 17:56:56 -0800865 drv->surfaceTexture->updateTexImage();
Jason Sams733396b2013-02-22 12:46:18 -0800866 }
Jason Sams93eacc72012-12-18 14:26:57 -0800867#endif
Jason Sams7314cca2015-02-24 18:25:59 -0800868 if (alloc->mHal.state.yuv) {
869 DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
870 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800871}
872
873
Jason Samseb4fe182011-05-26 16:33:01 -0700874void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
Tim Murray099bc262013-03-20 16:54:03 -0700875 uint32_t xoff, uint32_t lod, size_t count,
Alex Sakhartchoukc794cd52012-02-13 11:57:32 -0800876 const void *data, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -0700877 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
878
Tim Murray099bc262013-03-20 16:54:03 -0700879 const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700880 uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Tim Murray099bc262013-03-20 16:54:03 -0700881 size_t size = count * eSize;
Stephen Hines20c535f2012-12-06 19:04:38 -0800882 if (ptr != data) {
883 // Skip the copy if we are the same allocation. This can arise from
884 // our Bitmap optimization, where we share the same storage.
885 if (alloc->mHal.state.hasReferences) {
886 alloc->incRefs(data, count);
887 alloc->decRefs(ptr, count);
888 }
889 memcpy(ptr, data, size);
Jason Samseb4fe182011-05-26 16:33:01 -0700890 }
Jason Samseb4fe182011-05-26 16:33:01 -0700891 drv->uploadDeferred = true;
892}
893
894void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
895 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Tim Murray358747a2012-11-26 13:52:04 -0800896 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
Jason Samseb4fe182011-05-26 16:33:01 -0700897 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
898
Tim Murray099bc262013-03-20 16:54:03 -0700899 size_t eSize = alloc->mHal.state.elementSizeBytes;
900 size_t lineSize = eSize * w;
Tim Murray358747a2012-11-26 13:52:04 -0800901 if (!stride) {
902 stride = lineSize;
903 }
Jason Samseb4fe182011-05-26 16:33:01 -0700904
Jason Sams709a0972012-11-15 18:18:04 -0800905 if (alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700906 const uint8_t *src = static_cast<const uint8_t *>(data);
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700907 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Stephen Hines20c535f2012-12-06 19:04:38 -0800908 if (dst == src) {
909 // Skip the copy if we are the same allocation. This can arise from
910 // our Bitmap optimization, where we share the same storage.
911 drv->uploadDeferred = true;
912 return;
913 }
Jason Samseb4fe182011-05-26 16:33:01 -0700914
915 for (uint32_t line=yoff; line < (yoff+h); line++) {
916 if (alloc->mHal.state.hasReferences) {
917 alloc->incRefs(src, w);
918 alloc->decRefs(dst, w);
919 }
920 memcpy(dst, src, lineSize);
Tim Murray358747a2012-11-26 13:52:04 -0800921 src += stride;
Jason Sams709a0972012-11-15 18:18:04 -0800922 dst += alloc->mHal.drvState.lod[lod].stride;
Jason Samseb4fe182011-05-26 16:33:01 -0700923 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800924 if (alloc->mHal.state.yuv) {
Jason Sams0052f8d2013-09-19 17:27:29 -0700925 size_t clineSize = lineSize;
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800926 int lod = 1;
Jason Sams61656a72013-09-03 16:21:18 -0700927 int maxLod = 2;
928 if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YV12) {
929 maxLod = 3;
Jason Sams0052f8d2013-09-19 17:27:29 -0700930 clineSize >>= 1;
Jason Sams61656a72013-09-03 16:21:18 -0700931 } else if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
932 lod = 2;
933 maxLod = 3;
934 }
935
936 while (lod < maxLod) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700937 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800938
939 for (uint32_t line=(yoff >> 1); line < ((yoff+h)>>1); line++) {
Jason Sams0052f8d2013-09-19 17:27:29 -0700940 memcpy(dst, src, clineSize);
Miao Wang6b855bd2016-04-24 15:41:12 -0700941 // When copying from an array to an Allocation, the src pointer
942 // to the array should just move by the number of bytes copied.
943 src += clineSize;
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800944 dst += alloc->mHal.drvState.lod[lod].stride;
945 }
946 lod++;
947 }
948
949 }
Jason Samseb4fe182011-05-26 16:33:01 -0700950 drv->uploadDeferred = true;
951 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700952 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
Jason Samseb4fe182011-05-26 16:33:01 -0700953 }
954}
955
956void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
957 uint32_t xoff, uint32_t yoff, uint32_t zoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700958 uint32_t lod,
959 uint32_t w, uint32_t h, uint32_t d, const void *data,
960 size_t sizeBytes, size_t stride) {
961 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Jason Samseb4fe182011-05-26 16:33:01 -0700962
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700963 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
964 uint32_t lineSize = eSize * w;
965 if (!stride) {
966 stride = lineSize;
967 }
968
969 if (alloc->mHal.drvState.lod[0].mallocPtr) {
970 const uint8_t *src = static_cast<const uint8_t *>(data);
Miao Wanga814de92015-02-25 18:45:31 -0800971 for (uint32_t z = zoff; z < (d + zoff); z++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700972 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
973 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
974 if (dst == src) {
975 // Skip the copy if we are the same allocation. This can arise from
976 // our Bitmap optimization, where we share the same storage.
977 drv->uploadDeferred = true;
978 return;
979 }
980
981 for (uint32_t line=yoff; line < (yoff+h); line++) {
982 if (alloc->mHal.state.hasReferences) {
983 alloc->incRefs(src, w);
984 alloc->decRefs(dst, w);
985 }
986 memcpy(dst, src, lineSize);
987 src += stride;
988 dst += alloc->mHal.drvState.lod[lod].stride;
989 }
990 }
991 drv->uploadDeferred = true;
992 }
Jason Samseb4fe182011-05-26 16:33:01 -0700993}
994
Jason Sams807fdc42012-07-25 17:55:39 -0700995void rsdAllocationRead1D(const Context *rsc, const Allocation *alloc,
Tim Murray099bc262013-03-20 16:54:03 -0700996 uint32_t xoff, uint32_t lod, size_t count,
Jason Sams807fdc42012-07-25 17:55:39 -0700997 void *data, size_t sizeBytes) {
Tim Murray099bc262013-03-20 16:54:03 -0700998 const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700999 const uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Stephen Hines20c535f2012-12-06 19:04:38 -08001000 if (data != ptr) {
1001 // Skip the copy if we are the same allocation. This can arise from
1002 // our Bitmap optimization, where we share the same storage.
1003 memcpy(data, ptr, count * eSize);
1004 }
Jason Sams807fdc42012-07-25 17:55:39 -07001005}
1006
1007void rsdAllocationRead2D(const Context *rsc, const Allocation *alloc,
Tim Murray358747a2012-11-26 13:52:04 -08001008 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
1009 uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
Tim Murray099bc262013-03-20 16:54:03 -07001010 size_t eSize = alloc->mHal.state.elementSizeBytes;
1011 size_t lineSize = eSize * w;
Tim Murray358747a2012-11-26 13:52:04 -08001012 if (!stride) {
1013 stride = lineSize;
1014 }
Jason Sams807fdc42012-07-25 17:55:39 -07001015
Jason Sams709a0972012-11-15 18:18:04 -08001016 if (alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Sams807fdc42012-07-25 17:55:39 -07001017 uint8_t *dst = static_cast<uint8_t *>(data);
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001018 const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Stephen Hines20c535f2012-12-06 19:04:38 -08001019 if (dst == src) {
1020 // Skip the copy if we are the same allocation. This can arise from
1021 // our Bitmap optimization, where we share the same storage.
1022 return;
1023 }
Jason Sams807fdc42012-07-25 17:55:39 -07001024
1025 for (uint32_t line=yoff; line < (yoff+h); line++) {
1026 memcpy(dst, src, lineSize);
Tim Murray358747a2012-11-26 13:52:04 -08001027 dst += stride;
Jason Sams709a0972012-11-15 18:18:04 -08001028 src += alloc->mHal.drvState.lod[lod].stride;
Jason Sams807fdc42012-07-25 17:55:39 -07001029 }
1030 } else {
1031 ALOGE("Add code to readback from non-script memory");
1032 }
1033}
1034
Tim Murray358747a2012-11-26 13:52:04 -08001035
Jason Sams807fdc42012-07-25 17:55:39 -07001036void rsdAllocationRead3D(const Context *rsc, const Allocation *alloc,
1037 uint32_t xoff, uint32_t yoff, uint32_t zoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001038 uint32_t lod,
1039 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
1040 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
1041 uint32_t lineSize = eSize * w;
1042 if (!stride) {
1043 stride = lineSize;
1044 }
Jason Sams807fdc42012-07-25 17:55:39 -07001045
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001046 if (alloc->mHal.drvState.lod[0].mallocPtr) {
1047 uint8_t *dst = static_cast<uint8_t *>(data);
Miao Wanga814de92015-02-25 18:45:31 -08001048 for (uint32_t z = zoff; z < (d + zoff); z++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001049 const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
1050 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1051 if (dst == src) {
1052 // Skip the copy if we are the same allocation. This can arise from
1053 // our Bitmap optimization, where we share the same storage.
1054 return;
1055 }
1056
1057 for (uint32_t line=yoff; line < (yoff+h); line++) {
1058 memcpy(dst, src, lineSize);
1059 dst += stride;
1060 src += alloc->mHal.drvState.lod[lod].stride;
1061 }
1062 }
1063 }
Jason Sams807fdc42012-07-25 17:55:39 -07001064}
1065
1066void * rsdAllocationLock1D(const android::renderscript::Context *rsc,
1067 const android::renderscript::Allocation *alloc) {
Jason Sams709a0972012-11-15 18:18:04 -08001068 return alloc->mHal.drvState.lod[0].mallocPtr;
Jason Sams807fdc42012-07-25 17:55:39 -07001069}
1070
1071void rsdAllocationUnlock1D(const android::renderscript::Context *rsc,
1072 const android::renderscript::Allocation *alloc) {
1073
1074}
1075
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001076void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
1077 const android::renderscript::Allocation *dstAlloc,
Tim Murray099bc262013-03-20 16:54:03 -07001078 uint32_t dstXoff, uint32_t dstLod, size_t count,
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001079 const android::renderscript::Allocation *srcAlloc,
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001080 uint32_t srcXoff, uint32_t srcLod) {
1081}
1082
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001083
1084void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
1085 const android::renderscript::Allocation *dstAlloc,
1086 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1087 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1088 const android::renderscript::Allocation *srcAlloc,
1089 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1090 RsAllocationCubemapFace srcFace) {
Tim Murray099bc262013-03-20 16:54:03 -07001091 size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001092 for (uint32_t i = 0; i < h; i ++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001093 uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
1094 uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001095 memcpy(dstPtr, srcPtr, w * elementSize);
1096
Steve Blockaf12ac62012-01-06 19:20:56 +00001097 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
Stephen Hines0a44ab42011-06-23 16:18:28 -07001098 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001099 }
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001100}
1101
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001102void rsdAllocationData3D_alloc_script(const android::renderscript::Context *rsc,
1103 const android::renderscript::Allocation *dstAlloc,
1104 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod,
1105 uint32_t w, uint32_t h, uint32_t d,
1106 const android::renderscript::Allocation *srcAlloc,
1107 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod) {
1108 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
1109 for (uint32_t j = 0; j < d; j++) {
1110 for (uint32_t i = 0; i < h; i ++) {
1111 uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j,
1112 dstLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1113 uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j,
1114 srcLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1115 memcpy(dstPtr, srcPtr, w * elementSize);
1116
1117 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
1118 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
1119 }
1120 }
1121}
1122
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001123void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
1124 const android::renderscript::Allocation *dstAlloc,
1125 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1126 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1127 const android::renderscript::Allocation *srcAlloc,
1128 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1129 RsAllocationCubemapFace srcFace) {
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001130 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
1131 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
1132 "yet implemented.");
1133 return;
1134 }
1135 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
1136 dstLod, dstFace, w, h, srcAlloc,
1137 srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001138}
1139
1140void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
1141 const android::renderscript::Allocation *dstAlloc,
1142 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001143 uint32_t dstLod,
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001144 uint32_t w, uint32_t h, uint32_t d,
1145 const android::renderscript::Allocation *srcAlloc,
1146 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001147 uint32_t srcLod) {
1148 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
1149 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
1150 "yet implemented.");
1151 return;
1152 }
1153 rsdAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
1154 dstLod, w, h, d, srcAlloc,
1155 srcXoff, srcYoff, srcZoff, srcLod);
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001156}
1157
Miao Wangcc8cea72015-02-19 18:14:46 -08001158void rsdAllocationElementData(const Context *rsc, const Allocation *alloc,
1159 uint32_t x, uint32_t y, uint32_t z,
1160 const void *data, uint32_t cIdx, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -07001161 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1162
Miao Wangcc8cea72015-02-19 18:14:46 -08001163 uint8_t * ptr = GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -07001164
1165 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
1166 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
1167
1168 if (alloc->mHal.state.hasReferences) {
1169 e->incRefs(data);
1170 e->decRefs(ptr);
1171 }
1172
1173 memcpy(ptr, data, sizeBytes);
1174 drv->uploadDeferred = true;
1175}
1176
Miao Wangcc8cea72015-02-19 18:14:46 -08001177void rsdAllocationElementRead(const Context *rsc, const Allocation *alloc,
1178 uint32_t x, uint32_t y, uint32_t z,
1179 void *data, uint32_t cIdx, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -07001180 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1181
Miao Wangcc8cea72015-02-19 18:14:46 -08001182 uint8_t * ptr = GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -07001183
1184 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
1185 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
1186
Miao Wangcc8cea72015-02-19 18:14:46 -08001187 memcpy(data, ptr, sizeBytes);
Jason Samseb4fe182011-05-26 16:33:01 -07001188}
1189
Jason Sams61a4bb72012-07-25 19:33:43 -07001190static void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001191 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1192 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001193
1194 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001195 uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1196 const uint16_t *i1 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2, lod, face);
1197 const uint16_t *i2 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2+1, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001198
1199 for (uint32_t x=0; x < w; x++) {
1200 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
1201 oPtr ++;
1202 i1 += 2;
1203 i2 += 2;
1204 }
1205 }
1206}
1207
1208static void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001209 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1210 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001211
1212 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001213 uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1214 const uint32_t *i1 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1215 const uint32_t *i2 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001216
1217 for (uint32_t x=0; x < w; x++) {
1218 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
1219 oPtr ++;
1220 i1 += 2;
1221 i2 += 2;
1222 }
1223 }
1224}
1225
1226static void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001227 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1228 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001229
1230 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001231 uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1232 const uint8_t *i1 = GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1233 const uint8_t *i2 = GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001234
1235 for (uint32_t x=0; x < w; x++) {
1236 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
1237 oPtr ++;
1238 i1 += 2;
1239 i2 += 2;
1240 }
1241 }
1242}
1243
1244void rsdAllocationGenerateMipmaps(const Context *rsc, const Allocation *alloc) {
Jason Sams709a0972012-11-15 18:18:04 -08001245 if(!alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Sams61a4bb72012-07-25 19:33:43 -07001246 return;
1247 }
1248 uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
1249 for (uint32_t face = 0; face < numFaces; face ++) {
1250 for (uint32_t lod=0; lod < (alloc->getType()->getLODCount() -1); lod++) {
1251 switch (alloc->getType()->getElement()->getSizeBits()) {
1252 case 32:
1253 mip8888(alloc, lod, (RsAllocationCubemapFace)face);
1254 break;
1255 case 16:
1256 mip565(alloc, lod, (RsAllocationCubemapFace)face);
1257 break;
1258 case 8:
1259 mip8(alloc, lod, (RsAllocationCubemapFace)face);
1260 break;
1261 }
1262 }
1263 }
1264}
Jason Samsddceab92013-08-07 13:02:32 -07001265
1266uint32_t rsdAllocationGrallocBits(const android::renderscript::Context *rsc,
1267 android::renderscript::Allocation *alloc)
1268{
1269 return 0;
1270}
1271
Jason Samsa36c50a2014-06-17 12:06:06 -07001272void rsdAllocationUpdateCachedObject(const Context *rsc,
1273 const Allocation *alloc,
1274 rs_allocation *obj)
1275{
1276 obj->p = alloc;
1277#ifdef __LP64__
Chris Wailes44bef6f2014-08-12 13:51:10 -07001278 if (alloc != nullptr) {
Jason Samsa36c50a2014-06-17 12:06:06 -07001279 obj->r = alloc->mHal.drvState.lod[0].mallocPtr;
1280 obj->v1 = alloc->mHal.drv;
1281 obj->v2 = (void *)alloc->mHal.drvState.lod[0].stride;
1282 } else {
Chris Wailes44bef6f2014-08-12 13:51:10 -07001283 obj->r = nullptr;
1284 obj->v1 = nullptr;
1285 obj->v2 = nullptr;
Jason Samsa36c50a2014-06-17 12:06:06 -07001286 }
1287#endif
1288}