2011-11-18 10:28:17 -08:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
2012-05-21 04:12:37 -07:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
package org.mozilla.gecko.gfx;
|
|
|
|
|
2012-07-15 13:20:43 -07:00
|
|
|
import org.mozilla.gecko.GeckoApp;
|
2012-02-08 16:01:21 -08:00
|
|
|
import org.mozilla.gecko.GeckoInputConnection;
|
2012-07-15 13:20:43 -07:00
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.content.Context;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.graphics.PixelFormat;
|
|
|
|
import android.graphics.SurfaceTexture;
|
|
|
|
import android.os.Build;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.Log;
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.view.KeyEvent;
|
|
|
|
import android.view.MotionEvent;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.view.SurfaceHolder;
|
|
|
|
import android.view.SurfaceView;
|
|
|
|
import android.view.TextureView;
|
|
|
|
import android.view.ViewGroup;
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
import android.view.inputmethod.InputConnection;
|
2012-07-31 10:30:46 -07:00
|
|
|
import android.widget.FrameLayout;
|
2012-04-05 08:28:50 -07:00
|
|
|
|
2012-07-15 13:20:43 -07:00
|
|
|
import java.nio.IntBuffer;
|
2012-04-05 08:28:50 -07:00
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
/**
|
|
|
|
* A view rendered by the layer compositor.
|
|
|
|
*
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
* This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a
|
|
|
|
* mediator between the LayerRenderer and the LayerController.
|
|
|
|
*
|
2012-03-22 10:35:19 -07:00
|
|
|
* Note that LayerView is accessed by Robocop via reflection.
|
2011-11-18 10:28:17 -08:00
|
|
|
*/
|
2012-07-31 10:30:46 -07:00
|
|
|
public class LayerView extends FrameLayout {
|
2012-07-17 17:54:54 -07:00
|
|
|
private static String LOGTAG = "GeckoLayerView";
|
2012-04-07 00:09:26 -07:00
|
|
|
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
private LayerController mController;
|
2012-04-07 00:09:26 -07:00
|
|
|
private TouchEventHandler mTouchEventHandler;
|
2012-04-05 08:28:50 -07:00
|
|
|
private GLController mGLController;
|
2011-11-18 10:28:17 -08:00
|
|
|
private InputConnectionHandler mInputConnectionHandler;
|
|
|
|
private LayerRenderer mRenderer;
|
2012-03-22 15:07:00 -07:00
|
|
|
/* Must be a PAINT_xxx constant */
|
|
|
|
private int mPaintState = PAINT_NONE;
|
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
private SurfaceView mSurfaceView;
|
|
|
|
private TextureView mTextureView;
|
|
|
|
|
2012-04-05 08:28:50 -07:00
|
|
|
private Listener mListener;
|
|
|
|
|
2012-03-22 15:07:00 -07:00
|
|
|
/* Flags used to determine when to show the painted surface. The integer
|
|
|
|
* order must correspond to the order in which these states occur. */
|
|
|
|
public static final int PAINT_NONE = 0;
|
|
|
|
public static final int PAINT_BEFORE_FIRST = 1;
|
|
|
|
public static final int PAINT_AFTER_FIRST = 2;
|
2012-02-01 17:08:04 -08:00
|
|
|
|
2012-07-28 07:33:51 -07:00
|
|
|
public LayerView(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
|
|
|
mSurfaceView = new SurfaceView(context);
|
|
|
|
addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
|
|
|
|
|
|
SurfaceHolder holder = mSurfaceView.getHolder();
|
|
|
|
holder.addCallback(new SurfaceListener());
|
|
|
|
holder.setFormat(PixelFormat.RGB_565);
|
|
|
|
} else {
|
|
|
|
mTextureView = new TextureView(context);
|
|
|
|
mTextureView.setSurfaceTextureListener(new SurfaceTextureListener());
|
|
|
|
|
|
|
|
addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
|
|
}
|
|
|
|
|
2012-04-05 08:28:50 -07:00
|
|
|
mGLController = new GLController(this);
|
2012-07-28 07:33:51 -07:00
|
|
|
}
|
|
|
|
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
void connect(LayerController controller) {
|
|
|
|
mController = controller;
|
|
|
|
mTouchEventHandler = new TouchEventHandler(getContext(), this, mController);
|
2011-11-18 10:28:17 -08:00
|
|
|
mRenderer = new LayerRenderer(this);
|
|
|
|
mInputConnectionHandler = null;
|
|
|
|
|
|
|
|
setFocusable(true);
|
|
|
|
setFocusableInTouchMode(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onTouchEvent(MotionEvent event) {
|
2012-06-08 11:43:17 -07:00
|
|
|
if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
|
|
|
|
requestFocus();
|
|
|
|
|
2012-05-10 12:09:00 -07:00
|
|
|
/** We need to manually hide FormAssistPopup because it is not a regular PopupWindow. */
|
2012-07-27 23:31:54 -07:00
|
|
|
if (GeckoApp.mAppContext != null)
|
|
|
|
GeckoApp.mAppContext.hideFormAssistPopup();
|
2012-05-10 12:09:00 -07:00
|
|
|
|
2012-04-07 00:09:26 -07:00
|
|
|
return mTouchEventHandler.handleEvent(event);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-06-15 15:34:22 -07:00
|
|
|
@Override
|
|
|
|
public boolean onHoverEvent(MotionEvent event) {
|
|
|
|
return mTouchEventHandler.handleEvent(event);
|
|
|
|
}
|
|
|
|
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
public LayerController getController() { return mController; }
|
2012-04-07 00:09:26 -07:00
|
|
|
public TouchEventHandler getTouchEventHandler() { return mTouchEventHandler; }
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-05-26 13:11:47 -07:00
|
|
|
/** The LayerRenderer calls this to indicate that the window has changed size. */
|
|
|
|
public void setViewportSize(IntSize size) {
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
mController.setViewportSize(new FloatSize(size));
|
2012-05-26 13:11:47 -07:00
|
|
|
}
|
|
|
|
|
2012-01-26 11:23:13 -08:00
|
|
|
public GeckoInputConnection setInputConnectionHandler() {
|
2012-01-30 12:57:30 -08:00
|
|
|
GeckoInputConnection geckoInputConnection = GeckoInputConnection.create(this);
|
|
|
|
mInputConnectionHandler = geckoInputConnection;
|
|
|
|
return geckoInputConnection;
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onCreateInputConnection(outAttrs);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onKeyPreIme(keyCode, event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onKeyDown(keyCode, event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onKeyLongPress(keyCode, event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
|
|
if (mInputConnectionHandler != null)
|
|
|
|
return mInputConnectionHandler.onKeyUp(keyCode, event);
|
|
|
|
return false;
|
|
|
|
}
|
2011-11-30 09:27:13 -08:00
|
|
|
|
2012-05-09 19:32:54 -07:00
|
|
|
public void requestRender() {
|
2012-04-05 08:28:50 -07:00
|
|
|
if (mListener != null) {
|
|
|
|
mListener.renderRequested();
|
2011-11-30 09:27:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 06:40:58 -08:00
|
|
|
public void addLayer(Layer layer) {
|
|
|
|
mRenderer.addLayer(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeLayer(Layer layer) {
|
|
|
|
mRenderer.removeLayer(layer);
|
|
|
|
}
|
|
|
|
|
2011-12-15 15:45:52 -08:00
|
|
|
public int getMaxTextureSize() {
|
|
|
|
return mRenderer.getMaxTextureSize();
|
|
|
|
}
|
2012-01-26 11:23:13 -08:00
|
|
|
|
2012-01-30 19:46:13 -08:00
|
|
|
/** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */
|
2012-01-30 19:45:38 -08:00
|
|
|
public IntBuffer getPixels() {
|
|
|
|
return mRenderer.getPixels();
|
|
|
|
}
|
2012-03-12 10:03:54 -07:00
|
|
|
|
|
|
|
public void setLayerRenderer(LayerRenderer renderer) {
|
|
|
|
mRenderer = renderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public LayerRenderer getLayerRenderer() {
|
|
|
|
return mRenderer;
|
|
|
|
}
|
2012-04-05 08:28:50 -07:00
|
|
|
|
2012-03-22 15:07:00 -07:00
|
|
|
/* paintState must be a PAINT_xxx constant. The state will only be changed
|
|
|
|
* if paintState represents a state that occurs after the current state. */
|
|
|
|
public void setPaintState(int paintState) {
|
|
|
|
if (paintState > mPaintState) {
|
|
|
|
Log.d(LOGTAG, "LayerView paint state set to " + paintState);
|
|
|
|
mPaintState = paintState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getPaintState() {
|
|
|
|
return mPaintState;
|
|
|
|
}
|
2012-04-05 08:27:02 -07:00
|
|
|
|
2012-04-05 08:28:50 -07:00
|
|
|
|
2012-04-24 12:13:36 -07:00
|
|
|
public LayerRenderer getRenderer() {
|
2012-04-05 08:28:50 -07:00
|
|
|
return mRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setListener(Listener listener) {
|
|
|
|
mListener = listener;
|
|
|
|
}
|
|
|
|
|
2012-07-13 07:19:46 -07:00
|
|
|
Listener getListener() {
|
|
|
|
return mListener;
|
|
|
|
}
|
|
|
|
|
2012-05-09 19:32:54 -07:00
|
|
|
public GLController getGLController() {
|
2012-04-05 08:28:50 -07:00
|
|
|
return mGLController;
|
|
|
|
}
|
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
private void onSizeChanged(int width, int height) {
|
2012-05-18 12:58:46 -07:00
|
|
|
mGLController.surfaceChanged(width, height);
|
2012-04-05 08:28:50 -07:00
|
|
|
|
|
|
|
if (mListener != null) {
|
|
|
|
mListener.surfaceChanged(width, height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
private void onDestroyed() {
|
2012-04-05 08:28:50 -07:00
|
|
|
mGLController.surfaceDestroyed();
|
|
|
|
|
|
|
|
if (mListener != null) {
|
|
|
|
mListener.compositionPauseRequested();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
public Object getNativeWindow() {
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
|
|
|
return mSurfaceView.getHolder();
|
|
|
|
|
|
|
|
return mTextureView.getSurfaceTexture();
|
|
|
|
}
|
|
|
|
|
2012-04-05 08:28:50 -07:00
|
|
|
/** This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying signature. */
|
|
|
|
public static GLController registerCxxCompositor() {
|
|
|
|
try {
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
LayerView layerView = GeckoApp.mAppContext.getLayerController().getView();
|
2012-07-06 06:48:25 -07:00
|
|
|
layerView.mListener.compositorCreated();
|
2012-04-05 08:28:50 -07:00
|
|
|
return layerView.getGLController();
|
|
|
|
} catch (Exception e) {
|
2012-07-23 12:04:28 -07:00
|
|
|
Log.e(LOGTAG, "Error registering compositor!", e);
|
2012-04-05 08:28:50 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface Listener {
|
2012-07-06 06:48:25 -07:00
|
|
|
void compositorCreated();
|
2012-04-05 08:28:50 -07:00
|
|
|
void renderRequested();
|
|
|
|
void compositionPauseRequested();
|
2012-04-20 08:46:30 -07:00
|
|
|
void compositionResumeRequested(int width, int height);
|
2012-04-05 08:28:50 -07:00
|
|
|
void surfaceChanged(int width, int height);
|
|
|
|
}
|
2012-07-17 17:54:54 -07:00
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
private class SurfaceListener implements SurfaceHolder.Callback {
|
|
|
|
public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
|
|
|
int height) {
|
|
|
|
onSizeChanged(width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void surfaceCreated(SurfaceHolder holder) {
|
|
|
|
}
|
2012-07-17 17:54:54 -07:00
|
|
|
|
2012-07-31 10:30:46 -07:00
|
|
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
|
onDestroyed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
|
|
|
|
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
|
|
|
// We don't do this for surfaceCreated above because it is always followed by a surfaceChanged,
|
|
|
|
// but that is not the case here.
|
|
|
|
onSizeChanged(width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
|
|
|
onDestroyed();
|
|
|
|
return true; // allow Android to call release() on the SurfaceTexture, we are done drawing to it
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
|
|
|
onSizeChanged(width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2012-04-05 08:28:50 -07:00
|
|
|
}
|