Bug 1592739 - Stop using the vibrant region as the transparent region. r=mattwoodrow

This code was assuming that the only non-opaque parts of compositor rendering would be the
parts of the window that had vibrancy. But now that the default window background is transparent,
we can have non-vibrant parts where we render into transparency. Dialog windows such as sheet
windows are an example of this.
So instead of using the non-vibrant region of the window as its opaque region, we now use
the region that is covered by opaque Gecko layers. This region is a lot more conservative:
For example, the main browser chrome is now entirely transparent, because the chrome's opaque
parts share a layer with its transparent parts.
As a result, this change slightly affects the CALayer partitioning in the main browser window:
The entire browser chrome is now transparent, not just the tab bar.
The web content area is still opaque.

I think this will be fine. The thing I'm most concerned about is that scrolling inside web
content might cause invalidations of pixels from the chrome, because then we'd recomposite
the CALayers that cover the vibrant tab bar. This doesn't seem to happen most of the time
though, from what I can tell.

Differential Revision: https://phabricator.services.mozilla.com/D51466
This commit is contained in:
Markus Stange 2020-06-11 18:46:04 +00:00
parent f0b3aa554a
commit 7b1b52b19b
7 changed files with 1 additions and 65 deletions

View File

@ -1184,11 +1184,7 @@ bool LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion,
// opaque parts of the window are covered by different layers and we can // opaque parts of the window are covered by different layers and we can
// update those parts separately. // update those parts separately.
IntRegion opaqueRegion; IntRegion opaqueRegion;
#ifdef XP_MACOSX opaqueRegion.And(aOpaqueRegion, mRenderBounds);
opaqueRegion =
mCompositor->GetWidget()->GetOpaqueWidgetRegion().ToUnknownRegion();
#endif
opaqueRegion.AndWith(mRenderBounds);
// Limit the complexity of these regions. Usually, opaqueRegion should be // Limit the complexity of these regions. Usually, opaqueRegion should be
// only one or two rects, so this SimplifyInward call will not change the // only one or two rects, so this SimplifyInward call will not change the

View File

