rsAllocation.cpp revision dc763f345db3e796efc28dc4b4d8edffda5a803e
1/* 2 * Copyright (C) 2009 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#ifndef ANDROID_RS_BUILD_FOR_HOST 17#include "rsContext.h" 18 19#include <GLES/gl.h> 20#include <GLES2/gl2.h> 21#include <GLES/glext.h> 22#else 23#include "rsContextHostStub.h" 24 25#include <OpenGL/gl.h> 26#include <OpenGl/glext.h> 27#endif 28 29#include "utils/StopWatch.h" 30 31using namespace android; 32using namespace android::renderscript; 33 34Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc) 35{ 36 init(rsc, type); 37 38 mPtr = malloc(mType->getSizeBytes()); 39 if (mType->getElement()->getHasReferences()) { 40 memset(mPtr, 0, mType->getSizeBytes()); 41 } 42 if (!mPtr) { 43 LOGE("Allocation::Allocation, alloc failure"); 44 } 45} 46 47Allocation::Allocation(Context *rsc, const Type *type, void *bmp, 48 void *callbackData, RsBitmapCallback_t callback) 49: ObjectBase(rsc) 50{ 51 init(rsc, type); 52 53 mPtr = bmp; 54 mUserBitmapCallback = callback; 55 mUserBitmapCallbackData = callbackData; 56} 57 58void Allocation::init(Context *rsc, const Type *type) 59{ 60 mPtr = NULL; 61 62 mCpuWrite = false; 63 mCpuRead = false; 64 mGpuWrite = false; 65 mGpuRead = false; 66 67 mReadWriteRatio = 0; 68 mUpdateSize = 0; 69 70 mIsTexture = false; 71 mTextureID = 0; 72 mIsVertexBuffer = false; 73 mBufferID = 0; 74 mUploadDefered = false; 75 76 mUserBitmapCallback = NULL; 77 mUserBitmapCallbackData = NULL; 78 79 mType.set(type); 80 rsAssert(type); 81 82 mPtr = NULL; 83} 84 85Allocation::~Allocation() 86{ 87 if (mUserBitmapCallback != NULL) { 88 mUserBitmapCallback(mUserBitmapCallbackData); 89 } else { 90 free(mPtr); 91 } 92 mPtr = NULL; 93 94 if (mBufferID) { 95 // Causes a SW crash.... 96 //LOGV(" mBufferID %i", mBufferID); 97 //glDeleteBuffers(1, &mBufferID); 98 //mBufferID = 0; 99 } 100 if (mTextureID) { 101 glDeleteTextures(1, &mTextureID); 102 mTextureID = 0; 103 } 104} 105 106void Allocation::setCpuWritable(bool) 107{ 108} 109 110void Allocation::setGpuWritable(bool) 111{ 112} 113 114void Allocation::setCpuReadable(bool) 115{ 116} 117 118void Allocation::setGpuReadable(bool) 119{ 120} 121 122bool Allocation::fixAllocation() 123{ 124 return false; 125} 126 127void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset) 128{ 129 rsAssert(lodOffset < mType->getLODCount()); 130 mIsTexture = true; 131 mTextureLOD = lodOffset; 132 mUploadDefered = true; 133 mTextureGenMipmap = !mType->getDimLOD() && genMipmap; 134} 135 136void Allocation::uploadToTexture(const Context *rsc) 137{ 138 //rsAssert(!mTextureId); 139 140 mIsTexture = true; 141 if (!rsc->checkDriver()) { 142 mUploadDefered = true; 143 return; 144 } 145 146 GLenum type = mType->getElement()->getComponent().getGLType(); 147 GLenum format = mType->getElement()->getComponent().getGLFormat(); 148 149 if (!type || !format) { 150 return; 151 } 152 153 bool isFirstUpload = false; 154 155 if (!mTextureID) { 156 glGenTextures(1, &mTextureID); 157 158 if (!mTextureID) { 159 // This should not happen, however, its likely the cause of the 160 // white sqare bug. 161 // Force a crash to 1: restart the app, 2: make sure we get a bugreport. 162 LOGE("Upload to texture failed to gen mTextureID"); 163 rsc->dumpDebug(); 164 mUploadDefered = true; 165 return; 166 } 167 isFirstUpload = true; 168 } 169 glBindTexture(GL_TEXTURE_2D, mTextureID); 170 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 171 172 Adapter2D adapt(getContext(), this); 173 for(uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { 174 adapt.setLOD(lod+mTextureLOD); 175 176 uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); 177 if(isFirstUpload) { 178 glTexImage2D(GL_TEXTURE_2D, lod, format, 179 adapt.getDimX(), adapt.getDimY(), 180 0, format, type, ptr); 181 } else { 182 glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0, 183 adapt.getDimX(), adapt.getDimY(), 184 format, type, ptr); 185 } 186 } 187 if (mTextureGenMipmap) { 188#ifndef ANDROID_RS_BUILD_FOR_HOST 189 glGenerateMipmap(GL_TEXTURE_2D); 190#endif //ANDROID_RS_BUILD_FOR_HOST 191 } 192 193 rsc->checkError("Allocation::uploadToTexture"); 194} 195 196void Allocation::deferedUploadToBufferObject(const Context *rsc) 197{ 198 mIsVertexBuffer = true; 199 mUploadDefered = true; 200} 201 202void Allocation::uploadToBufferObject(const Context *rsc) 203{ 204 rsAssert(!mType->getDimY()); 205 rsAssert(!mType->getDimZ()); 206 207 mIsVertexBuffer = true; 208 if (!rsc->checkDriver()) { 209 mUploadDefered = true; 210 return; 211 } 212 213 if (!mBufferID) { 214 glGenBuffers(1, &mBufferID); 215 } 216 if (!mBufferID) { 217 LOGE("Upload to buffer object failed"); 218 mUploadDefered = true; 219 return; 220 } 221 222 glBindBuffer(GL_ARRAY_BUFFER, mBufferID); 223 glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); 224 glBindBuffer(GL_ARRAY_BUFFER, 0); 225 rsc->checkError("Allocation::uploadToBufferObject"); 226} 227 228void Allocation::uploadCheck(const Context *rsc) 229{ 230 if (mUploadDefered) { 231 mUploadDefered = false; 232 if (mIsVertexBuffer) { 233 uploadToBufferObject(rsc); 234 } 235 if (mIsTexture) { 236 uploadToTexture(rsc); 237 } 238 } 239} 240 241 242void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) 243{ 244 uint32_t size = mType->getSizeBytes(); 245 if (size != sizeBytes) { 246 LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes); 247 return; 248 } 249 250 if (mType->getElement()->getHasReferences()) { 251 incRefs(data, sizeBytes / mType->getElement()->getSizeBytes()); 252 decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes()); 253 } 254 255 memcpy(mPtr, data, size); 256 sendDirty(); 257 mUploadDefered = true; 258} 259 260void Allocation::read(void *data) 261{ 262 memcpy(data, mPtr, mType->getSizeBytes()); 263} 264 265void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) 266{ 267 uint32_t eSize = mType->getElementSizeBytes(); 268 uint8_t * ptr = static_cast<uint8_t *>(mPtr); 269 ptr += eSize * xoff; 270 uint32_t size = count * eSize; 271 272 if (size != sizeBytes) { 273 LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes); 274 mType->dumpLOGV("type info"); 275 return; 276 } 277 278 if (mType->getElement()->getHasReferences()) { 279 incRefs(data, count); 280 decRefs(ptr, count); 281 } 282 283 memcpy(ptr, data, size); 284 sendDirty(); 285 mUploadDefered = true; 286} 287 288void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, 289 uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) 290{ 291 uint32_t eSize = mType->getElementSizeBytes(); 292 uint32_t lineSize = eSize * w; 293 uint32_t destW = mType->getDimX(); 294 295 const uint8_t *src = static_cast<const uint8_t *>(data); 296 uint8_t *dst = static_cast<uint8_t *>(mPtr); 297 dst += eSize * (xoff + yoff * destW); 298 299 if ((lineSize * eSize * h) != sizeBytes) { 300 rsAssert(!"Allocation::subData called with mismatched size"); 301 return; 302 } 303 304 for (uint32_t line=yoff; line < (yoff+h); line++) { 305 if (mType->getElement()->getHasReferences()) { 306 incRefs(src, w); 307 decRefs(dst, w); 308 } 309 memcpy(dst, src, lineSize); 310 src += lineSize; 311 dst += destW * eSize; 312 } 313 sendDirty(); 314 mUploadDefered = true; 315} 316 317void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, 318 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) 319{ 320} 321 322void Allocation::subElementData(Context *rsc, uint32_t x, const void *data, 323 uint32_t cIdx, uint32_t sizeBytes) 324{ 325 uint32_t eSize = mType->getElementSizeBytes(); 326 uint8_t * ptr = static_cast<uint8_t *>(mPtr); 327 ptr += eSize * x; 328 329 if (cIdx >= mType->getElement()->getFieldCount()) { 330 LOGE("Error Allocation::subElementData component %i out of range.", cIdx); 331 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 332 return; 333 } 334 335 if (x >= mType->getDimX()) { 336 LOGE("Error Allocation::subElementData X offset %i out of range.", x); 337 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 338 return; 339 } 340 341 const Element * e = mType->getElement()->getField(cIdx); 342 ptr += mType->getElement()->getFieldOffsetBytes(cIdx); 343 344 if (sizeBytes != e->getSizeBytes()) { 345 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes()); 346 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 347 return; 348 } 349 350 if (e->getHasReferences()) { 351 e->incRefs(data); 352 e->decRefs(ptr); 353 } 354 355 memcpy(ptr, data, sizeBytes); 356 sendDirty(); 357 mUploadDefered = true; 358} 359 360void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y, 361 const void *data, uint32_t cIdx, uint32_t sizeBytes) 362{ 363 uint32_t eSize = mType->getElementSizeBytes(); 364 uint8_t * ptr = static_cast<uint8_t *>(mPtr); 365 ptr += eSize * (x + y * mType->getDimX()); 366 367 if (x >= mType->getDimX()) { 368 LOGE("Error Allocation::subElementData X offset %i out of range.", x); 369 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 370 return; 371 } 372 373 if (y >= mType->getDimY()) { 374 LOGE("Error Allocation::subElementData X offset %i out of range.", x); 375 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range."); 376 return; 377 } 378 379 if (cIdx >= mType->getElement()->getFieldCount()) { 380 LOGE("Error Allocation::subElementData component %i out of range.", cIdx); 381 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range."); 382 return; 383 } 384 385 const Element * e = mType->getElement()->getField(cIdx); 386 ptr += mType->getElement()->getFieldOffsetBytes(cIdx); 387 388 if (sizeBytes != e->getSizeBytes()) { 389 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes()); 390 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); 391 return; 392 } 393 394 if (e->getHasReferences()) { 395 e->incRefs(data); 396 e->decRefs(ptr); 397 } 398 399 memcpy(ptr, data, sizeBytes); 400 sendDirty(); 401 mUploadDefered = true; 402} 403 404void Allocation::addProgramToDirty(const Program *p) 405{ 406 mToDirtyList.push(p); 407} 408 409void Allocation::removeProgramToDirty(const Program *p) 410{ 411 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 412 if (mToDirtyList[ct] == p) { 413 mToDirtyList.removeAt(ct); 414 return; 415 } 416 } 417 rsAssert(0); 418} 419 420void Allocation::dumpLOGV(const char *prefix) const 421{ 422 ObjectBase::dumpLOGV(prefix); 423 424 String8 s(prefix); 425 s.append(" type "); 426 if (mType.get()) { 427 mType->dumpLOGV(s.string()); 428 } 429 430 LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i", 431 prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead); 432 433 LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i", 434 prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID); 435 436} 437 438void Allocation::serialize(OStream *stream) const 439{ 440 // Need to identify ourselves 441 stream->addU32((uint32_t)getClassId()); 442 443 String8 name(getName()); 444 stream->addString(&name); 445 446 // First thing we need to serialize is the type object since it will be needed 447 // to initialize the class 448 mType->serialize(stream); 449 450 uint32_t dataSize = mType->getSizeBytes(); 451 // Write how much data we are storing 452 stream->addU32(dataSize); 453 // Now write the data 454 stream->addByteArray(mPtr, dataSize); 455} 456 457Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) 458{ 459 // First make sure we are reading the correct object 460 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 461 if(classID != RS_A3D_CLASS_ID_ALLOCATION) { 462 LOGE("allocation loading skipped due to invalid class id\n"); 463 return NULL; 464 } 465 466 String8 name; 467 stream->loadString(&name); 468 469 Type *type = Type::createFromStream(rsc, stream); 470 if(!type) { 471 return NULL; 472 } 473 type->compute(); 474 475 // Number of bytes we wrote out for this allocation 476 uint32_t dataSize = stream->loadU32(); 477 if(dataSize != type->getSizeBytes()) { 478 LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n"); 479 ObjectBase::checkDelete(type); 480 return NULL; 481 } 482 483 Allocation *alloc = new Allocation(rsc, type); 484 alloc->setName(name.string(), name.size()); 485 486 // Read in all of our allocation data 487 alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize); 488 stream->reset(stream->getPos() + dataSize); 489 490 return alloc; 491} 492 493void Allocation::sendDirty() const 494{ 495 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 496 mToDirtyList[ct]->forceDirty(); 497 } 498} 499 500void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const 501{ 502 const uint8_t *p = static_cast<const uint8_t *>(ptr); 503 const Element *e = mType->getElement(); 504 uint32_t stride = e->getSizeBytes(); 505 506 p += stride * startOff; 507 while (ct > 0) { 508 e->incRefs(p); 509 ct --; 510 p += stride; 511 } 512} 513 514void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const 515{ 516 const uint8_t *p = static_cast<const uint8_t *>(ptr); 517 const Element *e = mType->getElement(); 518 uint32_t stride = e->getSizeBytes(); 519 520 p += stride * startOff; 521 while (ct > 0) { 522 e->decRefs(p); 523 ct --; 524 p += stride; 525 } 526} 527 528void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) 529{ 530} 531 532void Allocation::resize1D(Context *rsc, uint32_t dimX) 533{ 534 Type *t = mType->cloneAndResize1D(rsc, dimX); 535 536 uint32_t oldDimX = mType->getDimX(); 537 if (dimX == oldDimX) { 538 return; 539 } 540 541 if (dimX < oldDimX) { 542 decRefs(mPtr, oldDimX - dimX, dimX); 543 } 544 mPtr = realloc(mPtr, t->getSizeBytes()); 545 546 if (dimX > oldDimX) { 547 const Element *e = mType->getElement(); 548 uint32_t stride = e->getSizeBytes(); 549 memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX)); 550 } 551 mType.set(t); 552} 553 554void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) 555{ 556 LOGE("not implemented"); 557} 558 559///////////////// 560// 561 562 563namespace android { 564namespace renderscript { 565 566void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) 567{ 568 Allocation *alloc = static_cast<Allocation *>(va); 569 alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel); 570} 571 572void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) 573{ 574 Allocation *alloc = static_cast<Allocation *>(va); 575 alloc->deferedUploadToBufferObject(rsc); 576} 577 578static void mip565(const Adapter2D &out, const Adapter2D &in) 579{ 580 uint32_t w = out.getDimX(); 581 uint32_t h = out.getDimY(); 582 583 for (uint32_t y=0; y < h; y++) { 584 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y)); 585 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2)); 586 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1)); 587 588 for (uint32_t x=0; x < w; x++) { 589 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]); 590 oPtr ++; 591 i1 += 2; 592 i2 += 2; 593 } 594 } 595} 596 597static void mip8888(const Adapter2D &out, const Adapter2D &in) 598{ 599 uint32_t w = out.getDimX(); 600 uint32_t h = out.getDimY(); 601 602 for (uint32_t y=0; y < h; y++) { 603 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y)); 604 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2)); 605 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1)); 606 607 for (uint32_t x=0; x < w; x++) { 608 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]); 609 oPtr ++; 610 i1 += 2; 611 i2 += 2; 612 } 613 } 614} 615 616static void mip8(const Adapter2D &out, const Adapter2D &in) 617{ 618 uint32_t w = out.getDimX(); 619 uint32_t h = out.getDimY(); 620 621 for (uint32_t y=0; y < h; y++) { 622 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y)); 623 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2)); 624 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1)); 625 626 for (uint32_t x=0; x < w; x++) { 627 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f); 628 oPtr ++; 629 i1 += 2; 630 i2 += 2; 631 } 632 } 633} 634 635static void mip(const Adapter2D &out, const Adapter2D &in) 636{ 637 switch(out.getBaseType()->getElement()->getSizeBits()) { 638 case 32: 639 mip8888(out, in); 640 break; 641 case 16: 642 mip565(out, in); 643 break; 644 case 8: 645 mip8(out, in); 646 break; 647 648 } 649 650} 651 652typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count); 653 654static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) 655{ 656 memcpy(dst, src, count * 2); 657} 658static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) 659{ 660 memcpy(dst, src, count); 661} 662static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) 663{ 664 memcpy(dst, src, count * 4); 665} 666 667 668static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) 669{ 670 uint16_t *d = static_cast<uint16_t *>(dst); 671 const uint8_t *s = static_cast<const uint8_t *>(src); 672 673 while(count--) { 674 *d = rs888to565(s[0], s[1], s[2]); 675 d++; 676 s+= 3; 677 } 678} 679 680static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) 681{ 682 uint16_t *d = static_cast<uint16_t *>(dst); 683 const uint8_t *s = static_cast<const uint8_t *>(src); 684 685 while(count--) { 686 *d = rs888to565(s[0], s[1], s[2]); 687 d++; 688 s+= 4; 689 } 690} 691 692static ElementConverter_t pickConverter(const Element *dst, const Element *src) 693{ 694 GLenum srcGLType = src->getComponent().getGLType(); 695 GLenum srcGLFmt = src->getComponent().getGLFormat(); 696 GLenum dstGLType = dst->getComponent().getGLType(); 697 GLenum dstGLFmt = dst->getComponent().getGLFormat(); 698 699 if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) { 700 switch(dst->getSizeBytes()) { 701 case 4: 702 return elementConverter_cpy_32; 703 case 2: 704 return elementConverter_cpy_16; 705 case 1: 706 return elementConverter_cpy_8; 707 } 708 } 709 710 if (srcGLType == GL_UNSIGNED_BYTE && 711 srcGLFmt == GL_RGB && 712 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 713 dstGLFmt == GL_RGB) { 714 715 return elementConverter_888_to_565; 716 } 717 718 if (srcGLType == GL_UNSIGNED_BYTE && 719 srcGLFmt == GL_RGBA && 720 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 721 dstGLFmt == GL_RGB) { 722 723 return elementConverter_8888_to_565; 724 } 725 726 LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst); 727 LOGE("pickConverter, srcGLType = %x, srcGLFmt = %x", srcGLType, srcGLFmt); 728 LOGE("pickConverter, dstGLType = %x, dstGLFmt = %x", dstGLType, dstGLFmt); 729 src->dumpLOGV("SRC "); 730 dst->dumpLOGV("DST "); 731 return 0; 732} 733 734#ifndef ANDROID_RS_BUILD_FOR_HOST 735 736RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype, 737 void *bmp, void *callbackData, RsBitmapCallback_t callback) 738{ 739 const Type * type = static_cast<const Type *>(vtype); 740 Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback); 741 alloc->incUserRef(); 742 return alloc; 743} 744 745void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, RsElement _src, const void *data) 746{ 747 Allocation *texAlloc = static_cast<Allocation *>(va); 748 const Element *src = static_cast<const Element *>(_src); 749 const Element *dst = texAlloc->getType()->getElement(); 750 uint32_t w = texAlloc->getType()->getDimX(); 751 uint32_t h = texAlloc->getType()->getDimY(); 752 bool genMips = texAlloc->getType()->getDimLOD(); 753 754 ElementConverter_t cvt = pickConverter(dst, src); 755 if (cvt) { 756 cvt(texAlloc->getPtr(), data, w * h); 757 if (genMips) { 758 Adapter2D adapt(rsc, texAlloc); 759 Adapter2D adapt2(rsc, texAlloc); 760 for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { 761 adapt.setLOD(lod); 762 adapt2.setLOD(lod + 1); 763 mip(adapt2, adapt); 764 } 765 } 766 } else { 767 rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); 768 } 769} 770 771void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) 772{ 773 Allocation *a = static_cast<Allocation *>(va); 774 a->data(rsc, data, sizeBytes); 775} 776 777void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) 778{ 779 Allocation *a = static_cast<Allocation *>(va); 780 a->subData(rsc, xoff, count, data, sizeBytes); 781} 782 783void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) 784{ 785 Allocation *a = static_cast<Allocation *>(va); 786 a->subElementData(rsc, x, y, data, eoff, sizeBytes); 787} 788 789void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) 790{ 791 Allocation *a = static_cast<Allocation *>(va); 792 a->subElementData(rsc, x, data, eoff, sizeBytes); 793} 794 795void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) 796{ 797 Allocation *a = static_cast<Allocation *>(va); 798 a->subData(rsc, xoff, yoff, w, h, data, sizeBytes); 799} 800 801void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) 802{ 803 Allocation *a = static_cast<Allocation *>(va); 804 a->read(data); 805} 806 807void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) 808{ 809 Allocation *a = static_cast<Allocation *>(va); 810 a->resize1D(rsc, dimX); 811} 812 813void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) 814{ 815 Allocation *a = static_cast<Allocation *>(va); 816 a->resize2D(rsc, dimX, dimY); 817} 818 819#endif //ANDROID_RS_BUILD_FOR_HOST 820 821} 822} 823 824const void * rsaAllocationGetType(RsContext con, RsAllocation va) 825{ 826 Allocation *a = static_cast<Allocation *>(va); 827 a->getType()->incUserRef(); 828 829 return a->getType(); 830} 831 832RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype) 833{ 834 Context *rsc = static_cast<Context *>(con); 835 Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype)); 836 alloc->incUserRef(); 837 return alloc; 838} 839 840RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) 841{ 842 Context *rsc = static_cast<Context *>(con); 843 const Element *src = static_cast<const Element *>(_src); 844 const Element *dst = static_cast<const Element *>(_dst); 845 846 //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips); 847 RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD}; 848 uint32_t dimValues[] = {w, h, genMips}; 849 RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues); 850 851 RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type); 852 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 853 if (texAlloc == NULL) { 854 LOGE("Memory allocation failure"); 855 return NULL; 856 } 857 858 ElementConverter_t cvt = pickConverter(dst, src); 859 if (cvt) { 860 cvt(texAlloc->getPtr(), data, w * h); 861 if (genMips) { 862 Adapter2D adapt(rsc, texAlloc); 863 Adapter2D adapt2(rsc, texAlloc); 864 for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { 865 adapt.setLOD(lod); 866 adapt2.setLOD(lod + 1); 867 mip(adapt2, adapt); 868 } 869 } 870 } else { 871 rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); 872 } 873 874 return texAlloc; 875} 876