зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1669239 - Call Tick to paint in PuppetWidget::Paint instead of using WillPaintWindow r=emilio,mattwoodrow
The `WillPaintWindow` call is problematic for FirstContentfulPaint algorithm because it causes paints that outside of ticks, which would revoke the viewer flush for the next tick, hence no firstContentful paint entries are fired. However, this `WillPaintWindow` call is also useful because it allows the parent to aware that the layers are updated, so that the parent can fire corresponding events based on the status. If we don't do it, parent may end up not knowing that the layers are updated, so some tests may stall because of the missing events. The proposed solution here is simply using Tick here to satisfy both requirements. It's okay to remove mDirtyRegion in this patch because the mDirtyRegion usage was for BASIC_LAYERS. BASIC_LAYERS means BasicLayerManager which does in-process drawing which is nonsense from the content process. Differential Revision: https://phabricator.services.mozilla.com/D92445
This commit is contained in:
Родитель
2f3eeff1f7
Коммит
40945e8a39
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "ClientLayerManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/Hal.h"
|
||||
|
@ -268,10 +269,8 @@ void PuppetWidget::Invalidate(const LayoutDeviceIntRect& aRect) {
|
|||
return;
|
||||
}
|
||||
|
||||
mDirtyRegion.Or(mDirtyRegion, aRect);
|
||||
|
||||
if (mBrowserChild && !mDirtyRegion.IsEmpty() && !mPaintTask.IsPending()) {
|
||||
mPaintTask = new PaintTask(this);
|
||||
if (mBrowserChild && !aRect.IsEmpty() && !mPaintTask.IsPending()) {
|
||||
mPaintTask = new PaintTask(this, false);
|
||||
nsCOMPtr<nsIRunnable> event(mPaintTask.get());
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, event.forget());
|
||||
return;
|
||||
|
@ -980,61 +979,27 @@ void PuppetWidget::ClearCachedCursor() {
|
|||
mCustomCursor = nullptr;
|
||||
}
|
||||
|
||||
nsresult PuppetWidget::Paint() {
|
||||
MOZ_ASSERT(!mDirtyRegion.IsEmpty(), "paint event logic messed up");
|
||||
|
||||
if (!GetCurrentWidgetListener()) return NS_OK;
|
||||
|
||||
LayoutDeviceIntRegion region = mDirtyRegion;
|
||||
nsresult PuppetWidget::Paint(bool aDoTick) {
|
||||
if (!GetCurrentWidgetListener()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// reset repaint tracking
|
||||
mDirtyRegion.SetEmpty();
|
||||
mPaintTask.Revoke();
|
||||
|
||||
RefPtr<PuppetWidget> strongThis(this);
|
||||
|
||||
GetCurrentWidgetListener()->WillPaintWindow(this);
|
||||
|
||||
if (GetCurrentWidgetListener()) {
|
||||
#ifdef DEBUG
|
||||
debug_DumpPaintEvent(stderr, this, region.ToUnknownRegion(), "PuppetWidget",
|
||||
0);
|
||||
#endif
|
||||
|
||||
if (mLayerManager->GetBackendType() ==
|
||||
mozilla::layers::LayersBackend::LAYERS_CLIENT ||
|
||||
mLayerManager->GetBackendType() ==
|
||||
mozilla::layers::LayersBackend::LAYERS_WR ||
|
||||
(mozilla::layers::LayersBackend::LAYERS_BASIC ==
|
||||
mLayerManager->GetBackendType() &&
|
||||
mBrowserChild && mBrowserChild->IsLayersConnected().isSome())) {
|
||||
// Do nothing, the compositor will handle drawing
|
||||
if (mBrowserChild) {
|
||||
mBrowserChild->NotifyPainted();
|
||||
}
|
||||
} else if (mozilla::layers::LayersBackend::LAYERS_BASIC ==
|
||||
mLayerManager->GetBackendType()) {
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(mDrawTarget);
|
||||
if (!ctx) {
|
||||
gfxDevCrash(LogReason::InvalidContext)
|
||||
<< "PuppetWidget context problem " << gfx::hexa(mDrawTarget);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
ctx->Rectangle(gfxRect(0, 0, 0, 0));
|
||||
ctx->Clip();
|
||||
AutoLayerManagerSetup setupLayerManager(this, ctx,
|
||||
BufferMode::BUFFER_NONE);
|
||||
GetCurrentWidgetListener()->PaintWindow(this, region);
|
||||
if (mBrowserChild) {
|
||||
mBrowserChild->NotifyPainted();
|
||||
if (PresShell* presShell = mBrowserChild->GetTopLevelPresShell()) {
|
||||
if (RefPtr<nsRefreshDriver> refreshDriver = presShell->GetRefreshDriver()) {
|
||||
refreshDriver->ScheduleViewManagerFlush();
|
||||
// The Tick here is mainly for optimization purpose; Ticking
|
||||
// here allows us to notify layer updates faster.
|
||||
if (aDoTick) {
|
||||
refreshDriver->DoTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCurrentWidgetListener()) {
|
||||
GetCurrentWidgetListener()->DidPaintWindow();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1049,14 +1014,14 @@ void PuppetWidget::SetChild(PuppetWidget* aChild) {
|
|||
NS_IMETHODIMP
|
||||
PuppetWidget::PaintTask::Run() {
|
||||
if (mWidget) {
|
||||
mWidget->Paint();
|
||||
mWidget->Paint(mDoTick);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void PuppetWidget::PaintNowIfNeeded() {
|
||||
if (IsVisible() && mPaintTask.IsPending()) {
|
||||
Paint();
|
||||
Paint(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ class PuppetWidget : public nsBaseWidget,
|
|||
virtual void OnMemoryPressure(layers::MemoryPressureReason aWhy) override;
|
||||
|
||||
private:
|
||||
nsresult Paint();
|
||||
nsresult Paint(bool aDoTick);
|
||||
|
||||
void SetChild(PuppetWidget* aChild);
|
||||
|
||||
|
@ -355,12 +355,15 @@ class PuppetWidget : public nsBaseWidget,
|
|||
class PaintTask : public Runnable {
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
explicit PaintTask(PuppetWidget* widget)
|
||||
: Runnable("PuppetWidget::PaintTask"), mWidget(widget) {}
|
||||
explicit PaintTask(PuppetWidget* widget, bool aDoTick)
|
||||
: Runnable("PuppetWidget::PaintTask"),
|
||||
mWidget(widget),
|
||||
mDoTick(aDoTick) {}
|
||||
void Revoke() { mWidget = nullptr; }
|
||||
|
||||
private:
|
||||
PuppetWidget* mWidget;
|
||||
bool mDoTick;
|
||||
};
|
||||
|
||||
// BrowserChild normally holds a strong reference to this PuppetWidget
|
||||
|
@ -373,7 +376,6 @@ class PuppetWidget : public nsBaseWidget,
|
|||
// The "widget" to which we delegate events if we don't have an
|
||||
// event handler.
|
||||
RefPtr<PuppetWidget> mChild;
|
||||
LayoutDeviceIntRegion mDirtyRegion;
|
||||
nsRevocableEventPtr<PaintTask> mPaintTask;
|
||||
RefPtr<layers::MemoryPressureObserver> mMemoryPressureObserver;
|
||||
// XXX/cjones: keeping this around until we teach LayerManager to do
|
||||
|
|
Загрузка…
Ссылка в новой задаче