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