Bug 1366097 - Part 5. Add an SVGImageContext parameter to imgIContainer::GetImageContainerAtSize. r=tnikkel

This commit is contained in:
Andrew Osmond 2017-11-17 14:08:52 -05:00
Родитель c6bd7fcdf9
Коммит 114b8069b3
16 изменённых файлов: 50 добавлений и 17 удалений

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

@ -370,6 +370,7 @@ ClippedImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
ClippedImage::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
// XXX(seth): We currently don't have a way of clipping the result of
@ -379,7 +380,8 @@ ClippedImage::GetImageContainerAtSize(LayerManager* aManager,
// that method for performance reasons.
if (!ShouldClip()) {
return InnerImage()->GetImageContainerAtSize(aManager, aSize, aFlags);
return InnerImage()->GetImageContainerAtSize(aManager, aSize,
aSVGContext, aFlags);
}
return nullptr;

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

@ -54,6 +54,7 @@ public:
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
GetImageContainerAtSize(layers::LayerManager* aManager,
const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags) override;
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
const nsIntSize& aSize,

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

@ -237,6 +237,7 @@ DynamicImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
DynamicImage::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
return nullptr;

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

@ -82,6 +82,7 @@ FrozenImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
FrozenImage::GetImageContainerAtSize(layers::LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
// XXX(seth): GetImageContainer does not currently support anything but the

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

@ -53,6 +53,7 @@ public:
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
GetImageContainerAtSize(layers::LayerManager* aManager,
const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags) override;
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
const nsIntSize& aSize,

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

@ -91,6 +91,7 @@ ImageResource::SetCurrentImage(ImageContainer* aContainer,
already_AddRefed<ImageContainer>
ImageResource::GetImageContainerImpl(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
MOZ_ASSERT(NS_IsMainThread());
@ -119,7 +120,8 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
for (; i >= 0; --i) {
entry = &mImageContainers[i];
container = entry->mContainer.get();
if (size == entry->mSize && flags == entry->mFlags) {
if (size == entry->mSize && flags == entry->mFlags &&
aSVGContext == entry->mSVGContext) {
// Lack of a container is handled below.
break;
} else if (!container) {
@ -159,7 +161,8 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
IntSize bestSize;
RefPtr<SourceSurface> surface;
Tie(drawResult, bestSize, surface) =
GetFrameInternal(size, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
GetFrameInternal(size, aSVGContext, FRAME_CURRENT,
aFlags | FLAG_ASYNC_NOTIFY);
// The requested size might be refused by the surface cache (i.e. due to
// factor-of-2 mode). In that case we don't want to create an entry for this
@ -185,7 +188,8 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
i = mImageContainers.Length() - 1;
for (; i >= 0; --i) {
entry = &mImageContainers[i];
if (bestSize == entry->mSize && flags == entry->mFlags) {
if (bestSize == entry->mSize && flags == entry->mFlags &&
aSVGContext == entry->mSVGContext) {
container = entry->mContainer.get();
if (container) {
switch (entry->mLastDrawResult) {
@ -219,7 +223,7 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
entry->mContainer = container;
} else {
entry = mImageContainers.AppendElement(
ImageContainerEntry(bestSize, container.get(), flags));
ImageContainerEntry(bestSize, aSVGContext, container.get(), flags));
}
}
@ -240,7 +244,8 @@ ImageResource::UpdateImageContainer()
IntSize bestSize;
RefPtr<SourceSurface> surface;
Tie(entry.mLastDrawResult, bestSize, surface) =
GetFrameInternal(entry.mSize, FRAME_CURRENT, entry.mFlags);
GetFrameInternal(entry.mSize, entry.mSVGContext,
FRAME_CURRENT, entry.mFlags);
// It is possible that this is a factor-of-2 substitution. Since we
// managed to convert the weak reference into a strong reference, that

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

@ -339,6 +339,7 @@ protected:
virtual Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
GetFrameInternal(const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -362,6 +363,7 @@ protected:
already_AddRefed<layers::ImageContainer>
GetImageContainerImpl(layers::LayerManager* aManager,
const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags);
void UpdateImageContainer();
@ -375,15 +377,18 @@ private:
struct ImageContainerEntry {
ImageContainerEntry(const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
layers::ImageContainer* aContainer,
uint32_t aFlags)
: mSize(aSize)
, mSVGContext(aSVGContext)
, mContainer(aContainer)
, mLastDrawResult(DrawResult::NOT_READY)
, mFlags(aFlags)
{ }
gfx::IntSize mSize;
Maybe<SVGImageContext> mSVGContext;
// A weak pointer to our ImageContainer, which stays alive only as long as
// the layer system needs it.
WeakPtr<layers::ImageContainer> mContainer;

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

@ -225,9 +225,11 @@ ImageWrapper::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
ImageWrapper::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
return mInnerImage->GetImageContainerAtSize(aManager, aSize, aFlags);
return mInnerImage->GetImageContainerAtSize(aManager, aSize,
aSVGContext, aFlags);
}
NS_IMETHODIMP_(DrawResult)

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

@ -187,6 +187,7 @@ OrientedImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
OrientedImage::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
// XXX(seth): We currently don't have a way of orienting the result of
@ -196,7 +197,8 @@ OrientedImage::GetImageContainerAtSize(LayerManager* aManager,
// that method for performance reasons.
if (mOrientation.IsIdentity()) {
return InnerImage()->GetImageContainerAtSize(aManager, aSize, aFlags);
return InnerImage()->GetImageContainerAtSize(aManager, aSize,
aSVGContext, aFlags);
}
return nullptr;

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

@ -51,6 +51,7 @@ public:
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
GetImageContainerAtSize(layers::LayerManager* aManager,
const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags) override;
NS_IMETHOD_(DrawResult) Draw(gfxContext* aContext,
const nsIntSize& aSize,

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

@ -576,7 +576,7 @@ RasterImage::GetFrameAtSize(const IntSize& aSize,
NotifyDrawingObservers();
#endif
auto result = GetFrameInternal(aSize, aWhichFrame, aFlags);
auto result = GetFrameInternal(aSize, Nothing(), aWhichFrame, aFlags);
RefPtr<SourceSurface> surf = mozilla::Get<2>(result).forget();
// If we are here, it suggests the image is embedded in a canvas or some
@ -587,6 +587,7 @@ RasterImage::GetFrameAtSize(const IntSize& aSize,
Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
RasterImage::GetFrameInternal(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -655,7 +656,7 @@ RasterImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
RasterImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
{
return GetImageContainerImpl(aManager, mSize, aFlags);
return GetImageContainerImpl(aManager, mSize, Nothing(), aFlags);
}
NS_IMETHODIMP_(bool)
@ -680,9 +681,10 @@ RasterImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
RasterImage::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
return GetImageContainerImpl(aManager, aSize, aFlags);
return GetImageContainerImpl(aManager, aSize, aSVGContext, aFlags);
}
size_t

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

@ -309,6 +309,7 @@ private:
Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
GetFrameInternal(const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags) override;

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

@ -741,7 +741,7 @@ VectorImage::GetFrameAtSize(const IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags)
{
auto result = GetFrameInternal(aSize, aWhichFrame, aFlags);
auto result = GetFrameInternal(aSize, Nothing(), aWhichFrame, aFlags);
RefPtr<SourceSurface> surf = Get<2>(result).forget();
// If we are here, it suggests the image is embedded in a canvas or some
@ -752,6 +752,7 @@ VectorImage::GetFrameAtSize(const IntSize& aSize,
Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
VectorImage::GetFrameInternal(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags)
{
@ -773,7 +774,7 @@ VectorImage::GetFrameInternal(const IntSize& aSize,
}
RefPtr<SourceSurface> sourceSurface =
LookupCachedSurface(aSize, Nothing(), aFlags);
LookupCachedSurface(aSize, aSVGContext, aFlags);
if (sourceSurface) {
return MakeTuple(DrawResult::SUCCESS, aSize, Move(sourceSurface));
}
@ -797,9 +798,8 @@ VectorImage::GetFrameInternal(const IntSize& aSize,
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
MOZ_ASSERT(context); // already checked the draw target above
Maybe<SVGImageContext> svgContext;
SVGDrawingParameters params(context, aSize, ImageRegion::Create(aSize),
SamplingFilter::POINT, svgContext,
SamplingFilter::POINT, aSVGContext,
mSVGDocumentWrapper->GetCurrentTime(),
aFlags, 1.0);
@ -862,12 +862,13 @@ VectorImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
VectorImage::GetImageContainerAtSize(LayerManager* aManager,
const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
// Since we do not support high quality scaling with SVG, we mask it off so
// that container requests with and without it map to the same container.
uint32_t flags = aFlags & ~FLAG_HIGH_QUALITY_SCALING;
return GetImageContainerImpl(aManager, aSize, aFlags);
return GetImageContainerImpl(aManager, aSize, aSVGContext, flags);
}
//******************************************************************************

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

@ -83,6 +83,7 @@ protected:
private:
Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
GetFrameInternal(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags) override;

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

@ -315,7 +315,10 @@ interface imgIContainer : nsISupports
*
* @param aManager The LayerManager which will be used to create the
* ImageContainer.
* @param aSize The size to decode the frame at.
* @param aSVGContext If specified, SVG-related rendering context, such as
* overridden attributes on the image document's root <svg>
* node, and the size of the viewport that the full image
* would occupy. Ignored for raster images.
* @param aFlags Decoding / drawing flags (in other words, FLAG_* flags).
* Currently only FLAG_SYNC_DECODE and FLAG_SYNC_DECODE_IF_FAST
* are supported.
@ -324,6 +327,7 @@ interface imgIContainer : nsISupports
*/
[noscript, notxpcom] TempRefImageContainer getImageContainerAtSize(in LayerManager aManager,
[const] in nsIntSize aSize,
[const] in MaybeSVGImageContext aSVGContext,
in uint32_t aFlags);
/**

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

@ -73,6 +73,7 @@ TEST_F(ImageContainers, RasterImageContainer)
RefPtr<layers::ImageContainer> upscaleContainer =
image->GetImageContainerAtSize(layerManager,
requestedSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING);
ASSERT_TRUE(upscaleContainer != nullptr);
@ -87,6 +88,7 @@ TEST_F(ImageContainers, RasterImageContainer)
RefPtr<layers::ImageContainer> downscaleContainer =
image->GetImageContainerAtSize(layerManager,
requestedSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING);
containerSize = downscaleContainer->GetCurrentSize();
@ -97,6 +99,7 @@ TEST_F(ImageContainers, RasterImageContainer)
RefPtr<layers::ImageContainer> againContainer =
image->GetImageContainerAtSize(layerManager,
testCase.mSize,
Nothing(),
imgIContainer::FLAG_SYNC_DECODE);
ASSERT_EQ(nativeContainer.get(), againContainer.get());
}