Allocation.cpp revision a423096c0d49e5cfe13a400b4323a76f89c6885c
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#include <rs.h> 19 20using namespace android; 21using namespace RSC; 22 23void * Allocation::getIDSafe() const { 24 return getID(); 25} 26 27void Allocation::updateCacheInfo(sp<const Type> t) { 28 mCurrentDimX = t->getX(); 29 mCurrentDimY = t->getY(); 30 mCurrentDimZ = t->getZ(); 31 mCurrentCount = mCurrentDimX; 32 if (mCurrentDimY > 1) { 33 mCurrentCount *= mCurrentDimY; 34 } 35 if (mCurrentDimZ > 1) { 36 mCurrentCount *= mCurrentDimZ; 37 } 38} 39 40Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) : 41 BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0), 42 mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) { 43 44 if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT | 45 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 46 RS_ALLOCATION_USAGE_GRAPHICS_VERTEX | 47 RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS | 48 RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET | 49 RS_ALLOCATION_USAGE_IO_INPUT | 50 RS_ALLOCATION_USAGE_IO_OUTPUT | 51 RS_ALLOCATION_USAGE_SHARED)) != 0) { 52 ALOGE("Unknown usage specified."); 53 } 54 55 if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) { 56 mWriteAllowed = false; 57 if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT | 58 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | 59 RS_ALLOCATION_USAGE_SCRIPT)) != 0) { 60 ALOGE("Invalid usage combination."); 61 } 62 } 63 64 mType = t; 65 mUsage = usage; 66 67 if (t.get() != NULL) { 68 updateCacheInfo(t); 69 } 70} 71 72void Allocation::validateIsInt32() { 73 RsDataType dt = mType->getElement()->getDataType(); 74 if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) { 75 return; 76 } 77 ALOGE("32 bit integer source does not match allocation type %i", dt); 78} 79 80void Allocation::validateIsInt16() { 81 RsDataType dt = mType->getElement()->getDataType(); 82 if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) { 83 return; 84 } 85 ALOGE("16 bit integer source does not match allocation type %i", dt); 86} 87 88void Allocation::validateIsInt8() { 89 RsDataType dt = mType->getElement()->getDataType(); 90 if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) { 91 return; 92 } 93 ALOGE("8 bit integer source does not match allocation type %i", dt); 94} 95 96void Allocation::validateIsFloat32() { 97 RsDataType dt = mType->getElement()->getDataType(); 98 if (dt == RS_TYPE_FLOAT_32) { 99 return; 100 } 101 ALOGE("32 bit float source does not match allocation type %i", dt); 102} 103 104void Allocation::validateIsObject() { 105 RsDataType dt = mType->getElement()->getDataType(); 106 if ((dt == RS_TYPE_ELEMENT) || 107 (dt == RS_TYPE_TYPE) || 108 (dt == RS_TYPE_ALLOCATION) || 109 (dt == RS_TYPE_SAMPLER) || 110 (dt == RS_TYPE_SCRIPT) || 111 (dt == RS_TYPE_MESH) || 112 (dt == RS_TYPE_PROGRAM_FRAGMENT) || 113 (dt == RS_TYPE_PROGRAM_VERTEX) || 114 (dt == RS_TYPE_PROGRAM_RASTER) || 115 (dt == RS_TYPE_PROGRAM_STORE)) { 116 return; 117 } 118 ALOGE("Object source does not match allocation type %i", dt); 119} 120 121void Allocation::updateFromNative() { 122 BaseObj::updateFromNative(); 123 124 const void *typeID = RS::dispatch->AllocationGetType(mRS->getContext(), getID()); 125 if(typeID != NULL) { 126 sp<const Type> old = mType; 127 sp<Type> t = new Type((void *)typeID, mRS); 128 t->updateFromNative(); 129 updateCacheInfo(t); 130 mType = t; 131 } 132} 133 134void Allocation::syncAll(RsAllocationUsageType srcLocation) { 135 switch (srcLocation) { 136 case RS_ALLOCATION_USAGE_SCRIPT: 137 case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS: 138 case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE: 139 case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX: 140 break; 141 default: 142 ALOGE("Source must be exactly one usage type."); 143 } 144 RS::dispatch->AllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation); 145} 146 147void Allocation::ioSendOutput() { 148#ifndef RS_COMPATIBILITY_LIB 149 if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) { 150 ALOGE("Can only send buffer if IO_OUTPUT usage specified."); 151 } 152 RS::dispatch->AllocationIoSend(mRS->getContext(), getID()); 153#endif 154} 155 156void Allocation::ioGetInput() { 157#ifndef RS_COMPATIBILITY_LIB 158 if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) { 159 ALOGE("Can only send buffer if IO_OUTPUT usage specified."); 160 } 161 RS::dispatch->AllocationIoReceive(mRS->getContext(), getID()); 162#endif 163} 164 165void Allocation::generateMipmaps() { 166 RS::dispatch->AllocationGenerateMipmaps(mRS->getContext(), getID()); 167} 168 169void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) { 170 171 if(count < 1) { 172 ALOGE("Count must be >= 1."); 173 return; 174 } 175 if((off + count) > mCurrentCount) { 176 ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); 177 return; 178 } 179 180 RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, 181 count * mType->getElement()->getSizeBytes()); 182} 183 184void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) { 185 if(count < 1) { 186 ALOGE("Count must be >= 1."); 187 return; 188 } 189 if((off + count) > mCurrentCount) { 190 ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); 191 return; 192 } 193 194 RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, 195 count * mType->getElement()->getSizeBytes()); 196} 197 198void Allocation::copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data, 199 uint32_t dataOff) { 200 201 RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0, 202 mSelectedLOD, mSelectedFace, 203 count, 1, data->getIDSafe(), dataOff, 0, 204 data->mSelectedLOD, data->mSelectedFace); 205} 206 207void Allocation::copy1DFrom(const void* data) { 208 copy1DRangeFrom(0, mCurrentCount, data); 209} 210 211void Allocation::copy1DTo(void* data) { 212 copy1DRangeTo(0, mCurrentCount, data); 213} 214 215 216void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) { 217 if (mAdaptedAllocation != NULL) { 218 219 } else { 220 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 221 ALOGE("Updated region larger than allocation."); 222 } 223 } 224} 225 226void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 227 const void *data) { 228 validate2DRange(xoff, yoff, w, h); 229 RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 230 w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes()); 231} 232 233void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 234 sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff) { 235 validate2DRange(xoff, yoff, w, h); 236 RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff, 237 mSelectedLOD, mSelectedFace, 238 w, h, data->getIDSafe(), dataXoff, dataYoff, 239 data->mSelectedLOD, data->mSelectedFace); 240} 241 242void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 243 void* data) { 244 validate2DRange(xoff, yoff, w, h); 245 RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 246 w, h, data, w * h * mType->getElement()->getSizeBytes(), w * mType->getElement()->getSizeBytes()); 247} 248 249void Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 250 const void *data, size_t stride) { 251 validate2DRange(xoff, yoff, w, h); 252 RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 253 w, h, data, w * h * mType->getElement()->getSizeBytes(), stride); 254} 255 256void Allocation::copy2DStridedFrom(const void* data, size_t stride) { 257 copy2DStridedFrom(0, 0, mCurrentDimX, mCurrentDimY, data, stride); 258} 259 260void Allocation::copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, 261 void *data, size_t stride) { 262 validate2DRange(xoff, yoff, w, h); 263 RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, 264 w, h, data, w * h * mType->getElement()->getSizeBytes(), stride); 265} 266 267void Allocation::copy2DStridedTo(void* data, size_t stride) { 268 copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride); 269} 270 271android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 272 RsAllocationMipmapControl mips, uint32_t usage) { 273 void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0); 274 if (id == 0) { 275 ALOGE("Allocation creation failed."); 276 return NULL; 277 } 278 return new Allocation(id, rs, type, usage); 279} 280 281android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 282 RsAllocationMipmapControl mips, uint32_t usage, 283 void *pointer) { 284 void *id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 285 (uintptr_t)pointer); 286 if (id == 0) { 287 ALOGE("Allocation creation failed."); 288 } 289 return new Allocation(id, rs, type, usage); 290} 291 292android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type, 293 uint32_t usage) { 294 return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage); 295} 296 297android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e, 298 size_t count, uint32_t usage) { 299 Type::Builder b(rs, e); 300 b.setX(count); 301 sp<const Type> t = b.create(); 302 303 return createTyped(rs, t, usage); 304} 305 306android::sp<Allocation> Allocation::createSized2D(sp<RS> rs, sp<const Element> e, 307 size_t x, size_t y, uint32_t usage) { 308 Type::Builder b(rs, e); 309 b.setX(x); 310 b.setY(y); 311 sp<const Type> t = b.create(); 312 313 return createTyped(rs, t, usage); 314} 315