Backed out 3 changesets (bug 1456558) for crashtest assertion failures on a CLOSED TREE

Backed out changeset 70d8f11cf6e8 (bug 1456558)
Backed out changeset af9fc3daf97c (bug 1456558)
Backed out changeset f209a9d848f4 (bug 1456558)
This commit is contained in:
Andreea Pavel 2018-09-21 02:13:41 +03:00
Родитель 73e08d1bf5
Коммит 3805f6a285
11 изменённых файлов: 88 добавлений и 261 удалений

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

@ -546,7 +546,6 @@ private:
DECL_GFX_PREF(Live, "image.animated.generate-full-frames", ImageAnimatedGenerateFullFrames, bool, false);
DECL_GFX_PREF(Live, "image.animated.resume-from-last-displayed", ImageAnimatedResumeFromLastDisplayed, bool, false);
DECL_GFX_PREF(Live, "image.cache.factor2.threshold-surfaces", ImageCacheFactor2ThresholdSurfaces, int32_t, -1);
DECL_GFX_PREF(Live, "image.cache.max-rasterized-svg-threshold-kb", ImageCacheMaxRasterizedSVGThresholdKB, int32_t, 90*1024);
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false);

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

@ -160,7 +160,6 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
case ImgDrawResult::SUCCESS:
case ImgDrawResult::BAD_IMAGE:
case ImgDrawResult::BAD_ARGS:
case ImgDrawResult::NOT_SUPPORTED:
container.forget(aOutContainer);
return entry->mLastDrawResult;
case ImgDrawResult::NOT_READY:
@ -219,7 +218,6 @@ ImageResource::GetImageContainerImpl(LayerManager* aManager,
case ImgDrawResult::SUCCESS:
case ImgDrawResult::BAD_IMAGE:
case ImgDrawResult::BAD_ARGS:
case ImgDrawResult::NOT_SUPPORTED:
container.forget(aOutContainer);
return entry->mLastDrawResult;
case ImgDrawResult::NOT_READY:

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

@ -337,24 +337,6 @@ protected:
bool mAnimating:1; // Are we currently animating?
bool mError:1; // Error handling
/**
* Attempt to find a matching cached surface in the SurfaceCache, and if not
* available, request the production of such a surface (either synchronously
* or asynchronously).
*
* If the draw result is BAD_IMAGE, BAD_ARGS or NOT_READY, the size will be
* the same as aSize. If it is TEMPORARY_ERROR, INCOMPLETE, or SUCCESS, the
* size is a hint as to what we expect the surface size to be, once the best
* fitting size is available. It may or may not match the size of the surface
* returned at this moment. This is useful for choosing how to store the final
* result (e.g. if going into an ImageContainer, ideally we would share the
* same container for many requested sizes, if they all end up with the same
* best fit size in the end).
*
* A valid surface should only be returned for SUCCESS and INCOMPLETE.
*
* Any other draw result is invalid.
*/
virtual Tuple<ImgDrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
GetFrameInternal(const gfx::IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,

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

@ -109,11 +109,8 @@ private:
DrawableSurface mSurface;
MatchType mMatchType;
/// mSuggestedSize will be the size of the returned surface if the result is
/// SUBSTITUTE_BECAUSE_BEST. It will be empty for EXACT, and can contain a
/// non-empty size possibly different from the returned surface (if any) for
/// all other results. If non-empty, it will always be the size the caller
/// should request any decodes at.
/// If given, the size the caller should request a decode at. This may or may
/// not match the size the caller requested from the cache.
gfx::IntSize mSuggestedSize;
};

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

@ -24,8 +24,7 @@ struct SVGDrawingParameters
typedef mozilla::gfx::SamplingFilter SamplingFilter;
SVGDrawingParameters(gfxContext* aContext,
const nsIntSize& aRasterSize,
const nsIntSize& aDrawSize,
const nsIntSize& aSize,
const ImageRegion& aRegion,
SamplingFilter aSamplingFilter,
const Maybe<SVGImageContext>& aSVGContext,
@ -33,12 +32,11 @@ struct SVGDrawingParameters
uint32_t aFlags,
float aOpacity)
: context(aContext)
, size(aRasterSize)
, drawSize(aDrawSize)
, size(aSize.width, aSize.height)
, region(aRegion)
, samplingFilter(aSamplingFilter)
, svgContext(aSVGContext)
, viewportSize(aRasterSize)
, viewportSize(aSize)
, animationTime(aAnimationTime)
, flags(aFlags)
, opacity(aOpacity)
@ -52,8 +50,7 @@ struct SVGDrawingParameters
}
gfxContext* context;
IntSize size; // Size to rasterize a surface at.
IntSize drawSize; // Size to draw the given surface at.
IntSize size;
ImageRegion region;
SamplingFilter samplingFilter;
const Maybe<SVGImageContext>& svgContext;

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