@ -231,24 +231,6 @@ class CompositorWidget {
*/ */
virtual already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing(); virtual already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing();
#ifdef XP_MACOSX
/**
* Return the opaque region of the widget. This is racy and can only be used
* on macOS, where the widget works around the raciness.
* Bug 1576491 tracks fixing this properly.
* The problem with this method is that it can return values "from the future"
* - the compositor might be working on frame N but the widget will return its
* opaque region from frame N + 1.
* It is believed that this won't lead to visible glitches on macOS due to the
* SuspendAsyncCATransactions call when the vibrant region changes or when the
* window resizes. Whenever the compositor uses an opaque region that's a
* frame ahead, the result it renders won't be shown on the screen; instead,
* the next composite will happen with the correct display list, and that's
* what's shown on the screen once the FlushRendering call completes.
*/
virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() { return {}; }
#endif
/** /**
* Observe or unobserve vsync. * Observe or unobserve vsync.
*/ */

View File

@ -96,12 +96,6 @@ uintptr_t InProcessCompositorWidget::GetWidgetKey() {
nsIWidget* InProcessCompositorWidget::RealWidget() { return mWidget; } nsIWidget* InProcessCompositorWidget::RealWidget() { return mWidget; }
#ifdef XP_MACOSX
LayoutDeviceIntRegion InProcessCompositorWidget::GetOpaqueWidgetRegion() {
return mWidget->GetOpaqueWidgetRegion();
}
#endif
void InProcessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) { void InProcessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
if (RefPtr<CompositorVsyncDispatcher> cvd = if (RefPtr<CompositorVsyncDispatcher> cvd =
mWidget->GetCompositorVsyncDispatcher()) { mWidget->GetCompositorVsyncDispatcher()) {

View File

@ -33,9 +33,6 @@ class InProcessCompositorWidget : public CompositorWidget {
virtual bool InitCompositor(layers::Compositor* aCompositor) override; virtual bool InitCompositor(layers::Compositor* aCompositor) override;
virtual LayoutDeviceIntSize GetClientSize() override; virtual LayoutDeviceIntSize GetClientSize() override;
virtual uint32_t GetGLFrameBufferFormat() override; virtual uint32_t GetGLFrameBufferFormat() override;
#ifdef XP_MACOSX
virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() override;
#endif
virtual void ObserveVsync(VsyncObserver* aObserver) override; virtual void ObserveVsync(VsyncObserver* aObserver) override;
virtual uintptr_t GetWidgetKey() override; virtual uintptr_t GetWidgetKey() override;

View File

@ -491,8 +491,6 @@ class nsChildView final : public nsBaseWidget {
virtual LayoutDeviceIntPoint GetClientOffset() override; virtual LayoutDeviceIntPoint GetClientOffset() override;
virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() override;
void DispatchAPZWheelInputEvent(mozilla::InputData& aEvent, bool aCanTriggerSwipe); void DispatchAPZWheelInputEvent(mozilla::InputData& aEvent, bool aCanTriggerSwipe);
nsEventStatus DispatchAPZInputEvent(mozilla::InputData& aEvent); nsEventStatus DispatchAPZInputEvent(mozilla::InputData& aEvent);
@ -533,8 +531,6 @@ class nsChildView final : public nsBaseWidget {
void UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries); void UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries);
mozilla::VibrancyManager& EnsureVibrancyManager(); mozilla::VibrancyManager& EnsureVibrancyManager();
void UpdateInternalOpaqueRegion();
nsIWidget* GetWidgetForListenerEvents(); nsIWidget* GetWidgetForListenerEvents();
struct SwipeInfo { struct SwipeInfo {
@ -596,9 +592,6 @@ class nsChildView final : public nsBaseWidget {
RefPtr<mozilla::CancelableRunnable> mUnsuspendAsyncCATransactionsRunnable; RefPtr<mozilla::CancelableRunnable> mUnsuspendAsyncCATransactionsRunnable;
// The widget's opaque region. Written on the main thread, read on any thread.
mozilla::DataMutex<mozilla::LayoutDeviceIntRegion> mOpaqueRegion;
// This flag is only used when APZ is off. It indicates that the current pan // This flag is only used when APZ is off. It indicates that the current pan
// gesture was processed as a swipe. Sometimes the swipe animation can finish // gesture was processed as a swipe. Sometimes the swipe animation can finish
// before momentum events of the pan gesture have stopped firing, so this // before momentum events of the pan gesture have stopped firing, so this

View File

@ -236,7 +236,6 @@ nsChildView::nsChildView()
mDrawing(false), mDrawing(false),
mIsDispatchPaint(false), mIsDispatchPaint(false),
mPluginFocused{false}, mPluginFocused{false},
mOpaqueRegion("nsChildView::mOpaqueRegion"),
mCurrentPanGestureBelongsToSwipe{false} {} mCurrentPanGestureBelongsToSwipe{false} {}
nsChildView::~nsChildView() { nsChildView::~nsChildView() {
@ -506,8 +505,6 @@ void nsChildView::SetTransparencyMode(nsTransparencyMode aMode) {
windowWidget->SetTransparencyMode(aMode); windowWidget->SetTransparencyMode(aMode);
} }
UpdateInternalOpaqueRegion();
NS_OBJC_END_TRY_ABORT_BLOCK; NS_OBJC_END_TRY_ABORT_BLOCK;
} }
@ -1434,11 +1431,6 @@ LayoutDeviceIntPoint nsChildView::WidgetToScreenOffset() {
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0, 0)); NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(LayoutDeviceIntPoint(0, 0));
} }
LayoutDeviceIntRegion nsChildView::GetOpaqueWidgetRegion() {
auto opaqueRegion = mOpaqueRegion.Lock();
return *opaqueRegion;
}
nsresult nsChildView::SetTitle(const nsAString& title) { nsresult nsChildView::SetTitle(const nsAString& title) {
// child views don't have titles // child views don't have titles
return NS_OK; return NS_OK;
@ -1900,8 +1892,6 @@ void nsChildView::UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries
changed |= vm.UpdateVibrantRegion(VibrancyType::ACTIVE_SOURCE_LIST_SELECTION, changed |= vm.UpdateVibrantRegion(VibrancyType::ACTIVE_SOURCE_LIST_SELECTION,
activeSourceListSelectionRegion); activeSourceListSelectionRegion);
UpdateInternalOpaqueRegion();
if (changed) { if (changed) {
SuspendAsyncCATransactions(); SuspendAsyncCATransactions();
} }
@ -1915,19 +1905,6 @@ mozilla::VibrancyManager& nsChildView::EnsureVibrancyManager() {
return *mVibrancyManager; return *mVibrancyManager;
} }
void nsChildView::UpdateInternalOpaqueRegion() {
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "This should only be called on the main thread.");
auto opaqueRegion = mOpaqueRegion.Lock();
bool widgetIsOpaque = GetTransparencyMode() == eTransparencyOpaque;
if (!widgetIsOpaque) {
opaqueRegion->SetEmpty();
} else if (VibrancyManager::SystemSupportsVibrancy()) {
opaqueRegion->Sub(mBounds, EnsureVibrancyManager().GetUnionOfVibrantRegions());
} else {
*opaqueRegion = mBounds;
}
}
nsChildView::SwipeInfo nsChildView::SendMayStartSwipe( nsChildView::SwipeInfo nsChildView::SendMayStartSwipe(
const mozilla::PanGestureInput& aSwipeStartEvent) { const mozilla::PanGestureInput& aSwipeStartEvent) {
nsCOMPtr<nsIWidget> kungFuDeathGrip(this); nsCOMPtr<nsIWidget> kungFuDeathGrip(this);

View File

@ -465,9 +465,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
} }
virtual uint32_t GetGLFrameBufferFormat(); virtual uint32_t GetGLFrameBufferFormat();
virtual bool CompositorInitiallyPaused() { return false; } virtual bool CompositorInitiallyPaused() { return false; }
#ifdef XP_MACOSX
virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() { return {}; }
#endif
protected: protected:
void ResolveIconName(const nsAString& aIconName, const nsAString& aIconSuffix, void ResolveIconName(const nsAString& aIconName, const nsAString& aIconSuffix,