Bug 1368776 - Part 13. Make ImageResource::GetFrameInternal also return the suggested size for the lookup. r=tnikkel

This commit is contained in:
Andrew Osmond 2017-11-17 06:45:27 -05:00
Родитель 2463bc3782
Коммит a1d47a973a
5 изменённых файлов: 58 добавлений и 43 удалений

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

@ -62,8 +62,9 @@ ImageResource::AddCurrentImage(ImageContainer* aContainer,
MOZ_ASSERT(aContainer);
DrawResult drawResult;
IntSize size;
RefPtr<SourceSurface> surface;
Tie(drawResult, surface) =
Tie(drawResult, size, surface) =
GetFrameInternal(aSize, 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

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

@ -7,12 +7,13 @@
#define mozilla_image_Image_h
#include "mozilla/MemoryReporting.h"
#include "mozilla/Pair.h"
#include "mozilla/Tuple.h"
#include "mozilla/TimeStamp.h"
#include "gfx2DGlue.h"
#include "imgIContainer.h"
#include "ImageURL.h"
#include "ImageContainer.h"
#include "LookupResult.h"
#include "nsStringFwd.h"
#include "ProgressTracker.h"
#include "SurfaceCache.h"
@ -336,12 +337,13 @@ protected:
bool mAnimating:1; // Are we currently animating?
bool mError:1; // Error handling
virtual Pair<DrawResult, RefPtr<gfx::SourceSurface>>
virtual Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
GetFrameInternal(const gfx::IntSize& aSize,
uint32_t aWhichFrame,
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:
LookupResult(const LookupResult&) = delete;
LookupResult& operator=(const LookupResult& aOther) = delete;
DrawableSurface mSurface;
MatchType mMatchType;

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

@ -324,7 +324,7 @@ RasterImage::LookupFrameInternal(const IntSize& aSize,
PlaybackType::eStatic));
}
DrawableSurface
LookupResult
RasterImage::LookupFrame(const IntSize& aSize,
uint32_t aFlags,
PlaybackType aPlaybackType)
@ -340,7 +340,8 @@ RasterImage::LookupFrame(const IntSize& aSize,
IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
? aSize : mSize;
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 =
@ -348,7 +349,7 @@ RasterImage::LookupFrame(const IntSize& aSize,
if (!result && !mHasSize) {
// 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 ||
@ -380,11 +381,12 @@ RasterImage::LookupFrame(const IntSize& aSize,
if (!result) {
// We still weren't able to get a frame. Give up.
return DrawableSurface();
return result;
}
if (result.Surface()->GetCompositingFailed()) {
return DrawableSurface();
DrawableSurface tmp = Move(result.Surface());
return result;
}
MOZ_ASSERT(!result.Surface()->GetIsPaletted(),
@ -403,10 +405,11 @@ RasterImage::LookupFrame(const IntSize& aSize,
// IsAborted acquires the monitor for the imgFrame.
if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) &&
result.Surface()->IsAborted()) {
return DrawableSurface();
DrawableSurface tmp = Move(result.Surface());
return result;
}
return Move(result.Surface());
return result;
}
bool
@ -569,55 +572,62 @@ RasterImage::GetFrameAtSize(const IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags)
{
#ifdef DEBUG
NotifyDrawingObservers();
#endif
RefPtr<SourceSurface> surf =
GetFrameInternal(aSize, aWhichFrame, aFlags).second().forget();
auto result = GetFrameInternal(aSize, 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
// other path besides layers, and we won't need the file handle.
MarkSurfaceShared(surf);
return surf.forget();
}
Pair<DrawResult, RefPtr<SourceSurface>>
Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
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>());
if (aSize.IsEmpty() || aWhichFrame > FRAME_MAX_VALUE) {
return MakeTuple(DrawResult::BAD_ARGS, aSize,
RefPtr<SourceSurface>());
}
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
// not waiting for the data to be loaded from the network or not passing
// FLAG_SYNC_DECODE.
DrawableSurface surface =
LookupResult result =
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.
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
return MakeTuple(DrawResult::TEMPORARY_ERROR, suggestedSize,
RefPtr<SourceSurface>());
}
RefPtr<SourceSurface> sourceSurface = surface->GetSourceSurface();
if (!surface->IsFinished()) {
return MakePair(DrawResult::INCOMPLETE, Move(sourceSurface));
RefPtr<SourceSurface> surface = result.Surface()->GetSourceSurface();
if (!result.Surface()->IsFinished()) {
return MakeTuple(DrawResult::INCOMPLETE, suggestedSize, Move(surface));
}
return MakePair(DrawResult::SUCCESS, Move(sourceSurface));
return MakeTuple(DrawResult::SUCCESS, suggestedSize, Move(surface));
}
IntSize
@ -1149,8 +1159,10 @@ RasterImage::RequestDecodeForSizeInternal(const IntSize& aSize, uint32_t aFlags)
: aFlags & ~FLAG_SYNC_DECODE_IF_FAST;
// Perform a frame lookup, which will implicitly start decoding if needed.
return LookupFrame(aSize, flags, mAnimationState ? PlaybackType::eAnimated
: PlaybackType::eStatic);
PlaybackType playbackType = mAnimationState ? PlaybackType::eAnimated
: PlaybackType::eStatic;
LookupResult result = LookupFrame(aSize, flags, playbackType);
return Move(result.Surface());
}
static bool
@ -1443,9 +1455,9 @@ RasterImage::Draw(gfxContext* aContext,
? aFlags
: aFlags & ~FLAG_HIGH_QUALITY_SCALING;
DrawableSurface surface =
LookupResult result =
LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame));
if (!surface) {
if (!result) {
// Getting the frame (above) touches the image and kicks off decoding.
if (mDrawStartTime.IsNull()) {
mDrawStartTime = TimeStamp::Now();
@ -1454,10 +1466,10 @@ RasterImage::Draw(gfxContext* aContext,
}
bool shouldRecordTelemetry = !mDrawStartTime.IsNull() &&
surface->IsFinished();
result.Surface()->IsFinished();
auto result = DrawInternal(Move(surface), aContext, aSize,
aRegion, aSamplingFilter, flags, aOpacity);
auto drawResult = DrawInternal(Move(result.Surface()), aContext, aSize,
aRegion, aSamplingFilter, flags, aOpacity);
if (shouldRecordTelemetry) {
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
@ -1471,7 +1483,7 @@ RasterImage::Draw(gfxContext* aContext,
mDrawStartTime = TimeStamp();
}
return result;
return drawResult;
}
//******************************************************************************

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

@ -35,7 +35,6 @@
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/NotNull.h"
#include "mozilla/Pair.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/UniquePtr.h"
@ -291,9 +290,9 @@ private:
* @return a drawable surface, which may be empty if the requested surface
* could not be found.
*/
DrawableSurface LookupFrame(const gfx::IntSize& aSize,
uint32_t aFlags,
PlaybackType aPlaybackType);
LookupResult LookupFrame(const gfx::IntSize& aSize,
uint32_t aFlags,
PlaybackType aPlaybackType);
/// Helper method for LookupFrame().
LookupResult LookupFrameInternal(const gfx::IntSize& aSize,
@ -308,7 +307,7 @@ private:
uint32_t aFlags,
float aOpacity);
Pair<DrawResult, RefPtr<gfx::SourceSurface>>
Tuple<DrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
GetFrameInternal(const gfx::IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags) override;