1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef mozilla_widget_CompositorWidget_h__
6 #define mozilla_widget_CompositorWidget_h__
7 
8 #include "nsISupports.h"
9 #include "mozilla/RefPtr.h"
10 #include "Units.h"
11 #include "mozilla/gfx/2D.h"
12 #include "mozilla/layers/CompositorOptions.h"
13 #include "mozilla/layers/LayersTypes.h"
14 #include "mozilla/layers/NativeLayer.h"
15 
16 class nsIWidget;
17 class nsBaseWidget;
18 
19 namespace mozilla {
20 class VsyncObserver;
21 namespace gl {
22 class GLContext;
23 }  // namespace gl
24 namespace layers {
25 class Compositor;
26 class LayerManager;
27 class LayerManagerComposite;
28 class Compositor;
29 }  // namespace layers
30 namespace gfx {
31 class DrawTarget;
32 class SourceSurface;
33 }  // namespace gfx
34 namespace widget {
35 
36 class WinCompositorWidget;
37 class GtkCompositorWidget;
38 class AndroidCompositorWidget;
39 class CompositorWidgetInitData;
40 
41 // Gecko widgets usually need to communicate with the CompositorWidget with
42 // platform-specific messages (for example to update the window size or
43 // transparency). This functionality is controlled through a "host". Since
44 // this functionality is platform-dependent, it is only forward declared
45 // here.
46 class PlatformCompositorWidgetDelegate;
47 
48 // Headless mode uses its own, singular CompositorWidget implementation.
49 class HeadlessCompositorWidget;
50 
51 class CompositorWidgetDelegate {
52  public:
AsPlatformSpecificDelegate()53   virtual PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() {
54     return nullptr;
55   }
56 
AsHeadlessCompositorWidget()57   virtual HeadlessCompositorWidget* AsHeadlessCompositorWidget() {
58     return nullptr;
59   }
60 };
61 
62 // Platforms that support out-of-process widgets.
63 #if defined(XP_WIN) || defined(MOZ_X11)
64 // CompositorWidgetParent should implement CompositorWidget and
65 // PCompositorWidgetParent.
66 class CompositorWidgetParent;
67 
68 // CompositorWidgetChild should implement CompositorWidgetDelegate and
69 // PCompositorWidgetChild.
70 class CompositorWidgetChild;
71 
72 #  define MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
73 #endif
74 
75 class WidgetRenderingContext {
76  public:
77 #if defined(XP_MACOSX)
78   gl::GLContext* mGL = nullptr;
79 #endif
80 };
81 
82 /**
83  * Access to a widget from the compositor is restricted to these methods.
84  */
85 class CompositorWidget {
86  public:
87   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::widget::CompositorWidget)
88 
89   /**
90    * Create an in-process compositor widget. aWidget may be ignored if the
91    * platform does not require it.
92    */
93   static RefPtr<CompositorWidget> CreateLocal(
94       const CompositorWidgetInitData& aInitData,
95       const layers::CompositorOptions& aOptions, nsIWidget* aWidget);
96 
97   /**
98    * Called before rendering using OMTC. Returns false when the widget is
99    * not ready to be rendered (for example while the window is closed).
100    *
101    * Always called from the compositing thread, which may be the main-thread if
102    * OMTC is not enabled.
103    */
PreRender(WidgetRenderingContext * aContext)104   virtual bool PreRender(WidgetRenderingContext* aContext) { return true; }
105 
106   /**
107    * Called after rendering using OMTC. Not called when rendering was
108    * cancelled by a negative return value from PreRender.
109    *
110    * Always called from the compositing thread, which may be the main-thread if
111    * OMTC is not enabled.
112    */
PostRender(WidgetRenderingContext * aContext)113   virtual void PostRender(WidgetRenderingContext* aContext) {}
114 
115   /**
116    * Called before the first composite. If the result is non-null, one or more
117    * native layers will be placed on the window and used for compositing.
118    * When native layers are used, StartRemoteDrawing(InRegion) and
119    * EndRemoteDrawing(InRegion) will not be called.
120    */
GetNativeLayerRoot()121   virtual RefPtr<layers::NativeLayerRoot> GetNativeLayerRoot() {
122     return nullptr;
123   }
124 
125   /**
126    * Return a DrawTarget for the window which can be composited into.
127    *
128    * Only called if GetNativeLayerRoot() returns nullptr.
129    * Called by BasicCompositor on the compositor thread for OMTC drawing
130    * before each composition (unless there's a native layer root).
131    *
132    * The window may specify its buffer mode. If unspecified, it is assumed
133    * to require double-buffering.
134    */
135   virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawing();
StartRemoteDrawingInRegion(LayoutDeviceIntRegion & aInvalidRegion,layers::BufferMode * aBufferMode)136   virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
137       LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) {
138     return StartRemoteDrawing();
139   }
140 
141   /**
142    * Ensure that what was painted into the DrawTarget returned from
143    * StartRemoteDrawing reaches the screen.
144    *
145    * Called by BasicCompositor on the compositor thread for OMTC drawing
146    * after each composition for which StartRemoteDrawing(InRegion) was called.
147    */
EndRemoteDrawing()148   virtual void EndRemoteDrawing() {}
EndRemoteDrawingInRegion(gfx::DrawTarget * aDrawTarget,const LayoutDeviceIntRegion & aInvalidRegion)149   virtual void EndRemoteDrawingInRegion(
150       gfx::DrawTarget* aDrawTarget,
151       const LayoutDeviceIntRegion& aInvalidRegion) {
152     EndRemoteDrawing();
153   }
154 
155   /**
156    * Return true when it is better to defer EndRemoteDrawing().
157    *
158    * Called by BasicCompositor on the compositor thread for OMTC drawing
159    * after each composition.
160    */
NeedsToDeferEndRemoteDrawing()161   virtual bool NeedsToDeferEndRemoteDrawing() { return false; }
162 
163   /**
164    * Called when shutting down the LayerManager to clean-up any cached
165    * resources.
166    *
167    * Always called from the compositing thread.
168    */
CleanupWindowEffects()169   virtual void CleanupWindowEffects() {}
170 
171   /**
172    * A hook for the widget to prepare a Compositor, during the latter's
173    * initialization.
174    *
175    * If this method returns true, it means that the widget will be able to
176    * present frames from the compoositor.
177    *
178    * Returning false will cause the compositor's initialization to fail, and
179    * a different compositor backend will be used (if any).
180    */
InitCompositor(layers::Compositor * aCompositor)181   virtual bool InitCompositor(layers::Compositor* aCompositor) { return true; }
182 
183   /**
184    * Return the size of the drawable area of the widget.
185    */
186   virtual LayoutDeviceIntSize GetClientSize() = 0;
187 
188   /**
189    * Return the internal format of the default framebuffer for this
190    * widget.
191    */
192   virtual uint32_t GetGLFrameBufferFormat();
193 
194   /*
195    * Access the underlying nsIWidget. This method will be removed when the
196    * compositor no longer depends on nsIWidget on any platform.
197    */
198   virtual nsIWidget* RealWidget() = 0;
199 
200   /**
201    * Clean up any resources used by Start/EndRemoteDrawing.
202    *
203    * Called by BasicCompositor on the compositor thread for OMTC drawing
204    * when the compositor is destroyed.
205    */
206   virtual void CleanupRemoteDrawing();
207 
208   /**
209    * Return a key that can represent the widget object round-trip across the
210    * CompositorBridge channel. This only needs to be implemented on GTK and
211    * Windows.
212    *
213    * The key must be the nsIWidget pointer cast to a uintptr_t. See
214    * CompositorBridgeChild::RecvHideAllPlugins and
215    * CompositorBridgeParent::SendHideAllPlugins.
216    */
GetWidgetKey()217   virtual uintptr_t GetWidgetKey() { return 0; }
218 
219   /**
220    * Create a backbuffer for the software compositor.
221    */
222   virtual already_AddRefed<gfx::DrawTarget> GetBackBufferDrawTarget(
223       gfx::DrawTarget* aScreenTarget, const gfx::IntRect& aRect,
224       bool* aOutIsCleared);
225 
226   /**
227    * Ensure end of composition to back buffer.
228    *
229    * Called by BasicCompositor on the compositor thread for OMTC drawing
230    * after each composition to back buffer.
231    */
232   virtual already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing();
233 
234 #ifdef XP_MACOSX
235   /**
236    * Return the opaque region of the widget. This is racy and can only be used
237    * on macOS, where the widget works around the raciness.
238    * Bug 1576491 tracks fixing this properly.
239    * The problem with this method is that it can return values "from the future"
240    * - the compositor might be working on frame N but the widget will return its
241    * opaque region from frame N + 1.
242    * It is believed that this won't lead to visible glitches on macOS due to the
243    * SuspendAsyncCATransactions call when the vibrant region changes or when the
244    * window resizes. Whenever the compositor uses an opaque region that's a
245    * frame ahead, the result it renders won't be shown on the screen; instead,
246    * the next composite will happen with the correct display list, and that's
247    * what's shown on the screen once the FlushRendering call completes.
248    */
GetOpaqueWidgetRegion()249   virtual LayoutDeviceIntRegion GetOpaqueWidgetRegion() { return {}; }
250 #endif
251 
252   /**
253    * Observe or unobserve vsync.
254    */
255   virtual void ObserveVsync(VsyncObserver* aObserver) = 0;
256 
257   /**
258    * Get the compositor options for the compositor associated with this
259    * CompositorWidget.
260    */
GetCompositorOptions()261   const layers::CompositorOptions& GetCompositorOptions() { return mOptions; }
262 
263   /**
264    * Return true if the window is hidden and should not be composited.
265    */
IsHidden()266   virtual bool IsHidden() const { return false; }
267 
268   /**
269    * This is only used by out-of-process compositors.
270    */
271   virtual RefPtr<VsyncObserver> GetVsyncObserver() const;
272 
AsWindows()273   virtual WinCompositorWidget* AsWindows() { return nullptr; }
AsX11()274   virtual GtkCompositorWidget* AsX11() { return nullptr; }
AsAndroid()275   virtual AndroidCompositorWidget* AsAndroid() { return nullptr; }
276 
277   /**
278    * Return the platform-specific delegate for the widget, if any.
279    */
AsDelegate()280   virtual CompositorWidgetDelegate* AsDelegate() { return nullptr; }
281 
282  protected:
283   explicit CompositorWidget(const layers::CompositorOptions& aOptions);
284   virtual ~CompositorWidget();
285 
286   // Back buffer of BasicCompositor
287   RefPtr<gfx::DrawTarget> mLastBackBuffer;
288 
289   layers::CompositorOptions mOptions;
290 };
291 
292 }  // namespace widget
293 }  // namespace mozilla
294 
295 #endif
296