Allocation.cpp revision 7b3e3093f745134345dadf89498ad16e1f9c0e71
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "RenderScript.h" 18 19using namespace android; 20using namespace RSC; 21 22void * Allocation::getIDSafe() const { 23 return getID(); 24} 25 26void Allocation::updateCacheInfo(sp<const Type> t) { 27 mCurrentDimX = t->getX(); 28 mCurrentDimY = t->getY(); 29 mCurrentDimZ = t->getZ(); 30 mCurrentCount = mCurrentDimX; 31 if (mCurrentDimY > 1) { 32 mCurrentCount *= mCurrentDimY; 33 } 34 if (mCurrentDimZ > 1) { 35 mCurrentCount *= mCurrentDimZ; 36 } 37} 38 39Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) : 40 BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0), 41 mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) { 42 43 if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT | 44 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 45 RS_ALLOCATION_USAGE_GRAPHICS_VERTEX | 46 RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS | 47 RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET | 48 RS_ALLOCATION_USAGE_IO_INPUT | 49 RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) { 50 ALOGE("Unknown usage specified."); 51 } 52 53 if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) { 54 mWriteAllowed = false; 55 if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT | 56 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 57 RS_ALLOCATION_USAGE_SCRIPT)) != 0) { 58 ALOGE("Invalid usage combination."); 59 } 60 } 61 62 mType = t; 63 mUsage = usage; 64 65 if (t.get() != NULL) { 66 updateCacheInfo(t); 67 } 68} 69 70void Allocation::validateIsInt32() { 71 RsDataType dt = mType->getElement()->getDataType(); 72 if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) { 73 return; 74 } 75 ALOGE("32 bit integer source does not match allocation type %i", dt); 76} 77 78void Allocation::validateIsInt16() { 79 RsDataType dt = mType->getElement()->getDataType(); 80 if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) { 81 return; 82 } 83 ALOGE("16 bit integer source does not match allocation type %i", dt); 84} 85 86void Allocation::validateIsInt8() { 87 RsDataType dt = mType->getElement()->getDataType(); 88 if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) { 89 return; 90 } 91 ALOGE("8 bit integer source does not match allocation type %i", dt); 92} 93 94void Allocation::validateIsFloat32() { 95 RsDataType dt = mType->getElement()->getDataType(); 96 if (dt == RS_TYPE_FLOAT_32) { 97 return; 98 } 99 ALOGE("32 bit float source does not match allocation type %i", dt); 100} 101 102void Allocation::validateIsObject() { 103 RsDataType dt = mType->getElement()->getDataType(); 104 if ((dt == RS_TYPE_ELEMENT) || 105 (dt == RS_TYPE_TYPE) || 106 (dt == RS_TYPE_ALLOCATION) || 107 (dt == RS_TYPE_SAMPLER) || 108 (dt == RS_TYPE_SCRIPT) || 109 (dt == RS_TYPE_MESH) || 110 (dt == RS_TYPE_PROGRAM_FRAGMENT) || 111 (dt == RS_TYPE_PROGRAM_VERTEX) || 112 (dt == RS_TYPE_PROGRAM_RASTER) || 113 (dt == RS_TYPE_PROGRAM_STORE)) { 114 return; 115 } 116 ALOGE("Object source does not match allocation type %i", dt); 117} 118 119void Allocation::updateFromNative() { 120 BaseObj::updateFromNative(); 121 122 const void *typeID = rsaAllocationGetType(mRS->getContext(), getID()); 123 if(typeID != NULL) { 124 sp<const Type> old = mType; 125 sp<Type> t = new Type((void *)typeID, mRS); 126 t->updateFromNative(); 127 updateCacheInfo(t); 128 mType = t; 129 } 130} 131 132void Allocation::syncAll(RsAllocationUsageType srcLocation) { 133 switch (srcLocation) { 134 case RS_ALLOCATION_USAGE_SCRIPT: 135 case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS: 136 case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE: 137 case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX: 138 break; 139 default: 140 ALOGE("Source must be exactly one usage type."); 141 } 142 rsAllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation); 143} 144 145void Allocation::ioSendOutput() { 146 if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) { 147 ALOGE("Can only send buffer if IO_OUTPUT usage specified."); 148 } 149 rsAllocationIoSend(mRS->getContext(), getID()); 150} 151 152void Allocation::ioGetInput() { 153 if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) { 154 ALOGE("Can only send buffer if IO_OUTPUT usage specified."); 155 } 156 rsAllocationIoReceive(mRS->getContext(), getID()); 157} 158 159void Allocation::generateMipmaps() { 160 rsAllocationGenerateMipmaps(mRS->getContext(), getID()); 161} 162 163void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) { 164 165 if(count < 1) { 166 ALOGE("Count must be >= 1."); 167 return; 168 } 169 if((off + count) > mCurrentCount) { 170 ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); 171 return; 172 } 173 174 rsAllocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, 175 count * mType->getElement()->getSizeBytes()); 176} 177 178void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) { 179 if(count < 1) { 180 ALOGE("Count must be >= 1."); 181 return; 182 } 183 if((off + count) > mCurrentCount) { 184 ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); 185 return; 186 } 187 188 rsAllocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, 189 count * mType->getElement()->getSizeBytes()); 190} 191 192void Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data, 193 uint32_t dataOff) { 194 195 rsAllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0, 196 mSelectedLOD, mSelectedFace, 197 count, 1, data->getIDSafe(), dataOff, 0, 198 data->mSelectedLOD, data->mSelectedFace); 199} 200 201void Allocation::copy1DFrom(const void* data) { 202 copy1DRangeFrom(0, mCurrentCount, data); 203} 204 205void Allocation::copy1DTo(void* data) { 206 copy1DRangeTo(0, mCurrentCount, data); 207} 208 209 210void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) { 211 if (mAdaptedAllocation != NULL) { 212 213 } else { 214 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 215 ALOGE("Updated region larger than allocation."); 216 } 217 } 218} 219 220void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 221 const void *data) { 222 validate2DRange(xoff, yoff, w, h); 223 rsAllocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 224 w, h, data, w * h * mType->getElement()->getSizeBytes()); 225} 226 227void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 228 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) { 229 validate2DRange(xoff, yoff, w, h); 230 rsAllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff, 231 mSelectedLOD, mSelectedFace, 232 w, h, data->getIDSafe(), dataXoff, dataYoff, 233 data->mSelectedLOD, data->mSelectedFace); 234} 235 236void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 237 void* data) { 238 validate2DRange(xoff, yoff, w, h); 239 rsAllocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 240 w, h, data, w * h * mType->getElement()->getSizeBytes()); 241} 242 243/* 244void resize(int dimX) { 245 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 246 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 247 } 248 mRS.nAllocationResize1D(getID(), dimX); 249 mRS.finish(); // Necessary because resize is fifoed and update is async. 250 251 int typeID = mRS.nAllocationGetType(getID()); 252 mType = new Type(typeID, mRS); 253 mType.updateFromNative(); 254 updateCacheInfo(mType); 255} 256 257void resize(int dimX, int dimY) { 258 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 259 throw new RSInvalidStateException( 260 "Resize only support for 2D allocations at this time."); 261 } 262 if (mType.getY() == 0) { 263 throw new RSInvalidStateException( 264 "Resize only support for 2D allocations at this time."); 265 } 266 mRS.nAllocationResize2D(getID(), dimX, dimY); 267 mRS.finish(); // Necessary because resize is fifoed and update is async. 268 269 int typeID = mRS.nAllocationGetType(getID()); 270 mType = new Type(typeID, mRS); 271 mType.updateFromNative(); 272 updateCacheInfo(mType); 273} 274*/ 275 276 277android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 278 RsAllocationMipmapControl mips, uint32_t usage) { 279 void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0); 280 if (id == 0) { 281 ALOGE("Allocation creation failed."); 282 return NULL; 283 } 284 return new Allocation(id, rs, type, usage); 285} 286 287android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 288 RsAllocationMipmapControl mips, uint32_t usage, 289 void *pointer) { 290 void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 291 (uint32_t)pointer); 292 if (id == 0) { 293 ALOGE("Allocation creation failed."); 294 } 295 return new Allocation(id, rs, type, usage); 296} 297 298android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 299 uint32_t usage) { 300 return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage); 301} 302 303android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e, 304 size_t count, uint32_t usage) { 305 Type::Builder b(rs, e); 306 b.setX(count); 307 sp<const Type> t = b.create(); 308 309 return createTyped(rs, t, usage); 310} 311 312android::sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e, 313 size_t x, size_t y, uint32_t usage) { 314 Type::Builder b(rs, e); 315 b.setX(x); 316 b.setY(y); 317 sp<const Type> t = b.create(); 318 319 return createTyped(rs, t, usage); 320} 321