Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Unified Diff: remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java

Issue 2441723004: [Android][Client] Updating the calculations used for image overpanning (Closed)
Patch Set: Pre-CR cleanup Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
index e93364f249bf980843f5ad4556cb0376ba473eeb..510d3d733fe6a8457ffe6683af7230db3a2f4fac 100644
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
@@ -13,62 +13,50 @@ import android.graphics.RectF;
* This class is responsible for transforming the desktop image matrix.
*/
public class DesktopCanvas {
- /**
- * Maximum allowed zoom level - see {@link #scaleAndRepositionImage()}.
- */
+ private static final float EPSILON = 0.0001f;
Lambros 2016/10/24 22:20:33 Does this value need to be different from MINIMUM_
joedow 2016/10/25 02:28:18 This is used for floating point comparisons (speci
+
+ /** Maximum allowed zoom level - see {@link #scaleAndRepositionImage()}. */
private static final float MAX_ZOOM_FACTOR = 100.0f;
- /**
- * Used to smoothly reduce the amount of padding while the user is zooming.
- */
- private static final float PADDING_REDUCTION_FACTOR = 0.85f;
+ /** Used to smoothly reduce the viewport offset. */
+ private static final float OFFSET_REDUCTION_FACTOR = 0.85f;
+
+ /** Used to terminate the offset animation once a minimum offset(1 pixel) has been reached. */
+ private static final float MINIMUM_OFFSET_DISTANCE = 1;
Lambros 2016/10/24 22:20:33 This is in screen coordinates?
joedow 2016/10/25 02:28:18 It is in the same coordinates as mViewportOffset.
private final RenderStub mRenderStub;
private final RenderData mRenderData;
/**
- * Represents the actual center of the viewport in image space. This value needs to be a pair
- * of floats so the desktop image can be positioned with sub-pixel accuracy for smoother panning
- * animations at high zoom levels.
- */
- // TODO(joedow): See if we can collapse Viewport and Cursor position members. They were needed
- // in the past due to how we calculated the center positions but may not be needed now.
- private PointF mViewportPosition = new PointF();
-
- /**
* Represents the desired center of the viewport in image space. This value may not represent
* the actual center of the viewport as adjustments are made to ensure as much of the desktop is
* visible as possible. This value needs to be a pair of floats so the desktop image can be
* positioned with sub-pixel accuracy for smoother panning animations at high zoom levels.
- * Note: The internal cursor position may be placed outside of the image boundary, however the
- * cursor position we inject on the host side is restricted to the actual image dimensions.
*/
private PointF mCursorPosition = new PointF();
/**
* Represents the amount of space, in pixels, used by System UI on each edge of the screen.
*/
- // TODO(joedow): Update usage of this member so it is a true Rect instead of a set of offsets.
private Rect mSystemUiScreenSize = new Rect();
/**
- * Represents the amount of padding, in screen pixels, added to each edge of the desktop image.
- * This extra space allows the user to reveal portions of the desktop image which are obscured
- * by System UI.
+ * Represents the amount of space, in pixels, to shift the image under the viewport. This value
+ * is used to allow panning the image further than would be possible when using the normal
+ * boundary values to account for System UI. This functionality ensures the user can view and
+ * interact with any area of the remote image, even when System UI might otherwise obscure it.
*/
- private RectF mVisibleImagePadding = new RectF();
+ private PointF mViewportOffset = new PointF();
/**
- * Tracks whether to adjust the viewport to account for System UI. If false, the viewport
- * center is the center of the screen. If true, then System UI offsets will be used to
- * adjust the position of the viewport to ensure the cursor is visible.
+ * Tracks whether to adjust the size of the viewport to account for System UI. If false, the
+ * viewport center is mapped to the center of the screen. If true, then System UI sizes will be
+ * used to determine the center of the viewport.
*/
- private boolean mAdjustViewportForSystemUi = false;
+ private boolean mAdjustViewportSizeForSystemUi = false;
- /**
- * Represents the amount of space, in pixels, to adjust the cursor center along the y-axis.
- */
- private float mCursorOffsetScreenY = 0.0f;
+ /* Used to perform per-frame rendering tasks. */
+ private Event.ParameterCallback<Boolean, Void> mFrameRenderedCallback;
public DesktopCanvas(RenderStub renderStub, RenderData renderData) {
mRenderStub = renderStub;
@@ -76,88 +64,76 @@ public class DesktopCanvas {
}
/**
- * Sets the desired center position of the viewport (a.k.a. the cursor position) and ensures
- * the viewport is updated to include the cursor within it.
+ * Sets the desired center position of the viewport (a.k.a. the cursor position).
*
* @param newX The new x coordinate value for the desired center position.
* @param newY The new y coordinate value for the desired center position.
*/
public void setCursorPosition(float newX, float newY) {
- // First set the cursor position since its potential values are a superset of the viewport.
- mCursorPosition.set(newX, newY);
- constrainPointToBounds(mCursorPosition, getImageBounds());
-
- // Now set the viewport position based on the cursor.
- mViewportPosition.set(mCursorPosition);
- constrainPointToBounds(mViewportPosition, getViewportBounds());
-
- repositionImage();
+ updateCursorPosition(newX, newY, getImageBounds());
}
/**
- * Shifts the viewport by the passed in values (in image coordinates).
+ * Sets the center of the viewport using an absolute position (in image coordinates).
*
- * @param deltaX The distance (in image coordinates) to move the viewport along the x-axis.
- * @param deltaY The distance (in image coordinates) to move the viewport along the y-axis.
+ * @param newX The new x coordinate value for the center position of the viewport.
+ * @param newY The new y coordinate value for the center position of the viewport.
*/
- public void moveViewportCenter(float deltaX, float deltaY) {
- // Offset and adjust the viewport center position to fit the screen.
- mViewportPosition.offset(deltaX, deltaY);
- constrainPointToBounds(mViewportPosition, getViewportBounds());
-
- // We don't need to constrain the cursor position as the viewport position is always within
- // the bounds of the potential cursor positions.
- mCursorPosition.set(mViewportPosition);
-
- repositionImage();
+ public void setViewportCenter(float newX, float newY) {
+ updateCursorPosition(newX, newY, getViewportBounds());
}
/**
- * Shifts the cursor by the passed in values (in image coordinates) and adjusts the viewport.
+ * Shifts the cursor by the passed in values (in image coordinates).
*
* @param deltaX The distance (in image coordinates) to move the cursor along the x-axis.
* @param deltaY The distance (in image coordinates) to move the cursor along the y-axis.
* @return A point representing the new cursor position.
*/
public PointF moveCursorPosition(float deltaX, float deltaY) {
- setCursorPosition(mCursorPosition.x + deltaX, mCursorPosition.y + deltaY);
+ updateCursorPosition(
+ mCursorPosition.x + deltaX, mCursorPosition.y + deltaY, getImageBounds());
return new PointF(mCursorPosition.x, mCursorPosition.y);
}
/**
+ * Shifts the viewport by the passed in values (in image coordinates).
+ *
+ * @param deltaX The distance (in image coordinates) to move the viewport along the x-axis.
+ * @param deltaY The distance (in image coordinates) to move the viewport along the y-axis.
+ */
+ public void moveViewportCenter(float deltaX, float deltaY) {
+ updateCursorPosition(
+ mCursorPosition.x + deltaX, mCursorPosition.y + deltaY, getViewportBounds());
+ }
+
+ /**
* Handles System UI size and visibility changes.
*
* @param parameter The set of values defining the current System UI state.
*/
public void onSystemUiVisibilityChanged(SystemUiVisibilityChangedEventParameter parameter) {
if (parameter.softInputMethodVisible) {
- mSystemUiScreenSize.set(parameter.left, parameter.top,
- mRenderData.screenWidth - parameter.right,
- mRenderData.screenHeight - parameter.bottom);
-
- if (mAdjustViewportForSystemUi) {
- // Adjust the cursor position to ensure it's visible when large System UI (1/3 or
- // more of the total screen size) is displayed (typically the Soft Keyboard).
- // Without this change, it is difficult for users to enter text into edit controls
- // which are located bottom of the screen and may not see the cursor at all.
- if (mSystemUiScreenSize.bottom > (mRenderData.screenHeight / 3)) {
- // Center the cursor within the viewable area (not obscured by System UI).
- mCursorOffsetScreenY = (float) parameter.bottom / 2.0f;
- } else {
- mCursorOffsetScreenY = 0.0f;
- }
+ mSystemUiScreenSize.set(
+ parameter.left, parameter.top, parameter.right, parameter.bottom);
- // Apply the cursor offset.
- setCursorPosition(mCursorPosition.x, mCursorPosition.y);
+ if (mFrameRenderedCallback != null) {
Lambros 2016/10/24 22:20:33 Please add a comment, or move this to a method cal
joedow 2016/10/25 02:28:19 Done!
+ mRenderStub.onCanvasRendered().remove(mFrameRenderedCallback);
+ mFrameRenderedCallback = null;
}
} else {
- mCursorOffsetScreenY = 0.0f;
mSystemUiScreenSize.setEmpty();
+ startOffsetReductionAnimation();
}
+
+ repositionImage();
}
public void adjustViewportForSystemUi(boolean adjustViewportForSystemUi) {
- mAdjustViewportForSystemUi = adjustViewportForSystemUi;
+ mAdjustViewportSizeForSystemUi = adjustViewportForSystemUi;
+
+ // The viewport center may have changed so reposition the image to reflect the new value.
+ repositionImage();
}
/** Resizes the image by zooming it such that the image is displayed without borders. */
@@ -180,7 +156,7 @@ public class DesktopCanvas {
/**
* Repositions the image by translating and zooming it, to keep the zoom level within sensible
- * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The
+ * limits. The minimum zoom level is chosen to avoid letterboxing on all 4 sides. The
* maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable
* time, and to prevent arithmetic overflow problems from displaying the image.
*
@@ -217,47 +193,74 @@ public class DesktopCanvas {
mRenderData.transform.setScale(scale, scale);
}
- // Trim the image padding if the user is zooming out. This prevents cases where the image
- // pops to the center when it reaches its minimum size. Note that we do not need to do
- // anything when the user is zooming in as the canvas will expand and absorb the padding.
- if (scaleFactor < 1.0f) {
- mVisibleImagePadding.set(mVisibleImagePadding.left * PADDING_REDUCTION_FACTOR,
- mVisibleImagePadding.top * PADDING_REDUCTION_FACTOR,
- mVisibleImagePadding.right * PADDING_REDUCTION_FACTOR,
- mVisibleImagePadding.bottom * PADDING_REDUCTION_FACTOR);
- }
-
if (centerOnCursor) {
setCursorPosition(mCursorPosition.x, mCursorPosition.y);
} else {
- // Find the new screen center (it was probably changed during the zoom operation) and
- // update the viewport and cursor.
- float[] mappedPoints = {
- ((float) mRenderData.screenWidth / 2), ((float) mRenderData.screenHeight / 2)};
+ // Find the new screen center (it probably changed during the zoom operation) and update
+ // the viewport to smoothly track the zoom gesture.
+ float[] mappedPoints = {((float) mRenderData.screenWidth / 2) - mViewportOffset.x,
+ ((float) mRenderData.screenHeight / 2) - mViewportOffset.y};
Matrix screenToImage = new Matrix();
mRenderData.transform.invert(screenToImage);
screenToImage.mapPoints(mappedPoints);
// The cursor is mapped to the center of the viewport in this case.
- setCursorPosition(mappedPoints[0], mappedPoints[1]);
+ setViewportCenter(mappedPoints[0], mappedPoints[1]);
+ }
+ }
+
+ /**
+ * Sets the new cursor position, bounded by the given rect, and updates the image transform to
+ * reflect the new position.
+ */
+ private void updateCursorPosition(float newX, float newY, RectF bounds) {
+ mCursorPosition.set(newX, newY);
+ constrainPointToBounds(mCursorPosition, bounds);
+
+ calculateViewportOffset(newX - mCursorPosition.x, newY - mCursorPosition.y);
+
+ repositionImage();
+ }
+
+ /**
+ * Returns the height of the screen (in screen coordinates) for use in calculations involving
+ * viewport positioning.
+ */
+ private float getAdjustedScreenHeight() {
+ float adjustedScreenHeight;
+ if (mAdjustViewportSizeForSystemUi && !mSystemUiScreenSize.isEmpty()) {
Lambros 2016/10/24 22:37:27 You're calling isEmpty() on something that isn't a
joedow 2016/10/25 02:28:18 It is an actual Rect (updated based on previous CR
+ // Find the center point of the viewport on the screen.
+ adjustedScreenHeight = mSystemUiScreenSize.bottom;
Lambros 2016/10/24 22:20:32 I don't follow this. For example, if the system ke
joedow 2016/10/25 02:28:19 Since this is a rect, given an example screen heig
+ } else {
+ adjustedScreenHeight = ((float) mRenderData.screenHeight);
}
+
+ return adjustedScreenHeight;
+ }
+
+ /**
+ * Returns the center position of the viewport (in screen coordinates) including adjustments.
+ */
+ private PointF getViewportCenter() {
+ return new PointF((float) mRenderData.screenWidth / 2, getAdjustedScreenHeight() / 2);
}
/**
* Repositions the image by translating it (without affecting the zoom level).
*/
private void repositionImage() {
- // Map the current viewport position to screen coordinates and adjust the image position.
- float[] viewportPosition = {mViewportPosition.x, mViewportPosition.y};
- mRenderData.transform.mapPoints(viewportPosition);
+ PointF viewportPosition = new PointF(mCursorPosition.x, mCursorPosition.y);
+ constrainPointToBounds(viewportPosition, getViewportBounds());
+ float[] viewportAdjustment = {viewportPosition.x, viewportPosition.y};
+ mRenderData.transform.mapPoints(viewportAdjustment);
- float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportPosition[0];
- float viewportTransY =
- ((float) mRenderData.screenHeight / 2) - viewportPosition[1] - mCursorOffsetScreenY;
+ // Adjust the viewport to include the overpan amount.
+ viewportAdjustment[0] += mViewportOffset.x;
+ viewportAdjustment[1] += mViewportOffset.y;
// Translate the image to move the viewport to the expected screen location.
- mRenderData.transform.postTranslate(viewportTransX, viewportTransY);
-
- updateVisibleImagePadding();
+ PointF viewportCenter = getViewportCenter();
+ mRenderData.transform.postTranslate(
+ viewportCenter.x - viewportAdjustment[0], viewportCenter.y - viewportAdjustment[1]);
mRenderStub.setTransformation(mRenderData.transform);
}
@@ -284,27 +287,7 @@ public class DesktopCanvas {
/** Returns a region which defines the set of valid cursor positions in image space. */
private RectF getImageBounds() {
- // The set of valid cursor positions includes any point on the image as well as the padding.
- // Padding is additional space added to the image which is the larger value of:
- // - Potential overlap of the System UI and image content
- // - Actual amount of padding already being used
- //
- // By expanding the area, we allow the user to move the cursor 'under' the System UI which
- // pulls the content out from under it and allows it to be visible. Once the System UI has
- // been dismissed or changes size, we use the actual padding value instead which prevents
- // the desktop image from 'snapping' back to pre-System UI state.
- RectF systemUiOverlap = getSystemUiOverlap();
- float[] padding = {Math.max(mVisibleImagePadding.left, systemUiOverlap.left),
- Math.max(mVisibleImagePadding.top + mCursorOffsetScreenY, systemUiOverlap.top),
- Math.max(mVisibleImagePadding.right, systemUiOverlap.right),
- Math.max(mVisibleImagePadding.bottom - mCursorOffsetScreenY,
- systemUiOverlap.bottom)};
- Matrix screenToImage = new Matrix();
- mRenderData.transform.invert(screenToImage);
- screenToImage.mapVectors(padding);
-
- return new RectF(-padding[0], -padding[1], mRenderData.imageWidth + padding[2],
- mRenderData.imageHeight + padding[3]);
+ return new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
}
/** Returns a region which defines the set of valid viewport center values in image space. */
@@ -315,7 +298,8 @@ public class DesktopCanvas {
Matrix screenToImage = new Matrix();
mRenderData.transform.invert(screenToImage);
- float[] screenVectors = {(float) mRenderData.screenWidth, (float) mRenderData.screenHeight};
+ PointF viewportCenter = getViewportCenter();
+ float[] screenVectors = {viewportCenter.x, viewportCenter.y};
screenToImage.mapVectors(screenVectors);
PointF letterboxPadding = getLetterboxPadding();
@@ -323,14 +307,37 @@ public class DesktopCanvas {
screenToImage.mapVectors(letterboxPaddingVectors);
// screenCenter values are 1/2 of a particular screen dimension mapped to image space.
- float screenCenterX = (screenVectors[0] / 2.0f) - letterboxPaddingVectors[0];
- float screenCenterY = (screenVectors[1] / 2.0f) - letterboxPaddingVectors[1];
+ float screenCenterX = screenVectors[0] - letterboxPaddingVectors[0];
+ float screenCenterY = screenVectors[1] - letterboxPaddingVectors[1];
RectF imageBounds = getImageBounds();
imageBounds.inset(screenCenterX, screenCenterY);
return imageBounds;
}
/**
+ * Returns a region defining the maximum overpan distance required to view the entire image
+ * given the current amount of System UI overlapping it.
+ */
+ private RectF getViewportOffsetBounds() {
+ // The allowable region is determined by:
+ // - Overlap of the System UI and image content
+ // - Current viewport offset
+ //
+ // The System UI overlap represents the maximum allowable offset, this is used to bound the
+ // viewport movement in each direction. The current offset is used to prevent 'snapping'
+ // the image when the System UI overlap is reduced.
+ RectF overpanScreenRect =
+ new RectF(Math.min(mViewportOffset.x, 0.0f), Math.min(mViewportOffset.y, 0.0f),
Lambros 2016/10/24 22:20:33 Would new RectF().union(mViewportOffset.x, mViewpo
joedow 2016/10/25 02:28:19 It does, union returns void though so I can't chai
+ Math.max(mViewportOffset.x, 0.0f), Math.max(mViewportOffset.y, 0.0f));
+
+ RectF systemUiOverlap = getSystemUiOverlap();
+ return new RectF(Math.min(overpanScreenRect.left, -systemUiOverlap.left),
+ Math.min(overpanScreenRect.top, -systemUiOverlap.top),
+ Math.max(overpanScreenRect.right, systemUiOverlap.right),
+ Math.max(overpanScreenRect.bottom, systemUiOverlap.bottom));
+ }
+
+ /**
* Provides the amount of padding needed to center the image content on the screen.
*/
private PointF getLetterboxPadding() {
@@ -339,10 +346,8 @@ public class DesktopCanvas {
// We want to letterbox when the image is smaller than the screen in a specific dimension.
// Since we center the image, split the difference so it is equally distributed.
- float widthAdjust =
- Math.max(((float) mRenderData.screenWidth - imageVectors[0]) / 2.0f, 0.0f);
- float heightAdjust =
- Math.max(((float) mRenderData.screenHeight - imageVectors[1]) / 2.0f, 0.0f);
+ float widthAdjust = Math.max(((float) mRenderData.screenWidth - imageVectors[0]) / 2, 0);
+ float heightAdjust = Math.max((getAdjustedScreenHeight() - imageVectors[1]) / 2, 0);
return new PointF(widthAdjust, heightAdjust);
}
@@ -352,29 +357,71 @@ public class DesktopCanvas {
* desktop image below it. This is the maximum amount that could overlap, not the actual value.
*/
private RectF getSystemUiOverlap() {
+ if (mSystemUiScreenSize.isEmpty()) {
+ return new RectF(mSystemUiScreenSize);
Lambros 2016/10/24 22:20:33 Just 'new RectF()', no need to pass in an empty Re
joedow 2016/10/25 02:28:18 Good point, I think this is left over from a previ
+ }
+
// letterBox padding represents the space added to the image to center it on the screen.
Lambros 2016/10/24 22:20:32 nit: Begin with capital letter, or enclose with ''
joedow 2016/10/25 02:28:18 Done.
// Since it does not contain any interactable UI, we ignore it when calculating the overlap
// between the System UI and the remote desktop image.
// Note: Ignore negative padding (clamp to 0) since that means no overlap exists.
+ float adjustedScreenHeight = getAdjustedScreenHeight();
PointF letterboxPadding = getLetterboxPadding();
return new RectF(Math.max(mSystemUiScreenSize.left - letterboxPadding.x, 0.0f),
- Math.max(mSystemUiScreenSize.top - letterboxPadding.y + mCursorOffsetScreenY, 0.0f),
- Math.max(mSystemUiScreenSize.right - letterboxPadding.x, 0.0f),
- Math.max(mSystemUiScreenSize.bottom - letterboxPadding.y - mCursorOffsetScreenY,
+ Math.max(mSystemUiScreenSize.top - letterboxPadding.y, 0.0f),
+ Math.max(mRenderData.screenWidth - mSystemUiScreenSize.right - letterboxPadding.x,
+ 0.0f),
+ Math.max(adjustedScreenHeight - mSystemUiScreenSize.bottom - letterboxPadding.y,
0.0f));
}
/**
- * Calculates the amount of padding visible on each edge of the desktop image.
+ * Applies the given offset, as needed, to allow moving the image outside its normal bounds.
*/
- private void updateVisibleImagePadding() {
- PointF letterboxPadding = getLetterboxPadding();
- float[] imagePoints = {0.0f, 0.0f, mRenderData.imageWidth, mRenderData.imageHeight};
- mRenderData.transform.mapPoints(imagePoints);
+ private void calculateViewportOffset(float offsetX, float offsetY) {
+ if (mSystemUiScreenSize.isEmpty()) {
+ // We only want to change adjust the viewport offset when System UI is present.
Lambros 2016/10/24 22:20:33 Remove 'change' or 'adjust'.
joedow 2016/10/25 02:28:19 Done.
+ return;
+ }
+
+ float[] offsets = {offsetX, offsetY};
+ mRenderData.transform.mapVectors(offsets);
+
+ // Use a temporary variable here as {@link #getViewportOffsetBounds()} uses the current
+ // viewport offset as a maximum boundary. If we add the offset first, the result ends up
+ // being unbounded. Thus we use a temporary object for the boundary calculation.
+ PointF requestedOffset =
+ new PointF(mViewportOffset.x + offsets[0], mViewportOffset.y + offsets[1]);
+ constrainPointToBounds(requestedOffset, getViewportOffsetBounds());
+ mViewportOffset.set(requestedOffset);
+ }
+
+ /**
+ * Starts an animation to smoothly reduce the viewport offset. Does nothing if an animation is
+ * already running or the offset is already 0.
+ */
+ private void startOffsetReductionAnimation() {
+ if (mFrameRenderedCallback != null || Math.abs(mViewportOffset.length()) < EPSILON) {
+ return;
+ }
+
+ mFrameRenderedCallback = new Event.ParameterCallback<Boolean, Void>() {
+ @Override
+ public Boolean run(Void p) {
+ mViewportOffset.set(mViewportOffset.x * OFFSET_REDUCTION_FACTOR,
+ mViewportOffset.y * OFFSET_REDUCTION_FACTOR);
+
+ if (Math.abs(mViewportOffset.length()) < MINIMUM_OFFSET_DISTANCE) {
+ mViewportOffset.set(0.0f, 0.0f);
+ mFrameRenderedCallback = null;
+ }
+
+ repositionImage();
+
+ return mFrameRenderedCallback != null;
+ }
+ };
- mVisibleImagePadding.set(Math.max(imagePoints[0] - letterboxPadding.x, 0.0f),
- Math.max(imagePoints[1] - letterboxPadding.y, 0.0f),
- Math.max(mRenderData.screenWidth - imagePoints[2] - letterboxPadding.x, 0.0f),
- Math.max(mRenderData.screenHeight - imagePoints[3] - letterboxPadding.y, 0.0f));
+ mRenderStub.onCanvasRendered().addSelfRemovable(mFrameRenderedCallback);
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698