Bug 1370412 - Part 8a. Add "substitutable" flag to ISurfaceProvider state to indicate when the caller won't accept substitutes. r=tnikkel

When SurfaceCache::Lookup is called to access surface data, it indicates
that the caller will not accept substitutes as in the case of
SurfaceCache::LookupBestMatch. As such, we need to be careful not to
remove those surfaces from our cache when pruning (in part 8b). This is
the marker used to track that, at some point, there was a caller which
got this surface that would accept no other (e.g. factor of 2 mode must
make an accept for this particular surface).
This commit is contained in:
Andrew Osmond 2017-09-05 07:58:45 -04:00
parent ee46542020
commit 186b24b666
4 changed files with 31 additions and 3 deletions

View File

@ -145,6 +145,9 @@ DecoderFactory::CreateDecoder(DecoderType aType,
WrapNotNull(new DecodedSurfaceProvider(aImage,
surfaceKey,
WrapNotNull(decoder)));
if (aDecoderFlags & DecoderFlags::CANNOT_SUBSTITUTE) {
provider->Availability().SetCannotSubstitute();
}
// Attempt to insert the surface provider into the surface cache right away so
// we won't trigger any more decoders with the same parameters.

View File

@ -23,7 +23,15 @@ enum class DecoderFlags : uint8_t
FIRST_FRAME_ONLY = 1 << 0,
IS_REDECODE = 1 << 1,
IMAGE_IS_TRANSIENT = 1 << 2,
ASYNC_NOTIFY = 1 << 3
ASYNC_NOTIFY = 1 << 3,
/**
* By default, a surface is considered substitutable. That means callers are
* willing to accept a less than ideal match to display. If a caller requires
* a specific size and won't accept alternatives, then this flag should be
* set.
*/
CANNOT_SUBSTITUTE = 1 << 4
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DecoderFlags)

View File

@ -1286,6 +1286,12 @@ RasterImage::Decode(const IntSize& aSize,
if (mHasBeenDecoded) {
decoderFlags |= DecoderFlags::IS_REDECODE;
}
if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
// Used SurfaceCache::Lookup instead of SurfaceCache::LookupBestMatch. That
// means the caller can handle a differently sized surface to be returned
// at any point.
decoderFlags |= DecoderFlags::CANNOT_SUBSTITUTE;
}
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
if (IsOpaque()) {

View File

@ -134,6 +134,10 @@ VectorSurfaceKey(const gfx::IntSize& aSize,
* changes), an ISurfaceProvider which starts as a placeholder can only reveal
* the fact that it now has a surface available via a call to
* SurfaceCache::SurfaceAvailable().
*
* It also tracks whether or not there are "explicit" users of this surface
* which will not accept substitutes. This is used by SurfaceCache when pruning
* unnecessary surfaces from the cache.
*/
class AvailabilityState
{
@ -143,15 +147,22 @@ public:
bool IsAvailable() const { return mIsAvailable; }
bool IsPlaceholder() const { return !mIsAvailable; }
bool CannotSubstitute() const { return mCannotSubstitute; }
void SetCannotSubstitute() { mCannotSubstitute = true; }
private:
friend class SurfaceCacheImpl;
explicit AvailabilityState(bool aIsAvailable) : mIsAvailable(aIsAvailable) { }
explicit AvailabilityState(bool aIsAvailable)
: mIsAvailable(aIsAvailable)
, mCannotSubstitute(false)
{ }
void SetAvailable() { mIsAvailable = true; }
bool mIsAvailable;
bool mIsAvailable : 1;
bool mCannotSubstitute : 1;
};
enum class InsertOutcome : uint8_t {