gecko-dev/image/LookupResult.h
Andrew Osmond cee95ec8de Bug 1456558 - Part 3. Implement factor of 2 scaling support for SVGs in VectorImage. r=tnikkel
If FLAG_HIGH_QUALITY_SCALING is used, we should use
SurfaceCache::LookupBestMatch just like how it is done in RasterImage.
This may provide an alternative size at which we should rasterize the
SVG instead of the requested size. Since SurfaceCache imposes a maximum
size for which it will permit rasterized SVGs, we should also bypass the
cache entirely if we are well above that and simply draw directly to the
draw target in such cases.

With WebRender, it is somewhat more complicated. We will now return
NOT_SUPPORTED if the size is too big, and this should trigger fallback
to blob images. This should only produce drawing commands for the
relevant region and save us the high cost of rasterized a very large
surface on the main thread, which at the same time, looking as crisp as
a user would expect.
2018-09-20 20:22:06 -04:00

124 lines
4.6 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* LookupResult is the return type of SurfaceCache's Lookup*() functions. It
* combines a surface with relevant metadata tracked by SurfaceCache.
*/
#ifndef mozilla_image_LookupResult_h
#define mozilla_image_LookupResult_h
#include "mozilla/Attributes.h"
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/Move.h"
#include "ISurfaceProvider.h"
namespace mozilla {
namespace image {
enum class MatchType : uint8_t
{
NOT_FOUND, // No matching surface and no placeholder.
PENDING, // Found a matching placeholder, but no surface.
EXACT, // Found a surface that matches exactly.
SUBSTITUTE_BECAUSE_NOT_FOUND, // No exact match, but found a similar one.
SUBSTITUTE_BECAUSE_PENDING, // Found a similar surface and a placeholder
// for an exact match.
/* No exact match, but this should be considered an exact match for purposes
* of deciding whether or not to request a new decode. This is because the
* cache has determined that callers require too many size variants of this
* image. It determines the set of sizes which best represent the image, and
* will only suggest decoding of unavailable sizes from that set. */
SUBSTITUTE_BECAUSE_BEST
};
/**
* LookupResult is the return type of SurfaceCache's Lookup*() functions. It
* combines a surface with relevant metadata tracked by SurfaceCache.
*/
class MOZ_STACK_CLASS LookupResult
{
public:
explicit LookupResult(MatchType aMatchType)
: mMatchType(aMatchType)
{
MOZ_ASSERT(mMatchType == MatchType::NOT_FOUND ||
mMatchType == MatchType::PENDING,
"Only NOT_FOUND or PENDING make sense with no surface");
}
LookupResult(LookupResult&& aOther)
: mSurface(std::move(aOther.mSurface))
, mMatchType(aOther.mMatchType)
, mSuggestedSize(aOther.mSuggestedSize)
{ }
LookupResult(DrawableSurface&& aSurface, MatchType aMatchType)
: mSurface(std::move(aSurface))
, mMatchType(aMatchType)
{
MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
mMatchType == MatchType::PENDING),
"Only NOT_FOUND or PENDING make sense with no surface");
MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
mMatchType == MatchType::PENDING,
"NOT_FOUND or PENDING do not make sense with a surface");
}
LookupResult(DrawableSurface&& aSurface, MatchType aMatchType,
const gfx::IntSize& aSuggestedSize)
: mSurface(std::move(aSurface))
, mMatchType(aMatchType)
, mSuggestedSize(aSuggestedSize)
{
MOZ_ASSERT(!mSurface || !(mMatchType == MatchType::NOT_FOUND ||
mMatchType == MatchType::PENDING),
"Only NOT_FOUND or PENDING make sense with no surface");
MOZ_ASSERT(mSurface || mMatchType == MatchType::NOT_FOUND ||
mMatchType == MatchType::PENDING,
"NOT_FOUND or PENDING do not make sense with a surface");
}
LookupResult& operator=(LookupResult&& aOther)
{
MOZ_ASSERT(&aOther != this, "Self-move-assignment is not supported");
mSurface = std::move(aOther.mSurface);
mMatchType = aOther.mMatchType;
mSuggestedSize = aOther.mSuggestedSize;
return *this;
}
DrawableSurface& Surface() { return mSurface; }
const DrawableSurface& Surface() const { return mSurface; }
const gfx::IntSize& SuggestedSize() const { return mSuggestedSize; }
/// @return true if this LookupResult contains a surface.
explicit operator bool() const { return bool(mSurface); }
/// @return what kind of match this is (exact, substitute, etc.)
MatchType Type() const { return mMatchType; }
private:
LookupResult(const LookupResult&) = delete;
LookupResult& operator=(const LookupResult& aOther) = delete;
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.
gfx::IntSize mSuggestedSize;
};
} // namespace image
} // namespace mozilla
#endif // mozilla_image_LookupResult_h