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