blob: 7f2de1d2cd861b1fe2b8c7188bac3cb4489710d6 [file] [log] [blame]
Jason Samseb4fe182011-05-26 16:33:01 -07001/*
Jason Sams3522f402012-03-23 11:47:26 -07002 * Copyright (C) 2011-2012 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
17
18#include "rsdCore.h"
19#include "rsdBcc.h"
20#include "rsdRuntime.h"
21#include "rsdAllocation.h"
Alex Sakhartchouka9495242011-06-16 11:05:13 -070022#include "rsdFrameBufferObj.h"
Jason Samseb4fe182011-05-26 16:33:01 -070023
24#include "rsAllocation.h"
25
Jason Sams7ac2a4d2012-02-15 12:04:24 -080026#include "system/window.h"
27#include "hardware/gralloc.h"
28#include "ui/Rect.h"
29#include "ui/GraphicBufferMapper.h"
Jason Sams3522f402012-03-23 11:47:26 -070030#include "gui/SurfaceTexture.h"
Jason Sams7ac2a4d2012-02-15 12:04:24 -080031
Jason Samseb4fe182011-05-26 16:33:01 -070032#include <GLES/gl.h>
33#include <GLES2/gl2.h>
34#include <GLES/glext.h>
35
36using namespace android;
37using namespace android::renderscript;
38
39
40
41const static GLenum gFaceOrder[] = {
42 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
43 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
44 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
45 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
46 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
47 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
48};
49
50
Jason Samsa614ae12011-05-26 17:05:51 -070051GLenum rsdTypeToGLType(RsDataType t) {
52 switch (t) {
53 case RS_TYPE_UNSIGNED_5_6_5: return GL_UNSIGNED_SHORT_5_6_5;
54 case RS_TYPE_UNSIGNED_5_5_5_1: return GL_UNSIGNED_SHORT_5_5_5_1;
55 case RS_TYPE_UNSIGNED_4_4_4_4: return GL_UNSIGNED_SHORT_4_4_4_4;
56
57 //case RS_TYPE_FLOAT_16: return GL_HALF_FLOAT;
58 case RS_TYPE_FLOAT_32: return GL_FLOAT;
59 case RS_TYPE_UNSIGNED_8: return GL_UNSIGNED_BYTE;
60 case RS_TYPE_UNSIGNED_16: return GL_UNSIGNED_SHORT;
61 case RS_TYPE_SIGNED_8: return GL_BYTE;
62 case RS_TYPE_SIGNED_16: return GL_SHORT;
63 default: break;
64 }
65 return 0;
66}
67
68GLenum rsdKindToGLFormat(RsDataKind k) {
69 switch (k) {
70 case RS_KIND_PIXEL_L: return GL_LUMINANCE;
71 case RS_KIND_PIXEL_A: return GL_ALPHA;
72 case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
73 case RS_KIND_PIXEL_RGB: return GL_RGB;
74 case RS_KIND_PIXEL_RGBA: return GL_RGBA;
75 case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
76 default: break;
77 }
78 return 0;
79}
80
Jason Sams807fdc42012-07-25 17:55:39 -070081uint8_t *GetOffsetPtr(const android::renderscript::Allocation *alloc,
82 uint32_t xoff, uint32_t yoff, uint32_t lod,
83 RsAllocationCubemapFace face) {
84 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
85 uint8_t *ptr = (uint8_t *)drv->lod[lod].mallocPtr;
86 ptr += face * drv->faceOffset;
87 ptr += yoff * drv->lod[lod].stride;
88 ptr += xoff * alloc->mHal.state.elementSizeBytes;
89 return ptr;
90}
91
Jason Samsa614ae12011-05-26 17:05:51 -070092
Jason Sams2382aba2011-09-13 15:41:01 -070093static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
94 uint32_t xoff, uint32_t yoff, uint32_t lod,
95 RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
Jason Samseb4fe182011-05-26 16:33:01 -070096 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
97
Jason Samseb4fe182011-05-26 16:33:01 -070098 rsAssert(drv->textureID);
Jason Sams2382aba2011-09-13 15:41:01 -070099 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
100 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700101 GLenum t = GL_TEXTURE_2D;
102 if (alloc->mHal.state.hasFaces) {
103 t = gFaceOrder[face];
104 }
Jason Sams2382aba2011-09-13 15:41:01 -0700105 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
Jason Samseb4fe182011-05-26 16:33:01 -0700106}
107
108
109static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
110 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
111
Jason Sams2382aba2011-09-13 15:41:01 -0700112 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
113 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Samseb4fe182011-05-26 16:33:01 -0700114
115 uint32_t faceCount = 1;
116 if (alloc->mHal.state.hasFaces) {
117 faceCount = 6;
118 }
119
120 rsdGLCheckError(rsc, "Upload2DTexture 1 ");
121 for (uint32_t face = 0; face < faceCount; face ++) {
122 for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
Jason Sams807fdc42012-07-25 17:55:39 -0700123 const uint8_t *p = GetOffsetPtr(alloc, 0, 0, lod, (RsAllocationCubemapFace)face);
Jason Samseb4fe182011-05-26 16:33:01 -0700124
125 GLenum t = GL_TEXTURE_2D;
126 if (alloc->mHal.state.hasFaces) {
127 t = gFaceOrder[face];
128 }
129
130 if (isFirstUpload) {
Jason Sams2382aba2011-09-13 15:41:01 -0700131 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
Jason Samseb4fe182011-05-26 16:33:01 -0700132 alloc->mHal.state.type->getLODDimX(lod),
133 alloc->mHal.state.type->getLODDimY(lod),
Jason Samsa614ae12011-05-26 17:05:51 -0700134 0, drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700135 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700136 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
Jason Samseb4fe182011-05-26 16:33:01 -0700137 alloc->mHal.state.type->getLODDimX(lod),
138 alloc->mHal.state.type->getLODDimY(lod),
Jason Samsa614ae12011-05-26 17:05:51 -0700139 drv->glFormat, drv->glType, p);
Jason Samseb4fe182011-05-26 16:33:01 -0700140 }
141 }
142 }
143
144 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700145 RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
Jason Samseb4fe182011-05-26 16:33:01 -0700146 }
147 rsdGLCheckError(rsc, "Upload2DTexture");
148}
149
150static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
151 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
152
Jason Sams3522f402012-03-23 11:47:26 -0700153 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
Jason Sams41e373d2012-01-13 14:01:20 -0800154 if (!drv->textureID) {
155 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
156 }
157 return;
158 }
159
Jason Samsa614ae12011-05-26 17:05:51 -0700160 if (!drv->glType || !drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700161 return;
162 }
163
164 if (!alloc->getPtr()) {
165 return;
166 }
167
168 bool isFirstUpload = false;
169
170 if (!drv->textureID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700171 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
Jason Samseb4fe182011-05-26 16:33:01 -0700172 isFirstUpload = true;
173 }
174
175 Upload2DTexture(rsc, alloc, isFirstUpload);
176
177 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Jason Sams807fdc42012-07-25 17:55:39 -0700178 if (alloc->mHal.drvState.mallocPtrLOD0) {
179 free(alloc->mHal.drvState.mallocPtrLOD0);
180 alloc->mHal.drvState.mallocPtrLOD0 = NULL;
181 drv->lod[0].mallocPtr = NULL;
Jason Samseb4fe182011-05-26 16:33:01 -0700182 }
183 }
184 rsdGLCheckError(rsc, "UploadToTexture");
185}
186
187static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
188 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
189
Jason Samsa614ae12011-05-26 17:05:51 -0700190 if (!drv->glFormat) {
Jason Samseb4fe182011-05-26 16:33:01 -0700191 return;
192 }
193
194 if (!drv->renderTargetID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700195 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
Jason Samseb4fe182011-05-26 16:33:01 -0700196
197 if (!drv->renderTargetID) {
198 // This should generally not happen
Steve Blockaf12ac62012-01-06 19:20:56 +0000199 ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
Jason Samseb4fe182011-05-26 16:33:01 -0700200 rsc->dumpDebug();
201 return;
202 }
Jason Sams2382aba2011-09-13 15:41:01 -0700203 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
204 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
Jason Samseb4fe182011-05-26 16:33:01 -0700205 alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
206 }
207 rsdGLCheckError(rsc, "AllocateRenderTarget");
208}
209
210static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
211 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
212
213 rsAssert(!alloc->mHal.state.type->getDimY());
214 rsAssert(!alloc->mHal.state.type->getDimZ());
215
216 //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
217
218 if (!drv->bufferID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700219 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
Jason Samseb4fe182011-05-26 16:33:01 -0700220 }
221 if (!drv->bufferID) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000222 ALOGE("Upload to buffer object failed");
Jason Samseb4fe182011-05-26 16:33:01 -0700223 drv->uploadDeferred = true;
224 return;
225 }
Jason Sams2382aba2011-09-13 15:41:01 -0700226 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
227 RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
Jason Sams807fdc42012-07-25 17:55:39 -0700228 alloc->mHal.drvState.mallocPtrLOD0, GL_DYNAMIC_DRAW);
Jason Sams2382aba2011-09-13 15:41:01 -0700229 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
Jason Samseb4fe182011-05-26 16:33:01 -0700230 rsdGLCheckError(rsc, "UploadToBufferObject");
231}
232
233bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
234 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
235 if (!drv) {
236 return false;
237 }
238
Jason Sams807fdc42012-07-25 17:55:39 -0700239 drv->lod[0].dimX = alloc->getType()->getDimX();
240 drv->lod[0].dimY = alloc->getType()->getDimY();
241 drv->lod[0].mallocPtr = 0;
242 drv->lod[0].stride = alloc->mHal.state.dimensionX * alloc->mHal.state.elementSizeBytes;
243 drv->lodCount = alloc->getType()->getLODCount();
244 drv->faceCount = alloc->getType()->getDimFaces();
245
246 size_t offsets[Allocation::MAX_LOD];
247 memset(offsets, 0, sizeof(offsets));
248
249 size_t o = drv->lod[0].stride * rsMax(drv->lod[0].dimY, 1u) * rsMax(drv->lod[0].dimZ, 1u);
250 if(drv->lodCount > 1) {
251 uint32_t tx = drv->lod[0].dimX;
252 uint32_t ty = drv->lod[0].dimY;
253 uint32_t tz = drv->lod[0].dimZ;
254 for (uint32_t lod=1; lod < drv->lodCount; lod++) {
255 drv->lod[lod].dimX = tx;
256 drv->lod[lod].dimY = ty;
257 drv->lod[lod].dimZ = tz;
258 drv->lod[lod].stride = tx * alloc->mHal.state.elementSizeBytes;
259 offsets[lod] = o;
260 o += drv->lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
261 if (tx > 1) tx >>= 1;
262 if (ty > 1) ty >>= 1;
263 if (tz > 1) tz >>= 1;
264 }
265 }
266 drv->faceOffset = o;
267
268 uint8_t * ptr = NULL;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800269 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
270 } else {
Jason Sams807fdc42012-07-25 17:55:39 -0700271 size_t allocSize = drv->faceOffset;
272 if(drv->faceCount) {
273 allocSize *= 6;
274 }
275
276 ptr = (uint8_t *)malloc(allocSize);
Jason Sams179e9a42011-11-23 15:02:15 -0800277 if (!ptr) {
278 free(drv);
279 return false;
280 }
Jason Samseb4fe182011-05-26 16:33:01 -0700281 }
Jason Sams807fdc42012-07-25 17:55:39 -0700282 drv->lod[0].mallocPtr = ptr;
283 for (uint32_t lod=1; lod < drv->lodCount; lod++) {
284 drv->lod[lod].mallocPtr = ptr + offsets[lod];
285 }
Jason Samseb4fe182011-05-26 16:33:01 -0700286
287 drv->glTarget = GL_NONE;
288 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
289 if (alloc->mHal.state.hasFaces) {
290 drv->glTarget = GL_TEXTURE_CUBE_MAP;
291 } else {
292 drv->glTarget = GL_TEXTURE_2D;
293 }
294 } else {
295 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
296 drv->glTarget = GL_ARRAY_BUFFER;
297 }
298 }
299
Jason Samsa614ae12011-05-26 17:05:51 -0700300 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
301 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
302
Jason Sams807fdc42012-07-25 17:55:39 -0700303 alloc->mHal.drvState.strideLOD0 = drv->lod[0].stride;
304 alloc->mHal.drvState.mallocPtrLOD0 = ptr;
Jason Samseb4fe182011-05-26 16:33:01 -0700305 alloc->mHal.drv = drv;
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800306 if (forceZero && ptr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700307 memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
308 }
309
310 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
311 drv->uploadDeferred = true;
312 }
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700313
Jason Samsb3220332012-04-02 14:41:54 -0700314
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700315 drv->readBackFBO = NULL;
316
Jason Samseb4fe182011-05-26 16:33:01 -0700317 return true;
318}
319
320void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
321 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
322
323 if (drv->bufferID) {
324 // Causes a SW crash....
Steve Block65982012011-10-20 11:56:00 +0100325 //ALOGV(" mBufferID %i", mBufferID);
Jason Samseb4fe182011-05-26 16:33:01 -0700326 //glDeleteBuffers(1, &mBufferID);
327 //mBufferID = 0;
328 }
329 if (drv->textureID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700330 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
Jason Samseb4fe182011-05-26 16:33:01 -0700331 drv->textureID = 0;
332 }
333 if (drv->renderTargetID) {
Jason Sams2382aba2011-09-13 15:41:01 -0700334 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
Jason Samseb4fe182011-05-26 16:33:01 -0700335 drv->renderTargetID = 0;
336 }
337
Jason Sams807fdc42012-07-25 17:55:39 -0700338 if (alloc->mHal.drvState.mallocPtrLOD0) {
339 free(alloc->mHal.drvState.mallocPtrLOD0);
340 alloc->mHal.drvState.mallocPtrLOD0 = NULL;
Jason Samseb4fe182011-05-26 16:33:01 -0700341 }
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700342 if (drv->readBackFBO != NULL) {
343 delete drv->readBackFBO;
344 drv->readBackFBO = NULL;
345 }
Jason Samseb4fe182011-05-26 16:33:01 -0700346 free(drv);
347 alloc->mHal.drv = NULL;
348}
349
350void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
351 const Type *newType, bool zeroNew) {
352 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
353
Jason Sams807fdc42012-07-25 17:55:39 -0700354 alloc->mHal.drvState.mallocPtrLOD0 = (uint8_t *)realloc(
355 alloc->mHal.drvState.mallocPtrLOD0, newType->getSizeBytes());
Jason Samseb4fe182011-05-26 16:33:01 -0700356
357 const uint32_t oldDimX = alloc->mHal.state.dimensionX;
358 const uint32_t dimX = newType->getDimX();
359
360 if (dimX > oldDimX) {
361 const Element *e = alloc->mHal.state.type->getElement();
362 uint32_t stride = e->getSizeBytes();
Jason Sams807fdc42012-07-25 17:55:39 -0700363 memset(((uint8_t *)alloc->mHal.drvState.mallocPtrLOD0) + stride * oldDimX,
Jason Sams2275e9c2012-04-16 17:01:26 -0700364 0, stride * (dimX - oldDimX));
Jason Samseb4fe182011-05-26 16:33:01 -0700365 }
366}
367
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700368static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
369 if (!alloc->getIsScript()) {
370 return; // nothing to sync
371 }
372
373 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
374 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
375
376 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
377 if (!drv->textureID && !drv->renderTargetID) {
378 return; // nothing was rendered here yet, so nothing to sync
379 }
380 if (drv->readBackFBO == NULL) {
381 drv->readBackFBO = new RsdFrameBufferObj();
382 drv->readBackFBO->setColorTarget(drv, 0);
383 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
384 alloc->getType()->getDimY());
385 }
386
387 // Bind the framebuffer object so we can read back from it
388 drv->readBackFBO->setActive(rsc);
389
390 // Do the readback
Jason Sams2382aba2011-09-13 15:41:01 -0700391 RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700392 drv->glFormat, drv->glType, alloc->getPtr());
393
394 // Revert framebuffer to its original
395 lastFbo->setActive(rsc);
396}
Jason Samseb4fe182011-05-26 16:33:01 -0700397
398
399void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
400 RsAllocationUsageType src) {
401 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
402
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700403 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
404 if(!alloc->getIsRenderTarget()) {
405 rsc->setError(RS_ERROR_FATAL_DRIVER,
406 "Attempting to sync allocation from render target, "
407 "for non-render target allocation");
408 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
409 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
410 "render target");
411 } else {
412 rsdAllocationSyncFromFBO(rsc, alloc);
413 }
Jason Samseb4fe182011-05-26 16:33:01 -0700414 return;
415 }
416
417 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
418
419 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
420 UploadToTexture(rsc, alloc);
421 } else {
Jason Samsb3220332012-04-02 14:41:54 -0700422 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
Jason Sams0dc66932012-04-10 17:05:49 -0700423 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
Jason Samseb4fe182011-05-26 16:33:01 -0700424 AllocateRenderTarget(rsc, alloc);
425 }
426 }
427 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
428 UploadToBufferObject(rsc, alloc);
429 }
430
431 drv->uploadDeferred = false;
432}
433
434void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
435 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
436 drv->uploadDeferred = true;
437}
438
Jason Sams41e373d2012-01-13 14:01:20 -0800439int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
440 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
441 UploadToTexture(rsc, alloc);
442 return drv->textureID;
443}
444
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800445static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
446 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
447
Jamie Genniscd919a12012-06-13 16:34:11 -0700448 int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800449 if (r) {
450 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
451 return false;
452 }
453
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800454 // Must lock the whole surface
455 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
456 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
457
458 void *dst = NULL;
459 mapper.lock(drv->wndBuffer->handle,
460 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
461 bounds, &dst);
Jason Sams807fdc42012-07-25 17:55:39 -0700462 drv->lod[0].mallocPtr = dst;
463 alloc->mHal.drvState.mallocPtrLOD0 = dst;
464 drv->lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
Jason Samsb3220332012-04-02 14:41:54 -0700465
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800466 return true;
467}
468
469void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
470 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
471
472 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw);
473
Jason Samsb3220332012-04-02 14:41:54 -0700474 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
475 //TODO finish support for render target + script
476 drv->wnd = nw;
477 return;
478 }
479
480
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800481 // Cleanup old surface if there is one.
482 if (alloc->mHal.state.wndSurface) {
483 ANativeWindow *old = alloc->mHal.state.wndSurface;
484 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
485 mapper.unlock(drv->wndBuffer->handle);
Jamie Genniscd919a12012-06-13 16:34:11 -0700486 old->queueBuffer(old, drv->wndBuffer, -1);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800487 }
488
489 if (nw != NULL) {
490 int32_t r;
Jason Samsb3220332012-04-02 14:41:54 -0700491 uint32_t flags = 0;
492 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
493 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
494 }
495 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
496 flags |= GRALLOC_USAGE_HW_RENDER;
497 }
498
499 r = native_window_set_usage(nw, flags);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800500 if (r) {
501 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
502 return;
503 }
504
505 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX,
506 alloc->mHal.state.dimensionY);
507 if (r) {
508 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
509 return;
510 }
511
512 r = native_window_set_buffer_count(nw, 3);
513 if (r) {
514 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
515 return;
516 }
517
518 IoGetBuffer(rsc, alloc, nw);
519 }
520}
521
522void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
523 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
524 ANativeWindow *nw = alloc->mHal.state.wndSurface;
525
Jason Samsb3220332012-04-02 14:41:54 -0700526 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
527 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
528 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800529 return;
530 }
531
Jason Samsb3220332012-04-02 14:41:54 -0700532 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
533 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
534 mapper.unlock(drv->wndBuffer->handle);
Jamie Genniscd919a12012-06-13 16:34:11 -0700535 int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
Jason Samsb3220332012-04-02 14:41:54 -0700536 if (r) {
537 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
538 return;
539 }
540
541 IoGetBuffer(rsc, alloc, nw);
542 }
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800543}
544
545void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
Jason Sams3522f402012-03-23 11:47:26 -0700546 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
547 alloc->mHal.state.surfaceTexture->updateTexImage();
Jason Sams7ac2a4d2012-02-15 12:04:24 -0800548}
549
550
Jason Samseb4fe182011-05-26 16:33:01 -0700551void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
552 uint32_t xoff, uint32_t lod, uint32_t count,
Alex Sakhartchoukc794cd52012-02-13 11:57:32 -0800553 const void *data, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -0700554 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
555
556 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
Jason Sams807fdc42012-07-25 17:55:39 -0700557 uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -0700558 uint32_t size = count * eSize;
559
560 if (alloc->mHal.state.hasReferences) {
561 alloc->incRefs(data, count);
562 alloc->decRefs(ptr, count);
563 }
564
565 memcpy(ptr, data, size);
566 drv->uploadDeferred = true;
567}
568
569void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
570 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Alex Sakhartchoukc794cd52012-02-13 11:57:32 -0800571 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
Jason Samseb4fe182011-05-26 16:33:01 -0700572 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
573
574 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
575 uint32_t lineSize = eSize * w;
Jason Samseb4fe182011-05-26 16:33:01 -0700576
Jason Sams807fdc42012-07-25 17:55:39 -0700577 if (drv->lod[0].mallocPtr) {
Jason Samseb4fe182011-05-26 16:33:01 -0700578 const uint8_t *src = static_cast<const uint8_t *>(data);
Jason Sams807fdc42012-07-25 17:55:39 -0700579 uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, lod, face);
Jason Samseb4fe182011-05-26 16:33:01 -0700580
581 for (uint32_t line=yoff; line < (yoff+h); line++) {
582 if (alloc->mHal.state.hasReferences) {
583 alloc->incRefs(src, w);
584 alloc->decRefs(dst, w);
585 }
586 memcpy(dst, src, lineSize);
587 src += lineSize;
Jason Sams807fdc42012-07-25 17:55:39 -0700588 dst += drv->lod[lod].stride;
Jason Samseb4fe182011-05-26 16:33:01 -0700589 }
590 drv->uploadDeferred = true;
591 } else {
Jason Sams2382aba2011-09-13 15:41:01 -0700592 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
Jason Samseb4fe182011-05-26 16:33:01 -0700593 }
594}
595
596void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
597 uint32_t xoff, uint32_t yoff, uint32_t zoff,
598 uint32_t lod, RsAllocationCubemapFace face,
599 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
600
601}
602
Jason Sams807fdc42012-07-25 17:55:39 -0700603void rsdAllocationRead1D(const Context *rsc, const Allocation *alloc,
604 uint32_t xoff, uint32_t lod, uint32_t count,
605 void *data, size_t sizeBytes) {
606 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
607
608 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
609 const uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
610 memcpy(data, ptr, count * eSize);
611}
612
613void rsdAllocationRead2D(const Context *rsc, const Allocation *alloc,
614 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
615 uint32_t w, uint32_t h, void *data, size_t sizeBytes) {
616 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
617
618 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
619 uint32_t lineSize = eSize * w;
620
621 if (drv->lod[0].mallocPtr) {
622 uint8_t *dst = static_cast<uint8_t *>(data);
623 const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, lod, face);
624
625 for (uint32_t line=yoff; line < (yoff+h); line++) {
626 memcpy(dst, src, lineSize);
627 dst += lineSize;
628 src += drv->lod[lod].stride;
629 }
630 } else {
631 ALOGE("Add code to readback from non-script memory");
632 }
633}
634
635void rsdAllocationRead3D(const Context *rsc, const Allocation *alloc,
636 uint32_t xoff, uint32_t yoff, uint32_t zoff,
637 uint32_t lod, RsAllocationCubemapFace face,
638 uint32_t w, uint32_t h, uint32_t d, void *data, uint32_t sizeBytes) {
639
640}
641
642void * rsdAllocationLock1D(const android::renderscript::Context *rsc,
643 const android::renderscript::Allocation *alloc) {
644 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
645 return drv->lod[0].mallocPtr;
646}
647
648void rsdAllocationUnlock1D(const android::renderscript::Context *rsc,
649 const android::renderscript::Allocation *alloc) {
650
651}
652
Alex Sakhartchouk74a82792011-06-14 11:13:19 -0700653void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
654 const android::renderscript::Allocation *dstAlloc,
655 uint32_t dstXoff, uint32_t dstLod, uint32_t count,
656 const android::renderscript::Allocation *srcAlloc,
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700657 uint32_t srcXoff, uint32_t srcLod) {
658}
659
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700660
661void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
662 const android::renderscript::Allocation *dstAlloc,
663 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
664 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
665 const android::renderscript::Allocation *srcAlloc,
666 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
667 RsAllocationCubemapFace srcFace) {
668 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
669 for (uint32_t i = 0; i < h; i ++) {
Jason Sams807fdc42012-07-25 17:55:39 -0700670 uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
671 uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700672 memcpy(dstPtr, srcPtr, w * elementSize);
673
Steve Blockaf12ac62012-01-06 19:20:56 +0000674 //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 -0700675 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700676 }
Alex Sakhartchouk74a82792011-06-14 11:13:19 -0700677}
678
679void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
680 const android::renderscript::Allocation *dstAlloc,
681 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
682 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
683 const android::renderscript::Allocation *srcAlloc,
684 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
685 RsAllocationCubemapFace srcFace) {
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700686 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
687 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
688 "yet implemented.");
689 return;
690 }
691 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
692 dstLod, dstFace, w, h, srcAlloc,
693 srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk74a82792011-06-14 11:13:19 -0700694}
695
696void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
697 const android::renderscript::Allocation *dstAlloc,
698 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
699 uint32_t dstLod, RsAllocationCubemapFace dstFace,
700 uint32_t w, uint32_t h, uint32_t d,
701 const android::renderscript::Allocation *srcAlloc,
702 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
703 uint32_t srcLod, RsAllocationCubemapFace srcFace) {
704}
705
Jason Samseb4fe182011-05-26 16:33:01 -0700706void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
707 uint32_t x,
708 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
709 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
710
711 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
Jason Sams807fdc42012-07-25 17:55:39 -0700712 uint8_t * ptr = GetOffsetPtr(alloc, x, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -0700713
714 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
715 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
716
717 if (alloc->mHal.state.hasReferences) {
718 e->incRefs(data);
719 e->decRefs(ptr);
720 }
721
722 memcpy(ptr, data, sizeBytes);
723 drv->uploadDeferred = true;
724}
725
726void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
727 uint32_t x, uint32_t y,
728 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
729 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
730
731 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
Jason Sams807fdc42012-07-25 17:55:39 -0700732 uint8_t * ptr = GetOffsetPtr(alloc, x, y, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
Jason Samseb4fe182011-05-26 16:33:01 -0700733
734 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
735 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
736
737 if (alloc->mHal.state.hasReferences) {
738 e->incRefs(data);
739 e->decRefs(ptr);
740 }
741
742 memcpy(ptr, data, sizeBytes);
743 drv->uploadDeferred = true;
744}
745
746