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