blob: 83d4407f80ad2b4eef343fb76c6a282c4d663187 [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
Stephen Hinesb0934b62013-07-03 17:27:38 -070022#if !defined(RS_SERVER) && !defined(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
Tim Murray0b575de2013-03-15 15:56:43 -070042#ifdef RS_SERVER
43// server requires malloc.h for memalign
44#include <malloc.h>
45#endif
46
Chih-Hung Hsiehe939ce72016-11-15 16:27:11 -080047#ifndef RS_COMPATIBILITY_LIB
48using android::GraphicBufferMapper;
49using android::PIXEL_FORMAT_RGBA_8888;
50using android::Rect;
51#endif
52
53using android::renderscript::Allocation;
54using android::renderscript::Context;
55using android::renderscript::Element;
56using android::renderscript::Type;
57using android::renderscript::rs_allocation;
58using android::renderscript::rsBoxFilter565;
59using android::renderscript::rsBoxFilter8888;
60using android::renderscript::rsMax;
61using android::renderscript::rsRound;
Jason Samseb4fe182011-05-26 16:33:01 -070062
Jason Sams93eacc72012-12-18 14:26:57 -080063#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -070064const static GLenum gFaceOrder[] = {
65 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
66 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
67 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
68 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
69 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
70 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
71};
72
Jason Samsa614ae12011-05-26 17:05:51 -070073GLenum rsdTypeToGLType(RsDataType t) {
74 switch (t) {
75 case RS_TYPE_UNSIGNED_5_6_5: return GL_UNSIGNED_SHORT_5_6_5;
76 case RS_TYPE_UNSIGNED_5_5_5_1: return GL_UNSIGNED_SHORT_5_5_5_1;
77 case RS_TYPE_UNSIGNED_4_4_4_4: return GL_UNSIGNED_SHORT_4_4_4_4;
78
79 //case RS_TYPE_FLOAT_16: return GL_HALF_FLOAT;
80 case RS_TYPE_FLOAT_32: return GL_FLOAT;
81 case RS_TYPE_UNSIGNED_8: return GL_UNSIGNED_BYTE;
82 case RS_TYPE_UNSIGNED_16: return GL_UNSIGNED_SHORT;
83 case RS_TYPE_SIGNED_8: return GL_BYTE;
84 case RS_TYPE_SIGNED_16: return GL_SHORT;
85 default: break;
86 }
87 return 0;
88}
89
90GLenum rsdKindToGLFormat(RsDataKind k) {
91 switch (k) {
92 case RS_KIND_PIXEL_L: return GL_LUMINANCE;
93 case RS_KIND_PIXEL_A: return GL_ALPHA;
94 case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
95 case RS_KIND_PIXEL_RGB: return GL_RGB;
96 case RS_KIND_PIXEL_RGBA: return GL_RGBA;
97 case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
98 default: break;
99 }
100 return 0;
101}
Jason Sams93eacc72012-12-18 14:26:57 -0800102#endif
Jason Samsa614ae12011-05-26 17:05:51 -0700103
Jason Sams807fdc42012-07-25 17:55:39 -0700104uint8_t *GetOffsetPtr(const android::renderscript::Allocation *alloc,
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700105 uint32_t xoff, uint32_t yoff, uint32_t zoff,
106 uint32_t lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -0800107 uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
108 ptr += face * alloc->mHal.drvState.faceOffset;
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700109 ptr += zoff * alloc->mHal.drvState.lod[lod].dimY * alloc->mHal.drvState.lod[lod].stride;
Jason Sams709a0972012-11-15 18:18:04 -0800110 ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
Jason Sams807fdc42012-07-25 17:55:39 -0700111 ptr += xoff * alloc->mHal.state.elementSizeBytes;
112 return ptr;
113}
114
Jason Samsa614ae12011-05-26 17:05:51 -0700115
Jason Sams2382aba2011-09-13 15:41:01 -0700116static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
117 uint32_t xoff, uint32_t yoff, uint32_t lod,
118 RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
Jason Sams93eacc72012-12-18 14:26:57 -0800119#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700120 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
121
Jason Samseb4fe182011-05-26 16:33:01 -0700122 rsAssert(drv->textureID);
Jason Sams2382aba2011-09-13 15:41:01 -0700123 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
124 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700125 GLenum t = GL_TEXTURE_2D;
126 if (alloc->mHal.state.hasFaces) {
127 t = gFaceOrder[face];
128 }
Jason Sams2382aba2011-09-13 15:41:01 -0700129 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
Jason Sams93eacc72012-12-18 14:26:57 -0800130#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700131}
132
133
Jason Sams93eacc72012-12-18 14:26:57 -0800134#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700135static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
136 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
137
Jason Sams2382aba2011-09-13 15:41:01 -0700138 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
139 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700140
141 uint32_t faceCount = 1;
142 if (alloc->mHal.state.hasFaces) {
143 faceCount = 6;
144 }
145
146 rsdGLCheckError(rsc, "Upload2DTexture 1 ");
147 for (uint32_t face = 0; face < faceCount; face ++) {
148 for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700149 const uint8_t *p = GetOffsetPtr(alloc, 0, 0, 0, lod, (RsAllocationCubemapFace)face);
Jason Samseb4fe182011-05-26 16:33:01 -0700150
151 GLenum t = GL_TEXTURE_2D;
152 if (alloc->mHal.state.hasFaces) {
153 t = gFaceOrder[face];
154 }
155
156 if (isFirstUpload) {
Jason Sams2382aba2011-09-13 15:41:01 -0700157 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
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 0, drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700161 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700162 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
Jason Samseb4fe182011-05-26 16:33:01 -0700163 alloc->mHal.state.type->getLODDimX(lod),
164 alloc->mHal.state.type->getLODDimY(lod),
Jason Samsa614ae12011-05-26 17:05:51 -0700165 drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700166 }
167 }
168 }
169
170 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700171 RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
Jason Samseb4fe182011-05-26 16:33:01 -0700172 }
173 rsdGLCheckError(rsc, "Upload2DTexture");
174}
Jason Sams93eacc72012-12-18 14:26:57 -0800175#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700176
177static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800178#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700179 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
180
Jason Sams3522f402012-03-23 11:47:26 -0700181 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
Jason Sams41e373d2012-01-13 14:01:20 -0800182 if (!drv->textureID) {
183 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
184 }
185 return;
186 }
187
Jason Samsa614ae12011-05-26 17:05:51 -0700188 if (!drv->glType || !drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700189 return;
190 }
191
Jason Sams709a0972012-11-15 18:18:04 -0800192 if (!alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700193 return;
194 }
195
196 bool isFirstUpload = false;
197
198 if (!drv->textureID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700199 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
Jason Samseb4fe182011-05-26 16:33:01 -0700200 isFirstUpload = true;
201 }
202
203 Upload2DTexture(rsc, alloc, isFirstUpload);
204
205 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Jason Sams709a0972012-11-15 18:18:04 -0800206 if (alloc->mHal.drvState.lod[0].mallocPtr) {
207 free(alloc->mHal.drvState.lod[0].mallocPtr);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700208 alloc->mHal.drvState.lod[0].mallocPtr = nullptr;
Jason Samseb4fe182011-05-26 16:33:01 -0700209 }
210 }
211 rsdGLCheckError(rsc, "UploadToTexture");
Jason Sams93eacc72012-12-18 14:26:57 -0800212#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700213}
214
215static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800216#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700217 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
218
Jason Samsa614ae12011-05-26 17:05:51 -0700219 if (!drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700220 return;
221 }
222
223 if (!drv->renderTargetID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700224 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
Jason Samseb4fe182011-05-26 16:33:01 -0700225
226 if (!drv->renderTargetID) {
227 // This should generally not happen
Steve Blockaf12ac62012-01-06 19:20:56 +0000228 ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
Jason Samseb4fe182011-05-26 16:33:01 -0700229 rsc->dumpDebug();
230 return;
231 }
Jason Sams2382aba2011-09-13 15:41:01 -0700232 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
233 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
Jason Samsa572aca2013-01-09 11:52:26 -0800234 alloc->mHal.drvState.lod[0].dimX, alloc->mHal.drvState.lod[0].dimY);
Jason Samseb4fe182011-05-26 16:33:01 -0700235 }
236 rsdGLCheckError(rsc, "AllocateRenderTarget");
Jason Sams93eacc72012-12-18 14:26:57 -0800237#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700238}
239
240static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800241#ifndef RS_COMPATIBILITY_LIB
Jason Samseb4fe182011-05-26 16:33:01 -0700242 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
243
244 rsAssert(!alloc->mHal.state.type->getDimY());
245 rsAssert(!alloc->mHal.state.type->getDimZ());
246
247 //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
248
249 if (!drv->bufferID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700250 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
Jason Samseb4fe182011-05-26 16:33:01 -0700251 }
252 if (!drv->bufferID) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000253 ALOGE("Upload to buffer object failed");
Jason Samseb4fe182011-05-26 16:33:01 -0700254 drv->uploadDeferred = true;
255 return;
256 }
Jason Sams2382aba2011-09-13 15:41:01 -0700257 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
Jason Sams61656a72013-09-03 16:21:18 -0700258 RSD_CALL_GL(glBufferData, drv->glTarget,
259 alloc->mHal.state.type->getPackedSizeBytes(),
260 alloc->mHal.drvState.lod[0].mallocPtr, GL_DYNAMIC_DRAW);
Jason Sams2382aba2011-09-13 15:41:01 -0700261 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
Jason Samseb4fe182011-05-26 16:33:01 -0700262 rsdGLCheckError(rsc, "UploadToBufferObject");
Jason Sams93eacc72012-12-18 14:26:57 -0800263#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700264}
265
Tim Murray0b575de2013-03-15 15:56:43 -0700266
Jason Sams9d8e5af2013-02-28 14:00:08 -0800267static size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
Pirama Arumuga Nainarb010bc02015-06-18 10:32:21 -0700268#ifndef RS_COMPATIBILITY_LIB
269 // For the flexible YCbCr format, layout is initialized during call to
270 // Allocation::ioReceive. Return early and avoid clobberring any
271 // pre-existing layout.
272 if (yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
273 return 0;
274 }
275#endif
276
Jason Sams733396b2013-02-22 12:46:18 -0800277 // YUV only supports basic 2d
278 // so we can stash the plane pointers in the mipmap levels.
Jason Sams9d8e5af2013-02-28 14:00:08 -0800279 size_t uvSize = 0;
Jason Sams61656a72013-09-03 16:21:18 -0700280 state->lod[1].dimX = state->lod[0].dimX / 2;
281 state->lod[1].dimY = state->lod[0].dimY / 2;
282 state->lod[2].dimX = state->lod[0].dimX / 2;
283 state->lod[2].dimY = state->lod[0].dimY / 2;
284 state->yuv.shift = 1;
285 state->yuv.step = 1;
286 state->lodCount = 3;
287
Tim Murray0b575de2013-03-15 15:56:43 -0700288#ifndef RS_SERVER
Jason Sams733396b2013-02-22 12:46:18 -0800289 switch(yuv) {
290 case HAL_PIXEL_FORMAT_YV12:
Jason Sams4961cce2013-04-11 16:11:46 -0700291 state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
292 state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
Jason Sams733396b2013-02-22 12:46:18 -0800293 (state->lod[0].stride * state->lod[0].dimY);
Jason Sams9d8e5af2013-02-28 14:00:08 -0800294 uvSize += state->lod[2].stride * state->lod[2].dimY;
Jason Sams733396b2013-02-22 12:46:18 -0800295
Jason Sams4961cce2013-04-11 16:11:46 -0700296 state->lod[1].stride = state->lod[2].stride;
297 state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
298 (state->lod[2].stride * state->lod[2].dimY);
299 uvSize += state->lod[1].stride * state->lod[2].dimY;
Jason Sams733396b2013-02-22 12:46:18 -0800300 break;
301 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
Jason Sams61656a72013-09-03 16:21:18 -0700302 //state->lod[1].dimX = state->lod[0].dimX;
Jason Sams733396b2013-02-22 12:46:18 -0800303 state->lod[1].stride = state->lod[0].stride;
Jason Sams61656a72013-09-03 16:21:18 -0700304 state->lod[2].stride = state->lod[0].stride;
305 state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
Jason Sams733396b2013-02-22 12:46:18 -0800306 (state->lod[0].stride * state->lod[0].dimY);
Jason Sams61656a72013-09-03 16:21:18 -0700307 state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) + 1;
Jason Sams9d8e5af2013-02-28 14:00:08 -0800308 uvSize += state->lod[1].stride * state->lod[1].dimY;
Jason Sams61656a72013-09-03 16:21:18 -0700309 state->yuv.step = 2;
Jason Sams733396b2013-02-22 12:46:18 -0800310 break;
311 default:
312 rsAssert(0);
313 }
Tim Murray0b575de2013-03-15 15:56:43 -0700314#endif
Jason Sams9d8e5af2013-02-28 14:00:08 -0800315 return uvSize;
Jason Sams733396b2013-02-22 12:46:18 -0800316}
317
Jason Sams463bfce2012-08-21 13:54:42 -0700318static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
Miao Wang47a58812015-07-23 21:59:16 -0700319 const Type *type, uint8_t *ptr, size_t requiredAlignment) {
Jason Sams709a0972012-11-15 18:18:04 -0800320 alloc->mHal.drvState.lod[0].dimX = type->getDimX();
321 alloc->mHal.drvState.lod[0].dimY = type->getDimY();
Jason Samsf2b611e2012-12-27 19:05:22 -0800322 alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
Jason Sams709a0972012-11-15 18:18:04 -0800323 alloc->mHal.drvState.lod[0].mallocPtr = 0;
Miao Wang47a58812015-07-23 21:59:16 -0700324 // Stride needs to be aligned to a boundary defined by requiredAlignment!
Stephen Hines94999c32013-02-05 16:58:22 -0800325 size_t stride = alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
Miao Wang47a58812015-07-23 21:59:16 -0700326 alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
Jason Sams709a0972012-11-15 18:18:04 -0800327 alloc->mHal.drvState.lodCount = type->getLODCount();
328 alloc->mHal.drvState.faceCount = type->getDimFaces();
Jason Sams807fdc42012-07-25 17:55:39 -0700329
330 size_t offsets[Allocation::MAX_LOD];
331 memset(offsets, 0, sizeof(offsets));
332
Jason Sams709a0972012-11-15 18:18:04 -0800333 size_t o = alloc->mHal.drvState.lod[0].stride * rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
334 rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
Jason Samsd06653c2014-08-01 16:18:33 -0700335 if (alloc->mHal.state.yuv) {
336 o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
337
338 for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
339 offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
340 }
341 } else if(alloc->mHal.drvState.lodCount > 1) {
Jason Sams709a0972012-11-15 18:18:04 -0800342 uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
343 uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
344 uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
345 for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
346 alloc->mHal.drvState.lod[lod].dimX = tx;
347 alloc->mHal.drvState.lod[lod].dimY = ty;
348 alloc->mHal.drvState.lod[lod].dimZ = tz;
Stephen Hines94999c32013-02-05 16:58:22 -0800349 alloc->mHal.drvState.lod[lod].stride =
Miao Wang47a58812015-07-23 21:59:16 -0700350 rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
Jason Sams807fdc42012-07-25 17:55:39 -0700351 offsets[lod] = o;
Jason Sams709a0972012-11-15 18:18:04 -0800352 o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
Jason Sams807fdc42012-07-25 17:55:39 -0700353 if (tx > 1) tx >>= 1;
354 if (ty > 1) ty >>= 1;
355 if (tz > 1) tz >>= 1;
356 }
357 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800358
Jason Sams709a0972012-11-15 18:18:04 -0800359 alloc->mHal.drvState.faceOffset = o;
Jason Sams807fdc42012-07-25 17:55:39 -0700360
Jason Sams709a0972012-11-15 18:18:04 -0800361 alloc->mHal.drvState.lod[0].mallocPtr = ptr;
362 for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
363 alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
Jason Sams463bfce2012-08-21 13:54:42 -0700364 }
Jason Sams463bfce2012-08-21 13:54:42 -0700365
Jason Sams709a0972012-11-15 18:18:04 -0800366 size_t allocSize = alloc->mHal.drvState.faceOffset;
367 if(alloc->mHal.drvState.faceCount) {
Jason Sams463bfce2012-08-21 13:54:42 -0700368 allocSize *= 6;
369 }
370
371 return allocSize;
372}
373
Miao Wang47a58812015-07-23 21:59:16 -0700374static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
375 const Type *type, uint8_t *ptr) {
376 return AllocationBuildPointerTable(rsc, alloc, type, ptr, Allocation::kMinimumRSAlignment);
377}
378
379static uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero, size_t requiredAlignment) {
380 // We align all allocations to a boundary defined by requiredAlignment.
381 uint8_t* ptr = (uint8_t *)memalign(requiredAlignment, allocSize);
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800382 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700383 return nullptr;
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800384 }
385 if (forceZero) {
386 memset(ptr, 0, allocSize);
387 }
388 return ptr;
389}
390
Miao Wang47a58812015-07-23 21:59:16 -0700391bool rsdAllocationInitStrided(const Context *rsc, Allocation *alloc, bool forceZero, size_t requiredAlignment) {
Jason Sams463bfce2012-08-21 13:54:42 -0700392 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
393 if (!drv) {
394 return false;
395 }
396 alloc->mHal.drv = drv;
397
Miao Wang47a58812015-07-23 21:59:16 -0700398 // Check if requiredAlignment is power of 2, also requiredAlignment should be larger or equal than kMinimumRSAlignment.
399 if ((requiredAlignment & (requiredAlignment-1)) != 0 || requiredAlignment < Allocation::kMinimumRSAlignment) {
400 ALOGE("requiredAlignment must be power of 2");
401 return false;
402 }
Jason Sams463bfce2012-08-21 13:54:42 -0700403 // Calculate the object size.
Miao Wang47a58812015-07-23 21:59:16 -0700404 size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), nullptr, requiredAlignment);
Jason Sams463bfce2012-08-21 13:54:42 -0700405
Chris Wailes44bef6f2014-08-12 13:51:10 -0700406 uint8_t * ptr = nullptr;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800407 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
Jason Sams733396b2013-02-22 12:46:18 -0800408
409 } else if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
410 // Allocation is allocated when the surface is created
411 // in getSurface
Miao Wang47a58812015-07-23 21:59:16 -0700412#ifdef RS_COMPATIBILITY_LIB
413 } else if (alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT | RS_ALLOCATION_USAGE_SHARED)) {
414 if (alloc->mHal.state.userProvidedPtr == nullptr) {
415 ALOGE("User-backed buffer pointer cannot be null");
416 return false;
417 }
418 if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
419 ALOGE("User-allocated buffers must not have multiple faces or LODs");
420 return false;
421 }
422
423 drv->useUserProvidedPtr = true;
424 ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
425#endif
Chris Wailes44bef6f2014-08-12 13:51:10 -0700426 } else if (alloc->mHal.state.userProvidedPtr != nullptr) {
Tim Murray2e1a94d2012-11-29 13:12:25 -0800427 // user-provided allocation
Tim Murrayba24d082013-04-09 17:31:11 -0700428 // limitations: no faces, no LOD, USAGE_SCRIPT or SCRIPT+TEXTURE only
429 if (!(alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED) ||
430 alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))) {
431 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 -0800432 return false;
433 }
434 if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
435 ALOGE("User-allocated buffers must not have multiple faces or LODs");
436 return false;
437 }
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800438
Miao Wang47a58812015-07-23 21:59:16 -0700439 // rows must be aligned based on requiredAlignment.
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800440 // validate that here, otherwise fall back to not use the user-backed allocation
Miao Wang47a58812015-07-23 21:59:16 -0700441 if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % requiredAlignment) != 0) {
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800442 ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
443 drv->useUserProvidedPtr = false;
444
Miao Wang47a58812015-07-23 21:59:16 -0700445 ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800446 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700447 alloc->mHal.drv = nullptr;
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800448 free(drv);
449 return false;
450 }
451
452 } else {
453 drv->useUserProvidedPtr = true;
454 ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
455 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800456 } else {
Miao Wang47a58812015-07-23 21:59:16 -0700457 ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
Jason Sams179e9a42011-11-23 15:02:15 -0800458 if (!ptr) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700459 alloc->mHal.drv = nullptr;
Jason Sams179e9a42011-11-23 15:02:15 -0800460 free(drv);
461 return false;
462 }
Jason Samseb4fe182011-05-26 16:33:01 -0700463 }
Jason Sams463bfce2012-08-21 13:54:42 -0700464 // Build the pointer tables
Miao Wang47a58812015-07-23 21:59:16 -0700465 size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr, requiredAlignment);
Jason Sams463bfce2012-08-21 13:54:42 -0700466 if(allocSize != verifySize) {
467 rsAssert(!"Size mismatch");
Jason Sams807fdc42012-07-25 17:55:39 -0700468 }
Jason Samseb4fe182011-05-26 16:33:01 -0700469
Tim Murray0b575de2013-03-15 15:56:43 -0700470#ifndef RS_SERVER
Jason Samseb4fe182011-05-26 16:33:01 -0700471 drv->glTarget = GL_NONE;
472 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
473 if (alloc->mHal.state.hasFaces) {
474 drv->glTarget = GL_TEXTURE_CUBE_MAP;
475 } else {
476 drv->glTarget = GL_TEXTURE_2D;
477 }
478 } else {
479 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
480 drv->glTarget = GL_ARRAY_BUFFER;
481 }
482 }
Tim Murray0b575de2013-03-15 15:56:43 -0700483#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700484
Jason Sams93eacc72012-12-18 14:26:57 -0800485#ifndef RS_COMPATIBILITY_LIB
Jason Samsa614ae12011-05-26 17:05:51 -0700486 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
487 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
Jason Sams93eacc72012-12-18 14:26:57 -0800488#else
489 drv->glType = 0;
490 drv->glFormat = 0;
491#endif
Jason Samsa614ae12011-05-26 17:05:51 -0700492
Jason Samseb4fe182011-05-26 16:33:01 -0700493 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
494 drv->uploadDeferred = true;
495 }
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700496
Jason Samsb3220332012-04-02 14:41:54 -0700497
Chris Wailes44bef6f2014-08-12 13:51:10 -0700498 drv->readBackFBO = nullptr;
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700499
Tim Murrayc2cfe6a2013-02-14 16:21:33 -0800500 // fill out the initial state of the buffer if we couldn't use the user-provided ptr and USAGE_SHARED was accepted
501 if ((alloc->mHal.state.userProvidedPtr != 0) && (drv->useUserProvidedPtr == false)) {
502 rsdAllocationData2D(rsc, alloc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, alloc->getType()->getDimX(), alloc->getType()->getDimY(), alloc->mHal.state.userProvidedPtr, allocSize, 0);
503 }
504
Tim Murraye3af53b2014-06-10 09:46:51 -0700505
506#ifdef RS_FIND_OFFSETS
507 ALOGE("pointer for allocation: %p", alloc);
508 ALOGE("pointer for allocation.drv: %p", &alloc->mHal.drv);
509#endif
510
511
Jason Samseb4fe182011-05-26 16:33:01 -0700512 return true;
513}
514
Miao Wang47a58812015-07-23 21:59:16 -0700515bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
516 return rsdAllocationInitStrided(rsc, alloc, forceZero, Allocation::kMinimumRSAlignment);
517}
518
Jason Samsbc9dc272015-02-09 12:50:22 -0800519void rsdAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
520 //ALOGE("rsdAllocationAdapterOffset");
521
522 // Get a base pointer to the new LOD
523 const Allocation *base = alloc->mHal.state.baseAlloc;
524 const Type *type = alloc->mHal.state.type;
525 if (base == nullptr) {
526 return;
527 }
528
Jason Samsbc9dc272015-02-09 12:50:22 -0800529 //ALOGE("rsdAllocationAdapterOffset %p %p", ptrA, ptrB);
530 //ALOGE("rsdAllocationAdapterOffset lodCount %i", alloc->mHal.drvState.lodCount);
531
532 const int lodBias = alloc->mHal.state.originLOD;
533 uint32_t lodCount = rsMax(alloc->mHal.drvState.lodCount, (uint32_t)1);
534 for (uint32_t lod=0; lod < lodCount; lod++) {
535 alloc->mHal.drvState.lod[lod] = base->mHal.drvState.lod[lod + lodBias];
Jason Sams2178d422015-03-24 15:51:27 -0700536 alloc->mHal.drvState.lod[lod].mallocPtr = GetOffsetPtr(alloc,
537 alloc->mHal.state.originX, alloc->mHal.state.originY, alloc->mHal.state.originZ,
538 lodBias, (RsAllocationCubemapFace)alloc->mHal.state.originFace);
Jason Samsbc9dc272015-02-09 12:50:22 -0800539 }
540}
541
542bool rsdAllocationAdapterInit(const Context *rsc, Allocation *alloc) {
543 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
544 if (!drv) {
545 return false;
546 }
547 alloc->mHal.drv = drv;
548
549 // We need to build an allocation that looks like a subset of the parent allocation
550 rsdAllocationAdapterOffset(rsc, alloc);
551
552 return true;
553}
554
Jason Samseb4fe182011-05-26 16:33:01 -0700555void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
556 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
557
Jason Samsbc9dc272015-02-09 12:50:22 -0800558 if (alloc->mHal.state.baseAlloc == nullptr) {
Jason Sams93eacc72012-12-18 14:26:57 -0800559#ifndef RS_COMPATIBILITY_LIB
Jason Samsbc9dc272015-02-09 12:50:22 -0800560 if (drv->bufferID) {
561 // Causes a SW crash....
562 //ALOGV(" mBufferID %i", mBufferID);
563 //glDeleteBuffers(1, &mBufferID);
564 //mBufferID = 0;
565 }
566 if (drv->textureID) {
567 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
568 drv->textureID = 0;
569 }
570 if (drv->renderTargetID) {
571 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
572 drv->renderTargetID = 0;
573 }
Jason Sams93eacc72012-12-18 14:26:57 -0800574#endif
Jason Samseb4fe182011-05-26 16:33:01 -0700575
Jason Samsbc9dc272015-02-09 12:50:22 -0800576 if (alloc->mHal.drvState.lod[0].mallocPtr) {
577 // don't free user-allocated ptrs or IO_OUTPUT buffers
578 if (!(drv->useUserProvidedPtr) &&
579 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
580 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
581 free(alloc->mHal.drvState.lod[0].mallocPtr);
582 }
583 alloc->mHal.drvState.lod[0].mallocPtr = nullptr;
Tim Murray2e1a94d2012-11-29 13:12:25 -0800584 }
Jason Sams93eacc72012-12-18 14:26:57 -0800585
586#ifndef RS_COMPATIBILITY_LIB
Jason Samsbc9dc272015-02-09 12:50:22 -0800587 if (drv->readBackFBO != nullptr) {
588 delete drv->readBackFBO;
589 drv->readBackFBO = nullptr;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800590 }
Jason Samsbc9dc272015-02-09 12:50:22 -0800591
592 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
593 (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
594
595 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
596 ANativeWindow *nw = drv->wndSurface;
597 if (nw) {
598 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
599 mapper.unlock(drv->wndBuffer->handle);
Jason Samsabc1f942015-05-18 17:45:26 -0700600 int32_t r = nw->cancelBuffer(nw, drv->wndBuffer, -1);
Jason Samsbc9dc272015-02-09 12:50:22 -0800601
602 drv->wndSurface = nullptr;
603 native_window_api_disconnect(nw, NATIVE_WINDOW_API_CPU);
604 nw->decStrong(nullptr);
605 }
606 }
Jason Sams93eacc72012-12-18 14:26:57 -0800607#endif
Jason Samsbc9dc272015-02-09 12:50:22 -0800608 }
Jason Sams93eacc72012-12-18 14:26:57 -0800609
Jason Samseb4fe182011-05-26 16:33:01 -0700610 free(drv);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700611 alloc->mHal.drv = nullptr;
Jason Samseb4fe182011-05-26 16:33:01 -0700612}
613
614void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
615 const Type *newType, bool zeroNew) {
Jason Samsa572aca2013-01-09 11:52:26 -0800616 const uint32_t oldDimX = alloc->mHal.drvState.lod[0].dimX;
617 const uint32_t dimX = newType->getDimX();
618
Tim Murray9e2bda52012-12-18 12:05:46 -0800619 // can't resize Allocations with user-allocated buffers
620 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
621 ALOGE("Resize cannot be called on a USAGE_SHARED allocation");
622 return;
623 }
Jason Sams709a0972012-11-15 18:18:04 -0800624 void * oldPtr = alloc->mHal.drvState.lod[0].mallocPtr;
Jason Sams463bfce2012-08-21 13:54:42 -0700625 // Calculate the object size
Chris Wailes44bef6f2014-08-12 13:51:10 -0700626 size_t s = AllocationBuildPointerTable(rsc, alloc, newType, nullptr);
Jason Sams463bfce2012-08-21 13:54:42 -0700627 uint8_t *ptr = (uint8_t *)realloc(oldPtr, s);
628 // Build the relative pointer tables.
629 size_t verifySize = AllocationBuildPointerTable(rsc, alloc, newType, ptr);
630 if(s != verifySize) {
631 rsAssert(!"Size mismatch");
632 }
Jason Samseb4fe182011-05-26 16:33:01 -0700633
Jason Samseb4fe182011-05-26 16:33:01 -0700634
635 if (dimX > oldDimX) {
Tim Murray099bc262013-03-20 16:54:03 -0700636 size_t stride = alloc->mHal.state.elementSizeBytes;
Jason Sams709a0972012-11-15 18:18:04 -0800637 memset(((uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr) + stride * oldDimX,
Jason Sams2275e9c2012-04-16 17:01:26 -0700638 0, stride * (dimX - oldDimX));
Jason Samseb4fe182011-05-26 16:33:01 -0700639 }
640}
641
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700642static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800643#ifndef RS_COMPATIBILITY_LIB
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700644 if (!alloc->getIsScript()) {
645 return; // nothing to sync
646 }
647
648 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
649 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
650
651 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
652 if (!drv->textureID && !drv->renderTargetID) {
653 return; // nothing was rendered here yet, so nothing to sync
654 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700655 if (drv->readBackFBO == nullptr) {
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700656 drv->readBackFBO = new RsdFrameBufferObj();
657 drv->readBackFBO->setColorTarget(drv, 0);
658 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
659 alloc->getType()->getDimY());
660 }
661
662 // Bind the framebuffer object so we can read back from it
663 drv->readBackFBO->setActive(rsc);
664
665 // Do the readback
Jason Sams709a0972012-11-15 18:18:04 -0800666 RSD_CALL_GL(glReadPixels, 0, 0, alloc->mHal.drvState.lod[0].dimX,
667 alloc->mHal.drvState.lod[0].dimY,
668 drv->glFormat, drv->glType, alloc->mHal.drvState.lod[0].mallocPtr);
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700669
670 // Revert framebuffer to its original
671 lastFbo->setActive(rsc);
Jason Sams93eacc72012-12-18 14:26:57 -0800672#endif
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700673}
Jason Samseb4fe182011-05-26 16:33:01 -0700674
675
676void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
677 RsAllocationUsageType src) {
678 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
679
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700680 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
681 if(!alloc->getIsRenderTarget()) {
682 rsc->setError(RS_ERROR_FATAL_DRIVER,
683 "Attempting to sync allocation from render target, "
684 "for non-render target allocation");
685 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
686 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
687 "render target");
688 } else {
689 rsdAllocationSyncFromFBO(rsc, alloc);
690 }
Jason Samseb4fe182011-05-26 16:33:01 -0700691 return;
692 }
693
Jason Samsb8a94e22014-02-24 17:52:32 -0800694 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT || src == RS_ALLOCATION_USAGE_SHARED);
Jason Samseb4fe182011-05-26 16:33:01 -0700695
696 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
697 UploadToTexture(rsc, alloc);
698 } else {
Jason Samsb3220332012-04-02 14:41:54 -0700699 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
Jason Sams0dc66932012-04-10 17:05:49 -0700700 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
Jason Samseb4fe182011-05-26 16:33:01 -0700701 AllocateRenderTarget(rsc, alloc);
702 }
703 }
704 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
705 UploadToBufferObject(rsc, alloc);
706 }
707
Tim Murrayba24d082013-04-09 17:31:11 -0700708 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
Jason Samsb8a94e22014-02-24 17:52:32 -0800709
710 if (src == RS_ALLOCATION_USAGE_SHARED) {
711 // just a memory fence for the CPU driver
712 // vendor drivers probably want to flush any dirty cachelines for
713 // this particular Allocation
714 __sync_synchronize();
715 }
Tim Murrayba24d082013-04-09 17:31:11 -0700716 }
717
Jason Samseb4fe182011-05-26 16:33:01 -0700718 drv->uploadDeferred = false;
719}
720
721void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
722 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
723 drv->uploadDeferred = true;
724}
725
Jason Sams4961cce2013-04-11 16:11:46 -0700726#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800727static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
728 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
729
Jamie Genniscd919a12012-06-13 16:34:11 -0700730 int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800731 if (r) {
732 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
733 return false;
734 }
735
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800736 // Must lock the whole surface
737 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
738 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
739
Chris Wailes44bef6f2014-08-12 13:51:10 -0700740 void *dst = nullptr;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800741 mapper.lock(drv->wndBuffer->handle,
742 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
743 bounds, &dst);
Jason Sams709a0972012-11-15 18:18:04 -0800744 alloc->mHal.drvState.lod[0].mallocPtr = dst;
745 alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
Stephen Hines94999c32013-02-05 16:58:22 -0800746 rsAssert((alloc->mHal.drvState.lod[0].stride & 0xf) == 0);
Jason Samsb3220332012-04-02 14:41:54 -0700747
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800748 return true;
749}
Jason Sams93eacc72012-12-18 14:26:57 -0800750#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800751
Jason Sams733396b2013-02-22 12:46:18 -0800752void rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
Jason Sams93eacc72012-12-18 14:26:57 -0800753#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800754 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800755 ANativeWindow *old = drv->wndSurface;
756
757 if (nw) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700758 nw->incStrong(nullptr);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800759 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800760
Jason Samsb3220332012-04-02 14:41:54 -0700761 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
762 //TODO finish support for render target + script
763 drv->wnd = nw;
764 return;
765 }
766
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800767 // Cleanup old surface if there is one.
Tim Murray3a25fdd2013-02-22 17:56:56 -0800768 if (drv->wndSurface) {
769 ANativeWindow *old = drv->wndSurface;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800770 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
771 mapper.unlock(drv->wndBuffer->handle);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800772 old->cancelBuffer(old, drv->wndBuffer, -1);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700773 drv->wndSurface = nullptr;
Jason Sams9dae48e2013-09-23 15:56:11 -0700774
775 native_window_api_disconnect(old, NATIVE_WINDOW_API_CPU);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700776 old->decStrong(nullptr);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800777 }
778
Chris Wailes44bef6f2014-08-12 13:51:10 -0700779 if (nw != nullptr) {
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800780 int32_t r;
Jason Samsb3220332012-04-02 14:41:54 -0700781 uint32_t flags = 0;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800782
Jason Samsb3220332012-04-02 14:41:54 -0700783 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
784 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
785 }
786 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
787 flags |= GRALLOC_USAGE_HW_RENDER;
788 }
789
Jason Sams9dae48e2013-09-23 15:56:11 -0700790 r = native_window_api_connect(nw, NATIVE_WINDOW_API_CPU);
791 if (r) {
792 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
793 goto error;
794 }
795
Jason Samsb3220332012-04-02 14:41:54 -0700796 r = native_window_set_usage(nw, flags);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800797 if (r) {
798 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800799 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800800 }
801
Jason Samsa572aca2013-01-09 11:52:26 -0800802 r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
803 alloc->mHal.drvState.lod[0].dimY);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800804 if (r) {
805 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800806 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800807 }
808
Jason Sams733396b2013-02-22 12:46:18 -0800809 int format = 0;
810 const Element *e = alloc->mHal.state.type->getElement();
Jason Sams3b0efb62015-02-25 14:29:49 -0800811 if ((e->getType() != RS_TYPE_UNSIGNED_8) ||
812 (e->getVectorSize() != 4)) {
813 // We do not check for RGBA, RGBx, to allow for interop with U8_4
814
815 rsc->setError(RS_ERROR_DRIVER, "Surface passed to setSurface is not U8_4, RGBA.");
816 goto error;
817 }
Stephen Hines8b9b3aa2013-08-02 15:51:36 -0700818 format = PIXEL_FORMAT_RGBA_8888;
Jason Sams733396b2013-02-22 12:46:18 -0800819
820 r = native_window_set_buffers_format(nw, format);
821 if (r) {
822 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
Tim Murray3a25fdd2013-02-22 17:56:56 -0800823 goto error;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800824 }
825
826 IoGetBuffer(rsc, alloc, nw);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800827 drv->wndSurface = nw;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800828 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800829
830 return;
831
832 error:
833
834 if (nw) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700835 nw->decStrong(nullptr);
Tim Murray3a25fdd2013-02-22 17:56:56 -0800836 }
837
838
Jason Sams93eacc72012-12-18 14:26:57 -0800839#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800840}
841
842void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800843#ifndef RS_COMPATIBILITY_LIB
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800844 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Tim Murray3a25fdd2013-02-22 17:56:56 -0800845 ANativeWindow *nw = drv->wndSurface;
Jason Samsb3220332012-04-02 14:41:54 -0700846 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
847 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
848 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800849 return;
850 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800851 if (nw) {
852 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
853 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
854 mapper.unlock(drv->wndBuffer->handle);
855 int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
856 if (r) {
857 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
858 return;
859 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800860
Tim Murray3a25fdd2013-02-22 17:56:56 -0800861 IoGetBuffer(rsc, alloc, nw);
Jason Samsb3220332012-04-02 14:41:54 -0700862 }
Tim Murray3a25fdd2013-02-22 17:56:56 -0800863 } else {
864 rsc->setError(RS_ERROR_DRIVER, "Sent IO buffer with no attached surface.");
865 return;
Jason Samsb3220332012-04-02 14:41:54 -0700866 }
Jason Sams93eacc72012-12-18 14:26:57 -0800867#endif
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800868}
869
870void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
Jason Sams93eacc72012-12-18 14:26:57 -0800871#ifndef RS_COMPATIBILITY_LIB
Jason Sams3522f402012-03-23 11:47:26 -0700872 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Jason Samsddceab92013-08-07 13:02:32 -0700873 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Tim Murray3a25fdd2013-02-22 17:56:56 -0800874 drv->surfaceTexture->updateTexImage();
Jason Sams733396b2013-02-22 12:46:18 -0800875 }
Jason Sams93eacc72012-12-18 14:26:57 -0800876#endif
Jason Sams7314cca2015-02-24 18:25:59 -0800877 if (alloc->mHal.state.yuv) {
878 DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
879 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800880}
881
882
Jason Samseb4fe182011-05-26 16:33:01 -0700883void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
Tim Murray099bc262013-03-20 16:54:03 -0700884 uint32_t xoff, uint32_t lod, size_t count,
Alex Sakhartchoukc794cd52012-02-13 11:57:32 -0800885 const void *data, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -0700886 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
887
Tim Murray099bc262013-03-20 16:54:03 -0700888 const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700889 uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Tim Murray099bc262013-03-20 16:54:03 -0700890 size_t size = count * eSize;
Stephen Hines20c535f2012-12-06 19:04:38 -0800891 if (ptr != data) {
892 // Skip the copy if we are the same allocation. This can arise from
893 // our Bitmap optimization, where we share the same storage.
894 if (alloc->mHal.state.hasReferences) {
895 alloc->incRefs(data, count);
896 alloc->decRefs(ptr, count);
897 }
898 memcpy(ptr, data, size);
Jason Samseb4fe182011-05-26 16:33:01 -0700899 }
Jason Samseb4fe182011-05-26 16:33:01 -0700900 drv->uploadDeferred = true;
901}
902
903void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
904 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Tim Murray358747a2012-11-26 13:52:04 -0800905 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
Jason Samseb4fe182011-05-26 16:33:01 -0700906 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
907
Tim Murray099bc262013-03-20 16:54:03 -0700908 size_t eSize = alloc->mHal.state.elementSizeBytes;
909 size_t lineSize = eSize * w;
Tim Murray358747a2012-11-26 13:52:04 -0800910 if (!stride) {
911 stride = lineSize;
912 }
Jason Samseb4fe182011-05-26 16:33:01 -0700913
Jason Sams709a0972012-11-15 18:18:04 -0800914 if (alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700915 const uint8_t *src = static_cast<const uint8_t *>(data);
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700916 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Stephen Hines20c535f2012-12-06 19:04:38 -0800917 if (dst == src) {
918 // Skip the copy if we are the same allocation. This can arise from
919 // our Bitmap optimization, where we share the same storage.
920 drv->uploadDeferred = true;
921 return;
922 }
Jason Samseb4fe182011-05-26 16:33:01 -0700923
924 for (uint32_t line=yoff; line < (yoff+h); line++) {
925 if (alloc->mHal.state.hasReferences) {
926 alloc->incRefs(src, w);
927 alloc->decRefs(dst, w);
928 }
929 memcpy(dst, src, lineSize);
Tim Murray358747a2012-11-26 13:52:04 -0800930 src += stride;
Jason Sams709a0972012-11-15 18:18:04 -0800931 dst += alloc->mHal.drvState.lod[lod].stride;
Jason Samseb4fe182011-05-26 16:33:01 -0700932 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800933 if (alloc->mHal.state.yuv) {
Jason Sams0052f8d2013-09-19 17:27:29 -0700934 size_t clineSize = lineSize;
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800935 int lod = 1;
Jason Sams61656a72013-09-03 16:21:18 -0700936 int maxLod = 2;
937 if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YV12) {
938 maxLod = 3;
Jason Sams0052f8d2013-09-19 17:27:29 -0700939 clineSize >>= 1;
Jason Sams61656a72013-09-03 16:21:18 -0700940 } else if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
941 lod = 2;
942 maxLod = 3;
943 }
944
945 while (lod < maxLod) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700946 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800947
948 for (uint32_t line=(yoff >> 1); line < ((yoff+h)>>1); line++) {
Jason Sams0052f8d2013-09-19 17:27:29 -0700949 memcpy(dst, src, clineSize);
Miao Wang6b855bd2016-04-24 15:41:12 -0700950 // When copying from an array to an Allocation, the src pointer
951 // to the array should just move by the number of bytes copied.
952 src += clineSize;
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800953 dst += alloc->mHal.drvState.lod[lod].stride;
954 }
955 lod++;
956 }
957
958 }
Jason Samseb4fe182011-05-26 16:33:01 -0700959 drv->uploadDeferred = true;
960 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700961 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
Jason Samseb4fe182011-05-26 16:33:01 -0700962 }
963}
964
965void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
966 uint32_t xoff, uint32_t yoff, uint32_t zoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700967 uint32_t lod,
968 uint32_t w, uint32_t h, uint32_t d, const void *data,
969 size_t sizeBytes, size_t stride) {
970 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
Jason Samseb4fe182011-05-26 16:33:01 -0700971
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700972 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
973 uint32_t lineSize = eSize * w;
974 if (!stride) {
975 stride = lineSize;
976 }
977
978 if (alloc->mHal.drvState.lod[0].mallocPtr) {
979 const uint8_t *src = static_cast<const uint8_t *>(data);
Miao Wanga814de92015-02-25 18:45:31 -0800980 for (uint32_t z = zoff; z < (d + zoff); z++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -0700981 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
982 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
983 if (dst == src) {
984 // Skip the copy if we are the same allocation. This can arise from
985 // our Bitmap optimization, where we share the same storage.
986 drv->uploadDeferred = true;
987 return;
988 }
989
990 for (uint32_t line=yoff; line < (yoff+h); line++) {
991 if (alloc->mHal.state.hasReferences) {
992 alloc->incRefs(src, w);
993 alloc->decRefs(dst, w);
994 }
995 memcpy(dst, src, lineSize);
996 src += stride;
997 dst += alloc->mHal.drvState.lod[lod].stride;
998 }
999 }
1000 drv->uploadDeferred = true;
1001 }
Jason Samseb4fe182011-05-26 16:33:01 -07001002}
1003
Jason Sams807fdc42012-07-25 17:55:39 -07001004void rsdAllocationRead1D(const Context *rsc, const Allocation *alloc,
Tim Murray099bc262013-03-20 16:54:03 -07001005 uint32_t xoff, uint32_t lod, size_t count,
Jason Sams807fdc42012-07-25 17:55:39 -07001006 void *data, size_t sizeBytes) {
Tim Murray099bc262013-03-20 16:54:03 -07001007 const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001008 const uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Stephen Hines20c535f2012-12-06 19:04:38 -08001009 if (data != ptr) {
1010 // Skip the copy if we are the same allocation. This can arise from
1011 // our Bitmap optimization, where we share the same storage.
1012 memcpy(data, ptr, count * eSize);
1013 }
Jason Sams807fdc42012-07-25 17:55:39 -07001014}
1015
1016void rsdAllocationRead2D(const Context *rsc, const Allocation *alloc,
Tim Murray358747a2012-11-26 13:52:04 -08001017 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
1018 uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
Tim Murray099bc262013-03-20 16:54:03 -07001019 size_t eSize = alloc->mHal.state.elementSizeBytes;
1020 size_t lineSize = eSize * w;
Tim Murray358747a2012-11-26 13:52:04 -08001021 if (!stride) {
1022 stride = lineSize;
1023 }
Jason Sams807fdc42012-07-25 17:55:39 -07001024
Jason Sams709a0972012-11-15 18:18:04 -08001025 if (alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Sams807fdc42012-07-25 17:55:39 -07001026 uint8_t *dst = static_cast<uint8_t *>(data);
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001027 const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
Stephen Hines20c535f2012-12-06 19:04:38 -08001028 if (dst == src) {
1029 // Skip the copy if we are the same allocation. This can arise from
1030 // our Bitmap optimization, where we share the same storage.
1031 return;
1032 }
Jason Sams807fdc42012-07-25 17:55:39 -07001033
1034 for (uint32_t line=yoff; line < (yoff+h); line++) {
1035 memcpy(dst, src, lineSize);
Tim Murray358747a2012-11-26 13:52:04 -08001036 dst += stride;
Jason Sams709a0972012-11-15 18:18:04 -08001037 src += alloc->mHal.drvState.lod[lod].stride;
Jason Sams807fdc42012-07-25 17:55:39 -07001038 }
1039 } else {
1040 ALOGE("Add code to readback from non-script memory");
1041 }
1042}
1043
Tim Murray358747a2012-11-26 13:52:04 -08001044
Jason Sams807fdc42012-07-25 17:55:39 -07001045void rsdAllocationRead3D(const Context *rsc, const Allocation *alloc,
1046 uint32_t xoff, uint32_t yoff, uint32_t zoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001047 uint32_t lod,
1048 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
1049 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
1050 uint32_t lineSize = eSize * w;
1051 if (!stride) {
1052 stride = lineSize;
1053 }
Jason Sams807fdc42012-07-25 17:55:39 -07001054
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001055 if (alloc->mHal.drvState.lod[0].mallocPtr) {
1056 uint8_t *dst = static_cast<uint8_t *>(data);
Miao Wanga814de92015-02-25 18:45:31 -08001057 for (uint32_t z = zoff; z < (d + zoff); z++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001058 const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
1059 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1060 if (dst == src) {
1061 // Skip the copy if we are the same allocation. This can arise from
1062 // our Bitmap optimization, where we share the same storage.
1063 return;
1064 }
1065
1066 for (uint32_t line=yoff; line < (yoff+h); line++) {
1067 memcpy(dst, src, lineSize);
1068 dst += stride;
1069 src += alloc->mHal.drvState.lod[lod].stride;
1070 }
1071 }
1072 }
Jason Sams807fdc42012-07-25 17:55:39 -07001073}
1074
1075void * rsdAllocationLock1D(const android::renderscript::Context *rsc,
1076 const android::renderscript::Allocation *alloc) {
Jason Sams709a0972012-11-15 18:18:04 -08001077 return alloc->mHal.drvState.lod[0].mallocPtr;
Jason Sams807fdc42012-07-25 17:55:39 -07001078}
1079
1080void rsdAllocationUnlock1D(const android::renderscript::Context *rsc,
1081 const android::renderscript::Allocation *alloc) {
1082
1083}
1084
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001085void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
1086 const android::renderscript::Allocation *dstAlloc,
Tim Murray099bc262013-03-20 16:54:03 -07001087 uint32_t dstXoff, uint32_t dstLod, size_t count,
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001088 const android::renderscript::Allocation *srcAlloc,
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001089 uint32_t srcXoff, uint32_t srcLod) {
1090}
1091
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001092
1093void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
1094 const android::renderscript::Allocation *dstAlloc,
1095 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1096 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1097 const android::renderscript::Allocation *srcAlloc,
1098 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1099 RsAllocationCubemapFace srcFace) {
Tim Murray099bc262013-03-20 16:54:03 -07001100 size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001101 for (uint32_t i = 0; i < h; i ++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001102 uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
1103 uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001104 memcpy(dstPtr, srcPtr, w * elementSize);
1105
Steve Blockaf12ac62012-01-06 19:20:56 +00001106 //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 -07001107 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001108 }
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001109}
1110
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001111void rsdAllocationData3D_alloc_script(const android::renderscript::Context *rsc,
1112 const android::renderscript::Allocation *dstAlloc,
1113 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod,
1114 uint32_t w, uint32_t h, uint32_t d,
1115 const android::renderscript::Allocation *srcAlloc,
1116 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod) {
1117 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
1118 for (uint32_t j = 0; j < d; j++) {
1119 for (uint32_t i = 0; i < h; i ++) {
1120 uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j,
1121 dstLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1122 uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j,
1123 srcLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1124 memcpy(dstPtr, srcPtr, w * elementSize);
1125
1126 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
1127 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
1128 }
1129 }
1130}
1131
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001132void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
1133 const android::renderscript::Allocation *dstAlloc,
1134 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1135 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1136 const android::renderscript::Allocation *srcAlloc,
1137 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1138 RsAllocationCubemapFace srcFace) {
Alex Sakhartchouka9495242011-06-16 11:05:13 -07001139 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
1140 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
1141 "yet implemented.");
1142 return;
1143 }
1144 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
1145 dstLod, dstFace, w, h, srcAlloc,
1146 srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001147}
1148
1149void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
1150 const android::renderscript::Allocation *dstAlloc,
1151 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001152 uint32_t dstLod,
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001153 uint32_t w, uint32_t h, uint32_t d,
1154 const android::renderscript::Allocation *srcAlloc,
1155 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001156 uint32_t srcLod) {
1157 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
1158 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
1159 "yet implemented.");
1160 return;
1161 }
1162 rsdAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
1163 dstLod, w, h, d, srcAlloc,
1164 srcXoff, srcYoff, srcZoff, srcLod);
Alex Sakhartchouk74a82792011-06-14 11:13:19 -07001165}
1166
Miao Wangcc8cea72015-02-19 18:14:46 -08001167void rsdAllocationElementData(const Context *rsc, const Allocation *alloc,
1168 uint32_t x, uint32_t y, uint32_t z,
1169 const void *data, uint32_t cIdx, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -07001170 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1171
Miao Wangcc8cea72015-02-19 18:14:46 -08001172 uint8_t * ptr = GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -07001173
1174 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
1175 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
1176
1177 if (alloc->mHal.state.hasReferences) {
1178 e->incRefs(data);
1179 e->decRefs(ptr);
1180 }
1181
1182 memcpy(ptr, data, sizeBytes);
1183 drv->uploadDeferred = true;
1184}
1185
Miao Wangcc8cea72015-02-19 18:14:46 -08001186void rsdAllocationElementRead(const Context *rsc, const Allocation *alloc,
1187 uint32_t x, uint32_t y, uint32_t z,
1188 void *data, uint32_t cIdx, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -07001189 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1190
Miao Wangcc8cea72015-02-19 18:14:46 -08001191 uint8_t * ptr = GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -07001192
1193 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
1194 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
1195
Miao Wangcc8cea72015-02-19 18:14:46 -08001196 memcpy(data, ptr, sizeBytes);
Jason Samseb4fe182011-05-26 16:33:01 -07001197}
1198
Jason Sams61a4bb72012-07-25 19:33:43 -07001199static void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001200 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1201 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001202
1203 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001204 uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1205 const uint16_t *i1 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2, lod, face);
1206 const uint16_t *i2 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2+1, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001207
1208 for (uint32_t x=0; x < w; x++) {
1209 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
1210 oPtr ++;
1211 i1 += 2;
1212 i2 += 2;
1213 }
1214 }
1215}
1216
1217static void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001218 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1219 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001220
1221 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001222 uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1223 const uint32_t *i1 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1224 const uint32_t *i2 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001225
1226 for (uint32_t x=0; x < w; x++) {
1227 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
1228 oPtr ++;
1229 i1 += 2;
1230 i2 += 2;
1231 }
1232 }
1233}
1234
1235static void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
Jason Sams709a0972012-11-15 18:18:04 -08001236 uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
1237 uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
Jason Sams61a4bb72012-07-25 19:33:43 -07001238
1239 for (uint32_t y=0; y < h; y++) {
Jason Sams3bbc0fd2013-04-09 14:16:13 -07001240 uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1241 const uint8_t *i1 = GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1242 const uint8_t *i2 = GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
Jason Sams61a4bb72012-07-25 19:33:43 -07001243
1244 for (uint32_t x=0; x < w; x++) {
1245 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
1246 oPtr ++;
1247 i1 += 2;
1248 i2 += 2;
1249 }
1250 }
1251}
1252
1253void rsdAllocationGenerateMipmaps(const Context *rsc, const Allocation *alloc) {
Jason Sams709a0972012-11-15 18:18:04 -08001254 if(!alloc->mHal.drvState.lod[0].mallocPtr) {
Jason Sams61a4bb72012-07-25 19:33:43 -07001255 return;
1256 }
1257 uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
1258 for (uint32_t face = 0; face < numFaces; face ++) {
1259 for (uint32_t lod=0; lod < (alloc->getType()->getLODCount() -1); lod++) {
1260 switch (alloc->getType()->getElement()->getSizeBits()) {
1261 case 32:
1262 mip8888(alloc, lod, (RsAllocationCubemapFace)face);
1263 break;
1264 case 16:
1265 mip565(alloc, lod, (RsAllocationCubemapFace)face);
1266 break;
1267 case 8:
1268 mip8(alloc, lod, (RsAllocationCubemapFace)face);
1269 break;
1270 }
1271 }
1272 }
1273}
Jason Samsddceab92013-08-07 13:02:32 -07001274
1275uint32_t rsdAllocationGrallocBits(const android::renderscript::Context *rsc,
1276 android::renderscript::Allocation *alloc)
1277{
1278 return 0;
1279}
1280
Jason Samsa36c50a2014-06-17 12:06:06 -07001281void rsdAllocationUpdateCachedObject(const Context *rsc,
1282 const Allocation *alloc,
1283 rs_allocation *obj)
1284{
1285 obj->p = alloc;
1286#ifdef __LP64__
Chris Wailes44bef6f2014-08-12 13:51:10 -07001287 if (alloc != nullptr) {
Jason Samsa36c50a2014-06-17 12:06:06 -07001288 obj->r = alloc->mHal.drvState.lod[0].mallocPtr;
1289 obj->v1 = alloc->mHal.drv;
1290 obj->v2 = (void *)alloc->mHal.drvState.lod[0].stride;
1291 } else {
Chris Wailes44bef6f2014-08-12 13:51:10 -07001292 obj->r = nullptr;
1293 obj->v1 = nullptr;
1294 obj->v2 = nullptr;
Jason Samsa36c50a2014-06-17 12:06:06 -07001295 }
1296#endif
1297}