1c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner/*
2c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Copyright (C) 2009 The Android Open Source Project
3c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
4c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License");
5c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * you may not use this file except in compliance with the License.
6c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * You may obtain a copy of the License at
7c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
8c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *      http://www.apache.org/licenses/LICENSE-2.0
9c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
10c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Unless required by applicable law or agreed to in writing, software
11c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS,
12c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * See the License for the specific language governing permissions and
14c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * limitations under the License.
15c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner */
16c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
17c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerpackage com.android.gl2jni;
18c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner/*
19c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Copyright (C) 2008 The Android Open Source Project
20c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
21c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License");
22c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * you may not use this file except in compliance with the License.
23c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * You may obtain a copy of the License at
24c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
25c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *      http://www.apache.org/licenses/LICENSE-2.0
26c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
27c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * Unless required by applicable law or agreed to in writing, software
28c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS,
29c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * See the License for the specific language governing permissions and
31c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * limitations under the License.
32c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner */
33c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
34c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
35c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.content.Context;
36c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.graphics.PixelFormat;
37c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.opengl.GLSurfaceView;
38c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.util.AttributeSet;
39c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.util.Log;
40c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.view.KeyEvent;
41c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport android.view.MotionEvent;
42c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
43c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport javax.microedition.khronos.egl.EGL10;
44c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport javax.microedition.khronos.egl.EGLConfig;
45c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport javax.microedition.khronos.egl.EGLContext;
46c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport javax.microedition.khronos.egl.EGLDisplay;
47c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerimport javax.microedition.khronos.opengles.GL10;
48c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
49c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner/**
50c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * A simple GLSurfaceView sub-class that demonstrate how to perform
51c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * OpenGL ES 2.0 rendering into a GL Surface. Note the following important
52c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * details:
53c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
54c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * - The class must use a custom context factory to enable 2.0 rendering.
55c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   See ContextFactory class definition below.
56c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
57c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * - The class must use a custom EGLConfigChooser to be able to select
58c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   an EGLConfig that supports 2.0. This is done by providing a config
59c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   specification to eglChooseConfig() that has the attribute
60c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
61c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   set. See ConfigChooser class definition below.
62c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *
63c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner * - The class must select the surface's format, then choose an EGLConfig
64c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   that matches it exactly (with regards to red/green/blue/alpha channels
65c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner *   bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
66c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner */
67c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turnerclass GL2JNIView extends GLSurfaceView {
68c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static String TAG = "GL2JNIView";
69c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static final boolean DEBUG = false;
70c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
71c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    public GL2JNIView(Context context) {
72c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        super(context);
73c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        init(false, 0, 0);
74c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
75c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
76c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    public GL2JNIView(Context context, boolean translucent, int depth, int stencil) {
77c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        super(context);
78c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        init(translucent, depth, stencil);
79c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
80c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
81c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private void init(boolean translucent, int depth, int stencil) {
82c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
83c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
84c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * If we want a translucent one, we should change the surface's
85c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
86c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
87c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         */
88c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        if (translucent) {
89c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
90c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
91c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
92c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        /* Setup the context factory for 2.0 rendering.
93c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * See ContextFactory class definition below
94c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         */
95c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        setEGLContextFactory(new ContextFactory());
96c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
97c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        /* We need to choose an EGLConfig that matches the format of
98c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * our surface exactly. This is going to be done in our
99c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * custom config chooser. See ConfigChooser class definition
100c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * below.
101c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         */
102c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        setEGLConfigChooser( translucent ?
103c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                             new ConfigChooser(8, 8, 8, 8, depth, stencil) :
104c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                             new ConfigChooser(5, 6, 5, 0, depth, stencil) );
105c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
106c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        /* Set the renderer responsible for frame rendering */
107c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        setRenderer(new Renderer());
108c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
109c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
110c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
111c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
112c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
113c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            Log.w(TAG, "creating OpenGL ES 2.0 context");
114c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            checkEglError("Before eglCreateContext", egl);
115c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
116c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
117c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            checkEglError("After eglCreateContext", egl);
118c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            return context;
119c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
120c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
121c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
122c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            egl.eglDestroyContext(display, context);
123c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
124c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
125c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
126c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static void checkEglError(String prompt, EGL10 egl) {
127c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        int error;
128c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
129c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
130c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
131c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
132c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
133c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
134c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
135c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
136c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mRedSize = r;
137c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mGreenSize = g;
138c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mBlueSize = b;
139c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mAlphaSize = a;
140c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mDepthSize = depth;
141c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            mStencilSize = stencil;
142c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
143c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
144c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        /* This EGL config specification is used to specify 2.0 rendering.
145c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * We use a minimum size of 4 bits for red/green/blue, but will
146c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         * perform actual matching in chooseConfig() below.
147c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner         */
148c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private static int EGL_OPENGL_ES2_BIT = 4;
149c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private static int[] s_configAttribs2 =
150c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        {
151c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGL10.EGL_RED_SIZE, 4,
152c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGL10.EGL_GREEN_SIZE, 4,
153c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGL10.EGL_BLUE_SIZE, 4,
154c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
155c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGL10.EGL_NONE
156c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        };
157c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
158c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
159c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
160c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            /* Get the number of minimally matching EGL configurations
161c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner             */
162c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int[] num_config = new int[1];
163c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
164c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
165c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int numConfigs = num_config[0];
166c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
167c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            if (numConfigs <= 0) {
168c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                throw new IllegalArgumentException("No configs match configSpec");
169c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
170c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
171c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            /* Allocate then read the array of minimally matching EGL configs
172c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner             */
173c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGLConfig[] configs = new EGLConfig[numConfigs];
174c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
175c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
176c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            if (DEBUG) {
177c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                 printConfigs(egl, display, configs);
178c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
179c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            /* Now return the "best" one
180c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner             */
181c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            return chooseConfig(egl, display, configs);
182c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
183c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
184c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
185c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                EGLConfig[] configs) {
186c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            for(EGLConfig config : configs) {
187c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int d = findConfigAttrib(egl, display, config,
188c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                        EGL10.EGL_DEPTH_SIZE, 0);
189c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int s = findConfigAttrib(egl, display, config,
190c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                        EGL10.EGL_STENCIL_SIZE, 0);
191c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
192c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                // We need at least mDepthSize and mStencilSize bits
193c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                if (d < mDepthSize || s < mStencilSize)
194c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    continue;
195c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
196c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                // We want an *exact* match for red/green/blue/alpha
197c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int r = findConfigAttrib(egl, display, config,
198c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                        EGL10.EGL_RED_SIZE, 0);
199c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int g = findConfigAttrib(egl, display, config,
200c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                            EGL10.EGL_GREEN_SIZE, 0);
201c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int b = findConfigAttrib(egl, display, config,
202c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                            EGL10.EGL_BLUE_SIZE, 0);
203c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int a = findConfigAttrib(egl, display, config,
204c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                        EGL10.EGL_ALPHA_SIZE, 0);
205c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
206c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
207c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    return config;
208c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
209c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            return null;
210c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
211c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
212c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
213c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                EGLConfig config, int attribute, int defaultValue) {
214c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
215c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
216c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                return mValue[0];
217c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
218c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            return defaultValue;
219c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
220c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
221c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private void printConfigs(EGL10 egl, EGLDisplay display,
222c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            EGLConfig[] configs) {
223c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int numConfigs = configs.length;
224c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            Log.w(TAG, String.format("%d configurations", numConfigs));
225c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            for (int i = 0; i < numConfigs; i++) {
226c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                Log.w(TAG, String.format("Configuration %d:\n", i));
227c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                printConfig(egl, display, configs[i]);
228c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
229c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
230c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
231c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private void printConfig(EGL10 egl, EGLDisplay display,
232c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                EGLConfig config) {
233c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int[] attributes = {
234c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_BUFFER_SIZE,
235c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_ALPHA_SIZE,
236c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_BLUE_SIZE,
237c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_GREEN_SIZE,
238c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_RED_SIZE,
239c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_DEPTH_SIZE,
240c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_STENCIL_SIZE,
241c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_CONFIG_CAVEAT,
242c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_CONFIG_ID,
243c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_LEVEL,
244c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_MAX_PBUFFER_HEIGHT,
245c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_MAX_PBUFFER_PIXELS,
246c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_MAX_PBUFFER_WIDTH,
247c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_NATIVE_RENDERABLE,
248c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_NATIVE_VISUAL_ID,
249c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_NATIVE_VISUAL_TYPE,
250c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
251c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_SAMPLES,
252c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_SAMPLE_BUFFERS,
253c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_SURFACE_TYPE,
254c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_TRANSPARENT_TYPE,
255c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_TRANSPARENT_RED_VALUE,
256c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_TRANSPARENT_GREEN_VALUE,
257c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_TRANSPARENT_BLUE_VALUE,
258c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
259c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
260c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
261c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
262c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_LUMINANCE_SIZE,
263c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_ALPHA_MASK_SIZE,
264c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_COLOR_BUFFER_TYPE,
265c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    EGL10.EGL_RENDERABLE_TYPE,
266c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    0x3042 // EGL10.EGL_CONFORMANT
267c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            };
268c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            String[] names = {
269c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_BUFFER_SIZE",
270c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_ALPHA_SIZE",
271c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_BLUE_SIZE",
272c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_GREEN_SIZE",
273c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_RED_SIZE",
274c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_DEPTH_SIZE",
275c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_STENCIL_SIZE",
276c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_CONFIG_CAVEAT",
277c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_CONFIG_ID",
278c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_LEVEL",
279c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_MAX_PBUFFER_HEIGHT",
280c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_MAX_PBUFFER_PIXELS",
281c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_MAX_PBUFFER_WIDTH",
282c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_NATIVE_RENDERABLE",
283c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_NATIVE_VISUAL_ID",
284c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_NATIVE_VISUAL_TYPE",
285c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_PRESERVED_RESOURCES",
286c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_SAMPLES",
287c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_SAMPLE_BUFFERS",
288c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_SURFACE_TYPE",
289c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_TRANSPARENT_TYPE",
290c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_TRANSPARENT_RED_VALUE",
291c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_TRANSPARENT_GREEN_VALUE",
292c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_TRANSPARENT_BLUE_VALUE",
293c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_BIND_TO_TEXTURE_RGB",
294c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_BIND_TO_TEXTURE_RGBA",
295c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_MIN_SWAP_INTERVAL",
296c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_MAX_SWAP_INTERVAL",
297c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_LUMINANCE_SIZE",
298c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_ALPHA_MASK_SIZE",
299c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_COLOR_BUFFER_TYPE",
300c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_RENDERABLE_TYPE",
301c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    "EGL_CONFORMANT"
302c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            };
303c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            int[] value = new int[1];
304c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            for (int i = 0; i < attributes.length; i++) {
305c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                int attribute = attributes[i];
306c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                String name = names[i];
307c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
308c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
309c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                } else {
310c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    // Log.w(TAG, String.format("  %s: failed\n", name));
311c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                    while (egl.eglGetError() != EGL10.EGL_SUCCESS);
312c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner                }
313c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            }
314c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
315c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
316c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        // Subclasses can adjust these values:
317c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mRedSize;
318c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mGreenSize;
319c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mBlueSize;
320c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mAlphaSize;
321c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mDepthSize;
322c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        protected int mStencilSize;
323c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        private int[] mValue = new int[1];
324c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
325c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
326c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    private static class Renderer implements GLSurfaceView.Renderer {
327c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public void onDrawFrame(GL10 gl) {
328c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            GL2JNILib.step();
329c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
330c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
331c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public void onSurfaceChanged(GL10 gl, int width, int height) {
332c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            GL2JNILib.init(width, height);
333c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
334c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner
335c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
336c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner            // Do nothing.
337c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner        }
338c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner    }
339c817c5210e4207908b83faaf08a2c5b95251f871David 'Digit' Turner}
340