Merge "Fix missing frame or wrong frame position when resize starts"
This commit is contained in:
@@ -88,6 +88,7 @@ import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
@@ -238,6 +239,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
boolean mNewSurfaceNeeded;
|
||||
boolean mHasHadWindowFocus;
|
||||
boolean mLastWasImTarget;
|
||||
CountDownLatch mWindowDrawCountDown;
|
||||
|
||||
boolean mIsDrawing;
|
||||
int mLastSystemUiVisibility;
|
||||
@@ -436,6 +438,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
public void reportDrawFinish() {
|
||||
if (mWindowDrawCountDown != null) {
|
||||
mWindowDrawCountDown.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME for perf testing only
|
||||
private boolean mProfile = false;
|
||||
|
||||
@@ -2419,6 +2427,17 @@ public final class ViewRootImpl implements ViewParent,
|
||||
|
||||
if (mReportNextDraw) {
|
||||
mReportNextDraw = false;
|
||||
|
||||
// if we're using multi-thread renderer, wait for the window frame draws
|
||||
if (mWindowDrawCountDown != null) {
|
||||
try {
|
||||
mWindowDrawCountDown.await();
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Window redraw count down interruped!");
|
||||
}
|
||||
mWindowDrawCountDown = null;
|
||||
}
|
||||
|
||||
if (mAttachInfo.mHardwareRenderer != null) {
|
||||
mAttachInfo.mHardwareRenderer.fence();
|
||||
}
|
||||
@@ -2568,13 +2587,13 @@ public final class ViewRootImpl implements ViewParent,
|
||||
|
||||
// Stage the content drawn size now. It will be transferred to the renderer
|
||||
// shortly before the draw commands get send to the renderer.
|
||||
synchronized (mWindowCallbacks) {
|
||||
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
|
||||
mWindowCallbacks.get(i).onContentDraw(mWindowAttributes.surfaceInsets.left,
|
||||
mWindowAttributes.surfaceInsets.top, mWidth, mHeight);
|
||||
}
|
||||
}
|
||||
final boolean updated = updateContentDrawBounds();
|
||||
|
||||
mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
|
||||
|
||||
if (updated) {
|
||||
requestDrawWindow();
|
||||
}
|
||||
} else {
|
||||
// If we get here with a disabled & requested hardware renderer, something went
|
||||
// wrong (an invalidate posted right before we destroyed the hardware surface
|
||||
@@ -6796,6 +6815,30 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateContentDrawBounds() {
|
||||
boolean updated = false;
|
||||
synchronized (mWindowCallbacks) {
|
||||
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
|
||||
updated |= mWindowCallbacks.get(i).onContentDrawn(
|
||||
mWindowAttributes.surfaceInsets.left,
|
||||
mWindowAttributes.surfaceInsets.top,
|
||||
mWidth, mHeight);
|
||||
}
|
||||
}
|
||||
return updated | (mDragResizing && mReportNextDraw);
|
||||
}
|
||||
|
||||
private void requestDrawWindow() {
|
||||
if (mReportNextDraw) {
|
||||
mWindowDrawCountDown = new CountDownLatch(mWindowCallbacks.size());
|
||||
}
|
||||
synchronized (mWindowCallbacks) {
|
||||
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
|
||||
mWindowCallbacks.get(i).onRequestDraw(mReportNextDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for managing the accessibility interaction connection
|
||||
* based on the global accessibility state.
|
||||
|
||||
@@ -49,7 +49,14 @@ public interface WindowCallbacks {
|
||||
void onWindowDragResizeEnd();
|
||||
|
||||
/**
|
||||
* The content will now be drawn to these bounds.
|
||||
* The content will now be drawn to these bounds. Returns true if
|
||||
* a draw should be requested after the next content draw.
|
||||
*/
|
||||
void onContentDraw(int offsetX, int offsetY, int sizeX, int sizeY);
|
||||
boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY);
|
||||
|
||||
/**
|
||||
* Called to request the window to draw one frame.
|
||||
* @param reportNextDraw Whether it should report when the requested draw finishes.
|
||||
*/
|
||||
void onRequestDraw(boolean reportNextDraw);
|
||||
}
|
||||
|
||||
@@ -355,9 +355,22 @@ public class NonClientDecorView extends LinearLayout
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentDraw(int xOffset, int yOffset, int xSize, int ySize) {
|
||||
public boolean onContentDrawn(int xOffset, int yOffset, int xSize, int ySize) {
|
||||
if (mFrameRendererThread == null) {
|
||||
return false;
|
||||
}
|
||||
return mFrameRendererThread.onContentDrawn(xOffset, yOffset, xSize, ySize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestDraw(boolean reportNextDraw) {
|
||||
if (mFrameRendererThread != null) {
|
||||
mFrameRendererThread.onContentDraw(xOffset, yOffset, xSize, ySize);
|
||||
mFrameRendererThread.onRequsetDraw(reportNextDraw);
|
||||
} else if (reportNextDraw) {
|
||||
// If render thread is gone, just report immediately.
|
||||
if (isAttachedToWindow()) {
|
||||
getViewRootImpl().reportDrawFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,6 +436,9 @@ public class NonClientDecorView extends LinearLayout
|
||||
private int mLastXOffset;
|
||||
private int mLastYOffset;
|
||||
|
||||
// Whether to report when next frame is drawn or not.
|
||||
private boolean mReportNextDraw;
|
||||
|
||||
ResizeFrameThread(ThreadedRenderer renderer, Rect initialBounds) {
|
||||
setName("ResizeFrame");
|
||||
mRenderer = renderer;
|
||||
@@ -518,12 +534,13 @@ public class NonClientDecorView extends LinearLayout
|
||||
public void doFrame(long frameTimeNanos) {
|
||||
synchronized (this) {
|
||||
if (mRenderer == null) {
|
||||
reportDrawIfNeeded();
|
||||
// Tell the looper to stop. We are done.
|
||||
Looper.myLooper().quit();
|
||||
return;
|
||||
}
|
||||
mNewTargetRect.set(mTargetRect);
|
||||
if (!mNewTargetRect.equals(mOldTargetRect)) {
|
||||
if (!mNewTargetRect.equals(mOldTargetRect) || mReportNextDraw) {
|
||||
mOldTargetRect.set(mNewTargetRect);
|
||||
changeWindowSizeLocked(mNewTargetRect);
|
||||
}
|
||||
@@ -538,8 +555,9 @@ public class NonClientDecorView extends LinearLayout
|
||||
* @param yOffset The y offset where the content is drawn to.
|
||||
* @param xSize The width size of the content. This should not be 0.
|
||||
* @param ySize The height of the content.
|
||||
* @return true if a frame should be requested after the content is drawn; false otherwise.
|
||||
*/
|
||||
public void onContentDraw(int xOffset, int yOffset, int xSize, int ySize) {
|
||||
public boolean onContentDrawn(int xOffset, int yOffset, int xSize, int ySize) {
|
||||
synchronized (this) {
|
||||
final boolean firstCall = mLastContentWidth == 0;
|
||||
// The current content buffer is drawn here.
|
||||
@@ -555,10 +573,15 @@ public class NonClientDecorView extends LinearLayout
|
||||
mLastYOffset + mLastCaptionHeight + mLastContentHeight);
|
||||
// If this was the first call and changeWindowSizeLocked got already called prior
|
||||
// to us, we should re-issue a changeWindowSizeLocked now.
|
||||
if (firstCall && (mLastCaptionHeight != 0 || !mShowDecor)) {
|
||||
mOldTargetRect.set(0, 0, 0, 0);
|
||||
pingRenderLocked();
|
||||
}
|
||||
return firstCall && (mLastCaptionHeight != 0 || !mShowDecor);
|
||||
}
|
||||
}
|
||||
|
||||
public void onRequsetDraw(boolean reportNextDraw) {
|
||||
synchronized (this) {
|
||||
mReportNextDraw = reportNextDraw;
|
||||
mOldTargetRect.set(0, 0, 0, 0);
|
||||
pingRenderLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,6 +640,20 @@ public class NonClientDecorView extends LinearLayout
|
||||
// We need to render both rendered nodes explicitly.
|
||||
mRenderer.drawRenderNode(mFrameNode);
|
||||
mRenderer.drawRenderNode(mBackdropNode);
|
||||
|
||||
reportDrawIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify view root that a frame has been drawn by us, if it has requested so.
|
||||
*/
|
||||
private void reportDrawIfNeeded() {
|
||||
if (mReportNextDraw) {
|
||||
if (isAttachedToWindow()) {
|
||||
getViewRootImpl().reportDrawFinish();
|
||||
}
|
||||
mReportNextDraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user