Bug 1674473 [Linux] SW-WR Clear background when painting popup windows, r=lsalzman

Clear alpha from buffer before painting transparent windows by SW Webrender to avoid rendering artifacts.

Differential Revision: https://phabricator.services.mozilla.com/D102189
This commit is contained in:
stransky 2021-01-20 21:11:48 +00:00
Родитель bb776a0333
Коммит 0c7400ee46
6 изменённых файлов: 33 добавлений и 2 удалений

Просмотреть файл

@ -61,6 +61,7 @@ bool RenderCompositorSWGL::AllocateMappedBuffer() {
if (!mDT) {
return false;
}
mWidget->ClearBeforePaint(mDT, mRegion);
// Attempt to lock the underlying buffer directly from the draw target.
// Verify that the size at least matches what the widget claims and that
// the format is BGRA8 as SWGL requires.

Просмотреть файл

@ -163,6 +163,13 @@ class CompositorWidget {
*/
virtual bool NeedsToDeferEndRemoteDrawing() { return false; }
/**
* Some widgets (namely Gtk) may need clean up underlying surface
* before painting to draw transparent objects correctly.
*/
virtual void ClearBeforePaint(RefPtr<gfx::DrawTarget> aTarget,
const LayoutDeviceIntRegion& aRegion) {}
/**
* Called when shutting down the LayerManager to clean-up any cached
* resources.

Просмотреть файл

@ -14,6 +14,8 @@
namespace mozilla {
namespace widget {
using namespace gfx;
GtkCompositorWidget::GtkCompositorWidget(
const GtkCompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions, nsWindow* aWindow)
@ -125,5 +127,20 @@ void GtkCompositorWidget::SetEGLNativeWindowSize(
}
#endif
void GtkCompositorWidget::ClearBeforePaint(
RefPtr<gfx::DrawTarget> aTarget, const LayoutDeviceIntRegion& aRegion) {
// We need to clear target buffer alpha values of popup windows as
// SW-WR paints with alpha blending (see Bug 1674473).
if (mWidget->IsPopup()) {
for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
LayoutDeviceIntRect r = iter.Get();
aTarget->FillRect(gfx::Rect(r.x, r.y, r.width, r.height),
ColorPattern(DeviceColor(0, 0, 0, 0)),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
}
aTarget->Flush();
}
}
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -61,6 +61,9 @@ class GtkCompositorWidget : public CompositorWidget,
EGLNativeWindowType GetEGLNativeWindow();
int32_t GetDepth();
void ClearBeforePaint(RefPtr<gfx::DrawTarget> aTarget,
const LayoutDeviceIntRegion& aRegion) override;
#if defined(MOZ_X11)
Display* XDisplay() const { return mXDisplay; }
Window XWindow() const { return mXWindow; }

Просмотреть файл

@ -1248,10 +1248,12 @@ void nsWindow::Move(double aX, double aY) {
}
}
bool nsWindow::IsWaylandPopup() {
return !mIsX11Display && mIsTopLevel && mWindowType == eWindowType_popup;
bool nsWindow::IsPopup() {
return mIsTopLevel && mWindowType == eWindowType_popup;
}
bool nsWindow::IsWaylandPopup() { return !mIsX11Display && IsPopup(); }
void nsWindow::HideWaylandTooltips() {
while (gVisibleWaylandPopupWindows) {
nsWindow* window =

Просмотреть файл

@ -298,6 +298,7 @@ class nsWindow final : public nsBaseWidget {
GtkWidget* GetGtkWidget() { return mShell; }
nsIFrame* GetFrame();
bool IsDestroyed() { return mIsDestroyed; }
bool IsPopup();
bool IsWaylandPopup();
bool IsPIPWindow() { return mIsPIPWindow; };