Bug 1210553 - Remove the alternate flags arguments from SurfaceCache's Lookup functions. r=dholbert

This commit is contained in:
Seth Fowler 2015-10-05 17:06:34 -07:00
parent 02723e0858
commit b4f7779368
3 changed files with 43 additions and 77 deletions

View File

@ -288,31 +288,22 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum,
return mAnim->GetCompositedFrame(aFrameNum);
}
Maybe<SurfaceFlags> alternateFlags;
if (IsOpaque()) {
// If we're opaque, we can always substitute a frame that was decoded with a
// different decode flag for premultiplied alpha, because that can only
// matter for frames with transparency.
alternateFlags.emplace(ToSurfaceFlags(aFlags) ^
SurfaceFlags::NO_PREMULTIPLY_ALPHA);
}
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
// We don't want any substitution for sync decodes (except the premultiplied
// alpha optimization above), so we use SurfaceCache::Lookup in this case.
// We don't want any substitution for sync decodes, so we use
// SurfaceCache::Lookup in this case.
if (aFlags & FLAG_SYNC_DECODE) {
return SurfaceCache::Lookup(ImageKey(this),
RasterSurfaceKey(aSize,
ToSurfaceFlags(aFlags),
aFrameNum),
alternateFlags);
surfaceFlags,
aFrameNum));
}
// We'll return the best match we can find to the requested frame.
return SurfaceCache::LookupBestMatch(ImageKey(this),
RasterSurfaceKey(aSize,
ToSurfaceFlags(aFlags),
aFrameNum),
alternateFlags);
surfaceFlags,
aFrameNum));
}
DrawableFrameRef
@ -322,6 +313,12 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
{
MOZ_ASSERT(NS_IsMainThread());
// If we're opaque, we don't need to care about premultiplied alpha, because
// that can only matter for frames with transparency.
if (IsOpaque()) {
aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
}
IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
? aSize : mSize;
@ -1285,16 +1282,23 @@ RasterImage::Decode(const IntSize& aSize, uint32_t aFlags)
decoderFlags |= DecoderFlags::IS_REDECODE;
}
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
if (IsOpaque()) {
// If there's no transparency, it doesn't matter whether we premultiply
// alpha or not.
surfaceFlags &= ~SurfaceFlags::NO_PREMULTIPLY_ALPHA;
}
// Create a decoder.
nsRefPtr<Decoder> decoder;
if (mAnim) {
decoder = DecoderFactory::CreateAnimationDecoder(mDecoderType, this,
mSourceBuffer, decoderFlags,
ToSurfaceFlags(aFlags));
surfaceFlags);
} else {
decoder = DecoderFactory::CreateDecoder(mDecoderType, this, mSourceBuffer,
targetSize, decoderFlags,
ToSurfaceFlags(aFlags),
surfaceFlags,
mRequestedSampleSize);
}

View File

