Kaydet (Commit) b0a1d430 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

android: remove FlexibleGLSurfaceView

Change-Id: Ie2f3741d7aa86b5df25723d8665a679962a0efc9
üst 8b0772df
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011-2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.gfx;
//import org.mozilla.gecko.GeckoApp;
import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final String LOGTAG = "GeckoFlexibleGLSurfaceView";
private GLSurfaceView.Renderer mRenderer;
private GLThread mGLThread; // Protected by this class's monitor.
private GLController mController;
private Listener mListener;
public FlexibleGLSurfaceView(Context context) {
super(context);
init();
}
public FlexibleGLSurfaceView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
public void init() {
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setFormat(PixelFormat.RGB_565);
mController = new GLController(this);
}
public void setRenderer(GLSurfaceView.Renderer renderer) {
mRenderer = renderer;
}
public GLSurfaceView.Renderer getRenderer() {
return mRenderer;
}
public void setListener(Listener listener) {
mListener = listener;
}
public synchronized void requestRender() {
if (mGLThread != null) {
mGLThread.renderFrame();
}
if (mListener != null) {
mListener.renderRequested();
}
}
/**
* Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just
* like a GLSurfaceView. It is illegal to access the controller after this has been called.
*/
public synchronized void createGLThread() {
if (mGLThread != null) {
throw new FlexibleGLSurfaceViewException("createGLThread() called with a GL thread " +
"already in place!");
}
Log.e(LOGTAG, "### Creating GL thread!");
mGLThread = new GLThread(mController);
mGLThread.start();
notifyAll();
}
/**
* Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is
* fully shut down.
*/
public synchronized Thread destroyGLThread() {
// Wait for the GL thread to be started.
Log.e(LOGTAG, "### Waiting for GL thread to be created...");
while (mGLThread == null) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Log.e(LOGTAG, "### Destroying GL thread!");
Thread glThread = mGLThread;
mGLThread.shutdown();
mGLThread = null;
return glThread;
}
public synchronized void recreateSurface() {
if (mGLThread == null) {
throw new FlexibleGLSurfaceViewException("recreateSurface() called with no GL " +
"thread active!");
}
mGLThread.recreateSurface();
}
public synchronized GLController getGLController() {
if (mGLThread != null) {
throw new FlexibleGLSurfaceViewException("getGLController() called with a GL thread " +
"active; shut down the GL thread first!");
}
return mController;
}
public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mController.sizeChanged(width, height);
if (mGLThread != null) {
mGLThread.surfaceChanged(width, height);
}
if (mListener != null) {
mListener.surfaceChanged(width, height);
}
}
public synchronized void surfaceCreated(SurfaceHolder holder) {
mController.surfaceCreated();
if (mGLThread != null) {
mGLThread.surfaceCreated();
}
}
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
mController.surfaceDestroyed();
if (mGLThread != null) {
mGLThread.surfaceDestroyed();
}
if (mListener != null) {
mListener.compositionPauseRequested();
}
}
public interface Listener {
void renderRequested();
void compositionPauseRequested();
void compositionResumeRequested();
void surfaceChanged(int width, int height);
}
public static class FlexibleGLSurfaceViewException extends RuntimeException {
public static final long serialVersionUID = 1L;
FlexibleGLSurfaceViewException(String e) {
super(e);
}
}
}
...@@ -52,7 +52,7 @@ public class GLController { ...@@ -52,7 +52,7 @@ public class GLController {
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private static final String LOGTAG = "GeckoGLController"; private static final String LOGTAG = "GeckoGLController";
private FlexibleGLSurfaceView mView; private LayerView mView;
private int mGLVersion; private int mGLVersion;
private boolean mSurfaceValid; private boolean mSurfaceValid;
private int mWidth, mHeight; private int mWidth, mHeight;
...@@ -68,15 +68,15 @@ public class GLController { ...@@ -68,15 +68,15 @@ public class GLController {
private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4; private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
private static final int[] CONFIG_SPEC = { private static final int[] CONFIG_SPEC = {
EGL10.EGL_RED_SIZE, 5, EGL10.EGL_RED_SIZE, 5,
EGL10.EGL_GREEN_SIZE, 6, EGL10.EGL_GREEN_SIZE, 6,
EGL10.EGL_BLUE_SIZE, 5, EGL10.EGL_BLUE_SIZE, 5,
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT, EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE EGL10.EGL_NONE
}; };
public GLController(FlexibleGLSurfaceView view) { public GLController(LayerView view) {
mView = view; mView = view;
mGLVersion = 2; mGLVersion = 2;
mSurfaceValid = false; mSurfaceValid = false;
...@@ -93,27 +93,32 @@ public class GLController { ...@@ -93,27 +93,32 @@ public class GLController {
} }
public void disposeGLContext() { public void disposeGLContext() {
if (mEGL == null) {
return;
}
if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT)) { EGL10.EGL_NO_CONTEXT)) {
throw new GLControllerException("EGL context could not be released!"); throw new GLControllerException("EGL context could not be released! " +
getEGLError());
} }
if (mEGLSurface != null) { if (mEGLSurface != null) {
if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) { if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) {
throw new GLControllerException("EGL surface could not be destroyed!"); throw new GLControllerException("EGL surface could not be destroyed! " +
getEGLError());
} }
mEGLSurface = null; mEGLSurface = null;
} }
if (mEGLContext == null) { if (mEGLContext != null) {
if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) { if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) {
throw new GLControllerException("EGL context could not be destroyed!"); throw new GLControllerException("EGL context could not be destroyed! " +
getEGLError());
} }
mGL = null; mGL = null;
mEGLDisplay = null;
mEGLConfig = null;
mEGLContext = null; mEGLContext = null;
} }
} }
...@@ -123,7 +128,7 @@ public class GLController { ...@@ -123,7 +128,7 @@ public class GLController {
public EGLConfig getEGLConfig() { return mEGLConfig; } public EGLConfig getEGLConfig() { return mEGLConfig; }
public EGLContext getEGLContext() { return mEGLContext; } public EGLContext getEGLContext() { return mEGLContext; }
public EGLSurface getEGLSurface() { return mEGLSurface; } public EGLSurface getEGLSurface() { return mEGLSurface; }
public FlexibleGLSurfaceView getView() { return mView; } public LayerView getView() { return mView; }
public boolean hasSurface() { public boolean hasSurface() {
return mEGLSurface != null; return mEGLSurface != null;
...@@ -146,6 +151,8 @@ public class GLController { ...@@ -146,6 +151,8 @@ public class GLController {
return true; return true;
} }
// Wait until we are allowed to use EGL functions on the Surface backing
// this window.
public synchronized void waitForValidSurface() { public synchronized void waitForValidSurface() {
while (!mSurfaceValid) { while (!mSurfaceValid) {
try { try {
...@@ -189,7 +196,8 @@ public class GLController { ...@@ -189,7 +196,8 @@ public class GLController {
int[] version = new int[2]; int[] version = new int[2];
if (!mEGL.eglInitialize(mEGLDisplay, version)) { if (!mEGL.eglInitialize(mEGLDisplay, version)) {
throw new GLControllerException("eglInitialize() failed"); throw new GLControllerException("eglInitialize() failed " +
getEGLError());
} }
mEGLConfig = chooseConfig(); mEGLConfig = chooseConfig();
...@@ -200,9 +208,10 @@ public class GLController { ...@@ -200,9 +208,10 @@ public class GLController {
int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE }; int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE };
mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT,
attribList); attribList);
if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) { if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) {
throw new GLControllerException("createContext() failed"); throw new GLControllerException("createContext() failed " +
getEGLError());
} }
} }
...@@ -210,12 +219,14 @@ public class GLController { ...@@ -210,12 +219,14 @@ public class GLController {
int[] numConfigs = new int[1]; int[] numConfigs = new int[1];
if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) || if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) ||
numConfigs[0] <= 0) { numConfigs[0] <= 0) {
throw new GLControllerException("No available EGL configurations"); throw new GLControllerException("No available EGL configurations " +
getEGLError());
} }
EGLConfig[] configs = new EGLConfig[numConfigs[0]]; EGLConfig[] configs = new EGLConfig[numConfigs[0]];
if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) { if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) {
throw new GLControllerException("No EGL configuration for that specification"); throw new GLControllerException("No EGL configuration for that specification " +
getEGLError());
} }
// Select the first 565 RGB configuration. // Select the first 565 RGB configuration.
...@@ -236,12 +247,13 @@ public class GLController { ...@@ -236,12 +247,13 @@ public class GLController {
SurfaceHolder surfaceHolder = mView.getHolder(); SurfaceHolder surfaceHolder = mView.getHolder();
mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null);
if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) { if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
throw new GLControllerException("EGL window surface could not be created!"); throw new GLControllerException("EGL window surface could not be created! " +
getEGLError());
} }
if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) { if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
throw new GLControllerException("EGL surface could not be made into the current " + throw new GLControllerException("EGL surface could not be made into the current " +
"surface!"); "surface! " + getEGLError());
} }
mGL = mEGLContext.getGL(); mGL = mEGLContext.getGL();
...@@ -252,19 +264,28 @@ public class GLController { ...@@ -252,19 +264,28 @@ public class GLController {
} }
} }
// Provides an EGLSurface without assuming ownership of this surface. /**
* Provides an EGLSurface without assuming ownership of this surface.
* This class does not keep a reference to the provided EGL surface; the
* caller assumes ownership of the surface once it is returned.
*/
private EGLSurface provideEGLSurface() { private EGLSurface provideEGLSurface() {
if (mEGL == null) { if (mEGL == null) {
initEGL(); initEGL();
} }
SurfaceHolder surfaceHolder = mView.getHolder(); SurfaceHolder surfaceHolder = mView.getHolder();
mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); EGLSurface surface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null);
if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) { if (surface == null || surface == EGL10.EGL_NO_SURFACE) {
throw new GLControllerException("EGL window surface could not be created!"); throw new GLControllerException("EGL window surface could not be created! " +
getEGLError());
} }
return mEGLSurface; return surface;
}
private String getEGLError() {
return "Error " + mEGL.eglGetError();
} }
public static class GLControllerException extends RuntimeException { public static class GLControllerException extends RuntimeException {
......
...@@ -135,9 +135,6 @@ class GLThread extends Thread { ...@@ -135,9 +135,6 @@ class GLThread extends Thread {
} }
mController.swapBuffers(); mController.swapBuffers();
//if (!mController.swapBuffers() && mController.checkForLostContext()) {
// doRecreateSurface();
//}
} }
} }
......
...@@ -41,13 +41,18 @@ package org.mozilla.gecko.gfx; ...@@ -41,13 +41,18 @@ package org.mozilla.gecko.gfx;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.util.Log; import android.util.Log;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import org.libreoffice.LibreOfficeMainActivity;
import org.mozilla.gecko.ui.SimpleScaleGestureDetector; import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
import java.nio.IntBuffer; import java.nio.IntBuffer;
...@@ -61,9 +66,10 @@ import java.util.LinkedList; ...@@ -61,9 +66,10 @@ import java.util.LinkedList;
* *
* Note that LayerView is accessed by Robocop via reflection. * Note that LayerView is accessed by Robocop via reflection.
*/ */
public class LayerView extends FlexibleGLSurfaceView { public class LayerView extends SurfaceView implements SurfaceHolder.Callback {
private Context mContext; private Context mContext;
private LayerController mController; private LayerController mController;
private GLController mGLController;
private InputConnectionHandler mInputConnectionHandler; private InputConnectionHandler mInputConnectionHandler;
private LayerRenderer mRenderer; private LayerRenderer mRenderer;
private GestureDetector mGestureDetector; private GestureDetector mGestureDetector;
...@@ -76,6 +82,8 @@ public class LayerView extends FlexibleGLSurfaceView { ...@@ -76,6 +82,8 @@ public class LayerView extends FlexibleGLSurfaceView {
/* Must be a PAINT_xxx constant */ /* Must be a PAINT_xxx constant */
private int mPaintState = PAINT_NONE; private int mPaintState = PAINT_NONE;
private Listener mListener;
/* Flags used to determine when to show the painted surface. The integer /* Flags used to determine when to show the painted surface. The integer
* order must correspond to the order in which these states occur. */ * order must correspond to the order in which these states occur. */
public static final int PAINT_NONE = 0; public static final int PAINT_NONE = 0;
...@@ -86,10 +94,14 @@ public class LayerView extends FlexibleGLSurfaceView { ...@@ -86,10 +94,14 @@ public class LayerView extends FlexibleGLSurfaceView {
public LayerView(Context context, LayerController controller) { public LayerView(Context context, LayerController controller) {
super(context); super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setFormat(PixelFormat.RGB_565);
mGLController = new GLController(this);
mContext = context; mContext = context;
mController = controller; mController = controller;
mRenderer = new LayerRenderer(this); mRenderer = new LayerRenderer(this);
setRenderer(mRenderer);
mGestureDetector = new GestureDetector(context, controller.getGestureListener()); mGestureDetector = new GestureDetector(context, controller.getGestureListener());
mScaleGestureDetector = mScaleGestureDetector =
new SimpleScaleGestureDetector(controller.getScaleGestureListener()); new SimpleScaleGestureDetector(controller.getScaleGestureListener());
...@@ -187,10 +199,13 @@ public class LayerView extends FlexibleGLSurfaceView { ...@@ -187,10 +199,13 @@ public class LayerView extends FlexibleGLSurfaceView {
return false; return false;
} }
@Override
public void requestRender() { public void requestRender() {
super.requestRender(); if (mGLThread != null) {
mGLThread.renderFrame();
}
if (mListener != null) {
mListener.renderRequested();
}
synchronized(this) { synchronized(this) {
if (!mRenderTimeReset) { if (!mRenderTimeReset) {
...@@ -235,7 +250,6 @@ public class LayerView extends FlexibleGLSurfaceView { ...@@ -235,7 +250,6 @@ public class LayerView extends FlexibleGLSurfaceView {
public void setLayerRenderer(LayerRenderer renderer) { public void setLayerRenderer(LayerRenderer renderer) {
mRenderer = renderer; mRenderer = renderer;
setRenderer(mRenderer);
} }
public LayerRenderer getLayerRenderer() { public LayerRenderer getLayerRenderer() {
...@@ -254,5 +268,126 @@ public class LayerView extends FlexibleGLSurfaceView { ...@@ -254,5 +268,126 @@ public class LayerView extends FlexibleGLSurfaceView {
public int getPaintState() { public int getPaintState() {
return mPaintState; return mPaintState;
} }
}
public GLSurfaceView.Renderer getRenderer() {
return mRenderer;
}
public void setListener(Listener listener) {
mListener = listener;
}
public synchronized GLController getGLController() {
return mGLController;
}
/** Implementation of SurfaceHolder.Callback */
public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mGLController.sizeChanged(width, height);
if (mGLThread != null) {
mGLThread.surfaceChanged(width, height);
}
if (mListener != null) {
mListener.surfaceChanged(width, height);
}
}
/** Implementation of SurfaceHolder.Callback */
public synchronized void surfaceCreated(SurfaceHolder holder) {
mGLController.surfaceCreated();
if (mGLThread != null) {
mGLThread.surfaceCreated();
}
}
/** Implementation of SurfaceHolder.Callback */
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
mGLController.surfaceDestroyed();
if (mGLThread != null) {
mGLThread.surfaceDestroyed();
}
if (mListener != null) {
mListener.compositionPauseRequested();
}
}
/** This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying signature. */
public static GLController registerCxxCompositor() {
try {
LayerView layerView = LibreOfficeMainActivity.mAppContext.getLayerController().getView();
return layerView.getGLController();
} catch (Exception e) {
Log.e(LOGTAG, "### Exception! " + e);
return null;
}
}
public interface Listener {
void renderRequested();
void compositionPauseRequested();
void compositionResumeRequested();
void surfaceChanged(int width, int height);
}
private GLThread mGLThread; // Protected by this class's monitor.
/**
* Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just
* like a GLSurfaceView. It is illegal to access the controller after this has been called.
*/
public synchronized void createGLThread() {
if (mGLThread != null) {
throw new LayerViewException ("createGLThread() called with a GL thread already in place!");
}
Log.e(LOGTAG, "### Creating GL thread!");
mGLThread = new GLThread(mGLController);
mGLThread.start();
notifyAll();
}
/**
* Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is
* fully shut down.
*/
public synchronized Thread destroyGLThread() {
// Wait for the GL thread to be started.
Log.e(LOGTAG, "### Waiting for GL thread to be created...");
while (mGLThread == null) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Log.e(LOGTAG, "### Destroying GL thread!");
Thread glThread = mGLThread;
mGLThread.shutdown();
mGLThread = null;
return glThread;
}
public synchronized void recreateSurface() {
if (mGLThread == null) {
throw new LayerViewException("recreateSurface() called with no GL " +
"thread active!");
}
mGLThread.recreateSurface();
}
public static class LayerViewException extends RuntimeException {
public static final long serialVersionUID = 1L;
LayerViewException(String e) {
super(e);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment