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 #ifndef GFX_CONTENTHOST_H
7 #define GFX_CONTENTHOST_H
9 #include <stdint.h> // for uint32_t
10 #include <stdio.h> // for FILE
11 #include "mozilla-config.h" // for MOZ_DUMP_PAINTING
12 #include "CompositableHost.h" // for CompositableHost, etc
13 #include "RotatedBuffer.h" // for RotatedContentBuffer, etc
14 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE
15 #include "mozilla/RefPtr.h" // for RefPtr
16 #include "mozilla/gfx/BasePoint.h" // for BasePoint
17 #include "mozilla/gfx/Point.h" // for Point
18 #include "mozilla/gfx/Rect.h" // for Rect
19 #include "mozilla/gfx/Types.h" // for Filter
20 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
21 #include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
22 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
23 #include "mozilla/layers/LayersTypes.h" // for etc
24 #include "mozilla/layers/TextureHost.h" // for TextureHost
25 #include "mozilla/mozalloc.h" // for operator delete
26 #include "nsAutoPtr.h" // for nsAutoPtr
27 #include "nsCOMPtr.h" // for already_AddRefed
28 #include "nsDebug.h" // for NS_RUNTIMEABORT
29 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
30 #include "nsPoint.h" // for nsIntPoint
31 #include "nsRect.h" // for nsIntRect
32 #include "nsRegion.h" // for nsIntRegion
33 #include "nsTArray.h" // for nsTArray
34 #include "nscore.h" // for nsACString
36 namespace mozilla {
37 namespace gfx {
38 class Matrix4x4;
39 }
40 namespace layers {
41 class Compositor;
42 class ThebesBufferData;
43 class TiledLayerComposer;
44 struct EffectChain;
45 class TextureImageTextureSourceOGL;
47 struct TexturedEffect;
49 /**
50 * ContentHosts are used for compositing Thebes layers, always matched by a
51 * ContentClient of the same type.
52 *
53 * ContentHosts support only UpdateThebes(), not Update().
54 */
55 class ContentHost : public CompositableHost
56 {
57 public:
58 // Subclasses should implement this method if they support being used as a
59 // tiling.
60 virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; }
62 virtual bool UpdateThebes(const ThebesBufferData& aData,
63 const nsIntRegion& aUpdated,
64 const nsIntRegion& aOldValidRegionBack,
65 nsIntRegion* aUpdatedRegionBack) = 0;
67 virtual void SetPaintWillResample(bool aResample) { }
69 protected:
70 ContentHost(const TextureInfo& aTextureInfo)
71 : CompositableHost(aTextureInfo)
72 {}
73 };
75 /**
76 * Base class for non-tiled ContentHosts.
77 *
78 * Ownership of the SurfaceDescriptor and the resources it represents is passed
79 * from the ContentClient to the ContentHost when the TextureClient/Hosts are
80 * created, that is recevied here by SetTextureHosts which assigns one or two
81 * texture hosts (for single and double buffering) to the ContentHost.
82 *
83 * It is the responsibility of the ContentHost to destroy its resources when
84 * they are recreated or the ContentHost dies.
85 */
86 class ContentHostBase : public ContentHost
87 {
88 public:
89 typedef RotatedContentBuffer::ContentType ContentType;
90 typedef RotatedContentBuffer::PaintState PaintState;
92 ContentHostBase(const TextureInfo& aTextureInfo);
93 virtual ~ContentHostBase();
95 virtual void Composite(EffectChain& aEffectChain,
96 float aOpacity,
97 const gfx::Matrix4x4& aTransform,
98 const gfx::Filter& aFilter,
99 const gfx::Rect& aClipRect,
100 const nsIntRegion* aVisibleRegion = nullptr,
101 TiledLayerProperties* aLayerProperties = nullptr);
103 virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
105 virtual bool Lock() = 0;
106 virtual void Unlock() = 0;
108 virtual NewTextureSource* GetTextureSource() = 0;
109 virtual NewTextureSource* GetTextureSourceOnWhite() = 0;
111 protected:
112 virtual nsIntPoint GetOriginOffset()
113 {
114 return mBufferRect.TopLeft() - mBufferRotation;
115 }
117 bool PaintWillResample() { return mPaintWillResample; }
119 nsIntRect mBufferRect;
120 nsIntPoint mBufferRotation;
121 bool mPaintWillResample;
122 bool mInitialised;
123 };
125 /**
126 * Shared ContentHostBase implementation for content hosts that
127 * use up to two TextureHosts.
128 */
129 class ContentHostTexture : public ContentHostBase
130 {
131 public:
132 ContentHostTexture(const TextureInfo& aTextureInfo)
133 : ContentHostBase(aTextureInfo)
134 , mLocked(false)
135 { }
137 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
139 #ifdef MOZ_DUMP_PAINTING
140 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
142 virtual void Dump(FILE* aFile=nullptr,
143 const char* aPrefix="",
144 bool aDumpHtml=false) MOZ_OVERRIDE;
145 #endif
147 virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE;
149 virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
150 virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
151 TextureHost* aTextureOnWhite) MOZ_OVERRIDE;
153 virtual bool Lock() {
154 MOZ_ASSERT(!mLocked);
155 if (!mTextureHost) {
156 return false;
157 }
158 if (!mTextureHost->Lock()) {
159 return false;
160 }
162 if (mTextureHostOnWhite && !mTextureHostOnWhite->Lock()) {
163 return false;
164 }
166 mLocked = true;
167 return true;
168 }
169 virtual void Unlock() {
170 MOZ_ASSERT(mLocked);
171 mTextureHost->Unlock();
172 if (mTextureHostOnWhite) {
173 mTextureHostOnWhite->Unlock();
174 }
175 mLocked = false;
176 }
178 virtual NewTextureSource* GetTextureSource() {
179 MOZ_ASSERT(mLocked);
180 return mTextureHost->GetTextureSources();
181 }
182 virtual NewTextureSource* GetTextureSourceOnWhite() {
183 MOZ_ASSERT(mLocked);
184 if (mTextureHostOnWhite) {
185 return mTextureHostOnWhite->GetTextureSources();
186 }
187 return nullptr;
188 }
190 LayerRenderState GetRenderState();
192 protected:
193 RefPtr<TextureHost> mTextureHost;
194 RefPtr<TextureHost> mTextureHostOnWhite;
195 bool mLocked;
196 };
198 /**
199 * Double buffering is implemented by swapping the front and back TextureHosts.
200 * We assume that whenever we use double buffering, then we have
201 * render-to-texture and thus no texture upload to do.
202 */
203 class ContentHostDoubleBuffered : public ContentHostTexture
204 {
205 public:
206 ContentHostDoubleBuffered(const TextureInfo& aTextureInfo)
207 : ContentHostTexture(aTextureInfo)
208 {}
210 virtual ~ContentHostDoubleBuffered() {}
212 virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_DOUBLE; }
214 virtual bool UpdateThebes(const ThebesBufferData& aData,
215 const nsIntRegion& aUpdated,
216 const nsIntRegion& aOldValidRegionBack,
217 nsIntRegion* aUpdatedRegionBack);
219 protected:
220 nsIntRegion mValidRegionForNextBackBuffer;
221 };
223 /**
224 * Single buffered, therefore we must synchronously upload the image from the
225 * TextureHost in the layers transaction (i.e., in UpdateThebes).
226 */
227 class ContentHostSingleBuffered : public ContentHostTexture
228 {
229 public:
230 ContentHostSingleBuffered(const TextureInfo& aTextureInfo)
231 : ContentHostTexture(aTextureInfo)
232 {}
233 virtual ~ContentHostSingleBuffered() {}
235 virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_SINGLE; }
237 virtual bool UpdateThebes(const ThebesBufferData& aData,
238 const nsIntRegion& aUpdated,
239 const nsIntRegion& aOldValidRegionBack,
240 nsIntRegion* aUpdatedRegionBack);
241 };
243 /**
244 * Maintains a host-side only texture, and gets provided with
245 * surfaces that only cover the changed pixels during an update.
246 *
247 * Takes ownership of the passed in update surfaces, and must
248 * free them once texture upload is complete.
249 *
250 * Delays texture uploads until the next composite to
251 * avoid blocking the main thread.
252 */
253 class ContentHostIncremental : public ContentHostBase
254 {
255 public:
256 ContentHostIncremental(const TextureInfo& aTextureInfo);
257 ~ContentHostIncremental();
259 virtual CompositableType GetType() { return BUFFER_CONTENT_INC; }
261 virtual LayerRenderState GetRenderState() MOZ_OVERRIDE { return LayerRenderState(); }
263 virtual bool CreatedIncrementalTexture(ISurfaceAllocator* aAllocator,
264 const TextureInfo& aTextureInfo,
265 const nsIntRect& aBufferRect) MOZ_OVERRIDE;
267 virtual void UpdateIncremental(TextureIdentifier aTextureId,
268 SurfaceDescriptor& aSurface,
269 const nsIntRegion& aUpdated,
270 const nsIntRect& aBufferRect,
271 const nsIntPoint& aBufferRotation) MOZ_OVERRIDE;
273 virtual bool UpdateThebes(const ThebesBufferData& aData,
274 const nsIntRegion& aUpdated,
275 const nsIntRegion& aOldValidRegionBack,
276 nsIntRegion* aUpdatedRegionBack)
277 {
278 NS_ERROR("Shouldn't call this");
279 return false;
280 }
282 virtual bool Lock() {
283 MOZ_ASSERT(!mLocked);
284 ProcessTextureUpdates();
285 mLocked = true;
286 return true;
287 }
289 virtual void Unlock() {
290 MOZ_ASSERT(mLocked);
291 mLocked = false;
292 }
294 virtual NewTextureSource* GetTextureSource();
295 virtual NewTextureSource* GetTextureSourceOnWhite();
297 private:
299 void FlushUpdateQueue();
300 void ProcessTextureUpdates();
302 class Request
303 {
304 public:
305 Request()
306 {
307 MOZ_COUNT_CTOR(ContentHostIncremental::Request);
308 }
310 virtual ~Request()
311 {
312 MOZ_COUNT_DTOR(ContentHostIncremental::Request);
313 }
315 virtual void Execute(ContentHostIncremental *aHost) = 0;
316 };
318 class TextureCreationRequest : public Request
319 {
320 public:
321 TextureCreationRequest(const TextureInfo& aTextureInfo,
322 const nsIntRect& aBufferRect)
323 : mTextureInfo(aTextureInfo)
324 , mBufferRect(aBufferRect)
325 {}
327 virtual void Execute(ContentHostIncremental *aHost);
329 private:
330 TextureInfo mTextureInfo;
331 nsIntRect mBufferRect;
332 };
334 class TextureUpdateRequest : public Request
335 {
336 public:
337 TextureUpdateRequest(ISurfaceAllocator* aDeAllocator,
338 TextureIdentifier aTextureId,
339 SurfaceDescriptor& aDescriptor,
340 const nsIntRegion& aUpdated,
341 const nsIntRect& aBufferRect,
342 const nsIntPoint& aBufferRotation)
343 : mDeAllocator(aDeAllocator)
344 , mTextureId(aTextureId)
345 , mDescriptor(aDescriptor)
346 , mUpdated(aUpdated)
347 , mBufferRect(aBufferRect)
348 , mBufferRotation(aBufferRotation)
349 {}
351 ~TextureUpdateRequest()
352 {
353 //TODO: Recycle these?
354 mDeAllocator->DestroySharedSurface(&mDescriptor);
355 }
357 virtual void Execute(ContentHostIncremental *aHost);
359 private:
360 enum XSide {
361 LEFT, RIGHT
362 };
363 enum YSide {
364 TOP, BOTTOM
365 };
367 nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const;
369 RefPtr<ISurfaceAllocator> mDeAllocator;
370 TextureIdentifier mTextureId;
371 SurfaceDescriptor mDescriptor;
372 nsIntRegion mUpdated;
373 nsIntRect mBufferRect;
374 nsIntPoint mBufferRotation;
375 };
377 nsTArray<nsAutoPtr<Request> > mUpdateList;
379 // Specific to OGL to avoid exposing methods on TextureSource that only
380 // have one implementation.
381 RefPtr<TextureImageTextureSourceOGL> mSource;
382 RefPtr<TextureImageTextureSourceOGL> mSourceOnWhite;
384 RefPtr<ISurfaceAllocator> mDeAllocator;
385 bool mLocked;
386 };
388 }
389 }
391 #endif