diff options
Diffstat (limited to 'widget/CompositorWidget.h')
-rw-r--r-- | widget/CompositorWidget.h | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/widget/CompositorWidget.h b/widget/CompositorWidget.h new file mode 100644 index 0000000000..1ae80029c7 --- /dev/null +++ b/widget/CompositorWidget.h @@ -0,0 +1,287 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_widget_CompositorWidget_h__ +#define mozilla_widget_CompositorWidget_h__ + +#include "nsISupports.h" +#include "mozilla/RefPtr.h" +#include "Units.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/layers/CompositorOptions.h" +#include "mozilla/layers/LayersTypes.h" + +#ifdef MOZ_IS_GCC +# include "mozilla/layers/NativeLayer.h" +#endif + +class nsIWidget; +class nsBaseWidget; + +namespace mozilla { +class VsyncObserver; +namespace gl { +class GLContext; +} // namespace gl +namespace layers { +class Compositor; +class LayerManager; +class LayerManagerComposite; +class NativeLayerRoot; +} // namespace layers +namespace gfx { +class DrawTarget; +class SourceSurface; +} // namespace gfx +namespace widget { + +class WinCompositorWidget; +class GtkCompositorWidget; +class AndroidCompositorWidget; +class CompositorWidgetInitData; + +// Gecko widgets usually need to communicate with the CompositorWidget with +// platform-specific messages (for example to update the window size or +// transparency). This functionality is controlled through a "host". Since +// this functionality is platform-dependent, it is only forward declared +// here. +class PlatformCompositorWidgetDelegate; + +// Headless mode uses its own, singular CompositorWidget implementation. +class HeadlessCompositorWidget; + +class CompositorWidgetDelegate { + public: + virtual PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() { + return nullptr; + } + + virtual HeadlessCompositorWidget* AsHeadlessCompositorWidget() { + return nullptr; + } +}; + +// Platforms that support out-of-process widgets. +#if defined(XP_WIN) || defined(MOZ_X11) +// CompositorWidgetParent should implement CompositorWidget and +// PCompositorWidgetParent. +class CompositorWidgetParent; + +// CompositorWidgetChild should implement CompositorWidgetDelegate and +// PCompositorWidgetChild. +class CompositorWidgetChild; + +# define MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING +#endif + +class WidgetRenderingContext { + public: +#if defined(XP_MACOSX) + gl::GLContext* mGL = nullptr; +#endif +}; + +/** + * Access to a widget from the compositor is restricted to these methods. + */ +class CompositorWidget { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::widget::CompositorWidget) + + /** + * Create an in-process compositor widget. aWidget may be ignored if the + * platform does not require it. + */ + static RefPtr<CompositorWidget> CreateLocal( + const CompositorWidgetInitData& aInitData, + const layers::CompositorOptions& aOptions, nsIWidget* aWidget); + + /** + * Called before rendering using OMTC. Returns false when the widget is + * not ready to be rendered (for example while the window is closed). + * + * Always called from the compositing thread, which may be the main-thread if + * OMTC is not enabled. + */ + virtual bool PreRender(WidgetRenderingContext* aContext) { return true; } + + /** + * Called after rendering using OMTC. Not called when rendering was + * cancelled by a negative return value from PreRender. + * + * Always called from the compositing thread, which may be the main-thread if + * OMTC is not enabled. + */ + virtual void PostRender(WidgetRenderingContext* aContext) {} + + /** + * Called before the first composite. If the result is non-null, one or more + * native layers will be placed on the window and used for compositing. + * When native layers are used, StartRemoteDrawing(InRegion) and + * EndRemoteDrawing(InRegion) will not be called. + */ + virtual RefPtr<layers::NativeLayerRoot> GetNativeLayerRoot() { + return nullptr; + } + + /** + * Return a DrawTarget for the window which can be composited into. + * + * Only called if GetNativeLayerRoot() returns nullptr. + * Called by BasicCompositor on the compositor thread for OMTC drawing + * before each composition (unless there's a native layer root). + * + * The window may specify its buffer mode. If unspecified, it is assumed + * to require double-buffering. + */ + virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawing(); + virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion( + LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) { + return StartRemoteDrawing(); + } + + /** + * Ensure that what was painted into the DrawTarget returned from + * StartRemoteDrawing reaches the screen. + * + * Called by BasicCompositor on the compositor thread for OMTC drawing + * after each composition for which StartRemoteDrawing(InRegion) was called. + */ + virtual void EndRemoteDrawing() {} + virtual void EndRemoteDrawingInRegion( + gfx::DrawTarget* aDrawTarget, + const LayoutDeviceIntRegion& aInvalidRegion) { + EndRemoteDrawing(); + } + + /** + * Return true when it is better to defer EndRemoteDrawing(). + * + * Called by BasicCompositor on the compositor thread for OMTC drawing + * after each composition. + */ + virtual bool NeedsToDeferEndRemoteDrawing() { return false; } + + /** + * Some widgets (namely Gtk) may need clean up underlying surface + * before painting to draw transparent objects correctly. + */ + virtual void ClearBeforePaint(RefPtr<gfx::DrawTarget> aTarget, + const LayoutDeviceIntRegion& aRegion) {} + + /** + * Called when shutting down the LayerManager to clean-up any cached + * resources. + * + * Always called from the compositing thread. + */ + virtual void CleanupWindowEffects() {} + + /** + * A hook for the widget to prepare a Compositor, during the latter's + * initialization. + * + * If this method returns true, it means that the widget will be able to + * present frames from the compoositor. + * + * Returning false will cause the compositor's initialization to fail, and + * a different compositor backend will be used (if any). + */ + virtual bool InitCompositor(layers::Compositor* aCompositor) { return true; } + + /** + * Return the size of the drawable area of the widget. + */ + virtual LayoutDeviceIntSize GetClientSize() = 0; + + /** + * Return the internal format of the default framebuffer for this + * widget. + */ + virtual uint32_t GetGLFrameBufferFormat(); + + /* + * Access the underlying nsIWidget. This method will be removed when the + * compositor no longer depends on nsIWidget on any platform. + */ + virtual nsIWidget* RealWidget() = 0; + + /** + * Clean up any resources used by Start/EndRemoteDrawing. + * + * Called by BasicCompositor on the compositor thread for OMTC drawing + * when the compositor is destroyed. + */ + virtual void CleanupRemoteDrawing(); + + /** + * Return a key that can represent the widget object round-trip across the + * CompositorBridge channel. This only needs to be implemented on GTK and + * Windows. + * + * The key must be the nsIWidget pointer cast to a uintptr_t. See + * CompositorBridgeChild::RecvHideAllPlugins and + * CompositorBridgeParent::SendHideAllPlugins. + */ + virtual uintptr_t GetWidgetKey() { return 0; } + + /** + * Create a backbuffer for the software compositor. + */ + virtual already_AddRefed<gfx::DrawTarget> GetBackBufferDrawTarget( + gfx::DrawTarget* aScreenTarget, const gfx::IntRect& aRect, + bool* aOutIsCleared); + + /** + * Ensure end of composition to back buffer. + * + * Called by BasicCompositor on the compositor thread for OMTC drawing + * after each composition to back buffer. + */ + virtual already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing(); + + /** + * Observe or unobserve vsync. + */ + virtual void ObserveVsync(VsyncObserver* aObserver) = 0; + + /** + * Get the compositor options for the compositor associated with this + * CompositorWidget. + */ + const layers::CompositorOptions& GetCompositorOptions() { return mOptions; } + + /** + * Return true if the window is hidden and should not be composited. + */ + virtual bool IsHidden() const { return false; } + + /** + * This is only used by out-of-process compositors. + */ + virtual RefPtr<VsyncObserver> GetVsyncObserver() const; + + virtual WinCompositorWidget* AsWindows() { return nullptr; } + virtual GtkCompositorWidget* AsX11() { return nullptr; } + virtual AndroidCompositorWidget* AsAndroid() { return nullptr; } + + /** + * Return the platform-specific delegate for the widget, if any. + */ + virtual CompositorWidgetDelegate* AsDelegate() { return nullptr; } + + protected: + explicit CompositorWidget(const layers::CompositorOptions& aOptions); + virtual ~CompositorWidget(); + + // Back buffer of BasicCompositor + RefPtr<gfx::DrawTarget> mLastBackBuffer; + + layers::CompositorOptions mOptions; +}; + +} // namespace widget +} // namespace mozilla + +#endif |