@@ -935,6 +935,59 @@ void computeShownFrameLocked() {
935935 mDtDy = mWin .mGlobalScale ;
936936 }
937937
938+ void updateSurfaceWindowCrop (final boolean recoveringMemory ) {
939+ final WindowState w = mWin ;
940+
941+ // Need to recompute a new system decor rect each time.
942+ if ((w .mAttrs .flags & LayoutParams .FLAG_SCALED ) != 0 ) {
943+ // Currently can't do this cropping for scaled windows. We'll
944+ // just keep the crop rect the same as the source surface.
945+ w .mSystemDecorRect .set (0 , 0 , w .mRequestedWidth , w .mRequestedHeight );
946+ } else if (w .mLayer >= mService .mSystemDecorLayer ) {
947+ // Above the decor layer is easy, just use the entire window.
948+ w .mSystemDecorRect .set (0 , 0 , w .mCompatFrame .width (),
949+ w .mCompatFrame .height ());
950+ } else {
951+ final Rect decorRect = mService .mSystemDecorRect ;
952+ // Compute the offset of the window in relation to the decor rect.
953+ final int offX = w .mXOffset + w .mFrame .left ;
954+ final int offY = w .mYOffset + w .mFrame .top ;
955+ // Initialize the decor rect to the entire frame.
956+ w .mSystemDecorRect .set (0 , 0 , w .mFrame .width (), w .mFrame .height ());
957+ // Intersect with the decor rect, offsetted by window position.
958+ w .mSystemDecorRect .intersect (decorRect .left -offX , decorRect .top -offY ,
959+ decorRect .right -offX , decorRect .bottom -offY );
960+ // If size compatibility is being applied to the window, the
961+ // surface is scaled relative to the screen. Also apply this
962+ // scaling to the crop rect. We aren't using the standard rect
963+ // scale function because we want to round things to make the crop
964+ // always round to a larger rect to ensure we don't crop too
965+ // much and hide part of the window that should be seen.
966+ if (w .mEnforceSizeCompat && w .mInvGlobalScale != 1.0f ) {
967+ final float scale = w .mInvGlobalScale ;
968+ w .mSystemDecorRect .left = (int ) (w .mSystemDecorRect .left * scale - 0.5f );
969+ w .mSystemDecorRect .top = (int ) (w .mSystemDecorRect .top * scale - 0.5f );
970+ w .mSystemDecorRect .right = (int ) ((w .mSystemDecorRect .right +1 ) * scale - 0.5f );
971+ w .mSystemDecorRect .bottom = (int ) ((w .mSystemDecorRect .bottom +1 ) * scale - 0.5f );
972+ }
973+ }
974+
975+ if (!w .mSystemDecorRect .equals (w .mLastSystemDecorRect )) {
976+ w .mLastSystemDecorRect .set (w .mSystemDecorRect );
977+ try {
978+ if (WindowManagerService .SHOW_TRANSACTIONS ) WindowManagerService .logSurface (w ,
979+ "CROP " + w .mSystemDecorRect .toShortString (), null );
980+ mSurface .setWindowCrop (w .mSystemDecorRect );
981+ } catch (RuntimeException e ) {
982+ Slog .w (TAG , "Error setting crop surface of " + w
983+ + " crop=" + w .mSystemDecorRect .toShortString (), e );
984+ if (!recoveringMemory ) {
985+ mService .reclaimSomeSurfaceMemoryLocked (this , "crop" , true );
986+ }
987+ }
988+ }
989+ }
990+
938991 void setSurfaceBoundaries (final boolean recoveringMemory ) {
939992 final WindowState w = mWin ;
940993 int width , height ;
@@ -1003,54 +1056,7 @@ void setSurfaceBoundaries(final boolean recoveringMemory) {
10031056 }
10041057 }
10051058
1006- // Need to recompute a new system decor rect each time.
1007- if ((w .mAttrs .flags & LayoutParams .FLAG_SCALED ) != 0 ) {
1008- // Currently can't do this cropping for scaled windows. We'll
1009- // just keep the crop rect the same as the source surface.
1010- w .mSystemDecorRect .set (0 , 0 , w .mRequestedWidth , w .mRequestedHeight );
1011- } else if (w .mLayer >= mService .mSystemDecorLayer ) {
1012- // Above the decor layer is easy, just use the entire window.
1013- w .mSystemDecorRect .set (0 , 0 , w .mCompatFrame .width (),
1014- w .mCompatFrame .height ());
1015- } else {
1016- final Rect decorRect = mService .mSystemDecorRect ;
1017- // Compute the offset of the window in relation to the decor rect.
1018- final int offX = w .mXOffset + w .mFrame .left ;
1019- final int offY = w .mYOffset + w .mFrame .top ;
1020- // Initialize the decor rect to the entire frame.
1021- w .mSystemDecorRect .set (0 , 0 , w .mFrame .width (), w .mFrame .height ());
1022- // Intersect with the decor rect, offsetted by window position.
1023- w .mSystemDecorRect .intersect (decorRect .left -offX , decorRect .top -offY ,
1024- decorRect .right -offX , decorRect .bottom -offY );
1025- // If size compatibility is being applied to the window, the
1026- // surface is scaled relative to the screen. Also apply this
1027- // scaling to the crop rect. We aren't using the standard rect
1028- // scale function because we want to round things to make the crop
1029- // always round to a larger rect to ensure we don't crop too
1030- // much and hide part of the window that should be seen.
1031- if (w .mEnforceSizeCompat && w .mInvGlobalScale != 1.0f ) {
1032- final float scale = w .mInvGlobalScale ;
1033- w .mSystemDecorRect .left = (int ) (w .mSystemDecorRect .left * scale - 0.5f );
1034- w .mSystemDecorRect .top = (int ) (w .mSystemDecorRect .top * scale - 0.5f );
1035- w .mSystemDecorRect .right = (int ) ((w .mSystemDecorRect .right +1 ) * scale - 0.5f );
1036- w .mSystemDecorRect .bottom = (int ) ((w .mSystemDecorRect .bottom +1 ) * scale - 0.5f );
1037- }
1038- }
1039-
1040- if (!w .mSystemDecorRect .equals (w .mLastSystemDecorRect )) {
1041- w .mLastSystemDecorRect .set (w .mSystemDecorRect );
1042- try {
1043- if (WindowManagerService .SHOW_TRANSACTIONS ) WindowManagerService .logSurface (w ,
1044- "CROP " + w .mSystemDecorRect .toShortString (), null );
1045- mSurface .setWindowCrop (w .mSystemDecorRect );
1046- } catch (RuntimeException e ) {
1047- Slog .w (TAG , "Error setting crop surface of " + w
1048- + " crop=" + w .mSystemDecorRect .toShortString (), e );
1049- if (!recoveringMemory ) {
1050- mService .reclaimSomeSurfaceMemoryLocked (this , "crop" , true );
1051- }
1052- }
1053- }
1059+ updateSurfaceWindowCrop (recoveringMemory );
10541060 }
10551061
10561062 public void prepareSurfaceLocked (final boolean recoveringMemory ) {
@@ -1181,17 +1187,31 @@ void setTransparentRegionHint(final Region region) {
11811187 }
11821188
11831189 void setWallpaperOffset (int left , int top ) {
1190+ mSurfaceX = left ;
1191+ mSurfaceY = top ;
1192+ if (mAnimating ) {
1193+ // If this window (or its app token) is animating, then the position
1194+ // of the surface will be re-computed on the next animation frame.
1195+ // We can't poke it directly here because it depends on whatever
1196+ // transformation is being applied by the animation.
1197+ return ;
1198+ }
1199+ if (SHOW_LIGHT_TRANSACTIONS ) Slog .i (TAG ,
1200+ ">>> OPEN TRANSACTION setWallpaperOffset" );
11841201 Surface .openTransaction ();
11851202 try {
1186- mSurfaceX = left ;
1187- mSurfaceY = top ;
1188- mSurface .setPosition (left , top );
1189- mSurface . setWindowCrop ( null );
1203+ if ( WindowManagerService . SHOW_TRANSACTIONS ) WindowManagerService . logSurface ( mWin ,
1204+ "POS " + left + ", " + top , null ) ;
1205+ mSurface .setPosition (mWin . mFrame . left + left , mWin . mFrame . top + top );
1206+ updateSurfaceWindowCrop ( false );
11901207 } catch (RuntimeException e ) {
11911208 Slog .w (TAG , "Error positioning surface of " + mWin
11921209 + " pos=(" + left + "," + top + ")" , e );
1210+ } finally {
1211+ Surface .closeTransaction ();
1212+ if (SHOW_LIGHT_TRANSACTIONS ) Slog .i (TAG ,
1213+ "<<< CLOSE TRANSACTION setWallpaperOffset" );
11931214 }
1194- Surface .closeTransaction ();
11951215 }
11961216
11971217 // This must be called while inside a transaction.
0 commit comments