blob: 183726fb2fc6934f625edb593a215fdcc17e1aee [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
Jason Samsadd04be2015-02-25 16:42:00 -080075 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 }
Jason Sams46ba27e32015-02-06 17:45:15 -080088 }
89 mRS.nAllocationAdapterOffset(getID(mRS), mSelectedX, mSelectedY, mSelectedZ,
90 mSelectedLOD, mSelectedFace.mID, a1, a2, a3, a4);
91
92 }
93
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070094 /**
Jason Samsee2d8092011-06-21 16:42:42 -070095 * Set the active LOD. The LOD must be within the range for the
Jason Samsba862d12011-07-07 15:24:42 -070096 * 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.
Jason Samsee2d8092011-06-21 16:42:42 -0700100 *
101 * @param lod The LOD to make active.
102 */
Jason Sams49a05d72010-12-29 14:31:29 -0800103 public void setLOD(int lod) {
Jason Samsba862d12011-07-07 15:24:42 -0700104 if (!mAdaptedAllocation.getType().hasMipmaps()) {
Jason Samsee2d8092011-06-21 16:42:42 -0700105 throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps.");
106 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800107 if (mWindow.hasMipmaps()) {
Jason Samsee2d8092011-06-21 16:42:42 -0700108 throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
109 }
110
111 initLOD(lod);
Jason Sams46ba27e32015-02-06 17:45:15 -0800112 mSelectedLOD = lod;
113 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800114 }
115
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700116 /**
Jason Samsba862d12011-07-07 15:24:42 -0700117 * 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 */
Jason Sams49a05d72010-12-29 14:31:29 -0800122 public void setFace(Type.CubemapFace cf) {
Jason Samsba862d12011-07-07 15:24:42 -0700123 if (!mAdaptedAllocation.getType().hasFaces()) {
124 throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces.");
125 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800126 if (mWindow.hasFaces()) {
127 throw new RSInvalidStateException("Cannot set face when the adapter includes faces.");
Jason Samsba862d12011-07-07 15:24:42 -0700128 }
129 if (cf == null) {
130 throw new RSIllegalArgumentException("Cannot set null face.");
131 }
132
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700133 mSelectedFace = cf;
Jason Sams46ba27e32015-02-06 17:45:15 -0800134 updateOffsets();
135 }
136
137
138 /**
139 * @hide
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 */
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();
Jason Sams49a05d72010-12-29 14:31:29 -0800158 }
159
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700160 /**
Jason Samsba862d12011-07-07 15:24:42 -0700161 * 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 */
Jason Sams49a05d72010-12-29 14:31:29 -0800167 public void setY(int y) {
Jason Samsba862d12011-07-07 15:24:42 -0700168 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 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800174 if (mWindow.getY() == mAdaptedAllocation.getType().getY()) {
Jason Samsba862d12011-07-07 15:24:42 -0700175 throw new RSInvalidStateException("Cannot set Y when the adapter includes Y.");
176 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800177 if ((mWindow.getY() + y) >= mAdaptedAllocation.getType().getY()) {
178 throw new RSInvalidStateException("Cannot set (Y + window) which would be larger than dimension of allocation.");
179 }
Jason Samsba862d12011-07-07 15:24:42 -0700180
181 mSelectedY = y;
Jason Sams46ba27e32015-02-06 17:45:15 -0800182 updateOffsets();
Jason Sams49a05d72010-12-29 14:31:29 -0800183 }
184
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700185 /**
Jason Samsba862d12011-07-07 15:24:42 -0700186 * 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 */
Jason Sams49a05d72010-12-29 14:31:29 -0800192 public void setZ(int z) {
Jason Samsba862d12011-07-07 15:24:42 -0700193 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 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800199 if (mWindow.getZ() == mAdaptedAllocation.getType().getZ()) {
Jason Samsba862d12011-07-07 15:24:42 -0700200 throw new RSInvalidStateException("Cannot set Z when the adapter includes Z.");
201 }
Jason Sams46ba27e32015-02-06 17:45:15 -0800202 if ((mWindow.getZ() + z) >= mAdaptedAllocation.getType().getZ()) {
203 throw new RSInvalidStateException("Cannot set (Z + window) which would be larger than dimension of allocation.");
204 }
Jason Samsba862d12011-07-07 15:24:42 -0700205
206 mSelectedZ = z;
Jason Sams46ba27e32015-02-06 17:45:15 -0800207 updateOffsets();
208 }
209
210 /**
211 * @hide
212 */
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();
Jason Sams49a05d72010-12-29 14:31:29 -0800229 }
230
Jason Samsba862d12011-07-07 15:24:42 -0700231 static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
232 rs.validate();
Jason Sams46ba27e32015-02-06 17:45:15 -0800233 Type t = Type.createX(rs, a.getElement(), a.getType().getX());
234 return createTyped(rs, a, t);
Jason Samsba862d12011-07-07 15:24:42 -0700235 }
Jason Sams49a05d72010-12-29 14:31:29 -0800236
Jason Sams46ba27e32015-02-06 17:45:15 -0800237
Jason Sams49a05d72010-12-29 14:31:29 -0800238 static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
239 rs.validate();
Jason Sams46ba27e32015-02-06 17:45:15 -0800240 Type t = Type.createXY(rs, a.getElement(), a.getType().getX(), a.getType().getY());
241 return createTyped(rs, a, t);
Jason Sams49a05d72010-12-29 14:31:29 -0800242 }
243
Jason Sams46ba27e32015-02-06 17:45:15 -0800244 /**
245 * @hide
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 the type and allcation 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 */
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 }
Jason Sams49a05d72010-12-29 14:31:29 -0800305
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700306 /**
Jason Samsba862d12011-07-07 15:24:42 -0700307 * Override the Allocation resize. Resizing adapters is not
308 * allowed and will throw a RSInvalidStateException.
309 *
310 * @param dimX ignored.
311 */
312 public synchronized void resize(int dimX) {
313 throw new RSInvalidStateException("Resize not allowed for Adapters.");
314 }
315
Jason Sams49a05d72010-12-29 14:31:29 -0800316}
317
318