Bug 1711061 - Part 3. Add WebRenderImageProvider and implement for rasterized providers. r=tnikkel

This provides the framework to allow ISurfaceProvider objects to
implement WebRenderImageProvider. It is straightforward for rasterized
providers (DecodedSurfaceProvider, and SimpleSurfaceProvider). Later
parts in this series will provide the necessary changes for blob
recordings and for animatedi images.

Differential Revision: https://phabricator.services.mozilla.com/D126597
This commit is contained in:
Andrew Osmond 2021-10-26 13:28:24 +00:00
parent a122ca2764
commit e69927de97
8 changed files with 135 additions and 14 deletions

View File

@ -6,11 +6,13 @@
#include "DecodedSurfaceProvider.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/layers/SharedSurfacesChild.h"
#include "nsProxyRelease.h"
#include "Decoder.h"
using namespace mozilla::gfx;
using namespace mozilla::layers;
namespace mozilla {
namespace image {
@ -205,5 +207,28 @@ bool DecodedSurfaceProvider::ShouldPreferSyncRun() const {
StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup());
}
nsresult DecodedSurfaceProvider::UpdateKey(
layers::RenderRootStateManager* aManager,
wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
MOZ_ASSERT(mSurface);
RefPtr<SourceSurface> surface = mSurface->GetSourceSurface();
if (!surface) {
return NS_ERROR_FAILURE;
}
return SharedSurfacesChild::Share(surface, aManager, aResources, aKey);
}
nsresult SimpleSurfaceProvider::UpdateKey(
layers::RenderRootStateManager* aManager,
wr::IpcResourceUpdateQueue& aResources, wr::ImageKey& aKey) {
RefPtr<SourceSurface> surface = mSurface->GetSourceSurface();
if (!surface) {
return NS_ERROR_FAILURE;
}
return SharedSurfacesChild::Share(surface, aManager, aResources, aKey);
}
} // namespace image
} // namespace mozilla

View File

@ -55,6 +55,15 @@ class DecodedSurfaceProvider final : public ISurfaceProvider,
// don't block layout or page load.
TaskPriority Priority() const override { return TaskPriority::eLow; }
//////////////////////////////////////////////////////////////////////////////
// WebRenderImageProvider implementation.
//////////////////////////////////////////////////////////////////////////////
public:
nsresult UpdateKey(layers::RenderRootStateManager* aManager,
wr::IpcResourceUpdateQueue& aResources,
wr::ImageKey& aKey) override;
private:
virtual ~DecodedSurfaceProvider();

View File

