@@ -1810,3 +1810,165 @@ index ea8b9b08f3e6f6e99b8a4fa3fa427beb8c5f5945..a7ec2bd3afe53d500f0cd8f800223ee2
1810
1810
};
1811
1811
1812
1812
/**
1813
+ diff --git a/widget/headless/HeadlessCompositorWidget.cpp b/widget/headless/HeadlessCompositorWidget.cpp
1814
+ index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac068503639b33887 100644
1815
+ --- a/widget/headless/HeadlessCompositorWidget.cpp
1816
+ +++ b/widget/headless/HeadlessCompositorWidget.cpp
1817
+ @@ -3,6 +3,7 @@
1818
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
1819
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
1820
+
1821
+ + #include "mozilla/layers/CompositorThread.h"
1822
+ #include "mozilla/widget/PlatformWidgetTypes.h"
1823
+ #include "HeadlessCompositorWidget.h"
1824
+ #include "VsyncDispatcher.h"
1825
+ @@ -17,6 +18,54 @@ HeadlessCompositorWidget::HeadlessCompositorWidget(
1826
+ mClientSize = aInitData.InitialClientSize();
1827
+ }
1828
+
1829
+ + void HeadlessCompositorWidget::SetSnapshotListener(HeadlessWidget::SnapshotListener&& listener) {
1830
+ + MOZ_ASSERT(NS_IsMainThread());
1831
+ +
1832
+ + layers::CompositorThread()->Dispatch(NewRunnableMethod<HeadlessWidget::SnapshotListener&&>(
1833
+ + "HeadlessCompositorWidget::SetSnapshotListener", this,
1834
+ + &HeadlessCompositorWidget::SetSnapshotListenerOnCompositorThread,
1835
+ + std::move(listener)));
1836
+ + }
1837
+ +
1838
+ + void HeadlessCompositorWidget::SetSnapshotListenerOnCompositorThread(HeadlessWidget::SnapshotListener&& listener) {
1839
+ + MOZ_ASSERT(NS_IsInCompositorThread());
1840
+ + mSnapshotListener = std::move(listener);
1841
+ + UpdateDrawTarget();
1842
+ + }
1843
+ +
1844
+ + already_AddRefed<gfx::DrawTarget> HeadlessCompositorWidget::StartRemoteDrawingInRegion(
1845
+ + LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) {
1846
+ + if (!mDrawTarget)
1847
+ + return nullptr;
1848
+ +
1849
+ + *aBufferMode = layers::BufferMode::BUFFER_NONE;
1850
+ + RefPtr<gfx::DrawTarget> result = mDrawTarget;
1851
+ + return result.forget();
1852
+ + }
1853
+ +
1854
+ + void HeadlessCompositorWidget::EndRemoteDrawingInRegion(
1855
+ + gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
1856
+ + if (!mDrawTarget)
1857
+ + return;
1858
+ +
1859
+ + if (!mSnapshotListener)
1860
+ + return;
1861
+ +
1862
+ + RefPtr<gfx::SourceSurface> snapshot = mDrawTarget->Snapshot();
1863
+ + if (!snapshot) {
1864
+ + fprintf(stderr, "Failed to get snapshot of draw target\n");
1865
+ + return;
1866
+ + }
1867
+ +
1868
+ + RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
1869
+ + if (!dataSurface) {
1870
+ + fprintf(stderr, "Failed to get data surface from snapshot\n");
1871
+ + return;
1872
+ + }
1873
+ +
1874
+ + mSnapshotListener(std::move(dataSurface));
1875
+ + }
1876
+ +
1877
+ void HeadlessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
1878
+ if (RefPtr<CompositorVsyncDispatcher> cvd =
1879
+ mWidget->GetCompositorVsyncDispatcher()) {
1880
+ @@ -29,6 +78,25 @@ nsIWidget* HeadlessCompositorWidget::RealWidget() { return mWidget; }
1881
+ void HeadlessCompositorWidget::NotifyClientSizeChanged(
1882
+ const LayoutDeviceIntSize& aClientSize) {
1883
+ mClientSize = aClientSize;
1884
+ + UpdateDrawTarget();
1885
+ + }
1886
+ +
1887
+ + void HeadlessCompositorWidget::UpdateDrawTarget() {
1888
+ + if (!mSnapshotListener) {
1889
+ + mDrawTarget = nullptr;
1890
+ + return;
1891
+ + }
1892
+ +
1893
+ + if (mClientSize.IsEmpty()) {
1894
+ + mDrawTarget = nullptr;
1895
+ + return;
1896
+ + }
1897
+ +
1898
+ + gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
1899
+ + gfx::IntSize size = mClientSize.ToUnknownSize();
1900
+ + // TODO: this is called on Main thread, while Start/End drawing are on Compositor thread.
1901
+ + mDrawTarget = mozilla::gfx::Factory::CreateDrawTarget(
1902
+ + mozilla::gfx::BackendType::SKIA, size, format);
1903
+ }
1904
+
1905
+ LayoutDeviceIntSize HeadlessCompositorWidget::GetClientSize() {
1906
+ diff --git a/widget/headless/HeadlessCompositorWidget.h b/widget/headless/HeadlessCompositorWidget.h
1907
+ index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..849cd6f98982fbabc8e483c8bb8f7935225869fc 100644
1908
+ --- a/widget/headless/HeadlessCompositorWidget.h
1909
+ +++ b/widget/headless/HeadlessCompositorWidget.h
1910
+ @@ -23,9 +23,16 @@ class HeadlessCompositorWidget final : public CompositorWidget,
1911
+ HeadlessWidget* aWindow);
1912
+
1913
+ void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
1914
+ + void SetSnapshotListener(HeadlessWidget::SnapshotListener&& listener);
1915
+
1916
+ // CompositorWidget Overrides
1917
+
1918
+ + already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
1919
+ + LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) override;
1920
+ + void EndRemoteDrawingInRegion(
1921
+ + gfx::DrawTarget* aDrawTarget,
1922
+ + const LayoutDeviceIntRegion& aInvalidRegion) override;
1923
+ +
1924
+ uintptr_t GetWidgetKey() override;
1925
+
1926
+ LayoutDeviceIntSize GetClientSize() override;
1927
+ @@ -42,9 +49,15 @@ class HeadlessCompositorWidget final : public CompositorWidget,
1928
+ }
1929
+
1930
+ private:
1931
+ + void SetSnapshotListenerOnCompositorThread(HeadlessWidget::SnapshotListener&& listener);
1932
+ + void UpdateDrawTarget();
1933
+ +
1934
+ HeadlessWidget* mWidget;
1935
+
1936
+ LayoutDeviceIntSize mClientSize;
1937
+ +
1938
+ + HeadlessWidget::SnapshotListener mSnapshotListener;
1939
+ + RefPtr<gfx::DrawTarget> mDrawTarget;
1940
+ };
1941
+
1942
+ } // namespace widget
1943
+ diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
1944
+ index 7589d8a1a886dab5431e423d20f7d0aa19c2af75..19dd67a330848b6b39bfc578a6940385329fff8e 100644
1945
+ --- a/widget/headless/HeadlessWidget.cpp
1946
+ +++ b/widget/headless/HeadlessWidget.cpp
1947
+ @@ -499,5 +499,13 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPoint(
1948
+ return NS_OK;
1949
+ }
1950
+
1951
+ + void HeadlessWidget::SetSnapshotListener(SnapshotListener&& listener) {
1952
+ + if (!mCompositorWidget) {
1953
+ + fprintf(stderr, "Trying to set SnapshotListener without compositor widget\n");
1954
+ + return;
1955
+ + }
1956
+ + mCompositorWidget->SetSnapshotListener(std::move(listener));
1957
+ + }
1958
+ +
1959
+ } // namespace widget
1960
+ } // namespace mozilla
1961
+ diff --git a/widget/headless/HeadlessWidget.h b/widget/headless/HeadlessWidget.h
1962
+ index c375629d4a954f872a2abdd6983ae38dbb98f4ca..1857a4874ac9f8a3d7e402b5707a9ea58f241eb9 100644
1963
+ --- a/widget/headless/HeadlessWidget.h
1964
+ +++ b/widget/headless/HeadlessWidget.h
1965
+ @@ -153,6 +153,9 @@ class HeadlessWidget : public nsBaseWidget {
1966
+ uint32_t aPointerOrientation,
1967
+ nsIObserver* aObserver) override;
1968
+
1969
+ + using SnapshotListener = std::function<void(RefPtr<gfx::DataSourceSurface>&&)>;
1970
+ + void SetSnapshotListener(SnapshotListener&& listener);
1971
+ +
1972
+ private:
1973
+ ~HeadlessWidget();
1974
+ bool mEnabled;
0 commit comments