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 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 22 #include "system/window.h" 23 #include "gui/GLConsumer.h" 24 #endif 25 26 using namespace android; 27 using namespace android::renderscript; 28 29 Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages, 30 RsAllocationMipmapControl mc, void * ptr) 31 : ObjectBase(rsc) { 32 33 memset(&mHal, 0, sizeof(mHal)); 34 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; 35 mHal.state.usageFlags = usages; 36 mHal.state.mipmapControl = mc; 37 mHal.state.userProvidedPtr = ptr; 38 39 setType(type); 40 updateCache(); 41 } 42 43 Allocation::Allocation(Context *rsc, const Allocation *alloc, const Type *type) 44 : ObjectBase(rsc) { 45 46 memset(&mHal, 0, sizeof(mHal)); 47 mHal.state.baseAlloc = alloc; 48 mHal.state.usageFlags = alloc->mHal.state.usageFlags; 49 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; 50 51 setType(type); 52 updateCache(); 53 } 54 55 void Allocation::operator delete(void* ptr) { 56 if (ptr) { 57 Allocation *a = (Allocation*) ptr; 58 a->getContext()->mHal.funcs.freeRuntimeMem(ptr); 59 } 60 } 61 62 Allocation * Allocation::createAllocationStrided(Context *rsc, const Type *type, uint32_t usages, 63 RsAllocationMipmapControl mc, void * ptr, 64 size_t requiredAlignment) { 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 #ifdef RS_COMPATIBILITY_LIB 84 } else if (usages & RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT){ 85 a = new (allocMem) Allocation(rsc, type, usages, mc, ptr); 86 success = rsc->mHal.funcs.allocation.initStrided(rsc, a, type->getElement()->getHasReferences(), requiredAlignment); 87 #endif 88 } else { 89 a = new (allocMem) Allocation(rsc, type, usages, mc, ptr); 90 success = rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences()); 91 } 92 93 if (!success) { 94 rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); 95 delete a; 96 return nullptr; 97 } 98 99 return a; 100 } 101 102 Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages, 103 RsAllocationMipmapControl mc, void * ptr) { 104 return Allocation::createAllocationStrided(rsc, type, usages, mc, ptr, kMinimumRSAlignment); 105 } 106 107 Allocation * Allocation::createAdapter(Context *rsc, const Allocation *alloc, const Type *type) { 108 // Allocation objects must use allocator specified by the driver 109 void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0); 110 111 if (!allocMem) { 112 rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation"); 113 return nullptr; 114 } 115 116 Allocation *a = new (allocMem) Allocation(rsc, alloc, type); 117 118 if (!rsc->mHal.funcs.allocation.initAdapter(rsc, a)) { 119 rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); 120 delete a; 121 return nullptr; 122 } 123 124 return a; 125 } 126 127 void Allocation::adapterOffset(Context *rsc, const uint32_t *offsets, size_t len) { 128 if (len >= sizeof(uint32_t) * 9) { 129 mHal.state.originX = offsets[0]; 130 mHal.state.originY = offsets[1]; 131 mHal.state.originZ = offsets[2]; 132 mHal.state.originLOD = offsets[3]; 133 mHal.state.originFace = offsets[4]; 134 mHal.state.originArray[0] = offsets[5]; 135 mHal.state.originArray[1] = offsets[6]; 136 mHal.state.originArray[2] = offsets[7]; 137 mHal.state.originArray[3] = offsets[8]; 138 } 139 140 rsc->mHal.funcs.allocation.adapterOffset(rsc, this); 141 } 142 143 144 145 void Allocation::updateCache() { 146 const Type *type = mHal.state.type; 147 mHal.state.yuv = type->getDimYuv(); 148 mHal.state.hasFaces = type->getDimFaces(); 149 mHal.state.hasMipmaps = type->getDimLOD(); 150 mHal.state.elementSizeBytes = type->getElementSizeBytes(); 151 mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences(); 152 } 153 154 Allocation::~Allocation() { 155 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) 156 if (mGrallocConsumer.get()) { 157 mGrallocConsumer->releaseIdx(mCurrentIdx); 158 mGrallocConsumer = nullptr; 159 } 160 #endif 161 162 freeChildrenUnlocked(); 163 mRSC->mHal.funcs.allocation.destroy(mRSC, this); 164 } 165 166 void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { 167 rsc->mHal.funcs.allocation.syncAll(rsc, this, src); 168 } 169 170 void * Allocation::getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face, 171 uint32_t z, uint32_t array, size_t *stride) { 172 173 if ((lod >= mHal.drvState.lodCount) || 174 (z && (z >= mHal.drvState.lod[lod].dimZ)) || 175 ((face != RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) && !mHal.state.hasFaces) || 176 (array != 0)) { 177 return nullptr; 178 } 179 180 if (mRSC->mHal.funcs.allocation.getPointer != nullptr) { 181 // Notify the driver, if present that the user is mapping the buffer 182 mRSC->mHal.funcs.allocation.getPointer(rsc, this, lod, face, z, array); 183 } 184 185 size_t s = 0; 186 if ((stride != nullptr) && mHal.drvState.lod[0].dimY) { 187 *stride = mHal.drvState.lod[lod].stride; 188 } 189 return mHal.drvState.lod[lod].mallocPtr; 190 } 191 192 void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod, 193 uint32_t count, const void *data, size_t sizeBytes) { 194 const size_t eSize = mHal.state.type->getElementSizeBytes(); 195 196 if ((count * eSize) != sizeBytes) { 197 char buf[1024]; 198 sprintf(buf, "Allocation::subData called with mismatched size expected %zu, got %zu", 199 (count * eSize), sizeBytes); 200 rsc->setError(RS_ERROR_BAD_VALUE, buf); 201 mHal.state.type->dumpLOGV("type info"); 202 return; 203 } 204 205 rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes); 206 sendDirty(rsc); 207 } 208 209 void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 210 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 211 rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 212 sendDirty(rsc); 213 } 214 215 void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 216 uint32_t lod, 217 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 218 rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 219 sendDirty(rsc); 220 } 221 222 void Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod, 223 uint32_t count, void *data, size_t sizeBytes) { 224 const size_t eSize = mHal.state.type->getElementSizeBytes(); 225 226 if ((count * eSize) != sizeBytes) { 227 char buf[1024]; 228 sprintf(buf, "Allocation::read called with mismatched size expected %zu, got %zu", 229 (count * eSize), sizeBytes); 230 rsc->setError(RS_ERROR_BAD_VALUE, buf); 231 mHal.state.type->dumpLOGV("type info"); 232 return; 233 } 234 235 rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes); 236 } 237 238 void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 239 uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) { 240 const size_t eSize = mHal.state.elementSizeBytes; 241 const size_t lineSize = eSize * w; 242 if (!stride) { 243 stride = lineSize; 244 } else { 245 if ((lineSize * h) != sizeBytes) { 246 char buf[1024]; 247 sprintf(buf, "Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes); 248 rsc->setError(RS_ERROR_BAD_VALUE, buf); 249 return; 250 } 251 } 252 253 rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 254 } 255 256 void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 257 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) { 258 const size_t eSize = mHal.state.elementSizeBytes; 259 const size_t lineSize = eSize * w; 260 if (!stride) { 261 stride = lineSize; 262 } 263 264 rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 265 266 } 267 268 void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, uint32_t z, 269 const void *data, uint32_t cIdx, size_t sizeBytes) { 270 size_t eSize = mHal.state.elementSizeBytes; 271 272 if (x >= mHal.drvState.lod[0].dimX) { 273 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 274 return; 275 } 276 277 if (y > 0 && y >= mHal.drvState.lod[0].dimY) { 278 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range."); 279 return; 280 } 281 282 if (z > 0 && z >= mHal.drvState.lod[0].dimZ) { 283 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range."); 284 return; 285 } 286 287 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 288 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 289 return; 290 } 291 292 const Element * e = mHal.state.type->getElement()->getField(cIdx); 293 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 294 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 295 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 296 return; 297 } 298 299 rsc->mHal.funcs.allocation.elementData(rsc, this, x, y, z, data, cIdx, sizeBytes); 300 sendDirty(rsc); 301 } 302 303 void Allocation::elementRead(Context *rsc, uint32_t x, uint32_t y, uint32_t z, 304 void *data, uint32_t cIdx, size_t sizeBytes) { 305 size_t eSize = mHal.state.elementSizeBytes; 306 307 if (x >= mHal.drvState.lod[0].dimX) { 308 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 309 return; 310 } 311 312 if (y > 0 && y >= mHal.drvState.lod[0].dimY) { 313 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range."); 314 return; 315 } 316 317 if (z > 0 && z >= mHal.drvState.lod[0].dimZ) { 318 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range."); 319 return; 320 } 321 322 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 323 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 324 return; 325 } 326 327 const Element * e = mHal.state.type->getElement()->getField(cIdx); 328 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 329 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 330 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 331 return; 332 } 333 334 rsc->mHal.funcs.allocation.elementRead(rsc, this, x, y, z, data, cIdx, sizeBytes); 335 } 336 337 void Allocation::addProgramToDirty(const Program *p) { 338 mToDirtyList.push(p); 339 } 340 341 void Allocation::removeProgramToDirty(const Program *p) { 342 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 343 if (mToDirtyList[ct] == p) { 344 mToDirtyList.removeAt(ct); 345 return; 346 } 347 } 348 rsAssert(0); 349 } 350 351 void 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, mHal.state.mipmapControl); 363 } 364 365 uint32_t Allocation::getPackedSize() const { 366 uint32_t numItems = mHal.state.type->getCellCount(); 367 return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded(); 368 } 369 370 void Allocation::writePackedData(Context *rsc, const Type *type, 371 uint8_t *dst, const uint8_t *src, bool dstPadded) { 372 const Element *elem = type->getElement(); 373 uint32_t unpaddedBytes = elem->getSizeBytesUnpadded(); 374 uint32_t paddedBytes = elem->getSizeBytes(); 375 uint32_t numItems = type->getPackedSizeBytes() / paddedBytes; 376 377 uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes; 378 uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes; 379 380 // no sub-elements 381 uint32_t fieldCount = elem->getFieldCount(); 382 if (fieldCount == 0) { 383 for (uint32_t i = 0; i < numItems; i ++) { 384 memcpy(dst, src, unpaddedBytes); 385 src += srcInc; 386 dst += dstInc; 387 } 388 return; 389 } 390 391 // Cache offsets 392 uint32_t *offsetsPadded = new uint32_t[fieldCount]; 393 uint32_t *offsetsUnpadded = new uint32_t[fieldCount]; 394 uint32_t *sizeUnpadded = new uint32_t[fieldCount]; 395 396 for (uint32_t i = 0; i < fieldCount; i++) { 397 offsetsPadded[i] = elem->getFieldOffsetBytes(i); 398 offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i); 399 sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded(); 400 } 401 402 uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded; 403 uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded; 404 405 // complex elements, need to copy subelem after subelem 406 for (uint32_t i = 0; i < numItems; i ++) { 407 for (uint32_t fI = 0; fI < fieldCount; fI++) { 408 memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]); 409 } 410 src += srcInc; 411 dst += dstInc; 412 } 413 414 delete[] offsetsPadded; 415 delete[] offsetsUnpadded; 416 delete[] sizeUnpadded; 417 } 418 419 void Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) { 420 const uint8_t *src = (const uint8_t*)data; 421 uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this); 422 423 writePackedData(rsc, getType(), dst, src, true); 424 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 425 } 426 427 void Allocation::packVec3Allocation(Context *rsc, OStream *stream) const { 428 uint32_t paddedBytes = getType()->getElement()->getSizeBytes(); 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 #ifndef RS_COMPATIBILITY_LIB 580 Allocation::NewBufferListener::NewBufferListener(uint32_t numAlloc) { 581 alloc = new const Allocation *[numAlloc]; 582 mNumAlloc = numAlloc; 583 for (uint32_t i = 0; i < numAlloc; i++) { 584 alloc[i] = nullptr; 585 } 586 } 587 588 Allocation::NewBufferListener::~NewBufferListener() { 589 delete[] alloc; 590 } 591 592 void Allocation::NewBufferListener::onFrameAvailable(const BufferItem& /* item */) { 593 for (uint32_t i = 0; i < mNumAlloc; i++) { 594 if (alloc[i] != nullptr) { 595 intptr_t ip = (intptr_t)alloc[i]; 596 rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true); 597 } 598 } 599 } 600 #endif 601 602 void Allocation::setupGrallocConsumer(const Context *rsc, uint32_t numAlloc) { 603 #ifndef RS_COMPATIBILITY_LIB 604 // Configure GrallocConsumer to be in asynchronous mode 605 if (numAlloc > MAX_NUM_ALLOC || numAlloc <= 0) { 606 rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented"); 607 return; 608 } 609 sp<IGraphicBufferConsumer> bc; 610 BufferQueue::createBufferQueue(&mGraphicBufferProducer, &bc); 611 mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags, numAlloc); 612 613 mBufferListener = new NewBufferListener(numAlloc); 614 mBufferListener->rsc = rsc; 615 mBufferListener->alloc[0] = this; 616 mCurrentIdx = 0; 617 mBufferQueueInited = true; 618 619 mGrallocConsumer->setFrameAvailableListener(mBufferListener); 620 #endif 621 } 622 623 void * Allocation::getSurface(const Context *rsc) { 624 #ifndef RS_COMPATIBILITY_LIB 625 // Configure GrallocConsumer to be in asynchronous mode 626 if (!mBufferQueueInited) { 627 // This case is only used for single frame processing, 628 // since we will always call setupGrallocConsumer first in 629 // multi-frame case. 630 setupGrallocConsumer(rsc, 1); 631 } 632 mGraphicBufferProducer->incStrong(nullptr); 633 return mGraphicBufferProducer.get(); 634 #else 635 return nullptr; 636 #endif 637 //return rsc->mHal.funcs.allocation.getSurface(rsc, this); 638 } 639 640 void Allocation::shareBufferQueue(const Context *rsc, const Allocation *alloc) { 641 #ifndef RS_COMPATIBILITY_LIB 642 mGrallocConsumer = alloc->mGrallocConsumer; 643 mCurrentIdx = mGrallocConsumer->getNextAvailableIdx(this); 644 if (mCurrentIdx >= mGrallocConsumer->mNumAlloc) { 645 rsc->setError(RS_ERROR_DRIVER, "Maximum allocations attached to a BufferQueue"); 646 return; 647 } 648 649 mGraphicBufferProducer = alloc->mGraphicBufferProducer; 650 mBufferListener = alloc->mBufferListener; 651 mBufferListener->alloc[mCurrentIdx] = this; 652 mBufferQueueInited = true; 653 #endif 654 } 655 656 657 void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { 658 ANativeWindow *nw = (ANativeWindow *)sur; 659 rsc->mHal.funcs.allocation.setSurface(rsc, this, nw); 660 } 661 662 void Allocation::ioSend(const Context *rsc) { 663 rsc->mHal.funcs.allocation.ioSend(rsc, this); 664 } 665 666 void Allocation::ioReceive(const Context *rsc) { 667 void *ptr = nullptr; 668 size_t stride = 0; 669 #ifndef RS_COMPATIBILITY_LIB 670 if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 671 status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx); 672 673 if (ret == OK) { 674 rsc->mHal.funcs.allocation.ioReceive(rsc, this); 675 } else if (ret == BAD_VALUE) { 676 // No new frame, don't do anything 677 } else { 678 rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer."); 679 } 680 681 } 682 #endif 683 } 684 685 bool Allocation::hasSameDims(const Allocation *other) const { 686 const Type *type0 = this->getType(), 687 *type1 = other->getType(); 688 689 return (type0->getCellCount() == type1->getCellCount()) && 690 (type0->getDimLOD() == type1->getDimLOD()) && 691 (type0->getDimFaces() == type1->getDimFaces()) && 692 (type0->getDimYuv() == type1->getDimYuv()) && 693 (type0->getDimX() == type1->getDimX()) && 694 (type0->getDimY() == type1->getDimY()) && 695 (type0->getDimZ() == type1->getDimZ()); 696 } 697 698 699 ///////////////// 700 // 701 702 namespace android { 703 namespace renderscript { 704 705 void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { 706 Allocation *a = static_cast<Allocation *>(va); 707 a->sendDirty(rsc); 708 a->syncAll(rsc, src); 709 } 710 711 void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) { 712 Allocation *alloc = static_cast<Allocation *>(va); 713 rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc); 714 } 715 716 void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 717 Allocation *a = static_cast<Allocation *>(va); 718 const Type * t = a->getType(); 719 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 720 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 721 } 722 723 void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 724 uint32_t count, const void *data, size_t sizeBytes) { 725 Allocation *a = static_cast<Allocation *>(va); 726 a->data(rsc, xoff, lod, count, data, sizeBytes); 727 } 728 729 void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, 730 uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) { 731 Allocation *a = static_cast<Allocation *>(va); 732 a->elementData(rsc, x, 0, 0, data, eoff, sizeBytes); 733 } 734 735 void rsi_AllocationElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z, 736 uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) { 737 Allocation *a = static_cast<Allocation *>(va); 738 a->elementData(rsc, x, y, z, data, eoff, sizeBytes); 739 } 740 741 void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 742 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 743 Allocation *a = static_cast<Allocation *>(va); 744 a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 745 } 746 747 void rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 748 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 749 Allocation *a = static_cast<Allocation *>(va); 750 a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 751 } 752 753 754 void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 755 Allocation *a = static_cast<Allocation *>(va); 756 const Type * t = a->getType(); 757 if(t->getDimZ()) { 758 a->read(rsc, 0, 0, 0, 0, t->getDimX(), t->getDimY(), t->getDimZ(), 759 data, sizeBytes, 0); 760 } else if(t->getDimY()) { 761 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 762 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 763 } else { 764 a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes); 765 } 766 767 } 768 769 void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) { 770 Allocation *a = static_cast<Allocation *>(va); 771 a->resize1D(rsc, dimX); 772 } 773 774 void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) { 775 Allocation *a = static_cast<Allocation *>(va); 776 a->resize2D(rsc, dimX, dimY); 777 } 778 779 RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype, 780 RsAllocationMipmapControl mipmaps, 781 uint32_t usages, uintptr_t ptr) { 782 Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mipmaps, (void*)ptr); 783 if (!alloc) { 784 return nullptr; 785 } 786 alloc->incUserRef(); 787 return alloc; 788 } 789 790 RsAllocation rsi_AllocationCreateStrided(Context *rsc, RsType vtype, 791 RsAllocationMipmapControl mipmaps, 792 uint32_t usages, uintptr_t ptr, 793 size_t requiredAlignment) { 794 Allocation * alloc = Allocation::createAllocationStrided(rsc, static_cast<Type *>(vtype), usages, mipmaps, 795 (void*)ptr, requiredAlignment); 796 if (!alloc) { 797 return nullptr; 798 } 799 alloc->incUserRef(); 800 return alloc; 801 } 802 803 RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, 804 RsAllocationMipmapControl mipmaps, 805 const void *data, size_t sizeBytes, uint32_t usages) { 806 Type *t = static_cast<Type *>(vtype); 807 808 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 809 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 810 if (texAlloc == nullptr) { 811 ALOGE("Memory allocation failure"); 812 return nullptr; 813 } 814 815 texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 816 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 817 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 818 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 819 } 820 821 texAlloc->sendDirty(rsc); 822 return texAlloc; 823 } 824 825 RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, 826 RsAllocationMipmapControl mipmaps, 827 const void *data, size_t sizeBytes, uint32_t usages) { 828 Type *t = static_cast<Type *>(vtype); 829 830 // Cubemap allocation's faces should be Width by Width each. 831 // Source data should have 6 * Width by Width pixels 832 // Error checking is done in the java layer 833 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 834 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 835 if (texAlloc == nullptr) { 836 ALOGE("Memory allocation failure"); 837 return nullptr; 838 } 839 840 uint32_t faceSize = t->getDimX(); 841 uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes(); 842 uint32_t copySize = faceSize * t->getElementSizeBytes(); 843 844 uint8_t *sourcePtr = (uint8_t*)data; 845 for (uint32_t face = 0; face < 6; face ++) { 846 for (uint32_t dI = 0; dI < faceSize; dI ++) { 847 texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face, 848 t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0); 849 } 850 851 // Move the data pointer to the next cube face 852 sourcePtr += copySize; 853 } 854 855 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 856 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 857 } 858 859 texAlloc->sendDirty(rsc); 860 return texAlloc; 861 } 862 863 void rsi_AllocationCopy2DRange(Context *rsc, 864 RsAllocation dstAlloc, 865 uint32_t dstXoff, uint32_t dstYoff, 866 uint32_t dstMip, uint32_t dstFace, 867 uint32_t width, uint32_t height, 868 RsAllocation srcAlloc, 869 uint32_t srcXoff, uint32_t srcYoff, 870 uint32_t srcMip, uint32_t srcFace) { 871 Allocation *dst = static_cast<Allocation *>(dstAlloc); 872 Allocation *src= static_cast<Allocation *>(srcAlloc); 873 rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip, 874 (RsAllocationCubemapFace)dstFace, 875 width, height, 876 src, srcXoff, srcYoff,srcMip, 877 (RsAllocationCubemapFace)srcFace); 878 } 879 880 void rsi_AllocationCopy3DRange(Context *rsc, 881 RsAllocation dstAlloc, 882 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 883 uint32_t dstMip, 884 uint32_t width, uint32_t height, uint32_t depth, 885 RsAllocation srcAlloc, 886 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 887 uint32_t srcMip) { 888 Allocation *dst = static_cast<Allocation *>(dstAlloc); 889 Allocation *src= static_cast<Allocation *>(srcAlloc); 890 rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip, 891 width, height, depth, 892 src, srcXoff, srcYoff, srcZoff, srcMip); 893 } 894 895 void rsi_AllocationSetupBufferQueue(Context *rsc, RsAllocation valloc, uint32_t numAlloc) { 896 Allocation *alloc = static_cast<Allocation *>(valloc); 897 alloc->setupGrallocConsumer(rsc, numAlloc); 898 } 899 900 void * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) { 901 Allocation *alloc = static_cast<Allocation *>(valloc); 902 void *s = alloc->getSurface(rsc); 903 return s; 904 } 905 906 void rsi_AllocationShareBufferQueue(Context *rsc, RsAllocation valloc1, RsAllocation valloc2) { 907 Allocation *alloc1 = static_cast<Allocation *>(valloc1); 908 Allocation *alloc2 = static_cast<Allocation *>(valloc2); 909 alloc1->shareBufferQueue(rsc, alloc2); 910 } 911 912 void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { 913 Allocation *alloc = static_cast<Allocation *>(valloc); 914 alloc->setSurface(rsc, sur); 915 } 916 917 void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { 918 Allocation *alloc = static_cast<Allocation *>(valloc); 919 alloc->ioSend(rsc); 920 } 921 922 int64_t rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { 923 Allocation *alloc = static_cast<Allocation *>(valloc); 924 alloc->ioReceive(rsc); 925 return alloc->getTimeStamp(); 926 } 927 928 void *rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc, 929 uint32_t lod, RsAllocationCubemapFace face, 930 uint32_t z, uint32_t array, size_t *stride, size_t strideLen) { 931 Allocation *alloc = static_cast<Allocation *>(valloc); 932 rsAssert(strideLen == sizeof(size_t)); 933 934 return alloc->getPointer(rsc, lod, face, z, array, stride); 935 } 936 937 void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 938 uint32_t count, void *data, size_t sizeBytes) { 939 Allocation *a = static_cast<Allocation *>(va); 940 rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes); 941 } 942 943 void rsi_AllocationElementRead(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z, 944 uint32_t lod, void *data, size_t sizeBytes, size_t eoff) { 945 Allocation *a = static_cast<Allocation *>(va); 946 a->elementRead(rsc, x, y, z, data, eoff, sizeBytes); 947 } 948 949 void rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, 950 uint32_t lod, RsAllocationCubemapFace face, uint32_t w, 951 uint32_t h, void *data, size_t sizeBytes, size_t stride) { 952 Allocation *a = static_cast<Allocation *>(va); 953 a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 954 } 955 956 void rsi_Allocation3DRead(Context *rsc, RsAllocation va, 957 uint32_t xoff, uint32_t yoff, uint32_t zoff, 958 uint32_t lod, uint32_t w, uint32_t h, uint32_t d, 959 void *data, size_t sizeBytes, size_t stride) { 960 Allocation *a = static_cast<Allocation *>(va); 961 a->read(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 962 } 963 964 RsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) { 965 966 967 Allocation * alloc = Allocation::createAdapter(rsc, 968 static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow)); 969 if (!alloc) { 970 return nullptr; 971 } 972 alloc->incUserRef(); 973 return alloc; 974 } 975 976 void rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) { 977 Allocation *a = static_cast<Allocation *>(va); 978 a->adapterOffset(rsc, offsets, len); 979 } 980 981 982 } 983 } 984