image/src/SurfaceCache.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /**
     7  * SurfaceCache is a service for caching temporary surfaces in imagelib.
     8  */
    10 #ifndef MOZILLA_IMAGELIB_SURFACECACHE_H_
    11 #define MOZILLA_IMAGELIB_SURFACECACHE_H_
    13 #include "mozilla/HashFunctions.h"  // for HashGeneric and AddToHash
    14 #include "gfxPoint.h"               // for gfxSize
    15 #include "nsCOMPtr.h"               // for already_AddRefed
    16 #include "mozilla/gfx/Point.h"      // for mozilla::gfx::IntSize
    17 #include "SVGImageContext.h"        // for SVGImageContext
    19 class gfxDrawable;
    21 namespace mozilla {
    23 namespace gfx {
    24 class DrawTarget;
    25 } // namespace gfx
    27 namespace image {
    29 class Image;
    31 /*
    32  * ImageKey contains the information we need to look up all cached surfaces for
    33  * a particular image.
    34  */
    35 typedef Image* ImageKey;
    37 /*
    38  * SurfaceKey contains the information we need to look up a specific cached
    39  * surface. Together with an ImageKey, this uniquely identifies the surface.
    40  *
    41  * XXX(seth): Right now this is specialized to the needs of VectorImage. We'll
    42  * generalize it in bug 919071.
    43  */
    44 class SurfaceKey
    45 {
    46   typedef gfx::IntSize IntSize;
    47 public:
    48   SurfaceKey(const IntSize& aSize,
    49              const gfxSize aScale,
    50              const SVGImageContext* aSVGContext,
    51              const float aAnimationTime,
    52              const uint32_t aFlags)
    53     : mSize(aSize)
    54     , mScale(aScale)
    55     , mSVGContextIsValid(aSVGContext != nullptr)
    56     , mAnimationTime(aAnimationTime)
    57     , mFlags(aFlags)
    58   {
    59     // XXX(seth): Would love to use Maybe<T> here, but see bug 913586.
    60     if (mSVGContextIsValid)
    61       mSVGContext = *aSVGContext;
    62   }
    64   bool operator==(const SurfaceKey& aOther) const
    65   {
    66     bool matchesSVGContext = aOther.mSVGContextIsValid == mSVGContextIsValid &&
    67                              (!mSVGContextIsValid || aOther.mSVGContext == mSVGContext);
    68     return aOther.mSize == mSize &&
    69            aOther.mScale == mScale &&
    70            matchesSVGContext &&
    71            aOther.mAnimationTime == mAnimationTime &&
    72            aOther.mFlags == mFlags;
    73   }
    75   uint32_t Hash() const
    76   {
    77     uint32_t hash = HashGeneric(mSize.width, mSize.height);
    78     hash = AddToHash(hash, mScale.width, mScale.height);
    79     hash = AddToHash(hash, mSVGContextIsValid, mSVGContext.Hash());
    80     hash = AddToHash(hash, mAnimationTime, mFlags);
    81     return hash;
    82   }
    84   IntSize Size() const { return mSize; }
    86 private:
    87   IntSize         mSize;
    88   gfxSize         mScale;
    89   SVGImageContext mSVGContext;
    90   bool            mSVGContextIsValid;
    91   float           mAnimationTime;
    92   uint32_t        mFlags;
    93 };
    95 /**
    96  * SurfaceCache is an imagelib-global service that allows caching of temporary
    97  * surfaces. Surfaces expire from the cache automatically if they go too long
    98  * without being accessed.
    99  *
   100  * SurfaceCache is not thread-safe; it should only be accessed from the main
   101  * thread.
   102  */
   103 struct SurfaceCache
   104 {
   105   typedef gfx::IntSize IntSize;
   107   /*
   108    * Initialize static data. Called during imagelib module initialization.
   109    */
   110   static void Initialize();
   112   /*
   113    * Release static data. Called during imagelib module shutdown.
   114    */
   115   static void Shutdown();
   117   /*
   118    * Look up a surface in the cache.
   119    *
   120    * @param aImageKey    Key data identifying which image the surface belongs to.
   121    * @param aSurfaceKey  Key data which uniquely identifies the requested surface.
   122    *
   123    * @return the requested surface, or nullptr if not found.
   124    */
   125   static already_AddRefed<gfxDrawable> Lookup(const ImageKey    aImageKey,
   126                                               const SurfaceKey& aSurfaceKey);
   128   /*
   129    * Insert a surface into the cache. It is an error to call this function
   130    * without first calling Lookup to verify that the surface is not already in
   131    * the cache.
   132    *
   133    * @param aTarget      The new surface (in the form of a DrawTarget) to insert
   134    *                     into the cache.
   135    * @param aImageKey    Key data identifying which image the surface belongs to.
   136    * @param aSurfaceKey  Key data which uniquely identifies the requested surface.
   137    */
   138   static void Insert(mozilla::gfx::DrawTarget* aTarget,
   139                      const ImageKey            aImageKey,
   140                      const SurfaceKey&         aSurfaceKey);
   142   /*
   143    * Checks if a surface of a given size could possibly be stored in the cache.
   144    * If CanHold() returns false, Insert() will always fail to insert the
   145    * surface, but the inverse is not true: Insert() may take more information
   146    * into account than just image size when deciding whether to cache the
   147    * surface, so Insert() may still fail even if CanHold() returns true.
   148    *
   149    * Use CanHold() to avoid the need to create a temporary surface when we know
   150    * for sure the cache can't hold it.
   151    *
   152    * @param aSize  The dimensions of a surface in pixels.
   153    *
   154    * @return false if the surface cache can't hold a surface of that size.
   155    */
   156   static bool CanHold(const IntSize& aSize);
   158   /*
   159    * Evicts any cached surfaces associated with the given image from the cache.
   160    * This MUST be called, at a minimum, when the image is destroyed. If
   161    * another image were allocated at the same address it could result in
   162    * subtle, difficult-to-reproduce bugs.
   163    *
   164    * @param aImageKey  The image which should be removed from the cache.
   165    */
   166   static void Discard(const ImageKey aImageKey);
   168   /*
   169    * Evicts all caches surfaces from ths cache.
   170    */
   171   static void DiscardAll();
   173 private:
   174   virtual ~SurfaceCache() = 0;  // Forbid instantiation.
   175 };
   177 } // namespace image
   178 } // namespace mozilla
   180 #endif // MOZILLA_IMAGELIB_SURFACECACHE_H_

mercurial