blob: f358f93ccc4e5d49d0942c5ad68e8ce28e551753 [file] [log] [blame]
Jason Sams7e8aae72011-05-26 16:33:01 -07001/*
Jason Samsfe1d5ff2012-03-23 11:47:26 -07002 * Copyright (C) 2011-2012 The Android Open Source Project
Jason Sams7e8aae72011-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 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"
Jason Samsfe1d5ff2012-03-23 11:47:26 -070030#include "gui/SurfaceTexture.h"
Jason Sams163766c2012-02-15 12:04:24 -080031
Jason Sams7e8aae72011-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 Sams66db3ab2011-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
81
Jason Sams5316b9e2011-09-13 15:41:01 -070082static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
83 uint32_t xoff, uint32_t yoff, uint32_t lod,
84 RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
Jason Sams7e8aae72011-05-26 16:33:01 -070085 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
86
Jason Sams7e8aae72011-05-26 16:33:01 -070087 rsAssert(drv->textureID);
Jason Sams5316b9e2011-09-13 15:41:01 -070088 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
89 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Sams7e8aae72011-05-26 16:33:01 -070090 GLenum t = GL_TEXTURE_2D;
91 if (alloc->mHal.state.hasFaces) {
92 t = gFaceOrder[face];
93 }
Jason Sams5316b9e2011-09-13 15:41:01 -070094 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
Jason Sams7e8aae72011-05-26 16:33:01 -070095}
96
97
98static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
99 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
100
Jason Sams5316b9e2011-09-13 15:41:01 -0700101 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
102 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
Jason Sams7e8aae72011-05-26 16:33:01 -0700103
104 uint32_t faceCount = 1;
105 if (alloc->mHal.state.hasFaces) {
106 faceCount = 6;
107 }
108
109 rsdGLCheckError(rsc, "Upload2DTexture 1 ");
110 for (uint32_t face = 0; face < faceCount; face ++) {
111 for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
112 const uint8_t *p = (const uint8_t *)drv->mallocPtr;
113 p += alloc->mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
114
115 GLenum t = GL_TEXTURE_2D;
116 if (alloc->mHal.state.hasFaces) {
117 t = gFaceOrder[face];
118 }
119
120 if (isFirstUpload) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700121 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
Jason Sams7e8aae72011-05-26 16:33:01 -0700122 alloc->mHal.state.type->getLODDimX(lod),
123 alloc->mHal.state.type->getLODDimY(lod),
Jason Sams66db3ab2011-05-26 17:05:51 -0700124 0, drv->glFormat, drv->glType, p);
Jason Sams7e8aae72011-05-26 16:33:01 -0700125 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700126 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
Jason Sams7e8aae72011-05-26 16:33:01 -0700127 alloc->mHal.state.type->getLODDimX(lod),
128 alloc->mHal.state.type->getLODDimY(lod),
Jason Sams66db3ab2011-05-26 17:05:51 -0700129 drv->glFormat, drv->glType, p);
Jason Sams7e8aae72011-05-26 16:33:01 -0700130 }
131 }
132 }
133
134 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700135 RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
Jason Sams7e8aae72011-05-26 16:33:01 -0700136 }
137 rsdGLCheckError(rsc, "Upload2DTexture");
138}
139
140static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
141 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
142
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700143 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800144 if (!drv->textureID) {
145 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
146 }
147 return;
148 }
149
Jason Sams66db3ab2011-05-26 17:05:51 -0700150 if (!drv->glType || !drv->glFormat) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700151 return;
152 }
153
154 if (!alloc->getPtr()) {
155 return;
156 }
157
158 bool isFirstUpload = false;
159
160 if (!drv->textureID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700161 RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700162 isFirstUpload = true;
163 }
164
165 Upload2DTexture(rsc, alloc, isFirstUpload);
166
167 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
168 if (drv->mallocPtr) {
169 free(drv->mallocPtr);
170 drv->mallocPtr = NULL;
171 }
172 }
173 rsdGLCheckError(rsc, "UploadToTexture");
174}
175
176static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
177 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
178
Jason Sams66db3ab2011-05-26 17:05:51 -0700179 if (!drv->glFormat) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700180 return;
181 }
182
183 if (!drv->renderTargetID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700184 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700185
186 if (!drv->renderTargetID) {
187 // This should generally not happen
Steve Block3762c312012-01-06 19:20:56 +0000188 ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
Jason Sams7e8aae72011-05-26 16:33:01 -0700189 rsc->dumpDebug();
190 return;
191 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700192 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
193 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
Jason Sams7e8aae72011-05-26 16:33:01 -0700194 alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY);
195 }
196 rsdGLCheckError(rsc, "AllocateRenderTarget");
197}
198
199static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
200 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
201
202 rsAssert(!alloc->mHal.state.type->getDimY());
203 rsAssert(!alloc->mHal.state.type->getDimZ());
204
205 //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
206
207 if (!drv->bufferID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700208 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700209 }
210 if (!drv->bufferID) {
Steve Block3762c312012-01-06 19:20:56 +0000211 ALOGE("Upload to buffer object failed");
Jason Sams7e8aae72011-05-26 16:33:01 -0700212 drv->uploadDeferred = true;
213 return;
214 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700215 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
216 RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
Jason Sams7e8aae72011-05-26 16:33:01 -0700217 drv->mallocPtr, GL_DYNAMIC_DRAW);
Jason Sams5316b9e2011-09-13 15:41:01 -0700218 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
Jason Sams7e8aae72011-05-26 16:33:01 -0700219 rsdGLCheckError(rsc, "UploadToBufferObject");
220}
221
222bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
223 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
224 if (!drv) {
225 return false;
226 }
227
Jason Sams857d0c72011-11-23 15:02:15 -0800228 void * ptr = alloc->mHal.state.usrPtr;
Jason Sams163766c2012-02-15 12:04:24 -0800229 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
230 } else {
Jason Sams857d0c72011-11-23 15:02:15 -0800231 ptr = malloc(alloc->mHal.state.type->getSizeBytes());
232 if (!ptr) {
233 free(drv);
234 return false;
235 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700236 }
237
238 drv->glTarget = GL_NONE;
239 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
240 if (alloc->mHal.state.hasFaces) {
241 drv->glTarget = GL_TEXTURE_CUBE_MAP;
242 } else {
243 drv->glTarget = GL_TEXTURE_2D;
244 }
245 } else {
246 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
247 drv->glTarget = GL_ARRAY_BUFFER;
248 }
249 }
250
Jason Sams66db3ab2011-05-26 17:05:51 -0700251 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
252 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
253
254
Jason Sams7e8aae72011-05-26 16:33:01 -0700255 alloc->mHal.drvState.mallocPtr = ptr;
256 drv->mallocPtr = (uint8_t *)ptr;
257 alloc->mHal.drv = drv;
Jason Sams163766c2012-02-15 12:04:24 -0800258 if (forceZero && ptr) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700259 memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
260 }
261
262 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
263 drv->uploadDeferred = true;
264 }
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700265
266 drv->readBackFBO = NULL;
267
Jason Sams7e8aae72011-05-26 16:33:01 -0700268 return true;
269}
270
271void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
272 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
273
274 if (drv->bufferID) {
275 // Causes a SW crash....
Steve Block71f2cf12011-10-20 11:56:00 +0100276 //ALOGV(" mBufferID %i", mBufferID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700277 //glDeleteBuffers(1, &mBufferID);
278 //mBufferID = 0;
279 }
280 if (drv->textureID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700281 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700282 drv->textureID = 0;
283 }
284 if (drv->renderTargetID) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700285 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
Jason Sams7e8aae72011-05-26 16:33:01 -0700286 drv->renderTargetID = 0;
287 }
288
Jason Sams857d0c72011-11-23 15:02:15 -0800289 if (drv->mallocPtr && !alloc->mHal.state.usrPtr) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700290 free(drv->mallocPtr);
291 drv->mallocPtr = NULL;
292 }
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700293 if (drv->readBackFBO != NULL) {
294 delete drv->readBackFBO;
295 drv->readBackFBO = NULL;
296 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700297 free(drv);
298 alloc->mHal.drv = NULL;
299}
300
301void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
302 const Type *newType, bool zeroNew) {
303 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
304
305 drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes());
306
307 // fixme
308 ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr;
309
310 const uint32_t oldDimX = alloc->mHal.state.dimensionX;
311 const uint32_t dimX = newType->getDimX();
312
313 if (dimX > oldDimX) {
314 const Element *e = alloc->mHal.state.type->getElement();
315 uint32_t stride = e->getSizeBytes();
316 memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
317 }
318}
319
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700320static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
321 if (!alloc->getIsScript()) {
322 return; // nothing to sync
323 }
324
325 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
326 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
327
328 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
329 if (!drv->textureID && !drv->renderTargetID) {
330 return; // nothing was rendered here yet, so nothing to sync
331 }
332 if (drv->readBackFBO == NULL) {
333 drv->readBackFBO = new RsdFrameBufferObj();
334 drv->readBackFBO->setColorTarget(drv, 0);
335 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
336 alloc->getType()->getDimY());
337 }
338
339 // Bind the framebuffer object so we can read back from it
340 drv->readBackFBO->setActive(rsc);
341
342 // Do the readback
Jason Sams5316b9e2011-09-13 15:41:01 -0700343 RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700344 drv->glFormat, drv->glType, alloc->getPtr());
345
346 // Revert framebuffer to its original
347 lastFbo->setActive(rsc);
348}
Jason Sams7e8aae72011-05-26 16:33:01 -0700349
350
351void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
352 RsAllocationUsageType src) {
353 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
354
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700355 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
356 if(!alloc->getIsRenderTarget()) {
357 rsc->setError(RS_ERROR_FATAL_DRIVER,
358 "Attempting to sync allocation from render target, "
359 "for non-render target allocation");
360 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
361 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
362 "render target");
363 } else {
364 rsdAllocationSyncFromFBO(rsc, alloc);
365 }
Jason Sams7e8aae72011-05-26 16:33:01 -0700366 return;
367 }
368
369 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
370
371 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
372 UploadToTexture(rsc, alloc);
373 } else {
374 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
375 AllocateRenderTarget(rsc, alloc);
376 }
377 }
378 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
379 UploadToBufferObject(rsc, alloc);
380 }
381
382 drv->uploadDeferred = false;
383}
384
385void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
386 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
387 drv->uploadDeferred = true;
388}
389
Jason Sams615e7ce2012-01-13 14:01:20 -0800390int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
391 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
392 UploadToTexture(rsc, alloc);
393 return drv->textureID;
394}
395
Jason Sams163766c2012-02-15 12:04:24 -0800396static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
397 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
398
399 int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer);
400 if (r) {
401 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
402 return false;
403 }
404
405 // This lock is implicitly released by the queue buffer in IoSend
406 r = nw->lockBuffer(nw, drv->wndBuffer);
407 if (r) {
408 rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer.");
409 return false;
410 }
411
412 // Must lock the whole surface
413 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
414 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
415
416 void *dst = NULL;
417 mapper.lock(drv->wndBuffer->handle,
418 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
419 bounds, &dst);
420 alloc->mHal.drvState.mallocPtr = dst;
421 return true;
422}
423
424void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
425 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
426
427 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw);
428
429 // Cleanup old surface if there is one.
430 if (alloc->mHal.state.wndSurface) {
431 ANativeWindow *old = alloc->mHal.state.wndSurface;
432 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
433 mapper.unlock(drv->wndBuffer->handle);
434 old->queueBuffer(old, drv->wndBuffer);
435 }
436
437 if (nw != NULL) {
438 int32_t r;
439 r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY |
440 GRALLOC_USAGE_SW_WRITE_OFTEN);
441 if (r) {
442 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
443 return;
444 }
445
446 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX,
447 alloc->mHal.state.dimensionY);
448 if (r) {
449 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
450 return;
451 }
452
453 r = native_window_set_buffer_count(nw, 3);
454 if (r) {
455 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
456 return;
457 }
458
459 IoGetBuffer(rsc, alloc, nw);
460 }
461}
462
463void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
464 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
465 ANativeWindow *nw = alloc->mHal.state.wndSurface;
466
467 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
468 mapper.unlock(drv->wndBuffer->handle);
469 int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
470 if (r) {
471 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
472 return;
473 }
474
475 IoGetBuffer(rsc, alloc, nw);
476}
477
478void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700479 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
480 alloc->mHal.state.surfaceTexture->updateTexImage();
Jason Sams163766c2012-02-15 12:04:24 -0800481}
482
483
Jason Sams7e8aae72011-05-26 16:33:01 -0700484void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
485 uint32_t xoff, uint32_t lod, uint32_t count,
Alex Sakhartchouka3f15432012-02-13 11:57:32 -0800486 const void *data, size_t sizeBytes) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700487 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
488
489 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes();
490 uint8_t * ptr = drv->mallocPtr;
491 ptr += eSize * xoff;
492 uint32_t size = count * eSize;
493
494 if (alloc->mHal.state.hasReferences) {
495 alloc->incRefs(data, count);
496 alloc->decRefs(ptr, count);
497 }
498
499 memcpy(ptr, data, size);
500 drv->uploadDeferred = true;
501}
502
503void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
504 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Alex Sakhartchouka3f15432012-02-13 11:57:32 -0800505 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
Jason Sams7e8aae72011-05-26 16:33:01 -0700506 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
507
508 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
509 uint32_t lineSize = eSize * w;
510 uint32_t destW = alloc->mHal.state.dimensionX;
511
512 if (drv->mallocPtr) {
513 const uint8_t *src = static_cast<const uint8_t *>(data);
514 uint8_t *dst = drv->mallocPtr;
515 dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
516
517 for (uint32_t line=yoff; line < (yoff+h); line++) {
518 if (alloc->mHal.state.hasReferences) {
519 alloc->incRefs(src, w);
520 alloc->decRefs(dst, w);
521 }
522 memcpy(dst, src, lineSize);
523 src += lineSize;
524 dst += destW * eSize;
525 }
526 drv->uploadDeferred = true;
527 } else {
Jason Sams5316b9e2011-09-13 15:41:01 -0700528 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
Jason Sams7e8aae72011-05-26 16:33:01 -0700529 }
530}
531
532void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
533 uint32_t xoff, uint32_t yoff, uint32_t zoff,
534 uint32_t lod, RsAllocationCubemapFace face,
535 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
536
537}
538
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700539void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
540 const android::renderscript::Allocation *dstAlloc,
541 uint32_t dstXoff, uint32_t dstLod, uint32_t count,
542 const android::renderscript::Allocation *srcAlloc,
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700543 uint32_t srcXoff, uint32_t srcLod) {
544}
545
546uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc,
547 uint32_t xoff, uint32_t yoff, uint32_t lod,
548 RsAllocationCubemapFace face) {
549 uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr());
550 ptr += alloc->getType()->getLODOffset(lod, xoff, yoff);
551
552 if (face != 0) {
553 uint32_t totalSizeBytes = alloc->getType()->getSizeBytes();
554 uint32_t faceOffset = totalSizeBytes / 6;
555 ptr += faceOffset * (uint32_t)face;
556 }
557 return ptr;
558}
559
560
561void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
562 const android::renderscript::Allocation *dstAlloc,
563 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
564 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
565 const android::renderscript::Allocation *srcAlloc,
566 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
567 RsAllocationCubemapFace srcFace) {
568 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
569 for (uint32_t i = 0; i < h; i ++) {
570 uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
571 uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
572 memcpy(dstPtr, srcPtr, w * elementSize);
573
Steve Block3762c312012-01-06 19:20:56 +0000574 //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 -0700575 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700576 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700577}
578
579void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
580 const android::renderscript::Allocation *dstAlloc,
581 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
582 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
583 const android::renderscript::Allocation *srcAlloc,
584 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
585 RsAllocationCubemapFace srcFace) {
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700586 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
587 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
588 "yet implemented.");
589 return;
590 }
591 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
592 dstLod, dstFace, w, h, srcAlloc,
593 srcXoff, srcYoff, srcLod, srcFace);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700594}
595
596void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
597 const android::renderscript::Allocation *dstAlloc,
598 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
599 uint32_t dstLod, RsAllocationCubemapFace dstFace,
600 uint32_t w, uint32_t h, uint32_t d,
601 const android::renderscript::Allocation *srcAlloc,
602 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
603 uint32_t srcLod, RsAllocationCubemapFace srcFace) {
604}
605
Jason Sams7e8aae72011-05-26 16:33:01 -0700606void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
607 uint32_t x,
608 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
609 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
610
611 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
612 uint8_t * ptr = drv->mallocPtr;
613 ptr += eSize * x;
614
615 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
616 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
617
618 if (alloc->mHal.state.hasReferences) {
619 e->incRefs(data);
620 e->decRefs(ptr);
621 }
622
623 memcpy(ptr, data, sizeBytes);
624 drv->uploadDeferred = true;
625}
626
627void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
628 uint32_t x, uint32_t y,
629 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
630 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
631
632 uint32_t eSize = alloc->mHal.state.elementSizeBytes;
633 uint8_t * ptr = drv->mallocPtr;
634 ptr += eSize * (x + y * alloc->mHal.state.dimensionX);
635
636 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
637 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
638
639 if (alloc->mHal.state.hasReferences) {
640 e->incRefs(data);
641 e->decRefs(ptr);
642 }
643
644 memcpy(ptr, data, sizeBytes);
645 drv->uploadDeferred = true;
646}
647
648