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