rsAllocation.cpp revision 3df9bb0bd784bd9d01653de4de13af0982528a44
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 26using namespace android; 27using namespace android::renderscript; 28 29Allocation::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 43Allocation::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 55void Allocation::operator delete(void* ptr) { 56 if (ptr) { 57 Allocation *a = (Allocation*) ptr; 58 a->getContext()->mHal.funcs.freeRuntimeMem(ptr); 59 } 60} 61 62Allocation * 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 102Allocation * 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 107Allocation * 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 127void 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 145void 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 154Allocation::~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 166void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { 167 rsc->mHal.funcs.allocation.syncAll(rsc, this, src); 168} 169 170void * 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 192void 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 snprintf(buf, sizeof(buf), 199 "Allocation::subData called with mismatched size expected %zu, got %zu", 200 (count * eSize), sizeBytes); 201 rsc->setError(RS_ERROR_BAD_VALUE, buf); 202 mHal.state.type->dumpLOGV("type info"); 203 return; 204 } 205 206 rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes); 207 sendDirty(rsc); 208} 209 210void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 211 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 212 rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 213 sendDirty(rsc); 214} 215 216void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 217 uint32_t lod, 218 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 219 rsc->mHal.funcs.allocation.data3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 220 sendDirty(rsc); 221} 222 223void Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod, 224 uint32_t count, void *data, size_t sizeBytes) { 225 const size_t eSize = mHal.state.type->getElementSizeBytes(); 226 227 if ((count * eSize) != sizeBytes) { 228 char buf[1024]; 229 snprintf(buf, sizeof(buf), 230 "Allocation::read called with mismatched size expected %zu, got %zu", 231 (count * eSize), sizeBytes); 232 rsc->setError(RS_ERROR_BAD_VALUE, buf); 233 mHal.state.type->dumpLOGV("type info"); 234 return; 235 } 236 237 rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes); 238} 239 240void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 241 uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) { 242 const size_t eSize = mHal.state.elementSizeBytes; 243 const size_t lineSize = eSize * w; 244 if (!stride) { 245 stride = lineSize; 246 } else { 247 if ((lineSize * h) != sizeBytes) { 248 char buf[1024]; 249 snprintf(buf, sizeof(buf), "Allocation size mismatch, expected %zu, got %zu", 250 (lineSize * h), sizeBytes); 251 rsc->setError(RS_ERROR_BAD_VALUE, buf); 252 return; 253 } 254 } 255 256 rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 257} 258 259void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 260 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) { 261 const size_t eSize = mHal.state.elementSizeBytes; 262 const size_t lineSize = eSize * w; 263 if (!stride) { 264 stride = lineSize; 265 } 266 267 rsc->mHal.funcs.allocation.read3D(rsc, this, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 268 269} 270 271void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, uint32_t z, 272 const void *data, uint32_t cIdx, size_t sizeBytes) { 273 size_t eSize = mHal.state.elementSizeBytes; 274 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 306void Allocation::elementRead(Context *rsc, uint32_t x, uint32_t y, uint32_t z, 307 void *data, uint32_t cIdx, size_t sizeBytes) { 308 size_t eSize = mHal.state.elementSizeBytes; 309 310 if (x >= mHal.drvState.lod[0].dimX) { 311 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 312 return; 313 } 314 315 if (y > 0 && y >= mHal.drvState.lod[0].dimY) { 316 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Y offset out of range."); 317 return; 318 } 319 320 if (z > 0 && z >= mHal.drvState.lod[0].dimZ) { 321 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData Z offset out of range."); 322 return; 323 } 324 325 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 326 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 327 return; 328 } 329 330 const Element * e = mHal.state.type->getElement()->getField(cIdx); 331 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 332 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 333 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 334 return; 335 } 336 337 rsc->mHal.funcs.allocation.elementRead(rsc, this, x, y, z, data, cIdx, sizeBytes); 338} 339 340void Allocation::addProgramToDirty(const Program *p) { 341 mToDirtyList.push(p); 342} 343 344void Allocation::removeProgramToDirty(const Program *p) { 345 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 346 if (mToDirtyList[ct] == p) { 347 mToDirtyList.removeAt(ct); 348 return; 349 } 350 } 351 rsAssert(0); 352} 353 354void Allocation::dumpLOGV(const char *prefix) const { 355 ObjectBase::dumpLOGV(prefix); 356 char buf[1024]; 357 358 if ((strlen(prefix) + 10) < sizeof(buf)) { 359 snprintf(buf, sizeof(buf), "%s type ", prefix); 360 if (mHal.state.type) { 361 mHal.state.type->dumpLOGV(buf); 362 } 363 } 364 ALOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x", 365 prefix, mHal.drvState.lod[0].mallocPtr, mHal.state.usageFlags, mHal.state.mipmapControl); 366} 367 368uint32_t Allocation::getPackedSize() const { 369 uint32_t numItems = mHal.state.type->getCellCount(); 370 return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded(); 371} 372 373void Allocation::writePackedData(Context *rsc, const Type *type, 374 uint8_t *dst, const uint8_t *src, bool dstPadded) { 375 const Element *elem = type->getElement(); 376 uint32_t unpaddedBytes = elem->getSizeBytesUnpadded(); 377 uint32_t paddedBytes = elem->getSizeBytes(); 378 uint32_t numItems = type->getPackedSizeBytes() / paddedBytes; 379 380 uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes; 381 uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes; 382 383 // no sub-elements 384 uint32_t fieldCount = elem->getFieldCount(); 385 if (fieldCount == 0) { 386 for (uint32_t i = 0; i < numItems; i ++) { 387 memcpy(dst, src, unpaddedBytes); 388 src += srcInc; 389 dst += dstInc; 390 } 391 return; 392 } 393 394 // Cache offsets 395 uint32_t *offsetsPadded = new uint32_t[fieldCount]; 396 uint32_t *offsetsUnpadded = new uint32_t[fieldCount]; 397 uint32_t *sizeUnpadded = new uint32_t[fieldCount]; 398 399 for (uint32_t i = 0; i < fieldCount; i++) { 400 offsetsPadded[i] = elem->getFieldOffsetBytes(i); 401 offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i); 402 sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded(); 403 } 404 405 uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded; 406 uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded; 407 408 // complex elements, need to copy subelem after subelem 409 for (uint32_t i = 0; i < numItems; i ++) { 410 for (uint32_t fI = 0; fI < fieldCount; fI++) { 411 memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]); 412 } 413 src += srcInc; 414 dst += dstInc; 415 } 416 417 delete[] offsetsPadded; 418 delete[] offsetsUnpadded; 419 delete[] sizeUnpadded; 420} 421 422void Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) { 423 const uint8_t *src = (const uint8_t*)data; 424 uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this); 425 426 writePackedData(rsc, getType(), dst, src, true); 427 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 428} 429 430void Allocation::packVec3Allocation(Context *rsc, OStream *stream) const { 431 uint32_t paddedBytes = getType()->getElement()->getSizeBytes(); 432 uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded(); 433 uint32_t numItems = mHal.state.type->getCellCount(); 434 435 const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this); 436 uint8_t *dst = new uint8_t[numItems * unpaddedBytes]; 437 438 writePackedData(rsc, getType(), dst, src, false); 439 stream->addByteArray(dst, getPackedSize()); 440 441 delete[] dst; 442 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 443} 444 445void Allocation::serialize(Context *rsc, OStream *stream) const { 446 // Need to identify ourselves 447 stream->addU32((uint32_t)getClassId()); 448 stream->addString(getName()); 449 450 // First thing we need to serialize is the type object since it will be needed 451 // to initialize the class 452 mHal.state.type->serialize(rsc, stream); 453 454 uint32_t dataSize = mHal.state.type->getPackedSizeBytes(); 455 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 456 uint32_t packedSize = getPackedSize(); 457 // Write how much data we are storing 458 stream->addU32(packedSize); 459 if (dataSize == packedSize) { 460 // Now write the data 461 stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize); 462 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 463 } else { 464 // Now write the data 465 packVec3Allocation(rsc, stream); 466 } 467} 468 469Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { 470 // First make sure we are reading the correct object 471 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 472 if (classID != RS_A3D_CLASS_ID_ALLOCATION) { 473 rsc->setError(RS_ERROR_FATAL_DRIVER, 474 "allocation loading failed due to corrupt file. (invalid id)\n"); 475 return nullptr; 476 } 477 478 const char *name = stream->loadString(); 479 480 Type *type = Type::createFromStream(rsc, stream); 481 if (!type) { 482 return nullptr; 483 } 484 type->compute(); 485 486 Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); 487 type->decUserRef(); 488 489 // Number of bytes we wrote out for this allocation 490 uint32_t dataSize = stream->loadU32(); 491 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 492 uint32_t packedSize = alloc->getPackedSize(); 493 if (dataSize != type->getPackedSizeBytes() && 494 dataSize != packedSize) { 495 rsc->setError(RS_ERROR_FATAL_DRIVER, 496 "allocation loading failed due to corrupt file. (invalid size)\n"); 497 ObjectBase::checkDelete(alloc); 498 ObjectBase::checkDelete(type); 499 return nullptr; 500 } 501 502 alloc->assignName(name); 503 if (dataSize == type->getPackedSizeBytes()) { 504 uint32_t count = dataSize / type->getElementSizeBytes(); 505 // Read in all of our allocation data 506 alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize); 507 } else { 508 alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize); 509 } 510 stream->reset(stream->getPos() + dataSize); 511 512 return alloc; 513} 514 515void Allocation::sendDirty(const Context *rsc) const { 516#ifndef RS_COMPATIBILITY_LIB 517 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 518 mToDirtyList[ct]->forceDirty(); 519 } 520#endif 521 mRSC->mHal.funcs.allocation.markDirty(rsc, this); 522} 523 524void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const { 525 mHal.state.type->incRefs(ptr, ct, startOff); 526} 527 528void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const { 529 if (!mHal.state.hasReferences || !getIsScript()) { 530 return; 531 } 532 mHal.state.type->decRefs(ptr, ct, startOff); 533} 534 535void Allocation::callUpdateCacheObject(const Context *rsc, void *dstObj) const { 536 if (rsc->mHal.funcs.allocation.updateCachedObject != nullptr) { 537 rsc->mHal.funcs.allocation.updateCachedObject(rsc, this, (rs_allocation *)dstObj); 538 } else { 539 *((const void **)dstObj) = this; 540 } 541} 542 543 544void Allocation::freeChildrenUnlocked () { 545 void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this); 546 decRefs(ptr, mHal.state.type->getCellCount(), 0); 547 mRSC->mHal.funcs.allocation.unlock1D(mRSC, this); 548} 549 550bool Allocation::freeChildren() { 551 if (mHal.state.hasReferences) { 552 incSysRef(); 553 freeChildrenUnlocked(); 554 return decSysRef(); 555 } 556 return false; 557} 558 559void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) { 560} 561 562void Allocation::resize1D(Context *rsc, uint32_t dimX) { 563 uint32_t oldDimX = mHal.drvState.lod[0].dimX; 564 if (dimX == oldDimX) { 565 return; 566 } 567 568 ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX); 569 if (dimX < oldDimX) { 570 decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX); 571 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 572 } 573 rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences); 574 setType(t.get()); 575 updateCache(); 576} 577 578void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) { 579 rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented"); 580} 581 582#ifndef RS_COMPATIBILITY_LIB 583Allocation::NewBufferListener::NewBufferListener(uint32_t numAlloc) { 584 alloc = new const Allocation *[numAlloc]; 585 mNumAlloc = numAlloc; 586 for (uint32_t i = 0; i < numAlloc; i++) { 587 alloc[i] = nullptr; 588 } 589} 590 591Allocation::NewBufferListener::~NewBufferListener() { 592 delete[] alloc; 593} 594 595void Allocation::NewBufferListener::onFrameAvailable(const BufferItem& /* item */) { 596 for (uint32_t i = 0; i < mNumAlloc; i++) { 597 if (alloc[i] != nullptr) { 598 intptr_t ip = (intptr_t)alloc[i]; 599 rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true); 600 } 601 } 602} 603#endif 604 605void Allocation::setupGrallocConsumer(const Context *rsc, uint32_t numAlloc) { 606#ifndef RS_COMPATIBILITY_LIB 607 // Configure GrallocConsumer to be in asynchronous mode 608 if (numAlloc > MAX_NUM_ALLOC || numAlloc <= 0) { 609 rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented"); 610 return; 611 } 612 sp<IGraphicBufferConsumer> bc; 613 BufferQueue::createBufferQueue(&mGraphicBufferProducer, &bc); 614 mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags, numAlloc); 615 616 mBufferListener = new NewBufferListener(numAlloc); 617 mBufferListener->rsc = rsc; 618 mBufferListener->alloc[0] = this; 619 mCurrentIdx = 0; 620 mBufferQueueInited = true; 621 622 mGrallocConsumer->setFrameAvailableListener(mBufferListener); 623#endif 624} 625 626void * Allocation::getSurface(const Context *rsc) { 627#ifndef RS_COMPATIBILITY_LIB 628 // Configure GrallocConsumer to be in asynchronous mode 629 if (!mBufferQueueInited) { 630 // This case is only used for single frame processing, 631 // since we will always call setupGrallocConsumer first in 632 // multi-frame case. 633 setupGrallocConsumer(rsc, 1); 634 } 635 mGraphicBufferProducer->incStrong(nullptr); 636 return mGraphicBufferProducer.get(); 637#else 638 return nullptr; 639#endif 640 //return rsc->mHal.funcs.allocation.getSurface(rsc, this); 641} 642 643void Allocation::shareBufferQueue(const Context *rsc, const Allocation *alloc) { 644#ifndef RS_COMPATIBILITY_LIB 645 mGrallocConsumer = alloc->mGrallocConsumer; 646 mCurrentIdx = mGrallocConsumer->getNextAvailableIdx(this); 647 if (mCurrentIdx >= mGrallocConsumer->mNumAlloc) { 648 rsc->setError(RS_ERROR_DRIVER, "Maximum allocations attached to a BufferQueue"); 649 return; 650 } 651 652 mGraphicBufferProducer = alloc->mGraphicBufferProducer; 653 mBufferListener = alloc->mBufferListener; 654 mBufferListener->alloc[mCurrentIdx] = this; 655 mBufferQueueInited = true; 656#endif 657} 658 659 660void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { 661 ANativeWindow *nw = (ANativeWindow *)sur; 662 rsc->mHal.funcs.allocation.setSurface(rsc, this, nw); 663} 664 665void Allocation::ioSend(const Context *rsc) { 666 rsc->mHal.funcs.allocation.ioSend(rsc, this); 667} 668 669void Allocation::ioReceive(const Context *rsc) { 670 void *ptr = nullptr; 671 size_t stride = 0; 672#ifndef RS_COMPATIBILITY_LIB 673 if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 674 status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx); 675 676 if (ret == OK) { 677 rsc->mHal.funcs.allocation.ioReceive(rsc, this); 678 } else if (ret == BAD_VALUE) { 679 // No new frame, don't do anything 680 } else { 681 rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer."); 682 } 683 684 } 685#endif 686} 687 688bool Allocation::hasSameDims(const Allocation *other) const { 689 const Type *type0 = this->getType(), 690 *type1 = other->getType(); 691 692 return (type0->getCellCount() == type1->getCellCount()) && 693 (type0->getDimLOD() == type1->getDimLOD()) && 694 (type0->getDimFaces() == type1->getDimFaces()) && 695 (type0->getDimYuv() == type1->getDimYuv()) && 696 (type0->getDimX() == type1->getDimX()) && 697 (type0->getDimY() == type1->getDimY()) && 698 (type0->getDimZ() == type1->getDimZ()); 699} 700 701 702///////////////// 703// 704 705namespace android { 706namespace renderscript { 707 708void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { 709 Allocation *a = static_cast<Allocation *>(va); 710 a->sendDirty(rsc); 711 a->syncAll(rsc, src); 712} 713 714void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) { 715 Allocation *alloc = static_cast<Allocation *>(va); 716 rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc); 717} 718 719void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 720 Allocation *a = static_cast<Allocation *>(va); 721 const Type * t = a->getType(); 722 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 723 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 724} 725 726void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 727 uint32_t count, const void *data, size_t sizeBytes) { 728 Allocation *a = static_cast<Allocation *>(va); 729 a->data(rsc, xoff, lod, count, data, sizeBytes); 730} 731 732void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, 733 uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) { 734 Allocation *a = static_cast<Allocation *>(va); 735 a->elementData(rsc, x, 0, 0, data, eoff, sizeBytes); 736} 737 738void rsi_AllocationElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z, 739 uint32_t lod, const void *data, size_t sizeBytes, size_t eoff) { 740 Allocation *a = static_cast<Allocation *>(va); 741 a->elementData(rsc, x, y, z, data, eoff, sizeBytes); 742} 743 744void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 745 uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) { 746 Allocation *a = static_cast<Allocation *>(va); 747 a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 748} 749 750void rsi_Allocation3DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, 751 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes, size_t stride) { 752 Allocation *a = static_cast<Allocation *>(va); 753 a->data(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 754} 755 756 757void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 758 Allocation *a = static_cast<Allocation *>(va); 759 const Type * t = a->getType(); 760 if(t->getDimZ()) { 761 a->read(rsc, 0, 0, 0, 0, t->getDimX(), t->getDimY(), t->getDimZ(), 762 data, sizeBytes, 0); 763 } else if(t->getDimY()) { 764 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 765 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 766 } else { 767 a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes); 768 } 769 770} 771 772void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) { 773 Allocation *a = static_cast<Allocation *>(va); 774 a->resize1D(rsc, dimX); 775} 776 777void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) { 778 Allocation *a = static_cast<Allocation *>(va); 779 a->resize2D(rsc, dimX, dimY); 780} 781 782RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype, 783 RsAllocationMipmapControl mipmaps, 784 uint32_t usages, uintptr_t ptr) { 785 Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mipmaps, (void*)ptr); 786 if (!alloc) { 787 return nullptr; 788 } 789 alloc->incUserRef(); 790 return alloc; 791} 792 793RsAllocation rsi_AllocationCreateStrided(Context *rsc, RsType vtype, 794 RsAllocationMipmapControl mipmaps, 795 uint32_t usages, uintptr_t ptr, 796 size_t requiredAlignment) { 797 Allocation * alloc = Allocation::createAllocationStrided(rsc, static_cast<Type *>(vtype), usages, mipmaps, 798 (void*)ptr, requiredAlignment); 799 if (!alloc) { 800 return nullptr; 801 } 802 alloc->incUserRef(); 803 return alloc; 804} 805 806RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, 807 RsAllocationMipmapControl mipmaps, 808 const void *data, size_t sizeBytes, uint32_t usages) { 809 Type *t = static_cast<Type *>(vtype); 810 811 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 812 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 813 if (texAlloc == nullptr) { 814 ALOGE("Memory allocation failure"); 815 return nullptr; 816 } 817 818 texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 819 t->getDimX(), t->getDimY(), data, sizeBytes, 0); 820 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 821 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 822 } 823 824 texAlloc->sendDirty(rsc); 825 return texAlloc; 826} 827 828RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, 829 RsAllocationMipmapControl mipmaps, 830 const void *data, size_t sizeBytes, uint32_t usages) { 831 Type *t = static_cast<Type *>(vtype); 832 833 // Cubemap allocation's faces should be Width by Width each. 834 // Source data should have 6 * Width by Width pixels 835 // Error checking is done in the java layer 836 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0); 837 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 838 if (texAlloc == nullptr) { 839 ALOGE("Memory allocation failure"); 840 return nullptr; 841 } 842 843 uint32_t faceSize = t->getDimX(); 844 uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes(); 845 uint32_t copySize = faceSize * t->getElementSizeBytes(); 846 847 uint8_t *sourcePtr = (uint8_t*)data; 848 for (uint32_t face = 0; face < 6; face ++) { 849 for (uint32_t dI = 0; dI < faceSize; dI ++) { 850 texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face, 851 t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0); 852 } 853 854 // Move the data pointer to the next cube face 855 sourcePtr += copySize; 856 } 857 858 if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) { 859 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 860 } 861 862 texAlloc->sendDirty(rsc); 863 return texAlloc; 864} 865 866void rsi_AllocationCopy2DRange(Context *rsc, 867 RsAllocation dstAlloc, 868 uint32_t dstXoff, uint32_t dstYoff, 869 uint32_t dstMip, uint32_t dstFace, 870 uint32_t width, uint32_t height, 871 RsAllocation srcAlloc, 872 uint32_t srcXoff, uint32_t srcYoff, 873 uint32_t srcMip, uint32_t srcFace) { 874 Allocation *dst = static_cast<Allocation *>(dstAlloc); 875 Allocation *src= static_cast<Allocation *>(srcAlloc); 876 rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip, 877 (RsAllocationCubemapFace)dstFace, 878 width, height, 879 src, srcXoff, srcYoff,srcMip, 880 (RsAllocationCubemapFace)srcFace); 881} 882 883void rsi_AllocationCopy3DRange(Context *rsc, 884 RsAllocation dstAlloc, 885 uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, 886 uint32_t dstMip, 887 uint32_t width, uint32_t height, uint32_t depth, 888 RsAllocation srcAlloc, 889 uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, 890 uint32_t srcMip) { 891 Allocation *dst = static_cast<Allocation *>(dstAlloc); 892 Allocation *src= static_cast<Allocation *>(srcAlloc); 893 rsc->mHal.funcs.allocation.allocData3D(rsc, dst, dstXoff, dstYoff, dstZoff, dstMip, 894 width, height, depth, 895 src, srcXoff, srcYoff, srcZoff, srcMip); 896} 897 898void rsi_AllocationSetupBufferQueue(Context *rsc, RsAllocation valloc, uint32_t numAlloc) { 899 Allocation *alloc = static_cast<Allocation *>(valloc); 900 alloc->setupGrallocConsumer(rsc, numAlloc); 901} 902 903void * rsi_AllocationGetSurface(Context *rsc, RsAllocation valloc) { 904 Allocation *alloc = static_cast<Allocation *>(valloc); 905 void *s = alloc->getSurface(rsc); 906 return s; 907} 908 909void rsi_AllocationShareBufferQueue(Context *rsc, RsAllocation valloc1, RsAllocation valloc2) { 910 Allocation *alloc1 = static_cast<Allocation *>(valloc1); 911 Allocation *alloc2 = static_cast<Allocation *>(valloc2); 912 alloc1->shareBufferQueue(rsc, alloc2); 913} 914 915void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { 916 Allocation *alloc = static_cast<Allocation *>(valloc); 917 alloc->setSurface(rsc, sur); 918} 919 920void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { 921 Allocation *alloc = static_cast<Allocation *>(valloc); 922 alloc->ioSend(rsc); 923} 924 925int64_t rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { 926 Allocation *alloc = static_cast<Allocation *>(valloc); 927 alloc->ioReceive(rsc); 928 return alloc->getTimeStamp(); 929} 930 931void *rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc, 932 uint32_t lod, RsAllocationCubemapFace face, 933 uint32_t z, uint32_t array, size_t *stride, size_t strideLen) { 934 Allocation *alloc = static_cast<Allocation *>(valloc); 935 rsAssert(strideLen == sizeof(size_t)); 936 937 return alloc->getPointer(rsc, lod, face, z, array, stride); 938} 939 940void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 941 uint32_t count, void *data, size_t sizeBytes) { 942 Allocation *a = static_cast<Allocation *>(va); 943 rsc->mHal.funcs.allocation.read1D(rsc, a, xoff, lod, count, data, sizeBytes); 944} 945 946void rsi_AllocationElementRead(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t z, 947 uint32_t lod, void *data, size_t sizeBytes, size_t eoff) { 948 Allocation *a = static_cast<Allocation *>(va); 949 a->elementRead(rsc, x, y, z, data, eoff, sizeBytes); 950} 951 952void rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, 953 uint32_t lod, RsAllocationCubemapFace face, uint32_t w, 954 uint32_t h, void *data, size_t sizeBytes, size_t stride) { 955 Allocation *a = static_cast<Allocation *>(va); 956 a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride); 957} 958 959void rsi_Allocation3DRead(Context *rsc, RsAllocation va, 960 uint32_t xoff, uint32_t yoff, uint32_t zoff, 961 uint32_t lod, uint32_t w, uint32_t h, uint32_t d, 962 void *data, size_t sizeBytes, size_t stride) { 963 Allocation *a = static_cast<Allocation *>(va); 964 a->read(rsc, xoff, yoff, zoff, lod, w, h, d, data, sizeBytes, stride); 965} 966 967RsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) { 968 969 970 Allocation * alloc = Allocation::createAdapter(rsc, 971 static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow)); 972 if (!alloc) { 973 return nullptr; 974 } 975 alloc->incUserRef(); 976 return alloc; 977} 978 979void rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) { 980 Allocation *a = static_cast<Allocation *>(va); 981 a->adapterOffset(rsc, offsets, len); 982} 983 984 985} 986} 987