AllocationAdapter.java revision ee2d809ab099e67698a37f13a42d22eaa2251f77
1/* 2 * Copyright (C) 2008 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 17package android.renderscript; 18 19import android.content.res.Resources; 20import android.content.res.AssetManager; 21import android.graphics.Bitmap; 22import android.graphics.BitmapFactory; 23import android.util.Log; 24import android.util.TypedValue; 25 26/** 27 * 28 **/ 29public class AllocationAdapter extends Allocation { 30 private boolean mConstrainedLOD; 31 private boolean mConstrainedFace; 32 private boolean mConstrainedY; 33 private boolean mConstrainedZ; 34 35 private int mSelectedDimX; 36 private int mSelectedDimY; 37 private int mSelectedDimZ; 38 private int mSelectedCount; 39 private Allocation mAlloc; 40 41 private int mSelectedLOD = 0; 42 private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; 43 44 AllocationAdapter(int id, RenderScript rs, Allocation alloc) { 45 super(id, rs, null, alloc.mUsage); 46 mAlloc = alloc; 47 } 48 49 50 int getID() { 51 return mAlloc.getID(); 52 } 53 54 public void copyFrom(BaseObj[] d) { 55 mRS.validate(); 56 if (d.length != mSelectedCount) { 57 throw new RSIllegalArgumentException("Array size mismatch, allocation size = " + 58 mSelectedCount + ", array length = " + d.length); 59 } 60 int i[] = new int[d.length]; 61 for (int ct=0; ct < d.length; ct++) { 62 i[ct] = d[ct].getID(); 63 } 64 subData1D(0, mAlloc.mType.getCount(), i); 65 } 66 67 void validateBitmap(Bitmap b) { 68 mRS.validate(); 69 if(mSelectedDimX != b.getWidth() || 70 mSelectedDimY != b.getHeight()) { 71 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 72 } 73 } 74 75 public void copyFrom(int[] d) { 76 mRS.validate(); 77 subData1D(0, mSelectedCount, d); 78 } 79 public void copyFrom(short[] d) { 80 mRS.validate(); 81 subData1D(0, mSelectedCount, d); 82 } 83 public void copyFrom(byte[] d) { 84 mRS.validate(); 85 subData1D(0, mSelectedCount, d); 86 } 87 public void copyFrom(float[] d) { 88 mRS.validate(); 89 subData1D(0, mSelectedCount, d); 90 } 91 public void copyFrom(Bitmap b) { 92 validateBitmap(b); 93 mRS.nAllocationCopyFromBitmap(getID(), b); 94 } 95 96 public void copyTo(Bitmap b) { 97 validateBitmap(b); 98 mRS.nAllocationCopyToBitmap(getID(), b); 99 } 100 101 102 public void subData(int xoff, FieldPacker fp) { 103 int eSize = mAlloc.mType.mElement.getSizeBytes(); 104 final byte[] data = fp.getData(); 105 106 int count = data.length / eSize; 107 if ((eSize * count) != data.length) { 108 throw new RSIllegalArgumentException("Field packer length " + data.length + 109 " not divisible by element size " + eSize + "."); 110 } 111 data1DChecks(xoff, count, data.length, data.length); 112 mRS.nAllocationData1D(getID(), xoff, mSelectedLOD, count, data, data.length); 113 } 114 115 116 public void subElementData(int xoff, int component_number, FieldPacker fp) { 117 if (component_number >= mAlloc.mType.mElement.mElements.length) { 118 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 119 } 120 if(xoff < 0) { 121 throw new RSIllegalArgumentException("Offset must be >= 0."); 122 } 123 124 final byte[] data = fp.getData(); 125 int eSize = mAlloc.mType.mElement.mElements[component_number].getSizeBytes(); 126 127 if (data.length != eSize) { 128 throw new RSIllegalArgumentException("Field packer sizelength " + data.length + 129 " does not match component size " + eSize + "."); 130 } 131 132 mRS.nAllocationElementData1D(getID(), xoff, mSelectedLOD, component_number, data, data.length); 133 } 134 135 void data1DChecks(int off, int count, int len, int dataSize) { 136 mRS.validate(); 137 if(off < 0) { 138 throw new RSIllegalArgumentException("Offset must be >= 0."); 139 } 140 if(count < 1) { 141 throw new RSIllegalArgumentException("Count must be >= 1."); 142 } 143 if((off + count) > mSelectedCount) { 144 throw new RSIllegalArgumentException("Overflow, Available count " + mAlloc.mType.getCount() + 145 ", got " + count + " at offset " + off + "."); 146 } 147 if((len) < dataSize) { 148 throw new RSIllegalArgumentException("Array too small for allocation type. len = " + 149 len + ", dataSize = " + dataSize); 150 } 151 } 152 153 public void subData1D(int off, int count, int[] d) { 154 int dataSize = mAlloc.mType.mElement.getSizeBytes() * count; 155 data1DChecks(off, count, d.length * 4, dataSize); 156 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); 157 } 158 public void subData1D(int off, int count, short[] d) { 159 int dataSize = mAlloc.mType.mElement.getSizeBytes() * count; 160 data1DChecks(off, count, d.length * 2, dataSize); 161 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); 162 } 163 public void subData1D(int off, int count, byte[] d) { 164 int dataSize = mAlloc.mType.mElement.getSizeBytes() * count; 165 data1DChecks(off, count, d.length, dataSize); 166 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); 167 } 168 public void subData1D(int off, int count, float[] d) { 169 int dataSize = mAlloc.mType.mElement.getSizeBytes() * count; 170 data1DChecks(off, count, d.length * 4, dataSize); 171 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); 172 } 173 174 /** 175 * Copy part of an allocation from another allocation. 176 * 177 * @param off The offset of the first element to be copied. 178 * @param count The number of elements to be copied. 179 * @param data the source data allocation. 180 * @param dataOff off The offset of the first element in data to 181 * be copied. 182 */ 183 public void subData1D(int off, int count, AllocationAdapter data, int dataOff) { 184 mRS.nAllocationData2D(getID(), off, 0, 185 mSelectedLOD, mSelectedFace.mID, 186 count, 1, data.getID(), dataOff, 0, 187 data.mSelectedLOD, data.mSelectedFace.mID); 188 } 189 190 191 public void subData2D(int xoff, int yoff, int w, int h, int[] d) { 192 mRS.validate(); 193 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 194 w, h, d, d.length * 4); 195 } 196 197 public void subData2D(int xoff, int yoff, int w, int h, float[] d) { 198 mRS.validate(); 199 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 200 w, h, d, d.length * 4); 201 } 202 203 /** 204 * Copy a rectangular region into the allocation from another 205 * allocation. 206 * 207 * @param xoff X offset of the region to update. 208 * @param yoff Y offset of the region to update. 209 * @param w Width of the incoming region to update. 210 * @param h Height of the incoming region to update. 211 * @param data source allocation. 212 * @param dataXoff X offset in data of the region to update. 213 * @param dataYoff Y offset in data of the region to update. 214 */ 215 public void subData2D(int xoff, int yoff, int w, int h, 216 AllocationAdapter data, int dataXoff, int dataYoff) { 217 mRS.validate(); 218 mRS.nAllocationData2D(getID(), xoff, yoff, 219 mSelectedLOD, mSelectedFace.mID, 220 w, h, data.getID(), dataXoff, dataYoff, 221 data.mSelectedLOD, data.mSelectedFace.mID); 222 } 223 224 public void readData(int[] d) { 225 mRS.validate(); 226 mRS.nAllocationRead(getID(), d); 227 } 228 229 public void readData(float[] d) { 230 mRS.validate(); 231 mRS.nAllocationRead(getID(), d); 232 } 233 234 private void initLOD(int lod) { 235 if (lod < 0) { 236 throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ")."); 237 } 238 239 int tx = mAlloc.mType.getX(); 240 int ty = mAlloc.mType.getY(); 241 int tz = mAlloc.mType.getZ(); 242 243 for (int ct=0; ct < lod; ct++) { 244 if ((tx==1) && (ty == 1) && (tz == 1)) { 245 throw new RSIllegalArgumentException("Attempting to set lod (" + lod + ") out of range."); 246 } 247 248 if (tx > 1) tx >>= 1; 249 if (ty > 1) ty >>= 1; 250 if (tz > 1) tz >>= 1; 251 } 252 253 mSelectedDimX = tx; 254 mSelectedDimY = ty; 255 mSelectedCount = tx; 256 if (ty > 1) { 257 mSelectedCount *= ty; 258 } 259 if (tz > 1) { 260 mSelectedCount *= tz; 261 } 262 } 263 264 /** 265 * Set the active LOD. The LOD must be within the range for the 266 * type being adapted. 267 * 268 * @param lod The LOD to make active. 269 */ 270 public void setLOD(int lod) { 271 if (!mAlloc.getType().hasMipmaps()) { 272 throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps."); 273 } 274 if (!mConstrainedLOD) { 275 throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps."); 276 } 277 278 initLOD(lod); 279 } 280 281 public void setFace(Type.CubemapFace cf) { 282 mSelectedFace = cf; 283 } 284 285 public void setY(int y) { 286 mSelectedDimY = y; 287 } 288 289 public void setZ(int z) { 290 } 291 292 // creation 293 //static public AllocationAdapter create1D(RenderScript rs, Allocation a) { 294 //} 295 296 static public AllocationAdapter create2D(RenderScript rs, Allocation a) { 297 rs.validate(); 298 AllocationAdapter aa = new AllocationAdapter(0, rs, a); 299 aa.mConstrainedLOD = true; 300 aa.mConstrainedFace = true; 301 aa.mConstrainedY = false; 302 aa.mConstrainedZ = true; 303 aa.initLOD(0); 304 return aa; 305 } 306 307 308} 309 310 311