зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1436754 - Merge LayerSession into GeckoSession; r=snorp,jchen
Depends on D10990 Differential Revision: https://phabricator.services.mozilla.com/D10991 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
71ee91b62f
Коммит
32866173fc
|
@ -16,7 +16,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public final class CompositorController {
|
||||
private final LayerSession.Compositor mCompositor;
|
||||
private final GeckoSession.Compositor mCompositor;
|
||||
|
||||
public interface GetPixelsCallback {
|
||||
void onPixelsResult(int width, int height, IntBuffer pixels);
|
||||
|
@ -27,7 +27,7 @@ public final class CompositorController {
|
|||
private int mDefaultClearColor = Color.WHITE;
|
||||
private Runnable mFirstPaintCallback;
|
||||
|
||||
/* package */ CompositorController(final LayerSession session) {
|
||||
/* package */ CompositorController(final GeckoSession session) {
|
||||
mCompositor = session.mCompositor;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,12 @@ public final class DynamicToolbarAnimator {
|
|||
|
||||
private final Set<PinReason> mPinFlags = EnumSet.noneOf(PinReason.class);
|
||||
|
||||
private final LayerSession mTarget;
|
||||
private final LayerSession.Compositor mCompositor;
|
||||
private final GeckoSession mTarget;
|
||||
private final GeckoSession.Compositor mCompositor;
|
||||
private ToolbarChromeProxy mToolbarChromeProxy;
|
||||
private int mMaxToolbarHeight;
|
||||
|
||||
/* package */ DynamicToolbarAnimator(final LayerSession aTarget) {
|
||||
/* package */ DynamicToolbarAnimator(final GeckoSession aTarget) {
|
||||
mTarget = aTarget;
|
||||
mCompositor = aTarget.mCompositor;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public final class DynamicToolbarAnimator {
|
|||
}
|
||||
}
|
||||
|
||||
// Keep this package-private because applications should use one of LayerSession's
|
||||
// Keep this package-private because applications should use one of GeckoSession's
|
||||
// coordinates APIs instead of dealing with the dynamic toolbar manually.
|
||||
/* package */ int getCurrentToolbarHeight() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
@ -116,8 +116,8 @@ public final class DynamicToolbarAnimator {
|
|||
|
||||
if (mCompositor.isReady()) {
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
immediately ? LayerSession.REQUEST_SHOW_TOOLBAR_IMMEDIATELY
|
||||
: LayerSession.REQUEST_SHOW_TOOLBAR_ANIMATED);
|
||||
immediately ? GeckoSession.REQUEST_SHOW_TOOLBAR_IMMEDIATELY
|
||||
: GeckoSession.REQUEST_SHOW_TOOLBAR_ANIMATED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,8 +126,8 @@ public final class DynamicToolbarAnimator {
|
|||
|
||||
if (mCompositor.isReady()) {
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
immediately ? LayerSession.REQUEST_HIDE_TOOLBAR_IMMEDIATELY
|
||||
: LayerSession.REQUEST_HIDE_TOOLBAR_ANIMATED);
|
||||
immediately ? GeckoSession.REQUEST_HIDE_TOOLBAR_IMMEDIATELY
|
||||
: GeckoSession.REQUEST_HIDE_TOOLBAR_ANIMATED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,10 +136,10 @@ public final class DynamicToolbarAnimator {
|
|||
|
||||
if ((mToolbarChromeProxy != null) && mToolbarChromeProxy.isToolbarChromeVisible()) {
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
LayerSession.REQUEST_SHOW_TOOLBAR_IMMEDIATELY);
|
||||
GeckoSession.REQUEST_SHOW_TOOLBAR_IMMEDIATELY);
|
||||
} else {
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
LayerSession.REQUEST_HIDE_TOOLBAR_IMMEDIATELY);
|
||||
GeckoSession.REQUEST_HIDE_TOOLBAR_IMMEDIATELY);
|
||||
}
|
||||
|
||||
for (final PinReason reason : PinReason.values()) {
|
||||
|
@ -153,12 +153,12 @@ public final class DynamicToolbarAnimator {
|
|||
}
|
||||
|
||||
switch (message) {
|
||||
case LayerSession.STATIC_TOOLBAR_NEEDS_UPDATE: {
|
||||
case GeckoSession.STATIC_TOOLBAR_NEEDS_UPDATE: {
|
||||
// Send updated toolbar image to compositor.
|
||||
final Bitmap bm = mToolbarChromeProxy.getBitmapOfToolbarChrome();
|
||||
if (bm == null) {
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
LayerSession.TOOLBAR_SNAPSHOT_FAILED);
|
||||
GeckoSession.TOOLBAR_SNAPSHOT_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -172,22 +172,22 @@ public final class DynamicToolbarAnimator {
|
|||
} catch (final Throwable e) {
|
||||
Log.e(LOGTAG, "Cannot get toolbar pixels", e);
|
||||
mCompositor.sendToolbarAnimatorMessage(
|
||||
LayerSession.TOOLBAR_SNAPSHOT_FAILED);
|
||||
GeckoSession.TOOLBAR_SNAPSHOT_FAILED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LayerSession.STATIC_TOOLBAR_READY: {
|
||||
case GeckoSession.STATIC_TOOLBAR_READY: {
|
||||
// Hide toolbar and send TOOLBAR_HIDDEN message to compositor
|
||||
mToolbarChromeProxy.toggleToolbarChrome(false);
|
||||
mCompositor.sendToolbarAnimatorMessage(LayerSession.TOOLBAR_HIDDEN);
|
||||
mCompositor.sendToolbarAnimatorMessage(GeckoSession.TOOLBAR_HIDDEN);
|
||||
break;
|
||||
}
|
||||
|
||||
case LayerSession.TOOLBAR_SHOW: {
|
||||
case GeckoSession.TOOLBAR_SHOW: {
|
||||
// Show toolbar.
|
||||
mToolbarChromeProxy.toggleToolbarChrome(true);
|
||||
mCompositor.sendToolbarAnimatorMessage(LayerSession.TOOLBAR_VISIBLE);
|
||||
mCompositor.sendToolbarAnimatorMessage(GeckoSession.TOOLBAR_VISIBLE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ import android.content.ContentResolver;
|
|||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
|
@ -54,8 +56,7 @@ import android.view.inputmethod.CursorAnchorInfo;
|
|||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
|
||||
public class GeckoSession extends LayerSession
|
||||
implements Parcelable {
|
||||
public class GeckoSession implements Parcelable {
|
||||
private static final String LOGTAG = "GeckoSession";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
|
@ -106,6 +107,161 @@ public class GeckoSession extends LayerSession
|
|||
|
||||
private boolean mShouldPinOnScreen;
|
||||
|
||||
// All fields are accessed on UI thread only.
|
||||
private PanZoomController mNPZC;
|
||||
private OverscrollEdgeEffect mOverscroll;
|
||||
private DynamicToolbarAnimator mToolbar;
|
||||
private CompositorController mController;
|
||||
|
||||
private boolean mAttachedCompositor;
|
||||
private boolean mCompositorReady;
|
||||
private Surface mSurface;
|
||||
|
||||
// All fields of coordinates are in screen units.
|
||||
private int mLeft;
|
||||
private int mTop; // Top of the surface (including toolbar);
|
||||
private int mClientTop; // Top of the client area (i.e. excluding toolbar);
|
||||
private int mWidth;
|
||||
private int mHeight; // Height of the surface (including toolbar);
|
||||
private int mClientHeight; // Height of the client area (i.e. excluding toolbar);
|
||||
private float mViewportLeft;
|
||||
private float mViewportTop;
|
||||
private float mViewportZoom = 1.0f;
|
||||
|
||||
//
|
||||
// NOTE: These values are also defined in
|
||||
// gfx/layers/ipc/UiCompositorControllerMessageTypes.h and must be kept in sync. Any
|
||||
// new AnimatorMessageType added here must also be added there.
|
||||
//
|
||||
// Sent from compositor when the static toolbar wants to hide.
|
||||
/* package */ final static int STATIC_TOOLBAR_NEEDS_UPDATE = 0;
|
||||
// Sent from compositor when the static toolbar image has been updated and is ready to
|
||||
// animate.
|
||||
/* package */ final static int STATIC_TOOLBAR_READY = 1;
|
||||
// Sent to compositor when the real toolbar has been hidden.
|
||||
/* package */ final static int TOOLBAR_HIDDEN = 2;
|
||||
// Sent to compositor when the real toolbar is visible.
|
||||
/* package */ final static int TOOLBAR_VISIBLE = 3;
|
||||
// Sent from compositor when the static toolbar has been made visible so the real
|
||||
// toolbar should be shown.
|
||||
/* package */ final static int TOOLBAR_SHOW = 4;
|
||||
// Sent from compositor after first paint
|
||||
/* package */ final static int FIRST_PAINT = 5;
|
||||
// Sent to compositor requesting toolbar be shown immediately
|
||||
/* package */ final static int REQUEST_SHOW_TOOLBAR_IMMEDIATELY = 6;
|
||||
// Sent to compositor requesting toolbar be shown animated
|
||||
/* package */ final static int REQUEST_SHOW_TOOLBAR_ANIMATED = 7;
|
||||
// Sent to compositor requesting toolbar be hidden immediately
|
||||
/* package */ final static int REQUEST_HIDE_TOOLBAR_IMMEDIATELY = 8;
|
||||
// Sent to compositor requesting toolbar be hidden animated
|
||||
/* package */ final static int REQUEST_HIDE_TOOLBAR_ANIMATED = 9;
|
||||
// Sent from compositor when a layer has been updated
|
||||
/* package */ final static int LAYERS_UPDATED = 10;
|
||||
// Sent to compositor when the toolbar snapshot fails.
|
||||
/* package */ final static int TOOLBAR_SNAPSHOT_FAILED = 11;
|
||||
// Special message sent from UiCompositorControllerChild once it is open
|
||||
/* package */ final static int COMPOSITOR_CONTROLLER_OPEN = 20;
|
||||
// Special message sent from controller to query if the compositor controller is open.
|
||||
/* package */ final static int IS_COMPOSITOR_CONTROLLER_OPEN = 21;
|
||||
|
||||
protected class Compositor extends JNIObject {
|
||||
public boolean isReady() {
|
||||
return GeckoSession.this.isCompositorReady();
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void onCompositorAttached() {
|
||||
GeckoSession.this.onCompositorAttached();
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void onCompositorDetached() {
|
||||
// Clear out any pending calls on the UI thread.
|
||||
GeckoSession.this.onCompositorDetached();
|
||||
}
|
||||
|
||||
@WrapForJNI(dispatchTo = "gecko")
|
||||
@Override protected native void disposeNative();
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void attachNPZC(PanZoomController npzc);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void onBoundsChanged(int left, int top, int width, int height);
|
||||
|
||||
// Gecko thread pauses compositor; blocks UI thread.
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void syncPauseCompositor();
|
||||
|
||||
// UI thread resumes compositor and notifies Gecko thread; does not block UI thread.
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void syncResumeResizeCompositor(int width, int height, Object surface);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setMaxToolbarHeight(int height);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setPinned(boolean pinned, int reason);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void sendToolbarAnimatorMessage(int message);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void recvToolbarAnimatorMessage(int message) {
|
||||
GeckoSession.this.handleCompositorMessage(message);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setDefaultClearColor(int color);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void requestScreenPixels();
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void recvScreenPixels(int width, int height, int[] pixels) {
|
||||
GeckoSession.this.recvScreenPixels(width, height, pixels);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void enableLayerUpdateNotifications(boolean enable);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void sendToolbarPixelsToCompositor(final int width, final int height,
|
||||
final int[] pixels);
|
||||
|
||||
// The compositor invokes this function just before compositing a frame where the
|
||||
// document is different from the document composited on the last frame. In these
|
||||
// cases, the viewport information we have in Java is no longer valid and needs to
|
||||
// be replaced with the new viewport information provided.
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateRootFrameMetrics(float scrollX, float scrollY, float zoom) {
|
||||
GeckoSession.this.onMetricsChanged(scrollX, scrollY, zoom);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateOverscrollVelocity(final float x, final float y) {
|
||||
GeckoSession.this.updateOverscrollVelocity(x, y);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateOverscrollOffset(final float x, final float y) {
|
||||
GeckoSession.this.updateOverscrollOffset(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
disposeNative();
|
||||
}
|
||||
}
|
||||
|
||||
protected final Compositor mCompositor = new Compositor();
|
||||
|
||||
@WrapForJNI(stubName = "GetCompositor", calledFrom = "ui")
|
||||
private Object getCompositorFromNative() {
|
||||
// Only used by native code.
|
||||
return mCompositorReady ? mCompositor : null;
|
||||
}
|
||||
|
||||
/* package */ static abstract class CallbackResult<T> extends GeckoResult<T>
|
||||
implements EventCallback {
|
||||
@Override
|
||||
|
@ -2085,9 +2241,15 @@ public class GeckoSession extends LayerSession
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setShouldPinOnScreen(final boolean pinned) {
|
||||
super.setShouldPinOnScreen(pinned);
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mToolbar != null) {
|
||||
mToolbar.setPinned(pinned, DynamicToolbarAnimator.PinReason.CARET_DRAG);
|
||||
}
|
||||
|
||||
mShouldPinOnScreen = pinned;
|
||||
}
|
||||
|
||||
|
@ -3150,6 +3312,170 @@ public class GeckoSession extends LayerSession
|
|||
public void onScrollChanged(GeckoSession session, int scrollX, int scrollY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PanZoomController instance for this session.
|
||||
*
|
||||
* @return PanZoomController instance.
|
||||
*/
|
||||
@UiThread
|
||||
public PanZoomController getPanZoomController() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mNPZC == null) {
|
||||
mNPZC = new PanZoomController(this);
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.attachNPZC(mNPZC);
|
||||
}
|
||||
}
|
||||
return mNPZC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OverscrollEdgeEffect instance for this session.
|
||||
*
|
||||
* @return OverscrollEdgeEffect instance.
|
||||
*/
|
||||
@UiThread
|
||||
public OverscrollEdgeEffect getOverscrollEdgeEffect() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mOverscroll == null) {
|
||||
mOverscroll = new OverscrollEdgeEffect(this);
|
||||
}
|
||||
return mOverscroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DynamicToolbarAnimator instance for this session.
|
||||
*
|
||||
* @return DynamicToolbarAnimator instance.
|
||||
*/
|
||||
@UiThread
|
||||
public @NonNull DynamicToolbarAnimator getDynamicToolbarAnimator() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mToolbar == null) {
|
||||
mToolbar = new DynamicToolbarAnimator(this);
|
||||
}
|
||||
return mToolbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CompositorController instance for this session.
|
||||
*
|
||||
* @return CompositorController instance.
|
||||
*/
|
||||
@UiThread
|
||||
public @NonNull CompositorController getCompositorController() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mController == null) {
|
||||
mController = new CompositorController(this);
|
||||
if (mCompositorReady) {
|
||||
mController.onCompositorReady();
|
||||
}
|
||||
}
|
||||
return mController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from client coordinates to surface coordinates.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getClientToScreenMatrix(Matrix)
|
||||
* @see #getPageToSurfaceMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientToSurfaceMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
matrix.setScale(mViewportZoom, mViewportZoom);
|
||||
if (mClientTop != mTop) {
|
||||
matrix.postTranslate(0, mClientTop - mTop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from client coordinates to screen coordinates. The
|
||||
* client coordinates are in CSS pixels and are relative to the viewport origin; their
|
||||
* relation to screen coordinates does not depend on the current scroll position.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getClientToSurfaceMatrix(Matrix)
|
||||
* @see #getPageToScreenMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientToScreenMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getClientToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(mLeft, mTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from page coordinates to screen coordinates. The page
|
||||
* coordinates are in CSS pixels and are relative to the page origin; their relation
|
||||
* to screen coordinates depends on the current scroll position of the outermost
|
||||
* frame.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getPageToSurfaceMatrix(Matrix)
|
||||
* @see #getClientToScreenMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getPageToScreenMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getPageToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(mLeft, mTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from page coordinates to surface coordinates.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getPageToScreenMatrix(Matrix)
|
||||
* @see #getClientToSurfaceMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getPageToSurfaceMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getClientToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(-mViewportLeft, -mViewportTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds of the client area in client coordinates. The returned top-left
|
||||
* coordinates are always (0, 0). Use the matrix from {@link
|
||||
* #getClientToSurfaceMatrix(Matrix)} or {@link #getClientToScreenMatrix(Matrix)} to
|
||||
* map these bounds to surface or screen coordinates, respectively.
|
||||
*
|
||||
* @param rect RectF to be replaced by the client bounds in client coordinates.
|
||||
* @see #getSurfaceBounds(Rect)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientBounds(@NonNull final RectF rect) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
rect.set(0.0f, 0.0f, (float) mWidth / mViewportZoom,
|
||||
(float) mClientHeight / mViewportZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds of the client area in surface coordinates. This is equivalent to
|
||||
* mapping the bounds returned by #getClientBounds(RectF) with the matrix returned by
|
||||
* #getClientToSurfaceMatrix(Matrix).
|
||||
*
|
||||
* @param rect Rect to be replaced by the client bounds in surface coordinates.
|
||||
*/
|
||||
@UiThread
|
||||
public void getSurfaceBounds(@NonNull final Rect rect) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
rect.set(0, mClientTop - mTop, mWidth, mHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* GeckoSession applications implement this interface to handle tracking
|
||||
* protection events.
|
||||
|
@ -3598,6 +3924,237 @@ public class GeckoSession extends LayerSession
|
|||
int virtualId);
|
||||
}
|
||||
|
||||
/* package */ void onSurfaceChanged(final Surface surface, final int width,
|
||||
final int height) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
if (mCompositorReady) {
|
||||
mCompositor.syncResumeResizeCompositor(width, height, surface);
|
||||
onWindowBoundsChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a valid surface but we're not attached or the compositor
|
||||
// is not ready; save the surface for later when we're ready.
|
||||
mSurface = surface;
|
||||
|
||||
// Adjust bounds as the last step.
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
|
||||
/* package */ void onSurfaceDestroyed() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mCompositorReady) {
|
||||
mCompositor.syncPauseCompositor();
|
||||
return;
|
||||
}
|
||||
|
||||
// While the surface was valid, we never became attached or the
|
||||
// compositor never became ready; clear the saved surface.
|
||||
mSurface = null;
|
||||
}
|
||||
|
||||
/* package */ void onScreenOriginChanged(final int left, final int top) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mLeft == left && mTop == top) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLeft = left;
|
||||
mTop = top;
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
|
||||
/* package */ void onCompositorAttached() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mAttachedCompositor = true;
|
||||
|
||||
if (mNPZC != null) {
|
||||
mCompositor.attachNPZC(mNPZC);
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
// If we have a valid surface, create the compositor now that we're attached.
|
||||
// Leave mSurface alone because we'll need it later for onCompositorReady.
|
||||
onSurfaceChanged(mSurface, mWidth, mHeight);
|
||||
}
|
||||
|
||||
mCompositor.sendToolbarAnimatorMessage(IS_COMPOSITOR_CONTROLLER_OPEN);
|
||||
}
|
||||
|
||||
/* package */ void onCompositorDetached() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mController != null) {
|
||||
mController.onCompositorDetached();
|
||||
}
|
||||
|
||||
mAttachedCompositor = false;
|
||||
mCompositorReady = false;
|
||||
}
|
||||
|
||||
/* package */ void handleCompositorMessage(final int message) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case COMPOSITOR_CONTROLLER_OPEN: {
|
||||
if (isCompositorReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay calling onCompositorReady to avoid deadlock due
|
||||
// to synchronous call to the compositor.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onCompositorReady();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case FIRST_PAINT: {
|
||||
if (mController != null) {
|
||||
mController.onFirstPaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LAYERS_UPDATED: {
|
||||
if (mController != null) {
|
||||
mController.notifyDrawCallbacks();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATIC_TOOLBAR_READY:
|
||||
case TOOLBAR_SHOW: {
|
||||
if (mToolbar != null) {
|
||||
mToolbar.handleToolbarAnimatorMessage(message);
|
||||
// Update window bounds due to toolbar visibility change.
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (mToolbar != null) {
|
||||
mToolbar.handleToolbarAnimatorMessage(message);
|
||||
} else {
|
||||
Log.w(LOGTAG, "Unexpected message: " + message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void recvScreenPixels(int width, int height, int[] pixels) {
|
||||
if (mController != null) {
|
||||
mController.recvScreenPixels(width, height, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ boolean isCompositorReady() {
|
||||
return mCompositorReady;
|
||||
}
|
||||
|
||||
/* package */ void onCompositorReady() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mCompositorReady = true;
|
||||
|
||||
if (mController != null) {
|
||||
mController.onCompositorReady();
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
// If we have a valid surface, resume the
|
||||
// compositor now that the compositor is ready.
|
||||
onSurfaceChanged(mSurface, mWidth, mHeight);
|
||||
mSurface = null;
|
||||
}
|
||||
|
||||
if (mToolbar != null) {
|
||||
mToolbar.onCompositorReady();
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void updateOverscrollVelocity(final float x, final float y) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mOverscroll == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Multiply the velocity by 1000 to match what was done in JPZ.
|
||||
mOverscroll.setVelocity(x * 1000.0f, OverscrollEdgeEffect.AXIS_X);
|
||||
mOverscroll.setVelocity(y * 1000.0f, OverscrollEdgeEffect.AXIS_Y);
|
||||
}
|
||||
|
||||
/* package */ void updateOverscrollOffset(final float x, final float y) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mOverscroll == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOverscroll.setDistance(x, OverscrollEdgeEffect.AXIS_X);
|
||||
mOverscroll.setDistance(y, OverscrollEdgeEffect.AXIS_Y);
|
||||
}
|
||||
|
||||
/* package */ void onMetricsChanged(final float scrollX, final float scrollY,
|
||||
final float zoom) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mViewportLeft = scrollX;
|
||||
mViewportTop = scrollY;
|
||||
mViewportZoom = zoom;
|
||||
}
|
||||
|
||||
/* protected */ void onWindowBoundsChanged() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
final int toolbarHeight;
|
||||
if (mToolbar != null) {
|
||||
toolbarHeight = mToolbar.getCurrentToolbarHeight();
|
||||
} else {
|
||||
toolbarHeight = 0;
|
||||
}
|
||||
|
||||
mClientTop = mTop + toolbarHeight;
|
||||
mClientHeight = mHeight - toolbarHeight;
|
||||
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.onBoundsChanged(mLeft, mClientTop, mWidth, mClientHeight);
|
||||
}
|
||||
|
||||
if (mOverscroll != null) {
|
||||
mOverscroll.setSize(mWidth, mClientHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GeckoSession applications implement this interface to handle media events.
|
||||
*/
|
||||
|
|
|
@ -1,586 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* 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/. */
|
||||
|
||||
package org.mozilla.geckoview;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.mozglue.JNIObject;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
public class LayerSession {
|
||||
private static final String LOGTAG = "GeckoLayerSession";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
//
|
||||
// NOTE: These values are also defined in
|
||||
// gfx/layers/ipc/UiCompositorControllerMessageTypes.h and must be kept in sync. Any
|
||||
// new AnimatorMessageType added here must also be added there.
|
||||
//
|
||||
// Sent from compositor when the static toolbar wants to hide.
|
||||
/* package */ final static int STATIC_TOOLBAR_NEEDS_UPDATE = 0;
|
||||
// Sent from compositor when the static toolbar image has been updated and is ready to
|
||||
// animate.
|
||||
/* package */ final static int STATIC_TOOLBAR_READY = 1;
|
||||
// Sent to compositor when the real toolbar has been hidden.
|
||||
/* package */ final static int TOOLBAR_HIDDEN = 2;
|
||||
// Sent to compositor when the real toolbar is visible.
|
||||
/* package */ final static int TOOLBAR_VISIBLE = 3;
|
||||
// Sent from compositor when the static toolbar has been made visible so the real
|
||||
// toolbar should be shown.
|
||||
/* package */ final static int TOOLBAR_SHOW = 4;
|
||||
// Sent from compositor after first paint
|
||||
/* package */ final static int FIRST_PAINT = 5;
|
||||
// Sent to compositor requesting toolbar be shown immediately
|
||||
/* package */ final static int REQUEST_SHOW_TOOLBAR_IMMEDIATELY = 6;
|
||||
// Sent to compositor requesting toolbar be shown animated
|
||||
/* package */ final static int REQUEST_SHOW_TOOLBAR_ANIMATED = 7;
|
||||
// Sent to compositor requesting toolbar be hidden immediately
|
||||
/* package */ final static int REQUEST_HIDE_TOOLBAR_IMMEDIATELY = 8;
|
||||
// Sent to compositor requesting toolbar be hidden animated
|
||||
/* package */ final static int REQUEST_HIDE_TOOLBAR_ANIMATED = 9;
|
||||
// Sent from compositor when a layer has been updated
|
||||
/* package */ final static int LAYERS_UPDATED = 10;
|
||||
// Sent to compositor when the toolbar snapshot fails.
|
||||
/* package */ final static int TOOLBAR_SNAPSHOT_FAILED = 11;
|
||||
// Special message sent from UiCompositorControllerChild once it is open
|
||||
/* package */ final static int COMPOSITOR_CONTROLLER_OPEN = 20;
|
||||
// Special message sent from controller to query if the compositor controller is open.
|
||||
/* package */ final static int IS_COMPOSITOR_CONTROLLER_OPEN = 21;
|
||||
|
||||
protected class Compositor extends JNIObject {
|
||||
public boolean isReady() {
|
||||
return LayerSession.this.isCompositorReady();
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void onCompositorAttached() {
|
||||
LayerSession.this.onCompositorAttached();
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void onCompositorDetached() {
|
||||
// Clear out any pending calls on the UI thread.
|
||||
LayerSession.this.onCompositorDetached();
|
||||
}
|
||||
|
||||
@WrapForJNI(dispatchTo = "gecko")
|
||||
@Override protected native void disposeNative();
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void attachNPZC(PanZoomController npzc);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void onBoundsChanged(int left, int top, int width, int height);
|
||||
|
||||
// Gecko thread pauses compositor; blocks UI thread.
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void syncPauseCompositor();
|
||||
|
||||
// UI thread resumes compositor and notifies Gecko thread; does not block UI thread.
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void syncResumeResizeCompositor(int width, int height, Object surface);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setMaxToolbarHeight(int height);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setPinned(boolean pinned, int reason);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void sendToolbarAnimatorMessage(int message);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void recvToolbarAnimatorMessage(int message) {
|
||||
LayerSession.this.handleCompositorMessage(message);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void setDefaultClearColor(int color);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void requestScreenPixels();
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void recvScreenPixels(int width, int height, int[] pixels) {
|
||||
LayerSession.this.recvScreenPixels(width, height, pixels);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void enableLayerUpdateNotifications(boolean enable);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void sendToolbarPixelsToCompositor(final int width, final int height,
|
||||
final int[] pixels);
|
||||
|
||||
// The compositor invokes this function just before compositing a frame where the
|
||||
// document is different from the document composited on the last frame. In these
|
||||
// cases, the viewport information we have in Java is no longer valid and needs to
|
||||
// be replaced with the new viewport information provided.
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateRootFrameMetrics(float scrollX, float scrollY, float zoom) {
|
||||
LayerSession.this.onMetricsChanged(scrollX, scrollY, zoom);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateOverscrollVelocity(final float x, final float y) {
|
||||
LayerSession.this.updateOverscrollVelocity(x, y);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui")
|
||||
private void updateOverscrollOffset(final float x, final float y) {
|
||||
LayerSession.this.updateOverscrollOffset(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
disposeNative();
|
||||
}
|
||||
}
|
||||
|
||||
protected final Compositor mCompositor = new Compositor();
|
||||
|
||||
// All fields are accessed on UI thread only.
|
||||
private PanZoomController mNPZC;
|
||||
private OverscrollEdgeEffect mOverscroll;
|
||||
private DynamicToolbarAnimator mToolbar;
|
||||
private CompositorController mController;
|
||||
|
||||
private boolean mAttachedCompositor;
|
||||
private boolean mCompositorReady;
|
||||
private Surface mSurface;
|
||||
|
||||
// All fields of coordinates are in screen units.
|
||||
private int mLeft;
|
||||
private int mTop; // Top of the surface (including toolbar);
|
||||
private int mClientTop; // Top of the client area (i.e. excluding toolbar);
|
||||
private int mWidth;
|
||||
private int mHeight; // Height of the surface (including toolbar);
|
||||
private int mClientHeight; // Height of the client area (i.e. excluding toolbar);
|
||||
private float mViewportLeft;
|
||||
private float mViewportTop;
|
||||
private float mViewportZoom = 1.0f;
|
||||
|
||||
/**
|
||||
* Get the PanZoomController instance for this session.
|
||||
*
|
||||
* @return PanZoomController instance.
|
||||
*/
|
||||
@UiThread
|
||||
public PanZoomController getPanZoomController() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mNPZC == null) {
|
||||
mNPZC = new PanZoomController(this);
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.attachNPZC(mNPZC);
|
||||
}
|
||||
}
|
||||
return mNPZC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OverscrollEdgeEffect instance for this session.
|
||||
*
|
||||
* @return OverscrollEdgeEffect instance.
|
||||
*/
|
||||
@UiThread
|
||||
public OverscrollEdgeEffect getOverscrollEdgeEffect() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mOverscroll == null) {
|
||||
mOverscroll = new OverscrollEdgeEffect(this);
|
||||
}
|
||||
return mOverscroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DynamicToolbarAnimator instance for this session.
|
||||
*
|
||||
* @return DynamicToolbarAnimator instance.
|
||||
*/
|
||||
@UiThread
|
||||
public @NonNull DynamicToolbarAnimator getDynamicToolbarAnimator() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mToolbar == null) {
|
||||
mToolbar = new DynamicToolbarAnimator(this);
|
||||
}
|
||||
return mToolbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CompositorController instance for this session.
|
||||
*
|
||||
* @return CompositorController instance.
|
||||
*/
|
||||
@UiThread
|
||||
public @NonNull CompositorController getCompositorController() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mController == null) {
|
||||
mController = new CompositorController(this);
|
||||
if (mCompositorReady) {
|
||||
mController.onCompositorReady();
|
||||
}
|
||||
}
|
||||
return mController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from client coordinates to screen coordinates. The
|
||||
* client coordinates are in CSS pixels and are relative to the viewport origin; their
|
||||
* relation to screen coordinates does not depend on the current scroll position.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getClientToSurfaceMatrix(Matrix)
|
||||
* @see #getPageToScreenMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientToScreenMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getClientToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(mLeft, mTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from client coordinates to surface coordinates.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getClientToScreenMatrix(Matrix)
|
||||
* @see #getPageToSurfaceMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientToSurfaceMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
matrix.setScale(mViewportZoom, mViewportZoom);
|
||||
if (mClientTop != mTop) {
|
||||
matrix.postTranslate(0, mClientTop - mTop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from page coordinates to screen coordinates. The page
|
||||
* coordinates are in CSS pixels and are relative to the page origin; their relation
|
||||
* to screen coordinates depends on the current scroll position of the outermost
|
||||
* frame.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getPageToSurfaceMatrix(Matrix)
|
||||
* @see #getClientToScreenMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getPageToScreenMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getPageToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(mLeft, mTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a matrix for transforming from page coordinates to surface coordinates.
|
||||
*
|
||||
* @param matrix Matrix to be replaced by the transformation matrix.
|
||||
* @see #getPageToScreenMatrix(Matrix)
|
||||
* @see #getClientToSurfaceMatrix(Matrix)
|
||||
*/
|
||||
@UiThread
|
||||
public void getPageToSurfaceMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
getClientToSurfaceMatrix(matrix);
|
||||
matrix.postTranslate(-mViewportLeft, -mViewportTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds of the client area in client coordinates. The returned top-left
|
||||
* coordinates are always (0, 0). Use the matrix from {@link
|
||||
* #getClientToSurfaceMatrix(Matrix)} or {@link #getClientToScreenMatrix(Matrix)} to
|
||||
* map these bounds to surface or screen coordinates, respectively.
|
||||
*
|
||||
* @param rect RectF to be replaced by the client bounds in client coordinates.
|
||||
* @see #getSurfaceBounds(Rect)
|
||||
*/
|
||||
@UiThread
|
||||
public void getClientBounds(@NonNull final RectF rect) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
rect.set(0.0f, 0.0f, (float) mWidth / mViewportZoom,
|
||||
(float) mClientHeight / mViewportZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounds of the client area in surface coordinates. This is equivalent to
|
||||
* mapping the bounds returned by #getClientBounds(RectF) with the matrix returned by
|
||||
* #getClientToSurfaceMatrix(Matrix).
|
||||
*
|
||||
* @param rect Rect to be replaced by the client bounds in surface coordinates.
|
||||
*/
|
||||
@UiThread
|
||||
public void getSurfaceBounds(@NonNull final Rect rect) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
rect.set(0, mClientTop - mTop, mWidth, mHeight);
|
||||
}
|
||||
|
||||
@WrapForJNI(stubName = "GetCompositor", calledFrom = "ui")
|
||||
private Object getCompositorFromNative() {
|
||||
// Only used by native code.
|
||||
return mCompositorReady ? mCompositor : null;
|
||||
}
|
||||
|
||||
/* package */ void onCompositorAttached() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mAttachedCompositor = true;
|
||||
|
||||
if (mNPZC != null) {
|
||||
mCompositor.attachNPZC(mNPZC);
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
// If we have a valid surface, create the compositor now that we're attached.
|
||||
// Leave mSurface alone because we'll need it later for onCompositorReady.
|
||||
onSurfaceChanged(mSurface, mWidth, mHeight);
|
||||
}
|
||||
|
||||
mCompositor.sendToolbarAnimatorMessage(IS_COMPOSITOR_CONTROLLER_OPEN);
|
||||
}
|
||||
|
||||
/* package */ void onCompositorDetached() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mController != null) {
|
||||
mController.onCompositorDetached();
|
||||
}
|
||||
|
||||
mAttachedCompositor = false;
|
||||
mCompositorReady = false;
|
||||
}
|
||||
|
||||
/* package */ void handleCompositorMessage(final int message) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case COMPOSITOR_CONTROLLER_OPEN: {
|
||||
if (isCompositorReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay calling onCompositorReady to avoid deadlock due
|
||||
// to synchronous call to the compositor.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onCompositorReady();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case FIRST_PAINT: {
|
||||
if (mController != null) {
|
||||
mController.onFirstPaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LAYERS_UPDATED: {
|
||||
if (mController != null) {
|
||||
mController.notifyDrawCallbacks();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATIC_TOOLBAR_READY:
|
||||
case TOOLBAR_SHOW: {
|
||||
if (mToolbar != null) {
|
||||
mToolbar.handleToolbarAnimatorMessage(message);
|
||||
// Update window bounds due to toolbar visibility change.
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (mToolbar != null) {
|
||||
mToolbar.handleToolbarAnimatorMessage(message);
|
||||
} else {
|
||||
Log.w(LOGTAG, "Unexpected message: " + message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void recvScreenPixels(int width, int height, int[] pixels) {
|
||||
if (mController != null) {
|
||||
mController.recvScreenPixels(width, height, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ boolean isCompositorReady() {
|
||||
return mCompositorReady;
|
||||
}
|
||||
|
||||
/* package */ void onCompositorReady() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mCompositorReady = true;
|
||||
|
||||
if (mController != null) {
|
||||
mController.onCompositorReady();
|
||||
}
|
||||
|
||||
if (mSurface != null) {
|
||||
// If we have a valid surface, resume the
|
||||
// compositor now that the compositor is ready.
|
||||
onSurfaceChanged(mSurface, mWidth, mHeight);
|
||||
mSurface = null;
|
||||
}
|
||||
|
||||
if (mToolbar != null) {
|
||||
mToolbar.onCompositorReady();
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void updateOverscrollVelocity(final float x, final float y) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mOverscroll == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Multiply the velocity by 1000 to match what was done in JPZ.
|
||||
mOverscroll.setVelocity(x * 1000.0f, OverscrollEdgeEffect.AXIS_X);
|
||||
mOverscroll.setVelocity(y * 1000.0f, OverscrollEdgeEffect.AXIS_Y);
|
||||
}
|
||||
|
||||
/* package */ void updateOverscrollOffset(final float x, final float y) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mOverscroll == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOverscroll.setDistance(x, OverscrollEdgeEffect.AXIS_X);
|
||||
mOverscroll.setDistance(y, OverscrollEdgeEffect.AXIS_Y);
|
||||
}
|
||||
|
||||
protected void setShouldPinOnScreen(final boolean pinned) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mToolbar != null) {
|
||||
mToolbar.setPinned(pinned, DynamicToolbarAnimator.PinReason.CARET_DRAG);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void onMetricsChanged(final float scrollX, final float scrollY,
|
||||
final float zoom) {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
mViewportLeft = scrollX;
|
||||
mViewportTop = scrollY;
|
||||
mViewportZoom = zoom;
|
||||
}
|
||||
|
||||
/* protected */ void onWindowBoundsChanged() {
|
||||
if (DEBUG) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
final int toolbarHeight;
|
||||
if (mToolbar != null) {
|
||||
toolbarHeight = mToolbar.getCurrentToolbarHeight();
|
||||
} else {
|
||||
toolbarHeight = 0;
|
||||
}
|
||||
|
||||
mClientTop = mTop + toolbarHeight;
|
||||
mClientHeight = mHeight - toolbarHeight;
|
||||
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.onBoundsChanged(mLeft, mClientTop, mWidth, mClientHeight);
|
||||
}
|
||||
|
||||
if (mOverscroll != null) {
|
||||
mOverscroll.setSize(mWidth, mClientHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onSurfaceChanged(final Surface surface, final int width,
|
||||
final int height) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
if (mCompositorReady) {
|
||||
mCompositor.syncResumeResizeCompositor(width, height, surface);
|
||||
onWindowBoundsChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a valid surface but we're not attached or the compositor
|
||||
// is not ready; save the surface for later when we're ready.
|
||||
mSurface = surface;
|
||||
|
||||
// Adjust bounds as the last step.
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onSurfaceDestroyed() {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mCompositorReady) {
|
||||
mCompositor.syncPauseCompositor();
|
||||
return;
|
||||
}
|
||||
|
||||
// While the surface was valid, we never became attached or the
|
||||
// compositor never became ready; clear the saved surface.
|
||||
mSurface = null;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void onScreenOriginChanged(final int left, final int top) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mLeft == left && mTop == top) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLeft = left;
|
||||
mTop = top;
|
||||
onWindowBoundsChanged();
|
||||
}
|
||||
}
|
|
@ -32,12 +32,12 @@ public final class OverscrollEdgeEffect {
|
|||
// All four edges of the screen
|
||||
private final EdgeEffect[] mEdges = new EdgeEffect[4];
|
||||
|
||||
private final LayerSession mSession;
|
||||
private final GeckoSession mSession;
|
||||
private Runnable mInvalidationCallback;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
/* package */ OverscrollEdgeEffect(final LayerSession session) {
|
||||
/* package */ OverscrollEdgeEffect(final GeckoSession session) {
|
||||
mSession = session;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public class PanZoomController extends JNIObject {
|
|||
private static final int EVENT_SOURCE_MOTION = 1;
|
||||
private static final int EVENT_SOURCE_MOUSE = 2;
|
||||
|
||||
private final LayerSession mSession;
|
||||
private final GeckoSession mSession;
|
||||
private final Rect mTempRect = new Rect();
|
||||
private boolean mAttached;
|
||||
private float mPointerScrollFactor = 64.0f;
|
||||
|
@ -149,7 +149,7 @@ public class PanZoomController extends JNIObject {
|
|||
event.getMetaState(), x, y, event.getButtonState());
|
||||
}
|
||||
|
||||
protected PanZoomController(final LayerSession session) {
|
||||
protected PanZoomController(final GeckoSession session) {
|
||||
mSession = session;
|
||||
enableEventQueue();
|
||||
}
|
||||
|
|
|
@ -839,12 +839,12 @@ nsWindow::AndroidView::GetInitData(JSContext* aCx, JS::MutableHandleValue aOut)
|
|||
* separate from GeckoViewSupport.
|
||||
*/
|
||||
class nsWindow::LayerViewSupport final
|
||||
: public LayerSession::Compositor::Natives<LayerViewSupport>
|
||||
: public GeckoSession::Compositor::Natives<LayerViewSupport>
|
||||
{
|
||||
using LockedWindowPtr = WindowPtr<LayerViewSupport>::Locked;
|
||||
|
||||
WindowPtr<LayerViewSupport> mWindow;
|
||||
LayerSession::Compositor::WeakRef mCompositor;
|
||||
GeckoSession::Compositor::WeakRef mCompositor;
|
||||
Atomic<bool, ReleaseAcquire> mCompositorPaused;
|
||||
jni::Object::GlobalRef mSurface;
|
||||
|
||||
|
@ -882,16 +882,16 @@ class nsWindow::LayerViewSupport final
|
|||
};
|
||||
|
||||
public:
|
||||
typedef LayerSession::Compositor::Natives<LayerViewSupport> Base;
|
||||
typedef GeckoSession::Compositor::Natives<LayerViewSupport> Base;
|
||||
|
||||
static LayerViewSupport*
|
||||
FromNative(const LayerSession::Compositor::LocalRef& instance)
|
||||
FromNative(const GeckoSession::Compositor::LocalRef& instance)
|
||||
{
|
||||
return GetNative(instance);
|
||||
}
|
||||
|
||||
LayerViewSupport(NativePtr<LayerViewSupport>* aPtr, nsWindow* aWindow,
|
||||
const LayerSession::Compositor::LocalRef& aInstance)
|
||||
const GeckoSession::Compositor::LocalRef& aInstance)
|
||||
: mWindow(aPtr, aWindow)
|
||||
, mCompositor(aInstance)
|
||||
, mCompositorPaused(true)
|
||||
|
@ -908,7 +908,7 @@ public:
|
|||
void OnDetach(already_AddRefed<Runnable> aDisposer)
|
||||
{
|
||||
if (RefPtr<nsThread> uiThread = GetAndroidUiThread()) {
|
||||
LayerSession::Compositor::GlobalRef compositor(mCompositor);
|
||||
GeckoSession::Compositor::GlobalRef compositor(mCompositor);
|
||||
if (!compositor) {
|
||||
return;
|
||||
}
|
||||
|
@ -923,7 +923,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
const LayerSession::Compositor::Ref& GetJavaCompositor() const
|
||||
const GeckoSession::Compositor::Ref& GetJavaCompositor() const
|
||||
{
|
||||
return mCompositor;
|
||||
}
|
||||
|
@ -1004,7 +1004,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void SyncResumeResizeCompositor(const LayerSession::Compositor::LocalRef& aObj,
|
||||
void SyncResumeResizeCompositor(const GeckoSession::Compositor::LocalRef& aObj,
|
||||
int32_t aWidth, int32_t aHeight,
|
||||
jni::Object::Param aSurface)
|
||||
{
|
||||
|
@ -1020,10 +1020,10 @@ public:
|
|||
|
||||
class OnResumedEvent : public nsAppShell::Event
|
||||
{
|
||||
LayerSession::Compositor::GlobalRef mCompositor;
|
||||
GeckoSession::Compositor::GlobalRef mCompositor;
|
||||
|
||||
public:
|
||||
explicit OnResumedEvent(LayerSession::Compositor::GlobalRef&& aCompositor)
|
||||
explicit OnResumedEvent(GeckoSession::Compositor::GlobalRef&& aCompositor)
|
||||
: mCompositor(std::move(aCompositor))
|
||||
{}
|
||||
|
||||
|
@ -1033,7 +1033,7 @@ public:
|
|||
|
||||
JNIEnv* const env = jni::GetGeckoThreadEnv();
|
||||
LayerViewSupport* const lvs = GetNative(
|
||||
LayerSession::Compositor::LocalRef(env, mCompositor));
|
||||
GeckoSession::Compositor::LocalRef(env, mCompositor));
|
||||
|
||||
if (!lvs || !lvs->mWindow) {
|
||||
env->ExceptionClear();
|
||||
|
@ -1128,7 +1128,7 @@ public:
|
|||
|
||||
void RecvToolbarAnimatorMessage(int32_t aMessage)
|
||||
{
|
||||
auto compositor = LayerSession::Compositor::LocalRef(mCompositor);
|
||||
auto compositor = GeckoSession::Compositor::LocalRef(mCompositor);
|
||||
if (compositor) {
|
||||
compositor->RecvToolbarAnimatorMessage(aMessage);
|
||||
}
|
||||
|
@ -1155,7 +1155,7 @@ public:
|
|||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||
|
||||
auto pixels = mozilla::jni::IntArray::New(aMem.get<int>(), aMem.Size<int>());
|
||||
auto compositor = LayerSession::Compositor::LocalRef(mCompositor);
|
||||
auto compositor = GeckoSession::Compositor::LocalRef(mCompositor);
|
||||
if (compositor) {
|
||||
compositor->RecvScreenPixels(aSize.width, aSize.height, pixels);
|
||||
}
|
||||
|
@ -1320,8 +1320,8 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
|
|||
window.mNPZCSupport.Detach(window.mNPZCSupport->GetJavaNPZC());
|
||||
}
|
||||
|
||||
auto compositor = LayerSession::Compositor::LocalRef(
|
||||
inst.Env(), LayerSession::Compositor::Ref::From(aCompositor));
|
||||
auto compositor = GeckoSession::Compositor::LocalRef(
|
||||
inst.Env(), GeckoSession::Compositor::Ref::From(aCompositor));
|
||||
if (window.mLayerViewSupport &&
|
||||
window.mLayerViewSupport->GetJavaCompositor() != compositor) {
|
||||
window.mLayerViewSupport.Detach(
|
||||
|
@ -1354,7 +1354,7 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
|
|||
|
||||
DispatchToUiThread(
|
||||
"GeckoViewSupport::Transfer",
|
||||
[compositor = LayerSession::Compositor::GlobalRef(compositor)] {
|
||||
[compositor = GeckoSession::Compositor::GlobalRef(compositor)] {
|
||||
compositor->OnCompositorAttached();
|
||||
});
|
||||
}
|
||||
|
@ -2028,7 +2028,7 @@ nsWindow::UpdateOverscrollVelocity(const float aX, const float aY)
|
|||
|
||||
DispatchToUiThread(
|
||||
"nsWindow::UpdateOverscrollVelocity",
|
||||
[compositor = LayerSession::Compositor::GlobalRef(compositor),
|
||||
[compositor = GeckoSession::Compositor::GlobalRef(compositor),
|
||||
aX, aY] {
|
||||
compositor->UpdateOverscrollVelocity(aX, aY);
|
||||
});
|
||||
|
@ -2047,7 +2047,7 @@ nsWindow::UpdateOverscrollOffset(const float aX, const float aY)
|
|||
|
||||
DispatchToUiThread(
|
||||
"nsWindow::UpdateOverscrollOffset",
|
||||
[compositor = LayerSession::Compositor::GlobalRef(compositor),
|
||||
[compositor = GeckoSession::Compositor::GlobalRef(compositor),
|
||||
aX, aY] {
|
||||
compositor->UpdateOverscrollOffset(aX, aY);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче