Merge lp:~linaro-graphics-wg/glmark2/android-gui into lp:glmark2/2011.11
- android-gui
- Merge into trunk
Proposed by
Alexandros Frantzis
Status: | Merged |
---|---|
Merged at revision: | 231 |
Proposed branch: | lp:~linaro-graphics-wg/glmark2/android-gui |
Merge into: | lp:glmark2/2011.11 |
Diff against target: |
1505 lines (+1312/-51) 15 files modified
android/AndroidManifest.xml (+16/-2) android/build.xml (+92/-0) android/project.properties (+5/-2) android/res/layout/activity_editor.xml (+34/-0) android/res/layout/activity_main.xml (+20/-0) android/res/layout/list_header.xml (+5/-0) android/res/layout/list_item.xml (+32/-0) android/res/values/strings.xml (+3/-0) android/src/org/linaro/glmark2/EditorActivity.java (+513/-0) android/src/org/linaro/glmark2/GLVisualConfig.java (+44/-0) android/src/org/linaro/glmark2/Glmark2Native.java (+33/-0) android/src/org/linaro/glmark2/Glmark2SurfaceView.java (+0/-33) android/src/org/linaro/glmark2/MainActivity.java (+302/-0) android/src/org/linaro/glmark2/SceneInfo.java (+90/-0) src/android.cpp (+123/-14) |
To merge this branch: | bzr merge lp:~linaro-graphics-wg/glmark2/android-gui |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jesse Barker | Approve | ||
Review via email: mp+113942@code.launchpad.net |
Commit message
Description of the change
Android: Create GUI for defining and running benchmarks.
Separate blueprints will be used for additional features.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'android/AndroidManifest.xml' |
2 | --- android/AndroidManifest.xml 2012-06-21 12:57:43 +0000 |
3 | +++ android/AndroidManifest.xml 2012-07-09 10:15:24 +0000 |
4 | @@ -3,14 +3,28 @@ |
5 | android:versionCode="1" |
6 | android:versionName="2012.06" package="org.linaro.glmark2"> |
7 | <application android:label="@string/app_name"> |
8 | - <activity android:label="@string/app_name" |
9 | + <activity android:name="org.linaro.glmark2.MainActivity" |
10 | + android:label="@string/title_activity_main"> |
11 | + <intent-filter> |
12 | + <action android:name="android.intent.action.MAIN" /> |
13 | + <category android:name="android.intent.category.LAUNCHER" /> |
14 | + </intent-filter> |
15 | + </activity> |
16 | + <activity |
17 | + android:name="org.linaro.glmark2.EditorActivity" |
18 | + android:label="@string/title_activity_editor" > |
19 | + <intent-filter> |
20 | + <action android:name="android.intent.action.MAIN" /> |
21 | + </intent-filter> |
22 | + </activity> |
23 | + <activity android:label="@string/title_activity_glmark2" |
24 | android:theme="@android:style/Theme.NoTitleBar.Fullscreen" |
25 | android:launchMode="singleTask" |
26 | android:screenOrientation="nosensor" |
27 | + android:process=":glmark2" |
28 | android:name="org.linaro.glmark2.Glmark2Activity"> |
29 | <intent-filter> |
30 | <action android:name="android.intent.action.MAIN" /> |
31 | - <category android:name="android.intent.category.LAUNCHER" /> |
32 | </intent-filter> |
33 | </activity> |
34 | </application> |
35 | |
36 | === added file 'android/build.xml' |
37 | --- android/build.xml 1970-01-01 00:00:00 +0000 |
38 | +++ android/build.xml 2012-07-09 10:15:24 +0000 |
39 | @@ -0,0 +1,92 @@ |
40 | +<?xml version="1.0" encoding="UTF-8"?> |
41 | +<project name="Glmark2" default="help"> |
42 | + |
43 | + <!-- The local.properties file is created and updated by the 'android' tool. |
44 | + It contains the path to the SDK. It should *NOT* be checked into |
45 | + Version Control Systems. --> |
46 | + <property file="local.properties" /> |
47 | + |
48 | + <!-- The ant.properties file can be created by you. It is only edited by the |
49 | + 'android' tool to add properties to it. |
50 | + This is the place to change some Ant specific build properties. |
51 | + Here are some properties you may want to change/update: |
52 | + |
53 | + source.dir |
54 | + The name of the source directory. Default is 'src'. |
55 | + out.dir |
56 | + The name of the output directory. Default is 'bin'. |
57 | + |
58 | + For other overridable properties, look at the beginning of the rules |
59 | + files in the SDK, at tools/ant/build.xml |
60 | + |
61 | + Properties related to the SDK location or the project target should |
62 | + be updated using the 'android' tool with the 'update' action. |
63 | + |
64 | + This file is an integral part of the build system for your |
65 | + application and should be checked into Version Control Systems. |
66 | + |
67 | + --> |
68 | + <property file="ant.properties" /> |
69 | + |
70 | + <!-- if sdk.dir was not set from one of the property file, then |
71 | + get it from the ANDROID_HOME env var. |
72 | + This must be done before we load project.properties since |
73 | + the proguard config can use sdk.dir --> |
74 | + <property environment="env" /> |
75 | + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> |
76 | + <isset property="env.ANDROID_HOME" /> |
77 | + </condition> |
78 | + |
79 | + <!-- The project.properties file is created and updated by the 'android' |
80 | + tool, as well as ADT. |
81 | + |
82 | + This contains project specific properties such as project target, and library |
83 | + dependencies. Lower level build properties are stored in ant.properties |
84 | + (or in .classpath for Eclipse projects). |
85 | + |
86 | + This file is an integral part of the build system for your |
87 | + application and should be checked into Version Control Systems. --> |
88 | + <loadproperties srcFile="project.properties" /> |
89 | + |
90 | + <!-- quick check on sdk.dir --> |
91 | + <fail |
92 | + message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." |
93 | + unless="sdk.dir" |
94 | + /> |
95 | + |
96 | + <!-- |
97 | + Import per project custom build rules if present at the root of the project. |
98 | + This is the place to put custom intermediary targets such as: |
99 | + -pre-build |
100 | + -pre-compile |
101 | + -post-compile (This is typically used for code obfuscation. |
102 | + Compiled code location: ${out.classes.absolute.dir} |
103 | + If this is not done in place, override ${out.dex.input.absolute.dir}) |
104 | + -post-package |
105 | + -post-build |
106 | + -pre-clean |
107 | + --> |
108 | + <import file="custom_rules.xml" optional="true" /> |
109 | + |
110 | + <!-- Import the actual build file. |
111 | + |
112 | + To customize existing targets, there are two options: |
113 | + - Customize only one target: |
114 | + - copy/paste the target into this file, *before* the |
115 | + <import> task. |
116 | + - customize it to your needs. |
117 | + - Customize the whole content of build.xml |
118 | + - copy/paste the content of the rules files (minus the top node) |
119 | + into this file, replacing the <import> task. |
120 | + - customize to your needs. |
121 | + |
122 | + *********************** |
123 | + ****** IMPORTANT ****** |
124 | + *********************** |
125 | + In all cases you must update the value of version-tag below to read 'custom' instead of an integer, |
126 | + in order to avoid having your file be overridden by tools such as "android update project" |
127 | + --> |
128 | + <!-- version-tag: 1 --> |
129 | + <import file="${sdk.dir}/tools/ant/build.xml" /> |
130 | + |
131 | +</project> |
132 | |
133 | === renamed file 'android/default.properties' => 'android/project.properties' |
134 | --- android/default.properties 2011-08-10 20:48:56 +0000 |
135 | +++ android/project.properties 2012-07-09 10:15:24 +0000 |
136 | @@ -3,9 +3,12 @@ |
137 | # |
138 | # This file must be checked in Version Control Systems. |
139 | # |
140 | -# To customize properties used by the Ant build system use, |
141 | -# "build.properties", and override values to adapt the script to your |
142 | +# To customize properties used by the Ant build system edit |
143 | +# "ant.properties", and override values to adapt the script to your |
144 | # project structure. |
145 | +# |
146 | +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): |
147 | +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt |
148 | |
149 | # Project target. |
150 | target=android-10 |
151 | |
152 | === added directory 'android/res/layout' |
153 | === added file 'android/res/layout/activity_editor.xml' |
154 | --- android/res/layout/activity_editor.xml 1970-01-01 00:00:00 +0000 |
155 | +++ android/res/layout/activity_editor.xml 2012-07-09 10:15:24 +0000 |
156 | @@ -0,0 +1,34 @@ |
157 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
158 | + xmlns:tools="http://schemas.android.com/tools" |
159 | + android:layout_width="match_parent" |
160 | + android:layout_height="match_parent" > |
161 | + |
162 | + <LinearLayout android:id="@+id/buttonLinearLayout" |
163 | + android:layout_width="match_parent" |
164 | + android:layout_height="wrap_content" |
165 | + android:layout_alignParentBottom="true"> |
166 | + |
167 | + <Button android:id="@+id/runButton" |
168 | + android:layout_width="0dip" |
169 | + android:layout_height="wrap_content" |
170 | + android:layout_weight="1.0" |
171 | + android:layout_alignParentBottom="true" |
172 | + android:text="Run" /> |
173 | + |
174 | + <Button android:id="@+id/saveButton" |
175 | + android:layout_width="0dip" |
176 | + android:layout_height="wrap_content" |
177 | + android:layout_weight="1.0" |
178 | + android:layout_alignParentBottom="true" |
179 | + android:text="Save" /> |
180 | + |
181 | + </LinearLayout> |
182 | + |
183 | + |
184 | + <ListView android:id="@+id/editorListView" |
185 | + android:layout_above="@id/buttonLinearLayout" |
186 | + android:layout_weight="1.0" |
187 | + android:layout_width="match_parent" |
188 | + android:layout_height="match_parent" |
189 | + android:layout_alignParentTop="true" /> |
190 | +</RelativeLayout> |
191 | |
192 | === added file 'android/res/layout/activity_main.xml' |
193 | --- android/res/layout/activity_main.xml 1970-01-01 00:00:00 +0000 |
194 | +++ android/res/layout/activity_main.xml 2012-07-09 10:15:24 +0000 |
195 | @@ -0,0 +1,20 @@ |
196 | +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
197 | + xmlns:tools="http://schemas.android.com/tools" |
198 | + android:layout_width="match_parent" |
199 | + android:layout_height="match_parent" > |
200 | + |
201 | + <Button android:id="@+id/runButton" |
202 | + android:layout_width="match_parent" |
203 | + android:layout_height="wrap_content" |
204 | + android:layout_alignParentBottom="true" |
205 | + android:text="Run" /> |
206 | + |
207 | + <ListView android:id="@+id/benchmarkListView" |
208 | + android:layout_above="@id/runButton" |
209 | + android:layout_weight="1.0" |
210 | + android:layout_width="match_parent" |
211 | + android:layout_height="match_parent" |
212 | + android:layout_alignParentTop="true" /> |
213 | + |
214 | + |
215 | +</RelativeLayout> |
216 | |
217 | === added file 'android/res/layout/list_header.xml' |
218 | --- android/res/layout/list_header.xml 1970-01-01 00:00:00 +0000 |
219 | +++ android/res/layout/list_header.xml 2012-07-09 10:15:24 +0000 |
220 | @@ -0,0 +1,5 @@ |
221 | +<?xml version="1.0" encoding="utf-8"?> |
222 | + |
223 | +<TextView xmlns:android="http://schemas.android.com/apk/res/android" |
224 | + style="?android:attr/listSeparatorTextViewStyle" |
225 | + android:id="@+id/listHeader" /> |
226 | |
227 | === added file 'android/res/layout/list_item.xml' |
228 | --- android/res/layout/list_item.xml 1970-01-01 00:00:00 +0000 |
229 | +++ android/res/layout/list_item.xml 2012-07-09 10:15:24 +0000 |
230 | @@ -0,0 +1,32 @@ |
231 | +<?xml version="1.0" encoding="utf-8"?> |
232 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
233 | + android:layout_width="wrap_content" |
234 | + android:layout_height="wrap_content" |
235 | + android:minHeight="?android:attr/listPreferredItemHeight" |
236 | + android:gravity="center_vertical" |
237 | + android:paddingRight="?android:attr/scrollbarSize" > |
238 | + |
239 | + <RelativeLayout android:layout_width="wrap_content" |
240 | + android:layout_height="wrap_content" |
241 | + android:layout_marginLeft="15dip" |
242 | + android:layout_marginRight="6dip" |
243 | + android:layout_marginTop="6dip" |
244 | + android:layout_marginBottom="6dip" |
245 | + android:layout_weight="1"> |
246 | + |
247 | + <TextView android:id="@+id/title" |
248 | + android:layout_width="wrap_content" |
249 | + android:layout_height="wrap_content" |
250 | + android:textAppearance="?android:attr/textAppearanceLarge" /> |
251 | + |
252 | + <TextView android:id="@+id/summary" |
253 | + android:layout_width="wrap_content" |
254 | + android:layout_height="wrap_content" |
255 | + android:layout_alignLeft="@id/title" |
256 | + android:layout_below="@id/title" |
257 | + android:textAppearance="?android:attr/textAppearanceSmall" |
258 | + android:textColor="?android:attr/textColorSecondary" /> |
259 | + |
260 | + </RelativeLayout> |
261 | + |
262 | +</LinearLayout> |
263 | |
264 | === modified file 'android/res/values/strings.xml' |
265 | --- android/res/values/strings.xml 2011-08-12 10:34:06 +0000 |
266 | +++ android/res/values/strings.xml 2012-07-09 10:15:24 +0000 |
267 | @@ -1,4 +1,7 @@ |
268 | <?xml version="1.0" encoding="utf-8"?> |
269 | <resources> |
270 | <string name="app_name">GLMark2</string> |
271 | + <string name="title_activity_main">GLMark2</string> |
272 | + <string name="title_activity_editor">GLMark2 Benchmark Editor</string> |
273 | + <string name="title_activity_glmark2">GLMark2</string> |
274 | </resources> |
275 | |
276 | === added file 'android/src/org/linaro/glmark2/EditorActivity.java' |
277 | --- android/src/org/linaro/glmark2/EditorActivity.java 1970-01-01 00:00:00 +0000 |
278 | +++ android/src/org/linaro/glmark2/EditorActivity.java 2012-07-09 10:15:24 +0000 |
279 | @@ -0,0 +1,513 @@ |
280 | +/* |
281 | + * Copyright © 2012 Linaro Limited |
282 | + * |
283 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
284 | + * |
285 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
286 | + * terms of the GNU General Public License as published by the Free Software |
287 | + * Foundation, either version 3 of the License, or (at your option) any later |
288 | + * version. |
289 | + * |
290 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
291 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
292 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
293 | + * details. |
294 | + * |
295 | + * You should have received a copy of the GNU General Public License along with |
296 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
297 | + * |
298 | + * Authors: |
299 | + * Alexandros Frantzis |
300 | + */ |
301 | +package org.linaro.glmark2; |
302 | + |
303 | +import java.util.ArrayList; |
304 | + |
305 | +import android.app.Activity; |
306 | +import android.app.AlertDialog; |
307 | +import android.app.Dialog; |
308 | +import android.content.Context; |
309 | +import android.content.DialogInterface; |
310 | +import android.content.DialogInterface.OnDismissListener; |
311 | +import android.content.Intent; |
312 | +import android.graphics.Color; |
313 | +import android.os.Bundle; |
314 | +import android.os.Parcelable; |
315 | +import android.text.SpannableString; |
316 | +import android.text.style.ForegroundColorSpan; |
317 | +import android.util.Log; |
318 | +import android.view.inputmethod.EditorInfo; |
319 | +import android.view.KeyEvent; |
320 | +import android.view.LayoutInflater; |
321 | +import android.view.View; |
322 | +import android.view.ViewGroup; |
323 | +import android.view.WindowManager; |
324 | +import android.widget.AdapterView; |
325 | +import android.widget.AdapterView.OnItemClickListener; |
326 | +import android.widget.AdapterView.OnItemLongClickListener; |
327 | +import android.widget.ArrayAdapter; |
328 | +import android.widget.Button; |
329 | +import android.widget.EditText; |
330 | +import android.widget.ListView; |
331 | +import android.widget.TextView; |
332 | +import android.widget.TextView.OnEditorActionListener; |
333 | + |
334 | +public class EditorActivity extends Activity { |
335 | + public static final int DIALOG_SCENE_NAME_ID = 0; |
336 | + public static final int DIALOG_SCENE_OPTION_ID = 1; |
337 | + |
338 | + public static final int ITEM_POSITION_SCENE_NAME_HEADER = 0; |
339 | + public static final int ITEM_POSITION_SCENE_NAME = 1; |
340 | + public static final int ITEM_POSITION_SCENE_OPTION_HEADER = 2; |
341 | + public static final int ITEM_POSITION_SCENE_OPTION = 3; |
342 | + |
343 | + private EditorItemAdapter adapter; |
344 | + private ArrayList<SceneInfo> sceneInfoList; |
345 | + private String[] sceneNames; |
346 | + |
347 | + @Override |
348 | + public void onCreate(Bundle savedInstanceState) { |
349 | + super.onCreate(savedInstanceState); |
350 | + setContentView(R.layout.activity_editor); |
351 | + |
352 | + /* Get information about the available scenes */ |
353 | + sceneInfoList = getSceneInfoList(); |
354 | + sceneNames = getSceneNames(); |
355 | + |
356 | + /* Read information sent by the main activity */ |
357 | + final int benchmarkPos = this.getIntent().getIntExtra("benchmark-pos", 0); |
358 | + String benchmarkText = getIntent().getStringExtra("benchmark-text"); |
359 | + if (benchmarkText.isEmpty()) |
360 | + benchmarkText = sceneNames[0]; |
361 | + |
362 | + /* Set up the run button */ |
363 | + Button runButton = (Button) findViewById(R.id.runButton); |
364 | + runButton.setOnClickListener(new View.OnClickListener() { |
365 | + public void onClick(View v) { |
366 | + Intent intent = new Intent(EditorActivity.this, Glmark2Activity.class); |
367 | + String args = "-b " + getBenchmarkDescriptionText(); |
368 | + intent.putExtra("args", args); |
369 | + startActivity(intent); |
370 | + } |
371 | + }); |
372 | + |
373 | + /* Set up the save button */ |
374 | + Button button = (Button) findViewById(R.id.saveButton); |
375 | + button.setOnClickListener(new View.OnClickListener() { |
376 | + public void onClick(View v) { |
377 | + String newBenchmarkText = getBenchmarkDescriptionText(); |
378 | + Intent intent = new Intent(); |
379 | + intent.putExtra("benchmark-text", newBenchmarkText); |
380 | + intent.putExtra("benchmark-pos", benchmarkPos); |
381 | + setResult(RESULT_OK, intent); |
382 | + finish(); |
383 | + } |
384 | + }); |
385 | + |
386 | + /* Set up list view */ |
387 | + ListView lv = (ListView) findViewById(R.id.editorListView); |
388 | + adapter = new EditorItemAdapter(this, R.layout.list_item, |
389 | + getEditorItemList(benchmarkText)); |
390 | + lv.setAdapter(adapter); |
391 | + |
392 | + lv.setOnItemClickListener(new OnItemClickListener() { |
393 | + public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) { |
394 | + Bundle bundle = new Bundle(); |
395 | + bundle.putInt("item-pos", position); |
396 | + /* Show the right dialog, depending on the clicked list position */ |
397 | + if (position == ITEM_POSITION_SCENE_NAME) |
398 | + showDialog(DIALOG_SCENE_NAME_ID, bundle); |
399 | + else if (position >= ITEM_POSITION_SCENE_OPTION) |
400 | + showDialog(DIALOG_SCENE_OPTION_ID, bundle); |
401 | + } |
402 | + }); |
403 | + |
404 | + lv.setOnItemLongClickListener(new OnItemLongClickListener() { |
405 | + public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) { |
406 | + /* Reset the value of the long-clicked option */ |
407 | + if (position >= ITEM_POSITION_SCENE_OPTION) { |
408 | + EditorItem item = adapter.getItem(position); |
409 | + item.value = null; |
410 | + adapter.notifyDataSetChanged(); |
411 | + } |
412 | + return true; |
413 | + } |
414 | + }); |
415 | + } |
416 | + |
417 | + @Override |
418 | + protected Dialog onCreateDialog(int id, Bundle bundle) { |
419 | + final int itemPos = bundle.getInt("item-pos"); |
420 | + Dialog dialog; |
421 | + final int finalId = id; |
422 | + |
423 | + switch (id) { |
424 | + case DIALOG_SCENE_NAME_ID: |
425 | + { |
426 | + AlertDialog.Builder builder = new AlertDialog.Builder(this); |
427 | + builder.setTitle("Pick a scene"); |
428 | + builder.setItems(sceneNames, new DialogInterface.OnClickListener() { |
429 | + public void onClick(DialogInterface dialog, int item) { |
430 | + adapter.clear(); |
431 | + for (EditorItem ei: getEditorItemList(sceneNames[item])) |
432 | + adapter.add(ei); |
433 | + adapter.notifyDataSetChanged(); |
434 | + dismissDialog(DIALOG_SCENE_NAME_ID); |
435 | + } |
436 | + }); |
437 | + dialog = builder.create(); |
438 | + } |
439 | + break; |
440 | + |
441 | + case DIALOG_SCENE_OPTION_ID: |
442 | + { |
443 | + AlertDialog.Builder builder = new AlertDialog.Builder(this); |
444 | + final EditorItem item = adapter.getItem(itemPos); |
445 | + final EditText input = new EditText(this); |
446 | + if (item.value != null) |
447 | + input.setText(item.value); |
448 | + |
449 | + input.setOnEditorActionListener(new OnEditorActionListener() { |
450 | + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { |
451 | + if (actionId == EditorInfo.IME_ACTION_DONE || |
452 | + (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && |
453 | + event.getAction() == KeyEvent.ACTION_UP)) |
454 | + { |
455 | + item.value = v.getText().toString(); |
456 | + dismissDialog(DIALOG_SCENE_OPTION_ID); |
457 | + } |
458 | + return true; |
459 | + } |
460 | + }); |
461 | + builder.setTitle(item.option.name + ": " + item.option.description); |
462 | + dialog = builder.create(); |
463 | + ((AlertDialog)dialog).setView(input, 15, 6, 15, 6); |
464 | + dialog.getWindow().setSoftInputMode( |
465 | + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN | |
466 | + WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE |
467 | + ); |
468 | + |
469 | + } |
470 | + break; |
471 | + |
472 | + default: |
473 | + dialog = null; |
474 | + break; |
475 | + } |
476 | + |
477 | + if (dialog != null) { |
478 | + dialog.setOnDismissListener(new OnDismissListener() { |
479 | + public void onDismiss(DialogInterface dialog) { |
480 | + removeDialog(finalId); |
481 | + } |
482 | + }); |
483 | + } |
484 | + |
485 | + return dialog; |
486 | + } |
487 | + |
488 | + /** |
489 | + * Gets the value of an option. |
490 | + * |
491 | + * @param benchArray an array of option strings ("opt=val") |
492 | + * @param opt the options to get the value of |
493 | + * |
494 | + * @return the value or null |
495 | + */ |
496 | + private String getOptionValue(String[] benchArray, String opt) { |
497 | + String ret = null; |
498 | + |
499 | + /* Search from the end to the beginning */ |
500 | + for (int n = benchArray.length - 1; n >= 0; n--) { |
501 | + String s = benchArray[n].trim(); |
502 | + if (s.startsWith(opt + "=")) { |
503 | + int i = s.indexOf('='); |
504 | + if (i >= 0 && i + 1 < s.length()) { |
505 | + ret = s.substring(i + 1).trim(); |
506 | + break; |
507 | + } |
508 | + } |
509 | + } |
510 | + |
511 | + return ret; |
512 | + } |
513 | + |
514 | + /** |
515 | + * Gets the benchmark description string of the current editing state. |
516 | + * |
517 | + * @return the string |
518 | + */ |
519 | + private String getBenchmarkDescriptionText() { |
520 | + String ret = ""; |
521 | + |
522 | + for (int i = 0; i < adapter.getCount(); i++) { |
523 | + /* Convert each list item to a proper string representation */ |
524 | + EditorItem item = adapter.getItem(i); |
525 | + if (item == null) |
526 | + continue; |
527 | + |
528 | + String s = ""; |
529 | + |
530 | + /* |
531 | + * Append "opt=" if this is an option item, except the |
532 | + * "__custom__" item. |
533 | + */ |
534 | + if (item.option != null && item.value != null && |
535 | + !item.option.name.equals("__custom__")) |
536 | + { |
537 | + s += item.option.name + "="; |
538 | + } |
539 | + |
540 | + /* |
541 | + * Append the item value if this is not "__custom__". |
542 | + */ |
543 | + if (item.value != null && !item.value.equals("__custom__")) |
544 | + s += item.value; |
545 | + |
546 | + /* |
547 | + * Append ":" to the description string if needed. |
548 | + */ |
549 | + if (!s.isEmpty() && !ret.isEmpty()) |
550 | + ret += ":"; |
551 | + |
552 | + /* Append the item representation */ |
553 | + ret += s; |
554 | + } |
555 | + |
556 | + return ret; |
557 | + } |
558 | + |
559 | + /** |
560 | + * Creates an EditorItem list from a benchmark description string. |
561 | + * |
562 | + * @param benchDesc the benchmark description string |
563 | + * |
564 | + * @return the list |
565 | + */ |
566 | + private ArrayList<EditorItem> getEditorItemList(String benchDesc) { |
567 | + String[] benchArray = benchDesc.split(":"); |
568 | + String benchName = benchArray[0].trim(); |
569 | + |
570 | + if (benchName.isEmpty()) |
571 | + benchName = "__custom__"; |
572 | + |
573 | + /* Find SceneInfo from name */ |
574 | + SceneInfo sceneInfo = null; |
575 | + for (SceneInfo si: sceneInfoList) { |
576 | + if (si.name.equals(benchName)) { |
577 | + sceneInfo = si; |
578 | + break; |
579 | + } |
580 | + } |
581 | + |
582 | + /* If we couldn't find a matching SceneInfo, use __custom__ */ |
583 | + if (sceneInfo == null) { |
584 | + for (SceneInfo si: sceneInfoList) { |
585 | + if (si.name.equals("__custom__")) { |
586 | + sceneInfo = si; |
587 | + break; |
588 | + } |
589 | + } |
590 | + } |
591 | + |
592 | + ArrayList<EditorItem> l = new ArrayList<EditorItem>(); |
593 | + |
594 | + /* Append null item for Scene header */ |
595 | + l.add(null); |
596 | + |
597 | + /* Append scene name item */ |
598 | + l.add(new EditorItem(null, sceneInfo.name)); |
599 | + |
600 | + /* Append null item for Options header */ |
601 | + l.add(null); |
602 | + |
603 | + /* Append items to the list */ |
604 | + if (!sceneInfo.name.equals("__custom__")) { |
605 | + /* Append scene option items */ |
606 | + for (SceneInfo.Option opt: sceneInfo.options) |
607 | + l.add(new EditorItem(opt, getOptionValue(benchArray, opt.name))); |
608 | + } |
609 | + else { |
610 | + String desc = new String(benchDesc); |
611 | + if (desc.startsWith("__custom__")) |
612 | + desc = ""; |
613 | + |
614 | + /* Append scene option items (only one for __custom__) */ |
615 | + for (SceneInfo.Option opt: sceneInfo.options) |
616 | + l.add(new EditorItem(opt, desc)); |
617 | + } |
618 | + |
619 | + return l; |
620 | + } |
621 | + |
622 | + /** |
623 | + * Gets a list of information about the available scenes. |
624 | + * |
625 | + * @return the list |
626 | + */ |
627 | + private ArrayList<SceneInfo> getSceneInfoList() { |
628 | + ArrayList<SceneInfo> l = new ArrayList<SceneInfo>(); |
629 | + SceneInfo customSceneInfo = new SceneInfo("__custom__"); |
630 | + customSceneInfo.addOption("__custom__", "Custom benchmark string", ""); |
631 | + |
632 | + for (Parcelable p: getIntent().getParcelableArrayExtra("scene-info")) |
633 | + l.add((SceneInfo)p); |
634 | + |
635 | + /* Add the "__custom__" SceneInfo */ |
636 | + l.add(customSceneInfo); |
637 | + |
638 | + return l; |
639 | + } |
640 | + |
641 | + /** |
642 | + * Gets the array of scene names. |
643 | + * |
644 | + * @return the array |
645 | + */ |
646 | + private String[] getSceneNames() { |
647 | + ArrayList<String> l = new ArrayList<String>(); |
648 | + |
649 | + for (SceneInfo si: sceneInfoList) { |
650 | + if (!si.name.isEmpty()) |
651 | + l.add(si.name); |
652 | + } |
653 | + |
654 | + String[] a = new String[0]; |
655 | + return l.toArray(a); |
656 | + } |
657 | + |
658 | + |
659 | + static private class EditorItem { |
660 | + SceneInfo.Option option; |
661 | + |
662 | + public EditorItem(SceneInfo.Option o, String value) { |
663 | + this.option = o; |
664 | + this.value = value; |
665 | + } |
666 | + |
667 | + public String value; |
668 | + } |
669 | + |
670 | + /** |
671 | + * A ListView adapter that creates list item views from EditorItems |
672 | + */ |
673 | + private class EditorItemAdapter extends ArrayAdapter<EditorItem> { |
674 | + static final int VIEW_TYPE_HEADER = 0; |
675 | + static final int VIEW_TYPE_SCENE_NAME = 1; |
676 | + static final int VIEW_TYPE_SCENE_OPTION = 2; |
677 | + static final int VIEW_TYPE_COUNT = 3; |
678 | + |
679 | + public ArrayList<EditorItem> items; |
680 | + |
681 | + public EditorItemAdapter(Context context, int textViewResourceId, |
682 | + ArrayList<EditorItem> items) |
683 | + { |
684 | + super(context, textViewResourceId, items); |
685 | + this.items = items; |
686 | + } |
687 | + |
688 | + @Override |
689 | + public boolean isEnabled(int position) { |
690 | + return position == ITEM_POSITION_SCENE_NAME || |
691 | + position >= ITEM_POSITION_SCENE_OPTION; |
692 | + } |
693 | + |
694 | + @Override |
695 | + public int getItemViewType(int position) { |
696 | + if (position == ITEM_POSITION_SCENE_NAME) |
697 | + return VIEW_TYPE_SCENE_NAME; |
698 | + else if (position >= ITEM_POSITION_SCENE_OPTION) |
699 | + return VIEW_TYPE_SCENE_OPTION; |
700 | + else |
701 | + return VIEW_TYPE_HEADER; |
702 | + } |
703 | + |
704 | + @Override |
705 | + public int getViewTypeCount() { |
706 | + return VIEW_TYPE_COUNT; |
707 | + } |
708 | + |
709 | + @Override |
710 | + public View getView(int position, View convertView, ViewGroup parent) { |
711 | + int viewType = getItemViewType(position); |
712 | + View v = null; |
713 | + |
714 | + if (viewType == VIEW_TYPE_HEADER) |
715 | + v = getViewHeader(position, convertView); |
716 | + else if (viewType == VIEW_TYPE_SCENE_NAME) |
717 | + v = getViewScene(position, convertView); |
718 | + else if (viewType == VIEW_TYPE_SCENE_OPTION) |
719 | + v = getViewOption(position, convertView); |
720 | + |
721 | + return v; |
722 | + } |
723 | + |
724 | + private View getViewHeader(int position, View convertView) { |
725 | + /* Get the view/widget to use */ |
726 | + View v = convertView; |
727 | + if (v == null) { |
728 | + LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
729 | + v = vi.inflate(R.layout.list_header, null); |
730 | + } |
731 | + |
732 | + TextView tv = (TextView) v; |
733 | + |
734 | + if (position == ITEM_POSITION_SCENE_NAME_HEADER) |
735 | + tv.setText("Scene"); |
736 | + else if (position == ITEM_POSITION_SCENE_OPTION_HEADER) |
737 | + tv.setText("Options"); |
738 | + |
739 | + return tv; |
740 | + } |
741 | + |
742 | + private View getViewScene(int position, View convertView) { |
743 | + /* Get the view/widget to use */ |
744 | + View v = convertView; |
745 | + if (v == null) { |
746 | + LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
747 | + v = vi.inflate(R.layout.list_item, null); |
748 | + } |
749 | + |
750 | + EditorItem item = items.get(position); |
751 | + |
752 | + TextView title = (TextView) v.findViewById(R.id.title); |
753 | + TextView summary = (TextView) v.findViewById(R.id.summary); |
754 | + |
755 | + if (title != null) |
756 | + title.setText(item.value); |
757 | + if (summary != null) |
758 | + summary.setText("The scene to use"); |
759 | + |
760 | + return v; |
761 | + } |
762 | + |
763 | + private View getViewOption(int position, View convertView) { |
764 | + /* Get the view/widget to use */ |
765 | + View v = convertView; |
766 | + if (v == null) { |
767 | + LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
768 | + v = vi.inflate(R.layout.list_item, null); |
769 | + } |
770 | + |
771 | + EditorItem item = items.get(position); |
772 | + |
773 | + TextView title = (TextView) v.findViewById(R.id.title); |
774 | + TextView summary = (TextView) v.findViewById(R.id.summary); |
775 | + boolean hasUserSetValue = item.value != null; |
776 | + String value = hasUserSetValue ? item.value : item.option.defaultValue; |
777 | + |
778 | + if (title != null) { |
779 | + /* If the option has been edited by the user show it with emphasis */ |
780 | + SpannableString titleText = new SpannableString(item.option.name + " = " + value); |
781 | + ForegroundColorSpan span = new ForegroundColorSpan(hasUserSetValue ? Color.CYAN : Color.LTGRAY); |
782 | + titleText.setSpan(span, item.option.name.length() + " = ".length(), titleText.length(), 0); |
783 | + title.setText(titleText); |
784 | + } |
785 | + |
786 | + if (summary != null) |
787 | + summary.setText(item.option.description); |
788 | + |
789 | + return v; |
790 | + } |
791 | + } |
792 | +} |
793 | |
794 | === added file 'android/src/org/linaro/glmark2/GLVisualConfig.java' |
795 | --- android/src/org/linaro/glmark2/GLVisualConfig.java 1970-01-01 00:00:00 +0000 |
796 | +++ android/src/org/linaro/glmark2/GLVisualConfig.java 2012-07-09 10:15:24 +0000 |
797 | @@ -0,0 +1,44 @@ |
798 | +/* |
799 | + * Copyright © 2012 Linaro Limited |
800 | + * |
801 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
802 | + * |
803 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
804 | + * terms of the GNU General Public License as published by the Free Software |
805 | + * Foundation, either version 3 of the License, or (at your option) any later |
806 | + * version. |
807 | + * |
808 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
809 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
810 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
811 | + * details. |
812 | + * |
813 | + * You should have received a copy of the GNU General Public License along with |
814 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
815 | + * |
816 | + * Authors: |
817 | + * Alexandros Frantzis |
818 | + */ |
819 | +package org.linaro.glmark2; |
820 | + |
821 | +/** |
822 | + * Class that holds a configuration of a GL visual. |
823 | + */ |
824 | +class GLVisualConfig { |
825 | + public GLVisualConfig() {} |
826 | + public GLVisualConfig(int r, int g, int b, int a, int d, int buf) { |
827 | + red = r; |
828 | + green = g; |
829 | + blue = b; |
830 | + alpha = a; |
831 | + depth = d; |
832 | + buffer = buf; |
833 | + } |
834 | + |
835 | + public int red; |
836 | + public int green; |
837 | + public int blue; |
838 | + public int alpha; |
839 | + public int depth; |
840 | + public int buffer; |
841 | +} |
842 | |
843 | === added file 'android/src/org/linaro/glmark2/Glmark2Native.java' |
844 | --- android/src/org/linaro/glmark2/Glmark2Native.java 1970-01-01 00:00:00 +0000 |
845 | +++ android/src/org/linaro/glmark2/Glmark2Native.java 2012-07-09 10:15:24 +0000 |
846 | @@ -0,0 +1,33 @@ |
847 | +/* |
848 | + * Copyright © 2012 Linaro Limited |
849 | + * |
850 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
851 | + * |
852 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
853 | + * terms of the GNU General Public License as published by the Free Software |
854 | + * Foundation, either version 3 of the License, or (at your option) any later |
855 | + * version. |
856 | + * |
857 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
858 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
859 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
860 | + * details. |
861 | + * |
862 | + * You should have received a copy of the GNU General Public License along with |
863 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
864 | + * |
865 | + * Authors: |
866 | + * Alexandros Frantzis |
867 | + */ |
868 | +package org.linaro.glmark2; |
869 | + |
870 | +import android.content.res.AssetManager; |
871 | + |
872 | +class Glmark2Native { |
873 | + public static native void init(AssetManager assetManager, String args); |
874 | + public static native void resize(int w, int h); |
875 | + public static native boolean render(); |
876 | + public static native void done(); |
877 | + public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target); |
878 | + public static native SceneInfo[] getSceneInfo(AssetManager assetManager); |
879 | +} |
880 | |
881 | === modified file 'android/src/org/linaro/glmark2/Glmark2SurfaceView.java' |
882 | --- android/src/org/linaro/glmark2/Glmark2SurfaceView.java 2012-05-24 09:54:11 +0000 |
883 | +++ android/src/org/linaro/glmark2/Glmark2SurfaceView.java 2012-07-09 10:15:24 +0000 |
884 | @@ -1,9 +1,7 @@ |
885 | - |
886 | package org.linaro.glmark2; |
887 | |
888 | import android.graphics.PixelFormat; |
889 | import android.opengl.GLSurfaceView; |
890 | -import android.content.res.AssetManager; |
891 | import android.app.Activity; |
892 | import android.util.Log; |
893 | |
894 | @@ -12,29 +10,6 @@ |
895 | import javax.microedition.khronos.egl.EGLConfig; |
896 | import javax.microedition.khronos.opengles.GL10; |
897 | |
898 | -/** |
899 | - * Class that holds a configuration of a GL visual. |
900 | - */ |
901 | -class GLVisualConfig { |
902 | - public GLVisualConfig() {} |
903 | - public GLVisualConfig(int r, int g, int b, int a, int d, int buf) { |
904 | - red = r; |
905 | - green = g; |
906 | - blue = b; |
907 | - alpha = a; |
908 | - depth = d; |
909 | - buffer = buf; |
910 | - } |
911 | - |
912 | - public int red; |
913 | - public int green; |
914 | - public int blue; |
915 | - public int alpha; |
916 | - public int depth; |
917 | - public int buffer; |
918 | -} |
919 | - |
920 | - |
921 | class Glmark2SurfaceView extends GLSurfaceView { |
922 | |
923 | public static final String LOG_TAG = "glmark2"; |
924 | @@ -233,11 +208,3 @@ |
925 | |
926 | private Glmark2SurfaceView mView; |
927 | } |
928 | - |
929 | -class Glmark2Native { |
930 | - public static native void init(AssetManager assetManager, String args); |
931 | - public static native void resize(int w, int h); |
932 | - public static native boolean render(); |
933 | - public static native void done(); |
934 | - public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target); |
935 | -} |
936 | |
937 | === added file 'android/src/org/linaro/glmark2/MainActivity.java' |
938 | --- android/src/org/linaro/glmark2/MainActivity.java 1970-01-01 00:00:00 +0000 |
939 | +++ android/src/org/linaro/glmark2/MainActivity.java 2012-07-09 10:15:24 +0000 |
940 | @@ -0,0 +1,302 @@ |
941 | +/* |
942 | + * Copyright © 2012 Linaro Limited |
943 | + * |
944 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
945 | + * |
946 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
947 | + * terms of the GNU General Public License as published by the Free Software |
948 | + * Foundation, either version 3 of the License, or (at your option) any later |
949 | + * version. |
950 | + * |
951 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
952 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
953 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
954 | + * details. |
955 | + * |
956 | + * You should have received a copy of the GNU General Public License along with |
957 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
958 | + * |
959 | + * Authors: |
960 | + * Alexandros Frantzis |
961 | + */ |
962 | +package org.linaro.glmark2; |
963 | + |
964 | +import java.util.ArrayList; |
965 | + |
966 | +import android.os.Bundle; |
967 | +import android.app.Activity; |
968 | +import android.app.AlertDialog; |
969 | +import android.app.Dialog; |
970 | +import android.content.Context; |
971 | +import android.content.DialogInterface; |
972 | +import android.content.DialogInterface.OnDismissListener; |
973 | +import android.content.Intent; |
974 | +import android.widget.BaseAdapter; |
975 | +import android.widget.ArrayAdapter; |
976 | +import android.widget.ListView; |
977 | +import android.widget.TextView; |
978 | +import android.widget.Button; |
979 | +import android.view.LayoutInflater; |
980 | +import android.view.View; |
981 | +import android.view.ViewGroup; |
982 | +import android.util.Log; |
983 | +import android.widget.AdapterView.OnItemClickListener; |
984 | +import android.widget.AdapterView.OnItemLongClickListener; |
985 | +import android.widget.AdapterView; |
986 | + |
987 | +public class MainActivity extends Activity { |
988 | + public static final int DIALOG_BENCHMARK_ACTIONS_ID = 0; |
989 | + |
990 | + /** |
991 | + * The supported benchmark item actions. |
992 | + */ |
993 | + public enum BenchmarkItemAction { |
994 | + EDIT, DELETE, CLONE, MOVEUP, MOVEDOWN |
995 | + } |
996 | + |
997 | + ArrayList<String> benchmarks; |
998 | + BaseAdapter adapter; |
999 | + SceneInfo[] sceneInfoList; |
1000 | + |
1001 | + @Override |
1002 | + public void onCreate(Bundle savedInstanceState) { |
1003 | + super.onCreate(savedInstanceState); |
1004 | + setContentView(R.layout.activity_main); |
1005 | + ArrayList<String> savedBenchmarks = null; |
1006 | + |
1007 | + if (savedInstanceState != null) |
1008 | + savedBenchmarks = savedInstanceState.getStringArrayList("benchmarks"); |
1009 | + |
1010 | + init(savedBenchmarks); |
1011 | + } |
1012 | + |
1013 | + @Override |
1014 | + protected void onSaveInstanceState(Bundle outState) { |
1015 | + super.onSaveInstanceState(outState); |
1016 | + outState.putStringArrayList("benchmarks", benchmarks); |
1017 | + } |
1018 | + |
1019 | + @Override |
1020 | + protected Dialog onCreateDialog(int id, Bundle bundle) { |
1021 | + final CharSequence[] benchmarkActions = {"Delete", "Clone", "Move Up", "Move Down"}; |
1022 | + final BenchmarkItemAction[] benchmarkActionsId = { |
1023 | + BenchmarkItemAction.DELETE, BenchmarkItemAction.CLONE, |
1024 | + BenchmarkItemAction.MOVEUP, BenchmarkItemAction.MOVEDOWN |
1025 | + }; |
1026 | + final int benchmarkPos = bundle.getInt("benchmark-pos"); |
1027 | + final int finalId = id; |
1028 | + |
1029 | + Dialog dialog; |
1030 | + |
1031 | + switch (id) { |
1032 | + case DIALOG_BENCHMARK_ACTIONS_ID: |
1033 | + AlertDialog.Builder builder = new AlertDialog.Builder(this); |
1034 | + builder.setTitle("Pick an action"); |
1035 | + builder.setItems(benchmarkActions, new DialogInterface.OnClickListener() { |
1036 | + public void onClick(DialogInterface dialog, int item) { |
1037 | + doBenchmarkItemAction(benchmarkPos, benchmarkActionsId[item], null); |
1038 | + dismissDialog(DIALOG_BENCHMARK_ACTIONS_ID); |
1039 | + } |
1040 | + }); |
1041 | + dialog = builder.create(); |
1042 | + break; |
1043 | + |
1044 | + default: |
1045 | + dialog = null; |
1046 | + break; |
1047 | + } |
1048 | + |
1049 | + if (dialog != null) { |
1050 | + dialog.setOnDismissListener(new OnDismissListener() { |
1051 | + public void onDismiss(DialogInterface dialog) { |
1052 | + removeDialog(finalId); |
1053 | + } |
1054 | + }); |
1055 | + } |
1056 | + |
1057 | + return dialog; |
1058 | + } |
1059 | + |
1060 | + @Override |
1061 | + public void onActivityResult(int requestCode, int resultCode, Intent data) { |
1062 | + if (resultCode == RESULT_OK) { |
1063 | + String benchmarkText = data.getStringExtra("benchmark-text"); |
1064 | + int benchmarkPos = data.getIntExtra("benchmark-pos", 0); |
1065 | + doBenchmarkItemAction(benchmarkPos, BenchmarkItemAction.EDIT, benchmarkText); |
1066 | + } |
1067 | + } |
1068 | + |
1069 | + /** |
1070 | + * Initialize the activity. |
1071 | + * |
1072 | + * @param savedBenchmarks a list of benchmarks to load the list with (or null) |
1073 | + */ |
1074 | + private void init(ArrayList<String> savedBenchmarks) |
1075 | + { |
1076 | + /* Fill in the benchmark list */ |
1077 | + if (savedBenchmarks == null) { |
1078 | + benchmarks = new ArrayList<String>(); |
1079 | + benchmarks.add("Add benchmark..."); |
1080 | + } |
1081 | + else { |
1082 | + benchmarks = savedBenchmarks; |
1083 | + } |
1084 | + |
1085 | + /* Get Scene information */ |
1086 | + sceneInfoList = Glmark2Native.getSceneInfo(getAssets()); |
1087 | + |
1088 | + /* Set up the run button */ |
1089 | + Button button = (Button) findViewById(R.id.runButton); |
1090 | + button.setOnClickListener(new View.OnClickListener() { |
1091 | + public void onClick(View v) { |
1092 | + Intent intent = new Intent(MainActivity.this, Glmark2Activity.class); |
1093 | + String args = ""; |
1094 | + for (int i = 0; i < benchmarks.size() - 1; i++) |
1095 | + args += "-b " + benchmarks.get(i) + " "; |
1096 | + if (!args.isEmpty()) |
1097 | + intent.putExtra("args", args); |
1098 | + startActivity(intent); |
1099 | + } |
1100 | + }); |
1101 | + |
1102 | + /* Set up the benchmark list view */ |
1103 | + ListView lv = (ListView) findViewById(R.id.benchmarkListView); |
1104 | + adapter = new BenchmarkAdapter(this, R.layout.list_item, benchmarks); |
1105 | + lv.setAdapter(adapter); |
1106 | + |
1107 | + lv.setOnItemClickListener(new OnItemClickListener() { |
1108 | + public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) { |
1109 | + Intent intent = new Intent(MainActivity.this, EditorActivity.class); |
1110 | + String t = benchmarks.get(position); |
1111 | + if (position == benchmarks.size() - 1) |
1112 | + t = ""; |
1113 | + intent.putExtra("benchmark-text", t); |
1114 | + intent.putExtra("benchmark-pos", position); |
1115 | + intent.putExtra("scene-info", sceneInfoList); |
1116 | + startActivityForResult(intent, 1); |
1117 | + } |
1118 | + }); |
1119 | + |
1120 | + lv.setOnItemLongClickListener(new OnItemLongClickListener() { |
1121 | + public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) { |
1122 | + if (position < benchmarks.size() - 1) { |
1123 | + Bundle bundle = new Bundle(); |
1124 | + bundle.putInt("benchmark-pos", position); |
1125 | + showDialog(DIALOG_BENCHMARK_ACTIONS_ID, bundle); |
1126 | + } |
1127 | + return true; |
1128 | + } |
1129 | + }); |
1130 | + |
1131 | + } |
1132 | + |
1133 | + /** |
1134 | + * Perform an action on an listview benchmark item. |
1135 | + * |
1136 | + * @param position the position of the item in the listview |
1137 | + * @param action the action to perform |
1138 | + * @param data extra data needed by some actions |
1139 | + */ |
1140 | + private void doBenchmarkItemAction(int position, BenchmarkItemAction action, String data) |
1141 | + { |
1142 | + int scrollPosition = position; |
1143 | + |
1144 | + switch(action) { |
1145 | + case EDIT: |
1146 | + if (position == benchmarks.size() - 1) { |
1147 | + benchmarks.add(position, data); |
1148 | + scrollPosition = position + 1; |
1149 | + } |
1150 | + else { |
1151 | + benchmarks.set(position, data); |
1152 | + } |
1153 | + break; |
1154 | + case DELETE: |
1155 | + benchmarks.remove(position); |
1156 | + break; |
1157 | + case CLONE: |
1158 | + { |
1159 | + String s = benchmarks.get(position); |
1160 | + benchmarks.add(position, s); |
1161 | + scrollPosition = position + 1; |
1162 | + } |
1163 | + break; |
1164 | + case MOVEUP: |
1165 | + if (position > 0) { |
1166 | + String up = benchmarks.get(position - 1); |
1167 | + String s = benchmarks.get(position); |
1168 | + benchmarks.set(position - 1, s); |
1169 | + benchmarks.set(position, up); |
1170 | + scrollPosition = position - 1; |
1171 | + } |
1172 | + break; |
1173 | + case MOVEDOWN: |
1174 | + if (position < benchmarks.size() - 2) { |
1175 | + String down = benchmarks.get(position + 1); |
1176 | + String s = benchmarks.get(position); |
1177 | + benchmarks.set(position + 1, s); |
1178 | + benchmarks.set(position, down); |
1179 | + scrollPosition = position + 1; |
1180 | + } |
1181 | + break; |
1182 | + default: |
1183 | + break; |
1184 | + } |
1185 | + |
1186 | + |
1187 | + adapter.notifyDataSetChanged(); |
1188 | + |
1189 | + /* Scroll the list view so that the item of interest remains visible */ |
1190 | + final int finalScrollPosition = scrollPosition; |
1191 | + final ListView lv = (ListView) findViewById(R.id.benchmarkListView); |
1192 | + lv.post(new Runnable() { |
1193 | + @Override |
1194 | + public void run() { |
1195 | + lv.smoothScrollToPosition(finalScrollPosition); |
1196 | + } |
1197 | + }); |
1198 | + } |
1199 | + |
1200 | + /** |
1201 | + * A ListView adapter that creates item views from benchmark strings. |
1202 | + */ |
1203 | + private class BenchmarkAdapter extends ArrayAdapter<String> { |
1204 | + private ArrayList<String> items; |
1205 | + |
1206 | + public BenchmarkAdapter(Context context, int textViewResourceId, ArrayList<String> items) { |
1207 | + super(context, textViewResourceId, items); |
1208 | + this.items = items; |
1209 | + } |
1210 | + |
1211 | + @Override |
1212 | + public View getView(int position, View convertView, ViewGroup parent) { |
1213 | + /* Get the view/widget to use */ |
1214 | + View v = convertView; |
1215 | + if (v == null) { |
1216 | + LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
1217 | + v = vi.inflate(R.layout.list_item, null); |
1218 | + } |
1219 | + |
1220 | + /* Split the benchmark into its scene name and its options */ |
1221 | + String benchmark = items.get(position); |
1222 | + String[] ba = benchmark.split(":", 2); |
1223 | + |
1224 | + if (ba != null) { |
1225 | + TextView title = (TextView) v.findViewById(R.id.title); |
1226 | + TextView summary = (TextView) v.findViewById(R.id.summary); |
1227 | + title.setText(""); |
1228 | + summary.setText(""); |
1229 | + |
1230 | + if (title != null && ba.length > 0) |
1231 | + title.setText(ba[0]); |
1232 | + if (summary != null && ba.length > 1) |
1233 | + summary.setText(ba[1]); |
1234 | + } |
1235 | + return v; |
1236 | + } |
1237 | + } |
1238 | + |
1239 | + static { |
1240 | + System.loadLibrary("glmark2-android"); |
1241 | + } |
1242 | +} |
1243 | |
1244 | === added file 'android/src/org/linaro/glmark2/SceneInfo.java' |
1245 | --- android/src/org/linaro/glmark2/SceneInfo.java 1970-01-01 00:00:00 +0000 |
1246 | +++ android/src/org/linaro/glmark2/SceneInfo.java 2012-07-09 10:15:24 +0000 |
1247 | @@ -0,0 +1,90 @@ |
1248 | +/* |
1249 | + * Copyright © 2012 Linaro Limited |
1250 | + * |
1251 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
1252 | + * |
1253 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
1254 | + * terms of the GNU General Public License as published by the Free Software |
1255 | + * Foundation, either version 3 of the License, or (at your option) any later |
1256 | + * version. |
1257 | + * |
1258 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
1259 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1260 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
1261 | + * details. |
1262 | + * |
1263 | + * You should have received a copy of the GNU General Public License along with |
1264 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
1265 | + * |
1266 | + * Authors: |
1267 | + * Alexandros Frantzis |
1268 | + */ |
1269 | +package org.linaro.glmark2; |
1270 | + |
1271 | +import android.os.Parcelable; |
1272 | +import android.os.Parcel; |
1273 | +import java.util.ArrayList; |
1274 | + |
1275 | +class SceneInfo implements Parcelable { |
1276 | + static class Option { |
1277 | + String name; |
1278 | + String description; |
1279 | + String defaultValue; |
1280 | + } |
1281 | + |
1282 | + public SceneInfo(String name) { |
1283 | + this.name = name; |
1284 | + this.options = new ArrayList<Option>(); |
1285 | + } |
1286 | + |
1287 | + public void addOption(String name, String description, String defaultValue) { |
1288 | + Option opt = new Option(); |
1289 | + opt.name = name; |
1290 | + opt.description = description; |
1291 | + opt.defaultValue = defaultValue; |
1292 | + this.options.add(opt); |
1293 | + } |
1294 | + |
1295 | + public String name; |
1296 | + public ArrayList<Option> options; |
1297 | + |
1298 | + /* Parcelable interface */ |
1299 | + public static final Parcelable.Creator<SceneInfo> CREATOR = |
1300 | + new Parcelable.Creator<SceneInfo>() { |
1301 | + public SceneInfo createFromParcel(Parcel in) { |
1302 | + return new SceneInfo(in); |
1303 | + } |
1304 | + |
1305 | + public SceneInfo[] newArray(int size) { |
1306 | + return new SceneInfo[size]; |
1307 | + } |
1308 | + }; |
1309 | + |
1310 | + public int describeContents() { |
1311 | + return 0; |
1312 | + } |
1313 | + |
1314 | + public void writeToParcel(Parcel out, int flags) { |
1315 | + out.writeString(name); |
1316 | + out.writeInt(options.size()); |
1317 | + for (Option opt: options) { |
1318 | + out.writeString(opt.name); |
1319 | + out.writeString(opt.description); |
1320 | + out.writeString(opt.defaultValue); |
1321 | + } |
1322 | + } |
1323 | + |
1324 | + private SceneInfo(Parcel in) { |
1325 | + name = in.readString(); |
1326 | + options = new ArrayList<Option>(); |
1327 | + |
1328 | + int size = in.readInt(); |
1329 | + for (int i = 0; i < size; i++) { |
1330 | + Option opt = new Option(); |
1331 | + opt.name = in.readString(); |
1332 | + opt.description = in.readString(); |
1333 | + opt.defaultValue = in.readString(); |
1334 | + options.add(opt); |
1335 | + } |
1336 | + } |
1337 | +} |
1338 | |
1339 | === modified file 'src/android.cpp' |
1340 | --- src/android.cpp 2012-06-29 12:27:16 +0000 |
1341 | +++ src/android.cpp 2012-07-09 10:15:24 +0000 |
1342 | @@ -169,6 +169,77 @@ |
1343 | vc.buffer = env->GetIntField(jvc, fid); |
1344 | } |
1345 | |
1346 | +/** |
1347 | + * Creates a SceneInfo Java object from a Scene. |
1348 | + * |
1349 | + * @param env the JNIEnv |
1350 | + */ |
1351 | +static jobject |
1352 | +scene_info_from_scene(JNIEnv *env, Scene &scene) |
1353 | +{ |
1354 | + jclass cls = env->FindClass("org/linaro/glmark2/SceneInfo"); |
1355 | + jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V"); |
1356 | + jmethodID add_option = env->GetMethodID(cls, "addOption", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); |
1357 | + |
1358 | + /* Create the SceneInfo object */ |
1359 | + jstring name = env->NewStringUTF(scene.name().c_str()); |
1360 | + jobject scene_info = env->NewObject(cls, constructor, name); |
1361 | + |
1362 | + const std::map<std::string, Scene::Option> &options = scene.options(); |
1363 | + |
1364 | + /* Add options to the SceneInfo object */ |
1365 | + for (std::map<std::string, Scene::Option>::const_iterator opt_iter = options.begin(); |
1366 | + opt_iter != options.end(); |
1367 | + opt_iter++) |
1368 | + { |
1369 | + const Scene::Option &opt = opt_iter->second; |
1370 | + jstring opt_name = env->NewStringUTF(opt.name.c_str()); |
1371 | + jstring opt_description = env->NewStringUTF(opt.description.c_str()); |
1372 | + jstring opt_default_value = env->NewStringUTF(opt.default_value.c_str()); |
1373 | + |
1374 | + env->CallVoidMethod(scene_info, add_option, |
1375 | + opt_name, |
1376 | + opt_description, |
1377 | + opt_default_value); |
1378 | + |
1379 | + env->DeleteLocalRef(opt_name); |
1380 | + env->DeleteLocalRef(opt_description); |
1381 | + env->DeleteLocalRef(opt_default_value); |
1382 | + } |
1383 | + |
1384 | + return scene_info; |
1385 | +} |
1386 | + |
1387 | +class DummyCanvas : public Canvas { |
1388 | +public: |
1389 | + DummyCanvas() : Canvas(0, 0) {} |
1390 | +}; |
1391 | + |
1392 | +/** |
1393 | + * Creates all the available scenes and adds them to the supplied vector. |
1394 | + * |
1395 | + * @param scenes the vector to add the scenes to |
1396 | + * @param canvas the canvas to create the scenes with |
1397 | + */ |
1398 | +static void |
1399 | +create_and_add_scenes(std::vector<Scene*>& scenes, Canvas& canvas) |
1400 | +{ |
1401 | + scenes.push_back(new SceneDefaultOptions(canvas)); |
1402 | + scenes.push_back(new SceneBuild(canvas)); |
1403 | + scenes.push_back(new SceneTexture(canvas)); |
1404 | + scenes.push_back(new SceneShading(canvas)); |
1405 | + scenes.push_back(new SceneConditionals(canvas)); |
1406 | + scenes.push_back(new SceneFunction(canvas)); |
1407 | + scenes.push_back(new SceneLoop(canvas)); |
1408 | + scenes.push_back(new SceneBump(canvas)); |
1409 | + scenes.push_back(new SceneEffect2D(canvas)); |
1410 | + scenes.push_back(new ScenePulsar(canvas)); |
1411 | + scenes.push_back(new SceneDesktop(canvas)); |
1412 | + scenes.push_back(new SceneBuffer(canvas)); |
1413 | + scenes.push_back(new SceneIdeas(canvas)); |
1414 | + scenes.push_back(new SceneTerrain(canvas)); |
1415 | +} |
1416 | + |
1417 | |
1418 | void |
1419 | Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz, |
1420 | @@ -209,20 +280,17 @@ |
1421 | Log::info("glmark2 %s\n", GLMARK_VERSION); |
1422 | g_canvas->print_info(); |
1423 | |
1424 | - Benchmark::register_scene(*new SceneDefaultOptions(*g_canvas)); |
1425 | - Benchmark::register_scene(*new SceneBuild(*g_canvas)); |
1426 | - Benchmark::register_scene(*new SceneTexture(*g_canvas)); |
1427 | - Benchmark::register_scene(*new SceneShading(*g_canvas)); |
1428 | - Benchmark::register_scene(*new SceneConditionals(*g_canvas)); |
1429 | - Benchmark::register_scene(*new SceneFunction(*g_canvas)); |
1430 | - Benchmark::register_scene(*new SceneLoop(*g_canvas)); |
1431 | - Benchmark::register_scene(*new SceneBump(*g_canvas)); |
1432 | - Benchmark::register_scene(*new SceneEffect2D(*g_canvas)); |
1433 | - Benchmark::register_scene(*new ScenePulsar(*g_canvas)); |
1434 | - Benchmark::register_scene(*new SceneDesktop(*g_canvas)); |
1435 | - Benchmark::register_scene(*new SceneBuffer(*g_canvas)); |
1436 | - Benchmark::register_scene(*new SceneIdeas(*g_canvas)); |
1437 | - Benchmark::register_scene(*new SceneTerrain(*g_canvas)); |
1438 | + std::vector<Scene*> scenes; |
1439 | + |
1440 | + /* Add and register scenes */ |
1441 | + create_and_add_scenes(scenes, *g_canvas); |
1442 | + |
1443 | + for (std::vector<Scene*>::const_iterator iter = scenes.begin(); |
1444 | + iter != scenes.end(); |
1445 | + iter++) |
1446 | + { |
1447 | + Benchmark::register_scene(**iter); |
1448 | + } |
1449 | |
1450 | g_benchmark_collection = new BenchmarkCollection(); |
1451 | g_benchmark_collection->populate_from_options(); |
1452 | @@ -288,6 +356,42 @@ |
1453 | return vc.match_score(target); |
1454 | } |
1455 | |
1456 | +jobjectArray |
1457 | +Java_org_linaro_glmark2_native_getSceneInfo(JNIEnv* env, jclass clazz, |
1458 | + jobject asset_manager) |
1459 | +{ |
1460 | + static_cast<void>(clazz); |
1461 | + |
1462 | + Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager)); |
1463 | + |
1464 | + std::vector<Scene*> scenes; |
1465 | + DummyCanvas canvas; |
1466 | + std::vector<jobject> si_vector; |
1467 | + |
1468 | + create_and_add_scenes(scenes, canvas); |
1469 | + |
1470 | + /* Create SceneInfo instances for all the scenes */ |
1471 | + for (std::vector<Scene*>::const_iterator iter = scenes.begin(); |
1472 | + iter != scenes.end(); |
1473 | + iter++) |
1474 | + { |
1475 | + jobject si = scene_info_from_scene(env, **iter); |
1476 | + si_vector.push_back(si); |
1477 | + } |
1478 | + |
1479 | + /* Create a SceneInfo[] array */ |
1480 | + jclass si_cls = env->FindClass("org/linaro/glmark2/SceneInfo"); |
1481 | + jobjectArray si_array = env->NewObjectArray(si_vector.size(), si_cls, 0); |
1482 | + |
1483 | + /* Populate the SceneInfo[] array */ |
1484 | + for (size_t i = 0; i < si_vector.size(); i++) |
1485 | + env->SetObjectArrayElement(si_array, i, si_vector[i]); |
1486 | + |
1487 | + Util::dispose_pointer_vector(scenes); |
1488 | + |
1489 | + return si_array; |
1490 | +} |
1491 | + |
1492 | static JNINativeMethod glmark2_native_methods[] = { |
1493 | { |
1494 | "init", |
1495 | @@ -313,6 +417,11 @@ |
1496 | "scoreConfig", |
1497 | "(Lorg/linaro/glmark2/GLVisualConfig;Lorg/linaro/glmark2/GLVisualConfig;)I", |
1498 | reinterpret_cast<void*>(Java_org_linaro_glmark2_native_scoreConfig) |
1499 | + }, |
1500 | + { |
1501 | + "getSceneInfo", |
1502 | + "(Landroid/content/res/AssetManager;)[Lorg/linaro/glmark2/SceneInfo;", |
1503 | + reinterpret_cast<void*>(Java_org_linaro_glmark2_native_getSceneInfo) |
1504 | } |
1505 | }; |
1506 |
I'm not much of a java guy, but it seems fine.