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