Merge "Sync SurfaceView position changes to parent render."
This commit is contained in:
@@ -95,6 +95,23 @@ interface IWindowSession {
|
||||
out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
|
||||
out Rect outOutsets, out Configuration outConfig, out Surface outSurface);
|
||||
|
||||
/**
|
||||
* Position a window relative to it's parent (attached) window without triggering
|
||||
* a full relayout. This action may be deferred until a given frame number
|
||||
* for the parent window appears. This allows for synchronizing movement of a child
|
||||
* to repainting the contents of the parent.
|
||||
*
|
||||
* @param window The window being modified. Must be attached to a parent window
|
||||
* or this call will fail.
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
* @param deferTransactionUntilFrame Frame number from our parent (attached) to
|
||||
* defer this action until.
|
||||
* @param outFrame Rect in which is placed the new position/size on screen.
|
||||
*/
|
||||
void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame,
|
||||
out Rect outFrame);
|
||||
|
||||
/**
|
||||
* If a call to relayout() asked to have the surface destroy deferred,
|
||||
* it must call this once it is okay to destroy that surface.
|
||||
|
||||
@@ -56,6 +56,8 @@ public class Surface implements Parcelable {
|
||||
private static native int nativeGetWidth(long nativeObject);
|
||||
private static native int nativeGetHeight(long nativeObject);
|
||||
|
||||
private static native long nativeGetNextFrameNumber(long nativeObject);
|
||||
|
||||
public static final Parcelable.Creator<Surface> CREATOR =
|
||||
new Parcelable.Creator<Surface>() {
|
||||
@Override
|
||||
@@ -219,6 +221,18 @@ public class Surface implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next frame number which will be dequeued for rendering.
|
||||
* Intended for use with SurfaceFlinger's deferred transactions API.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public long getNextFrameNumber() {
|
||||
synchronized (mLock) {
|
||||
return nativeGetNextFrameNumber(mNativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the consumer of this Surface is running behind the producer.
|
||||
*
|
||||
|
||||
@@ -81,6 +81,9 @@ public class SurfaceControl {
|
||||
private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
|
||||
private static native void nativeSetDisplayPowerMode(
|
||||
IBinder displayToken, int mode);
|
||||
private static native void nativeDeferTransactionUntil(long nativeObject,
|
||||
IBinder handle, long frame);
|
||||
private static native IBinder nativeGetHandle(long nativeObject);
|
||||
|
||||
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
@@ -358,6 +361,14 @@ public class SurfaceControl {
|
||||
nativeCloseTransaction();
|
||||
}
|
||||
|
||||
public void deferTransactionUntil(IBinder handle, long frame) {
|
||||
nativeDeferTransactionUntil(mNativeObject, handle, frame);
|
||||
}
|
||||
|
||||
public IBinder getHandle() {
|
||||
return nativeGetHandle(mNativeObject);
|
||||
}
|
||||
|
||||
/** flag the transaction as an animation */
|
||||
public static void setAnimationTransaction() {
|
||||
nativeSetAnimationTransaction();
|
||||
|
||||
@@ -448,11 +448,10 @@ public class SurfaceView extends View {
|
||||
final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
|
||||
final boolean visibleChanged = mVisible != mRequestedVisible;
|
||||
final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height;
|
||||
final boolean positionChanged = mLeft != mLocation[0] || mTop != mLocation[1];
|
||||
|
||||
if (force || creating || formatChanged || sizeChanged || visibleChanged
|
||||
|| mLeft != mLocation[0] || mTop != mLocation[1]
|
||||
|| mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded || layoutSizeChanged) {
|
||||
|
||||
if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
|
||||
+ " format=" + formatChanged + " size=" + sizeChanged
|
||||
+ " visible=" + visibleChanged
|
||||
@@ -616,11 +615,22 @@ public class SurfaceView extends View {
|
||||
mSession.performDeferredDestroy(mWindow);
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Exception from relayout", ex);
|
||||
}
|
||||
if (DEBUG) Log.v(
|
||||
TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
|
||||
" w=" + mLayout.width + " h=" + mLayout.height +
|
||||
", frame=" + mSurfaceFrame);
|
||||
} else if (positionChanged) { // Only the position has changed
|
||||
mLeft = mLocation[0];
|
||||
mTop = mLocation[1];
|
||||
try {
|
||||
mSession.repositionChild(mWindow, mLeft, mTop,
|
||||
viewRoot != null ? viewRoot.getNextFrameNumber() : -1,
|
||||
mWinFrame);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Exception from relayout", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6607,6 +6607,20 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
long getNextFrameNumber() {
|
||||
long frameNumber = -1;
|
||||
if (mSurfaceHolder != null) {
|
||||
mSurfaceHolder.mSurfaceLock.lock();
|
||||
}
|
||||
if (mSurface.isValid()) {
|
||||
frameNumber = mSurface.getNextFrameNumber();
|
||||
}
|
||||
if (mSurfaceHolder != null) {
|
||||
mSurfaceHolder.mSurfaceLock.unlock();
|
||||
}
|
||||
return frameNumber;
|
||||
}
|
||||
|
||||
class TakenSurfaceHolder extends BaseSurfaceHolder {
|
||||
@Override
|
||||
public boolean onAllowLockCanvas() {
|
||||
|
||||
@@ -460,6 +460,10 @@ static jint nativeGetHeight(JNIEnv* env, jclass clazz, jlong nativeObject) {
|
||||
anw->query(anw, NATIVE_WINDOW_HEIGHT, &value);
|
||||
return value;
|
||||
}
|
||||
static jlong nativeGetNextFrameNumber(JNIEnv *env, jclass clazz, jlong nativeObject) {
|
||||
Surface* surface = reinterpret_cast<Surface*>(nativeObject);
|
||||
return surface->getNextFrameNumber();
|
||||
}
|
||||
|
||||
namespace uirenderer {
|
||||
|
||||
@@ -536,6 +540,7 @@ static const JNINativeMethod gSurfaceMethods[] = {
|
||||
(void*)nativeWriteToParcel },
|
||||
{"nativeGetWidth", "(J)I", (void*)nativeGetWidth },
|
||||
{"nativeGetHeight", "(J)I", (void*)nativeGetHeight },
|
||||
{"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber },
|
||||
|
||||
// HWUI context
|
||||
{"nHwuiCreate", "(JJ)J", (void*) hwui::create },
|
||||
|
||||
@@ -571,6 +571,21 @@ static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
|
||||
jobject handleObject, jlong frameNumber) {
|
||||
auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
|
||||
sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
|
||||
|
||||
ctrl->deferTransactionUntil(handle, frameNumber);
|
||||
}
|
||||
|
||||
static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
|
||||
auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
|
||||
|
||||
return javaObjectForIBinder(env, ctrl->getHandle());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
@@ -638,6 +653,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
(void*)nativeGetAnimationFrameStats },
|
||||
{"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
|
||||
(void*)nativeSetDisplayPowerMode },
|
||||
{"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
|
||||
(void*)nativeDeferTransactionUntil },
|
||||
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
|
||||
(void*)nativeGetHandle }
|
||||
};
|
||||
|
||||
int register_android_view_SurfaceControl(JNIEnv* env)
|
||||
|
||||
@@ -187,6 +187,12 @@ final class Session extends IWindowSession.Stub
|
||||
mService.removeWindow(this, window);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repositionChild(IWindow window, int x, int y, long deferTransactionUntilFrame,
|
||||
Rect outFrame) {
|
||||
mService.repositionChild(this, window, x, y, deferTransactionUntilFrame, outFrame);
|
||||
}
|
||||
|
||||
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
|
||||
int requestedWidth, int requestedHeight, int viewFlags,
|
||||
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
|
||||
|
||||
@@ -2468,6 +2468,54 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
void repositionChild(Session session, IWindow client,
|
||||
int x, int y, long deferTransactionUntilFrame, Rect outFrame) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild");
|
||||
long origId = Binder.clearCallingIdentity();
|
||||
|
||||
try {
|
||||
synchronized(mWindowMap) {
|
||||
WindowState win = windowForClientLocked(session, client, false);
|
||||
if (win == null) {
|
||||
return;
|
||||
}
|
||||
if (win.mAttachedWindow == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"repositionChild called but window is not"
|
||||
+ "attached to a parent win=" + win);
|
||||
}
|
||||
|
||||
win.mFrame.left = x;
|
||||
win.mFrame.top = y;
|
||||
|
||||
win.mWinAnimator.computeShownFrameLocked();
|
||||
|
||||
if (SHOW_TRANSACTIONS) {
|
||||
Slog.i(TAG, ">>> OPEN TRANSACTION repositionChild");
|
||||
}
|
||||
|
||||
SurfaceControl.openTransaction();
|
||||
|
||||
if (deferTransactionUntilFrame > 0) {
|
||||
win.mWinAnimator.mSurfaceControl.deferTransactionUntil(
|
||||
win.mAttachedWindow.mWinAnimator.mSurfaceControl.getHandle(),
|
||||
deferTransactionUntilFrame);
|
||||
}
|
||||
win.mWinAnimator.setSurfaceBoundariesLocked(false);
|
||||
|
||||
SurfaceControl.closeTransaction();
|
||||
if (SHOW_TRANSACTIONS) {
|
||||
Slog.i(TAG, "<<< CLOSE TRANSACTION repositionChild");
|
||||
}
|
||||
|
||||
outFrame = win.mCompatFrame;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
|
||||
}
|
||||
}
|
||||
|
||||
public int relayoutWindow(Session session, IWindow client, int seq,
|
||||
WindowManager.LayoutParams attrs, int requestedWidth,
|
||||
int requestedHeight, int viewVisibility, int flags,
|
||||
|
||||
Reference in New Issue
Block a user