Home | History | Annotate | Download | only in glperf
      1 /*
      2  * Copyright (C) 2009 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 
     17 package com.android.glperf;
     18 /*
     19  * Copyright (C) 2008 The Android Open Source Project
     20  *
     21  * Licensed under the Apache License, Version 2.0 (the "License");
     22  * you may not use this file except in compliance with the License.
     23  * You may obtain a copy of the License at
     24  *
     25  *      http://www.apache.org/licenses/LICENSE-2.0
     26  *
     27  * Unless required by applicable law or agreed to in writing, software
     28  * distributed under the License is distributed on an "AS IS" BASIS,
     29  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     30  * See the License for the specific language governing permissions and
     31  * limitations under the License.
     32  */
     33 
     34 
     35 import android.content.Context;
     36 import android.opengl.GLSurfaceView;
     37 import android.util.AttributeSet;
     38 import android.util.Log;
     39 import android.view.KeyEvent;
     40 import android.view.MotionEvent;
     41 
     42 import javax.microedition.khronos.egl.EGL10;
     43 import javax.microedition.khronos.egl.EGLConfig;
     44 import javax.microedition.khronos.egl.EGLContext;
     45 import javax.microedition.khronos.egl.EGLDisplay;
     46 import javax.microedition.khronos.opengles.GL10;
     47 
     48 /**
     49  * An implementation of SurfaceView that uses the dedicated surface for
     50  * displaying an OpenGL animation.  This allows the animation to run in a
     51  * separate thread, without requiring that it be driven by the update mechanism
     52  * of the view hierarchy.
     53  *
     54  * The application-specific rendering code is delegated to a GLView.Renderer
     55  * instance.
     56  */
     57 class GLPerfView extends GLSurfaceView {
     58     private static String TAG = "GLPerfView";
     59 
     60     public GLPerfView(Context context) {
     61         super(context);
     62         init(false, 0, 0);
     63     }
     64 
     65     public GLPerfView(Context context, boolean translucent, int depth, int stencil) {
     66         super(context);
     67         init(translucent, depth, stencil);
     68     }
     69 
     70     private void init(boolean translucent, int depth, int stencil) {
     71         setEGLContextFactory(new ContextFactory());
     72         setEGLConfigChooser( translucent ?
     73               new ConfigChooser(8,8,8,8, depth, stencil) :
     74               new ConfigChooser(5,6,5,0, depth, stencil));
     75         setRenderer(new Renderer());
     76     }
     77 
     78     private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
     79         private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
     80         public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
     81             Log.w(TAG, "creating OpenGL ES 2.0 context");
     82             checkEglError("Before eglCreateContext", egl);
     83             int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
     84             EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
     85             checkEglError("After eglCreateContext", egl);
     86             return context;
     87         }
     88 
     89         public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
     90             egl.eglDestroyContext(display, context);
     91         }
     92     }
     93 
     94     private static void checkEglError(String prompt, EGL10 egl) {
     95         int error;
     96         while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
     97             Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
     98         }
     99     }
    100 
    101     private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
    102         private static int EGL_OPENGL_ES2_BIT = 4;
    103         private static int[] s_configAttribs2 =
    104         {
    105             EGL10.EGL_RED_SIZE, 4,
    106             EGL10.EGL_GREEN_SIZE, 4,
    107             EGL10.EGL_BLUE_SIZE, 4,
    108             EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    109             EGL10.EGL_NONE
    110         };
    111 
    112         public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
    113             mRedSize = r;
    114             mGreenSize = g;
    115             mBlueSize = b;
    116             mAlphaSize = a;
    117             mDepthSize = depth;
    118             mStencilSize = stencil;
    119         }
    120 
    121         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
    122 
    123             int[] num_config = new int[1];
    124             egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
    125 
    126             int numConfigs = num_config[0];
    127 
    128             if (numConfigs <= 0) {
    129                 throw new IllegalArgumentException("No configs match configSpec");
    130             }
    131             EGLConfig[] configs = new EGLConfig[numConfigs];
    132             egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
    133             // printConfigs(egl, display, configs);
    134             return chooseConfig(egl, display, configs);
    135         }
    136 
    137         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
    138                 EGLConfig[] configs) {
    139             EGLConfig closestConfig = null;
    140             int closestDistance = 1000;
    141             for(EGLConfig config : configs) {
    142                 int d = findConfigAttrib(egl, display, config,
    143                         EGL10.EGL_DEPTH_SIZE, 0);
    144                 int s = findConfigAttrib(egl, display, config,
    145                         EGL10.EGL_STENCIL_SIZE, 0);
    146                 if (d >= mDepthSize && s>= mStencilSize) {
    147                     int r = findConfigAttrib(egl, display, config,
    148                             EGL10.EGL_RED_SIZE, 0);
    149                     int g = findConfigAttrib(egl, display, config,
    150                              EGL10.EGL_GREEN_SIZE, 0);
    151                     int b = findConfigAttrib(egl, display, config,
    152                               EGL10.EGL_BLUE_SIZE, 0);
    153                     int a = findConfigAttrib(egl, display, config,
    154                             EGL10.EGL_ALPHA_SIZE, 0);
    155                     int distance = Math.abs(r - mRedSize)
    156                                 + Math.abs(g - mGreenSize)
    157                                 + Math.abs(b - mBlueSize)
    158                                 + Math.abs(a - mAlphaSize);
    159                     if (distance < closestDistance) {
    160                         closestDistance = distance;
    161                         closestConfig = config;
    162                     }
    163                 }
    164             }
    165             return closestConfig;
    166         }
    167 
    168         private int findConfigAttrib(EGL10 egl, EGLDisplay display,
    169                 EGLConfig config, int attribute, int defaultValue) {
    170 
    171             if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
    172                 return mValue[0];
    173             }
    174             return defaultValue;
    175         }
    176 
    177         private void printConfigs(EGL10 egl, EGLDisplay display,
    178             EGLConfig[] configs) {
    179             int numConfigs = configs.length;
    180             Log.w(TAG, String.format("%d configurations", numConfigs));
    181             for (int i = 0; i < numConfigs; i++) {
    182                 Log.w(TAG, String.format("Configuration %d:\n", i));
    183                 printConfig(egl, display, configs[i]);
    184             }
    185         }
    186 
    187         private void printConfig(EGL10 egl, EGLDisplay display,
    188                 EGLConfig config) {
    189             int[] attributes = {
    190                     EGL10.EGL_BUFFER_SIZE,
    191                     EGL10.EGL_ALPHA_SIZE,
    192                     EGL10.EGL_BLUE_SIZE,
    193                     EGL10.EGL_GREEN_SIZE,
    194                     EGL10.EGL_RED_SIZE,
    195                     EGL10.EGL_DEPTH_SIZE,
    196                     EGL10.EGL_STENCIL_SIZE,
    197                     EGL10.EGL_CONFIG_CAVEAT,
    198                     EGL10.EGL_CONFIG_ID,
    199                     EGL10.EGL_LEVEL,
    200                     EGL10.EGL_MAX_PBUFFER_HEIGHT,
    201                     EGL10.EGL_MAX_PBUFFER_PIXELS,
    202                     EGL10.EGL_MAX_PBUFFER_WIDTH,
    203                     EGL10.EGL_NATIVE_RENDERABLE,
    204                     EGL10.EGL_NATIVE_VISUAL_ID,
    205                     EGL10.EGL_NATIVE_VISUAL_TYPE,
    206                     0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
    207                     EGL10.EGL_SAMPLES,
    208                     EGL10.EGL_SAMPLE_BUFFERS,
    209                     EGL10.EGL_SURFACE_TYPE,
    210                     EGL10.EGL_TRANSPARENT_TYPE,
    211                     EGL10.EGL_TRANSPARENT_RED_VALUE,
    212                     EGL10.EGL_TRANSPARENT_GREEN_VALUE,
    213                     EGL10.EGL_TRANSPARENT_BLUE_VALUE,
    214                     0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
    215                     0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
    216                     0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
    217                     0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
    218                     EGL10.EGL_LUMINANCE_SIZE,
    219                     EGL10.EGL_ALPHA_MASK_SIZE,
    220                     EGL10.EGL_COLOR_BUFFER_TYPE,
    221                     EGL10.EGL_RENDERABLE_TYPE,
    222                     0x3042 // EGL10.EGL_CONFORMANT
    223             };
    224             String[] names = {
    225                     "EGL_BUFFER_SIZE",
    226                     "EGL_ALPHA_SIZE",
    227                     "EGL_BLUE_SIZE",
    228                     "EGL_GREEN_SIZE",
    229                     "EGL_RED_SIZE",
    230                     "EGL_DEPTH_SIZE",
    231                     "EGL_STENCIL_SIZE",
    232                     "EGL_CONFIG_CAVEAT",
    233                     "EGL_CONFIG_ID",
    234                     "EGL_LEVEL",
    235                     "EGL_MAX_PBUFFER_HEIGHT",
    236                     "EGL_MAX_PBUFFER_PIXELS",
    237                     "EGL_MAX_PBUFFER_WIDTH",
    238                     "EGL_NATIVE_RENDERABLE",
    239                     "EGL_NATIVE_VISUAL_ID",
    240                     "EGL_NATIVE_VISUAL_TYPE",
    241                     "EGL_PRESERVED_RESOURCES",
    242                     "EGL_SAMPLES",
    243                     "EGL_SAMPLE_BUFFERS",
    244                     "EGL_SURFACE_TYPE",
    245                     "EGL_TRANSPARENT_TYPE",
    246                     "EGL_TRANSPARENT_RED_VALUE",
    247                     "EGL_TRANSPARENT_GREEN_VALUE",
    248                     "EGL_TRANSPARENT_BLUE_VALUE",
    249                     "EGL_BIND_TO_TEXTURE_RGB",
    250                     "EGL_BIND_TO_TEXTURE_RGBA",
    251                     "EGL_MIN_SWAP_INTERVAL",
    252                     "EGL_MAX_SWAP_INTERVAL",
    253                     "EGL_LUMINANCE_SIZE",
    254                     "EGL_ALPHA_MASK_SIZE",
    255                     "EGL_COLOR_BUFFER_TYPE",
    256                     "EGL_RENDERABLE_TYPE",
    257                     "EGL_CONFORMANT"
    258             };
    259             int[] value = new int[1];
    260             for (int i = 0; i < attributes.length; i++) {
    261                 int attribute = attributes[i];
    262                 String name = names[i];
    263                 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
    264                     Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
    265                 } else {
    266                     // Log.w(TAG, String.format("  %s: failed\n", name));
    267                     while (egl.eglGetError() != EGL10.EGL_SUCCESS);
    268                 }
    269             }
    270         }
    271 
    272         // Subclasses can adjust these values:
    273         protected int mRedSize;
    274         protected int mGreenSize;
    275         protected int mBlueSize;
    276         protected int mAlphaSize;
    277         protected int mDepthSize;
    278         protected int mStencilSize;
    279         private int[] mValue = new int[1];
    280     }
    281 
    282     private static class Renderer implements GLSurfaceView.Renderer {
    283         public void onDrawFrame(GL10 gl) {
    284             GLPerfLib.step();
    285         }
    286 
    287         public void onSurfaceChanged(GL10 gl, int width, int height) {
    288             GLPerfLib.init(width, height);
    289         }
    290 
    291         public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    292             // Do nothing.
    293         }
    294     }
    295 }
    296 
    297