Bug 1880054. Simplify some imagelib event target code. r=gfx-reviewers,lsalzman

This code was added before we decided to do fission, when we wanted to separate out different sites that were in the same process so we could prioritize them better. We are not going down that path so we can simplify this code. There should be no change in functionality with this patch, just simpler code.

Differential Revision: https://phabricator.services.mozilla.com/D201705
This commit is contained in:
Timothy Nikkel 2024-02-25 04:54:33 +00:00
parent 9ca7fc04b2
commit 732e327254
9 changed files with 33 additions and 94 deletions

View File

@ -23,41 +23,9 @@ namespace image {
// Helpers for sending notifications to the image associated with a decoder.
///////////////////////////////////////////////////////////////////////////////
void IDecodingTask::EnsureHasEventTarget(NotNull<RasterImage*> aImage) {
if (!mEventTarget) {
// We determine the event target as late as possible, at the first dispatch
// time, because the observers bound to an imgRequest will affect it.
// We cache it rather than query for the event target each time because the
// event target can change. We don't want to risk events being executed in
// a different order than they are dispatched, which can happen if we
// selected scheduler groups which have no ordering guarantees relative to
// each other (e.g. it moves from scheduler group A for doc group DA to
// scheduler group B for doc group DB due to changing observers -- if we
// dispatched the first event on A, and the second on B, we don't know which
// will execute first.)
RefPtr<ProgressTracker> tracker = aImage->GetProgressTracker();
if (tracker) {
mEventTarget = tracker->GetEventTarget();
} else {
mEventTarget = GetMainThreadSerialEventTarget();
}
}
}
bool IDecodingTask::IsOnEventTarget() const {
// This is essentially equivalent to NS_IsOnMainThread() because all of the
// event targets are for the main thread (although perhaps with a different
// label / scheduler group). The observers in ProgressTracker may have
// different event targets from this, so this is just a best effort guess.
bool current = false;
mEventTarget->IsOnCurrentThread(&current);
return current;
}
void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
NotNull<Decoder*> aDecoder) {
MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode());
EnsureHasEventTarget(aImage);
// Capture the decoder's state. If we need to notify asynchronously, it's
// important that we don't wait until the lambda actually runs to capture the
@ -72,7 +40,7 @@ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
// Synchronously notify if we can.
if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
aImage->NotifyProgress(progress, invalidRect, frameCount, decoderFlags,
surfaceFlags);
return;
@ -86,21 +54,21 @@ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
// We're forced to notify asynchronously.
NotNull<RefPtr<RasterImage>> image = aImage;
mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
"IDecodingTask::NotifyProgress",
[=]() -> void {
image->NotifyProgress(progress, invalidRect,
frameCount, decoderFlags,
surfaceFlags);
})),
NS_DISPATCH_NORMAL);
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
"IDecodingTask::NotifyProgress",
[=]() -> void {
image->NotifyProgress(progress, invalidRect,
frameCount, decoderFlags,
surfaceFlags);
})),
NS_DISPATCH_NORMAL);
}
void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
NotNull<Decoder*> aDecoder) {
MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(),
"Decode complete in the middle of a frame?");
EnsureHasEventTarget(aImage);
// Capture the decoder's state.
DecoderFinalStatus finalStatus = aDecoder->FinalStatus();
@ -113,7 +81,7 @@ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
// Synchronously notify if we can.
if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress,
invalidRect, frameCount, decoderFlags,
surfaceFlags);
@ -128,15 +96,16 @@ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
// We're forced to notify asynchronously.
NotNull<RefPtr<RasterImage>> image = aImage;
mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
"IDecodingTask::NotifyDecodeComplete",
[=]() -> void {
image->NotifyDecodeComplete(
finalStatus, metadata, telemetry, progress,
invalidRect, frameCount, decoderFlags,
surfaceFlags);
})),
NS_DISPATCH_NORMAL);
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
"IDecodingTask::NotifyDecodeComplete",
[=]() -> void {
image->NotifyDecodeComplete(
finalStatus, metadata, telemetry, progress,
invalidRect, frameCount, decoderFlags,
surfaceFlags);
})),
NS_DISPATCH_NORMAL);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -53,13 +53,6 @@ class IDecodingTask : public IResumable {
/// Notify @aImage that @aDecoder has finished.
void NotifyDecodeComplete(NotNull<RasterImage*> aImage,
NotNull<Decoder*> aDecoder);
private:
void EnsureHasEventTarget(NotNull<RasterImage*> aImage);
bool IsOnEventTarget() const;
nsCOMPtr<nsIEventTarget> mEventTarget;
};
/**

View File

@ -10,8 +10,6 @@
#include "nsISupports.h"
#include "nsRect.h"
class nsIEventTarget;
namespace mozilla {
namespace image {

View File

@ -218,7 +218,7 @@ void ImageResource::SendOnUnlockedDraw(uint32_t aFlags) {
mProgressTracker->OnUnlockedDraw();
} else {
NotNull<RefPtr<ImageResource>> image = WrapNotNull(this);
nsCOMPtr<nsIEventTarget> eventTarget = mProgressTracker->GetEventTarget();
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
"image::ImageResource::SendOnUnlockedDraw", [=]() -> void {
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();

View File

@ -408,10 +408,6 @@ void ProgressTracker::EmulateRequestFinished(IProgressObserver* aObserver) {
}
}
already_AddRefed<nsIEventTarget> ProgressTracker::GetEventTarget() const {
return do_AddRef(GetMainThreadSerialEventTarget());
}
void ProgressTracker::AddObserver(IProgressObserver* aObserver) {
MOZ_ASSERT(NS_IsMainThread());
RefPtr<IProgressObserver> observer = aObserver;

View File

@ -179,9 +179,6 @@ class ProgressTracker : public mozilla::SupportsWeakPtr {
bool RemoveObserver(IProgressObserver* aObserver);
uint32_t ObserverCount() const;
// Get the event target we should currently dispatch events to.
already_AddRefed<nsIEventTarget> GetEventTarget() const;
// Resets our weak reference to our image. Image subclasses should call this
// in their destructor.
void ResetImage();

View File

@ -480,12 +480,7 @@ void RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {
bool animatedFramesDiscarded =
mAnimationState && aSurfaceKey.Playback() == PlaybackType::eAnimated;
nsCOMPtr<nsIEventTarget> eventTarget;
if (mProgressTracker) {
eventTarget = mProgressTracker->GetEventTarget();
} else {
eventTarget = do_GetMainThread();
}
nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
RefPtr<RasterImage> image = this;
nsCOMPtr<nsIRunnable> ev =

View File

@ -1557,12 +1557,7 @@ void VectorImage::InvalidateObserversOnNextRefreshDriverTick() {
// set by InvalidateFrameInternal in layout/generic/nsFrame.cpp. These bits
// get cleared when we repaint the SVG into a surface by
// nsIFrame::ClearInvalidationStateBits in nsDisplayList::PaintRoot.
nsCOMPtr<nsIEventTarget> eventTarget;
if (mProgressTracker) {
eventTarget = mProgressTracker->GetEventTarget();
} else {
eventTarget = do_GetMainThread();
}
nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
RefPtr<VectorImage> self(this);
nsCOMPtr<nsIRunnable> ev(NS_NewRunnableFunction(

View File

@ -334,8 +334,7 @@ void imgRequest::Cancel(nsresult aStatus) {
if (NS_IsMainThread()) {
ContinueCancel(aStatus);
} else {
RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
nsCOMPtr<nsIEventTarget> eventTarget = progressTracker->GetEventTarget();
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
nsCOMPtr<nsIRunnable> ev = new imgRequestMainThreadCancel(this, aStatus);
eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
}
@ -1027,26 +1026,23 @@ imgRequest::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInStr,
if (result.mImage) {
image = result.mImage;
nsCOMPtr<nsIEventTarget> eventTarget;
// Update our state to reflect this new part.
{
MutexAutoLock lock(mMutex);
mImage = image;
// We only get an event target if we are not on the main thread, because
// we have to dispatch in that case. If we are on the main thread, but
// on a different scheduler group than ProgressTracker would give us,
// that is okay because nothing in imagelib requires that, just our
// listeners (which have their own checks).
if (!NS_IsMainThread()) {
eventTarget = mProgressTracker->GetEventTarget();
MOZ_ASSERT(eventTarget);
}
mProgressTracker = nullptr;
}
// We only get an event target if we are not on the main thread, because
// we have to dispatch in that case.
nsCOMPtr<nsIEventTarget> eventTarget;
if (!NS_IsMainThread()) {
eventTarget = GetMainThreadSerialEventTarget();
MOZ_ASSERT(eventTarget);
}
// Some property objects are not threadsafe, and we need to send
// OnImageAvailable on the main thread, so finish on the main thread.
if (!eventTarget) {