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: 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 #include "SourceSurfaceCairo.h"
7 #include "DrawTargetCairo.h"
8 #include "HelpersCairo.h"
9 #include "DataSourceSurfaceWrapper.h"
11 #include "cairo.h"
13 namespace mozilla {
14 namespace gfx {
16 static SurfaceFormat
17 CairoFormatToSurfaceFormat(cairo_format_t format)
18 {
19 switch (format)
20 {
21 case CAIRO_FORMAT_ARGB32:
22 return SurfaceFormat::B8G8R8A8;
23 case CAIRO_FORMAT_RGB24:
24 return SurfaceFormat::B8G8R8X8;
25 case CAIRO_FORMAT_A8:
26 return SurfaceFormat::A8;
27 default:
28 return SurfaceFormat::B8G8R8A8;
29 }
30 }
32 SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface,
33 const IntSize& aSize,
34 const SurfaceFormat& aFormat,
35 DrawTargetCairo* aDrawTarget /* = nullptr */)
36 : mSize(aSize)
37 , mFormat(aFormat)
38 , mSurface(aSurface)
39 , mDrawTarget(aDrawTarget)
40 {
41 cairo_surface_reference(mSurface);
42 }
44 SourceSurfaceCairo::~SourceSurfaceCairo()
45 {
46 cairo_surface_destroy(mSurface);
47 }
49 IntSize
50 SourceSurfaceCairo::GetSize() const
51 {
52 return mSize;
53 }
55 SurfaceFormat
56 SourceSurfaceCairo::GetFormat() const
57 {
58 return mFormat;
59 }
61 TemporaryRef<DataSourceSurface>
62 SourceSurfaceCairo::GetDataSurface()
63 {
64 RefPtr<DataSourceSurface> dataSurf;
66 if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
67 dataSurf = new DataSourceSurfaceCairo(mSurface);
68 } else {
69 cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat),
70 mSize.width, mSize.height);
72 // Fill the new image surface with the contents of our surface.
73 cairo_t* ctx = cairo_create(imageSurf);
74 cairo_set_source_surface(ctx, mSurface, 0, 0);
75 cairo_paint(ctx);
76 cairo_destroy(ctx);
78 dataSurf = new DataSourceSurfaceCairo(imageSurf);
79 cairo_surface_destroy(imageSurf);
80 }
82 // We also need to make sure that the returned surface has
83 // surface->GetType() == SurfaceType::DATA.
84 dataSurf = new DataSourceSurfaceWrapper(dataSurf);
86 return dataSurf;
87 }
89 cairo_surface_t*
90 SourceSurfaceCairo::GetSurface() const
91 {
92 return mSurface;
93 }
95 void
96 SourceSurfaceCairo::DrawTargetWillChange()
97 {
98 if (mDrawTarget) {
99 mDrawTarget = nullptr;
101 // We're about to lose our version of the surface, so make a copy of it.
102 cairo_surface_t* surface = cairo_surface_create_similar(mSurface,
103 GfxFormatToCairoContent(mFormat),
104 mSize.width, mSize.height);
105 cairo_t* ctx = cairo_create(surface);
106 cairo_pattern_t* pat = cairo_pattern_create_for_surface(mSurface);
107 cairo_set_source(ctx, pat);
108 cairo_paint(ctx);
109 cairo_destroy(ctx);
110 cairo_pattern_destroy(pat);
112 // Swap in this new surface.
113 cairo_surface_destroy(mSurface);
114 mSurface = surface;
115 }
116 }
118 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf)
119 : mImageSurface(imageSurf)
120 {
121 cairo_surface_reference(mImageSurface);
122 }
124 DataSourceSurfaceCairo::~DataSourceSurfaceCairo()
125 {
126 cairo_surface_destroy(mImageSurface);
127 }
129 unsigned char *
130 DataSourceSurfaceCairo::GetData()
131 {
132 return cairo_image_surface_get_data(mImageSurface);
133 }
135 int32_t
136 DataSourceSurfaceCairo::Stride()
137 {
138 return cairo_image_surface_get_stride(mImageSurface);
139 }
141 IntSize
142 DataSourceSurfaceCairo::GetSize() const
143 {
144 IntSize size;
145 size.width = cairo_image_surface_get_width(mImageSurface);
146 size.height = cairo_image_surface_get_height(mImageSurface);
148 return size;
149 }
151 SurfaceFormat
152 DataSourceSurfaceCairo::GetFormat() const
153 {
154 return CairoFormatToSurfaceFormat(cairo_image_surface_get_format(mImageSurface));
155 }
157 cairo_surface_t*
158 DataSourceSurfaceCairo::GetSurface() const
159 {
160 return mImageSurface;
161 }
163 }
164 }