RenderScriptGL.java revision 9c4086a6765cca1eb215f9a307038544b295792b
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
19import java.lang.reflect.Field;
20
21import android.content.Context;
22import android.graphics.PixelFormat;
23import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
25import android.util.Config;
26import android.util.Log;
27import android.view.Surface;
28import android.view.SurfaceHolder;
29import android.view.SurfaceView;
30
31/**
32 * The Graphics derivitive of RenderScript.  Extends the basic context to add a
33 * root script which is the display window for graphical output.  When the
34 * system needs to update the display the currently bound root script will be
35 * called.  This script is expected to issue the rendering commands to repaint
36 * the screen.
37 **/
38public class RenderScriptGL extends RenderScript {
39    private Surface mSurface;
40    int mWidth;
41    int mHeight;
42
43    /**
44     * Class which is used to describe a pixel format for a graphical buffer.
45     * This is used to describe the intended format of the display surface.
46     *
47     * The configuration is described by pairs of minimum and preferred bit
48     * depths for each component within the config and additional structural
49     * information.
50     */
51    public static class SurfaceConfig {
52        int mDepthMin       = 0;
53        int mDepthPref      = 0;
54        int mStencilMin     = 0;
55        int mStencilPref    = 0;
56        int mColorMin       = 8;
57        int mColorPref      = 8;
58        int mAlphaMin       = 0;
59        int mAlphaPref      = 0;
60        int mSamplesMin     = 1;
61        int mSamplesPref    = 1;
62        float mSamplesQ     = 1.f;
63
64        public SurfaceConfig() {
65        }
66
67        public SurfaceConfig(SurfaceConfig sc) {
68            mDepthMin = sc.mDepthMin;
69            mDepthPref = sc.mDepthPref;
70            mStencilMin = sc.mStencilMin;
71            mStencilPref = sc.mStencilPref;
72            mColorMin = sc.mColorMin;
73            mColorPref = sc.mColorPref;
74            mAlphaMin = sc.mAlphaMin;
75            mAlphaPref = sc.mAlphaPref;
76            mSamplesMin = sc.mSamplesMin;
77            mSamplesPref = sc.mSamplesPref;
78            mSamplesQ = sc.mSamplesQ;
79        }
80
81        private void validateRange(int umin, int upref, int rmin, int rmax) {
82            if (umin < rmin || umin > rmax) {
83                throw new RSIllegalArgumentException("Minimum value provided out of range.");
84            }
85            if (upref < umin) {
86                throw new RSIllegalArgumentException("preferred must be >= Minimum.");
87            }
88        }
89
90        /**
91         * Set the per-component bit depth for color (red, green, blue).  This
92         * configures the surface for an unsigned integer buffer type.
93         *
94         * @param minimum
95         * @param preferred
96         */
97        public void setColor(int minimum, int preferred) {
98            validateRange(minimum, preferred, 5, 8);
99            mColorMin = minimum;
100            mColorPref = preferred;
101        }
102
103        /**
104         * Set the bit depth for alpha. This configures the surface for
105         * an unsigned integer buffer type.
106         *
107         * @param minimum
108         * @param preferred
109         */
110        public void setAlpha(int minimum, int preferred) {
111            validateRange(minimum, preferred, 0, 8);
112            mAlphaMin = minimum;
113            mAlphaPref = preferred;
114        }
115
116         /**
117         * Set the bit depth for the depth buffer. This configures the
118         * surface for an unsigned integer buffer type.  If a minimum of 0
119         * is specified then its possible no depth buffer will be
120         * allocated.
121         *
122         * @param minimum
123         * @param preferred
124         */
125        public void setDepth(int minimum, int preferred) {
126            validateRange(minimum, preferred, 0, 24);
127            mDepthMin = minimum;
128            mDepthPref = preferred;
129        }
130
131        /**
132         * Configure the multisample rendering.
133         *
134         * @param minimum The required number of samples, must be at least 1.
135         * @param preferred The targe number of samples, must be at least
136         *                  minimum
137         * @param Q  The quality of samples, range 0-1.  Used to decide between
138         *           different formats which have the same number of samples but
139         *           different rendering quality.
140         */
141        public void setSamples(int minimum, int preferred, float Q) {
142            validateRange(minimum, preferred, 1, 32);
143            if (Q < 0.0f || Q > 1.0f) {
144                throw new RSIllegalArgumentException("Quality out of 0-1 range.");
145            }
146            mSamplesMin = minimum;
147            mSamplesPref = preferred;
148            mSamplesQ = Q;
149        }
150    };
151
152    SurfaceConfig mSurfaceConfig;
153
154    /**
155     * Construct a new RenderScriptGL context.
156     *
157     * @param ctx The context.
158     * @param sc The desired format of the primary rendering surface.
159     */
160    public RenderScriptGL(Context ctx, SurfaceConfig sc) {
161        super(ctx);
162        mSurfaceConfig = new SurfaceConfig(sc);
163
164        mSurface = null;
165        mWidth = 0;
166        mHeight = 0;
167        mDev = nDeviceCreate();
168        mContext = nContextCreateGL(mDev, 0,
169                                    mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref,
170                                    mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref,
171                                    mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref,
172                                    mSurfaceConfig.mStencilMin, mSurfaceConfig.mStencilPref,
173                                    mSurfaceConfig.mSamplesMin, mSurfaceConfig.mSamplesPref,
174                                    mSurfaceConfig.mSamplesQ);
175        if (mContext == 0) {
176            throw new RSDriverException("Failed to create RS context.");
177        }
178        mMessageThread = new MessageThread(this);
179        mMessageThread.start();
180    }
181
182    /**
183     * Bind an os surface
184     *
185     *
186     * @param w
187     * @param h
188     * @param sur
189     */
190    public void setSurface(SurfaceHolder sur, int w, int h) {
191        validate();
192        if (sur != null) {
193            mSurface = sur.getSurface();
194        } else {
195            mSurface = null;
196        }
197        mWidth = w;
198        mHeight = h;
199        nContextSetSurface(w, h, mSurface);
200    }
201
202    /**
203     * return the height of the last set surface.
204     *
205     * @return int
206     */
207    public int getHeight() {
208        return mHeight;
209    }
210
211    /**
212     * return the width of the last set surface.
213     *
214     * @return int
215     */
216    public int getWidth() {
217        return mWidth;
218    }
219
220    /**
221     * Temporarly halt calls to the root rendering script.
222     *
223     */
224    public void pause() {
225        validate();
226        nContextPause();
227    }
228
229    /**
230     * Resume calls to the root rendering script.
231     *
232     */
233    public void resume() {
234        validate();
235        nContextResume();
236    }
237
238
239    /**
240     * Set the script to handle calls to render the primary surface.
241     *
242     * @param s Graphics script to process rendering requests.
243     */
244    public void bindRootScript(Script s) {
245        validate();
246        nContextBindRootScript(safeID(s));
247    }
248
249    /**
250     * Set the default ProgramStore object seen as the parent state by the root
251     * rendering script.
252     *
253     * @param p
254     */
255    public void bindProgramStore(ProgramStore p) {
256        validate();
257        nContextBindProgramStore(safeID(p));
258    }
259
260    /**
261     * Set the default ProgramFragment object seen as the parent state by the
262     * root rendering script.
263     *
264     * @param p
265     */
266    public void bindProgramFragment(ProgramFragment p) {
267        validate();
268        nContextBindProgramFragment(safeID(p));
269    }
270
271    /**
272     * Set the default ProgramRaster object seen as the parent state by the
273     * root rendering script.
274     *
275     * @param p
276     */
277    public void bindProgramRaster(ProgramRaster p) {
278        validate();
279        nContextBindProgramRaster(safeID(p));
280    }
281
282    /**
283     * Set the default ProgramVertex object seen as the parent state by the
284     * root rendering script.
285     *
286     * @param p
287     */
288    public void bindProgramVertex(ProgramVertex p) {
289        validate();
290        nContextBindProgramVertex(safeID(p));
291    }
292
293}
294