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