1 /* 2 * Copyright (C) 2011-2012 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" 22 #include "rsdFrameBufferObj.h" 23 24 #include "rsAllocation.h" 25 26 #include "system/window.h" 27 #include "hardware/gralloc.h" 28 #include "ui/Rect.h" 29 #include "ui/GraphicBufferMapper.h" 30 #include "gui/SurfaceTexture.h" 31 32 #include <GLES/gl.h> 33 #include <GLES2/gl2.h> 34 #include <GLES/glext.h> 35 36 using namespace android; 37 using namespace android::renderscript; 38 39 40 41 const 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 51 GLenum 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 68 GLenum 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 82 static 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) { 85 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 86 87 rsAssert(drv->textureID); 88 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID); 89 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1); 90 GLenum t = GL_TEXTURE_2D; 91 if (alloc->mHal.state.hasFaces) { 92 t = gFaceOrder[face]; 93 } 94 RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr); 95 } 96 97 98 static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) { 99 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 100 101 RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID); 102 RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1); 103 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 *)alloc->mHal.drvState.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) { 121 RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat, 122 alloc->mHal.state.type->getLODDimX(lod), 123 alloc->mHal.state.type->getLODDimY(lod), 124 0, drv->glFormat, drv->glType, p); 125 } else { 126 RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0, 127 alloc->mHal.state.type->getLODDimX(lod), 128 alloc->mHal.state.type->getLODDimY(lod), 129 drv->glFormat, drv->glType, p); 130 } 131 } 132 } 133 134 if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) { 135 RSD_CALL_GL(glGenerateMipmap, drv->glTarget); 136 } 137 rsdGLCheckError(rsc, "Upload2DTexture"); 138 } 139 140 static void UploadToTexture(const Context *rsc, const Allocation *alloc) { 141 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 142 143 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) { 144 if (!drv->textureID) { 145 RSD_CALL_GL(glGenTextures, 1, &drv->textureID); 146 } 147 return; 148 } 149 150 if (!drv->glType || !drv->glFormat) { 151 return; 152 } 153 154 if (!alloc->getPtr()) { 155 return; 156 } 157 158 bool isFirstUpload = false; 159 160 if (!drv->textureID) { 161 RSD_CALL_GL(glGenTextures, 1, &drv->textureID); 162 isFirstUpload = true; 163 } 164 165 Upload2DTexture(rsc, alloc, isFirstUpload); 166 167 if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { 168 if (alloc->mHal.drvState.mallocPtr) { 169 free(alloc->mHal.drvState.mallocPtr); 170 alloc->mHal.drvState.mallocPtr = NULL; 171 } 172 } 173 rsdGLCheckError(rsc, "UploadToTexture"); 174 } 175 176 static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) { 177 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 178 179 if (!drv->glFormat) { 180 return; 181 } 182 183 if (!drv->renderTargetID) { 184 RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID); 185 186 if (!drv->renderTargetID) { 187 // This should generally not happen 188 ALOGE("allocateRenderTarget failed to gen mRenderTargetID"); 189 rsc->dumpDebug(); 190 return; 191 } 192 RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID); 193 RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat, 194 alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY); 195 } 196 rsdGLCheckError(rsc, "AllocateRenderTarget"); 197 } 198 199 static 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) { 208 RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID); 209 } 210 if (!drv->bufferID) { 211 ALOGE("Upload to buffer object failed"); 212 drv->uploadDeferred = true; 213 return; 214 } 215 RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID); 216 RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(), 217 alloc->mHal.drvState.mallocPtr, GL_DYNAMIC_DRAW); 218 RSD_CALL_GL(glBindBuffer, drv->glTarget, 0); 219 rsdGLCheckError(rsc, "UploadToBufferObject"); 220 } 221 222 bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { 223 DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation)); 224 if (!drv) { 225 return false; 226 } 227 228 void * ptr = NULL; 229 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) { 230 } else { 231 ptr = malloc(alloc->mHal.state.type->getSizeBytes()); 232 if (!ptr) { 233 free(drv); 234 return false; 235 } 236 } 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 251 drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType()); 252 drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind()); 253 254 255 alloc->mHal.drvState.mallocPtr = ptr; 256 alloc->mHal.drvState.stride = alloc->mHal.state.dimensionX * alloc->mHal.state.elementSizeBytes; 257 alloc->mHal.drv = drv; 258 if (forceZero && ptr) { 259 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 } 265 266 drv->width = alloc->getType()->getDimX(); 267 drv->height = alloc->getType()->getDimY(); 268 269 drv->readBackFBO = NULL; 270 271 return true; 272 } 273 274 void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { 275 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 276 277 if (drv->bufferID) { 278 // Causes a SW crash.... 279 //ALOGV(" mBufferID %i", mBufferID); 280 //glDeleteBuffers(1, &mBufferID); 281 //mBufferID = 0; 282 } 283 if (drv->textureID) { 284 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID); 285 drv->textureID = 0; 286 } 287 if (drv->renderTargetID) { 288 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID); 289 drv->renderTargetID = 0; 290 } 291 292 if (alloc->mHal.drvState.mallocPtr) { 293 free(alloc->mHal.drvState.mallocPtr); 294 alloc->mHal.drvState.mallocPtr = NULL; 295 } 296 if (drv->readBackFBO != NULL) { 297 delete drv->readBackFBO; 298 drv->readBackFBO = NULL; 299 } 300 free(drv); 301 alloc->mHal.drv = NULL; 302 } 303 304 void rsdAllocationResize(const Context *rsc, const Allocation *alloc, 305 const Type *newType, bool zeroNew) { 306 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 307 308 alloc->mHal.drvState.mallocPtr = (uint8_t *)realloc( 309 alloc->mHal.drvState.mallocPtr, newType->getSizeBytes()); 310 311 const uint32_t oldDimX = alloc->mHal.state.dimensionX; 312 const uint32_t dimX = newType->getDimX(); 313 314 if (dimX > oldDimX) { 315 const Element *e = alloc->mHal.state.type->getElement(); 316 uint32_t stride = e->getSizeBytes(); 317 memset(((uint8_t *)alloc->mHal.drvState.mallocPtr) + stride * oldDimX, 318 0, stride * (dimX - oldDimX)); 319 } 320 } 321 322 static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { 323 if (!alloc->getIsScript()) { 324 return; // nothing to sync 325 } 326 327 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 328 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; 329 330 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 331 if (!drv->textureID && !drv->renderTargetID) { 332 return; // nothing was rendered here yet, so nothing to sync 333 } 334 if (drv->readBackFBO == NULL) { 335 drv->readBackFBO = new RsdFrameBufferObj(); 336 drv->readBackFBO->setColorTarget(drv, 0); 337 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), 338 alloc->getType()->getDimY()); 339 } 340 341 // Bind the framebuffer object so we can read back from it 342 drv->readBackFBO->setActive(rsc); 343 344 // Do the readback 345 RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), 346 drv->glFormat, drv->glType, alloc->getPtr()); 347 348 // Revert framebuffer to its original 349 lastFbo->setActive(rsc); 350 } 351 352 353 void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, 354 RsAllocationUsageType src) { 355 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 356 357 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 358 if(!alloc->getIsRenderTarget()) { 359 rsc->setError(RS_ERROR_FATAL_DRIVER, 360 "Attempting to sync allocation from render target, " 361 "for non-render target allocation"); 362 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { 363 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" 364 "render target"); 365 } else { 366 rsdAllocationSyncFromFBO(rsc, alloc); 367 } 368 return; 369 } 370 371 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); 372 373 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) { 374 UploadToTexture(rsc, alloc); 375 } else { 376 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) && 377 !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) { 378 AllocateRenderTarget(rsc, alloc); 379 } 380 } 381 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) { 382 UploadToBufferObject(rsc, alloc); 383 } 384 385 drv->uploadDeferred = false; 386 } 387 388 void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) { 389 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 390 drv->uploadDeferred = true; 391 } 392 393 int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) { 394 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 395 UploadToTexture(rsc, alloc); 396 return drv->textureID; 397 } 398 399 static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 400 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 401 402 int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer); 403 if (r) { 404 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); 405 return false; 406 } 407 408 // This lock is implicitly released by the queue buffer in IoSend 409 r = nw->lockBuffer(nw, drv->wndBuffer); 410 if (r) { 411 rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer."); 412 return false; 413 } 414 415 // Must lock the whole surface 416 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 417 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); 418 419 void *dst = NULL; 420 mapper.lock(drv->wndBuffer->handle, 421 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, 422 bounds, &dst); 423 alloc->mHal.drvState.mallocPtr = dst; 424 alloc->mHal.drvState.stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes; 425 426 return true; 427 } 428 429 void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 430 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 431 432 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); 433 434 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 435 //TODO finish support for render target + script 436 drv->wnd = nw; 437 return; 438 } 439 440 441 // Cleanup old surface if there is one. 442 if (alloc->mHal.state.wndSurface) { 443 ANativeWindow *old = alloc->mHal.state.wndSurface; 444 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 445 mapper.unlock(drv->wndBuffer->handle); 446 old->queueBuffer(old, drv->wndBuffer); 447 } 448 449 if (nw != NULL) { 450 int32_t r; 451 uint32_t flags = 0; 452 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 453 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN; 454 } 455 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 456 flags |= GRALLOC_USAGE_HW_RENDER; 457 } 458 459 r = native_window_set_usage(nw, flags); 460 if (r) { 461 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); 462 return; 463 } 464 465 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, 466 alloc->mHal.state.dimensionY); 467 if (r) { 468 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); 469 return; 470 } 471 472 r = native_window_set_buffer_count(nw, 3); 473 if (r) { 474 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); 475 return; 476 } 477 478 IoGetBuffer(rsc, alloc, nw); 479 } 480 } 481 482 void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { 483 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 484 ANativeWindow *nw = alloc->mHal.state.wndSurface; 485 486 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 487 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 488 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface); 489 return; 490 } 491 492 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 493 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 494 mapper.unlock(drv->wndBuffer->handle); 495 int32_t r = nw->queueBuffer(nw, drv->wndBuffer); 496 if (r) { 497 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer."); 498 return; 499 } 500 501 IoGetBuffer(rsc, alloc, nw); 502 } 503 } 504 505 void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { 506 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 507 alloc->mHal.state.surfaceTexture->updateTexImage(); 508 } 509 510 511 void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, 512 uint32_t xoff, uint32_t lod, uint32_t count, 513 const void *data, size_t sizeBytes) { 514 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 515 516 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); 517 uint8_t * ptr = (uint8_t *)alloc->mHal.drvState.mallocPtr; 518 ptr += eSize * xoff; 519 uint32_t size = count * eSize; 520 521 if (alloc->mHal.state.hasReferences) { 522 alloc->incRefs(data, count); 523 alloc->decRefs(ptr, count); 524 } 525 526 memcpy(ptr, data, size); 527 drv->uploadDeferred = true; 528 } 529 530 void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, 531 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 532 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { 533 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 534 535 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 536 uint32_t lineSize = eSize * w; 537 538 if (alloc->mHal.drvState.mallocPtr) { 539 const uint8_t *src = static_cast<const uint8_t *>(data); 540 uint8_t *dst = (uint8_t *)alloc->mHal.drvState.mallocPtr; 541 dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff); 542 543 for (uint32_t line=yoff; line < (yoff+h); line++) { 544 if (alloc->mHal.state.hasReferences) { 545 alloc->incRefs(src, w); 546 alloc->decRefs(dst, w); 547 } 548 memcpy(dst, src, lineSize); 549 src += lineSize; 550 dst += alloc->mHal.drvState.stride; 551 } 552 drv->uploadDeferred = true; 553 } else { 554 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h); 555 } 556 } 557 558 void rsdAllocationData3D(const Context *rsc, const Allocation *alloc, 559 uint32_t xoff, uint32_t yoff, uint32_t zoff, 560 uint32_t lod, RsAllocationCubemapFace face, 561 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) { 562 563 } 564 565 void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, 566 const android::renderscript::Allocation *dstAlloc, 567 uint32_t dstXoff, uint32_t dstLod, uint32_t count, 568 const android::renderscript::Allocation *srcAlloc, 569 uint32_t srcXoff, uint32_t srcLod) { 570 } 571 572 uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, 573 uint32_t xoff, uint32_t yoff, uint32_t lod, 574 RsAllocationCubemapFace face) { 575 uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); 576 ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); 577 578 if (face != 0) { 579 uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); 580 uint32_t faceOffset = totalSizeBytes / 6; 581 ptr += faceOffset * (uint32_t)face; 582 } 583 return ptr; 584 } 585 586 587 void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, 588 const android::renderscript::Allocation *dstAlloc, 589 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 590 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 591 const android::renderscript::Allocation *srcAlloc, 592 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 593 RsAllocationCubemapFace srcFace) { 594 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); 595 for (uint32_t i = 0; i < h; i ++) { 596 uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); 597 uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); 598 memcpy(dstPtr, srcPtr, w * elementSize); 599 600 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", 601 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); 602 } 603 } 604 605 void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, 606 const android::renderscript::Allocation *dstAlloc, 607 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 608 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 609 const android::renderscript::Allocation *srcAlloc, 610 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 611 RsAllocationCubemapFace srcFace) { 612 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { 613 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " 614 "yet implemented."); 615 return; 616 } 617 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, 618 dstLod, dstFace, w, h, srcAlloc, 619 srcXoff, srcYoff, srcLod, srcFace); 620 } 621 622 void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, 623 const android::renderscript::Allocation *dstAlloc, 624 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 625 uint32_t dstLod, RsAllocationCubemapFace dstFace, 626 uint32_t w, uint32_t h, uint32_t d, 627 const android::renderscript::Allocation *srcAlloc, 628 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 629 uint32_t srcLod, RsAllocationCubemapFace srcFace) { 630 } 631 632 void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc, 633 uint32_t x, 634 const void *data, uint32_t cIdx, uint32_t sizeBytes) { 635 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 636 637 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 638 uint8_t * ptr = (uint8_t *)alloc->mHal.drvState.mallocPtr; 639 ptr += eSize * x; 640 641 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); 642 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); 643 644 if (alloc->mHal.state.hasReferences) { 645 e->incRefs(data); 646 e->decRefs(ptr); 647 } 648 649 memcpy(ptr, data, sizeBytes); 650 drv->uploadDeferred = true; 651 } 652 653 void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc, 654 uint32_t x, uint32_t y, 655 const void *data, uint32_t cIdx, uint32_t sizeBytes) { 656 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 657 658 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 659 uint8_t * ptr = (uint8_t *)alloc->mHal.drvState.mallocPtr; 660 ptr += (eSize * x) + (y * alloc->mHal.drvState.stride); 661 662 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); 663 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); 664 665 if (alloc->mHal.state.hasReferences) { 666 e->incRefs(data); 667 e->decRefs(ptr); 668 } 669 670 memcpy(ptr, data, sizeBytes); 671 drv->uploadDeferred = true; 672 } 673 674 675