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 17 package android.renderscript; 18 19 /** 20 * Only intended for use by generated reflected code. 21 * 22 **/ 23 public class AllocationAdapter extends Allocation { 24 Type mWindow; 25 AllocationAdapter(long id, RenderScript rs, Allocation alloc, Type t)26 AllocationAdapter(long id, RenderScript rs, Allocation alloc, Type t) { 27 super(id, rs, alloc.mType, alloc.mUsage); 28 mAdaptedAllocation = alloc; 29 mWindow = t; 30 } 31 32 /* 33 long getID(RenderScript rs) { 34 throw new RSInvalidStateException( 35 "This operation is not supported with adapters at this time."); 36 } 37 */ 38 initLOD(int lod)39 void initLOD(int lod) { 40 if (lod < 0) { 41 throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ")."); 42 } 43 44 int tx = mAdaptedAllocation.mType.getX(); 45 int ty = mAdaptedAllocation.mType.getY(); 46 int tz = mAdaptedAllocation.mType.getZ(); 47 48 for (int ct=0; ct < lod; ct++) { 49 if ((tx==1) && (ty == 1) && (tz == 1)) { 50 throw new RSIllegalArgumentException("Attempting to set lod (" + lod + ") out of range."); 51 } 52 53 if (tx > 1) tx >>= 1; 54 if (ty > 1) ty >>= 1; 55 if (tz > 1) tz >>= 1; 56 } 57 58 mCurrentDimX = tx; 59 mCurrentDimY = ty; 60 mCurrentDimZ = tz; 61 mCurrentCount = mCurrentDimX; 62 if (mCurrentDimY > 1) { 63 mCurrentCount *= mCurrentDimY; 64 } 65 if (mCurrentDimZ > 1) { 66 mCurrentCount *= mCurrentDimZ; 67 } 68 mSelectedY = 0; 69 mSelectedZ = 0; 70 } 71 updateOffsets()72 private void updateOffsets() { 73 int a1 = 0, a2 = 0, a3 = 0, a4 = 0; 74 75 if (mSelectedArray != null) { 76 if (mSelectedArray.length > 0) { 77 a1 = mSelectedArray[0]; 78 } 79 if (mSelectedArray.length > 1) { 80 a2 = mSelectedArray[2]; 81 } 82 if (mSelectedArray.length > 2) { 83 a3 = mSelectedArray[2]; 84 } 85 if (mSelectedArray.length > 3) { 86 a4 = mSelectedArray[3]; 87 } 88 } 89 mRS.nAllocationAdapterOffset(getID(mRS), mSelectedX, mSelectedY, mSelectedZ, 90 mSelectedLOD, mSelectedFace.mID, a1, a2, a3, a4); 91 92 } 93 94 /** 95 * Set the active LOD. The LOD must be within the range for the 96 * type being adapted. The base allocation must have mipmaps. 97 * 98 * Because this changes the dimensions of the adapter the 99 * current Y and Z will be reset. 100 * 101 * @param lod The LOD to make active. 102 */ setLOD(int lod)103 public void setLOD(int lod) { 104 if (!mAdaptedAllocation.getType().hasMipmaps()) { 105 throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps."); 106 } 107 if (mWindow.hasMipmaps()) { 108 throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps."); 109 } 110 111 initLOD(lod); 112 mSelectedLOD = lod; 113 updateOffsets(); 114 } 115 116 /** 117 * Set the active Face. The base allocation must be of a type 118 * that includes faces. 119 * 120 * @param cf The face to make active. 121 */ setFace(Type.CubemapFace cf)122 public void setFace(Type.CubemapFace cf) { 123 if (!mAdaptedAllocation.getType().hasFaces()) { 124 throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces."); 125 } 126 if (mWindow.hasFaces()) { 127 throw new RSInvalidStateException("Cannot set face when the adapter includes faces."); 128 } 129 if (cf == null) { 130 throw new RSIllegalArgumentException("Cannot set null face."); 131 } 132 133 mSelectedFace = cf; 134 updateOffsets(); 135 } 136 137 138 /** 139 * 140 * Set the active X. The x value must be within the range for 141 * the allocation being adapted. 142 * 143 * @param x The x to make active. 144 */ setX(int x)145 public void setX(int x) { 146 if (mAdaptedAllocation.getType().getX() <= x) { 147 throw new RSInvalidStateException("Cannot set X greater than dimension of allocation."); 148 } 149 if (mWindow.getX() == mAdaptedAllocation.getType().getX()) { 150 throw new RSInvalidStateException("Cannot set X when the adapter includes X."); 151 } 152 if ((mWindow.getX() + x) >= mAdaptedAllocation.getType().getX()) { 153 throw new RSInvalidStateException("Cannot set (X + window) which would be larger than dimension of allocation."); 154 } 155 156 mSelectedX = x; 157 updateOffsets(); 158 } 159 160 /** 161 * Set the active Y. The y value must be within the range for 162 * the allocation being adapted. The base allocation must 163 * contain the Y dimension. 164 * 165 * @param y The y to make active. 166 */ setY(int y)167 public void setY(int y) { 168 if (mAdaptedAllocation.getType().getY() == 0) { 169 throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim."); 170 } 171 if (mAdaptedAllocation.getType().getY() <= y) { 172 throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation."); 173 } 174 if (mWindow.getY() == mAdaptedAllocation.getType().getY()) { 175 throw new RSInvalidStateException("Cannot set Y when the adapter includes Y."); 176 } 177 if ((mWindow.getY() + y) >= mAdaptedAllocation.getType().getY()) { 178 throw new RSInvalidStateException("Cannot set (Y + window) which would be larger than dimension of allocation."); 179 } 180 181 mSelectedY = y; 182 updateOffsets(); 183 } 184 185 /** 186 * Set the active Z. The z value must be within the range for 187 * the allocation being adapted. The base allocation must 188 * contain the Z dimension. 189 * 190 * @param z The z to make active. 191 */ setZ(int z)192 public void setZ(int z) { 193 if (mAdaptedAllocation.getType().getZ() == 0) { 194 throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim."); 195 } 196 if (mAdaptedAllocation.getType().getZ() <= z) { 197 throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation."); 198 } 199 if (mWindow.getZ() == mAdaptedAllocation.getType().getZ()) { 200 throw new RSInvalidStateException("Cannot set Z when the adapter includes Z."); 201 } 202 if ((mWindow.getZ() + z) >= mAdaptedAllocation.getType().getZ()) { 203 throw new RSInvalidStateException("Cannot set (Z + window) which would be larger than dimension of allocation."); 204 } 205 206 mSelectedZ = z; 207 updateOffsets(); 208 } 209 210 /** 211 * @hide 212 */ setArray(int arrayNum, int arrayVal)213 public void setArray(int arrayNum, int arrayVal) { 214 if (mAdaptedAllocation.getType().getArray(arrayNum) == 0) { 215 throw new RSInvalidStateException("Cannot set arrayNum when the allocation type does not include arrayNum dim."); 216 } 217 if (mAdaptedAllocation.getType().getArray(arrayNum) <= arrayVal) { 218 throw new RSInvalidStateException("Cannot set arrayNum greater than dimension of allocation."); 219 } 220 if (mWindow.getArray(arrayNum) == mAdaptedAllocation.getType().getArray(arrayNum)) { 221 throw new RSInvalidStateException("Cannot set arrayNum when the adapter includes arrayNum."); 222 } 223 if ((mWindow.getArray(arrayNum) + arrayVal) >= mAdaptedAllocation.getType().getArray(arrayNum)) { 224 throw new RSInvalidStateException("Cannot set (arrayNum + window) which would be larger than dimension of allocation."); 225 } 226 227 mSelectedArray[arrayNum] = arrayVal; 228 updateOffsets(); 229 } 230 create1D(RenderScript rs, Allocation a)231 static public AllocationAdapter create1D(RenderScript rs, Allocation a) { 232 rs.validate(); 233 Type t = Type.createX(rs, a.getElement(), a.getType().getX()); 234 return createTyped(rs, a, t); 235 } 236 237 create2D(RenderScript rs, Allocation a)238 static public AllocationAdapter create2D(RenderScript rs, Allocation a) { 239 rs.validate(); 240 Type t = Type.createXY(rs, a.getElement(), a.getType().getX(), a.getType().getY()); 241 return createTyped(rs, a, t); 242 } 243 244 /** 245 * 246 * 247 * Create an arbitrary window into the base allocation. 248 * The type describes the shape of the window. 249 * 250 * Any dimensions present in the type must be equal or smaller 251 * to the dimensions in the source allocation. A dimension 252 * present in the allocation that is not present in the type 253 * will be constrained away with the selectors. 254 * 255 * If a dimension is present in both the type and allocation, one of 256 * two things will happen. 257 * 258 * If the type is smaller than the allocation, a window will be 259 * created, the selected value in the adapter for that dimension 260 * will act as the base address, and the type will describe the 261 * size of the view starting at that point. 262 * 263 * If the type and allocation dimension are of the same size, 264 * then setting the selector for the dimension will be an error. 265 */ createTyped(RenderScript rs, Allocation a, Type t)266 static public AllocationAdapter createTyped(RenderScript rs, Allocation a, Type t) { 267 rs.validate(); 268 269 if (a.mAdaptedAllocation != null) { 270 throw new RSInvalidStateException("Adapters cannot be nested."); 271 } 272 273 if (!a.getType().getElement().equals(t.getElement())) { 274 throw new RSInvalidStateException("Element must match Allocation type."); 275 } 276 277 if (t.hasFaces() || t.hasMipmaps()) { 278 throw new RSInvalidStateException("Adapters do not support window types with Mipmaps or Faces."); 279 } 280 281 Type at = a.getType(); 282 if ((t.getX() > at.getX()) || 283 (t.getY() > at.getY()) || 284 (t.getZ() > at.getZ()) || 285 (t.getArrayCount() > at.getArrayCount())) { 286 287 throw new RSInvalidStateException("Type cannot have dimension larger than the source allocation."); 288 } 289 290 if (t.getArrayCount() > 0) { 291 for (int i = 0; i < t.getArray(i); i++) { 292 if (t.getArray(i) > at.getArray(i)) { 293 throw new RSInvalidStateException("Type cannot have dimension larger than the source allocation."); 294 } 295 } 296 } 297 298 // Create the object 299 long id = rs.nAllocationAdapterCreate(a.getID(rs), t.getID(rs)); 300 if (id == 0) { 301 throw new RSRuntimeException("AllocationAdapter creation failed."); 302 } 303 return new AllocationAdapter(id, rs, a, t); 304 } 305 306 /** 307 * Override the Allocation resize. Resizing adapters is not 308 * allowed and will throw a RSInvalidStateException. 309 * 310 * @param dimX ignored. 311 */ resize(int dimX)312 public synchronized void resize(int dimX) { 313 throw new RSInvalidStateException("Resize not allowed for Adapters."); 314 } 315 316 } 317 318 319