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