@ -17,6 +17,7 @@
#include "mozilla/NotNull.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "imgFrame.h"
#include "SurfaceCache.h"
@ -31,7 +32,7 @@ class DrawableSurface;
* An interface for objects which can either store a surface or dynamically
* generate one.
*/
class ISurfaceProvider {
class ISurfaceProvider : public WebRenderImageProvider {
public:
// Subclasses may or may not be XPCOM classes, so we just require that they
// implement AddRef and Release.
@ -45,8 +46,8 @@ class ISurfaceProvider {
/// entry in the surface cache.
const SurfaceKey& GetSurfaceKey() const { return mSurfaceKey; }
/// @return a (potentially lazily computed) drawable reference to a surface.
virtual DrawableSurface Surface();
/// @return a drawable reference to a surface.
DrawableSurface Surface();
/// @return true if DrawableRef() will return a completely decoded surface.
virtual bool IsFinished() const = 0;
@ -92,7 +93,8 @@ class ISurfaceProvider {
protected:
ISurfaceProvider(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey,
AvailabilityState aAvailability)
: mImageKey(aImageKey),
: WebRenderImageProvider(aImageKey),
mImageKey(aImageKey),
mSurfaceKey(aSurfaceKey),
mAvailability(aAvailability) {
MOZ_ASSERT(aImageKey, "Must have a valid image key");
@ -145,10 +147,6 @@ class MOZ_STACK_CLASS DrawableSurface final {
public:
DrawableSurface() : mHaveSurface(false) {}
explicit DrawableSurface(DrawableFrameRef&& aDrawableRef)
: mDrawableRef(std::move(aDrawableRef)),
mHaveSurface(bool(mDrawableRef)) {}
explicit DrawableSurface(NotNull<ISurfaceProvider*> aProvider)
: mProvider(aProvider), mHaveSurface(true) {}
@ -232,6 +230,10 @@ class MOZ_STACK_CLASS DrawableSurface final {
return mProvider->IsFullyDecoded();
}
void TakeProvider(WebRenderImageProvider** aOutProvider) {
mProvider.forget(aOutProvider);
}
explicit operator bool() const { return mHaveSurface; }
imgFrame* operator->() { return DrawableRef().get(); }
@ -261,10 +263,9 @@ class MOZ_STACK_CLASS DrawableSurface final {
};
// Surface() is implemented here so that DrawableSurface's definition is
// visible. This default implementation eagerly obtains a DrawableFrameRef for
// the first frame and is intended for static ISurfaceProviders.
// visible.
inline DrawableSurface ISurfaceProvider::Surface() {
return DrawableSurface(DrawableRef(/* aFrame = */ 0));
return DrawableSurface(WrapNotNull(this));
}
/**
@ -289,6 +290,10 @@ class SimpleSurfaceProvider final : public ISurfaceProvider {
return size.width * size.height * mSurface->GetBytesPerPixel();
}
nsresult UpdateKey(layers::RenderRootStateManager* aManager,
wr::IpcResourceUpdateQueue& aResources,
wr::ImageKey& aKey) override;
protected:
DrawableFrameRef DrawableRef(size_t aFrame) override {
MOZ_ASSERT(aFrame == 0,

View File

@ -7,9 +7,11 @@
#include "imgRequest.h"
#include "Layers.h" // for LayerManager
#include "WebRenderImageProvider.h"
#include "nsIObserverService.h"
#include "nsRefreshDriver.h"
#include "nsContentUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/SourceSurfaceRawData.h"
@ -23,6 +25,15 @@
namespace mozilla {
namespace image {
WebRenderImageProvider::WebRenderImageProvider(const ImageResource* aImage)
: mProviderId(aImage->GetImageProviderId()) {}
/* static */ ImageProviderId WebRenderImageProvider::AllocateProviderId() {
// Callable on all threads.
static Atomic<ImageProviderId> sProviderId(0u);
return ++sProviderId;
}
///////////////////////////////////////////////////////////////////////////////
// Memory Reporting
///////////////////////////////////////////////////////////////////////////////
@ -421,7 +432,8 @@ ImageResource::ImageResource(nsIURI* aURI)
mAnimating(false),
mError(false),
mImageProducerID(layers::ImageContainer::AllocateProducerID()),
mLastFrameID(0) {}
mLastFrameID(0),
mProviderId(WebRenderImageProvider::AllocateProviderId()) {}
ImageResource::~ImageResource() {
// Ask our ProgressTracker to drop its weak reference to us.

View File

@ -22,6 +22,7 @@
#include "nsStringFwd.h"
#include "ProgressTracker.h"
#include "SurfaceCache.h"
#include "WebRenderImageProvider.h"
class imgRequest;
class nsIRequest;
@ -328,6 +329,8 @@ class ImageResource : public Image {
void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
MallocSizeOf aMallocSizeOf) const override;
ImageProviderId GetImageProviderId() const { return mProviderId; }
protected:
explicit ImageResource(nsIURI* aURI);
~ImageResource();
@ -504,6 +507,7 @@ class ImageResource : public Image {
AutoTArray<ImageContainerEntry, 1> mImageContainers;
layers::ImageContainer::ProducerID mImageProducerID;
layers::ImageContainer::FrameID mLastFrameID;
ImageProviderId mProviderId;
};
} // namespace image

View File

@ -27,7 +27,7 @@
namespace mozilla {
namespace image {
class Image;
class ImageResource;
class ISurfaceProvider;
class LookupResult;
class SurfaceCacheImpl;
@ -37,7 +37,7 @@ struct SurfaceMemoryCounter;
* ImageKey contains the information we need to look up all SurfaceCache entries
* for a particular image.
*/
typedef Image* ImageKey;
using ImageKey = ImageResource*;
/*
* SurfaceKey contains the information we need to look up a specific

View File

@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_
#define MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_
#include "nsISupportsImpl.h"
namespace mozilla {
namespace layers {
class RenderRootStateManager;
}
namespace wr {
class IpcResourceUpdateQueue;
struct ExternalImageId;
struct ImageKey;
} // namespace wr
namespace image {
class ImageResource;
using ImageProviderId = uint32_t;
class WebRenderImageProvider {
public:
// Subclasses may or may not be XPCOM classes, so we just require that they
// implement AddRef and Release.
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
ImageProviderId GetProviderId() const { return mProviderId; }
static ImageProviderId AllocateProviderId();
/**
* Generate an ImageKey for the given frame.
* @param aSurface The current frame. This should match what was cached via
* SetCurrentFrame, but if it does not, it will need to
* regenerate the cached ImageKey.
*/
virtual nsresult UpdateKey(layers::RenderRootStateManager* aManager,
wr::IpcResourceUpdateQueue& aResources,
wr::ImageKey& aKey) {
return NS_ERROR_NOT_AVAILABLE;
}
/**
* Invalidate if a blob recording, requiring it to be regenerated.
*/
virtual void InvalidateRecording() {}
protected:
WebRenderImageProvider(const ImageResource* aImage);
private:
ImageProviderId mProviderId;
};
} // namespace image
} // namespace mozilla
#endif /* MOZILLA_IMAGE_WEBRENDERIMAGEPROVIDER_H_ */

View File

@ -66,6 +66,7 @@ EXPORTS.mozilla.image += [
"ImageMemoryReporter.h",
"Resolution.h",
"SourceSurfaceBlobImage.h",
"WebRenderImageProvider.h",
]
UNIFIED_SOURCES += [