diff options
author | Alexandros Frantzis <alexandros.frantzis@linaro.org> | 2012-07-10 12:47:01 +0300 |
---|---|---|
committer | Alexandros Frantzis <alexandros.frantzis@linaro.org> | 2012-07-10 12:47:01 +0300 |
commit | 2a6ed135286d7099a59a8faff54ddf221df7f5ef (patch) | |
tree | 92d96b8f057ef2a6ae4bac79e987fa16f182262f | |
parent | dadc5dbcf7be248a256b073e2e7b91ea8805713d (diff) | |
parent | d92b6df21a6b508b49fd11e6e32840f575b6f9a5 (diff) | |
download | glmark2-2a6ed135286d7099a59a8faff54ddf221df7f5ef.tar.gz |
Android: Create a GUI for defining and running benchmarks.
-rw-r--r-- | android/AndroidManifest.xml | 18 | ||||
-rw-r--r-- | android/build.xml | 92 | ||||
-rw-r--r-- | android/default.properties | 11 | ||||
-rw-r--r-- | android/project.properties | 14 | ||||
-rw-r--r-- | android/res/layout/activity_editor.xml | 34 | ||||
-rw-r--r-- | android/res/layout/activity_main.xml | 20 | ||||
-rw-r--r-- | android/res/layout/list_header.xml | 5 | ||||
-rw-r--r-- | android/res/layout/list_item.xml | 32 | ||||
-rw-r--r-- | android/res/values/strings.xml | 3 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/EditorActivity.java | 522 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/GLVisualConfig.java | 44 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/Glmark2Native.java | 33 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/Glmark2SurfaceView.java | 33 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/MainActivity.java | 302 | ||||
-rw-r--r-- | android/src/org/linaro/glmark2/SceneInfo.java | 90 | ||||
-rw-r--r-- | src/android.cpp | 139 |
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) } }; |