@ -12,7 +12,6 @@
#include <algorithm>
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h"
#include "mozilla/Move.h"
@ -252,11 +251,10 @@ class ImageSurfaceCache
{
~ImageSurfaceCache() { }
public:
explicit ImageSurfaceCache(const ImageKey aImageKey)
ImageSurfaceCache()
: mLocked(false)
, mFactor2Mode(false)
, mFactor2Pruned(false)
, mIsVectorImage(aImageKey->GetType() == imgIContainer::TYPE_VECTOR)
{ }
MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache)
@ -332,7 +330,7 @@ public:
// Try for a best match second, if using compact.
IntSize suggestedSize = SuggestedSize(aIdealKey.Size());
if (suggestedSize != aIdealKey.Size()) {
if (mFactor2Mode) {
if (!exactMatch) {
SurfaceKey compactKey = aIdealKey.CloneWithSize(suggestedSize);
mSurfaces.Get(compactKey, getter_AddRefs(exactMatch));
@ -403,7 +401,7 @@ public:
} else if (aIdealKey.Size() != bestMatch->GetSurfaceKey().Size()) {
// The best factor of 2 match is still decoding, but the best we've got.
MOZ_ASSERT(suggestedSize != aIdealKey.Size());
MOZ_ASSERT(mFactor2Mode || mIsVectorImage);
MOZ_ASSERT(mFactor2Mode);
matchType = MatchType::SUBSTITUTE_BECAUSE_BEST;
} else {
// The exact match is still decoding, but it's the best we've got.
@ -435,18 +433,20 @@ public:
return;
}
// Determine how many native surfaces this image has. If it is zero, and it
// is a vector image, then we should impute a single native size. Otherwise,
// it may be zero because we don't know yet, or the image has an error, or
// it isn't supported.
// Determine how many native surfaces this image has. Zero means we either
// don't know yet (in which case do nothing), or we don't want to limit the
// number of surfaces for this image.
//
// XXX(aosmond): Vector images have zero native sizes. This is because they
// are regenerated at the given size. There isn't an equivalent concept to
// the native size (and w/h ratio) to provide a frame of reference to what
// are "good" sizes. While it is desirable to have a similar mechanism as
// that for raster images, it will need a different approach.
auto first = ConstIter();
NotNull<CachedSurface*> current = WrapNotNull(first.UserData());
Image* image = static_cast<Image*>(current->GetImageKey());
size_t nativeSizes = image->GetNativeSizesLength();
if (mIsVectorImage) {
MOZ_ASSERT(nativeSizes == 0);
nativeSizes = 1;
} else if (nativeSizes == 0) {
if (nativeSizes == 0) {
return;
}
@ -530,33 +530,6 @@ public:
}
IntSize SuggestedSize(const IntSize& aSize) const
{
IntSize suggestedSize = SuggestedSizeInternal(aSize);
MOZ_ASSERT(SurfaceCache::IsLegalSize(suggestedSize));
// Whether or not we are in factor of 2 mode, vector image rasterization is
// clamped at a configured maximum if the caller is willing to accept
// substitutes.
if (mIsVectorImage) {
// If we exceed the maximum, we need to scale the size downwards to fit.
// It shouldn't get here if it is significantly larger because
// VectorImage::UseSurfaceCacheForSize should prevent us from requesting
// a rasterized version of a surface greater than 4x the maximum.
int32_t maxSizeKB = gfxPrefs::ImageCacheMaxRasterizedSVGThresholdKB();
int32_t proposedKB = suggestedSize.width * suggestedSize.height / 256;
if (maxSizeKB >= proposedKB) {
return suggestedSize;
}
double scale = sqrt(double(maxSizeKB) / proposedKB);
suggestedSize.width = int32_t(scale * suggestedSize.width);
suggestedSize.height = int32_t(scale * suggestedSize.height);
}
return suggestedSize;
}
IntSize SuggestedSizeInternal(const IntSize& aSize) const
{
// When not in factor of 2 mode, we can always decode at the given size.
if (!mFactor2Mode) {
@ -579,48 +552,11 @@ public:
NS_FAILED(image->GetHeight(&factorSize.height)) ||
factorSize.IsEmpty()) {
// We should not have entered factor of 2 mode without a valid size, and
// several successfully decoded surfaces. Note that valid vector images
// may have a default size of 0x0, and those are not yet supported.
// several successfully decoded surfaces.
MOZ_ASSERT_UNREACHABLE("Expected valid native size!");
return aSize;
}
if (mIsVectorImage) {
// Ensure the aspect ratio matches the native size before forcing the
// caller to accept a factor of 2 size. The difference between the aspect
// ratios is:
//
// delta = nativeWidth/nativeHeight - desiredWidth/desiredHeight
//
// delta*nativeHeight*desiredHeight = nativeWidth*desiredHeight
// - desiredWidth*nativeHeight
//
// Using the maximum accepted delta as a constant, we can avoid the
// floating point division and just compare after some integer ops.
int32_t delta = factorSize.width * aSize.height - aSize.width * factorSize.height;
int32_t maxDelta = (factorSize.height * aSize.height) >> 4;
if (delta > maxDelta || delta < -maxDelta) {
return aSize;
}
// If the requested size is bigger than the native size, we actually need
// to grow the native size instead of shrinking it.
if (factorSize.width < aSize.width) {
do {
IntSize candidate(factorSize.width * 2, factorSize.height * 2);
if (!SurfaceCache::IsLegalSize(candidate)) {
break;
}
factorSize = candidate;
} while (factorSize.width < aSize.width);
return factorSize;
}
// Otherwise we can find the best fit as normal.
}
// Start with the native size as the best first guess.
IntSize bestSize = factorSize;
factorSize.width /= 2;
@ -738,10 +674,6 @@ private:
// True if all non-factor of 2 surfaces have been removed from the cache. Note
// that this excludes unsubstitutable sizes.
bool mFactor2Pruned;
// True if the surfaces are produced from a vector image. If so, it must match
// the aspect ratio when using factor of 2 mode.
bool mIsVectorImage;
};
/**
@ -828,10 +760,9 @@ public:
// Locate the appropriate per-image cache. If there's not an existing cache
// for this image, create it.
const ImageKey imageKey = aProvider->GetImageKey();
RefPtr<ImageSurfaceCache> cache = GetImageCache(imageKey);
RefPtr<ImageSurfaceCache> cache = GetImageCache(aProvider->GetImageKey());
if (!cache) {
cache = new ImageSurfaceCache(imageKey);
cache = new ImageSurfaceCache;
mImageCaches.Put(aProvider->GetImageKey(), cache);
}
@ -1083,7 +1014,7 @@ public:
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache) {
cache = new ImageSurfaceCache(aImageKey);
cache = new ImageSurfaceCache;
mImageCaches.Put(aImageKey, cache);
}
@ -1699,30 +1630,5 @@ SurfaceCache::MaximumCapacity()
return sInstance->MaximumCapacity();
}
/* static */ bool
SurfaceCache::IsLegalSize(const IntSize& aSize)
{
// reject over-wide or over-tall images
const int32_t k64KLimit = 0x0000FFFF;
if (MOZ_UNLIKELY(aSize.width > k64KLimit || aSize.height > k64KLimit )) {
NS_WARNING("image too big");
return false;
}
// protect against invalid sizes
if (MOZ_UNLIKELY(aSize.height <= 0 || aSize.width <= 0)) {
return false;
}
// check to make sure we don't overflow a 32-bit
CheckedInt32 requiredBytes = CheckedInt32(aSize.width) *
CheckedInt32(aSize.height) * 4;
if (MOZ_UNLIKELY(!requiredBytes.isValid())) {
NS_WARNING("width or height too large");
return false;
}
return true;
}
} // namespace image
} // namespace mozilla

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

