Thu, 15 Jan 2015 15:59:08 +0100
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_