зеркало из 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);
|
||||
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче