Bug 1839109. Don't send animated image updates to throttled refresh drivers. r=gfx-reviewers,bradwerth

The patch for bug 1830753 stops these for CompositorBridgeChild's that are recorded as paused. That fixes the problem for animated images that are in the top level chrome document, but doesn't fix the problem for images in a content tab because the CompositorBridgeChild in the content process is not aware the compositor is paused. So instead we check the throttled state of the refresh driver. Since we only have access to the layer manager at this point it is a bit of a trip to get the refresh driver but very possible.

Differential Revision: https://phabricator.services.mozilla.com/D181353
This commit is contained in:
Timothy Nikkel 2023-06-21 05:17:45 +00:00
Родитель 05b9f135b3
Коммит cb5dd67397
1 изменённых файлов: 37 добавлений и 0 удалений

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

@ -15,6 +15,9 @@
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/SchedulerGroup.h" #include "mozilla/SchedulerGroup.h"
#include "mozilla/StaticPrefs_image.h" #include "mozilla/StaticPrefs_image.h"
#include "mozilla/PresShell.h"
#include "nsRefreshDriver.h"
#include "nsView.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -448,6 +451,25 @@ void SharedSurfacesAnimation::HoldSurfaceForRecycling(
aEntry.mPendingRelease.AppendElement(aSurface); aEntry.mPendingRelease.AppendElement(aSurface);
} }
// This will get the widget listener that handles painting. Generally, this is
// the attached widget listener (or previously attached if the attached is paint
// suppressed). Otherwise it is the widget listener. There should be a function
// in nsIWidget that does this for us but there isn't yet.
static nsIWidgetListener* GetPaintWidgetListener(nsIWidget* aWidget) {
if (auto* attached = aWidget->GetAttachedWidgetListener()) {
if (attached->GetView() &&
attached->GetView()->IsPrimaryFramePaintSuppressed()) {
if (auto* previouslyAttached =
aWidget->GetPreviouslyAttachedWidgetListener()) {
return previouslyAttached;
}
}
return attached;
}
return aWidget->GetWidgetListener();
}
nsresult SharedSurfacesAnimation::SetCurrentFrame( nsresult SharedSurfacesAnimation::SetCurrentFrame(
SourceSurfaceSharedData* aSurface, const gfx::IntRect& aDirtyRect) { SourceSurfaceSharedData* aSurface, const gfx::IntRect& aDirtyRect) {
MOZ_ASSERT(aSurface); MOZ_ASSERT(aSurface);
@ -474,6 +496,21 @@ nsresult SharedSurfacesAnimation::SetCurrentFrame(
} }
} }
// Only root compositor bridge childs record if they are paused, so check
// the refresh driver.
if (auto* widget = entry.mManager->LayerManager()->GetWidget()) {
nsIWidgetListener* wl = GetPaintWidgetListener(widget);
// Note call to wl->GetView() to make sure this is view type widget
// listener even though we don't use the view in this code.
if (wl && wl->GetView() && wl->GetPresShell()) {
if (auto* rd = wl->GetPresShell()->GetRefreshDriver()) {
if (rd->IsThrottled()) {
continue;
}
}
}
}
entry.MergeDirtyRect(Some(aDirtyRect)); entry.MergeDirtyRect(Some(aDirtyRect));
Maybe<IntRect> dirtyRect = entry.TakeDirtyRect(); Maybe<IntRect> dirtyRect = entry.TakeDirtyRect();
if (dirtyRect) { if (dirtyRect) {