forked from mirrors/gecko-dev
Make the vsync source request frame callbacks from opaque native layers. This is necessary as opaque layers may occlude the MozContainer surface, which is normally used for frame callbacks. Wayland compositors may (and are encouraged to) optimize away such callbacks, so we need to make sure to request frame callbacks from actually visible surfaces. Callbacks are requested for all layers, but only the first callback will trigger the vsync source. In order to get this right concerning multiple requested callbacks, possibly being called from different threads etc., introduce a callback abstraction, `CallbackMultiplexHelper`, to make this simple to handle for callers. Differential Revision: https://phabricator.services.mozilla.com/D116026
109 lines
3.4 KiB
C++
109 lines
3.4 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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 widget_gtk_GtkCompositorWidget_h
|
|
#define widget_gtk_GtkCompositorWidget_h
|
|
|
|
#include "GLDefs.h"
|
|
#include "mozilla/DataMutex.h"
|
|
#include "mozilla/widget/CompositorWidget.h"
|
|
#include "WindowSurfaceProvider.h"
|
|
|
|
class nsIWidget;
|
|
class nsWindow;
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
class NativeLayerRootWayland;
|
|
} // namespace layers
|
|
|
|
namespace widget {
|
|
|
|
class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
|
|
public:
|
|
virtual void NotifyClientSizeChanged(
|
|
const LayoutDeviceIntSize& aClientSize) = 0;
|
|
virtual GtkCompositorWidget* AsGtkCompositorWidget() { return nullptr; };
|
|
|
|
// CompositorWidgetDelegate Overrides
|
|
|
|
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
|
return this;
|
|
}
|
|
};
|
|
|
|
class GtkCompositorWidgetInitData;
|
|
|
|
class GtkCompositorWidget : public CompositorWidget,
|
|
public PlatformCompositorWidgetDelegate {
|
|
public:
|
|
GtkCompositorWidget(const GtkCompositorWidgetInitData& aInitData,
|
|
const layers::CompositorOptions& aOptions,
|
|
nsWindow* aWindow /* = nullptr*/);
|
|
~GtkCompositorWidget();
|
|
|
|
// CompositorWidget Overrides
|
|
|
|
already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
|
|
void EndRemoteDrawing() override;
|
|
|
|
already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
|
|
const LayoutDeviceIntRegion& aInvalidRegion,
|
|
layers::BufferMode* aBufferMode) override;
|
|
void EndRemoteDrawingInRegion(
|
|
gfx::DrawTarget* aDrawTarget,
|
|
const LayoutDeviceIntRegion& aInvalidRegion) override;
|
|
uintptr_t GetWidgetKey() override;
|
|
|
|
LayoutDeviceIntSize GetClientSize() override;
|
|
|
|
nsIWidget* RealWidget() override;
|
|
GtkCompositorWidget* AsGTK() override { return this; }
|
|
CompositorWidgetDelegate* AsDelegate() override { return this; }
|
|
|
|
EGLNativeWindowType GetEGLNativeWindow();
|
|
|
|
LayoutDeviceIntRegion GetTransparentRegion() override;
|
|
|
|
#if defined(MOZ_X11)
|
|
Window XWindow() const { return mXWindow; }
|
|
#endif
|
|
#if defined(MOZ_WAYLAND)
|
|
void SetEGLNativeWindowSize(const LayoutDeviceIntSize& aEGLWindowSize);
|
|
RefPtr<mozilla::layers::NativeLayerRoot> GetNativeLayerRoot() override;
|
|
#endif
|
|
|
|
// PlatformCompositorWidgetDelegate Overrides
|
|
|
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
|
GtkCompositorWidget* AsGtkCompositorWidget() override { return this; }
|
|
|
|
protected:
|
|
nsWindow* mWidget;
|
|
|
|
private:
|
|
// This field is written to on the main thread and read from on the compositor
|
|
// or renderer thread. During window resizing, this is subject to a (largely
|
|
// benign) read/write race, see bug 1665726. The DataMutex doesn't prevent the
|
|
// read/write race, but it does make it Not Undefined Behaviour, and also
|
|
// ensures we only ever use the old or new size, and not some weird synthesis
|
|
// of the two.
|
|
DataMutex<LayoutDeviceIntSize> mClientSize;
|
|
|
|
WindowSurfaceProvider mProvider;
|
|
|
|
#if defined(MOZ_X11)
|
|
Window mXWindow = {};
|
|
#endif
|
|
#ifdef MOZ_WAYLAND
|
|
RefPtr<mozilla::layers::NativeLayerRootWayland> mNativeLayerRoot;
|
|
#endif
|
|
};
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
|
|
#endif // widget_gtk_GtkCompositorWidget_h
|