blob: cf06bea6a826526410ad34a94832d9a7be81efb5 [file] [log] [blame]
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
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.util.Log;
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, boolean useOpenGL, int msaaSampleCount) {
super(ctx);
mSampleRenderer = new SkiaSampleRenderer(this);
mRequestedMSAASampleCount = msaaSampleCount;
setEGLContextClientVersion(2);
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);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int count = event.getPointerCount();
for (int i = 0; i < count; i++) {
final float x = event.getX(i);
final float y = event.getY(i);
final int owner = event.getPointerId(i);
int action = event.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_POINTER_UP:
action = MotionEvent.ACTION_UP;
break;
case MotionEvent.ACTION_POINTER_DOWN:
action = MotionEvent.ACTION_DOWN;
break;
default:
break;
}
final int finalAction = action;
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.handleClick(owner, x, y, finalAction);
}
});
}
return true;
}
public void inval() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.postInval();
}
});
}
public void terminate() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.term();
}
});
}
public void showOverview() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.showOverview();
}
});
}
public void nextSample() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.nextSample();
}
});
}
public void previousSample() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.previousSample();
}
});
}
public void goToSample(final int position) {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.goToSample(position);
}
});
}
public void toggleRenderingMode() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.toggleRenderingMode();
}
});
}
public void toggleSlideshow() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.toggleSlideshow();
}
});
}
public void toggleFPS() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.toggleFPS();
}
});
}
public void toggleTiling() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.toggleTiling();
}
});
}
public void toggleBBox() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.toggleBBox();
}
});
}
public void saveToPDF() {
queueEvent(new Runnable() {
@Override
public void run() {
mSampleRenderer.saveToPDF();
}
});
}
public boolean getUsesOpenGLAPI() {
return mRequestedOpenGLAPI;
}
public int getMSAASampleCount() {
return mSampleRenderer.getMSAASampleCount();
}
private class SampleViewEGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int numConfigs = 0;
int[] configSpec = null;
int[] value = new int[1];
int[] validAPIs = new int[] {
EGL14.EGL_OPENGL_API,
EGL14.EGL_OPENGL_ES_API
};
int initialAPI = mRequestedOpenGLAPI ? 0 : 1;
for (int i = initialAPI; i < validAPIs.length && numConfigs == 0; i++) {
int currentAPI = validAPIs[i];
EGL14.eglBindAPI(currentAPI);
// setup the renderableType which will only be included in the
// spec if we are attempting to get access to the OpenGL APIs.
int renderableType = EGL14.EGL_OPENGL_BIT;
if (currentAPI == EGL14.EGL_OPENGL_API) {
renderableType = EGL14.EGL_OPENGL_ES2_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_SAMPLE_BUFFERS, 1,
EGL10.EGL_SAMPLES, mRequestedMSAASampleCount,
EGL10.EGL_RENDERABLE_TYPE, renderableType,
EGL10.EGL_NONE
};
// EGL_RENDERABLE_TYPE is only needed when attempting to use
// the OpenGL API (not ES) and causes many EGL drivers to fail
// with a BAD_ATTRIBUTE error.
if (!mRequestedOpenGLAPI) {
configSpec[16] = EGL10.EGL_NONE;
Log.i("Skia", "spec: " + configSpec);
}
if (!egl.eglChooseConfig(display, configSpec, null, 0, value)) {
Log.i("Skia", "Could not get MSAA context count: " + mRequestedMSAASampleCount);
}
numConfigs = value[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
};
// EGL_RENDERABLE_TYPE is only needed when attempting to use
// the OpenGL API (not ES) and causes many EGL drivers to fail
// with a BAD_ATTRIBUTE error.
if (!mRequestedOpenGLAPI) {
configSpec[12] = EGL10.EGL_NONE;
Log.i("Skia", "spec: " + configSpec);
}
if (!egl.eglChooseConfig(display, configSpec, null, 0, value)) {
Log.i("Skia", "Could not get non-MSAA context count");
}
numConfigs = value[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, value)) {
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) {
int[] value = new int[1];
if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
return value[0];
}
return defaultValue;
}
}
}