diff options
Diffstat (limited to 'platform_tools')
7 files changed, 292 insertions, 17 deletions
diff --git a/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.cpp b/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.cpp index 6098643b99..7ce43cc158 100644 --- a/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.cpp +++ b/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.cpp @@ -44,11 +44,13 @@ struct WindowGlue { jmethodID m_inval; jmethodID m_queueSkEvent; jmethodID m_startTimer; + jmethodID m_getMSAASampleCount; WindowGlue() { m_obj = NULL; m_inval = NULL; m_queueSkEvent = NULL; m_startTimer = NULL; + m_getMSAASampleCount = NULL; } } gWindowGlue; @@ -58,6 +60,23 @@ SampleWindow* gWindow; ///////////// SkOSWindow impl ///////////// /////////////////////////////////////////// +bool SkOSWindow::attach(SkBackEndTypes /* attachType */, int /*msaaSampleCount*/, AttachmentInfo* info) +{ + JNIEnv* env = gActivityGlue.m_env; + if (!env || !gWindowGlue.m_getMSAASampleCount || !gWindowGlue.m_obj) { + return false; + } + if (env->IsSameObject(gWindowGlue.m_obj, NULL)) { + SkDebugf("ERROR: The JNI WeakRef to the Window is invalid"); + return false; + } + info->fSampleCount = env->CallIntMethod(gWindowGlue.m_obj, gWindowGlue.m_getMSAASampleCount); + + // This is the value requested in SkiaSampleView.java. + info->fStencilBits = 8; + return true; +} + void SkOSWindow::onSetTitle(const char title[]) { JNIEnv* env = gActivityGlue.m_env; @@ -155,7 +174,7 @@ static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], } JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_init(JNIEnv* env, - jobject thiz, jobject jsampleActivity) + jobject thiz, jobject jsampleActivity, jint msaaSampleCount) { // setup jni hooks to the java activity gActivityGlue.m_env = env; @@ -173,12 +192,25 @@ JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_init(JNIEnv* env, gWindowGlue.m_inval = GetJMethod(env, clazz, "requestRender", "()V"); gWindowGlue.m_queueSkEvent = GetJMethod(env, clazz, "queueSkEvent", "()V"); gWindowGlue.m_startTimer = GetJMethod(env, clazz, "startTimer", "(I)V"); + gWindowGlue.m_getMSAASampleCount = GetJMethod(env, clazz, "getMSAASampleCount", "()I"); env->DeleteLocalRef(clazz); application_init(); + SkTArray<const char*> args; + + args.push_back("SampleApp"); // TODO: push ability to select skp dir into the UI - const char* argv[] = { "SampleApp", "--pictureDir", "/sdcard/skiabot/skia_skp" }; - gWindow = new SampleWindow(NULL, sizeof(argv)/sizeof(char*), const_cast<char**>(argv), NULL); + args.push_back("--pictureDir"); + args.push_back("/sdcard/skiabot/skia_skp"); + + SkString msaaSampleCountString; + if (msaaSampleCount > 0) { + args.push_back("--msaa"); + msaaSampleCountString.appendS32(static_cast<uint32_t>(msaaSampleCount)); + args.push_back(msaaSampleCountString.c_str()); + } + + gWindow = new SampleWindow(NULL, args.count(), const_cast<char**>(args.begin()), NULL); // send the list of slides up to the activity const int slideCount = gWindow->sampleCount(); diff --git a/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.h b/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.h index 5d371235fe..023f679425 100644 --- a/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.h +++ b/platform_tools/android/app/jni/com_skia_SkiaSampleRenderer.h @@ -10,10 +10,10 @@ extern "C" { /* * Class: com_skia_SkiaSampleRenderer * Method: init - * Signature: (Lcom/skia/SkiaSampleActivity;)V + * Signature: (Lcom/skia/SkiaSampleActivity;I)V */ JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_init - (JNIEnv *, jobject, jobject); + (JNIEnv *, jobject, jobject, jint); /* * Class: com_skia_SkiaSampleRenderer diff --git a/platform_tools/android/app/res/menu/action_bar.xml b/platform_tools/android/app/res/menu/action_bar.xml index 2e8cf70125..72e135e43b 100644 --- a/platform_tools/android/app/res/menu/action_bar.xml +++ b/platform_tools/android/app/res/menu/action_bar.xml @@ -43,6 +43,32 @@ android:title="@string/bbox" /> <item + android:id="@+id/glcontext_menu" + android:title="@string/glcontext_menu"> + <menu> + <item + android:id="@+id/glcontext_opengles" + android:title="@string/glcontext_opengles" + android:checkable="true" + /> + <item + android:id="@+id/glcontext_msaa4_opengles" + android:title="@string/glcontext_msaa4_opengles" + android:checkable="true" + /> + <item + android:id="@+id/glcontext_opengl" + android:title="@string/glcontext_opengl" + android:checkable="true" + /> + <item + android:id="@+id/glcontext_msaa4_opengl" + android:title="@string/glcontext_msaa4_opengl" + android:checkable="true" + /> + </menu> + </item> + <item android:id="@+id/save_to_pdf" android:title="@string/save_to_pdf" /> diff --git a/platform_tools/android/app/res/values/strings.xml b/platform_tools/android/app/res/values/strings.xml index 610ef380b2..b0b4e7b74b 100644 --- a/platform_tools/android/app/res/values/strings.xml +++ b/platform_tools/android/app/res/values/strings.xml @@ -10,4 +10,9 @@ <string name="save_to_pdf">Save to PDF</string> <string name="save_failed">Save Failed</string> <string name="file_saved">%s saved!</string> + <string name="glcontext_menu">Set OpenGL Context Type</string> + <string name="glcontext_opengles">OpenGL ES</string> + <string name="glcontext_msaa4_opengles">OpenGL ES, MSAA4</string> + <string name="glcontext_opengl">OpenGL</string> + <string name="glcontext_msaa4_opengl">OpenGL, MSAA4</string> </resources>
\ No newline at end of file diff --git a/platform_tools/android/app/src/com/skia/SkiaSampleActivity.java b/platform_tools/android/app/src/com/skia/SkiaSampleActivity.java index 0a7a569728..090d6ad14c 100644 --- a/platform_tools/android/app/src/com/skia/SkiaSampleActivity.java +++ b/platform_tools/android/app/src/com/skia/SkiaSampleActivity.java @@ -11,6 +11,7 @@ import android.app.ActionBar; import android.app.Activity; import android.app.DownloadManager; import android.content.Context; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -38,7 +39,6 @@ public class SkiaSampleActivity extends Activity setContentView(R.layout.layout); mTitle = (TextView) findViewById(R.id.title_view); - mSampleView = new SkiaSampleView(this); mSlideList = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1); try { @@ -50,18 +50,28 @@ public class SkiaSampleActivity extends Activity try { System.loadLibrary("SampleApp"); - LinearLayout holder = (LinearLayout) findViewById(R.id.holder); - holder.addView(mSampleView, new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); + createSampleView(false, 0); setupActionBar(); - } catch (UnsatisfiedLinkError e) { mTitle.setText("ERROR: native library could not be loaded"); } } + private void createSampleView(boolean useOpenGLAPI, int msaaSampleCount) { + if (mSampleView != null) { + ViewGroup viewGroup = (ViewGroup) mSampleView.getParent(); + viewGroup.removeView(mSampleView); + mSampleView.terminate(); + } + + mSampleView = new SkiaSampleView(this, useOpenGLAPI, msaaSampleCount); + LinearLayout holder = (LinearLayout) findViewById(R.id.holder); + holder.addView(mSampleView, new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + } + private void setupActionBar() { ActionBar.OnNavigationListener navigationCallback = new ActionBar.OnNavigationListener() { @Override @@ -81,7 +91,7 @@ public class SkiaSampleActivity extends Activity @Override protected void onResume () { super.onResume(); - if (mSampleView.getWidth() > 0 && mSampleView.getHeight() > 0) { + if (mSampleView != null && mSampleView.getWidth() > 0 && mSampleView.getHeight() > 0) { //TODO try mSampleView.requestRender() instead mSampleView.inval(); } @@ -89,7 +99,9 @@ public class SkiaSampleActivity extends Activity @Override public void onDestroy() { - mSampleView.terminate(); + if (mSampleView != null) { + mSampleView.terminate(); + } super.onDestroy(); } @@ -100,7 +112,38 @@ public class SkiaSampleActivity extends Activity } @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (mSampleView != null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + ((MenuItem) menu.findItem(R.id.glcontext_menu)) + .setEnabled(false); + + } else { + boolean usesOpenGLAPI = mSampleView.getUsesOpenGLAPI(); + boolean isMSAA4 = mSampleView.getMSAASampleCount() == 4; + + ((MenuItem) menu.findItem(R.id.glcontext_opengles)) + .setChecked(!usesOpenGLAPI && !isMSAA4); + + ((MenuItem) menu.findItem(R.id.glcontext_msaa4_opengles)) + .setChecked(!usesOpenGLAPI && isMSAA4); + + ((MenuItem) menu.findItem(R.id.glcontext_opengl)) + .setChecked(usesOpenGLAPI && !isMSAA4); + + ((MenuItem) menu.findItem(R.id.glcontext_msaa4_opengl)) + .setChecked(usesOpenGLAPI && isMSAA4); + } + } + return true; + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { + if (mSampleView == null) { + return false; + } + switch (item.getItemId()) { case R.id.overview: mSampleView.showOverview(); @@ -129,6 +172,14 @@ public class SkiaSampleActivity extends Activity case R.id.save_to_pdf: mSampleView.saveToPDF(); return true; + case R.id.glcontext_opengles: + return setOpenGLContextSettings(false, 0); + case R.id.glcontext_msaa4_opengles: + return setOpenGLContextSettings(false, 4); + case R.id.glcontext_opengl: + return setOpenGLContextSettings(true, 0); + case R.id.glcontext_msaa4_opengl: + return setOpenGLContextSettings(true, 4); default: return false; } @@ -203,4 +254,16 @@ public class SkiaSampleActivity extends Activity } }.start(); } + + private boolean setOpenGLContextSettings(boolean requestedOpenGLAPI, int requestedSampleCount) { + if (mSampleView != null && + mSampleView.getMSAASampleCount() == requestedSampleCount && + mSampleView.getUsesOpenGLAPI() == requestedOpenGLAPI) { + return true; + } + + createSampleView(requestedOpenGLAPI, requestedSampleCount); + + return true; + } } diff --git a/platform_tools/android/app/src/com/skia/SkiaSampleRenderer.java b/platform_tools/android/app/src/com/skia/SkiaSampleRenderer.java index 1479c92396..d8fb8845b4 100644 --- a/platform_tools/android/app/src/com/skia/SkiaSampleRenderer.java +++ b/platform_tools/android/app/src/com/skia/SkiaSampleRenderer.java @@ -9,14 +9,17 @@ package com.skia; import android.opengl.GLSurfaceView; import android.os.Handler; +import android.util.Log; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; public class SkiaSampleRenderer implements GLSurfaceView.Renderer { private final SkiaSampleView mSampleView; private Handler mHandler = new Handler(); + private int mMSAASampleCount; SkiaSampleRenderer(SkiaSampleView view) { mSampleView = view; @@ -34,9 +37,24 @@ public class SkiaSampleRenderer implements GLSurfaceView.Renderer { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { + if (gl instanceof GL11) { + int value[] = new int[1]; + ((GL11) gl).glGetIntegerv(GL11.GL_SAMPLES, value, 0); + if (value[0] == 1) { + mMSAASampleCount = 0; + } else { + mMSAASampleCount = value[0]; + } + } + gl.glClearStencil(0); gl.glClear(GL10.GL_STENCIL_BUFFER_BIT); - init((SkiaSampleActivity)mSampleView.getContext()); + init((SkiaSampleActivity)mSampleView.getContext(), mMSAASampleCount); + } + + // Called by JNI and the view. + synchronized public int getMSAASampleCount() { + return mMSAASampleCount; } // Called by JNI @@ -71,7 +89,7 @@ public class SkiaSampleRenderer implements GLSurfaceView.Renderer { mSampleView.requestRender(); } - native void init(SkiaSampleActivity activity); + native void init(SkiaSampleActivity activity, int msaaSampleCount); native void term(); native void draw(); native void updateSize(int w, int h); diff --git a/platform_tools/android/app/src/com/skia/SkiaSampleView.java b/platform_tools/android/app/src/com/skia/SkiaSampleView.java index 0d493c96df..b1f7318319 100644 --- a/platform_tools/android/app/src/com/skia/SkiaSampleView.java +++ b/platform_tools/android/app/src/com/skia/SkiaSampleView.java @@ -7,21 +7,36 @@ package com.skia; +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + import android.content.Context; +import android.opengl.EGL14; import android.opengl.GLSurfaceView; +import android.os.Build; import android.view.MotionEvent; public class SkiaSampleView extends GLSurfaceView { private final SkiaSampleRenderer mSampleRenderer; + private boolean mRequestedOpenGLAPI; // true == use (desktop) OpenGL. false == use OpenGL ES. + private int mRequestedMSAASampleCount; - public SkiaSampleView(Context ctx) { + public SkiaSampleView(Context ctx, boolean useOpenGL, int msaaSampleCount) { super(ctx); mSampleRenderer = new SkiaSampleRenderer(this); + mRequestedMSAASampleCount = msaaSampleCount; setEGLContextClientVersion(2); - setEGLConfigChooser(8,8,8,8,0,8); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + setEGLConfigChooser(8, 8, 8, 8, 0, 8); + } else { + mRequestedOpenGLAPI = useOpenGL; + setEGLConfigChooser(new SampleViewEGLConfigChooser()); + } setRenderer(mSampleRenderer); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } @@ -162,4 +177,120 @@ public class SkiaSampleView extends GLSurfaceView { } }); } + + public boolean getUsesOpenGLAPI() { + return mRequestedOpenGLAPI; + } + + public int getMSAASampleCount() { + return mSampleRenderer.getMSAASampleCount(); + } + + private class SampleViewEGLConfigChooser implements GLSurfaceView.EGLConfigChooser { + private int[] mValue; + + @Override + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + mValue = new int[1]; + + int glAPIToTry; + + if (mRequestedOpenGLAPI) { + glAPIToTry = EGL14.EGL_OPENGL_API; + } else { + glAPIToTry = EGL14.EGL_OPENGL_ES_API; + } + + int numConfigs = 0; + int[] configSpec = null; + + do { + EGL14.eglBindAPI(glAPIToTry); + + int renderableType; + if (glAPIToTry == EGL14.EGL_OPENGL_API) { + renderableType = EGL14.EGL_OPENGL_ES2_BIT; + + // If this API does not work, try ES next. + glAPIToTry = EGL14.EGL_OPENGL_ES_API; + } else { + renderableType = EGL14.EGL_OPENGL_BIT; + } + + + if (mRequestedMSAASampleCount > 0) { + configSpec = new int[] { + EGL10.EGL_RED_SIZE, 8, + EGL10.EGL_GREEN_SIZE, 8, + EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_ALPHA_SIZE, 8, + EGL10.EGL_DEPTH_SIZE, 0, + EGL10.EGL_STENCIL_SIZE, 8, + EGL10.EGL_RENDERABLE_TYPE, renderableType, + EGL10.EGL_SAMPLE_BUFFERS, 1, + EGL10.EGL_SAMPLES, mRequestedMSAASampleCount, + EGL10.EGL_NONE + }; + + if (!egl.eglChooseConfig(display, configSpec, null, 0, mValue)) { + throw new IllegalArgumentException("Could not get MSAA context count"); + } + + numConfigs = mValue[0]; + } + + if (numConfigs <= 0) { + // Try without multisampling. + configSpec = new int[] { + EGL10.EGL_RED_SIZE, 8, + EGL10.EGL_GREEN_SIZE, 8, + EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_ALPHA_SIZE, 8, + EGL10.EGL_DEPTH_SIZE, 0, + EGL10.EGL_STENCIL_SIZE, 8, + EGL10.EGL_RENDERABLE_TYPE, renderableType, + EGL10.EGL_NONE + }; + + if (!egl.eglChooseConfig(display, configSpec, null, 0, mValue)) { + throw new IllegalArgumentException("Could not get non-MSAA context count"); + } + numConfigs = mValue[0]; + } + + } while (glAPIToTry != EGL14.EGL_OPENGL_ES_API && numConfigs == 0); + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + // Get all matching configurations. + EGLConfig[] configs = new EGLConfig[numConfigs]; + if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, mValue)) { + throw new IllegalArgumentException("Could not get config data"); + } + + for (int i = 0; i < configs.length; ++i) { + EGLConfig config = configs[i]; + if (findConfigAttrib(egl, display, config , EGL10.EGL_RED_SIZE, 0) == 8 && + findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0) == 8 && + findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0) == 8 && + findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0) == 8 && + findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0) == 8) { + return config; + } + } + + throw new IllegalArgumentException("Could not find suitable EGL config"); + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + } } |