rsAllocation.cpp revision 442b7ff3ca1dffd1555d34e0afc1bdbb6387e8e2
1/* 2 * Copyright (C) 2013 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#include "rsContext.h" 18#include "rsAllocation.h" 19#include "rsAdapter.h" 20#include "rs_hal.h" 21 22#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 23#include "system/window.h" 24#include "gui/GLConsumer.h" 25#endif 26 27using namespace android; 28using namespace android::renderscript; 29 30Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages, 31 RsAllocationMipmapControl mc, void * ptr) 32 : ObjectBase(rsc) { 33 34 memset(&mHal, 0, sizeof(mHal)); 35 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; 36 mHal.state.usageFlags = usages; 37 mHal.state.mipmapControl = mc; 38 mHal.state.userProvidedPtr = ptr; 39 40 setType(type); 41 updateCache(); 42} 43 44Allocation::Allocation(Context *rsc, const Allocation *alloc, const Type *type) 45 : ObjectBase(rsc) { 46 47 memset(&mHal, 0, sizeof(mHal)); 48 49 50 mHal.state.baseAlloc = alloc; 51 mHal.state.type = type; 52 mHal.state.usageFlags = alloc->mHal.state.usageFlags; 53 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; 54 55 setType(type); 56 updateCache(); 57 58 59 60 61 struct Hal { 62 void * drv; 63 64 struct DrvState { 65 struct LodState { 66 void * mallocPtr; 67 size_t stride; 68 uint32_t dimX; 69 uint32_t dimY; 70 uint32_t dimZ; 71 } lod[android::renderscript::Allocation::MAX_LOD]; 72 size_t faceOffset; 73 uint32_t lodCount; 74 uint32_t faceCount; 75 76 struct YuvState { 77 uint32_t shift; 78 uint32_t step; 79 } yuv; 80 81 int grallocFlags; 82 uint32_t dimArray[Type::mMaxArrays]; 83 }; 84 mutable DrvState drvState; 85 86 }; 87 Hal mHal; 88 89} 90 91void Allocation::operator delete(void* ptr) { 92 if (ptr) { 93 Allocation *a = (Allocation*) ptr; 94 a->getContext()->mHal.funcs.freeRuntimeMem(ptr); 95 } 96} 97 98Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages, 99 RsAllocationMipmapControl mc, void * ptr) { 100 // Allocation objects must use allocator specified by the driver 101 void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0); 102 103 if (!allocMem) { 104 rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation"); 105 return nullptr; 106 } 107 108 Allocation *a = new (allocMem) Allocation(rsc, type, usages, mc, ptr); 109 110 if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) { 111 rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); 112 delete a; 113 return nullptr; 114 } 115 116 return a; 117} 118 119Allocation * Allocation::createAdapter(Context *rsc, const Allocation *alloc, const Type *type) { 120 // Allocation objects must use allocator specified by the driver 121 void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0); 122 123 if (!allocMem) { 124 rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation"); 125 return nullptr; 126 } 127 128 Allocation *a = new (allocMem) Allocation(rsc, alloc, type); 129 130 if (!rsc->mHal.funcs.allocation.initAdapter(rsc, a)) { 131 rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); 132 delete a; 133 return nullptr; 134 } 135 136 return a; 137} 138 139void Allocation::adapterOffset(Context *rsc, const uint32_t *offsets, size_t len) { 140 if (len >= sizeof(uint32_t) * 9) { 141 mHal.state.originX = offsets[0]; 142 mHal.state.originY = offsets[1]; 143 mHal.state.originZ = offsets[2]; 144 mHal.state.originLOD = offsets[3]; 145 mHal.state.originFace = offsets[4]; 146 mHal.state.originArray[0] = offsets[5]; 147 mHal.state.originArray[1] = offsets[6]; 148 mHal.state.originArray[2] = offsets[7]; 149 mHal.state.originArray[3] = offsets[8]; 150 } 151 152 rsc->mHal.funcs.allocation.adapterOffset(rsc, this); 153} 154 155 156 157void Allocation::updateCache() { 158 const Type *type = mHal.state.type; 159 mHal.state.yuv = type->getDimYuv(); 160 mHal.state.hasFaces = type->getDimFaces(); 161 mHal.state.hasMipmaps = type->getDimLOD(); 162 mHal.state.elementSizeBytes = type->getElementSizeBytes(); 163 mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences(); 164} 165 166Allocation::~Allocation() { 167#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 168 if (mGrallocConsumer.get()) { 169 mGrallocConsumer->unlockBuffer(); 170 mGrallocConsumer = nullptr; 171 } 172#endif 173 174 freeChildrenUnlocked(); 175 mRSC->mHal.funcs.allocation.destroy(mRSC, this); 176} 177 178void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { 179 rsc->mHal.funcs.allocation.syncAll(rsc, this, src); 180} 181 182void * Allocation::getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face, 183 uint32_t z, uint32_t array, size_t *stride) { 184 185 if ((lod >= mHal.drvState.lodCount) || 186 (z && (z >= mHal.drvState.lod[lod].dimZ)) || 187 ((face != RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) && !mHal.state.hasFaces) || 188 (array != 0)) { 189 return nullptr; 190 } 191 192 size_t s = 0; 193 //void *ptr = mRSC->mHal.funcs.allocation.lock1D(rsc, this); 194 if ((stride != nullptr) && mHal.drvState.lod[0].dimY) { 195 *stride = mHal.drvState.lod[lod].stride; 196 } 197 return mHal.drvState.lod[lod].mallocPtr; 198} 199 200void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod, 201 uint32_t count, const void *data, size_t sizeBytes) { 202 const size_t eSize = mHal.state.type->getElementSizeBytes(); 203 204 if ((count * eSize) != sizeBytes) { 205 char buf[1024]; 206 sprintf(buf, "Allocation::subData called with mismatched size expected %zu, got %zu", 207 (count * eSize), sizeBytes); 208 rsc->setError(RS_ERROR_BAD_VALUE, buf); 209 mHal.state.type->dumpLOGV("type info"); 210 return; 211 } 212 213 rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes); 214 sendDirty(rsc); 215} 216 217void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 218 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 219 rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 220 sendDirty(rsc); 221} 222 223void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 224 uint32_t lod, 225 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 226 rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 227 sendDirty(rsc); 228} 229 230void Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod, 231 uint32_t count, void *data, size_t sizeBytes) { 232 const size_t eSize = mHal.state.type->getElementSizeBytes(); 233 234 if ((count * eSize) != sizeBytes) { 235 char buf[1024]; 236 sprintf(buf, "Allocation::read called with mismatched size expected %zu, got %zu", 237 (count * eSize), sizeBytes); 238 rsc->setError(RS_ERROR_BAD_VALUE, buf); 239 mHal.state.type->dumpLOGV("type info"); 240 return; 241 } 242 243 rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes); 244} 245 246void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 247 uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) { 248 const size_t eSize = mHal.state.elementSizeBytes; 249 const size_t lineSize = eSize * w; 250 if (!stride) { 251 stride = lineSize; 252 } else { 253 if ((lineSize * h) != sizeBytes) { 254 char buf[1024]; 255 sprintf(buf, "Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes); 256 rsc->setError(RS_ERROR_BAD_VALUE, buf); 257 return; 258 } 259 } 260 261 rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 262} 263 264void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 265 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) { 266 const size_t eSize = mHal.state.elementSizeBytes; 267 const size_t lineSize = eSize * w; 268 if (!stride) { 269 stride = lineSize; 270 } 271 272 rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 273 274} 275 276void Allocation::elementData(Context *rsc, uint32_t x, const void *data, 277 uint32_t cIdx, size_t sizeBytes) { 278 size_t eSize = mHal.state.elementSizeBytes; 279 280 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 281 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 282 return; 283 } 284 285 if (x >= mHal.drvState.lod[0].dimX) { 286 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 287 return; 288 } 289 290 const Element * e = mHal.state.type->getElement()->getField(cIdx); 291 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 292 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 293 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 294 return; 295 } 296 297 rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes); 298 sendDirty(rsc); 299} 300 301void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, 302 const void *data, uint32_t cIdx, size_t sizeBytes) { 303 size_t eSize = mHal.state.elementSizeBytes; 304 305 if (x >= mHal.drvState.lod[0].dimX) { 306 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 307 return; 308 } 309 310 if (y >= mHal.drvState.lod[0].dimY) { 311 rsc->setError(RS_ERROR_BAD_VALUE, 312 "subElementData X offset out of range."); 313 return; 314 } 315 316 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 317 rsc->setError(RS_ERROR_BAD_VALUE, 318 "subElementData component out of range."); 319 return; 320 } 321 322 const Element * e = mHal.state.type->getElement()->getField(cIdx); 323 uint32_t elemArraySize = 324 mHal.state.type->getElement()->getFieldArraySize(cIdx); 325 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 326 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 327 return; 328 } 329 330 rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, 331 sizeBytes); 332 sendDirty(rsc); 333} 334 335void Allocation::addProgramToDirty(const Program *p) { 336 mToDirtyList.push_back(p); 337} 338 339void Allocation::removeProgramToDirty(const Program *p) { 340 for (auto entryIter = mToDirtyList.begin(), endIter = mToDirtyList.end(); 341 entryIter != endIter; entryIter++) { 342 343 if (p == *entryIter) { 344 mToDirtyList.erase(entryIter); 345 return; 346 } 347 } 348 rsAssert(0); 349} 350 351void Allocation::dumpLOGV(const char *prefix) const { 352 ObjectBase::dumpLOGV(prefix); 353 char buf[1024]; 354 355 if ((strlen(prefix) + 10) < sizeof(buf)) { 356 sprintf(buf, "%s type ", prefix); 357 if (mHal.state.type) { 358 mHal.state.type->dumpLOGV(buf); 359 } 360 } 361 ALOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x", 362 prefix, mHal.drvState.lod[0].mallocPtr, mHal.state.usageFlags, 363 mHal.state.mipmapControl); 364} 365 366uint32_t Allocation::getPackedSize() const { 367 uint32_t numItems = mHal.state.type->getCellCount(); 368 return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded(); 369} 370 371void Allocation::writePackedData(Context *rsc, const Type *type, 372 uint8_t *dst, const uint8_t *src, bool dstPadded) { 373 const Element *elem = type->getElement(); 374 uint32_t unpaddedBytes = elem->getSizeBytesUnpadded(); 375 uint32_t paddedBytes = elem->getSizeBytes(); 376 uint32_t numItems = type->getPackedSizeBytes() / paddedBytes; 377 378 uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes; 379 uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes; 380 381 // no sub-elements 382 uint32_t fieldCount = elem->getFieldCount(); 383 if (fieldCount == 0) { 384 for (uint32_t i = 0; i < numItems; i ++) { 385 memcpy(dst, src, unpaddedBytes); 386 src += srcInc; 387 dst += dstInc; 388 } 389 return; 390 } 391 392 // Cache offsets 393 uint32_t *offsetsPadded = new uint32_t[fieldCount]; 394 uint32_t *offsetsUnpadded = new uint32_t[fieldCount]; 395 uint32_t *sizeUnpadded = new uint32_t[fieldCount]; 396 397 for (uint32_t i = 0; i < fieldCount; i++) { 398 offsetsPadded[i] = elem->getFieldOffsetBytes(i); 399 offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i); 400 sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded(); 401 } 402 403 uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded; 404 uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded; 405 406 // complex elements, need to copy subelem after subelem 407 for (uint32_t i = 0; i < numItems; i ++) { 408 for (uint32_t fI = 0; fI < fieldCount; fI++) { 409 memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]); 410 } 411 src += srcInc; 412 dst += dstInc; 413 } 414 415 delete[] offsetsPadded; 416 delete[] offsetsUnpadded; 417 delete[] sizeUnpadded; 418} 419 420void Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) { 421 const uint8_t *src = (const uint8_t*)data; 422 uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this); 423 424 writePackedData(rsc, getType(), dst, src, true); 425 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 426} 427 428void Allocation::packVec3Allocation(Context *rsc, OStream *stream) const { 429 uint32_t paddedBytes = getType()->getElement()->getSizeBytes(); 430 uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded(); 431 uint32_t numItems = mHal.state.type->getCellCount(); 432 433 const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this); 434 uint8_t *dst = new uint8_t[numItems * unpaddedBytes]; 435 436 writePackedData(rsc, getType(), dst, src, false); 437 stream->addByteArray(dst, getPackedSize()); 438 439 delete[] dst; 440 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 441} 442 443void Allocation::serialize(Context *rsc, OStream *stream) const { 444 // Need to identify ourselves 445 stream->addU32((uint32_t)getClassId()); 446 stream->addString(getName()); 447 448 // First thing we need to serialize is the type object since it will be needed 449 // to initialize the class 450 mHal.state.type->serialize(rsc, stream); 451 452 uint32_t dataSize = mHal.state.type->getPackedSizeBytes(); 453 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 454 uint32_t packedSize = getPackedSize(); 455 // Write how much data we are storing 456 stream->addU32(packedSize); 457 if (dataSize == packedSize) { 458 // Now write the data 459 stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize); 460 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 461 } else { 462 // Now write the data 463 packVec3Allocation(rsc, stream); 464 } 465} 466 467Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { 468 // First make sure we are reading the correct object 469 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 470 if (classID != RS_A3D_CLASS_ID_ALLOCATION) { 471 rsc->setError(RS_ERROR_FATAL_DRIVER, 472 "allocation loading failed due to corrupt file. (invalid id)\n"); 473 return nullptr; 474 } 475 476 const char *name = stream->loadString(); 477 478 Type *type = Type::createFromStream(rsc, stream); 479 if (!type) { 480 return nullptr; 481 } 482 type->compute(); 483 484 Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); 485 type->decUserRef(); 486 487 // Number of bytes we wrote out for this allocation 488 uint32_t dataSize = stream->loadU32(); 489 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 490 uint32_t packedSize = alloc->getPackedSize(); 491 if (dataSize != type->getPackedSizeBytes() && 492 dataSize != packedSize) { 493 rsc->setError(RS_ERROR_FATAL_DRIVER, 494 "allocation loading failed due to corrupt file. (invalid size)\n"); 495 ObjectBase::checkDelete(alloc); 496 ObjectBase::checkDelete(type); 497 return nullptr; 498 } 499 500 alloc->assignName(name); 501 if (dataSize == type->getPackedSizeBytes()) { 502 uint32_t count = dataSize / type->getElementSizeBytes(); 503 // Read in all of our allocation data 504 alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize); 505 } else { 506 alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize); 507 } 508 stream->reset(stream->getPos() + dataSize); 509 510 return alloc; 511} 512 513void Allocation::sendDirty(const Context *rsc) const { 514#ifndef RS_COMPATIBILITY_LIB 515 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 516 mToDirtyList[ct]->forceDirty(); 517 } 518#endif 519 mRSC->mHal.funcs.allocation.markDirty(rsc, this); 520} 521 522void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const { 523 mHal.state.type->incRefs(ptr, ct, startOff); 524} 525 526void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const { 527 if (!mHal.state.hasReferences || !getIsScript()) { 528 return; 529 } 530 mHal.state.type->decRefs(ptr, ct, startOff); 531} 532 533void Allocation::callUpdateCacheObject(const Context *rsc, void *dstObj) const { 534 if (rsc->mHal.funcs.allocation.updateCachedObject != nullptr) { 535 rsc->mHal.funcs.allocation.updateCachedObject(rsc, this, (rs_allocation *)dstObj); 536 } else { 537 *((const void **)dstObj) = this; 538 } 539} 540 541 542void Allocation::freeChildrenUnlocked () { 543 void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this); 544 decRefs(ptr, mHal.state.type->getCellCount(), 0); 545 mRSC->mHal.funcs.allocation.unlock1D(mRSC, this); 546} 547 548bool Allocation::freeChildren() { 549 if (mHal.state.hasReferences) { 550 incSysRef(); 551 freeChildrenUnlocked(); 552 return decSysRef(); 553 } 554 return false; 555} 556 557void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) { 558} 559 560void Allocation::resize1D(Context *rsc, uint32_t dimX) { 561 uint32_t oldDimX = mHal.drvState.lod[0].dimX; 562 if (dimX == oldDimX) { 563 return; 564 } 565 566 ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX); 567 if (dimX < oldDimX) { 568 decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX); 569 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 570 } 571 rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences); 572 setType(t.get()); 573 updateCache(); 574} 575 576void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) { 577 rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented"); 578} 579 580#ifndef RS_COMPATIBILITY_LIB 581void Allocation::NewBufferListener::onFrameAvailable() { 582 intptr_t ip = (intptr_t)alloc; 583 rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true); 584} 585#endif 586 587void * Allocation::getSurface(const Context *rsc) { 588#ifndef RS_COMPATIBILITY_LIB 589 // Configure GrallocConsumer to be in asynchronous mode 590 sp<IGraphicBufferProducer> bp; 591 sp<IGraphicBufferConsumer> bc; 592 BufferQueue::createBufferQueue(&bp, &bc); 593 mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags); 594 bp->incStrong(nullptr); 595 596 mBufferListener = new NewBufferListener(); 597 mBufferListener->rsc = rsc; 598 mBufferListener->alloc = this; 599 600 mGrallocConsumer->setFrameAvailableListener(mBufferListener); 601 return bp.get(); 602#else 603 return nullptr; 604#endif 605 //return rsc->mHal.funcs.allocation.getSurface(rsc, this); 606} 607 608void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { 609 ANativeWindow *nw = (ANativeWindow *)sur; 610 rsc->mHal.funcs.allocation.setSurface(rsc, this, nw); 611} 612 613void Allocation::ioSend(const Context *rsc) { 614 rsc->mHal.funcs.allocation.ioSend(rsc, this); 615} 616 617void Allocation::ioReceive(const Context *rsc) { 618 void *ptr = nullptr; 619 size_t stride = 0; 620#ifndef RS_COMPATIBILITY_LIB 621 if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 622 status_t ret = mGrallocConsumer->lockNextBuffer(); 623 624 if (ret == OK) { 625 rsc->mHal.funcs.allocation.ioReceive(rsc, this); 626 } else if (ret == BAD_VALUE) { 627 // No new frame, don't do anything 628 } else { 629 rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer."); 630 } 631 632 } 633#endif 634} 635 636bool Allocation::hasSameDims(const Allocation *other) const { 637 const Type *type0 = this->getType(), 638 *type1 = other->getType(); 639 640 return (type0->getCellCount() == type1->getCellCount()) && 641 (type0->getDimLOD() == type1->getDimLOD()) && 642 (type0->getDimFaces() == type1->getDimFaces()) && 643 (type0->getDimYuv() == type1->getDimYuv()) && 644 (type0->getDimX() == type1->getDimX()) && 645 (type0->getDimY() == type1->getDimY()) && 646 (type0->getDimZ() == type1->getDimZ()); 647} 648 649 650///////////////// 651// 652 653namespace android { 654namespace renderscript { 655 656void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { 657 Allocation *a = static_cast<Allocation *>(va); 658 a->sendDirty(rsc); 659 a->syncAll(rsc, src); 660} 661 662void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) { 663 Allocation *alloc = static_cast<Allocation *>(va); 664 rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc); 665} 666 667void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 668 Allocation *a = static_cast<Allocation *>(va); 669 const Type * t = a->getType(); 670 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 671 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 672} 673 674void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 675 uint32_t count, const void *data, size_t sizeBytes) { 676 Allocation *a = static_cast<Allocation *>(va); 677 a->data(rsc, xoff, lod, count, data, sizeBytes); 678} 679 680void rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face, 681 const void *data, size_t sizeBytes, size_t eoff) { 682 Allocation *a = static_cast<Allocation *>(va); 683 a->elementData(rsc, x, y, data, eoff, sizeBytes); 684} 685 686void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod, 687 const void *data, size_t sizeBytes, size_t eoff) { 688 Allocation *a = static_cast<Allocation *>(va); 689 a->elementData(rsc, x, data, eoff, sizeBytes); 690} 691 692void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 693 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 694 Allocation *a = static_cast<Allocation *>(va); 695 a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 696} 697 698void rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 699 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 700 Allocation *a = static_cast<Allocation *>(va); 701 a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 702} 703 704 705void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 706 Allocation *a = static_cast<Allocation *>(va); 707 const Type * t = a->getType(); 708 if(t->getDimY()) { 709 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 710 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 711 } else { 712 a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes); 713 } 714 715} 716 717void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) { 718 Allocation *a = static_cast<Allocation *>(va); 719 a->resize1D(rsc, dimX); 720} 721 722void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) { 723 Allocation *a = static_cast<Allocation *>(va); 724 a->resize2D(rsc, dimX, dimY); 725} 726 727RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype, 728 RsAllocationMipmapControl mipmaps, 729 uint32_t usages, uintptr_t ptr) { 730 Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mipmaps, (void*)ptr); 731 if (!alloc) { 732 return nullptr; 733 } 734 alloc->incUserRef(); 735 return alloc; 736} 737 738RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, 739 RsAllocationMipmapControl mipmaps, 740 const void *data, size_t sizeBytes, uint32_t usages) { 741 Type *t = static_cast<Type *>(vtype); 742 743 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 744 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 745 if (texAlloc == nullptr) { 746 ALOGE("Memory allocation failure"); 747 return nullptr; 748 } 749 750 texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 751 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 752 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 753 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 754 } 755 756 texAlloc->sendDirty(rsc); 757 return texAlloc; 758} 759 760RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, 761 RsAllocationMipmapControl mipmaps, 762 const void *data, size_t sizeBytes, uint32_t usages) { 763 Type *t = static_cast<Type *>(vtype); 764 765 // Cubemap allocation's faces should be Width by Width each. 766 // Source data should have 6 * Width by Width pixels 767 // Error checking is done in the java layer 768 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 769 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 770 if (texAlloc == nullptr) { 771 ALOGE("Memory allocation failure"); 772 return nullptr; 773 } 774 775 uint32_t faceSize = t->getDimX(); 776 uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes(); 777 uint32_t copySize = faceSize * t->getElementSizeBytes(); 778 779 uint8_t *sourcePtr = (uint8_t*)data; 780 for (uint32_t face = 0; face < 6; face ++) { 781 for (uint32_t dI = 0; dI < faceSize; dI ++) { 782 texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face, 783 t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0); 784 } 785 786 // Move the data pointer to the next cube face 787 sourcePtr += copySize; 788 } 789 790 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 791 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 792 } 793 794 texAlloc->sendDirty(rsc); 795 return texAlloc; 796} 797 798void rsi_AllocationCopy2DRange(Context *rsc, 799 RsAllocation dstAlloc, 800 uint32_t dstXoff, uint32_t dstYoff, 801 uint32_t dstMip, uint32_t dstFace, 802 uint32_t width, uint32_t height, 803 RsAllocation srcAlloc, 804 uint32_t srcXoff, uint32_t srcYoff, 805 uint32_t srcMip, uint32_t srcFace) { 806 Allocation *dst = static_cast<Allocation *>(dstAlloc); 807 Allocation *src= static_cast<Allocation *>(srcAlloc); 808 rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip, 809 (RsAllocationCubemapFace)dstFace, 810 width, height, 811 src, srcXoff, srcYoff,srcMip, 812 (RsAllocationCubemapFace)srcFace); 813} 814 815void rsi_AllocationCopy3DRange(Context *rsc, 816 RsAllocation dstAlloc, 817 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 818 uint32_t dstMip, 819 uint32_t width, uint32_t height, uint32_t depth, 820 RsAllocation srcAlloc, 821 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 822 uint32_t srcMip) { 823 Allocation *dst = static_cast<Allocation *>(dstAlloc); 824 Allocation *src= static_cast<Allocation *>(srcAlloc); 825 rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip, 826 width, height, depth, 827 src, srcXoff, srcYoff, srcZoff, srcMip); 828} 829 830 831void * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) { 832 Allocation *alloc = static_cast<Allocation *>(valloc); 833 void *s = alloc->getSurface(rsc); 834 return s; 835} 836 837void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { 838 Allocation *alloc = static_cast<Allocation *>(valloc); 839 alloc->setSurface(rsc, sur); 840} 841 842void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { 843 Allocation *alloc = static_cast<Allocation *>(valloc); 844 alloc->ioSend(rsc); 845} 846 847void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { 848 Allocation *alloc = static_cast<Allocation *>(valloc); 849 alloc->ioReceive(rsc); 850} 851 852void *rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc, 853 uint32_t lod, RsAllocationCubemapFace face, 854 uint32_t z, uint32_t array, size_t *stride, size_t strideLen) { 855 Allocation *alloc = static_cast<Allocation *>(valloc); 856 rsAssert(strideLen == sizeof(size_t)); 857 858 return alloc->getPointer(rsc, lod, face, z, array, stride); 859} 860 861void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 862 uint32_t count, void *data, size_t sizeBytes) { 863 Allocation *a = static_cast<Allocation *>(va); 864 rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes); 865} 866 867void rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, 868 uint32_t lod, RsAllocationCubemapFace face, uint32_t w, 869 uint32_t h, void *data, size_t sizeBytes, size_t stride) { 870 Allocation *a = static_cast<Allocation *>(va); 871 a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 872} 873 874RsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) { 875 876 877 Allocation * alloc = Allocation::createAdapter(rsc, 878 static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow)); 879 if (!alloc) { 880 return nullptr; 881 } 882 alloc->incUserRef(); 883 return alloc; 884} 885 886void rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) { 887 Allocation *a = static_cast<Allocation *>(va); 888 a->adapterOffset(rsc, offsets, len); 889} 890 891 892} 893} 894 895extern "C" const void * rsaAllocationGetType(RsContext con, RsAllocation va) { 896 Allocation *a = static_cast<Allocation *>(va); 897 a->getType()->incUserRef(); 898 899 return a->getType(); 900} 901