@ -443,11 +443,6 @@ struct SurfaceCache
*/
static size_t MaximumCapacity();
/**
* @return true if the given size is valid.
*/
static bool IsLegalSize(const IntSize& aSize);
private:
virtual ~SurfaceCache() = 0; // Forbid instantiation.
};

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

@ -807,21 +807,15 @@ VectorImage::GetFrameInternal(const IntSize& aSize,
RefPtr<SourceSurface>());
}
// We don't allow large surfaces to be rasterized on the Draw and
// GetImageContainerAtSize paths, because those have alternatives. If we get
// here however, then we know it came from GetFrame(AtSize) and that path does
// not have any fallback method, so we don't check UseSurfaceCacheForSize.
RefPtr<SourceSurface> sourceSurface;
IntSize decodeSize;
Tie(sourceSurface, decodeSize) =
RefPtr<SourceSurface> sourceSurface =
LookupCachedSurface(aSize, aSVGContext, aFlags);
if (sourceSurface) {
return MakeTuple(ImgDrawResult::SUCCESS, decodeSize, std::move(sourceSurface));
return MakeTuple(ImgDrawResult::SUCCESS, aSize, std::move(sourceSurface));
}
if (mIsDrawing) {
NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
return MakeTuple(ImgDrawResult::TEMPORARY_ERROR, decodeSize,
return MakeTuple(ImgDrawResult::TEMPORARY_ERROR, aSize,
RefPtr<SourceSurface>());
}
@ -830,8 +824,7 @@ VectorImage::GetFrameInternal(const IntSize& aSize,
// flags, having an animation, etc). Otherwise CreateSurface will assume that
// the caller is capable of drawing directly to its own draw target if we
// cannot cache.
SVGDrawingParameters params(nullptr, decodeSize, aSize,
ImageRegion::Create(decodeSize),
SVGDrawingParameters params(nullptr, aSize, ImageRegion::Create(aSize),
SamplingFilter::POINT, aSVGContext,
mSVGDocumentWrapper->GetCurrentTime(),
aFlags, 1.0);
@ -847,12 +840,12 @@ VectorImage::GetFrameInternal(const IntSize& aSize,
CreateSurface(params, svgDrawable, didCache);
if (!surface) {
MOZ_ASSERT(!didCache);
return MakeTuple(ImgDrawResult::TEMPORARY_ERROR, decodeSize,
return MakeTuple(ImgDrawResult::TEMPORARY_ERROR, aSize,
RefPtr<SourceSurface>());
}
SendFrameComplete(didCache, params.flags);
return MakeTuple(ImgDrawResult::SUCCESS, decodeSize, std::move(surface));
return MakeTuple(ImgDrawResult::SUCCESS, aSize, std::move(surface));
}
//******************************************************************************
@ -911,9 +904,7 @@ VectorImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
{
// Since we only support image containers with WebRender, and it can handle
// textures larger than the hw max texture size, we don't need to check aSize.
return !aSize.IsEmpty() &&
UseSurfaceCacheForSize(aSize) &&
IsImageContainerAvailable(aManager, aFlags);
return !aSize.IsEmpty() && IsImageContainerAvailable(aManager, aFlags);
}
//******************************************************************************
@ -924,16 +915,15 @@ VectorImage::GetImageContainerAtSize(layers::LayerManager* aManager,
uint32_t aFlags,
layers::ImageContainer** aOutContainer)
{
if (!UseSurfaceCacheForSize(aSize)) {
return ImgDrawResult::NOT_SUPPORTED;
}
Maybe<SVGImageContext> newSVGContext;
MaybeRestrictSVGContext(newSVGContext, aSVGContext, aFlags);
// The aspect ratio flag was already handled as part of the SVG context
// restriction above.
uint32_t flags = aFlags & ~(FLAG_FORCE_PRESERVEASPECTRATIO_NONE);
// Since we do not support high quality scaling with SVG, we mask it off so
// that container requests with and without it map to the same container.
// Similarly the aspect ratio flag was already handled as part of the SVG
// context restriction above.
uint32_t flags = aFlags & ~(FLAG_HIGH_QUALITY_SCALING |
FLAG_FORCE_PRESERVEASPECTRATIO_NONE);
return GetImageContainerImpl(aManager, aSize,
newSVGContext ? newSVGContext : aSVGContext,
flags, aOutContainer);
@ -1012,13 +1002,10 @@ VectorImage::Draw(gfxContext* aContext,
SendOnUnlockedDraw(aFlags);
}
// We should bypass the cache when:
// - We are using a DrawTargetRecording because we prefer the drawing commands
// in general to the rasterized surface. This allows blob images to avoid
// rasterized SVGs with WebRender.
// - The size exceeds what we are will to cache as a rasterized surface.
if (aContext->GetDrawTarget()->GetBackendType() == BackendType::RECORDING ||
!UseSurfaceCacheForSize(aSize)) {
// We should always bypass the cache when using DrawTargetRecording because
// we prefer the drawing commands in general to the rasterized surface. This
// allows blob images to avoid rasterized SVGs with WebRender.
if (aContext->GetDrawTarget()->GetBackendType() == BackendType::RECORDING) {
aFlags |= FLAG_BYPASS_SURFACE_CACHE;
}
@ -1034,19 +1021,18 @@ VectorImage::Draw(gfxContext* aContext,
bool contextPaint =
MaybeRestrictSVGContext(newSVGContext, aSVGContext, aFlags);
SVGDrawingParameters params(aContext, aSize, aSize, aRegion, aSamplingFilter,
SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter,
newSVGContext ? newSVGContext : aSVGContext,
animTime, aFlags, aOpacity);
// If we have an prerasterized version of this image that matches the
// drawing parameters, use that.
RefPtr<SourceSurface> sourceSurface;
Tie(sourceSurface, params.size) =
RefPtr<SourceSurface> sourceSurface =
LookupCachedSurface(aSize, params.svgContext, aFlags);
if (sourceSurface) {
RefPtr<gfxDrawable> drawable =
new gfxSurfaceDrawable(sourceSurface, params.size);
Show(drawable, params);
RefPtr<gfxDrawable> svgDrawable =
new gfxSurfaceDrawable(sourceSurface, sourceSurface->GetSize());
Show(svgDrawable, params);
return ImgDrawResult::SUCCESS;
}
@ -1090,56 +1076,29 @@ VectorImage::CreateSVGDrawable(const SVGDrawingParameters& aParams)
return svgDrawable.forget();
}
bool
VectorImage::UseSurfaceCacheForSize(const IntSize& aSize) const
{
int32_t maxSizeKB = gfxPrefs::ImageCacheMaxRasterizedSVGThresholdKB();
if (maxSizeKB <= 0) {
return true;
}
if (!SurfaceCache::IsLegalSize(aSize)) {
return false;
}
// With factor of 2 mode, we should be willing to use a surface which is up
// to twice the width, and twice the height, of the maximum sized surface
// before switching to drawing to the target directly. That means the size in
// KB works out to be:
// width * height * 4 [bytes/pixel] * / 1024 [bytes/KB] <= 2 * 2 * maxSizeKB
return aSize.width * aSize.height / 1024 <= maxSizeKB;
}
Tuple<RefPtr<SourceSurface>, IntSize>
already_AddRefed<SourceSurface>
VectorImage::LookupCachedSurface(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
// If we're not allowed to use a cached surface, don't attempt a lookup.
if (aFlags & FLAG_BYPASS_SURFACE_CACHE) {
return MakeTuple(RefPtr<SourceSurface>(), aSize);
return nullptr;
}
// We don't do any caching if we have animation, so don't bother with a lookup
// in this case either.
if (mHaveAnimations) {
return MakeTuple(RefPtr<SourceSurface>(), aSize);
return nullptr;
}
LookupResult result(MatchType::NOT_FOUND);
SurfaceKey surfaceKey = VectorSurfaceKey(aSize, aSVGContext);
if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
result = SurfaceCache::Lookup(ImageKey(this), surfaceKey);
} else {
result = SurfaceCache::LookupBestMatch(ImageKey(this), surfaceKey);
}
LookupResult result =
SurfaceCache::Lookup(ImageKey(this),
VectorSurfaceKey(aSize, aSVGContext));
IntSize rasterSize = result.SuggestedSize().IsEmpty()
? aSize : result.SuggestedSize();
MOZ_ASSERT(result.Type() != MatchType::SUBSTITUTE_BECAUSE_PENDING);
if (!result || result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND) {
// No matching surface, or the OS freed the volatile buffer.
return MakeTuple(RefPtr<SourceSurface>(), rasterSize);
MOZ_ASSERT(result.SuggestedSize().IsEmpty(), "SVG should not substitute!");
if (!result) {
return nullptr; // No matching surface, or the OS freed the volatile buffer.
}
RefPtr<SourceSurface> sourceSurface = result.Surface()->GetSourceSurface();
@ -1147,10 +1106,10 @@ VectorImage::LookupCachedSurface(const IntSize& aSize,
// Something went wrong. (Probably a GPU driver crash or device reset.)
// Attempt to recover.
RecoverFromLossOfSurfaces();
return MakeTuple(RefPtr<SourceSurface>(), rasterSize);
return nullptr;
}
return MakeTuple(std::move(sourceSurface), rasterSize);
return sourceSurface.forget();
}
already_AddRefed<SourceSurface>
@ -1230,15 +1189,7 @@ VectorImage::CreateSurface(const SVGDrawingParameters& aParams,
SurfaceKey surfaceKey = VectorSurfaceKey(aParams.size, aParams.svgContext);
NotNull<RefPtr<ISurfaceProvider>> provider =
MakeNotNull<SimpleSurfaceProvider*>(ImageKey(this), surfaceKey, frame);
if (SurfaceCache::Insert(provider) == InsertOutcome::SUCCESS &&
aParams.size != aParams.drawSize) {
// We created a new surface that wasn't the size we requested, which means
// we entered factor-of-2 mode. We should purge any surfaces we no longer
// need rather than waiting for the cache to expire them.
SurfaceCache::PruneImage(ImageKey(this));
}
SurfaceCache::Insert(provider);
return surface.forget();
}
@ -1273,21 +1224,10 @@ VectorImage::SendFrameComplete(bool aDidCache, uint32_t aFlags)
void
VectorImage::Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams)
{
// The surface size may differ from the size at which we wish to draw. As
// such, we may need to adjust the context/region to take this into account.
gfxContextMatrixAutoSaveRestore saveMatrix(aParams.context);
ImageRegion region(aParams.region);
if (aParams.drawSize != aParams.size) {
gfx::Size scale(double(aParams.drawSize.width) / aParams.size.width,
double(aParams.drawSize.height) / aParams.size.height);
aParams.context->Multiply(gfxMatrix::Scaling(scale.width, scale.height));
region.Scale(1.0 / scale.width, 1.0 / scale.height);
}
MOZ_ASSERT(aDrawable, "Should have a gfxDrawable by now");
gfxUtils::DrawPixelSnapped(aParams.context, aDrawable,
SizeDouble(aParams.size),
region,
aParams.region,
SurfaceFormat::B8G8R8A8,
aParams.samplingFilter,
aParams.flags, aParams.opacity, false);

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

@ -92,12 +92,8 @@ private:
const IntSize& aSize,
uint32_t aFlags) override;
/**
* Attempt to find a matching cached surface in the SurfaceCache. Returns the
* cached surface, if found, and the size to rasterize at, if applicable.
* If we cannot rasterize, it will be the requested size to draw at (aSize).
*/
Tuple<RefPtr<SourceSurface>, IntSize>
/// Attempt to find a matching cached surface in the SurfaceCache.
already_AddRefed<SourceSurface>
LookupCachedSurface(const IntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags);
@ -110,9 +106,6 @@ private:
already_AddRefed<gfxDrawable>
CreateSVGDrawable(const SVGDrawingParameters& aParams);
/// Returns true if we use the surface cache to store rasterized copies.
bool UseSurfaceCacheForSize(const IntSize& aSize) const;
/// Rasterize the SVG into a surface. aWillCache will be set to whether or
/// not the new surface was put into the cache.
already_AddRefed<SourceSurface>

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

@ -7,7 +7,6 @@
#include "imgFrame.h"
#include "ImageRegion.h"
#include "ShutdownTracker.h"
#include "SurfaceCache.h"
#include "prenv.h"
@ -158,13 +157,38 @@ ClearSurface(DataSourceSurface* aSurface, const IntSize& aSize, SurfaceFormat aF
return true;
}
// Returns true if an image of aWidth x aHeight is allowed and legal.
static bool
AllowedImageSize(int32_t aWidth, int32_t aHeight)
{
// reject over-wide or over-tall images
const int32_t k64KLimit = 0x0000FFFF;
if (MOZ_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) {
NS_WARNING("image too big");
return false;
}
// protect against invalid sizes
if (MOZ_UNLIKELY(aHeight <= 0 || aWidth <= 0)) {
return false;
}
// check to make sure we don't overflow a 32-bit
CheckedInt32 requiredBytes = CheckedInt32(aWidth) * CheckedInt32(aHeight) * 4;
if (MOZ_UNLIKELY(!requiredBytes.isValid())) {
NS_WARNING("width or height too large");
return false;
}
return true;
}
static bool AllowedImageAndFrameDimensions(const nsIntSize& aImageSize,
const nsIntRect& aFrameRect)
{
if (!SurfaceCache::IsLegalSize(aImageSize)) {
if (!AllowedImageSize(aImageSize.width, aImageSize.height)) {
return false;
}
if (!SurfaceCache::IsLegalSize(aFrameRect.Size())) {
if (!AllowedImageSize(aFrameRect.Width(), aFrameRect.Height())) {
return false;
}
nsIntRect imageRect(0, 0, aImageSize.width, aImageSize.height);
@ -313,7 +337,7 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
{
// Assert for properties that should be verified by decoders,
// warn for properties related to bad content.
if (!SurfaceCache::IsLegalSize(aSize)) {
if (!AllowedImageSize(aSize.width, aSize.height)) {
NS_WARNING("Should have legal image size");
mAborted = true;
return NS_ERROR_FAILURE;

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

@ -4620,10 +4620,6 @@ pref("image.animated.resume-from-last-displayed", true);
// same data at different sizes.
pref("image.cache.factor2.threshold-surfaces", 4);
// Maximum number of pixels in either dimension that we are willing to upscale
// an SVG to when we are in "factor of 2" mode.
pref("image.cache.max-rasterized-svg-threshold-kb", 92160);
// The maximum size, in bytes, of the decoded images we cache
pref("image.cache.size", 5242880);