blob: 77dd86a418f524017b8325c399e8e14856558c7a [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
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/**
Jason Sams49a05d72010-12-29 14:31:29 -080027 *
28 **/
29public class AllocationAdapter extends Allocation {
Jason Samsee2d8092011-06-21 16:42:42 -070030 private boolean mConstrainedLOD;
31 private boolean mConstrainedFace;
32 private boolean mConstrainedY;
33 private boolean mConstrainedZ;
34
Jason Sams49a05d72010-12-29 14:31:29 -080035 private int mSelectedDimX;
36 private int mSelectedDimY;
Jason Samsee2d8092011-06-21 16:42:42 -070037 private int mSelectedDimZ;
Jason Sams49a05d72010-12-29 14:31:29 -080038 private int mSelectedCount;
39 private Allocation mAlloc;
40
41 private int mSelectedLOD = 0;
Stephen Hines20fbd012011-06-16 17:44:53 -070042 private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
Jason Sams49a05d72010-12-29 14:31:29 -080043
44 AllocationAdapter(int id, RenderScript rs, Allocation alloc) {
45 super(id, rs, null, alloc.mUsage);
Jason Samsee2d8092011-06-21 16:42:42 -070046 mAlloc = alloc;
Jason Sams49a05d72010-12-29 14:31:29 -080047 }
48
49
Jason Samsee2d8092011-06-21 16:42:42 -070050 int getID() {
51 return mAlloc.getID();
52 }
53
Jason Sams49a05d72010-12-29 14:31:29 -080054 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 }
Jason Samsee2d8092011-06-21 16:42:42 -070064 subData1D(0, mAlloc.mType.getCount(), i);
Jason Sams49a05d72010-12-29 14:31:29 -080065 }
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) {
Jason Samsee2d8092011-06-21 16:42:42 -0700103 int eSize = mAlloc.mType.mElement.getSizeBytes();
Jason Sams49a05d72010-12-29 14:31:29 -0800104 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) {
Jason Samsee2d8092011-06-21 16:42:42 -0700117 if (component_number >= mAlloc.mType.mElement.mElements.length) {
Jason Sams49a05d72010-12-29 14:31:29 -0800118 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();
Jason Samsee2d8092011-06-21 16:42:42 -0700125 int eSize = mAlloc.mType.mElement.mElements[component_number].getSizeBytes();
Jason Sams49a05d72010-12-29 14:31:29 -0800126
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 }
Jason Samsee2d8092011-06-21 16:42:42 -0700143 if((off + count) > mSelectedCount) {
144 throw new RSIllegalArgumentException("Overflow, Available count " + mAlloc.mType.getCount() +
Jason Sams49a05d72010-12-29 14:31:29 -0800145 ", got " + count + " at offset " + off + ".");
146 }
147 if((len) < dataSize) {
Jason Samsee2d8092011-06-21 16:42:42 -0700148 throw new RSIllegalArgumentException("Array too small for allocation type. len = " +
149 len + ", dataSize = " + dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800150 }
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
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700174 /**
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
Jason Sams49a05d72010-12-29 14:31:29 -0800190
191 public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
192 mRS.validate();
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700193 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
194 w, h, d, d.length * 4);
Jason Sams49a05d72010-12-29 14:31:29 -0800195 }
196
197 public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
198 mRS.validate();
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700199 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);
Jason Sams49a05d72010-12-29 14:31:29 -0800222 }
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
Jason Samsee2d8092011-06-21 16:42:42 -0700234 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 */
Jason Sams49a05d72010-12-29 14:31:29 -0800270 public void setLOD(int lod) {
Jason Samsee2d8092011-06-21 16:42:42 -0700271 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);
Jason Sams49a05d72010-12-29 14:31:29 -0800279 }
280
281 public void setFace(Type.CubemapFace cf) {
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700282 mSelectedFace = cf;
Jason Sams49a05d72010-12-29 14:31:29 -0800283 }
284
285 public void setY(int y) {
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700286 mSelectedDimY = y;
Jason Sams49a05d72010-12-29 14:31:29 -0800287 }
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);
Jason Samsee2d8092011-06-21 16:42:42 -0700299 aa.mConstrainedLOD = true;
300 aa.mConstrainedFace = true;
301 aa.mConstrainedY = false;
302 aa.mConstrainedZ = true;
303 aa.initLOD(0);
Jason Sams49a05d72010-12-29 14:31:29 -0800304 return aa;
305 }
306
307
308}
309
310