зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1368776 - Part 13. Make ImageResource::GetFrameInternal also return the suggested size for the lookup. r=tnikkel
This commit is contained in:
Родитель
2463bc3782
Коммит
a1d47a973a
|
@ -62,8 +62,9 @@ ImageResource::AddCurrentImage(ImageContainer* aContainer,
|
||||||
MOZ_ASSERT(aContainer);
|
MOZ_ASSERT(aContainer);
|
||||||
|
|
||||||
DrawResult drawResult;
|
DrawResult drawResult;
|
||||||
|
IntSize size;
|
||||||
RefPtr<SourceSurface> surface;
|
RefPtr<SourceSurface> surface;
|
||||||
Tie(drawResult, surface) =
|
Tie(drawResult, size, surface) =
|
||||||
GetFrameInternal(aSize, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
|
GetFrameInternal(aSize, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
// The OS threw out some or all of our buffer. We'll need to wait for the
|
// The OS threw out some or all of our buffer. We'll need to wait for the
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
#define mozilla_image_Image_h
|
#define mozilla_image_Image_h
|
||||||
|
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Pair.h"
|
#include "mozilla/Tuple.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "gfx2DGlue.h"
|
#include "gfx2DGlue.h"
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "ImageURL.h"
|
#include "ImageURL.h"
|
||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
|
#include "LookupResult.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
#include "ProgressTracker.h"
|
#include "ProgressTracker.h"
|
||||||
#include "SurfaceCache.h"
|
#include "SurfaceCache.h"
|
||||||
|
@ -336,12 +337,13 @@ protected:
|
||||||
bool mAnimating:1; // Are we currently animating?
|
bool mAnimating:1; // Are we currently animating?
|
||||||
bool mError:1; // Error handling
|
bool mError:1; // Error handling
|
||||||
|
|
||||||
virtual Pair<DrawResult, RefPtr<gfx::SourceSurface>>
|
virtual Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
|
||||||
GetFrameInternal(const gfx::IntSize& aSize,
|
GetFrameInternal(const gfx::IntSize& aSize,
|
||||||
uint32_t aWhichFrame,
|
uint32_t aWhichFrame,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags)
|
||||||
{
|
{
|
||||||
return MakePair(DrawResult::BAD_IMAGE, RefPtr<gfx::SourceSurface>());
|
return MakeTuple(DrawResult::BAD_IMAGE, aSize,
|
||||||
|
RefPtr<gfx::SourceSurface>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -102,6 +102,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LookupResult(const LookupResult&) = delete;
|
LookupResult(const LookupResult&) = delete;
|
||||||
|
LookupResult& operator=(const LookupResult& aOther) = delete;
|
||||||
|
|
||||||
DrawableSurface mSurface;
|
DrawableSurface mSurface;
|
||||||
MatchType mMatchType;
|
MatchType mMatchType;
|
||||||
|
|
|
@ -324,7 +324,7 @@ RasterImage::LookupFrameInternal(const IntSize& aSize,
|
||||||
PlaybackType::eStatic));
|
PlaybackType::eStatic));
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawableSurface
|
LookupResult
|
||||||
RasterImage::LookupFrame(const IntSize& aSize,
|
RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType)
|
PlaybackType aPlaybackType)
|
||||||
|
@ -340,7 +340,8 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
|
IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
|
||||||
? aSize : mSize;
|
? aSize : mSize;
|
||||||
if (requestedSize.IsEmpty()) {
|
if (requestedSize.IsEmpty()) {
|
||||||
return DrawableSurface(); // Can't decode to a surface of zero size.
|
// Can't decode to a surface of zero size.
|
||||||
|
return LookupResult(MatchType::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult result =
|
LookupResult result =
|
||||||
|
@ -348,7 +349,7 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
|
|
||||||
if (!result && !mHasSize) {
|
if (!result && !mHasSize) {
|
||||||
// We can't request a decode without knowing our intrinsic size. Give up.
|
// We can't request a decode without knowing our intrinsic size. Give up.
|
||||||
return DrawableSurface();
|
return LookupResult(MatchType::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Type() == MatchType::NOT_FOUND ||
|
if (result.Type() == MatchType::NOT_FOUND ||
|
||||||
|
@ -380,11 +381,12 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// We still weren't able to get a frame. Give up.
|
// We still weren't able to get a frame. Give up.
|
||||||
return DrawableSurface();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Surface()->GetCompositingFailed()) {
|
if (result.Surface()->GetCompositingFailed()) {
|
||||||
return DrawableSurface();
|
DrawableSurface tmp = Move(result.Surface());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!result.Surface()->GetIsPaletted(),
|
MOZ_ASSERT(!result.Surface()->GetIsPaletted(),
|
||||||
|
@ -403,10 +405,11 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
||||||
// IsAborted acquires the monitor for the imgFrame.
|
// IsAborted acquires the monitor for the imgFrame.
|
||||||
if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) &&
|
if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) &&
|
||||||
result.Surface()->IsAborted()) {
|
result.Surface()->IsAborted()) {
|
||||||
return DrawableSurface();
|
DrawableSurface tmp = Move(result.Surface());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Move(result.Surface());
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -569,55 +572,62 @@ RasterImage::GetFrameAtSize(const IntSize& aSize,
|
||||||
uint32_t aWhichFrame,
|
uint32_t aWhichFrame,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NotifyDrawingObservers();
|
NotifyDrawingObservers();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RefPtr<SourceSurface> surf =
|
auto result = GetFrameInternal(aSize, aWhichFrame, aFlags);
|
||||||
GetFrameInternal(aSize, aWhichFrame, aFlags).second().forget();
|
RefPtr<SourceSurface> surf = mozilla::Get<2>(result).forget();
|
||||||
|
|
||||||
// If we are here, it suggests the image is embedded in a canvas or some
|
// If we are here, it suggests the image is embedded in a canvas or some
|
||||||
// other path besides layers, and we won't need the file handle.
|
// other path besides layers, and we won't need the file handle.
|
||||||
MarkSurfaceShared(surf);
|
MarkSurfaceShared(surf);
|
||||||
return surf.forget();
|
return surf.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<DrawResult, RefPtr<SourceSurface>>
|
Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
|
||||||
RasterImage::GetFrameInternal(const IntSize& aSize,
|
RasterImage::GetFrameInternal(const IntSize& aSize,
|
||||||
uint32_t aWhichFrame,
|
uint32_t aWhichFrame,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
|
||||||
|
|
||||||
if (aSize.IsEmpty()) {
|
if (aSize.IsEmpty() || aWhichFrame > FRAME_MAX_VALUE) {
|
||||||
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
|
return MakeTuple(DrawResult::BAD_ARGS, aSize,
|
||||||
}
|
RefPtr<SourceSurface>());
|
||||||
|
|
||||||
if (aWhichFrame > FRAME_MAX_VALUE) {
|
|
||||||
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mError) {
|
if (mError) {
|
||||||
return MakePair(DrawResult::BAD_IMAGE, RefPtr<SourceSurface>());
|
return MakeTuple(DrawResult::BAD_IMAGE, aSize,
|
||||||
|
RefPtr<SourceSurface>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the frame. If it's not there, it's probably the caller's fault for
|
// Get the frame. If it's not there, it's probably the caller's fault for
|
||||||
// not waiting for the data to be loaded from the network or not passing
|
// not waiting for the data to be loaded from the network or not passing
|
||||||
// FLAG_SYNC_DECODE.
|
// FLAG_SYNC_DECODE.
|
||||||
DrawableSurface surface =
|
LookupResult result =
|
||||||
LookupFrame(aSize, aFlags, ToPlaybackType(aWhichFrame));
|
LookupFrame(aSize, aFlags, ToPlaybackType(aWhichFrame));
|
||||||
if (!surface) {
|
|
||||||
|
// The surface cache may have suggested we use a different size than the
|
||||||
|
// given size in the future. This may or may not be accompanied by an
|
||||||
|
// actual surface, depending on what it has in its cache.
|
||||||
|
IntSize suggestedSize = result.SuggestedSize().IsEmpty()
|
||||||
|
? aSize : result.SuggestedSize();
|
||||||
|
MOZ_ASSERT_IF(result.Type() == MatchType::SUBSTITUTE_BECAUSE_BEST,
|
||||||
|
suggestedSize != aSize);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
// The OS threw this frame away and we couldn't redecode it.
|
// The OS threw this frame away and we couldn't redecode it.
|
||||||
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
|
return MakeTuple(DrawResult::TEMPORARY_ERROR, suggestedSize,
|
||||||
|
RefPtr<SourceSurface>());
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<SourceSurface> sourceSurface = surface->GetSourceSurface();
|
RefPtr<SourceSurface> surface = result.Surface()->GetSourceSurface();
|
||||||
|
if (!result.Surface()->IsFinished()) {
|
||||||
if (!surface->IsFinished()) {
|
return MakeTuple(DrawResult::INCOMPLETE, suggestedSize, Move(surface));
|
||||||
return MakePair(DrawResult::INCOMPLETE, Move(sourceSurface));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MakePair(DrawResult::SUCCESS, Move(sourceSurface));
|
return MakeTuple(DrawResult::SUCCESS, suggestedSize, Move(surface));
|
||||||
}
|
}
|
||||||
|
|
||||||
IntSize
|
IntSize
|
||||||
|
@ -1149,8 +1159,10 @@ RasterImage::RequestDecodeForSizeInternal(const IntSize& aSize, uint32_t aFlags)
|
||||||
: aFlags & ~FLAG_SYNC_DECODE_IF_FAST;
|
: aFlags & ~FLAG_SYNC_DECODE_IF_FAST;
|
||||||
|
|
||||||
// Perform a frame lookup, which will implicitly start decoding if needed.
|
// Perform a frame lookup, which will implicitly start decoding if needed.
|
||||||
return LookupFrame(aSize, flags, mAnimationState ? PlaybackType::eAnimated
|
PlaybackType playbackType = mAnimationState ? PlaybackType::eAnimated
|
||||||
: PlaybackType::eStatic);
|
: PlaybackType::eStatic;
|
||||||
|
LookupResult result = LookupFrame(aSize, flags, playbackType);
|
||||||
|
return Move(result.Surface());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1443,9 +1455,9 @@ RasterImage::Draw(gfxContext* aContext,
|
||||||
? aFlags
|
? aFlags
|
||||||
: aFlags & ~FLAG_HIGH_QUALITY_SCALING;
|
: aFlags & ~FLAG_HIGH_QUALITY_SCALING;
|
||||||
|
|
||||||
DrawableSurface surface =
|
LookupResult result =
|
||||||
LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame));
|
LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame));
|
||||||
if (!surface) {
|
if (!result) {
|
||||||
// Getting the frame (above) touches the image and kicks off decoding.
|
// Getting the frame (above) touches the image and kicks off decoding.
|
||||||
if (mDrawStartTime.IsNull()) {
|
if (mDrawStartTime.IsNull()) {
|
||||||
mDrawStartTime = TimeStamp::Now();
|
mDrawStartTime = TimeStamp::Now();
|
||||||
|
@ -1454,10 +1466,10 @@ RasterImage::Draw(gfxContext* aContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldRecordTelemetry = !mDrawStartTime.IsNull() &&
|
bool shouldRecordTelemetry = !mDrawStartTime.IsNull() &&
|
||||||
surface->IsFinished();
|
result.Surface()->IsFinished();
|
||||||
|
|
||||||
auto result = DrawInternal(Move(surface), aContext, aSize,
|
auto drawResult = DrawInternal(Move(result.Surface()), aContext, aSize,
|
||||||
aRegion, aSamplingFilter, flags, aOpacity);
|
aRegion, aSamplingFilter, flags, aOpacity);
|
||||||
|
|
||||||
if (shouldRecordTelemetry) {
|
if (shouldRecordTelemetry) {
|
||||||
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
|
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
|
||||||
|
@ -1471,7 +1483,7 @@ RasterImage::Draw(gfxContext* aContext,
|
||||||
mDrawStartTime = TimeStamp();
|
mDrawStartTime = TimeStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return drawResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
#include "mozilla/Pair.h"
|
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "mozilla/WeakPtr.h"
|
#include "mozilla/WeakPtr.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
@ -291,9 +290,9 @@ private:
|
||||||
* @return a drawable surface, which may be empty if the requested surface
|
* @return a drawable surface, which may be empty if the requested surface
|
||||||
* could not be found.
|
* could not be found.
|
||||||
*/
|
*/
|
||||||
DrawableSurface LookupFrame(const gfx::IntSize& aSize,
|
LookupResult LookupFrame(const gfx::IntSize& aSize,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
PlaybackType aPlaybackType);
|
PlaybackType aPlaybackType);
|
||||||
|
|
||||||
/// Helper method for LookupFrame().
|
/// Helper method for LookupFrame().
|
||||||
LookupResult LookupFrameInternal(const gfx::IntSize& aSize,
|
LookupResult LookupFrameInternal(const gfx::IntSize& aSize,
|
||||||
|
@ -308,7 +307,7 @@ private:
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
float aOpacity);
|
float aOpacity);
|
||||||
|
|
||||||
Pair<DrawResult, RefPtr<gfx::SourceSurface>>
|
Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
|
||||||
GetFrameInternal(const gfx::IntSize& aSize,
|
GetFrameInternal(const gfx::IntSize& aSize,
|
||||||
uint32_t aWhichFrame,
|
uint32_t aWhichFrame,
|
||||||
uint32_t aFlags) override;
|
uint32_t aFlags) override;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче