aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandros Frantzis <alexandros.frantzis@linaro.org>2012-07-10 12:47:01 +0300
committerAlexandros Frantzis <alexandros.frantzis@linaro.org>2012-07-10 12:47:01 +0300
commit2a6ed135286d7099a59a8faff54ddf221df7f5ef (patch)
tree92d96b8f057ef2a6ae4bac79e987fa16f182262f
parentdadc5dbcf7be248a256b073e2e7b91ea8805713d (diff)
parentd92b6df21a6b508b49fd11e6e32840f575b6f9a5 (diff)
downloadglmark2-2a6ed135286d7099a59a8faff54ddf221df7f5ef.tar.gz
Android: Create a GUI for defining and running benchmarks.
-rw-r--r--android/AndroidManifest.xml18
-rw-r--r--android/build.xml92
-rw-r--r--android/default.properties11
-rw-r--r--android/project.properties14
-rw-r--r--android/res/layout/activity_editor.xml34
-rw-r--r--android/res/layout/activity_main.xml20
-rw-r--r--android/res/layout/list_header.xml5
-rw-r--r--android/res/layout/list_item.xml32
-rw-r--r--android/res/values/strings.xml3
-rw-r--r--android/src/org/linaro/glmark2/EditorActivity.java522
-rw-r--r--android/src/org/linaro/glmark2/GLVisualConfig.java44
-rw-r--r--android/src/org/linaro/glmark2/Glmark2Native.java33
-rw-r--r--android/src/org/linaro/glmark2/Glmark2SurfaceView.java33
-rw-r--r--android/src/org/linaro/glmark2/MainActivity.java302
-rw-r--r--android/src/org/linaro/glmark2/SceneInfo.java90
-rw-r--r--src/android.cpp139
16 files changed, 1331 insertions, 61 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index b0719c7..32701a4 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -3,14 +3,28 @@
android:versionCode="1"
android:versionName="2012.06" package="org.linaro.glmark2">
<application android:label="@string/app_name">
- <activity android:label="@string/app_name"
+ <activity android:name="org.linaro.glmark2.MainActivity"
+ android:label="@string/title_activity_main">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="org.linaro.glmark2.EditorActivity"
+ android:label="@string/title_activity_editor" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:label="@string/title_activity_glmark2"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
+ android:process=":glmark2"
android:name="org.linaro.glmark2.Glmark2Activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
diff --git a/android/build.xml b/android/build.xml
new file mode 100644
index 0000000..8d11dd3
--- /dev/null
+++ b/android/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Glmark2" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ 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."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/android/default.properties b/android/default.properties
deleted file mode 100644
index 66db0d1..0000000
--- a/android/default.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-10
diff --git a/android/project.properties b/android/project.properties
new file mode 100644
index 0000000..b7c2081
--- /dev/null
+++ b/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-10
diff --git a/android/res/layout/activity_editor.xml b/android/res/layout/activity_editor.xml
new file mode 100644
index 0000000..3e2461f
--- /dev/null
+++ b/android/res/layout/activity_editor.xml
@@ -0,0 +1,34 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout android:id="@+id/buttonLinearLayout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true">
+
+ <Button android:id="@+id/runButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_alignParentBottom="true"
+ android:text="Run" />
+
+ <Button android:id="@+id/saveButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_alignParentBottom="true"
+ android:text="Save" />
+
+ </LinearLayout>
+
+
+ <ListView android:id="@+id/editorListView"
+ android:layout_above="@id/buttonLinearLayout"
+ android:layout_weight="1.0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true" />
+</RelativeLayout>
diff --git a/android/res/layout/activity_main.xml b/android/res/layout/activity_main.xml
new file mode 100644
index 0000000..a68f596
--- /dev/null
+++ b/android/res/layout/activity_main.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <Button android:id="@+id/runButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:text="Run" />
+
+ <ListView android:id="@+id/benchmarkListView"
+ android:layout_above="@id/runButton"
+ android:layout_weight="1.0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true" />
+
+
+</RelativeLayout>
diff --git a/android/res/layout/list_header.xml b/android/res/layout/list_header.xml
new file mode 100644
index 0000000..9c5bd8f
--- /dev/null
+++ b/android/res/layout/list_header.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:id="@+id/listHeader" />
diff --git a/android/res/layout/list_item.xml b/android/res/layout/list_item.xml
new file mode 100644
index 0000000..7b3233d
--- /dev/null
+++ b/android/res/layout/list_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingRight="?android:attr/scrollbarSize" >
+
+ <RelativeLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@id/title"
+ android:layout_below="@id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index 607787b..9fda68e 100644
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GLMark2</string>
+ <string name="title_activity_main">GLMark2</string>
+ <string name="title_activity_editor">GLMark2 Benchmark Editor</string>
+ <string name="title_activity_glmark2">GLMark2</string>
</resources>
diff --git a/android/src/org/linaro/glmark2/EditorActivity.java b/android/src/org/linaro/glmark2/EditorActivity.java
new file mode 100644
index 0000000..2ff30f3
--- /dev/null
+++ b/android/src/org/linaro/glmark2/EditorActivity.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.text.SpannableString;
+import android.text.style.ForegroundColorSpan;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+public class EditorActivity extends Activity {
+ public static final int DIALOG_SCENE_NAME_ID = 0;
+ public static final int DIALOG_SCENE_OPTION_ID = 1;
+
+ public static final int ITEM_POSITION_SCENE_NAME_HEADER = 0;
+ public static final int ITEM_POSITION_SCENE_NAME = 1;
+ public static final int ITEM_POSITION_SCENE_OPTION_HEADER = 2;
+ public static final int ITEM_POSITION_SCENE_OPTION = 3;
+
+ private EditorItemAdapter adapter;
+ private ArrayList<SceneInfo> sceneInfoList;
+ private String[] sceneNames;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_editor);
+
+ /* Get information about the available scenes */
+ sceneInfoList = getSceneInfoList();
+ sceneNames = getSceneNames();
+
+ /* Read information sent by the main activity */
+ final int benchmarkPos = this.getIntent().getIntExtra("benchmark-pos", 0);
+ String benchmarkText = getIntent().getStringExtra("benchmark-text");
+ if (benchmarkText.isEmpty())
+ benchmarkText = sceneNames[0];
+
+ /* Set up the run button */
+ Button runButton = (Button) findViewById(R.id.runButton);
+ runButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(EditorActivity.this, Glmark2Activity.class);
+ String args = "-b " + getBenchmarkDescriptionText();
+ intent.putExtra("args", args);
+ startActivity(intent);
+ }
+ });
+
+ /* Set up the save button */
+ Button button = (Button) findViewById(R.id.saveButton);
+ button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ String newBenchmarkText = getBenchmarkDescriptionText();
+ Intent intent = new Intent();
+ intent.putExtra("benchmark-text", newBenchmarkText);
+ intent.putExtra("benchmark-pos", benchmarkPos);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ });
+
+ /* Set up list view */
+ ListView lv = (ListView) findViewById(R.id.editorListView);
+ adapter = new EditorItemAdapter(this, R.layout.list_item,
+ getEditorItemList(benchmarkText));
+ lv.setAdapter(adapter);
+
+ lv.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("item-pos", position);
+ /* Show the right dialog, depending on the clicked list position */
+ if (position == ITEM_POSITION_SCENE_NAME)
+ showDialog(DIALOG_SCENE_NAME_ID, bundle);
+ else if (position >= ITEM_POSITION_SCENE_OPTION)
+ showDialog(DIALOG_SCENE_OPTION_ID, bundle);
+ }
+ });
+
+ lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) {
+ /* Reset the value of the long-clicked option */
+ if (position >= ITEM_POSITION_SCENE_OPTION) {
+ EditorItem item = adapter.getItem(position);
+ item.value = null;
+ adapter.notifyDataSetChanged();
+ }
+ return true;
+ }
+ });
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id, Bundle bundle) {
+ final int itemPos = bundle.getInt("item-pos");
+ Dialog dialog;
+ final int finalId = id;
+
+ switch (id) {
+ case DIALOG_SCENE_NAME_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Pick a scene");
+ builder.setItems(sceneNames, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ adapter.clear();
+ for (EditorItem ei: getEditorItemList(sceneNames[item]))
+ adapter.add(ei);
+ adapter.notifyDataSetChanged();
+ dismissDialog(DIALOG_SCENE_NAME_ID);
+ }
+ });
+ dialog = builder.create();
+ }
+ break;
+
+ case DIALOG_SCENE_OPTION_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final EditorItem item = adapter.getItem(itemPos);
+ final EditText input = new EditText(this);
+ if (item.value != null)
+ input.setText(item.value);
+
+ input.setOnEditorActionListener(new OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE ||
+ (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER &&
+ event.getAction() == KeyEvent.ACTION_UP))
+ {
+ item.value = v.getText().toString();
+ dismissDialog(DIALOG_SCENE_OPTION_ID);
+ }
+ return true;
+ }
+ });
+ builder.setTitle(item.option.name + ": " + item.option.description);
+ dialog = builder.create();
+ ((AlertDialog)dialog).setView(input, 15, 6, 15, 6);
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
+ );
+
+ }
+ break;
+
+ default:
+ dialog = null;
+ break;
+ }
+
+ if (dialog != null) {
+ dialog.setOnDismissListener(new OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ removeDialog(finalId);
+ }
+ });
+ }
+
+ return dialog;
+ }
+
+ /**
+ * Gets the value of an option.
+ *
+ * @param benchArray an array of option strings ("opt=val")
+ * @param opt the options to get the value of
+ *
+ * @return the value or null
+ */
+ private String getOptionValue(String[] benchArray, String opt) {
+ String ret = null;
+
+ /* Search from the end to the beginning */
+ for (int n = benchArray.length - 1; n >= 0; n--) {
+ String s = benchArray[n].trim();
+ if (s.startsWith(opt + "=")) {
+ int i = s.indexOf('=');
+ if (i >= 0 && i + 1 < s.length()) {
+ ret = s.substring(i + 1).trim();
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ /**
+ * Gets the benchmark description string of the current editing state.
+ *
+ * @return the string
+ */
+ private String getBenchmarkDescriptionText() {
+ String ret = "";
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ /* Convert each list item to a proper string representation */
+ EditorItem item = adapter.getItem(i);
+ if (item == null)
+ continue;
+
+ String s = "";
+
+ /*
+ * Append "opt=" if this is an option item, except the
+ * "__custom__" item.
+ */
+ if (item.option != null && item.value != null &&
+ !item.option.name.equals("__custom__"))
+ {
+ s += item.option.name + "=";
+ }
+
+ /*
+ * Append the item value if this is not "__custom__".
+ */
+ if (item.value != null && !item.value.equals("__custom__"))
+ s += item.value;
+
+ /*
+ * Append ":" to the description string if needed.
+ */
+ if (!s.isEmpty() && !ret.isEmpty())
+ ret += ":";
+
+ /* Append the item representation */
+ ret += s;
+ }
+
+ return ret;
+ }
+
+ /**
+ * Creates an EditorItem list from a benchmark description string.
+ *
+ * @param benchDesc the benchmark description string
+ *
+ * @return the list
+ */
+ private ArrayList<EditorItem> getEditorItemList(String benchDesc) {
+ String[] benchArray = benchDesc.split(":");
+ String benchName = benchArray[0].trim();
+
+ if (benchName.isEmpty())
+ benchName = "__custom__";
+
+ /* Find SceneInfo from name */
+ SceneInfo sceneInfo = null;
+ for (SceneInfo si: sceneInfoList) {
+ if (si.name.equals(benchName)) {
+ sceneInfo = si;
+ break;
+ }
+ }
+
+ /* If we couldn't find a matching SceneInfo, use __custom__ */
+ if (sceneInfo == null) {
+ for (SceneInfo si: sceneInfoList) {
+ if (si.name.equals("__custom__")) {
+ sceneInfo = si;
+ break;
+ }
+ }
+ }
+
+ ArrayList<EditorItem> l = new ArrayList<EditorItem>();
+
+ /* Append null item for Scene header */
+ l.add(null);
+
+ /* Append scene name item */
+ l.add(new EditorItem(null, sceneInfo.name));
+
+ /* Append null item for Options header */
+ l.add(null);
+
+ /* Append items to the list */
+ if (!sceneInfo.name.equals("__custom__")) {
+ /* Append scene option items */
+ for (SceneInfo.Option opt: sceneInfo.options)
+ l.add(new EditorItem(opt, getOptionValue(benchArray, opt.name)));
+ }
+ else {
+ String desc = new String(benchDesc);
+ if (desc.startsWith("__custom__"))
+ desc = "";
+
+ /* Append scene option items (only one for __custom__) */
+ for (SceneInfo.Option opt: sceneInfo.options)
+ l.add(new EditorItem(opt, desc));
+ }
+
+ return l;
+ }
+
+ /**
+ * Gets a list of information about the available scenes.
+ *
+ * @return the list
+ */
+ private ArrayList<SceneInfo> getSceneInfoList() {
+ ArrayList<SceneInfo> l = new ArrayList<SceneInfo>();
+ SceneInfo customSceneInfo = new SceneInfo("__custom__");
+ customSceneInfo.addOption("__custom__", "Custom benchmark string", "");
+
+ for (Parcelable p: getIntent().getParcelableArrayExtra("scene-info"))
+ l.add((SceneInfo)p);
+
+ /* Sort SceneInfo list by name */
+ Collections.sort(l, new Comparator<SceneInfo>() {
+ public int compare(SceneInfo s1, SceneInfo s2) {
+ return s1.name.compareTo(s2.name);
+ }
+ });
+
+ /* Add the "__custom__" SceneInfo */
+ l.add(customSceneInfo);
+
+ return l;
+ }
+
+ /**
+ * Gets the array of scene names.
+ *
+ * @return the array
+ */
+ private String[] getSceneNames() {
+ ArrayList<String> l = new ArrayList<String>();
+
+ for (SceneInfo si: sceneInfoList) {
+ if (!si.name.isEmpty())
+ l.add(si.name);
+ }
+
+ String[] a = new String[0];
+ return l.toArray(a);
+ }
+
+
+ static private class EditorItem {
+ SceneInfo.Option option;
+
+ public EditorItem(SceneInfo.Option o, String value) {
+ this.option = o;
+ this.value = value;
+ }
+
+ public String value;
+ }
+
+ /**
+ * A ListView adapter that creates list item views from EditorItems
+ */
+ private class EditorItemAdapter extends ArrayAdapter<EditorItem> {
+ static final int VIEW_TYPE_HEADER = 0;
+ static final int VIEW_TYPE_SCENE_NAME = 1;
+ static final int VIEW_TYPE_SCENE_OPTION = 2;
+ static final int VIEW_TYPE_COUNT = 3;
+
+ public ArrayList<EditorItem> items;
+
+ public EditorItemAdapter(Context context, int textViewResourceId,
+ ArrayList<EditorItem> items)
+ {
+ super(context, textViewResourceId, items);
+ this.items = items;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position == ITEM_POSITION_SCENE_NAME ||
+ position >= ITEM_POSITION_SCENE_OPTION;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position == ITEM_POSITION_SCENE_NAME)
+ return VIEW_TYPE_SCENE_NAME;
+ else if (position >= ITEM_POSITION_SCENE_OPTION)
+ return VIEW_TYPE_SCENE_OPTION;
+ else
+ return VIEW_TYPE_HEADER;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return VIEW_TYPE_COUNT;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ int viewType = getItemViewType(position);
+ View v = null;
+
+ if (viewType == VIEW_TYPE_HEADER)
+ v = getViewHeader(position, convertView);
+ else if (viewType == VIEW_TYPE_SCENE_NAME)
+ v = getViewScene(position, convertView);
+ else if (viewType == VIEW_TYPE_SCENE_OPTION)
+ v = getViewOption(position, convertView);
+
+ return v;
+ }
+
+ private View getViewHeader(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_header, null);
+ }
+
+ TextView tv = (TextView) v;
+
+ if (position == ITEM_POSITION_SCENE_NAME_HEADER)
+ tv.setText("Scene");
+ else if (position == ITEM_POSITION_SCENE_OPTION_HEADER)
+ tv.setText("Options");
+
+ return tv;
+ }
+
+ private View getViewScene(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ EditorItem item = items.get(position);
+
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+
+ if (title != null)
+ title.setText(item.value);
+ if (summary != null)
+ summary.setText("The scene to use");
+
+ return v;
+ }
+
+ private View getViewOption(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ EditorItem item = items.get(position);
+
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+ boolean hasUserSetValue = item.value != null;
+ String value = hasUserSetValue ? item.value : item.option.defaultValue;
+
+ if (title != null) {
+ /* If the option has been edited by the user show it with emphasis */
+ SpannableString titleText = new SpannableString(item.option.name + " = " + value);
+ ForegroundColorSpan span = new ForegroundColorSpan(hasUserSetValue ? Color.CYAN : Color.LTGRAY);
+ titleText.setSpan(span, item.option.name.length() + " = ".length(), titleText.length(), 0);
+ title.setText(titleText);
+ }
+
+ if (summary != null)
+ summary.setText(item.option.description);
+
+ return v;
+ }
+ }
+}
diff --git a/android/src/org/linaro/glmark2/GLVisualConfig.java b/android/src/org/linaro/glmark2/GLVisualConfig.java
new file mode 100644
index 0000000..9aeb5ca
--- /dev/null
+++ b/android/src/org/linaro/glmark2/GLVisualConfig.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+/**
+ * Class that holds a configuration of a GL visual.
+ */
+class GLVisualConfig {
+ public GLVisualConfig() {}
+ public GLVisualConfig(int r, int g, int b, int a, int d, int buf) {
+ red = r;
+ green = g;
+ blue = b;
+ alpha = a;
+ depth = d;
+ buffer = buf;
+ }
+
+ public int red;
+ public int green;
+ public int blue;
+ public int alpha;
+ public int depth;
+ public int buffer;
+}
diff --git a/android/src/org/linaro/glmark2/Glmark2Native.java b/android/src/org/linaro/glmark2/Glmark2Native.java
new file mode 100644
index 0000000..0f2fd26
--- /dev/null
+++ b/android/src/org/linaro/glmark2/Glmark2Native.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.content.res.AssetManager;
+
+class Glmark2Native {
+ public static native void init(AssetManager assetManager, String args);
+ public static native void resize(int w, int h);
+ public static native boolean render();
+ public static native void done();
+ public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target);
+ public static native SceneInfo[] getSceneInfo(AssetManager assetManager);
+}
diff --git a/android/src/org/linaro/glmark2/Glmark2SurfaceView.java b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
index 425c6a7..1a64837 100644
--- a/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
+++ b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
@@ -1,9 +1,7 @@
-
package org.linaro.glmark2;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
-import android.content.res.AssetManager;
import android.app.Activity;
import android.util.Log;
@@ -12,29 +10,6 @@ import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
-/**
- * Class that holds a configuration of a GL visual.
- */
-class GLVisualConfig {
- public GLVisualConfig() {}
- public GLVisualConfig(int r, int g, int b, int a, int d, int buf) {
- red = r;
- green = g;
- blue = b;
- alpha = a;
- depth = d;
- buffer = buf;
- }
-
- public int red;
- public int green;
- public int blue;
- public int alpha;
- public int depth;
- public int buffer;
-}
-
-
class Glmark2SurfaceView extends GLSurfaceView {
public static final String LOG_TAG = "glmark2";
@@ -233,11 +208,3 @@ class Glmark2Renderer implements GLSurfaceView.Renderer {
private Glmark2SurfaceView mView;
}
-
-class Glmark2Native {
- public static native void init(AssetManager assetManager, String args);
- public static native void resize(int w, int h);
- public static native boolean render();
- public static native void done();
- public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target);
-}
diff --git a/android/src/org/linaro/glmark2/MainActivity.java b/android/src/org/linaro/glmark2/MainActivity.java
new file mode 100644
index 0000000..fa11acb
--- /dev/null
+++ b/android/src/org/linaro/glmark2/MainActivity.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.util.ArrayList;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.widget.BaseAdapter;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Button;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.util.Log;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.AdapterView;
+
+public class MainActivity extends Activity {
+ public static final int DIALOG_BENCHMARK_ACTIONS_ID = 0;
+
+ /**
+ * The supported benchmark item actions.
+ */
+ public enum BenchmarkItemAction {
+ EDIT, DELETE, CLONE, MOVEUP, MOVEDOWN
+ }
+
+ ArrayList<String> benchmarks;
+ BaseAdapter adapter;
+ SceneInfo[] sceneInfoList;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ArrayList<String> savedBenchmarks = null;
+
+ if (savedInstanceState != null)
+ savedBenchmarks = savedInstanceState.getStringArrayList("benchmarks");
+
+ init(savedBenchmarks);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putStringArrayList("benchmarks", benchmarks);
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id, Bundle bundle) {
+ final CharSequence[] benchmarkActions = {"Delete", "Clone", "Move Up", "Move Down"};
+ final BenchmarkItemAction[] benchmarkActionsId = {
+ BenchmarkItemAction.DELETE, BenchmarkItemAction.CLONE,
+ BenchmarkItemAction.MOVEUP, BenchmarkItemAction.MOVEDOWN
+ };
+ final int benchmarkPos = bundle.getInt("benchmark-pos");
+ final int finalId = id;
+
+ Dialog dialog;
+
+ switch (id) {
+ case DIALOG_BENCHMARK_ACTIONS_ID:
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Pick an action");
+ builder.setItems(benchmarkActions, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ doBenchmarkItemAction(benchmarkPos, benchmarkActionsId[item], null);
+ dismissDialog(DIALOG_BENCHMARK_ACTIONS_ID);
+ }
+ });
+ dialog = builder.create();
+ break;
+
+ default:
+ dialog = null;
+ break;
+ }
+
+ if (dialog != null) {
+ dialog.setOnDismissListener(new OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ removeDialog(finalId);
+ }
+ });
+ }
+
+ return dialog;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_OK) {
+ String benchmarkText = data.getStringExtra("benchmark-text");
+ int benchmarkPos = data.getIntExtra("benchmark-pos", 0);
+ doBenchmarkItemAction(benchmarkPos, BenchmarkItemAction.EDIT, benchmarkText);
+ }
+ }
+
+ /**
+ * Initialize the activity.
+ *
+ * @param savedBenchmarks a list of benchmarks to load the list with (or null)
+ */
+ private void init(ArrayList<String> savedBenchmarks)
+ {
+ /* Fill in the benchmark list */
+ if (savedBenchmarks == null) {
+ benchmarks = new ArrayList<String>();
+ benchmarks.add("Add benchmark...");
+ }
+ else {
+ benchmarks = savedBenchmarks;
+ }
+
+ /* Get Scene information */
+ sceneInfoList = Glmark2Native.getSceneInfo(getAssets());
+
+ /* Set up the run button */
+ Button button = (Button) findViewById(R.id.runButton);
+ button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(MainActivity.this, Glmark2Activity.class);
+ String args = "";
+ for (int i = 0; i < benchmarks.size() - 1; i++)
+ args += "-b " + benchmarks.get(i) + " ";
+ if (!args.isEmpty())
+ intent.putExtra("args", args);
+ startActivity(intent);
+ }
+ });
+
+ /* Set up the benchmark list view */
+ ListView lv = (ListView) findViewById(R.id.benchmarkListView);
+ adapter = new BenchmarkAdapter(this, R.layout.list_item, benchmarks);
+ lv.setAdapter(adapter);
+
+ lv.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
+ Intent intent = new Intent(MainActivity.this, EditorActivity.class);
+ String t = benchmarks.get(position);
+ if (position == benchmarks.size() - 1)
+ t = "";
+ intent.putExtra("benchmark-text", t);
+ intent.putExtra("benchmark-pos", position);
+ intent.putExtra("scene-info", sceneInfoList);
+ startActivityForResult(intent, 1);
+ }
+ });
+
+ lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) {
+ if (position < benchmarks.size() - 1) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("benchmark-pos", position);
+ showDialog(DIALOG_BENCHMARK_ACTIONS_ID, bundle);
+ }
+ return true;
+ }
+ });
+
+ }
+
+ /**
+ * Perform an action on an listview benchmark item.
+ *
+ * @param position the position of the item in the listview
+ * @param action the action to perform
+ * @param data extra data needed by some actions
+ */
+ private void doBenchmarkItemAction(int position, BenchmarkItemAction action, String data)
+ {
+ int scrollPosition = position;
+
+ switch(action) {
+ case EDIT:
+ if (position == benchmarks.size() - 1) {
+ benchmarks.add(position, data);
+ scrollPosition = position + 1;
+ }
+ else {
+ benchmarks.set(position, data);
+ }
+ break;
+ case DELETE:
+ benchmarks.remove(position);
+ break;
+ case CLONE:
+ {
+ String s = benchmarks.get(position);
+ benchmarks.add(position, s);
+ scrollPosition = position + 1;
+ }
+ break;
+ case MOVEUP:
+ if (position > 0) {
+ String up = benchmarks.get(position - 1);
+ String s = benchmarks.get(position);
+ benchmarks.set(position - 1, s);
+ benchmarks.set(position, up);
+ scrollPosition = position - 1;
+ }
+ break;
+ case MOVEDOWN:
+ if (position < benchmarks.size() - 2) {
+ String down = benchmarks.get(position + 1);
+ String s = benchmarks.get(position);
+ benchmarks.set(position + 1, s);
+ benchmarks.set(position, down);
+ scrollPosition = position + 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ adapter.notifyDataSetChanged();
+
+ /* Scroll the list view so that the item of interest remains visible */
+ final int finalScrollPosition = scrollPosition;
+ final ListView lv = (ListView) findViewById(R.id.benchmarkListView);
+ lv.post(new Runnable() {
+ @Override
+ public void run() {
+ lv.smoothScrollToPosition(finalScrollPosition);
+ }
+ });
+ }
+
+ /**
+ * A ListView adapter that creates item views from benchmark strings.
+ */
+ private class BenchmarkAdapter extends ArrayAdapter<String> {
+ private ArrayList<String> items;
+
+ public BenchmarkAdapter(Context context, int textViewResourceId, ArrayList<String> items) {
+ super(context, textViewResourceId, items);
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ /* Split the benchmark into its scene name and its options */
+ String benchmark = items.get(position);
+ String[] ba = benchmark.split(":", 2);
+
+ if (ba != null) {
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+ title.setText("");
+ summary.setText("");
+
+ if (title != null && ba.length > 0)
+ title.setText(ba[0]);
+ if (summary != null && ba.length > 1)
+ summary.setText(ba[1]);
+ }
+ return v;
+ }
+ }
+
+ static {
+ System.loadLibrary("glmark2-android");
+ }
+}
diff --git a/android/src/org/linaro/glmark2/SceneInfo.java b/android/src/org/linaro/glmark2/SceneInfo.java
new file mode 100644
index 0000000..7a85e07
--- /dev/null
+++ b/android/src/org/linaro/glmark2/SceneInfo.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import java.util.ArrayList;
+
+class SceneInfo implements Parcelable {
+ static class Option {
+ String name;
+ String description;
+ String defaultValue;
+ }
+
+ public SceneInfo(String name) {
+ this.name = name;
+ this.options = new ArrayList<Option>();
+ }
+
+ public void addOption(String name, String description, String defaultValue) {
+ Option opt = new Option();
+ opt.name = name;
+ opt.description = description;
+ opt.defaultValue = defaultValue;
+ this.options.add(opt);
+ }
+
+ public String name;
+ public ArrayList<Option> options;
+
+ /* Parcelable interface */
+ public static final Parcelable.Creator<SceneInfo> CREATOR =
+ new Parcelable.Creator<SceneInfo>() {
+ public SceneInfo createFromParcel(Parcel in) {
+ return new SceneInfo(in);
+ }
+
+ public SceneInfo[] newArray(int size) {
+ return new SceneInfo[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(name);
+ out.writeInt(options.size());
+ for (Option opt: options) {
+ out.writeString(opt.name);
+ out.writeString(opt.description);
+ out.writeString(opt.defaultValue);
+ }
+ }
+
+ private SceneInfo(Parcel in) {
+ name = in.readString();
+ options = new ArrayList<Option>();
+
+ int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ Option opt = new Option();
+ opt.name = in.readString();
+ opt.description = in.readString();
+ opt.defaultValue = in.readString();
+ options.add(opt);
+ }
+ }
+}
diff --git a/src/android.cpp b/src/android.cpp
index b8acdb5..64c7f35 100644
--- a/src/android.cpp
+++ b/src/android.cpp
@@ -169,6 +169,78 @@ gl_visual_config_from_jobject(JNIEnv *env, jobject jvc, GLVisualConfig &vc)
vc.buffer = env->GetIntField(jvc, fid);
}
+/**
+ * Creates a SceneInfo Java object from a Scene.
+ *
+ * @param env the JNIEnv
+ */
+static jobject
+scene_info_from_scene(JNIEnv *env, Scene &scene)
+{
+ jclass cls = env->FindClass("org/linaro/glmark2/SceneInfo");
+ jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V");
+ jmethodID add_option = env->GetMethodID(cls, "addOption", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+
+ /* Create the SceneInfo object */
+ jstring name = env->NewStringUTF(scene.name().c_str());
+ jobject scene_info = env->NewObject(cls, constructor, name);
+
+ const std::map<std::string, Scene::Option> &options = scene.options();
+
+ /* Add options to the SceneInfo object */
+ for (std::map<std::string, Scene::Option>::const_iterator opt_iter = options.begin();
+ opt_iter != options.end();
+ opt_iter++)
+ {
+ const Scene::Option &opt = opt_iter->second;
+ jstring opt_name = env->NewStringUTF(opt.name.c_str());
+ jstring opt_description = env->NewStringUTF(opt.description.c_str());
+ jstring opt_default_value = env->NewStringUTF(opt.default_value.c_str());
+
+ env->CallVoidMethod(scene_info, add_option,
+ opt_name,
+ opt_description,
+ opt_default_value);
+
+ env->DeleteLocalRef(opt_name);
+ env->DeleteLocalRef(opt_description);
+ env->DeleteLocalRef(opt_default_value);
+ }
+
+ return scene_info;
+}
+
+class DummyCanvas : public Canvas {
+public:
+ DummyCanvas() : Canvas(0, 0) {}
+};
+
+/**
+ * Creates all the available scenes and adds them to the supplied vector.
+ *
+ * @param scenes the vector to add the scenes to
+ * @param canvas the canvas to create the scenes with
+ */
+static void
+create_and_add_scenes(std::vector<Scene*>& scenes, Canvas& canvas)
+{
+ scenes.push_back(new SceneDefaultOptions(canvas));
+ scenes.push_back(new SceneBuild(canvas));
+ scenes.push_back(new SceneTexture(canvas));
+ scenes.push_back(new SceneShading(canvas));
+ scenes.push_back(new SceneConditionals(canvas));
+ scenes.push_back(new SceneFunction(canvas));
+ scenes.push_back(new SceneLoop(canvas));
+ scenes.push_back(new SceneBump(canvas));
+ scenes.push_back(new SceneEffect2D(canvas));
+ scenes.push_back(new ScenePulsar(canvas));
+ scenes.push_back(new SceneDesktop(canvas));
+ scenes.push_back(new SceneBuffer(canvas));
+ scenes.push_back(new SceneIdeas(canvas));
+ scenes.push_back(new SceneTerrain(canvas));
+ scenes.push_back(new SceneJellyfish(canvas));
+}
+
void
Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz,
@@ -209,21 +281,17 @@ Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz,
Log::info("glmark2 %s\n", GLMARK_VERSION);
g_canvas->print_info();
- Benchmark::register_scene(*new SceneDefaultOptions(*g_canvas));
- Benchmark::register_scene(*new SceneBuild(*g_canvas));
- Benchmark::register_scene(*new SceneTexture(*g_canvas));
- Benchmark::register_scene(*new SceneShading(*g_canvas));
- Benchmark::register_scene(*new SceneConditionals(*g_canvas));
- Benchmark::register_scene(*new SceneFunction(*g_canvas));
- Benchmark::register_scene(*new SceneLoop(*g_canvas));
- Benchmark::register_scene(*new SceneBump(*g_canvas));
- Benchmark::register_scene(*new SceneEffect2D(*g_canvas));
- Benchmark::register_scene(*new ScenePulsar(*g_canvas));
- Benchmark::register_scene(*new SceneDesktop(*g_canvas));
- Benchmark::register_scene(*new SceneBuffer(*g_canvas));
- Benchmark::register_scene(*new SceneIdeas(*g_canvas));
- Benchmark::register_scene(*new SceneTerrain(*g_canvas));
- Benchmark::register_scene(*new SceneJellyfish(*g_canvas));
+ std::vector<Scene*> scenes;
+
+ /* Add and register scenes */
+ create_and_add_scenes(scenes, *g_canvas);
+
+ for (std::vector<Scene*>::const_iterator iter = scenes.begin();
+ iter != scenes.end();
+ iter++)
+ {
+ Benchmark::register_scene(**iter);
+ }
g_benchmark_collection = new BenchmarkCollection();
g_benchmark_collection->populate_from_options();
@@ -289,6 +357,42 @@ Java_org_linaro_glmark2_native_scoreConfig(JNIEnv* env, jclass clazz,
return vc.match_score(target);
}
+jobjectArray
+Java_org_linaro_glmark2_native_getSceneInfo(JNIEnv* env, jclass clazz,
+ jobject asset_manager)
+{
+ static_cast<void>(clazz);
+
+ Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
+
+ std::vector<Scene*> scenes;
+ DummyCanvas canvas;
+ std::vector<jobject> si_vector;
+
+ create_and_add_scenes(scenes, canvas);
+
+ /* Create SceneInfo instances for all the scenes */
+ for (std::vector<Scene*>::const_iterator iter = scenes.begin();
+ iter != scenes.end();
+ iter++)
+ {
+ jobject si = scene_info_from_scene(env, **iter);
+ si_vector.push_back(si);
+ }
+
+ /* Create a SceneInfo[] array */
+ jclass si_cls = env->FindClass("org/linaro/glmark2/SceneInfo");
+ jobjectArray si_array = env->NewObjectArray(si_vector.size(), si_cls, 0);
+
+ /* Populate the SceneInfo[] array */
+ for (size_t i = 0; i < si_vector.size(); i++)
+ env->SetObjectArrayElement(si_array, i, si_vector[i]);
+
+ Util::dispose_pointer_vector(scenes);
+
+ return si_array;
+}
+
static JNINativeMethod glmark2_native_methods[] = {
{
"init",
@@ -314,6 +418,11 @@ static JNINativeMethod glmark2_native_methods[] = {
"scoreConfig",
"(Lorg/linaro/glmark2/GLVisualConfig;Lorg/linaro/glmark2/GLVisualConfig;)I",
reinterpret_cast<void*>(Java_org_linaro_glmark2_native_scoreConfig)
+ },
+ {
+ "getSceneInfo",
+ "(Landroid/content/res/AssetManager;)[Lorg/linaro/glmark2/SceneInfo;",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_getSceneInfo)
}
};