1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2009 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui;
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.GLSurfaceView.EGLConfigChooser;
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
202e1771b997ab6966411b2c612562c538ae3e325dPin Tingimport com.android.gallery3d.common.ApiHelper;
212e1771b997ab6966411b2c612562c538ae3e325dPin Ting
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.egl.EGL10;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.egl.EGLConfig;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.egl.EGLDisplay;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * The code is copied/adapted from
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * <code>android.opengl.GLSurfaceView.BaseConfigChooser</code>. Here we try to
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * choose a configuration that support RGBA_8888 format and if possible,
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * with stencil buffer, but is not required.
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linclass GalleryEGLConfigChooser implements EGLConfigChooser {
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "GalleryEGLConfigChooser";
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
362e1771b997ab6966411b2c612562c538ae3e325dPin Ting    private final int mConfigSpec565[] = new int[] {
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_RED_SIZE, 5,
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_GREEN_SIZE, 6,
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_BLUE_SIZE, 5,
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_ALPHA_SIZE, 0,
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_NONE
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
442e1771b997ab6966411b2c612562c538ae3e325dPin Ting    private final int mConfigSpec888[] = new int[] {
452e1771b997ab6966411b2c612562c538ae3e325dPin Ting            EGL10.EGL_RED_SIZE, 8,
462e1771b997ab6966411b2c612562c538ae3e325dPin Ting            EGL10.EGL_GREEN_SIZE, 8,
472e1771b997ab6966411b2c612562c538ae3e325dPin Ting            EGL10.EGL_BLUE_SIZE, 8,
482e1771b997ab6966411b2c612562c538ae3e325dPin Ting            EGL10.EGL_ALPHA_SIZE, 0,
492e1771b997ab6966411b2c612562c538ae3e325dPin Ting            EGL10.EGL_NONE
502e1771b997ab6966411b2c612562c538ae3e325dPin Ting    };
512e1771b997ab6966411b2c612562c538ae3e325dPin Ting
527817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @Override
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int[] numConfig = new int[1];
552e1771b997ab6966411b2c612562c538ae3e325dPin Ting        int mConfigSpec[] = ApiHelper.USE_888_PIXEL_FORMAT
562e1771b997ab6966411b2c612562c538ae3e325dPin Ting                ? mConfigSpec888 : mConfigSpec565;
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, numConfig)) {
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            throw new RuntimeException("eglChooseConfig failed");
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (numConfig[0] <= 0) {
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            throw new RuntimeException("No configs match configSpec");
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        EGLConfig[] configs = new EGLConfig[numConfig[0]];
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (!egl.eglChooseConfig(display,
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mConfigSpec, configs, configs.length, numConfig)) {
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            throw new RuntimeException();
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return chooseConfig(egl, display, configs);
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private EGLConfig chooseConfig(
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10 egl, EGLDisplay display, EGLConfig configs[]) {
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        EGLConfig result = null;
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int minStencil = Integer.MAX_VALUE;
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int value[] = new int[1];
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // Because we need only one bit of stencil, try to choose a config that
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // has stencil support but with smallest number of stencil bits. If
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // none is found, choose any one.
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int i = 0, n = configs.length; i < n; ++i) {
852e1771b997ab6966411b2c612562c538ae3e325dPin Ting            if (!ApiHelper.USE_888_PIXEL_FORMAT) {
862e1771b997ab6966411b2c612562c538ae3e325dPin Ting                if (egl.eglGetConfigAttrib(
872e1771b997ab6966411b2c612562c538ae3e325dPin Ting                    display, configs[i], EGL10.EGL_RED_SIZE, value)) {
882e1771b997ab6966411b2c612562c538ae3e325dPin Ting                    // Filter out ARGB 8888 configs.
892e1771b997ab6966411b2c612562c538ae3e325dPin Ting                    if (value[0] == 8) continue;
902e1771b997ab6966411b2c612562c538ae3e325dPin Ting                }
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (egl.eglGetConfigAttrib(
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    display, configs[i], EGL10.EGL_STENCIL_SIZE, value)) {
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (value[0] == 0) continue;
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (value[0] < minStencil) {
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    minStencil = value[0];
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    result = configs[i];
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                throw new RuntimeException(
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        "eglGetConfigAttrib error: " + egl.eglGetError());
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (result == null) result = configs[0];
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        egl.eglGetConfigAttrib(
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                display, result, EGL10.EGL_STENCIL_SIZE, value);
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        logConfig(egl, display, result);
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return result;
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int[] ATTR_ID = {
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_RED_SIZE,
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_GREEN_SIZE,
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_BLUE_SIZE,
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_ALPHA_SIZE,
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_DEPTH_SIZE,
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_STENCIL_SIZE,
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_CONFIG_ID,
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            EGL10.EGL_CONFIG_CAVEAT
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String[] ATTR_NAME = {
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        "R", "G", "B", "A", "D", "S", "ID", "CAVEAT"
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void logConfig(EGL10 egl, EGLDisplay display, EGLConfig config) {
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int value[] = new int[1];
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        StringBuilder sb = new StringBuilder();
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int j = 0; j < ATTR_ID.length; j++) {
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            egl.eglGetConfigAttrib(display, config, ATTR_ID[j], value);
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            sb.append(ATTR_NAME[j] + value[0] + " ");
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Log.i(TAG, "Config chosen: " + sb.toString());
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
136