rsdAllocation.cpp revision f22c8ace148b69847aaf5ad1829e9ec95a44df6c
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 *)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) { 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 (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 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 drv->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 = alloc->mHal.state.usrPtr; 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 drv->mallocPtr = (uint8_t *)ptr; 258 alloc->mHal.drv = drv; 259 if (forceZero && ptr) { 260 memset(ptr, 0, alloc->mHal.state.type->getSizeBytes()); 261 } 262 263 if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { 264 drv->uploadDeferred = true; 265 } 266 267 drv->width = alloc->getType()->getDimX(); 268 drv->height = alloc->getType()->getDimY(); 269 270 drv->readBackFBO = NULL; 271 272 return true; 273} 274 275void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { 276 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 277 278 if (drv->bufferID) { 279 // Causes a SW crash.... 280 //ALOGV(" mBufferID %i", mBufferID); 281 //glDeleteBuffers(1, &mBufferID); 282 //mBufferID = 0; 283 } 284 if (drv->textureID) { 285 RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID); 286 drv->textureID = 0; 287 } 288 if (drv->renderTargetID) { 289 RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID); 290 drv->renderTargetID = 0; 291 } 292 293 if (drv->mallocPtr && !alloc->mHal.state.usrPtr) { 294 free(drv->mallocPtr); 295 drv->mallocPtr = NULL; 296 } 297 if (drv->readBackFBO != NULL) { 298 delete drv->readBackFBO; 299 drv->readBackFBO = NULL; 300 } 301 free(drv); 302 alloc->mHal.drv = NULL; 303} 304 305void rsdAllocationResize(const Context *rsc, const Allocation *alloc, 306 const Type *newType, bool zeroNew) { 307 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 308 309 drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes()); 310 311 // fixme 312 ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr; 313 314 const uint32_t oldDimX = alloc->mHal.state.dimensionX; 315 const uint32_t dimX = newType->getDimX(); 316 317 if (dimX > oldDimX) { 318 const Element *e = alloc->mHal.state.type->getElement(); 319 uint32_t stride = e->getSizeBytes(); 320 memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX)); 321 } 322} 323 324static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { 325 if (!alloc->getIsScript()) { 326 return; // nothing to sync 327 } 328 329 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 330 RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; 331 332 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 333 if (!drv->textureID && !drv->renderTargetID) { 334 return; // nothing was rendered here yet, so nothing to sync 335 } 336 if (drv->readBackFBO == NULL) { 337 drv->readBackFBO = new RsdFrameBufferObj(); 338 drv->readBackFBO->setColorTarget(drv, 0); 339 drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), 340 alloc->getType()->getDimY()); 341 } 342 343 // Bind the framebuffer object so we can read back from it 344 drv->readBackFBO->setActive(rsc); 345 346 // Do the readback 347 RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), 348 drv->glFormat, drv->glType, alloc->getPtr()); 349 350 // Revert framebuffer to its original 351 lastFbo->setActive(rsc); 352} 353 354 355void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, 356 RsAllocationUsageType src) { 357 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 358 359 if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 360 if(!alloc->getIsRenderTarget()) { 361 rsc->setError(RS_ERROR_FATAL_DRIVER, 362 "Attempting to sync allocation from render target, " 363 "for non-render target allocation"); 364 } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { 365 rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" 366 "render target"); 367 } else { 368 rsdAllocationSyncFromFBO(rsc, alloc); 369 } 370 return; 371 } 372 373 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); 374 375 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) { 376 UploadToTexture(rsc, alloc); 377 } else { 378 if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) && 379 ~(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) { 380 AllocateRenderTarget(rsc, alloc); 381 } 382 } 383 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) { 384 UploadToBufferObject(rsc, alloc); 385 } 386 387 drv->uploadDeferred = false; 388} 389 390void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) { 391 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 392 drv->uploadDeferred = true; 393} 394 395int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) { 396 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 397 UploadToTexture(rsc, alloc); 398 return drv->textureID; 399} 400 401static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 402 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 403 404 int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer); 405 if (r) { 406 rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); 407 return false; 408 } 409 410 // This lock is implicitly released by the queue buffer in IoSend 411 r = nw->lockBuffer(nw, drv->wndBuffer); 412 if (r) { 413 rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer."); 414 return false; 415 } 416 417 // Must lock the whole surface 418 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 419 Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); 420 421 void *dst = NULL; 422 mapper.lock(drv->wndBuffer->handle, 423 GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, 424 bounds, &dst); 425 alloc->mHal.drvState.mallocPtr = dst; 426 alloc->mHal.drvState.stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes; 427 428 return true; 429} 430 431void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 432 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 433 434 //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); 435 436 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 437 //TODO finish support for render target + script 438 drv->wnd = nw; 439 return; 440 } 441 442 443 // Cleanup old surface if there is one. 444 if (alloc->mHal.state.wndSurface) { 445 ANativeWindow *old = alloc->mHal.state.wndSurface; 446 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 447 mapper.unlock(drv->wndBuffer->handle); 448 old->queueBuffer(old, drv->wndBuffer); 449 } 450 451 if (nw != NULL) { 452 int32_t r; 453 uint32_t flags = 0; 454 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 455 flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN; 456 } 457 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 458 flags |= GRALLOC_USAGE_HW_RENDER; 459 } 460 461 r = native_window_set_usage(nw, flags); 462 if (r) { 463 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); 464 return; 465 } 466 467 r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, 468 alloc->mHal.state.dimensionY); 469 if (r) { 470 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); 471 return; 472 } 473 474 r = native_window_set_buffer_count(nw, 3); 475 if (r) { 476 rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); 477 return; 478 } 479 480 IoGetBuffer(rsc, alloc, nw); 481 } 482} 483 484void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { 485 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 486 ANativeWindow *nw = alloc->mHal.state.wndSurface; 487 488 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { 489 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 490 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface); 491 return; 492 } 493 494 if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 495 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 496 mapper.unlock(drv->wndBuffer->handle); 497 int32_t r = nw->queueBuffer(nw, drv->wndBuffer); 498 if (r) { 499 rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer."); 500 return; 501 } 502 503 IoGetBuffer(rsc, alloc, nw); 504 } 505} 506 507void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { 508 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 509 alloc->mHal.state.surfaceTexture->updateTexImage(); 510} 511 512 513void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, 514 uint32_t xoff, uint32_t lod, uint32_t count, 515 const void *data, size_t sizeBytes) { 516 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 517 518 const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); 519 uint8_t * ptr = drv->mallocPtr; 520 ptr += eSize * xoff; 521 uint32_t size = count * eSize; 522 523 if (alloc->mHal.state.hasReferences) { 524 alloc->incRefs(data, count); 525 alloc->decRefs(ptr, count); 526 } 527 528 memcpy(ptr, data, size); 529 drv->uploadDeferred = true; 530} 531 532void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, 533 uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 534 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { 535 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 536 537 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 538 uint32_t lineSize = eSize * w; 539 540 if (drv->mallocPtr) { 541 const uint8_t *src = static_cast<const uint8_t *>(data); 542 uint8_t *dst = drv->mallocPtr; 543 dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff); 544 545 for (uint32_t line=yoff; line < (yoff+h); line++) { 546 if (alloc->mHal.state.hasReferences) { 547 alloc->incRefs(src, w); 548 alloc->decRefs(dst, w); 549 } 550 memcpy(dst, src, lineSize); 551 src += lineSize; 552 dst += alloc->mHal.drvState.stride; 553 } 554 drv->uploadDeferred = true; 555 } else { 556 Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h); 557 } 558} 559 560void rsdAllocationData3D(const Context *rsc, const Allocation *alloc, 561 uint32_t xoff, uint32_t yoff, uint32_t zoff, 562 uint32_t lod, RsAllocationCubemapFace face, 563 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) { 564 565} 566 567void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, 568 const android::renderscript::Allocation *dstAlloc, 569 uint32_t dstXoff, uint32_t dstLod, uint32_t count, 570 const android::renderscript::Allocation *srcAlloc, 571 uint32_t srcXoff, uint32_t srcLod) { 572} 573 574uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, 575 uint32_t xoff, uint32_t yoff, uint32_t lod, 576 RsAllocationCubemapFace face) { 577 uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); 578 ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); 579 580 if (face != 0) { 581 uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); 582 uint32_t faceOffset = totalSizeBytes / 6; 583 ptr += faceOffset * (uint32_t)face; 584 } 585 return ptr; 586} 587 588 589void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, 590 const android::renderscript::Allocation *dstAlloc, 591 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 592 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 593 const android::renderscript::Allocation *srcAlloc, 594 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 595 RsAllocationCubemapFace srcFace) { 596 uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); 597 for (uint32_t i = 0; i < h; i ++) { 598 uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); 599 uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); 600 memcpy(dstPtr, srcPtr, w * elementSize); 601 602 //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", 603 // dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); 604 } 605} 606 607void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, 608 const android::renderscript::Allocation *dstAlloc, 609 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, 610 RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, 611 const android::renderscript::Allocation *srcAlloc, 612 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, 613 RsAllocationCubemapFace srcFace) { 614 if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { 615 rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " 616 "yet implemented."); 617 return; 618 } 619 rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, 620 dstLod, dstFace, w, h, srcAlloc, 621 srcXoff, srcYoff, srcLod, srcFace); 622} 623 624void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, 625 const android::renderscript::Allocation *dstAlloc, 626 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 627 uint32_t dstLod, RsAllocationCubemapFace dstFace, 628 uint32_t w, uint32_t h, uint32_t d, 629 const android::renderscript::Allocation *srcAlloc, 630 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 631 uint32_t srcLod, RsAllocationCubemapFace srcFace) { 632} 633 634void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc, 635 uint32_t x, 636 const void *data, uint32_t cIdx, uint32_t sizeBytes) { 637 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 638 639 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 640 uint8_t * ptr = drv->mallocPtr; 641 ptr += eSize * x; 642 643 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); 644 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); 645 646 if (alloc->mHal.state.hasReferences) { 647 e->incRefs(data); 648 e->decRefs(ptr); 649 } 650 651 memcpy(ptr, data, sizeBytes); 652 drv->uploadDeferred = true; 653} 654 655void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc, 656 uint32_t x, uint32_t y, 657 const void *data, uint32_t cIdx, uint32_t sizeBytes) { 658 DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 659 660 uint32_t eSize = alloc->mHal.state.elementSizeBytes; 661 uint8_t * ptr = drv->mallocPtr; 662 ptr += (eSize * x) + (y * alloc->mHal.drvState.stride); 663 664 const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); 665 ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); 666 667 if (alloc->mHal.state.hasReferences) { 668 e->incRefs(data); 669 e->decRefs(ptr); 670 } 671 672 memcpy(ptr, data, sizeBytes); 673 drv->uploadDeferred = true; 674} 675 676 677