зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1416319
- 7. Don't expose viewport metrics from LayerSession; r=rbarker
Provide a set of coordinates APIs in LayerSession instead of exposing the raw viewport metrics, which are hard to use. This also lets us remove ImmutableViewportMetrics completely. The new APIs provide rectangular bounds in client or surface coordinates, and matrices to transform those coordinates to screen coordinates. This is done because the transformation to screen coordinates could (in the future) involve skew, rotation, etc, so it's up to the application to decide how to handle non-rectangular screen bounds. MozReview-Commit-ID: 8Yw8L63TmrQ --HG-- extra : rebase_source : 76954d32da9fb8435ec68ea53b6dc618f8cb0121
This commit is contained in:
Родитель
e1e55d7285
Коммит
0c82587e52
|
@ -400,7 +400,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
|
|||
'gfx/GeckoDisplay.java',
|
||||
'gfx/GeckoSurface.java',
|
||||
'gfx/GeckoSurfaceTexture.java',
|
||||
'gfx/ImmutableViewportMetrics.java',
|
||||
'gfx/IntSize.java',
|
||||
'gfx/LayerSession.java',
|
||||
'gfx/LayerView.java',
|
||||
|
|
|
@ -1,104 +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.gecko.gfx;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
|
||||
/**
|
||||
* ImmutableViewportMetrics are used to store the viewport metrics
|
||||
* in way that we can access a version of them from multiple threads
|
||||
* without having to take a lock
|
||||
*/
|
||||
public class ImmutableViewportMetrics {
|
||||
|
||||
// We need to flatten the RectF and FloatSize structures
|
||||
// because Java doesn't have the concept of const classes
|
||||
public final float viewportRectLeft;
|
||||
public final float viewportRectTop;
|
||||
public final int viewportRectWidth;
|
||||
public final int viewportRectHeight;
|
||||
|
||||
public final float zoomFactor;
|
||||
|
||||
public ImmutableViewportMetrics() {
|
||||
viewportRectLeft = 0;
|
||||
viewportRectTop = 0;
|
||||
viewportRectWidth = 0;
|
||||
viewportRectHeight = 0;
|
||||
zoomFactor = 1.0f;
|
||||
}
|
||||
|
||||
private ImmutableViewportMetrics(
|
||||
float aViewportRectLeft, float aViewportRectTop, int aViewportRectWidth,
|
||||
int aViewportRectHeight, float aZoomFactor)
|
||||
{
|
||||
viewportRectLeft = aViewportRectLeft;
|
||||
viewportRectTop = aViewportRectTop;
|
||||
viewportRectWidth = aViewportRectWidth;
|
||||
viewportRectHeight = aViewportRectHeight;
|
||||
zoomFactor = aZoomFactor;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return viewportRectWidth;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return viewportRectHeight;
|
||||
}
|
||||
|
||||
public float viewportRectRight() {
|
||||
return viewportRectLeft + viewportRectWidth;
|
||||
}
|
||||
|
||||
public float viewportRectBottom() {
|
||||
return viewportRectTop + viewportRectHeight;
|
||||
}
|
||||
|
||||
public PointF getOrigin() {
|
||||
return new PointF(viewportRectLeft, viewportRectTop);
|
||||
}
|
||||
|
||||
public FloatSize getSize() {
|
||||
return new FloatSize(viewportRectWidth, viewportRectHeight);
|
||||
}
|
||||
|
||||
public RectF getViewport() {
|
||||
return new RectF(viewportRectLeft,
|
||||
viewportRectTop,
|
||||
viewportRectRight(),
|
||||
viewportRectBottom());
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setViewportSize(int width, int height) {
|
||||
if (width == viewportRectWidth && height == viewportRectHeight) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return new ImmutableViewportMetrics(
|
||||
viewportRectLeft, viewportRectTop, width, height,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) {
|
||||
return new ImmutableViewportMetrics(
|
||||
newOriginX, newOriginY, viewportRectWidth, viewportRectHeight,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) {
|
||||
return new ImmutableViewportMetrics(
|
||||
viewportRectLeft, viewportRectTop, viewportRectWidth, viewportRectHeight,
|
||||
newZoomFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + ","
|
||||
+ viewportRectWidth + "x" + viewportRectHeight + ") z=" + zoomFactor;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,10 @@ import org.mozilla.gecko.util.ThreadUtils;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
|
@ -144,18 +148,25 @@ public class LayerSession {
|
|||
|
||||
protected final Compositor mCompositor = new Compositor();
|
||||
|
||||
// Following fields are accessed on UI thread.
|
||||
// All fields are accessed on UI thread only.
|
||||
private GeckoDisplay mDisplay;
|
||||
private DynamicToolbarAnimator mToolbar;
|
||||
private ImmutableViewportMetrics mViewportMetrics = new ImmutableViewportMetrics();
|
||||
|
||||
private boolean mAttachedCompositor;
|
||||
private boolean mCalledCreateCompositor;
|
||||
private boolean mCompositorReady;
|
||||
private Surface mSurface;
|
||||
|
||||
// All fields of coordinates are in screen units.
|
||||
private int mLeft;
|
||||
private int mTop;
|
||||
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;
|
||||
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;
|
||||
|
||||
/* package */ GeckoDisplay getDisplay() {
|
||||
if (DEBUG) {
|
||||
|
@ -178,9 +189,96 @@ public class LayerSession {
|
|||
return mToolbar;
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics getViewportMetrics() {
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
public void getClientToScreenMatrix(@NonNull final Matrix matrix) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
return mViewportMetrics;
|
||||
|
||||
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)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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
|
||||
* #getClientToSurfaceMatrix(Matrix) or #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)
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public void getSurfaceBounds(@NonNull final Rect rect) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
rect.set(0, mClientTop - mTop, mWidth, mHeight);
|
||||
}
|
||||
|
||||
/* package */ void onCompositorAttached() {
|
||||
|
@ -296,14 +394,9 @@ public class LayerSession {
|
|||
ThreadUtils.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (mViewportMetrics.viewportRectLeft != scrollX ||
|
||||
mViewportMetrics.viewportRectTop != scrollY) {
|
||||
mViewportMetrics = mViewportMetrics.setViewportOrigin(scrollX, scrollY);
|
||||
}
|
||||
|
||||
if (mViewportMetrics.zoomFactor != zoom) {
|
||||
mViewportMetrics = mViewportMetrics.setZoomFactor(zoom);
|
||||
}
|
||||
mViewportLeft = scrollX;
|
||||
mViewportTop = scrollY;
|
||||
mViewportZoom = zoom;
|
||||
}
|
||||
|
||||
/* protected */ void onWindowBoundsChanged() {
|
||||
|
@ -318,15 +411,11 @@ public class LayerSession {
|
|||
toolbarHeight = 0;
|
||||
}
|
||||
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.onBoundsChanged(mLeft, mTop + toolbarHeight,
|
||||
mWidth, mHeight - toolbarHeight);
|
||||
}
|
||||
mClientTop = mTop + toolbarHeight;
|
||||
mClientHeight = mHeight - toolbarHeight;
|
||||
|
||||
if (mViewportMetrics.viewportRectWidth != mWidth ||
|
||||
mViewportMetrics.viewportRectHeight != (mHeight - toolbarHeight)) {
|
||||
mViewportMetrics = mViewportMetrics.setViewportSize(mWidth,
|
||||
mHeight - toolbarHeight);
|
||||
if (mAttachedCompositor) {
|
||||
mCompositor.onBoundsChanged(mLeft, mClientTop, mWidth, mClientHeight);
|
||||
}
|
||||
|
||||
if (mCompositor.layerView != null) {
|
||||
|
@ -341,11 +430,6 @@ public class LayerSession {
|
|||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
if (mViewportMetrics.viewportRectWidth == 0 ||
|
||||
mViewportMetrics.viewportRectHeight == 0) {
|
||||
mViewportMetrics = mViewportMetrics.setViewportSize(width, height);
|
||||
}
|
||||
|
||||
if (mCompositorReady) {
|
||||
mCompositor.syncResumeResizeCompositor(width, height, surface);
|
||||
onWindowBoundsChanged();
|
||||
|
@ -361,6 +445,9 @@ public class LayerSession {
|
|||
// 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() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче