blob: fb93d822e8a65cee59e61ef9c404081514baa1dd [file] [log] [blame]
Jason Sams7e8aae72011-05-26 16:33:01 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
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 Sakhartchouk8650c322011-06-16 11:05:13 -070022#include "rsdFrameBufferObj.h"
Jason Sams7e8aae72011-05-26 16:33:01 -070023
24#include "rsAllocation.h"
25
Jason Sams163766c2012-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"
30
Jason Sams7e8aae72011-05-26 16:33:01 -070031#include <GLES/gl.h>
32#include <GLES2/gl2.h>
33#include <GLES/glext.h>
34
35using namespace android;
36using namespace android::renderscript;
37
38
39
40const static GLenum gFaceOrder[] = {
41 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
42 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
43 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
44 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
45 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
46 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
47};
48
49
Jason Sams66db3ab2011-05-26 17:05:51 -070050GLenum rsdTypeToGLType(RsDataType t) {
51 switch (t) {
52 case RS_TYPE_UNSIGNED_5_6_5: return GL_UNSIGNED_SHORT_5_6_5;
53 case RS_TYPE_UNSIGNED_5_5_5_1: return GL_UNSIGNED_SHORT_5_5_5_1;
54 case RS_TYPE_UNSIGNED_4_4_4_4: return GL_UNSIGNED_SHORT_4_4_4_4;
55
56 //case RS_TYPE_FLOAT_16: return GL_HALF_FLOAT;
57 case RS_TYPE_FLOAT_32: return GL_FLOAT;
58 case RS_TYPE_UNSIGNED_8: return GL_UNSIGNED_BYTE;
59 case RS_TYPE_UNSIGNED_16: return GL_UNSIGNED_SHORT;
60 case RS_TYPE_SIGNED_8: return GL_BYTE;
61 case RS_TYPE_SIGNED_16: return GL_SHORT;
62 default: break;
63 }
64 return 0;
65}
66
67GLenum rsdKindToGLFormat(RsDataKind k) {
68 switch (k) {
69 case RS_KIND_PIXEL_L: return GL_LUMINANCE;
70 case RS_KIND_PIXEL_A: return GL_ALPHA;
71 case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
72 case RS_KIND_PIXEL_RGB: return GL_RGB;
73 case RS_KIND_PIXEL_RGBA: return GL_RGBA;
74 case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
75 default: break;
76 }
77 return 0;
78}
79
80
Jason Sams5316b9e2011-09-13 15:41:01 -070081static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
82 uint32_t xoff, uint32_t yoff, uint32_t lod,
83 RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
Jason Sams7e8aae72011-05-26 16:33:01 -070084 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
85
Jason Sams7e8aae72011-05-26 16:33:01 -070086 rsAssert(drv->textureID);
Jason Sams5316b9e2011-09-13 15:41:01 -070087 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
88 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Sams7e8aae72011-05-26 16:33:01 -070089 GLenum t = GL_TEXTURE_2D;
90 if (alloc->mHal.state.hasFaces) {
91 t = gFaceOrder[face];
92 }
Jason Sams5316b9e2011-09-13 15:41:01 -070093 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
Jason Sams7e8aae72011-05-26 16:33:01 -070094}
95
96
97static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
98 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
99
Jason Sams5316b9e2011-09-13 15:41:01 -0700100 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
101 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Sams7e8aae72011-05-26 16:33:01 -0700102
103 uint32_t faceCount = 1;
104 if (alloc->mHal.state.hasFaces) {
105 faceCount = 6;
106 }
107
108 rsdGLCheckError(rsc, "Upload2DTexture 1 ");
109 for (uint32_t face = 0; face < faceCount; face ++) {
110 for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
111 const uint8_t *p = (const uint8_t *)drv->mallocPtr;
112 p += alloc->mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
113
114 GLenum t = GL_TEXTURE_2D;
115 if (alloc->mHal.state.hasFaces) {
116 t = gFaceOrder[face];
117 }
118
119 if (isFirstUpload) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700120 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
Jason Sams7e8aae72011-05-26 16:33:01 -0700121 alloc->mHal.state.type->getLODDimX(lod),
122 alloc->mHal.state.type->getLODDimY(lod),
Jason Sams66db3ab2011-05-26 17:05:51 -0700123 0, drv->glFormat, drv->glType, p);
Jason Sams7e8aae72011-05-26 16:33:01 -0700124 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700125 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
Jason Sams7e8aae72011-05-26 16:33:01 -0700126 alloc->mHal.state.type->getLODDimX(lod),
127 alloc->mHal.state.type->getLODDimY(lod),
Jason Sams66db3ab2011-05-26 17:05:51 -0700128 drv->glFormat, drv->glType, p);
Jason Sams7e8aae72011-05-26 16:33:01 -0700129 }
130 }
131 }
132
133 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700134 RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
Jason Sams7e8aae72011-05-26 16:33:01 -0700135 }
136 rsdGLCheckError(rsc, "Upload2DTexture");
137}
138
139static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
140 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
141
Jason Sams615e7ce2012-01-13 14:01:20 -0800142 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
143 if (!drv->textureID) {
144 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
145 }
146 return;
147 }
148
Jason Sams66db3ab2011-05-26 17:05:51 -0700149 if (!drv->glType || !drv->glFormat) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700150 return;
151 }
152
153 if (!alloc->getPtr()) {
154 return;
155 }
156
157 bool isFirstUpload = false;
158
159 if (!drv->textureID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700160 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700161 isFirstUpload = true;
162 }
163
164 Upload2DTexture(rsc, alloc, isFirstUpload);
165
166 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
167 if (drv->mallocPtr) {
168 free(drv->mallocPtr);
169 drv->mallocPtr = NULL;
170 }
171 }
172 rsdGLCheckError(rsc, "UploadToTexture");
173}
174
175static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
176 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
177
Jason Sams66db3ab2011-05-26 17:05:51 -0700178 if (!drv->glFormat) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700179 return;
180 }
181
182 if (!drv->renderTargetID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700183 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700184
185 if (!drv->renderTargetID) {
186 // This should generally not happen
Steve Block3762c312012-01-06 19:20:56 +0000187 ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
Jason Sams7e8aae72011-05-26 16:33:01 -0700188 rsc->dumpDebug();
189 return;
190 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700191 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
192 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
Jason Sams7e8aae72011-05-26 16:33:01 -0700193 alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
194 }
195 rsdGLCheckError(rsc, "AllocateRenderTarget");
196}
197
198static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
199 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
200
201 rsAssert(!alloc->mHal.state.type->getDimY());
202 rsAssert(!alloc->mHal.state.type->getDimZ());
203
204 //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
205
206 if (!drv->bufferID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700207 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700208 }
209 if (!drv->bufferID) {
Steve Block3762c312012-01-06 19:20:56 +0000210 ALOGE("Upload to buffer object failed");
Jason Sams7e8aae72011-05-26 16:33:01 -0700211 drv->uploadDeferred = true;
212 return;
213 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700214 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
215 RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
Jason Sams7e8aae72011-05-26 16:33:01 -0700216 drv->mallocPtr, GL_DYNAMIC_DRAW);
Jason Sams5316b9e2011-09-13 15:41:01 -0700217 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
Jason Sams7e8aae72011-05-26 16:33:01 -0700218 rsdGLCheckError(rsc, "UploadToBufferObject");
219}
220
221bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
222 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
223 if (!drv) {
224 return false;
225 }
226
Jason Sams857d0c72011-11-23 15:02:15 -0800227 void * ptr = alloc->mHal.state.usrPtr;
Jason Sams163766c2012-02-15 12:04:24 -0800228 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
229 } else {
Jason Sams857d0c72011-11-23 15:02:15 -0800230 ptr = malloc(alloc->mHal.state.type->getSizeBytes());
231 if (!ptr) {
232 free(drv);
233 return false;
234 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700235 }
236
237 drv->glTarget = GL_NONE;
238 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
239 if (alloc->mHal.state.hasFaces) {
240 drv->glTarget = GL_TEXTURE_CUBE_MAP;
241 } else {
242 drv->glTarget = GL_TEXTURE_2D;
243 }
244 } else {
245 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
246 drv->glTarget = GL_ARRAY_BUFFER;
247 }
248 }
249
Jason Sams66db3ab2011-05-26 17:05:51 -0700250 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
251 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
252
253
Jason Sams7e8aae72011-05-26 16:33:01 -0700254 alloc->mHal.drvState.mallocPtr = ptr;
255 drv->mallocPtr = (uint8_t *)ptr;
256 alloc->mHal.drv = drv;
Jason Sams163766c2012-02-15 12:04:24 -0800257 if (forceZero && ptr) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700258 memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
259 }
260
261 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
262 drv->uploadDeferred = true;
263 }
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700264
265 drv->readBackFBO = NULL;
266
Jason Sams7e8aae72011-05-26 16:33:01 -0700267 return true;
268}
269
270void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
271 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
272
273 if (drv->bufferID) {
274 // Causes a SW crash....
Steve Block71f2cf12011-10-20 11:56:00 +0100275 //ALOGV(" mBufferID %i", mBufferID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700276 //glDeleteBuffers(1, &mBufferID);
277 //mBufferID = 0;
278 }
279 if (drv->textureID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700280 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700281 drv->textureID = 0;
282 }
283 if (drv->renderTargetID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700284 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700285 drv->renderTargetID = 0;
286 }
287
Jason Sams857d0c72011-11-23 15:02:15 -0800288 if (drv->mallocPtr && !alloc->mHal.state.usrPtr) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700289 free(drv->mallocPtr);
290 drv->mallocPtr = NULL;
291 }
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700292 if (drv->readBackFBO != NULL) {
293 delete drv->readBackFBO;
294 drv->readBackFBO = NULL;
295 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700296 free(drv);
297 alloc->mHal.drv = NULL;
298}
299
300void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
301 const Type *newType, bool zeroNew) {
302 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
303
304 drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes());
305
306 // fixme
307 ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr;
308
309 const uint32_t oldDimX = alloc->mHal.state.dimensionX;
310 const uint32_t dimX = newType->getDimX();
311
312 if (dimX > oldDimX) {
313 const Element *e = alloc->mHal.state.type->getElement();
314 uint32_t stride = e->getSizeBytes();
315 memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
316 }
317}
318
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700319static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
320 if (!alloc->getIsScript()) {
321 return; // nothing to sync
322 }
323
324 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
325 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
326
327 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
328 if (!drv->textureID && !drv->renderTargetID) {
329 return; // nothing was rendered here yet, so nothing to sync
330 }
331 if (drv->readBackFBO == NULL) {
332 drv->readBackFBO = new RsdFrameBufferObj();
333 drv->readBackFBO->setColorTarget(drv, 0);
334 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
335 alloc->getType()->getDimY());
336 }
337
338 // Bind the framebuffer object so we can read back from it
339 drv->readBackFBO->setActive(rsc);
340
341 // Do the readback
Jason Sams5316b9e2011-09-13 15:41:01 -0700342 RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700343 drv->glFormat, drv->glType, alloc->getPtr());
344
345 // Revert framebuffer to its original
346 lastFbo->setActive(rsc);
347}
Jason Sams7e8aae72011-05-26 16:33:01 -0700348
349
350void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
351 RsAllocationUsageType src) {
352 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
353
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700354 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
355 if(!alloc->getIsRenderTarget()) {
356 rsc->setError(RS_ERROR_FATAL_DRIVER,
357 "Attempting to sync allocation from render target, "
358 "for non-render target allocation");
359 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
360 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
361 "render target");
362 } else {
363 rsdAllocationSyncFromFBO(rsc, alloc);
364 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700365 return;
366 }
367
368 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
369
370 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
371 UploadToTexture(rsc, alloc);
372 } else {
373 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
374 AllocateRenderTarget(rsc, alloc);
375 }
376 }
377 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
378 UploadToBufferObject(rsc, alloc);
379 }
380
381 drv->uploadDeferred = false;
382}
383
384void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
385 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
386 drv->uploadDeferred = true;
387}
388
Jason Sams615e7ce2012-01-13 14:01:20 -0800389int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
390 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
391 UploadToTexture(rsc, alloc);
392 return drv->textureID;
393}
394
Jason Sams163766c2012-02-15 12:04:24 -0800395static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
396 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
397
398 int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer);
399 if (r) {
400 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
401 return false;
402 }
403
404 // This lock is implicitly released by the queue buffer in IoSend
405 r = nw->lockBuffer(nw, drv->wndBuffer);
406 if (r) {
407 rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer.");
408 return false;
409 }
410
411 // Must lock the whole surface
412 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
413 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
414
415 void *dst = NULL;
416 mapper.lock(drv->wndBuffer->handle,
417 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
418 bounds, &dst);
419 alloc->mHal.drvState.mallocPtr = dst;
420 return true;
421}
422
423void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
424 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
425
426 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw);
427
428 // Cleanup old surface if there is one.
429 if (alloc->mHal.state.wndSurface) {
430 ANativeWindow *old = alloc->mHal.state.wndSurface;
431 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
432 mapper.unlock(drv->wndBuffer->handle);
433 old->queueBuffer(old, drv->wndBuffer);
434 }
435
436 if (nw != NULL) {
437 int32_t r;
438 r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY |
439 GRALLOC_USAGE_SW_WRITE_OFTEN);
440 if (r) {
441 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
442 return;
443 }
444
445 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX,
446 alloc->mHal.state.dimensionY);
447 if (r) {
448 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
449 return;
450 }
451
452 r = native_window_set_buffer_count(nw, 3);
453 if (r) {
454 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
455 return;
456 }
457
458 IoGetBuffer(rsc, alloc, nw);
459 }
460}
461
462void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
463 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
464 ANativeWindow *nw = alloc->mHal.state.wndSurface;
465
466 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
467 mapper.unlock(drv->wndBuffer->handle);
468 int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
469 if (r) {
470 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
471 return;
472 }
473
474 IoGetBuffer(rsc, alloc, nw);
475}
476
477void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
478 ALOGE("not implemented");
479}
480
481
Jason Sams7e8aae72011-05-26 16:33:01 -0700482void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
483 uint32_t xoff, uint32_t lod, uint32_t count,
Alex Sakhartchouka3f15432012-02-13 11:57:32 -0800484 const void *data, size_t sizeBytes) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700485 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
486
487 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
488 uint8_t * ptr = drv->mallocPtr;
489 ptr += eSize * xoff;
490 uint32_t size = count * eSize;
491
492 if (alloc->mHal.state.hasReferences) {
493 alloc->incRefs(data, count);
494 alloc->decRefs(ptr, count);
495 }
496
497 memcpy(ptr, data, size);
498 drv->uploadDeferred = true;
499}
500
501void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
502 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Alex Sakhartchouka3f15432012-02-13 11:57:32 -0800503 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700504 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
505
506 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
507 uint32_t lineSize = eSize * w;
508 uint32_t destW = alloc->mHal.state.dimensionX;
509
510 if (drv->mallocPtr) {
511 const uint8_t *src = static_cast<const uint8_t *>(data);
512 uint8_t *dst = drv->mallocPtr;
513 dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
514
515 for (uint32_t line=yoff; line < (yoff+h); line++) {
516 if (alloc->mHal.state.hasReferences) {
517 alloc->incRefs(src, w);
518 alloc->decRefs(dst, w);
519 }
520 memcpy(dst, src, lineSize);
521 src += lineSize;
522 dst += destW * eSize;
523 }
524 drv->uploadDeferred = true;
525 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700526 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
Jason Sams7e8aae72011-05-26 16:33:01 -0700527 }
528}
529
530void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
531 uint32_t xoff, uint32_t yoff, uint32_t zoff,
532 uint32_t lod, RsAllocationCubemapFace face,
533 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
534
535}
536
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700537void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
538 const android::renderscript::Allocation *dstAlloc,
539 uint32_t dstXoff, uint32_t dstLod, uint32_t count,
540 const android::renderscript::Allocation *srcAlloc,
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700541 uint32_t srcXoff, uint32_t srcLod) {
542}
543
544uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc,
545 uint32_t xoff, uint32_t yoff, uint32_t lod,
546 RsAllocationCubemapFace face) {
547 uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr());
548 ptr += alloc->getType()->getLODOffset(lod, xoff, yoff);
549
550 if (face != 0) {
551 uint32_t totalSizeBytes = alloc->getType()->getSizeBytes();
552 uint32_t faceOffset = totalSizeBytes / 6;
553 ptr += faceOffset * (uint32_t)face;
554 }
555 return ptr;
556}
557
558
559void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
560 const android::renderscript::Allocation *dstAlloc,
561 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
562 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
563 const android::renderscript::Allocation *srcAlloc,
564 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
565 RsAllocationCubemapFace srcFace) {
566 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
567 for (uint32_t i = 0; i < h; i ++) {
568 uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
569 uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
570 memcpy(dstPtr, srcPtr, w * elementSize);
571
Steve Block3762c312012-01-06 19:20:56 +0000572 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
Stephen Hines3d782662011-06-23 16:18:28 -0700573 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700574 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700575}
576
577void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
578 const android::renderscript::Allocation *dstAlloc,
579 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
580 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
581 const android::renderscript::Allocation *srcAlloc,
582 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
583 RsAllocationCubemapFace srcFace) {
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700584 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
585 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
586 "yet implemented.");
587 return;
588 }
589 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
590 dstLod, dstFace, w, h, srcAlloc,
591 srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700592}
593
594void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
595 const android::renderscript::Allocation *dstAlloc,
596 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
597 uint32_t dstLod, RsAllocationCubemapFace dstFace,
598 uint32_t w, uint32_t h, uint32_t d,
599 const android::renderscript::Allocation *srcAlloc,
600 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
601 uint32_t srcLod, RsAllocationCubemapFace srcFace) {
602}
603
Jason Sams7e8aae72011-05-26 16:33:01 -0700604void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
605 uint32_t x,
606 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
607 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
608
609 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
610 uint8_t * ptr = drv->mallocPtr;
611 ptr += eSize * x;
612
613 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
614 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
615
616 if (alloc->mHal.state.hasReferences) {
617 e->incRefs(data);
618 e->decRefs(ptr);
619 }
620
621 memcpy(ptr, data, sizeBytes);
622 drv->uploadDeferred = true;
623}
624
625void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
626 uint32_t x, uint32_t y,
627 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
628 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
629
630 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
631 uint8_t * ptr = drv->mallocPtr;
632 ptr += eSize * (x + y * alloc->mHal.state.dimensionX);
633
634 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
635 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
636
637 if (alloc->mHal.state.hasReferences) {
638 e->incRefs(data);
639 e->decRefs(ptr);
640 }
641
642 memcpy(ptr, data, sizeBytes);
643 drv->uploadDeferred = true;
644}
645
646