Bug 1491442 - Disable window overlay drawing in the CoreAnimation path. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Fri, 16 Aug 2019 01:15:10 +0000
changeset 488414 e6e88a4fc6b95571d04db7841603bea7148df02f
parent 488413 a5ba7777641703116a83c6b4bbea66308fb6e816
child 488415 706ff8a1badcd0c796e151b9e015bbfed0b20ddf
push id36443
push userccoroiu@mozilla.com
push dateFri, 16 Aug 2019 09:48:15 +0000
treeherdermozilla-central@5d4cbfe103bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1491442
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1491442 - Disable window overlay drawing in the CoreAnimation path. r=mattwoodrow Window overlay drawing was added as a workaround for the following: When our NSOpenGLContext covered the entire window, it would cover the titlebar contents and hide the window buttons and the title string. It would also not get anti-aliased rounded corner clipping. In windows that use CoreAnimation layers for the window frame, this is no longer a problem, because the CoreAnimation layer tree takes care of these effects: It applies rounded corner clipping to the window content layers, it puts the window buttons on top, and it also puts the title string on top if it is shown. So when we're using CoreAnimation, the existing code needs to be deactivated, otherwise we'd draw those things twice. Differential Revision: https://phabricator.services.mozilla.com/D38760
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -1845,16 +1845,18 @@ void nsChildView::CreateCompositor() {
   }
 }
 
 void nsChildView::ConfigureAPZCTreeManager() { nsBaseWidget::ConfigureAPZCTreeManager(); }
 
 void nsChildView::ConfigureAPZControllerThread() { nsBaseWidget::ConfigureAPZControllerThread(); }
 
 LayoutDeviceIntRect nsChildView::RectContainingTitlebarControls() {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   NSRect rect = NSZeroRect;
 
   // If we draw the titlebar title string, set the rect to the full window
   // width times the default titlebar height. This height does not necessarily
   // include all the titlebar controls because we may have moved them further
   // down, but at least it will include the whole title text.
   BaseWindow* window = (BaseWindow*)[mView window];
   if ([window wantsTitleDrawn] && [window isKindOfClass:[ToolbarWindow class]]) {
@@ -1884,17 +1886,17 @@ void nsChildView::PrepareWindowEffects()
     nsCocoaWindow* windowWidget = GetXULWindowWidget();
     mIsFullscreen =
         (styleMask & NSFullScreenWindowMask) || (windowWidget && windowWidget->InFullScreenMode());
 
     canBeOpaque = mIsFullscreen && wasFullscreen;
     if (canBeOpaque && VibrancyManager::SystemSupportsVibrancy()) {
       canBeOpaque = !EnsureVibrancyManager().HasVibrantRegions();
     }
-    if (mIsCoveringTitlebar) {
+    if (mIsCoveringTitlebar && !StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
       mTitlebarRect = RectContainingTitlebarControls();
       UpdateTitlebarCGContext();
     }
   }
 
   // If we've just transitioned into or out of full screen then update the opacity on our GLContext.
   if (canBeOpaque != mIsOpaque) {
     mIsOpaque = canBeOpaque;
@@ -1907,16 +1909,20 @@ void nsChildView::PrepareWindowEffects()
 void nsChildView::CleanupWindowEffects() {
   mCornerMaskImage = nullptr;
   mTitlebarImage = nullptr;
 }
 
 void nsChildView::AddWindowOverlayWebRenderCommands(layers::WebRenderBridgeChild* aWrBridge,
                                                     wr::DisplayListBuilder& aBuilder,
                                                     wr::IpcResourceUpdateQueue& aResources) {
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    return;
+  }
+
   PrepareWindowEffects();
 
   if (!mIsCoveringTitlebar || mIsFullscreen || mTitlebarRect.IsEmpty()) {
     return;
   }
 
   bool needUpdate = mUpdatedTitlebarRegion.Intersects(mTitlebarRect);
   mUpdatedTitlebarRegion.SetEmpty();
@@ -2065,16 +2071,20 @@ void nsChildView::DoCompositorCleanup() 
 void nsChildView::DrawWindowOverlay(WidgetRenderingContext* aContext, LayoutDeviceIntRect aRect) {
   mozilla::UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
   if (manager) {
     DrawWindowOverlay(manager.get(), aRect);
   }
 }
 
 void nsChildView::DrawWindowOverlay(GLManager* aManager, LayoutDeviceIntRect aRect) {
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
+    return;
+  }
+
   GLContext* gl = aManager->gl();
   ScopedGLState scopedScissorTestState(gl, LOCAL_GL_SCISSOR_TEST, false);
 
   MaybeDrawTitlebar(aManager);
   MaybeDrawRoundedCorners(aManager, aRect);
 }
 
 static void ClearRegion(gfx::DrawTarget* aDT, LayoutDeviceIntRegion aRegion) {
@@ -2098,16 +2108,18 @@ static CGContextRef CreateCGContext(cons
 }
 
 static LayoutDeviceIntSize TextureSizeForSize(const LayoutDeviceIntSize& aSize) {
   return LayoutDeviceIntSize(RoundUpPow2(aSize.width), RoundUpPow2(aSize.height));
 }
 
 // When this method is entered, mEffectsLock is already being held.
 void nsChildView::UpdateTitlebarCGContext() {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   if (mTitlebarRect.IsEmpty()) {
     ReleaseTitlebarCGContext();
     return;
   }
 
   NSRect titlebarRect = DevPixelsToCocoaPoints(mTitlebarRect);
   NSRect dirtyRect = [mView convertRect:[(BaseWindow*)[mView window] getAndResetNativeDirtyRect]
                                fromView:nil];
@@ -2230,16 +2242,18 @@ void nsChildView::UpdateTitlebarCGContex
 // This is necessary because the real titlebar controls are covered by our
 // OpenGL context. Note that in terms of the NSView hierarchy, our ChildView
 // is actually below the titlebar controls - that's why hovering and clicking
 // them works as expected - but their visual representation is only drawn into
 // the normal window buffer, and the window buffer surface lies below the
 // GLContext surface. In order to make the titlebar controls visible, we have
 // to redraw them inside the OpenGL context surface.
 void nsChildView::MaybeDrawTitlebar(GLManager* aManager) {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   MutexAutoLock lock(mEffectsLock);
   if (!mIsCoveringTitlebar || mIsFullscreen || mTitlebarRect.IsEmpty()) {
     return;
   }
 
   LayoutDeviceIntRegion updatedTitlebarRegion;
   updatedTitlebarRegion.And(mUpdatedTitlebarRegion, mTitlebarRect);
   updatedTitlebarRegion.MoveBy(-mTitlebarRect.TopLeft());
@@ -2256,16 +2270,18 @@ void nsChildView::MaybeDrawTitlebar(GLMa
 }
 
 static void DrawTopLeftCornerMask(CGContextRef aCtx, int aRadius) {
   CGContextSetRGBFillColor(aCtx, 1.0, 1.0, 1.0, 1.0);
   CGContextFillEllipseInRect(aCtx, CGRectMake(0, 0, aRadius * 2, aRadius * 2));
 }
 
 void nsChildView::MaybeDrawRoundedCorners(GLManager* aManager, const LayoutDeviceIntRect& aRect) {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   MutexAutoLock lock(mEffectsLock);
 
   if (!mCornerMaskImage) {
     mCornerMaskImage = MakeUnique<RectTextureImage>();
   }
 
   LayoutDeviceIntSize size(mDevPixelCornerRadius, mDevPixelCornerRadius);
   mCornerMaskImage->UpdateIfNeeded(
@@ -3560,16 +3576,18 @@ NSEvent* gLastDragMouseDownEvent = nil;
 // rounded corners and will leave transparent pixels in the corners. In these
 // places the contents of the window's "drawRect" buffer can show through. So
 // we need to make sure that this buffer is transparent in the corners so that
 // the rounded corner anti-aliasing in the OpenGL context will blend directly
 // against the backdrop of the window.
 // We don't bother clearing parts of the window that are covered by opaque
 // pixels from the OpenGL context.
 - (void)clearCorners {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   CGFloat radius = [self cornerRadius];
   CGFloat w = [self bounds].size.width, h = [self bounds].size.height;
   [[NSColor clearColor] set];
 
   if ([self isCoveringTitlebar]) {
     NSRectFill(NSMakeRect(0, 0, radius, radius));
     NSRectFill(NSMakeRect(w - radius, 0, radius, radius));
   }
@@ -3579,16 +3597,18 @@ NSEvent* gLastDragMouseDownEvent = nil;
     NSRectFill(NSMakeRect(w - radius, h - radius, radius, radius));
   }
 }
 
 // This is the analog of nsChildView::MaybeDrawRoundedCorners for CGContexts.
 // We only need to mask the top corners here because Cocoa does the masking
 // for the window's bottom corners automatically.
 - (void)maskTopCornersInContext:(CGContextRef)aContext {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   CGFloat radius = [self cornerRadius];
   int32_t devPixelCornerRadius = mGeckoChild->CocoaPointsToDevPixels(radius);
 
   // First make sure that mTopLeftCornerMask is set up.
   if (!mTopLeftCornerMask || int32_t(CGImageGetWidth(mTopLeftCornerMask)) != devPixelCornerRadius) {
     CGImageRelease(mTopLeftCornerMask);
     CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
     CGContextRef imgCtx =
@@ -3616,16 +3636,18 @@ NSEvent* gLastDragMouseDownEvent = nil;
   CGContextTranslateCTM(aContext, [self bounds].size.width, 0);
   CGContextScaleCTM(aContext, -1, 1);
   CGContextDrawImage(aContext, destRect, mTopLeftCornerMask);
 
   CGContextRestoreGState(aContext);
 }
 
 - (void)drawTitleString {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   BaseWindow* window = (BaseWindow*)[self window];
   if (![window wantsTitleDrawn]) {
     return;
   }
 
   NSView* frameView = [[window contentView] superview];
   if (![frameView respondsToSelector:@selector(_drawTitleBar:)]) {
     return;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -3063,16 +3063,18 @@ static const NSString* kStateWantsTitleD
     // silence the warning by calling a private method instead.
     [frameView _addKnownSubview:aView positioned:NSWindowBelow relativeTo:nil];
   } else {
     [frameView addSubview:aView positioned:NSWindowBelow relativeTo:nil];
   }
 }
 
 - (NSArray*)titlebarControls {
+  MOZ_RELEASE_ASSERT(!StaticPrefs::gfx_core_animation_enabled_AtStartup());
+
   // Return all subviews of the frameView which are not the content view.
   NSView* frameView = [[self contentView] superview];
   NSMutableArray* array = [[[frameView subviews] mutableCopy] autorelease];
   [array removeObject:[self contentView]];
   return array;
 }
 
 - (BOOL)respondsToSelector:(SEL)aSelector {