rsAllocation.cpp revision 10e5e570bab66a6cd543c857b26c576795eb240f
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(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(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(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 uint8_t * ptr = static_cast<uint8_t *>(mPtr); 297 if (mType->getElement()->getHasReferences()) { 298 incRefs(src, w); 299 decRefs(dst, w); 300 } 301 memcpy(dst, src, lineSize); 302 src += lineSize; 303 dst += destW * eSize; 304 } 305 sendDirty(); 306 mUploadDefered = true; 307} 308 309void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff, 310 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) 311{ 312} 313 314void Allocation::addProgramToDirty(const Program *p) 315{ 316 mToDirtyList.push(p); 317} 318 319void Allocation::removeProgramToDirty(const Program *p) 320{ 321 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 322 if (mToDirtyList[ct] == p) { 323 mToDirtyList.removeAt(ct); 324 return; 325 } 326 } 327 rsAssert(0); 328} 329 330void Allocation::dumpLOGV(const char *prefix) const 331{ 332 ObjectBase::dumpLOGV(prefix); 333 334 String8 s(prefix); 335 s.append(" type "); 336 if (mType.get()) { 337 mType->dumpLOGV(s.string()); 338 } 339 340 LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i", 341 prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead); 342 343 LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i", 344 prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID); 345 346} 347 348void Allocation::serialize(OStream *stream) const 349{ 350 // Need to identify ourselves 351 stream->addU32((uint32_t)getClassId()); 352 353 String8 name(getName()); 354 stream->addString(&name); 355 356 // First thing we need to serialize is the type object since it will be needed 357 // to initialize the class 358 mType->serialize(stream); 359 360 uint32_t dataSize = mType->getSizeBytes(); 361 // Write how much data we are storing 362 stream->addU32(dataSize); 363 // Now write the data 364 stream->addByteArray(mPtr, dataSize); 365} 366 367Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) 368{ 369 // First make sure we are reading the correct object 370 RsA3DClassID classID = (RsA3DClassID)stream->loadU32(); 371 if(classID != RS_A3D_CLASS_ID_ALLOCATION) { 372 LOGE("allocation loading skipped due to invalid class id\n"); 373 return NULL; 374 } 375 376 String8 name; 377 stream->loadString(&name); 378 379 Type *type = Type::createFromStream(rsc, stream); 380 if(!type) { 381 return NULL; 382 } 383 type->compute(); 384 385 // Number of bytes we wrote out for this allocation 386 uint32_t dataSize = stream->loadU32(); 387 if(dataSize != type->getSizeBytes()) { 388 LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n"); 389 delete type; 390 return NULL; 391 } 392 393 Allocation *alloc = new Allocation(rsc, type); 394 alloc->setName(name.string(), name.size()); 395 396 // Read in all of our allocation data 397 alloc->data(stream->getPtr() + stream->getPos(), dataSize); 398 stream->reset(stream->getPos() + dataSize); 399 400 return alloc; 401} 402 403void Allocation::sendDirty() const 404{ 405 for (size_t ct=0; ct < mToDirtyList.size(); ct++) { 406 mToDirtyList[ct]->forceDirty(); 407 } 408} 409 410void Allocation::incRefs(const void *ptr, size_t ct) const 411{ 412 const uint8_t *p = static_cast<const uint8_t *>(ptr); 413 const Element *e = mType->getElement(); 414 uint32_t stride = e->getSizeBytes(); 415 416 while (ct > 0) { 417 e->incRefs(p); 418 ct --; 419 p += stride; 420 } 421} 422 423void Allocation::decRefs(const void *ptr, size_t ct) const 424{ 425 const uint8_t *p = static_cast<const uint8_t *>(ptr); 426 const Element *e = mType->getElement(); 427 uint32_t stride = e->getSizeBytes(); 428 429 while (ct > 0) { 430 e->decRefs(p); 431 ct --; 432 p += stride; 433 } 434} 435 436///////////////// 437// 438 439 440namespace android { 441namespace renderscript { 442 443RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype) 444{ 445 const Type * type = static_cast<const Type *>(vtype); 446 447 Allocation * alloc = new Allocation(rsc, type); 448 alloc->incUserRef(); 449 return alloc; 450} 451 452RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count) 453{ 454 Type * type = new Type(rsc); 455 type->setDimX(count); 456 type->setElement(static_cast<Element *>(e)); 457 type->compute(); 458 return rsi_AllocationCreateTyped(rsc, type); 459} 460 461void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) 462{ 463 Allocation *alloc = static_cast<Allocation *>(va); 464 alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel); 465} 466 467void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) 468{ 469 Allocation *alloc = static_cast<Allocation *>(va); 470 alloc->deferedUploadToBufferObject(rsc); 471} 472 473static void mip565(const Adapter2D &out, const Adapter2D &in) 474{ 475 uint32_t w = out.getDimX(); 476 uint32_t h = out.getDimY(); 477 478 for (uint32_t y=0; y < h; y++) { 479 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y)); 480 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2)); 481 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1)); 482 483 for (uint32_t x=0; x < w; x++) { 484 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]); 485 oPtr ++; 486 i1 += 2; 487 i2 += 2; 488 } 489 } 490} 491 492static void mip8888(const Adapter2D &out, const Adapter2D &in) 493{ 494 uint32_t w = out.getDimX(); 495 uint32_t h = out.getDimY(); 496 497 for (uint32_t y=0; y < h; y++) { 498 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y)); 499 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2)); 500 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1)); 501 502 for (uint32_t x=0; x < w; x++) { 503 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]); 504 oPtr ++; 505 i1 += 2; 506 i2 += 2; 507 } 508 } 509} 510 511static void mip8(const Adapter2D &out, const Adapter2D &in) 512{ 513 uint32_t w = out.getDimX(); 514 uint32_t h = out.getDimY(); 515 516 for (uint32_t y=0; y < h; y++) { 517 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y)); 518 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2)); 519 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1)); 520 521 for (uint32_t x=0; x < w; x++) { 522 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f); 523 oPtr ++; 524 i1 += 2; 525 i2 += 2; 526 } 527 } 528} 529 530static void mip(const Adapter2D &out, const Adapter2D &in) 531{ 532 switch(out.getBaseType()->getElement()->getSizeBits()) { 533 case 32: 534 mip8888(out, in); 535 break; 536 case 16: 537 mip565(out, in); 538 break; 539 case 8: 540 mip8(out, in); 541 break; 542 543 } 544 545} 546 547typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count); 548 549static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) 550{ 551 memcpy(dst, src, count * 2); 552} 553static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) 554{ 555 memcpy(dst, src, count); 556} 557static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) 558{ 559 memcpy(dst, src, count * 4); 560} 561 562 563static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) 564{ 565 uint16_t *d = static_cast<uint16_t *>(dst); 566 const uint8_t *s = static_cast<const uint8_t *>(src); 567 568 while(count--) { 569 *d = rs888to565(s[0], s[1], s[2]); 570 d++; 571 s+= 3; 572 } 573} 574 575static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) 576{ 577 uint16_t *d = static_cast<uint16_t *>(dst); 578 const uint8_t *s = static_cast<const uint8_t *>(src); 579 580 while(count--) { 581 *d = rs888to565(s[0], s[1], s[2]); 582 d++; 583 s+= 4; 584 } 585} 586 587static ElementConverter_t pickConverter(const Element *dst, const Element *src) 588{ 589 GLenum srcGLType = src->getComponent().getGLType(); 590 GLenum srcGLFmt = src->getComponent().getGLFormat(); 591 GLenum dstGLType = dst->getComponent().getGLType(); 592 GLenum dstGLFmt = dst->getComponent().getGLFormat(); 593 594 if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) { 595 switch(dst->getSizeBytes()) { 596 case 4: 597 return elementConverter_cpy_32; 598 case 2: 599 return elementConverter_cpy_16; 600 case 1: 601 return elementConverter_cpy_8; 602 } 603 } 604 605 if (srcGLType == GL_UNSIGNED_BYTE && 606 srcGLFmt == GL_RGB && 607 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 608 dstGLFmt == GL_RGB) { 609 610 return elementConverter_888_to_565; 611 } 612 613 if (srcGLType == GL_UNSIGNED_BYTE && 614 srcGLFmt == GL_RGBA && 615 dstGLType == GL_UNSIGNED_SHORT_5_6_5 && 616 dstGLFmt == GL_RGB) { 617 618 return elementConverter_8888_to_565; 619 } 620 621 LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst); 622 LOGE("pickConverter, srcGLType = %x, srcGLFmt = %x", srcGLType, srcGLFmt); 623 LOGE("pickConverter, dstGLType = %x, dstGLFmt = %x", dstGLType, dstGLFmt); 624 src->dumpLOGV("SRC "); 625 dst->dumpLOGV("DST "); 626 return 0; 627} 628 629#ifndef ANDROID_RS_BUILD_FOR_HOST 630 631RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype, 632 void *bmp, void *callbackData, RsBitmapCallback_t callback) 633{ 634 const Type * type = static_cast<const Type *>(vtype); 635 Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback); 636 alloc->incUserRef(); 637 return alloc; 638} 639 640RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) 641{ 642 const Element *src = static_cast<const Element *>(_src); 643 const Element *dst = static_cast<const Element *>(_dst); 644 645 // Check for pow2 on pre es 2.0 versions. 646 rsAssert(rsc->checkVersion2_0() || (!(w & (w-1)) && !(h & (h-1)))); 647 648 //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips); 649 rsi_TypeBegin(rsc, _dst); 650 rsi_TypeAdd(rsc, RS_DIMENSION_X, w); 651 rsi_TypeAdd(rsc, RS_DIMENSION_Y, h); 652 if (genMips) { 653 rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1); 654 } 655 RsType type = rsi_TypeCreate(rsc); 656 657 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type); 658 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc); 659 if (texAlloc == NULL) { 660 LOGE("Memory allocation failure"); 661 return NULL; 662 } 663 664 ElementConverter_t cvt = pickConverter(dst, src); 665 cvt(texAlloc->getPtr(), data, w * h); 666 667 if (genMips) { 668 Adapter2D adapt(rsc, texAlloc); 669 Adapter2D adapt2(rsc, texAlloc); 670 for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { 671 adapt.setLOD(lod); 672 adapt2.setLOD(lod + 1); 673 mip(adapt2, adapt); 674 } 675 } 676 677 return texAlloc; 678} 679 680RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) 681{ 682 const Element *srcE = static_cast<const Element *>(_src); 683 const Element *dstE = static_cast<const Element *>(_dst); 684 uint32_t w2 = rsHigherPow2(w); 685 uint32_t h2 = rsHigherPow2(h); 686 687 if ((w2 == w) && (h2 == h)) { 688 return rsi_AllocationCreateFromBitmap(rsc, w, h, _dst, _src, genMips, data); 689 } 690 691 uint32_t bpp = srcE->getSizeBytes(); 692 size_t size = w2 * h2 * bpp; 693 uint8_t *tmp = static_cast<uint8_t *>(malloc(size)); 694 memset(tmp, 0, size); 695 696 const uint8_t * src = static_cast<const uint8_t *>(data); 697 for (uint32_t y = 0; y < h; y++) { 698 uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp]; 699 memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp); 700 src += w * bpp; 701 } 702 703 RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp); 704 free(tmp); 705 return ret; 706} 707 708void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) 709{ 710 Allocation *a = static_cast<Allocation *>(va); 711 a->data(data, sizeBytes); 712} 713 714void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) 715{ 716 Allocation *a = static_cast<Allocation *>(va); 717 a->subData(xoff, count, data, sizeBytes); 718} 719 720void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) 721{ 722 Allocation *a = static_cast<Allocation *>(va); 723 a->subData(xoff, yoff, w, h, data, sizeBytes); 724} 725 726void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) 727{ 728 Allocation *a = static_cast<Allocation *>(va); 729 a->read(data); 730} 731 732const void* rsi_AllocationGetType(Context *rsc, RsAllocation va) 733{ 734 Allocation *a = static_cast<Allocation *>(va); 735 a->getType()->incUserRef(); 736 737 return a->getType(); 738} 739 740#endif //ANDROID_RS_BUILD_FOR_HOST 741 742} 743} 744