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