blob: 9e28f7c5d0972c75cdb1fd650ec6c8d59c4dadc5 [file] [log] [blame]
Jason Sams49a05d72010-12-29 14:31:29 -08001/*
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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070019/**
Tim Murrayc11e25c2013-04-09 11:01:01 -070020 * Only intended for use by generated reflected code.
Jason Sams49a05d72010-12-29 14:31:29 -080021 *
22 **/
23public class AllocationAdapter extends Allocation {
Jason Sams46ba27e32015-02-06 17:45:15 -080024 Type mWindow;
25
26 AllocationAdapter(long id, RenderScript rs, Allocation alloc, Type t) {
Jason Samsba862d12011-07-07 15:24:42 -070027 super(id, rs, alloc.mType, alloc.mUsage);
28 mAdaptedAllocation = alloc;
Jason Sams46ba27e32015-02-06 17:45:15 -080029 mWindow = t;
Jason Sams49a05d72010-12-29 14:31:29 -080030 }
31
Jason Sams46ba27e32015-02-06 17:45:15 -080032 /*
Tim Murray460a0492013-11-19 12:45:54 -080033 long getID(RenderScript rs) {
Jason Sams48fe5342011-07-08 13:52:30 -070034 throw new RSInvalidStateException(
35 "This operation is not supported with adapters at this time.");
Jason Samsee2d8092011-06-21 16:42:42 -070036 }
Jason Sams46ba27e32015-02-06 17:45:15 -080037 */
Jason Sams49a05d72010-12-29 14:31:29 -080038
Jason Samsba862d12011-07-07 15:24:42 -070039 void initLOD(int lod) {
Jason Samsee2d8092011-06-21 16:42:42 -070040 if (lod < 0) {
41 throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ").");
42 }
43
Jason Samsba862d12011-07-07 15:24:42 -070044 int tx = mAdaptedAllocation.mType.getX();
45 int ty = mAdaptedAllocation.mType.getY();
46 int tz = mAdaptedAllocation.mType.getZ();
Jason Samsee2d8092011-06-21 16:42:42 -070047
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
Jason Samsba862d12011-07-07 15:24:42 -070058 mCurrentDimX = tx;
59 mCurrentDimY = ty;
60 mCurrentDimZ = tz;
61 mCurrentCount = mCurrentDimX;
62 if (mCurrentDimY > 1) {
63 mCurrentCount *= mCurrentDimY;
Jason Samsee2d8092011-06-21 16:42:42 -070064 }
Jason Samsba862d12011-07-07 15:24:42 -070065 if (mCurrentDimZ > 1) {
66 mCurrentCount *= mCurrentDimZ;
Jason Samsee2d8092011-06-21 16:42:42 -070067 }
Jason Samsba862d12011-07-07 15:24:42 -070068 mSelectedY = 0;
69 mSelectedZ = 0;
Jason Samsee2d8092011-06-21 16:42:42 -070070 }
71
Jason Sams46ba27e32015-02-06 17:45:15 -080072 private void updateOffsets() {
73 int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
74
75 if (mSelectedArray.length > 0) {
76 a1 = mSelectedArray[0];
77 }
78 if (mSelectedArray.length > 1) {
79 a2 = mSelectedArray[2];
80 }
81 if (mSelectedArray.length > 2) {
82 a3 = mSelectedArray[2];
83 }
84 if (mSelectedArray.length > 3) {
85 a4 = mSelectedArray[3];
86 }
87 mRS.nAllocationAdapterOffset(getID(mRS), mSelectedX, mSelectedY, mSelectedZ,
88 mSelectedLOD, mSelectedFace.mID, a1, a2, a3, a4);
89
90 }
91
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070092 /**
Jason Samsee2d8092011-06-21 16:42:42 -070093 * Set the active LOD. The LOD must be within the range for the
Jason Samsba862d12011-07-07 15:24:42 -070094 * type being adapted. The base allocation must have mipmaps.
95 *
96 * Because this changes the dimensions of the adapter the
97 * current Y and Z will be reset.
Jason Samsee2d8092011-06-21 16:42:42 -070098 *
99 * @param lod The LOD to make active.
100 */
Jason Sams49a05d72010-12-29 14:31:29 -0800101 public void setLOD(int lod) {
Jason Samsba862d12011-07-07 15:24:42 -0700102 if (!mAdaptedAllocation.getType().hasMipmaps()) {
Jason Samsee2d8092011-06-21 16:42:42 -0700103 throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps.");
104 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800105 if (mWindow.hasMipmaps()) {
Jason Samsee2d8092011-06-21 16:42:42 -0700106 throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
107 }
108
109 initLOD(lod);
Jason Sams46ba27e32015-02-06 17:45:15 -0800110 mSelectedLOD = lod;
111 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800112 }
113
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700114 /**
Jason Samsba862d12011-07-07 15:24:42 -0700115 * Set the active Face. The base allocation must be of a type
116 * that includes faces.
117 *
118 * @param cf The face to make active.
119 */
Jason Sams49a05d72010-12-29 14:31:29 -0800120 public void setFace(Type.CubemapFace cf) {
Jason Samsba862d12011-07-07 15:24:42 -0700121 if (!mAdaptedAllocation.getType().hasFaces()) {
122 throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces.");
123 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800124 if (mWindow.hasFaces()) {
125 throw new RSInvalidStateException("Cannot set face when the adapter includes faces.");
Jason Samsba862d12011-07-07 15:24:42 -0700126 }
127 if (cf == null) {
128 throw new RSIllegalArgumentException("Cannot set null face.");
129 }
130
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700131 mSelectedFace = cf;
Jason Sams46ba27e32015-02-06 17:45:15 -0800132 updateOffsets();
133 }
134
135
136 /**
137 * @hide
138 * Set the active X. The x value must be within the range for
139 * the allocation being adapted.
140 *
141 * @param x The x to make active.
142 */
143 public void setX(int x) {
144 if (mAdaptedAllocation.getType().getX() <= x) {
145 throw new RSInvalidStateException("Cannot set X greater than dimension of allocation.");
146 }
147 if (mWindow.getX() == mAdaptedAllocation.getType().getX()) {
148 throw new RSInvalidStateException("Cannot set X when the adapter includes X.");
149 }
150 if ((mWindow.getX() + x) >= mAdaptedAllocation.getType().getX()) {
151 throw new RSInvalidStateException("Cannot set (X + window) which would be larger than dimension of allocation.");
152 }
153
154 mSelectedX = x;
155 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800156 }
157
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700158 /**
Jason Samsba862d12011-07-07 15:24:42 -0700159 * Set the active Y. The y value must be within the range for
160 * the allocation being adapted. The base allocation must
161 * contain the Y dimension.
162 *
163 * @param y The y to make active.
164 */
Jason Sams49a05d72010-12-29 14:31:29 -0800165 public void setY(int y) {
Jason Samsba862d12011-07-07 15:24:42 -0700166 if (mAdaptedAllocation.getType().getY() == 0) {
167 throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim.");
168 }
169 if (mAdaptedAllocation.getType().getY() <= y) {
170 throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation.");
171 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800172 if (mWindow.getY() == mAdaptedAllocation.getType().getY()) {
Jason Samsba862d12011-07-07 15:24:42 -0700173 throw new RSInvalidStateException("Cannot set Y when the adapter includes Y.");
174 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800175 if ((mWindow.getY() + y) >= mAdaptedAllocation.getType().getY()) {
176 throw new RSInvalidStateException("Cannot set (Y + window) which would be larger than dimension of allocation.");
177 }
Jason Samsba862d12011-07-07 15:24:42 -0700178
179 mSelectedY = y;
Jason Sams46ba27e32015-02-06 17:45:15 -0800180 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800181 }
182
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700183 /**
Jason Samsba862d12011-07-07 15:24:42 -0700184 * Set the active Z. The z value must be within the range for
185 * the allocation being adapted. The base allocation must
186 * contain the Z dimension.
187 *
188 * @param z The z to make active.
189 */
Jason Sams49a05d72010-12-29 14:31:29 -0800190 public void setZ(int z) {
Jason Samsba862d12011-07-07 15:24:42 -0700191 if (mAdaptedAllocation.getType().getZ() == 0) {
192 throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim.");
193 }
194 if (mAdaptedAllocation.getType().getZ() <= z) {
195 throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation.");
196 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800197 if (mWindow.getZ() == mAdaptedAllocation.getType().getZ()) {
Jason Samsba862d12011-07-07 15:24:42 -0700198 throw new RSInvalidStateException("Cannot set Z when the adapter includes Z.");
199 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800200 if ((mWindow.getZ() + z) >= mAdaptedAllocation.getType().getZ()) {
201 throw new RSInvalidStateException("Cannot set (Z + window) which would be larger than dimension of allocation.");
202 }
Jason Samsba862d12011-07-07 15:24:42 -0700203
204 mSelectedZ = z;
Jason Sams46ba27e32015-02-06 17:45:15 -0800205 updateOffsets();
206 }
207
208 /**
209 * @hide
210 */
211 public void setArray(int arrayNum, int arrayVal) {
212 if (mAdaptedAllocation.getType().getArray(arrayNum) == 0) {
213 throw new RSInvalidStateException("Cannot set arrayNum when the allocation type does not include arrayNum dim.");
214 }
215 if (mAdaptedAllocation.getType().getArray(arrayNum) <= arrayVal) {
216 throw new RSInvalidStateException("Cannot set arrayNum greater than dimension of allocation.");
217 }
218 if (mWindow.getArray(arrayNum) == mAdaptedAllocation.getType().getArray(arrayNum)) {
219 throw new RSInvalidStateException("Cannot set arrayNum when the adapter includes arrayNum.");
220 }
221 if ((mWindow.getArray(arrayNum) + arrayVal) >= mAdaptedAllocation.getType().getArray(arrayNum)) {
222 throw new RSInvalidStateException("Cannot set (arrayNum + window) which would be larger than dimension of allocation.");
223 }
224
225 mSelectedArray[arrayNum] = arrayVal;
226 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800227 }
228
Jason Samsba862d12011-07-07 15:24:42 -0700229 static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
230 rs.validate();
Jason Sams46ba27e32015-02-06 17:45:15 -0800231 Type t = Type.createX(rs, a.getElement(), a.getType().getX());
232 return createTyped(rs, a, t);
Jason Samsba862d12011-07-07 15:24:42 -0700233 }
Jason Sams49a05d72010-12-29 14:31:29 -0800234
Jason Sams46ba27e32015-02-06 17:45:15 -0800235
Jason Sams49a05d72010-12-29 14:31:29 -0800236 static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
237 rs.validate();
Jason Sams46ba27e32015-02-06 17:45:15 -0800238 Type t = Type.createXY(rs, a.getElement(), a.getType().getX(), a.getType().getY());
239 return createTyped(rs, a, t);
Jason Sams49a05d72010-12-29 14:31:29 -0800240 }
241
Jason Sams46ba27e32015-02-06 17:45:15 -0800242 /**
243 * @hide
244 *
245 * Create an arbitrary window into the base allocation
246 * The type describes the shape of the window.
247 *
248 * Any dimensions present in the type must be equal or smaller
249 * to the dimensions in the source allocation. A dimension
250 * present in the allocation that is not present in the type
251 * will be constrained away with the selectors
252 *
253 * If a dimension is present in the type and allcation one of
254 * two things will happen
255 *
256 * If the type is smaller than the allocation a window will be
257 * created, the selected value in the adapter for that dimension
258 * will act as the base address and the type will describe the
259 * size of the view starting at that point.
260 *
261 * If the type and allocation dimension are of the same size
262 * then setting the selector for the dimension will be an error.
263 */
264 static public AllocationAdapter createTyped(RenderScript rs, Allocation a, Type t) {
265 rs.validate();
266
267 if (a.mAdaptedAllocation != null) {
268 throw new RSInvalidStateException("Adapters cannot be nested.");
269 }
270
271 if (!a.getType().getElement().equals(t.getElement())) {
272 throw new RSInvalidStateException("Element must match Allocation type.");
273 }
274
275 if (t.hasFaces() || t.hasMipmaps()) {
276 throw new RSInvalidStateException("Adapters do not support window types with Mipmaps or Faces.");
277 }
278
279 Type at = a.getType();
280 if ((t.getX() > at.getX()) ||
281 (t.getY() > at.getY()) ||
282 (t.getZ() > at.getZ()) ||
283 (t.getArrayCount() > at.getArrayCount())) {
284
285 throw new RSInvalidStateException("Type cannot have dimension larger than the source allocation.");
286 }
287
288 if (t.getArrayCount() > 0) {
289 for (int i = 0; i < t.getArray(i); i++) {
290 if (t.getArray(i) > at.getArray(i)) {
291 throw new RSInvalidStateException("Type cannot have dimension larger than the source allocation.");
292 }
293 }
294 }
295
296 // Create the object
297 long id = rs.nAllocationAdapterCreate(a.getID(rs), t.getID(rs));
298 if (id == 0) {
299 throw new RSRuntimeException("AllocationAdapter creation failed.");
300 }
301 return new AllocationAdapter(id, rs, a, t);
302 }
Jason Sams49a05d72010-12-29 14:31:29 -0800303
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700304 /**
Jason Samsba862d12011-07-07 15:24:42 -0700305 * Override the Allocation resize. Resizing adapters is not
306 * allowed and will throw a RSInvalidStateException.
307 *
308 * @param dimX ignored.
309 */
310 public synchronized void resize(int dimX) {
311 throw new RSInvalidStateException("Resize not allowed for Adapters.");
312 }
313
Jason Sams49a05d72010-12-29 14:31:29 -0800314}
315
316