| /* |
| * 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; |
| } |
| |
| } |
| } |