Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
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: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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 #ifndef GFX_ASURFACE_H
7 #define GFX_ASURFACE_H
9 #include "mozilla/MemoryReporting.h"
10 #include "gfxTypes.h"
11 #include "mozilla/Scoped.h"
12 #include "nscore.h"
13 #include "nsSize.h"
15 #ifdef MOZILLA_INTERNAL_API
16 #include "nsStringFwd.h"
17 #else
18 #include "nsStringAPI.h"
19 #endif
21 class gfxImageSurface;
22 struct nsIntPoint;
23 struct nsIntRect;
24 struct gfxRect;
25 struct gfxPoint;
27 template <typename T>
28 struct already_AddRefed;
30 /**
31 * A surface is something you can draw on. Instantiate a subclass of this
32 * abstract class, and use gfxContext to draw on this surface.
33 */
34 class gfxASurface {
35 public:
36 #ifdef MOZILLA_INTERNAL_API
37 nsrefcnt AddRef(void);
38 nsrefcnt Release(void);
40 // These functions exist so that browsercomps can refcount a gfxASurface
41 virtual nsrefcnt AddRefExternal(void);
42 virtual nsrefcnt ReleaseExternal(void);
43 #else
44 virtual nsrefcnt AddRef(void);
45 virtual nsrefcnt Release(void);
46 #endif
48 public:
50 /** Wrap the given cairo surface and return a gfxASurface for it.
51 * This adds a reference to csurf (owned by the returned gfxASurface).
52 */
53 static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const gfxIntSize& aSize = gfxIntSize(-1, -1));
55 /*** this DOES NOT addref the surface */
56 cairo_surface_t *CairoSurface() {
57 return mSurface;
58 }
60 gfxSurfaceType GetType() const;
62 gfxContentType GetContentType() const;
64 void SetDeviceOffset(const gfxPoint& offset);
65 gfxPoint GetDeviceOffset() const;
67 virtual bool GetRotateForLandscape() { return false; }
69 void Flush() const;
70 void MarkDirty();
71 void MarkDirty(const gfxRect& r);
73 /* Printing backend functions */
74 virtual nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName);
75 virtual nsresult EndPrinting();
76 virtual nsresult AbortPrinting();
77 virtual nsresult BeginPage();
78 virtual nsresult EndPage();
80 void SetData(const cairo_user_data_key_t *key,
81 void *user_data,
82 thebes_destroy_func_t destroy);
83 void *GetData(const cairo_user_data_key_t *key);
85 virtual void Finish();
87 /**
88 * Create an offscreen surface that can be efficiently copied into
89 * this surface (at least if tiling is not involved).
90 * Returns null on error.
91 */
92 virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
93 const nsIntSize& aSize);
95 /**
96 * Returns an image surface for this surface, or nullptr if not supported.
97 * This will not copy image data, just wraps an image surface around
98 * pixel data already available in memory.
99 */
100 virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
102 /**
103 * Returns a read-only ARGB32 image surface for this surface. If this is an
104 * optimized surface this may require a copy.
105 * Returns null on error.
106 */
107 virtual already_AddRefed<gfxImageSurface> GetAsReadableARGB32ImageSurface();
109 /**
110 * Creates a new ARGB32 image surface with the same contents as this surface.
111 * Returns null on error.
112 */
113 already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface();
115 int CairoStatus();
117 /* Make sure that the given dimensions don't overflow a 32-bit signed int
118 * using 4 bytes per pixel; optionally, make sure that either dimension
119 * doesn't exceed the given limit.
120 */
121 static bool CheckSurfaceSize(const nsIntSize& sz, int32_t limit = 0);
123 /* Provide a stride value that will respect all alignment requirements of
124 * the accelerated image-rendering code.
125 */
126 static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width);
128 /* Return the default set of context flags for this surface; these are
129 * hints to the context about any special rendering considerations. See
130 * gfxContext::SetFlag for documentation.
131 */
132 virtual int32_t GetDefaultContextFlags() const { return 0; }
134 static gfxContentType ContentFromFormat(gfxImageFormat format);
136 void SetSubpixelAntialiasingEnabled(bool aEnabled);
137 bool GetSubpixelAntialiasingEnabled();
139 /**
140 * Record number of bytes for given surface type. Use positive bytes
141 * for allocations and negative bytes for deallocations.
142 */
143 static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
144 int32_t aBytes);
146 /**
147 * Same as above, but use current surface type as returned by GetType().
148 * The bytes will be accumulated until RecordMemoryFreed is called,
149 * in which case the value that was recorded for this surface will
150 * be freed.
151 */
152 void RecordMemoryUsed(int32_t aBytes);
153 void RecordMemoryFreed();
155 virtual int32_t KnownMemoryUsed() { return mBytesRecorded; }
157 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
158 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
159 // gfxASurface has many sub-classes. This method indicates if a sub-class
160 // is capable of measuring its own size accurately. If not, the caller
161 // must fall back to a computed size. (Note that gfxASurface can actually
162 // measure itself, but we must |return false| here because it serves as the
163 // (conservative) default for all the sub-classes. Therefore, this
164 // function should only be called on a |gfxASurface*| that actually points
165 // to a sub-class of gfxASurface.)
166 virtual bool SizeOfIsMeasured() const { return false; }
168 /**
169 * Where does this surface's memory live? By default, we say it's in this
170 * process's heap.
171 */
172 virtual gfxMemoryLocation GetMemoryLocation() const;
174 static int32_t BytePerPixelFromFormat(gfxImageFormat format);
176 virtual const nsIntSize GetSize() const;
178 /**
179 * Debug functions to encode the current image as a PNG and export it.
180 */
182 /**
183 * Writes a binary PNG file.
184 */
185 void WriteAsPNG(const char* aFile);
187 /**
188 * Write as a PNG encoded Data URL to a file.
189 */
190 void DumpAsDataURL(FILE* aOutput = stdout);
192 /**
193 * Write as a PNG encoded Data URL to stdout.
194 */
195 void PrintAsDataURL();
197 /**
198 * Copy a PNG encoded Data URL to the clipboard.
199 */
200 void CopyAsDataURL();
202 void WriteAsPNG_internal(FILE* aFile, bool aBinary);
204 void SetOpaqueRect(const gfxRect& aRect);
206 const gfxRect& GetOpaqueRect() {
207 if (!!mOpaqueRect)
208 return *mOpaqueRect;
209 return GetEmptyOpaqueRect();
210 }
212 /**
213 * Move the pixels in |aSourceRect| to |aDestTopLeft|. Like with
214 * memmove(), |aSourceRect| and the rectangle defined by
215 * |aDestTopLeft| are allowed to overlap, and the effect is
216 * equivalent to copying |aSourceRect| to a scratch surface and
217 * then back to |aDestTopLeft|.
218 *
219 * |aSourceRect| and the destination rectangle defined by
220 * |aDestTopLeft| are clipped to this surface's bounds.
221 */
222 virtual void MovePixels(const nsIntRect& aSourceRect,
223 const nsIntPoint& aDestTopLeft);
225 /**
226 * Mark the surface as being allowed/not allowed to be used as a source.
227 */
228 void SetAllowUseAsSource(bool aAllow) { mAllowUseAsSource = aAllow; }
229 bool GetAllowUseAsSource() { return mAllowUseAsSource; }
231 static uint8_t BytesPerPixel(gfxImageFormat aImageFormat);
233 protected:
234 gfxASurface();
236 static gfxASurface* GetSurfaceWrapper(cairo_surface_t *csurf);
237 static void SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf);
239 /**
240 * An implementation of MovePixels that assumes the backend can
241 * internally handle this operation and doesn't allocate any
242 * temporary surfaces.
243 */
244 void FastMovePixels(const nsIntRect& aSourceRect,
245 const nsIntPoint& aDestTopLeft);
247 // NB: Init() *must* be called from within subclass's
248 // constructors. It's unsafe to call it after the ctor finishes;
249 // leaks and use-after-frees are possible.
250 void Init(cairo_surface_t *surface, bool existingSurface = false);
252 // out-of-line helper to allow GetOpaqueRect() to be inlined
253 // without including gfxRect.h here
254 static const gfxRect& GetEmptyOpaqueRect();
256 virtual ~gfxASurface();
258 cairo_surface_t *mSurface;
259 mozilla::ScopedDeletePtr<gfxRect> mOpaqueRect;
261 private:
262 static void SurfaceDestroyFunc(void *data);
264 int32_t mFloatingRefs;
265 int32_t mBytesRecorded;
267 protected:
268 bool mSurfaceValid;
269 bool mAllowUseAsSource;
270 };
272 /**
273 * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo
274 */
275 class gfxUnknownSurface : public gfxASurface {
276 public:
277 gfxUnknownSurface(cairo_surface_t *surf, const gfxIntSize& aSize)
278 : mSize(aSize)
279 {
280 Init(surf, true);
281 }
283 virtual ~gfxUnknownSurface() { }
284 virtual const nsIntSize GetSize() const { return mSize; }
286 private:
287 nsIntSize mSize;
288 };
290 #endif /* GFX_ASURFACE_H */