@ -276,8 +276,7 @@ public:
}
Pair<already_AddRefed<CachedSurface>, MatchType>
LookupBestMatch(const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags)
LookupBestMatch(const SurfaceKey& aSurfaceKey)
{
// Try for an exact match first.
nsRefPtr<CachedSurface> exactMatch;
@ -287,7 +286,7 @@ public:
}
// There's no perfect match, so find the best match we can.
MatchContext matchContext(aSurfaceKey, aAlternateFlags);
MatchContext matchContext(aSurfaceKey);
ForEach(TryToImproveMatch, &matchContext);
MatchType matchType;
@ -328,14 +327,11 @@ public:
private:
struct MatchContext
{
MatchContext(const SurfaceKey& aIdealKey,
const Maybe<SurfaceFlags>& aAlternateFlags)
explicit MatchContext(const SurfaceKey& aIdealKey)
: mIdealKey(aIdealKey)
, mAlternateFlags(aAlternateFlags)
{ }
const SurfaceKey& mIdealKey;
const Maybe<SurfaceFlags> mAlternateFlags;
nsRefPtr<CachedSurface> mBestMatch;
};
@ -357,10 +353,8 @@ private:
return PL_DHASH_NEXT;
}
// Matching the flags is required, but we can match the alternate flags as
// well if some were provided.
if (aSurfaceKey.Flags() != idealKey.Flags() &&
Some(aSurfaceKey.Flags()) != context->mAlternateFlags) {
// Matching the flags is required.
if (aSurfaceKey.Flags() != idealKey.Flags()) {
return PL_DHASH_NEXT;
}
@ -636,8 +630,7 @@ public:
}
LookupResult LookupBestMatch(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags)
const SurfaceKey& aSurfaceKey)
{
nsRefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache) {
@ -655,8 +648,7 @@ public:
DrawableFrameRef ref;
MatchType matchType = MatchType::NOT_FOUND;
while (true) {
Tie(surface, matchType) =
cache->LookupBestMatch(aSurfaceKey, aAlternateFlags);
Tie(surface, matchType) = cache->LookupBestMatch(aSurfaceKey);
if (!surface) {
return LookupResult(matchType); // Lookup in the per-image cache missed.
@ -672,12 +664,13 @@ public:
Remove(surface);
}
MOZ_ASSERT((matchType == MatchType::EXACT) ==
(surface->GetSurfaceKey() == aSurfaceKey ||
(aAlternateFlags &&
surface->GetSurfaceKey() ==
aSurfaceKey.WithNewFlags(*aAlternateFlags))),
"Result differs in a way other than size or alternate flags");
MOZ_ASSERT_IF(matchType == MatchType::EXACT,
surface->GetSurfaceKey() == aSurfaceKey);
MOZ_ASSERT_IF(matchType == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND ||
matchType == MatchType::SUBSTITUTE_BECAUSE_PENDING,
surface->GetSurfaceKey().SVGContext() == aSurfaceKey.SVGContext() &&
surface->GetSurfaceKey().AnimationTime() == aSurfaceKey.AnimationTime() &&
surface->GetSurfaceKey().Flags() == aSurfaceKey.Flags());
if (matchType == MatchType::EXACT) {
MarkUsed(surface, cache);
@ -1050,37 +1043,26 @@ SurfaceCache::Shutdown()
/* static */ LookupResult
SurfaceCache::Lookup(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags
/* = Nothing() */)
const SurfaceKey& aSurfaceKey)
{
if (!sInstance) {
return LookupResult(MatchType::NOT_FOUND);
}
MutexAutoLock lock(sInstance->GetMutex());
LookupResult result = sInstance->Lookup(aImageKey, aSurfaceKey);
if (!result && aAlternateFlags) {
result = sInstance->Lookup(aImageKey,
aSurfaceKey.WithNewFlags(*aAlternateFlags));
}
return result;
return sInstance->Lookup(aImageKey, aSurfaceKey);
}
/* static */ LookupResult
SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags
/* = Nothing() */)
const SurfaceKey& aSurfaceKey)
{
if (!sInstance) {
return LookupResult(MatchType::NOT_FOUND);
}
MutexAutoLock lock(sInstance->GetMutex());
return sInstance->LookupBestMatch(aImageKey, aSurfaceKey, aAlternateFlags);
return sInstance->LookupBestMatch(aImageKey, aSurfaceKey);
}
/* static */ InsertOutcome

View File

@ -69,11 +69,6 @@ public:
float AnimationTime() const { return mAnimationTime; }
SurfaceFlags Flags() const { return mFlags; }
SurfaceKey WithNewFlags(SurfaceFlags aFlags) const
{
return SurfaceKey(mSize, mSVGContext, mAnimationTime, aFlags);
}
private:
SurfaceKey(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
@ -181,38 +176,25 @@ struct SurfaceCache
* @param aSurfaceKey Key data which uniquely identifies the requested
* surface.
*
* @param aAlternateFlags If not Nothing(), a different set of flags than the
* ones specified in @aSurfaceKey which are also
* acceptable to the caller. This is more efficient
* than calling Lookup() twice, which requires taking a
* lock each time.
*
* @return a LookupResult, which will either contain a
* DrawableFrameRef to the requested surface, or an
* empty DrawableFrameRef if the surface was not found.
*/
static LookupResult Lookup(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags
= Nothing());
const SurfaceKey& aSurfaceKey);
/**
* Looks up the best matching surface in the cache and returns a drawable
* reference to the imgFrame containing it.
*
* Returned surfaces may vary from the requested surface only in terms of
* size, unless @aAlternateFlags is specified.
* size.
*
* @param aImageKey Key data identifying which image the surface belongs
* to.
*
* @param aSurfaceKey Key data which identifies the ideal surface to return.
*
* @param aAlternateFlags If not Nothing(), a different set of flags than the
* ones specified in @aSurfaceKey which are also
* acceptable to the caller. This is much more
* efficient than calling LookupBestMatch() twice.
*
* @return a LookupResult, which will either contain a
* DrawableFrameRef to a surface similar to the
* requested surface, or an empty DrawableFrameRef if
@ -221,9 +203,7 @@ struct SurfaceCache
* returned surface exactly matches @aSurfaceKey.
*/
static LookupResult LookupBestMatch(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const Maybe<SurfaceFlags>& aAlternateFlags
= Nothing());
const SurfaceKey& aSurfaceKey);
/**
* Insert a surface into the cache. If a surface with the same ImageKey and