rsdAllocation.cpp revision cd919a177f2b25af1b304dd4d79f0a768fed342f
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 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 51GLenum 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 82static 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 98static 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 140static 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 176static 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 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) { 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 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 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 274void 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 304void 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 322static 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 353void 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 388void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) { 389 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 390 drv->uploadDeferred = true; 391} 392 393int32_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 399static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 400 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 401 402 int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer); 403 if (r) { 404 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); 405 return false; 406 } 407 408 // Must lock the whole surface 409 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 410 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); 411 412 void *dst = NULL; 413 mapper.lock(drv->wndBuffer->handle, 414 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, 415 bounds, &dst); 416 alloc->mHal.drvState.mallocPtr = dst; 417 alloc->mHal.drvState.stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes; 418 419 return true; 420} 421 422void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 423 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 424 425 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); 426 427 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 428 //TODO finish support for render target + script 429 drv->wnd = nw; 430 return; 431 } 432 433 434 // Cleanup old surface if there is one. 435 if (alloc->mHal.state.wndSurface) { 436 ANativeWindow *old = alloc->mHal.state.wndSurface; 437 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 438 mapper.unlock(drv->wndBuffer->handle); 439 old->queueBuffer(old, drv->wndBuffer, -1); 440 } 441 442 if (nw != NULL) { 443 int32_t r; 444 uint32_t flags = 0; 445 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 446 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN; 447 } 448 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 449 flags |= GRALLOC_USAGE_HW_RENDER; 450 } 451 452 r = native_window_set_usage(nw, flags); 453 if (r) { 454 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); 455 return; 456 } 457 458 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, 459 alloc->mHal.state.dimensionY); 460 if (r) { 461 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); 462 return; 463 } 464 465 r = native_window_set_buffer_count(nw, 3); 466 if (r) { 467 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); 468 return; 469 } 470 471 IoGetBuffer(rsc, alloc, nw); 472 } 473} 474 475void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { 476 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 477 ANativeWindow *nw = alloc->mHal.state.wndSurface; 478 479 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 480 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 481 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface); 482 return; 483 } 484 485 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 486 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 487 mapper.unlock(drv->wndBuffer->handle); 488 int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1); 489 if (r) { 490 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer."); 491 return; 492 } 493 494 IoGetBuffer(rsc, alloc, nw); 495 } 496} 497 498void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { 499 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 500 alloc->mHal.state.surfaceTexture->updateTexImage(); 501} 502 503 504void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, 505 uint32_t xoff, uint32_t lod, uint32_t count, 506 const void *data, size_t sizeBytes) { 507 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 508 509 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); 510 uint8_t * ptr = (uint8_t *)alloc->mHal.drvState.mallocPtr; 511 ptr += eSize * xoff; 512 uint32_t size = count * eSize; 513 514 if (alloc->mHal.state.hasReferences) { 515 alloc->incRefs(data, count); 516 alloc->decRefs(ptr, count); 517 } 518 519 memcpy(ptr, data, size); 520 drv->uploadDeferred = true; 521} 522 523void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, 524 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 525 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { 526 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 527 528 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 529 uint32_t lineSize = eSize * w; 530 531 if (alloc->mHal.drvState.mallocPtr) { 532 const uint8_t *src = static_cast<const uint8_t *>(data); 533 uint8_t *dst = (uint8_t *)alloc->mHal.drvState.mallocPtr; 534 dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff); 535 536 for (uint32_t line=yoff; line < (yoff+h); line++) { 537 if (alloc->mHal.state.hasReferences) { 538 alloc->incRefs(src, w); 539 alloc->decRefs(dst, w); 540 } 541 memcpy(dst, src, lineSize); 542 src += lineSize; 543 dst += alloc->mHal.drvState.stride; 544 } 545 drv->uploadDeferred = true; 546 } else { 547 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h); 548 } 549} 550 551void rsdAllocationData3D(const Context *rsc, const Allocation *alloc, 552 uint32_t xoff, uint32_t yoff, uint32_t zoff, 553 uint32_t lod, RsAllocationCubemapFace face, 554 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) { 555 556} 557 558void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, 559 const android::renderscript::Allocation *dstAlloc, 560 uint32_t dstXoff, uint32_t dstLod, uint32_t count, 561 const android::renderscript::Allocation *srcAlloc, 562 uint32_t srcXoff, uint32_t srcLod) { 563} 564 565uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, 566 uint32_t xoff, uint32_t yoff, uint32_t lod, 567 RsAllocationCubemapFace face) { 568 uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); 569 ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); 570 571 if (face != 0) { 572 uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); 573 uint32_t faceOffset = totalSizeBytes / 6; 574 ptr += faceOffset * (uint32_t)face; 575 } 576 return ptr; 577} 578 579 580void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, 581 const android::renderscript::Allocation *dstAlloc, 582 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 583 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 584 const android::renderscript::Allocation *srcAlloc, 585 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 586 RsAllocationCubemapFace srcFace) { 587 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); 588 for (uint32_t i = 0; i < h; i ++) { 589 uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); 590 uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); 591 memcpy(dstPtr, srcPtr, w * elementSize); 592 593 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", 594 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); 595 } 596} 597 598void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, 599 const android::renderscript::Allocation *dstAlloc, 600 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 601 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 602 const android::renderscript::Allocation *srcAlloc, 603 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 604 RsAllocationCubemapFace srcFace) { 605 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { 606 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " 607 "yet implemented."); 608 return; 609 } 610 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, 611 dstLod, dstFace, w, h, srcAlloc, 612 srcXoff, srcYoff, srcLod, srcFace); 613} 614 615void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, 616 const android::renderscript::Allocation *dstAlloc, 617 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 618 uint32_t dstLod, RsAllocationCubemapFace dstFace, 619 uint32_t w, uint32_t h, uint32_t d, 620 const android::renderscript::Allocation *srcAlloc, 621 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 622 uint32_t srcLod, RsAllocationCubemapFace srcFace) { 623} 624 625void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc, 626 uint32_t x, 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 = (uint8_t *)alloc->mHal.drvState.mallocPtr; 632 ptr += eSize * x; 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 646void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc, 647 uint32_t x, uint32_t y, 648 const void *data, uint32_t cIdx, uint32_t sizeBytes) { 649 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 650 651 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 652 uint8_t * ptr = (uint8_t *)alloc->mHal.drvState.mallocPtr; 653 ptr += (eSize * x) + (y * alloc->mHal.drvState.stride); 654 655 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); 656 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); 657 658 if (alloc->mHal.state.hasReferences) { 659 e->incRefs(data); 660 e->decRefs(ptr); 661 } 662 663 memcpy(ptr, data, sizeBytes); 664 drv->uploadDeferred = true; 665} 666 667 668