1 package org.linaro.glmark2;
2 
3 import java.io.File;
4 
5 import android.graphics.PixelFormat;
6 import android.opengl.GLSurfaceView;
7 import android.app.Activity;
8 import android.util.Log;
9 
10 import javax.microedition.khronos.egl.EGL10;
11 import javax.microedition.khronos.egl.EGLDisplay;
12 import javax.microedition.khronos.egl.EGLConfig;
13 import javax.microedition.khronos.opengles.GL10;
14 
15 class Glmark2SurfaceView extends GLSurfaceView {
16 
17     public static final String LOG_TAG = "glmark2";
18 
Glmark2SurfaceView(Activity activity)19     public Glmark2SurfaceView(Activity activity) {
20         super(activity);
21         mActivity = activity;
22 
23         setEGLContextClientVersion(2);
24 
25         setEGLConfigChooser(getConfigChooser());
26 
27         setRenderer(new Glmark2Renderer(this));
28     }
29 
getConfigChooser()30     private EGLConfigChooser getConfigChooser() {
31         String args = mActivity.getIntent().getStringExtra("args");
32 
33         if (args == null)
34             args = "";
35 
36         String[] argv = args.split(" ");
37 
38         /* Find the visual-config option argument */
39         String configString = new String();
40         boolean keepNext = false;
41         for (String arg : argv) {
42             if (keepNext) {
43                 configString = arg;
44                 break;
45             }
46 
47             if (arg.equals("--visual-config"))
48                 keepNext = true;
49         }
50 
51         /* Parse the config string parameters */
52         String[] configParams = configString.split(":");
53         GLVisualConfig targetConfig = new GLVisualConfig(5, 6, 5, 0, 16, 0, 1);
54 
55         for (String param : configParams) {
56             String[] paramKeyValue = param.split("=");
57             if (paramKeyValue.length < 2)
58                 continue;
59 
60             if (paramKeyValue[0].equals("red") || paramKeyValue[0].equals("r"))
61                 targetConfig.red = Integer.parseInt(paramKeyValue[1]);
62             else if (paramKeyValue[0].equals("green") || paramKeyValue[0].equals("g"))
63                 targetConfig.green = Integer.parseInt(paramKeyValue[1]);
64             else if (paramKeyValue[0].equals("blue") || paramKeyValue[0].equals("b"))
65                 targetConfig.blue = Integer.parseInt(paramKeyValue[1]);
66             else if (paramKeyValue[0].equals("alpha") || paramKeyValue[0].equals("a"))
67                 targetConfig.alpha = Integer.parseInt(paramKeyValue[1]);
68             else if (paramKeyValue[0].equals("depth") || paramKeyValue[0].equals("d"))
69                 targetConfig.depth = Integer.parseInt(paramKeyValue[1]);
70             else if (paramKeyValue[0].equals("stencil") || paramKeyValue[0].equals("s"))
71                 targetConfig.stencil = Integer.parseInt(paramKeyValue[1]);
72             else if (paramKeyValue[0].equals("buffer") || paramKeyValue[0].equals("buf"))
73                 targetConfig.buffer = Integer.parseInt(paramKeyValue[1]);
74         }
75 
76         return new Glmark2ConfigChooser(targetConfig);
77     }
78 
79     /**
80      * EGLConfigChooser that quits with an error dialog when a suitable config
81      * cannot be found.
82      */
83     private class Glmark2ConfigChooser implements EGLConfigChooser {
84         private int[] mAttribList;
85 
Glmark2ConfigChooser(GLVisualConfig targetConfig)86         public Glmark2ConfigChooser(GLVisualConfig targetConfig)
87         {
88             mAttribList = new int[] {
89                     EGL10.EGL_RED_SIZE, targetConfig.red,
90                     EGL10.EGL_GREEN_SIZE, targetConfig.green,
91                     EGL10.EGL_BLUE_SIZE, targetConfig.blue,
92                     EGL10.EGL_ALPHA_SIZE, targetConfig.alpha,
93                     EGL10.EGL_DEPTH_SIZE, targetConfig.depth,
94                     EGL10.EGL_STENCIL_SIZE, targetConfig.stencil,
95                     EGL10.EGL_BUFFER_SIZE, targetConfig.buffer,
96                     EGL10.EGL_RENDERABLE_TYPE, 4, /* 4 = EGL_OPENGL_ES2_BIT */
97                     EGL10.EGL_NONE };
98 
99             mTargetConfig = targetConfig;
100        }
101 
102         @Override
chooseConfig(EGL10 egl, EGLDisplay display)103         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
104             try {
105                 return chooseConfigInternal(egl, display);
106             }
107             catch (Exception e) {
108                 /* Log an error message */
109                 Log.e(LOG_TAG, "No suitable EGLConfig for GLES2.0 found. Please check that proper GLES2.0 drivers are installed.");
110                 /* Display an informative (and lethal for the app) dialog */
111                 mActivity.runOnUiThread(new Runnable() {
112                     public void run() {
113                         mActivity.showDialog(Glmark2Activity.DIALOG_EGLCONFIG_FAIL_ID);
114                     }
115                 });
116 
117                 /* Wait here until the app process gets killed... */
118                 synchronized (this) {
119                     try { this.wait(); } catch (Exception ex) { }
120                 }
121             }
122             return null;
123         }
124 
chooseConfigInternal(EGL10 egl, EGLDisplay display)125         private EGLConfig chooseConfigInternal(EGL10 egl, EGLDisplay display) {
126             /* Get the number of available configs matching the attributes */
127             int[] num_config = new int[1];
128             if (!egl.eglChooseConfig(display, mAttribList, null, 0, num_config)) {
129                 throw new IllegalArgumentException("eglChooseConfig failed");
130             }
131 
132             int numConfigs = num_config[0];
133 
134             if (numConfigs <= 0) {
135                 throw new IllegalArgumentException("No matching configs found");
136             }
137 
138             /* Get the matching configs */
139             EGLConfig[] configs = new EGLConfig[numConfigs];
140             if (!egl.eglChooseConfig(display, mAttribList, configs, numConfigs,
141                                      num_config))
142             {
143                 throw new IllegalArgumentException("eglChooseConfig#2 failed");
144             }
145 
146             /* Find the best matching config. */
147             int bestScore = Integer.MIN_VALUE;
148             EGLConfig bestConfig = configs[0];
149 
150             for (EGLConfig config : configs) {
151                 GLVisualConfig vc = new GLVisualConfig();
152                 vc.red = findConfigAttrib(egl, display, config,
153                                           EGL10.EGL_RED_SIZE, 0);
154                 vc.green = findConfigAttrib(egl, display, config,
155                                             EGL10.EGL_GREEN_SIZE, 0);
156                 vc.blue = findConfigAttrib(egl, display, config,
157                                            EGL10.EGL_BLUE_SIZE, 0);
158                 vc.alpha = findConfigAttrib(egl, display, config,
159                                             EGL10.EGL_ALPHA_SIZE, 0);
160                 vc.depth = findConfigAttrib(egl, display, config,
161                                             EGL10.EGL_DEPTH_SIZE, 0);
162                 vc.stencil = findConfigAttrib(egl, display, config,
163                                             EGL10.EGL_STENCIL_SIZE, 0);
164                 vc.buffer = findConfigAttrib(egl, display, config,
165                                              EGL10.EGL_BUFFER_SIZE, 0);
166 
167                 int score = Glmark2Native.scoreConfig(vc, mTargetConfig);
168 
169                 if (score > bestScore) {
170                     bestScore = score;
171                     bestConfig = config;
172                 }
173             }
174 
175             return bestConfig;
176         }
177 
findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue)178         private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config,
179                                      int attribute, int defaultValue)
180         {
181             int[] value = new int[] { defaultValue };
182             egl.eglGetConfigAttrib(display, config, attribute, value);
183             return value[0];
184         }
185 
186         protected GLVisualConfig mTargetConfig;
187     }
188 
getActivity()189     public Activity getActivity() {
190         return mActivity;
191     }
192 
193     private Activity mActivity;
194 
195 }
196 
197 class Glmark2Renderer implements GLSurfaceView.Renderer {
Glmark2Renderer(Glmark2SurfaceView view)198     public Glmark2Renderer(Glmark2SurfaceView view) {
199         mView = view;
200     }
201 
onDrawFrame(GL10 gl)202     public void onDrawFrame(GL10 gl) {
203         if (!Glmark2Native.render())
204             mView.getActivity().finish();
205     }
206 
onSurfaceChanged(GL10 gl, int width, int height)207     public void onSurfaceChanged(GL10 gl, int width, int height) {
208         Glmark2Native.resize(width, height);
209     }
210 
onSurfaceCreated(GL10 gl, EGLConfig config)211     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
212         String args = mView.getActivity().getIntent().getStringExtra("args");
213         File f = new File(mView.getActivity().getFilesDir(), "last_run.log");
214         Glmark2Native.init(mView.getActivity().getAssets(), args, f.getAbsolutePath());
215     }
216 
217     private Glmark2SurfaceView mView;
218 }
219