зеркало из https://github.com/mozilla/moz-skia.git
Support MSAA4 and (non-ES) OpenGL in Android SampleApp
Add a menu item to set the OpenGL context type that SampleApp uses on Android. The submenu of the new item will present options to create OpenGL ES or OpenGL, aliased or multisampled. R=djsollen@google.com, bsalomon@google.com Author: kkinnunen@nvidia.com Review URL: https://codereview.chromium.org/60273006 git-svn-id: http://skia.googlecode.com/svn/trunk@12610 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
bc55eec80e
Коммит
a3b84d41ef
|
@ -29,12 +29,7 @@ public:
|
|||
int fStencilBits;
|
||||
};
|
||||
|
||||
bool attach(SkBackEndTypes /* attachType */, int /* msaaSampleCount */, AttachmentInfo* info) {
|
||||
// These are the values requested in SkiaSampleView.java
|
||||
info->fSampleCount = 0;
|
||||
info->fStencilBits = 8;
|
||||
return true;
|
||||
}
|
||||
bool attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info);
|
||||
void detach() {}
|
||||
void present() {}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -42,6 +42,32 @@
|
|||
android:id="@+id/bbox"
|
||||
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"
|
||||
|
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -99,8 +111,39 @@ public class SkiaSampleActivity extends Activity
|
|||
return true;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче