1/* 2 * Copyright (C) 2009-2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "rsContext.h" 18#include "rsAllocation.h" 19#include "rsAdapter.h" 20#include "rs_hal.h" 21 22using namespace android; 23using namespace android::renderscript; 24 25Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages, 26 RsAllocationMipmapControl mc, void * ptr) 27 : ObjectBase(rsc) { 28 29 memset(&mHal, 0, sizeof(mHal)); 30 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; 31 mHal.state.usageFlags = usages; 32 mHal.state.mipmapControl = mc; 33 34 setType(type); 35 updateCache(); 36} 37 38Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages, 39 RsAllocationMipmapControl mc, void * ptr) { 40 Allocation *a = new Allocation(rsc, type, usages, mc, ptr); 41 42 if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) { 43 rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); 44 delete a; 45 return NULL; 46 } 47 48 return a; 49} 50 51void Allocation::updateCache() { 52 const Type *type = mHal.state.type; 53 mHal.state.dimensionX = type->getDimX(); 54 mHal.state.dimensionY = type->getDimY(); 55 mHal.state.dimensionZ = type->getDimZ(); 56 mHal.state.hasFaces = type->getDimFaces(); 57 mHal.state.hasMipmaps = type->getDimLOD(); 58 mHal.state.elementSizeBytes = type->getElementSizeBytes(); 59 mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences(); 60} 61 62Allocation::~Allocation() { 63 freeChildrenUnlocked(); 64 mRSC->mHal.funcs.allocation.destroy(mRSC, this); 65} 66 67void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { 68 rsc->mHal.funcs.allocation.syncAll(rsc, this, src); 69} 70 71void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod, 72 uint32_t count, const void *data, size_t sizeBytes) { 73 const size_t eSize = mHal.state.type->getElementSizeBytes(); 74 75 if ((count * eSize) != sizeBytes) { 76 ALOGE("Allocation::subData called with mismatched size expected %zu, got %zu", 77 (count * eSize), sizeBytes); 78 mHal.state.type->dumpLOGV("type info"); 79 return; 80 } 81 82 rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes); 83 sendDirty(rsc); 84} 85 86void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 87 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { 88 const size_t eSize = mHal.state.elementSizeBytes; 89 const size_t lineSize = eSize * w; 90 91 //ALOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes); 92 93 if ((lineSize * h) != sizeBytes) { 94 ALOGE("Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes); 95 rsAssert(!"Allocation::subData called with mismatched size"); 96 return; 97 } 98 99 rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes); 100 sendDirty(rsc); 101} 102 103void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 104 uint32_t lod, RsAllocationCubemapFace face, 105 uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes) { 106} 107 108void Allocation::read(Context *rsc, uint32_t xoff, uint32_t lod, 109 uint32_t count, void *data, size_t sizeBytes) { 110 const size_t eSize = mHal.state.type->getElementSizeBytes(); 111 112 if ((count * eSize) != sizeBytes) { 113 ALOGE("Allocation::read called with mismatched size expected %zu, got %zu", 114 (count * eSize), sizeBytes); 115 mHal.state.type->dumpLOGV("type info"); 116 return; 117 } 118 119 rsc->mHal.funcs.allocation.read1D(rsc, this, xoff, lod, count, data, sizeBytes); 120} 121 122void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 123 uint32_t w, uint32_t h, void *data, size_t sizeBytes) { 124 const size_t eSize = mHal.state.elementSizeBytes; 125 const size_t lineSize = eSize * w; 126 127 if ((lineSize * h) != sizeBytes) { 128 ALOGE("Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes); 129 rsAssert(!"Allocation::read called with mismatched size"); 130 return; 131 } 132 133 rsc->mHal.funcs.allocation.read2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes); 134} 135 136void Allocation::read(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 137 uint32_t lod, RsAllocationCubemapFace face, 138 uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes) { 139} 140 141void Allocation::elementData(Context *rsc, uint32_t x, const void *data, 142 uint32_t cIdx, size_t sizeBytes) { 143 size_t eSize = mHal.state.elementSizeBytes; 144 145 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 146 ALOGE("Error Allocation::subElementData component %i out of range.", cIdx); 147 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 148 return; 149 } 150 151 if (x >= mHal.state.dimensionX) { 152 ALOGE("Error Allocation::subElementData X offset %i out of range.", x); 153 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 154 return; 155 } 156 157 const Element * e = mHal.state.type->getElement()->getField(cIdx); 158 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 159 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 160 ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes()); 161 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 162 return; 163 } 164 165 rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes); 166 sendDirty(rsc); 167} 168 169void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, 170 const void *data, uint32_t cIdx, size_t sizeBytes) { 171 size_t eSize = mHal.state.elementSizeBytes; 172 173 if (x >= mHal.state.dimensionX) { 174 ALOGE("Error Allocation::subElementData X offset %i out of range.", x); 175 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 176 return; 177 } 178 179 if (y >= mHal.state.dimensionY) { 180 ALOGE("Error Allocation::subElementData X offset %i out of range.", x); 181 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 182 return; 183 } 184 185 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { 186 ALOGE("Error Allocation::subElementData component %i out of range.", cIdx); 187 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 188 return; 189 } 190 191 const Element * e = mHal.state.type->getElement()->getField(cIdx); 192 uint32_t elemArraySize = mHal.state.type->getElement()->getFieldArraySize(cIdx); 193 if (sizeBytes != e->getSizeBytes() * elemArraySize) { 194 ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes()); 195 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 196 return; 197 } 198 199 rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, sizeBytes); 200 sendDirty(rsc); 201} 202 203void Allocation::dumpLOGV(const char *prefix) const { 204 ObjectBase::dumpLOGV(prefix); 205 206 String8 s(prefix); 207 s.append(" type "); 208 if (mHal.state.type) { 209 mHal.state.type->dumpLOGV(s.string()); 210 } 211 212 ALOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x", 213 prefix, mHal.drvState.mallocPtrLOD0, mHal.state.usageFlags, mHal.state.mipmapControl); 214} 215 216uint32_t Allocation::getPackedSize() const { 217 uint32_t numItems = mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes(); 218 return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded(); 219} 220 221void Allocation::writePackedData(Context *rsc, const Type *type, 222 uint8_t *dst, const uint8_t *src, bool dstPadded) { 223 const Element *elem = type->getElement(); 224 uint32_t unpaddedBytes = elem->getSizeBytesUnpadded(); 225 uint32_t paddedBytes = elem->getSizeBytes(); 226 uint32_t numItems = type->getSizeBytes() / paddedBytes; 227 228 uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes; 229 uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes; 230 231 // no sub-elements 232 uint32_t fieldCount = elem->getFieldCount(); 233 if (fieldCount == 0) { 234 for (uint32_t i = 0; i < numItems; i ++) { 235 memcpy(dst, src, unpaddedBytes); 236 src += srcInc; 237 dst += dstInc; 238 } 239 return; 240 } 241 242 // Cache offsets 243 uint32_t *offsetsPadded = new uint32_t[fieldCount]; 244 uint32_t *offsetsUnpadded = new uint32_t[fieldCount]; 245 uint32_t *sizeUnpadded = new uint32_t[fieldCount]; 246 247 for (uint32_t i = 0; i < fieldCount; i++) { 248 offsetsPadded[i] = elem->getFieldOffsetBytes(i); 249 offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i); 250 sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded(); 251 } 252 253 uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded; 254 uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded; 255 256 // complex elements, need to copy subelem after subelem 257 for (uint32_t i = 0; i < numItems; i ++) { 258 for (uint32_t fI = 0; fI < fieldCount; fI++) { 259 memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]); 260 } 261 src += srcInc; 262 dst += dstInc; 263 } 264 265 delete[] offsetsPadded; 266 delete[] offsetsUnpadded; 267 delete[] sizeUnpadded; 268} 269 270void Allocation::unpackVec3Allocation(Context *rsc, const void *data, size_t dataSize) { 271 const uint8_t *src = (const uint8_t*)data; 272 uint8_t *dst = (uint8_t *)rsc->mHal.funcs.allocation.lock1D(rsc, this); 273 274 writePackedData(rsc, getType(), dst, src, true); 275 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 276} 277 278void Allocation::packVec3Allocation(Context *rsc, OStream *stream) const { 279 uint32_t paddedBytes = getType()->getElement()->getSizeBytes(); 280 uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded(); 281 uint32_t numItems = mHal.state.type->getSizeBytes() / paddedBytes; 282 283 const uint8_t *src = (const uint8_t*)rsc->mHal.funcs.allocation.lock1D(rsc, this); 284 uint8_t *dst = new uint8_t[numItems * unpaddedBytes]; 285 286 writePackedData(rsc, getType(), dst, src, false); 287 stream->addByteArray(dst, getPackedSize()); 288 289 delete[] dst; 290 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 291} 292 293void Allocation::serialize(Context *rsc, OStream *stream) const { 294 // Need to identify ourselves 295 stream->addU32((uint32_t)getClassId()); 296 297 String8 name(getName()); 298 stream->addString(&name); 299 300 // First thing we need to serialize is the type object since it will be needed 301 // to initialize the class 302 mHal.state.type->serialize(rsc, stream); 303 304 uint32_t dataSize = mHal.state.type->getSizeBytes(); 305 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 306 uint32_t packedSize = getPackedSize(); 307 // Write how much data we are storing 308 stream->addU32(packedSize); 309 if (dataSize == packedSize) { 310 // Now write the data 311 stream->addByteArray(rsc->mHal.funcs.allocation.lock1D(rsc, this), dataSize); 312 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 313 } else { 314 // Now write the data 315 packVec3Allocation(rsc, stream); 316 } 317} 318 319Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { 320 // First make sure we are reading the correct object 321 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 322 if (classID != RS_A3D_CLASS_ID_ALLOCATION) { 323 ALOGE("allocation loading skipped due to invalid class id\n"); 324 return NULL; 325 } 326 327 String8 name; 328 stream->loadString(&name); 329 330 Type *type = Type::createFromStream(rsc, stream); 331 if (!type) { 332 return NULL; 333 } 334 type->compute(); 335 336 Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); 337 type->decUserRef(); 338 339 // Number of bytes we wrote out for this allocation 340 uint32_t dataSize = stream->loadU32(); 341 // 3 element vectors are padded to 4 in memory, but padding isn't serialized 342 uint32_t packedSize = alloc->getPackedSize(); 343 if (dataSize != type->getSizeBytes() && 344 dataSize != packedSize) { 345 ALOGE("failed to read allocation because numbytes written is not the same loaded type wants\n"); 346 ObjectBase::checkDelete(alloc); 347 ObjectBase::checkDelete(type); 348 return NULL; 349 } 350 351 alloc->setName(name.string(), name.size()); 352 353 if (dataSize == type->getSizeBytes()) { 354 uint32_t count = dataSize / type->getElementSizeBytes(); 355 // Read in all of our allocation data 356 alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize); 357 } else { 358 alloc->unpackVec3Allocation(rsc, stream->getPtr() + stream->getPos(), dataSize); 359 } 360 stream->reset(stream->getPos() + dataSize); 361 362 return alloc; 363} 364 365void Allocation::sendDirty(const Context *rsc) const { 366 mRSC->mHal.funcs.allocation.markDirty(rsc, this); 367} 368 369void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const { 370 mHal.state.type->incRefs(ptr, ct, startOff); 371} 372 373void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const { 374 if (!mHal.state.hasReferences || !getIsScript()) { 375 return; 376 } 377 mHal.state.type->decRefs(ptr, ct, startOff); 378} 379 380void Allocation::freeChildrenUnlocked () { 381 void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this); 382 decRefs(ptr, mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes(), 0); 383 mRSC->mHal.funcs.allocation.unlock1D(mRSC, this); 384} 385 386bool Allocation::freeChildren() { 387 if (mHal.state.hasReferences) { 388 incSysRef(); 389 freeChildrenUnlocked(); 390 return decSysRef(); 391 } 392 return false; 393} 394 395void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) { 396} 397 398void Allocation::resize1D(Context *rsc, uint32_t dimX) { 399 uint32_t oldDimX = mHal.state.dimensionX; 400 if (dimX == oldDimX) { 401 return; 402 } 403 404 ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX); 405 if (dimX < oldDimX) { 406 decRefs(rsc->mHal.funcs.allocation.lock1D(rsc, this), oldDimX - dimX, dimX); 407 rsc->mHal.funcs.allocation.unlock1D(rsc, this); 408 } 409 rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences); 410 setType(t.get()); 411 updateCache(); 412} 413 414void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) { 415 ALOGE("not implemented"); 416} 417 418///////////////// 419// 420 421namespace android { 422namespace renderscript { 423 424void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { 425 Allocation *a = static_cast<Allocation *>(va); 426 a->sendDirty(rsc); 427 a->syncAll(rsc, src); 428} 429 430void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) { 431 Allocation *alloc = static_cast<Allocation *>(va); 432 rsc->mHal.funcs.allocation.generateMipmaps(rsc, alloc); 433} 434 435void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 436 Allocation *a = static_cast<Allocation *>(va); 437 const Type * t = a->getType(); 438 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 439 t->getDimX(), t->getDimY(), data, sizeBytes); 440} 441 442void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, 443 uint32_t count, const void *data, size_t sizeBytes) { 444 Allocation *a = static_cast<Allocation *>(va); 445 a->data(rsc, xoff, lod, count, data, sizeBytes); 446} 447 448void rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face, 449 const void *data, size_t sizeBytes, size_t eoff) { 450 Allocation *a = static_cast<Allocation *>(va); 451 a->elementData(rsc, x, y, data, eoff, sizeBytes); 452} 453 454void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod, 455 const void *data, size_t sizeBytes, size_t eoff) { 456 Allocation *a = static_cast<Allocation *>(va); 457 a->elementData(rsc, x, data, eoff, sizeBytes); 458} 459 460void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, 461 uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { 462 Allocation *a = static_cast<Allocation *>(va); 463 a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes); 464} 465 466void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t sizeBytes) { 467 Allocation *a = static_cast<Allocation *>(va); 468 const Type * t = a->getType(); 469 if(t->getDimY()) { 470 a->read(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 471 t->getDimX(), t->getDimY(), data, sizeBytes); 472 } else { 473 a->read(rsc, 0, 0, t->getDimX(), data, sizeBytes); 474 } 475 476} 477 478void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) { 479 Allocation *a = static_cast<Allocation *>(va); 480 a->resize1D(rsc, dimX); 481} 482 483void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) { 484 Allocation *a = static_cast<Allocation *>(va); 485 a->resize2D(rsc, dimX, dimY); 486} 487 488RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype, 489 RsAllocationMipmapControl mips, 490 uint32_t usages, uint32_t ptr) { 491 Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips, (void *)ptr); 492 if (!alloc) { 493 return NULL; 494 } 495 alloc->incUserRef(); 496 return alloc; 497} 498 499RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, 500 RsAllocationMipmapControl mips, 501 const void *data, size_t sizeBytes, uint32_t usages) { 502 Type *t = static_cast<Type *>(vtype); 503 504 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0); 505 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 506 if (texAlloc == NULL) { 507 ALOGE("Memory allocation failure"); 508 return NULL; 509 } 510 511 texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 512 t->getDimX(), t->getDimY(), data, sizeBytes); 513 if (mips == RS_ALLOCATION_MIPMAP_FULL) { 514 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 515 } 516 517 texAlloc->sendDirty(rsc); 518 return texAlloc; 519} 520 521RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, 522 RsAllocationMipmapControl mips, 523 const void *data, size_t sizeBytes, uint32_t usages) { 524 Type *t = static_cast<Type *>(vtype); 525 526 // Cubemap allocation's faces should be Width by Width each. 527 // Source data should have 6 * Width by Width pixels 528 // Error checking is done in the java layer 529 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0); 530 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 531 if (texAlloc == NULL) { 532 ALOGE("Memory allocation failure"); 533 return NULL; 534 } 535 536 uint32_t faceSize = t->getDimX(); 537 uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes(); 538 uint32_t copySize = faceSize * t->getElementSizeBytes(); 539 540 uint8_t *sourcePtr = (uint8_t*)data; 541 for (uint32_t face = 0; face < 6; face ++) { 542 for (uint32_t dI = 0; dI < faceSize; dI ++) { 543 texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face, 544 t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize); 545 } 546 547 // Move the data pointer to the next cube face 548 sourcePtr += copySize; 549 } 550 551 if (mips == RS_ALLOCATION_MIPMAP_FULL) { 552 rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc); 553 } 554 555 texAlloc->sendDirty(rsc); 556 return texAlloc; 557} 558 559void rsi_AllocationCopy2DRange(Context *rsc, 560 RsAllocation dstAlloc, 561 uint32_t dstXoff, uint32_t dstYoff, 562 uint32_t dstMip, uint32_t dstFace, 563 uint32_t width, uint32_t height, 564 RsAllocation srcAlloc, 565 uint32_t srcXoff, uint32_t srcYoff, 566 uint32_t srcMip, uint32_t srcFace) { 567 Allocation *dst = static_cast<Allocation *>(dstAlloc); 568 Allocation *src= static_cast<Allocation *>(srcAlloc); 569 rsc->mHal.funcs.allocation.allocData2D(rsc, dst, dstXoff, dstYoff, dstMip, 570 (RsAllocationCubemapFace)dstFace, 571 width, height, 572 src, srcXoff, srcYoff,srcMip, 573 (RsAllocationCubemapFace)srcFace); 574} 575 576} 577} 578 579const void * rsaAllocationGetType(RsContext con, RsAllocation va) { 580 Allocation *a = static_cast<Allocation *>(va); 581 a->getType()->incUserRef(); 582 583 return a->getType(); 584} 585