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
19/**
20 * Only intended for use by generated reflected code.
21 *
22 **/
23public class AllocationAdapter extends Allocation {
24    AllocationAdapter(long id, RenderScript rs, Allocation alloc) {
25        super(id, rs, alloc.mType, alloc.mUsage);
26        mAdaptedAllocation = alloc;
27    }
28
29    long getID(RenderScript rs) {
30        throw new RSInvalidStateException(
31            "This operation is not supported with adapters at this time.");
32    }
33
34    /**
35     * @hide
36     */
37    public void subData(int xoff, FieldPacker fp) {
38        super.setFromFieldPacker(xoff, fp);
39    }
40    /**
41     * @hide
42     */
43    public void subElementData(int xoff, int component_number, FieldPacker fp) {
44        super.setFromFieldPacker(xoff, component_number, fp);
45    }
46    /**
47     * @hide
48     */
49    public void subData1D(int off, int count, int[] d) {
50        super.copy1DRangeFrom(off, count, d);
51    }
52    /**
53     * @hide
54     */
55    public void subData1D(int off, int count, short[] d) {
56        super.copy1DRangeFrom(off, count, d);
57    }
58    /**
59     * @hide
60     */
61    public void subData1D(int off, int count, byte[] d) {
62        super.copy1DRangeFrom(off, count, d);
63    }
64    /**
65     * @hide
66     */
67    public void subData1D(int off, int count, float[] d) {
68        super.copy1DRangeFrom(off, count, d);
69    }
70    /**
71     * @hide
72     */
73    public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
74        super.copy2DRangeFrom(xoff, yoff, w, h, d);
75    }
76    /**
77     * @hide
78     */
79    public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
80        super.copy2DRangeFrom(xoff, yoff, w, h, d);
81    }
82    /**
83     * @hide
84     */
85    public void readData(int[] d) {
86        super.copyTo(d);
87    }
88    /**
89     * @hide
90     */
91    public void readData(float[] d) {
92        super.copyTo(d);
93    }
94
95    void initLOD(int lod) {
96        if (lod < 0) {
97            throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ").");
98        }
99
100        int tx = mAdaptedAllocation.mType.getX();
101        int ty = mAdaptedAllocation.mType.getY();
102        int tz = mAdaptedAllocation.mType.getZ();
103
104        for (int ct=0; ct < lod; ct++) {
105            if ((tx==1) && (ty == 1) && (tz == 1)) {
106                throw new RSIllegalArgumentException("Attempting to set lod (" + lod + ") out of range.");
107            }
108
109            if (tx > 1) tx >>= 1;
110            if (ty > 1) ty >>= 1;
111            if (tz > 1) tz >>= 1;
112        }
113
114        mCurrentDimX = tx;
115        mCurrentDimY = ty;
116        mCurrentDimZ = tz;
117        mCurrentCount = mCurrentDimX;
118        if (mCurrentDimY > 1) {
119            mCurrentCount *= mCurrentDimY;
120        }
121        if (mCurrentDimZ > 1) {
122            mCurrentCount *= mCurrentDimZ;
123        }
124        mSelectedY = 0;
125        mSelectedZ = 0;
126    }
127
128    /**
129     * Set the active LOD.  The LOD must be within the range for the
130     * type being adapted.  The base allocation must have mipmaps.
131     *
132     * Because this changes the dimensions of the adapter the
133     * current Y and Z will be reset.
134     *
135     * @param lod The LOD to make active.
136     */
137    public void setLOD(int lod) {
138        if (!mAdaptedAllocation.getType().hasMipmaps()) {
139            throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps.");
140        }
141        if (!mConstrainedLOD) {
142            throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
143        }
144
145        initLOD(lod);
146    }
147
148    /**
149     * Set the active Face.  The base allocation must be of a type
150     * that includes faces.
151     *
152     * @param cf The face to make active.
153     */
154    public void setFace(Type.CubemapFace cf) {
155        if (!mAdaptedAllocation.getType().hasFaces()) {
156            throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces.");
157        }
158        if (!mConstrainedFace) {
159            throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps.");
160        }
161        if (cf == null) {
162            throw new RSIllegalArgumentException("Cannot set null face.");
163        }
164
165        mSelectedFace = cf;
166    }
167
168    /**
169     * Set the active Y.  The y value must be within the range for
170     * the allocation being adapted.  The base allocation must
171     * contain the Y dimension.
172     *
173     * @param y The y to make active.
174     */
175    public void setY(int y) {
176        if (mAdaptedAllocation.getType().getY() == 0) {
177            throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim.");
178        }
179        if (mAdaptedAllocation.getType().getY() <= y) {
180            throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation.");
181        }
182        if (!mConstrainedY) {
183            throw new RSInvalidStateException("Cannot set Y when the adapter includes Y.");
184        }
185
186        mSelectedY = y;
187    }
188
189    /**
190     * Set the active Z.  The z value must be within the range for
191     * the allocation being adapted.  The base allocation must
192     * contain the Z dimension.
193     *
194     * @param z The z to make active.
195     */
196    public void setZ(int z) {
197        if (mAdaptedAllocation.getType().getZ() == 0) {
198            throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim.");
199        }
200        if (mAdaptedAllocation.getType().getZ() <= z) {
201            throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation.");
202        }
203        if (!mConstrainedZ) {
204            throw new RSInvalidStateException("Cannot set Z when the adapter includes Z.");
205        }
206
207        mSelectedZ = z;
208    }
209
210    static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
211        rs.validate();
212        AllocationAdapter aa = new AllocationAdapter(0, rs, a);
213        aa.mConstrainedLOD = true;
214        aa.mConstrainedFace = true;
215        aa.mConstrainedY = true;
216        aa.mConstrainedZ = true;
217        aa.initLOD(0);
218        return aa;
219    }
220
221    static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
222        rs.validate();
223        AllocationAdapter aa = new AllocationAdapter(0, rs, a);
224        aa.mConstrainedLOD = true;
225        aa.mConstrainedFace = true;
226        aa.mConstrainedY = false;
227        aa.mConstrainedZ = true;
228        aa.initLOD(0);
229        return aa;
230    }
231
232
233    /**
234     * Override the Allocation resize.  Resizing adapters is not
235     * allowed and will throw a RSInvalidStateException.
236     *
237     * @param dimX ignored.
238     */
239    public synchronized void resize(int dimX) {
240        throw new RSInvalidStateException("Resize not allowed for Adapters.");
241    }
242
243}
244
245
246