rsAllocation.cpp revision 225afd317e101a7be5fe02c0a86361146ea89f05
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 566RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype) 567{ 568 const Type * type = static_cast<const Type *>(vtype); 569 570 Allocation * alloc = new Allocation(rsc, type); 571 alloc->incUserRef(); 572 return alloc; 573} 574 575RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count) 576{ 577 Type * type = new Type(rsc); 578 type->setDimX(count); 579 type->setElement(static_cast<Element *>(e)); 580 type->compute(); 581 return rsi_AllocationCreateTyped(rsc, type); 582} 583 584void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) 585{ 586 Allocation *alloc = static_cast<Allocation *>(va); 587 alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel); 588} 589 590void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) 591{ 592 Allocation *alloc = static_cast<Allocation *>(va); 593 alloc->deferedUploadToBufferObject(rsc); 594} 595 596static void mip565(const Adapter2D &out, const Adapter2D &in) 597{ 598 uint32_t w = out.getDimX(); 599 uint32_t h = out.getDimY(); 600 601 for (uint32_t y=0; y < h; y++) { 602 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y)); 603 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2)); 604 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1)); 605 606 for (uint32_t x=0; x < w; x++) { 607 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]); 608 oPtr ++; 609 i1 += 2; 610 i2 += 2; 611 } 612 } 613} 614 615static void mip8888(const Adapter2D &out, const Adapter2D &in) 616{ 617 uint32_t w = out.getDimX(); 618 uint32_t h = out.getDimY(); 619 620 for (uint32_t y=0; y < h; y++) { 621 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y)); 622 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2)); 623 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1)); 624 625 for (uint32_t x=0; x < w; x++) { 626 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]); 627 oPtr ++; 628 i1 += 2; 629 i2 += 2; 630 } 631 } 632} 633 634static void mip8(const Adapter2D &out, const Adapter2D &in) 635{ 636 uint32_t w = out.getDimX(); 637 uint32_t h = out.getDimY(); 638 639 for (uint32_t y=0; y < h; y++) { 640 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y)); 641 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2)); 642 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1)); 643 644 for (uint32_t x=0; x < w; x++) { 645 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f); 646 oPtr ++; 647 i1 += 2; 648 i2 += 2; 649 } 650 } 651} 652 653static void mip(const Adapter2D &out, const Adapter2D &in) 654{ 655 switch(out.getBaseType()->getElement()->getSizeBits()) { 656 case 32: 657 mip8888(out, in); 658 break; 659 case 16: 660 mip565(out, in); 661 break; 662 case 8: 663 mip8(out, in); 664 break; 665 666 } 667 668} 669 670typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count); 671 672static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) 673{ 674 memcpy(dst, src, count * 2); 675} 676static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) 677{ 678 memcpy(dst, src, count); 679} 680static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) 681{ 682 memcpy(dst, src, count * 4); 683} 684 685 686static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) 687{ 688 uint16_t *d = static_cast<uint16_t *>(dst); 689 const uint8_t *s = static_cast<const uint8_t *>(src); 690 691 while(count--) { 692 *d = rs888to565(s[0], s[1], s[2]); 693 d++; 694 s+= 3; 695 } 696} 697 698static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) 699{ 700 uint16_t *d = static_cast<uint16_t *>(dst); 701 const uint8_t *s = static_cast<const uint8_t *>(src); 702 703 while(count--) { 704 *d = rs888to565(s[0], s[1], s[2]); 705 d++; 706 s+= 4; 707 } 708} 709 710static ElementConverter_t pickConverter(const Element *dst, const Element *src) 711{ 712 GLenum srcGLType = src->getComponent().getGLType(); 713 GLenum srcGLFmt = src->getComponent().getGLFormat(); 714 GLenum dstGLType = dst->getComponent().getGLType(); 715 GLenum dstGLFmt = dst->getComponent().getGLFormat(); 716 717 if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) { 718 switch(dst->getSizeBytes()) { 719 case 4: 720 return elementConverter_cpy_32; 721 case 2: 722 return elementConverter_cpy_16; 723 case 1: 724 return elementConverter_cpy_8; 725 } 726 } 727 728 if (srcGLType == GL_UNSIGNED_BYTE && 729 srcGLFmt == GL_RGB && 730 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 731 dstGLFmt == GL_RGB) { 732 733 return elementConverter_888_to_565; 734 } 735 736 if (srcGLType == GL_UNSIGNED_BYTE && 737 srcGLFmt == GL_RGBA && 738 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 739 dstGLFmt == GL_RGB) { 740 741 return elementConverter_8888_to_565; 742 } 743 744 LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst); 745 LOGE("pickConverter, srcGLType = %x, srcGLFmt = %x", srcGLType, srcGLFmt); 746 LOGE("pickConverter, dstGLType = %x, dstGLFmt = %x", dstGLType, dstGLFmt); 747 src->dumpLOGV("SRC "); 748 dst->dumpLOGV("DST "); 749 return 0; 750} 751 752#ifndef ANDROID_RS_BUILD_FOR_HOST 753 754RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype, 755 void *bmp, void *callbackData, RsBitmapCallback_t callback) 756{ 757 const Type * type = static_cast<const Type *>(vtype); 758 Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback); 759 alloc->incUserRef(); 760 return alloc; 761} 762 763void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, RsElement _src, const void *data) 764{ 765 Allocation *texAlloc = static_cast<Allocation *>(va); 766 const Element *src = static_cast<const Element *>(_src); 767 const Element *dst = texAlloc->getType()->getElement(); 768 uint32_t w = texAlloc->getType()->getDimX(); 769 uint32_t h = texAlloc->getType()->getDimY(); 770 bool genMips = texAlloc->getType()->getDimLOD(); 771 772 ElementConverter_t cvt = pickConverter(dst, src); 773 if (cvt) { 774 cvt(texAlloc->getPtr(), data, w * h); 775 if (genMips) { 776 Adapter2D adapt(rsc, texAlloc); 777 Adapter2D adapt2(rsc, texAlloc); 778 for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { 779 adapt.setLOD(lod); 780 adapt2.setLOD(lod + 1); 781 mip(adapt2, adapt); 782 } 783 } 784 } else { 785 rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); 786 } 787} 788 789RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) 790{ 791 const Element *src = static_cast<const Element *>(_src); 792 const Element *dst = static_cast<const Element *>(_dst); 793 794 //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips); 795 RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD}; 796 uint32_t dimValues[] = {w, h, genMips}; 797 RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues); 798 799 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type); 800 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 801 if (texAlloc == NULL) { 802 LOGE("Memory allocation failure"); 803 return NULL; 804 } 805 806 ElementConverter_t cvt = pickConverter(dst, src); 807 if (cvt) { 808 cvt(texAlloc->getPtr(), data, w * h); 809 if (genMips) { 810 Adapter2D adapt(rsc, texAlloc); 811 Adapter2D adapt2(rsc, texAlloc); 812 for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { 813 adapt.setLOD(lod); 814 adapt2.setLOD(lod + 1); 815 mip(adapt2, adapt); 816 } 817 } 818 } else { 819 rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); 820 } 821 822 return texAlloc; 823} 824 825void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) 826{ 827 Allocation *a = static_cast<Allocation *>(va); 828 a->data(rsc, data, sizeBytes); 829} 830 831void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) 832{ 833 Allocation *a = static_cast<Allocation *>(va); 834 a->subData(rsc, xoff, count, data, sizeBytes); 835} 836 837void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) 838{ 839 Allocation *a = static_cast<Allocation *>(va); 840 a->subElementData(rsc, x, y, data, eoff, sizeBytes); 841} 842 843void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) 844{ 845 Allocation *a = static_cast<Allocation *>(va); 846 a->subElementData(rsc, x, data, eoff, sizeBytes); 847} 848 849void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) 850{ 851 Allocation *a = static_cast<Allocation *>(va); 852 a->subData(rsc, xoff, yoff, w, h, data, sizeBytes); 853} 854 855void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) 856{ 857 Allocation *a = static_cast<Allocation *>(va); 858 a->read(data); 859} 860 861void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) 862{ 863 Allocation *a = static_cast<Allocation *>(va); 864 a->resize1D(rsc, dimX); 865} 866 867void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) 868{ 869 Allocation *a = static_cast<Allocation *>(va); 870 a->resize2D(rsc, dimX, dimY); 871} 872 873const void* rsi_AllocationGetType(Context *rsc, RsAllocation va) 874{ 875 Allocation *a = static_cast<Allocation *>(va); 876 a->getType()->incUserRef(); 877 878 return a->getType(); 879} 880 881#endif //ANDROID_RS_BUILD_FOR_HOST 882 883} 884} 885