image/src/SurfaceCache.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/image/src/SurfaceCache.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,180 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/**
    1.10 + * SurfaceCache is a service for caching temporary surfaces in imagelib.
    1.11 + */
    1.12 +
    1.13 +#ifndef MOZILLA_IMAGELIB_SURFACECACHE_H_
    1.14 +#define MOZILLA_IMAGELIB_SURFACECACHE_H_
    1.15 +
    1.16 +#include "mozilla/HashFunctions.h"  // for HashGeneric and AddToHash
    1.17 +#include "gfxPoint.h"               // for gfxSize
    1.18 +#include "nsCOMPtr.h"               // for already_AddRefed
    1.19 +#include "mozilla/gfx/Point.h"      // for mozilla::gfx::IntSize
    1.20 +#include "SVGImageContext.h"        // for SVGImageContext
    1.21 +
    1.22 +class gfxDrawable;
    1.23 +
    1.24 +namespace mozilla {
    1.25 +
    1.26 +namespace gfx {
    1.27 +class DrawTarget;
    1.28 +} // namespace gfx
    1.29 +
    1.30 +namespace image {
    1.31 +
    1.32 +class Image;
    1.33 +
    1.34 +/*
    1.35 + * ImageKey contains the information we need to look up all cached surfaces for
    1.36 + * a particular image.
    1.37 + */
    1.38 +typedef Image* ImageKey;
    1.39 +
    1.40 +/*
    1.41 + * SurfaceKey contains the information we need to look up a specific cached
    1.42 + * surface. Together with an ImageKey, this uniquely identifies the surface.
    1.43 + *
    1.44 + * XXX(seth): Right now this is specialized to the needs of VectorImage. We'll
    1.45 + * generalize it in bug 919071.
    1.46 + */
    1.47 +class SurfaceKey
    1.48 +{
    1.49 +  typedef gfx::IntSize IntSize;
    1.50 +public:
    1.51 +  SurfaceKey(const IntSize& aSize,
    1.52 +             const gfxSize aScale,
    1.53 +             const SVGImageContext* aSVGContext,
    1.54 +             const float aAnimationTime,
    1.55 +             const uint32_t aFlags)
    1.56 +    : mSize(aSize)
    1.57 +    , mScale(aScale)
    1.58 +    , mSVGContextIsValid(aSVGContext != nullptr)
    1.59 +    , mAnimationTime(aAnimationTime)
    1.60 +    , mFlags(aFlags)
    1.61 +  {
    1.62 +    // XXX(seth): Would love to use Maybe<T> here, but see bug 913586.
    1.63 +    if (mSVGContextIsValid)
    1.64 +      mSVGContext = *aSVGContext;
    1.65 +  }
    1.66 +
    1.67 +  bool operator==(const SurfaceKey& aOther) const
    1.68 +  {
    1.69 +    bool matchesSVGContext = aOther.mSVGContextIsValid == mSVGContextIsValid &&
    1.70 +                             (!mSVGContextIsValid || aOther.mSVGContext == mSVGContext);
    1.71 +    return aOther.mSize == mSize &&
    1.72 +           aOther.mScale == mScale &&
    1.73 +           matchesSVGContext &&
    1.74 +           aOther.mAnimationTime == mAnimationTime &&
    1.75 +           aOther.mFlags == mFlags;
    1.76 +  }
    1.77 +
    1.78 +  uint32_t Hash() const
    1.79 +  {
    1.80 +    uint32_t hash = HashGeneric(mSize.width, mSize.height);
    1.81 +    hash = AddToHash(hash, mScale.width, mScale.height);
    1.82 +    hash = AddToHash(hash, mSVGContextIsValid, mSVGContext.Hash());
    1.83 +    hash = AddToHash(hash, mAnimationTime, mFlags);
    1.84 +    return hash;
    1.85 +  }
    1.86 +
    1.87 +  IntSize Size() const { return mSize; }
    1.88 +
    1.89 +private:
    1.90 +  IntSize         mSize;
    1.91 +  gfxSize         mScale;
    1.92 +  SVGImageContext mSVGContext;
    1.93 +  bool            mSVGContextIsValid;
    1.94 +  float           mAnimationTime;
    1.95 +  uint32_t        mFlags;
    1.96 +};
    1.97 +
    1.98 +/**
    1.99 + * SurfaceCache is an imagelib-global service that allows caching of temporary
   1.100 + * surfaces. Surfaces expire from the cache automatically if they go too long
   1.101 + * without being accessed.
   1.102 + *
   1.103 + * SurfaceCache is not thread-safe; it should only be accessed from the main
   1.104 + * thread.
   1.105 + */
   1.106 +struct SurfaceCache
   1.107 +{
   1.108 +  typedef gfx::IntSize IntSize;
   1.109 +
   1.110 +  /*
   1.111 +   * Initialize static data. Called during imagelib module initialization.
   1.112 +   */
   1.113 +  static void Initialize();
   1.114 +
   1.115 +  /*
   1.116 +   * Release static data. Called during imagelib module shutdown.
   1.117 +   */
   1.118 +  static void Shutdown();
   1.119 +
   1.120 +  /*
   1.121 +   * Look up a surface in the cache.
   1.122 +   *
   1.123 +   * @param aImageKey    Key data identifying which image the surface belongs to.
   1.124 +   * @param aSurfaceKey  Key data which uniquely identifies the requested surface.
   1.125 +   *
   1.126 +   * @return the requested surface, or nullptr if not found.
   1.127 +   */
   1.128 +  static already_AddRefed<gfxDrawable> Lookup(const ImageKey    aImageKey,
   1.129 +                                              const SurfaceKey& aSurfaceKey);
   1.130 +
   1.131 +  /*
   1.132 +   * Insert a surface into the cache. It is an error to call this function
   1.133 +   * without first calling Lookup to verify that the surface is not already in
   1.134 +   * the cache.
   1.135 +   *
   1.136 +   * @param aTarget      The new surface (in the form of a DrawTarget) to insert
   1.137 +   *                     into the cache.
   1.138 +   * @param aImageKey    Key data identifying which image the surface belongs to.
   1.139 +   * @param aSurfaceKey  Key data which uniquely identifies the requested surface.
   1.140 +   */
   1.141 +  static void Insert(mozilla::gfx::DrawTarget* aTarget,
   1.142 +                     const ImageKey            aImageKey,
   1.143 +                     const SurfaceKey&         aSurfaceKey);
   1.144 +
   1.145 +  /*
   1.146 +   * Checks if a surface of a given size could possibly be stored in the cache.
   1.147 +   * If CanHold() returns false, Insert() will always fail to insert the
   1.148 +   * surface, but the inverse is not true: Insert() may take more information
   1.149 +   * into account than just image size when deciding whether to cache the
   1.150 +   * surface, so Insert() may still fail even if CanHold() returns true.
   1.151 +   *
   1.152 +   * Use CanHold() to avoid the need to create a temporary surface when we know
   1.153 +   * for sure the cache can't hold it.
   1.154 +   *
   1.155 +   * @param aSize  The dimensions of a surface in pixels.
   1.156 +   *
   1.157 +   * @return false if the surface cache can't hold a surface of that size.
   1.158 +   */
   1.159 +  static bool CanHold(const IntSize& aSize);
   1.160 +
   1.161 +  /*
   1.162 +   * Evicts any cached surfaces associated with the given image from the cache.
   1.163 +   * This MUST be called, at a minimum, when the image is destroyed. If
   1.164 +   * another image were allocated at the same address it could result in
   1.165 +   * subtle, difficult-to-reproduce bugs.
   1.166 +   *
   1.167 +   * @param aImageKey  The image which should be removed from the cache.
   1.168 +   */
   1.169 +  static void Discard(const ImageKey aImageKey);
   1.170 +
   1.171 +  /*
   1.172 +   * Evicts all caches surfaces from ths cache.
   1.173 +   */
   1.174 +  static void DiscardAll();
   1.175 +
   1.176 +private:
   1.177 +  virtual ~SurfaceCache() = 0;  // Forbid instantiation.
   1.178 +};
   1.179 +
   1.180 +} // namespace image
   1.181 +} // namespace mozilla
   1.182 +
   1.183 +#endif // MOZILLA_IMAGELIB_SURFACECACHE_H_

mercurial