зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1201796 (Part 2) - Add GetFrameAtSize() to support downscale-during-decode for GetFrame() use cases. r=tn
This commit is contained in:
Родитель
30373cd6eb
Коммит
ddc24ded58
|
@ -220,6 +220,16 @@ ClippedImage::GetFrame(uint32_t aWhichFrame,
|
|||
return GetFrameInternal(mClip.Size(), Nothing(), aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
ClippedImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
// XXX(seth): It'd be nice to support downscale-during-decode for this case,
|
||||
// but right now we just fall back to the intrinsic size.
|
||||
return GetFrame(aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
ClippedImage::GetFrameInternal(const nsIntSize& aSize,
|
||||
const Maybe<SVGImageContext>& aSVGContext,
|
||||
|
|
|
@ -37,6 +37,10 @@ public:
|
|||
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrameAtSize(const gfx::IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(bool) IsImageContainerAvailable(layers::LayerManager* aManager,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||
|
|
|
@ -168,10 +168,18 @@ DynamicImage::GetFrame(uint32_t aWhichFrame,
|
|||
uint32_t aFlags)
|
||||
{
|
||||
gfxIntSize size(mDrawable->Size());
|
||||
return GetFrameAtSize(IntSize(size.width, size.height),
|
||||
aWhichFrame,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
DynamicImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenContentDrawTarget(IntSize(size.width, size.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
CreateOffscreenContentDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
|
||||
if (!dt) {
|
||||
gfxWarning() <<
|
||||
"DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
|
||||
|
@ -179,7 +187,7 @@ DynamicImage::GetFrame(uint32_t aWhichFrame,
|
|||
}
|
||||
nsRefPtr<gfxContext> context = new gfxContext(dt);
|
||||
|
||||
auto result = Draw(context, size, ImageRegion::Create(size),
|
||||
auto result = Draw(context, aSize, ImageRegion::Create(aSize),
|
||||
aWhichFrame, GraphicsFilter::FILTER_NEAREST,
|
||||
Nothing(), aFlags);
|
||||
|
||||
|
|
|
@ -44,6 +44,14 @@ FrozenImage::GetFrame(uint32_t aWhichFrame,
|
|||
return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
FrozenImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return InnerImage()->GetFrameAtSize(aSize, FRAME_FIRST, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
FrozenImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,10 @@ public:
|
|||
NS_IMETHOD GetAnimated(bool* aAnimated) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrameAtSize(const gfx::IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(bool) IsImageContainerAvailable(layers::LayerManager* aManager,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||
|
|
|
@ -174,6 +174,14 @@ ImageWrapper::GetFrame(uint32_t aWhichFrame,
|
|||
return mInnerImage->GetFrame(aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
ImageWrapper::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return mInnerImage->GetFrameAtSize(aSize, aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
ImageWrapper::IsOpaque()
|
||||
{
|
||||
|
|
|
@ -122,6 +122,16 @@ OrientedImage::GetFrame(uint32_t aWhichFrame,
|
|||
return target->Snapshot();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
OrientedImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
// XXX(seth): It'd be nice to support downscale-during-decode for this case,
|
||||
// but right now we just fall back to the intrinsic size.
|
||||
return GetFrame(aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
OrientedImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
|
||||
{
|
||||
|
|
|
@ -34,6 +34,10 @@ public:
|
|||
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<SourceSurface>)
|
||||
GetFrameAtSize(const gfx::IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(bool) IsImageContainerAvailable(layers::LayerManager* aManager,
|
||||
uint32_t aFlags) override;
|
||||
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
|
||||
|
|
|
@ -698,14 +698,28 @@ NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
|||
RasterImage::GetFrame(uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return GetFrameInternal(aWhichFrame, aFlags).second().forget();
|
||||
return GetFrameInternal(mSize, aWhichFrame, aFlags).second().forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
RasterImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return GetFrameInternal(aSize, aWhichFrame, aFlags).second().forget();
|
||||
}
|
||||
|
||||
Pair<DrawResult, RefPtr<SourceSurface>>
|
||||
RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
||||
RasterImage::GetFrameInternal(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
||||
|
||||
if (aSize.IsEmpty()) {
|
||||
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
|
||||
}
|
||||
|
||||
if (aWhichFrame > FRAME_MAX_VALUE) {
|
||||
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
|
||||
}
|
||||
|
@ -718,7 +732,7 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
|||
// not waiting for the data to be loaded from the network or not passing
|
||||
// FLAG_SYNC_DECODE
|
||||
DrawableFrameRef frameRef =
|
||||
LookupFrame(GetRequestedFrameIndex(aWhichFrame), mSize, aFlags);
|
||||
LookupFrame(GetRequestedFrameIndex(aWhichFrame), aSize, aFlags);
|
||||
if (!frameRef) {
|
||||
// The OS threw this frame away and we couldn't redecode it.
|
||||
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
|
||||
|
@ -727,15 +741,15 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
|
|||
// If this frame covers the entire image, we can just reuse its existing
|
||||
// surface.
|
||||
RefPtr<SourceSurface> frameSurf;
|
||||
IntRect frameRect = frameRef->GetRect();
|
||||
if (frameRect.x == 0 && frameRect.y == 0 &&
|
||||
frameRect.width == mSize.width &&
|
||||
frameRect.height == mSize.height) {
|
||||
if (!frameRef->NeedsPadding() &&
|
||||
frameRef->GetSize() == aSize) {
|
||||
frameSurf = frameRef->GetSurface();
|
||||
}
|
||||
|
||||
// The image doesn't have a usable surface because it's been optimized away or
|
||||
// because it's a partial update frame from an animation. Create one.
|
||||
// because it's a partial update frame from an animation. Create one. (In this
|
||||
// case we fall back to returning a surface at our intrinsic size, even if a
|
||||
// different size was originally specified.)
|
||||
if (!frameSurf) {
|
||||
frameSurf = CopyFrame(aWhichFrame, aFlags);
|
||||
}
|
||||
|
@ -756,7 +770,7 @@ RasterImage::GetCurrentImage(ImageContainer* aContainer, uint32_t aFlags)
|
|||
DrawResult drawResult;
|
||||
RefPtr<SourceSurface> surface;
|
||||
Tie(drawResult, surface) =
|
||||
GetFrameInternal(FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
|
||||
GetFrameInternal(mSize, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
|
||||
if (!surface) {
|
||||
// The OS threw out some or all of our buffer. We'll need to wait for the
|
||||
// redecode (which was automatically triggered by GetFrame) to complete.
|
||||
|
|
|
@ -265,7 +265,9 @@ private:
|
|||
uint32_t aFlags);
|
||||
|
||||
Pair<DrawResult, RefPtr<gfx::SourceSurface>>
|
||||
GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags);
|
||||
GetFrameInternal(const gfx::IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags);
|
||||
|
||||
LookupResult LookupFrameInternal(uint32_t aFrameNum,
|
||||
const gfx::IntSize& aSize,
|
||||
|
|
|
@ -668,19 +668,8 @@ VectorImage::IsOpaque()
|
|||
/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame,
|
||||
* in uint32_t aFlags; */
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
VectorImage::GetFrame(uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
VectorImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
||||
|
||||
if (aWhichFrame > FRAME_MAX_VALUE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mError || !mIsFullyLoaded) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Look up height & width
|
||||
// ----------------------
|
||||
SVGSVGElement* svgElem = mSVGDocumentWrapper->GetRootSVGElem();
|
||||
|
@ -695,12 +684,32 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return GetFrameAtSize(imageIntSize, aWhichFrame, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
|
||||
VectorImage::GetFrameAtSize(const IntSize& aSize,
|
||||
uint32_t aWhichFrame,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
||||
|
||||
if (aSize.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aWhichFrame > FRAME_MAX_VALUE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mError || !mIsFullyLoaded) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Make our surface the size of what will ultimately be drawn to it.
|
||||
// (either the full image size, or the restricted region)
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
|
||||
CreateOffscreenContentDrawTarget(IntSize(imageIntSize.width,
|
||||
imageIntSize.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
CreateOffscreenContentDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
|
||||
if (!dt) {
|
||||
NS_ERROR("Could not create a DrawTarget");
|
||||
return nullptr;
|
||||
|
@ -708,8 +717,8 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
|
|||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(dt);
|
||||
|
||||
auto result = Draw(context, imageIntSize,
|
||||
ImageRegion::Create(imageIntSize),
|
||||
auto result = Draw(context, aSize,
|
||||
ImageRegion::Create(aSize),
|
||||
aWhichFrame, GraphicsFilter::FILTER_NEAREST,
|
||||
Nothing(), aFlags);
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ native nsIntSizeByVal(nsIntSize);
|
|||
*
|
||||
* Internally, imgIContainer also manages animation of images.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(4880727a-5673-44f7-b248-f6c86e22a434)]
|
||||
[scriptable, builtinclass, uuid(4e5a0547-6c54-4051-8b52-1f2fdd667696)]
|
||||
interface imgIContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -267,6 +267,21 @@ interface imgIContainer : nsISupports
|
|||
[noscript, notxpcom] TempRefSourceSurface getFrame(in uint32_t aWhichFrame,
|
||||
in uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Get a surface for the given frame at the specified size. Matching the
|
||||
* requested size is best effort; it's not guaranteed that the surface you get
|
||||
* will be a perfect match. (Some reasons you may get a surface of a different
|
||||
* size include: if you requested upscaling, if downscale-during-decode is
|
||||
* disabled, or if you didn't request the first frame.)
|
||||
*
|
||||
* @param aSize The desired size.
|
||||
* @param aWhichFrame Frame specifier of the FRAME_* variety.
|
||||
* @param aFlags Flags of the FLAG_* variety
|
||||
*/
|
||||
[noscript, notxpcom] TempRefSourceSurface getFrameAtSize([const] in nsIntSize aSize,
|
||||
in uint32_t aWhichFrame,
|
||||
in uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Whether this image is opaque (i.e., needs a background painted behind it).
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче