Skip to content

Commit

Permalink
browser(firefox): screencast for headless mac (microsoft#2956)
Browse files Browse the repository at this point in the history
  • Loading branch information
yury-s authored Jul 15, 2020
1 parent 4a00e5c commit 0aff9be
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 41 deletions.
4 changes: 2 additions & 2 deletions browser_patches/firefox/BUILD_NUMBER
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
1127
Changed: [email protected] Tue Jul 14 12:47:49 PDT 2020
1128
Changed: [email protected] Wed Jul 15 09:22:48 PDT 2020
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ nsresult nsScreencastService::StartVideoRecording(nsIDocShell* aDocShell, const
return NS_ERROR_UNEXPECTED;
nsIWidget* widget = view->GetWidget();

#ifdef MOZ_WIDGET_GTK
*sessionId = ++mLastSessionId;
rtc::scoped_refptr<webrtc::VideoCaptureModule> capturer = CreateWindowCapturer(widget, *sessionId);
if (!capturer)
Expand All @@ -154,10 +153,6 @@ nsresult nsScreencastService::StartVideoRecording(nsIDocShell* aDocShell, const

mIdToSession.emplace(*sessionId, std::move(session));
return NS_OK;
#else
// TODO: support Windows and Mac.
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}

nsresult nsScreencastService::StopVideoRecording(int32_t sessionId) {
Expand Down
105 changes: 71 additions & 34 deletions browser_patches/firefox/patches/bootstrap.diff
Original file line number Diff line number Diff line change
Expand Up @@ -1810,8 +1810,34 @@ index ea8b9b08f3e6f6e99b8a4fa3fa427beb8c5f5945..a7ec2bd3afe53d500f0cd8f800223ee2
};

/**
diff --git a/widget/InProcessCompositorWidget.cpp b/widget/InProcessCompositorWidget.cpp
index 7d7ef5a5f9e6c092e643eb5c3feef239e90c0bb2..7c975244f26b3c2ec20d8174e5d84fc9938860a9 100644
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -4,6 +4,8 @@

#include "InProcessCompositorWidget.h"

+#include "HeadlessCompositorWidget.h"
+#include "HeadlessWidget.h"
#include "mozilla/VsyncDispatcher.h"
#include "nsBaseWidget.h"

@@ -22,6 +24,12 @@ RefPtr<CompositorWidget> CompositorWidget::CreateLocal(
const CompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions, nsIWidget* aWidget) {
MOZ_ASSERT(aWidget);
+ if (aInitData.type() ==
+ CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
+ return new HeadlessCompositorWidget(
+ aInitData.get_HeadlessCompositorWidgetInitData(), aOptions,
+ static_cast<HeadlessWidget*>(aWidget));
+ }
# ifdef MOZ_WIDGET_ANDROID
return new AndroidCompositorWidget(aOptions,
static_cast<nsBaseWidget*>(aWidget));
diff --git a/widget/headless/HeadlessCompositorWidget.cpp b/widget/headless/HeadlessCompositorWidget.cpp
index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac068503639b33887 100644
index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..5f4080dacc1376cda7ec75ed0ed2823cd01d6001 100644
--- a/widget/headless/HeadlessCompositorWidget.cpp
+++ b/widget/headless/HeadlessCompositorWidget.cpp
@@ -3,6 +3,7 @@
Expand All @@ -1822,7 +1848,7 @@ index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac0685036
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "HeadlessCompositorWidget.h"
#include "VsyncDispatcher.h"
@@ -17,6 +18,54 @@ HeadlessCompositorWidget::HeadlessCompositorWidget(
@@ -17,6 +18,32 @@ HeadlessCompositorWidget::HeadlessCompositorWidget(
mClientSize = aInitData.InitialClientSize();
}

Expand All @@ -1839,6 +1865,7 @@ index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac0685036
+ MOZ_ASSERT(NS_IsInCompositorThread());
+ mSnapshotListener = std::move(listener);
+ UpdateDrawTarget();
+ PeriodicSnapshot();
+}
+
+already_AddRefed<gfx::DrawTarget> HeadlessCompositorWidget::StartRemoteDrawingInRegion(
Expand All @@ -1850,34 +1877,11 @@ index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac0685036
+ RefPtr<gfx::DrawTarget> result = mDrawTarget;
+ return result.forget();
+}
+
+void HeadlessCompositorWidget::EndRemoteDrawingInRegion(
+ gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
+ if (!mDrawTarget)
+ return;
+
+ if (!mSnapshotListener)
+ return;
+
+ RefPtr<gfx::SourceSurface> snapshot = mDrawTarget->Snapshot();
+ if (!snapshot) {
+ fprintf(stderr, "Failed to get snapshot of draw target\n");
+ return;
+ }
+
+ RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
+ if (!dataSurface) {
+ fprintf(stderr, "Failed to get data surface from snapshot\n");
+ return;
+ }
+
+ mSnapshotListener(std::move(dataSurface));
+}
+
void HeadlessCompositorWidget::ObserveVsync(VsyncObserver* aObserver) {
if (RefPtr<CompositorVsyncDispatcher> cvd =
mWidget->GetCompositorVsyncDispatcher()) {
@@ -29,6 +78,25 @@ nsIWidget* HeadlessCompositorWidget::RealWidget() { return mWidget; }
@@ -29,6 +56,51 @@ nsIWidget* HeadlessCompositorWidget::RealWidget() { return mWidget; }
void HeadlessCompositorWidget::NotifyClientSizeChanged(
const LayoutDeviceIntSize& aClientSize) {
mClientSize = aClientSize;
Expand All @@ -1900,14 +1904,40 @@ index b31a969b7ab3d0fc80912b110d91dfdf3e5991f4..41f483959bd80aa9cc6ad9eac0685036
+ // TODO: this is called on Main thread, while Start/End drawing are on Compositor thread.
+ mDrawTarget = mozilla::gfx::Factory::CreateDrawTarget(
+ mozilla::gfx::BackendType::SKIA, size, format);
+}
+
+void HeadlessCompositorWidget::PeriodicSnapshot() {
+ if (!mDrawTarget)
+ return;
+
+ if (!mSnapshotListener)
+ return;
+
+ RefPtr<gfx::SourceSurface> snapshot = mDrawTarget->Snapshot();
+ if (!snapshot) {
+ fprintf(stderr, "Failed to get snapshot of draw target\n");
+ return;
+ }
+
+ RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
+ if (!dataSurface) {
+ fprintf(stderr, "Failed to get data surface from snapshot\n");
+ return;
+ }
+
+ mSnapshotListener(std::move(dataSurface));
+
+ NS_DelayedDispatchToCurrentThread(NewRunnableMethod(
+ "HeadlessCompositorWidget::PeriodicSnapshot", this,
+ &HeadlessCompositorWidget::PeriodicSnapshot), 40);
}

LayoutDeviceIntSize HeadlessCompositorWidget::GetClientSize() {
diff --git a/widget/headless/HeadlessCompositorWidget.h b/widget/headless/HeadlessCompositorWidget.h
index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..849cd6f98982fbabc8e483c8bb8f7935225869fc 100644
index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..e6d542ac3945a1845d604e1c24bf7505fcc40e13 100644
--- a/widget/headless/HeadlessCompositorWidget.h
+++ b/widget/headless/HeadlessCompositorWidget.h
@@ -23,9 +23,16 @@ class HeadlessCompositorWidget final : public CompositorWidget,
@@ -23,9 +23,13 @@ class HeadlessCompositorWidget final : public CompositorWidget,
HeadlessWidget* aWindow);

void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
Expand All @@ -1917,19 +1947,17 @@ index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..849cd6f98982fbabc8e483c8bb8f7935

+ already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
+ LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) override;
+ void EndRemoteDrawingInRegion(
+ gfx::DrawTarget* aDrawTarget,
+ const LayoutDeviceIntRegion& aInvalidRegion) override;
+
uintptr_t GetWidgetKey() override;

LayoutDeviceIntSize GetClientSize() override;
@@ -42,9 +49,15 @@ class HeadlessCompositorWidget final : public CompositorWidget,
@@ -42,9 +46,16 @@ class HeadlessCompositorWidget final : public CompositorWidget,
}

private:
+ void SetSnapshotListenerOnCompositorThread(HeadlessWidget::SnapshotListener&& listener);
+ void UpdateDrawTarget();
+ void PeriodicSnapshot();
+
HeadlessWidget* mWidget;

Expand All @@ -1941,10 +1969,19 @@ index 7f91de9e67d7ffa02de3eef1d760e5cfd05e7ad6..849cd6f98982fbabc8e483c8bb8f7935

} // namespace widget
diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
index 7589d8a1a886dab5431e423d20f7d0aa19c2af75..19dd67a330848b6b39bfc578a6940385329fff8e 100644
index 7589d8a1a886dab5431e423d20f7d0aa19c2af75..b14925a7b6972c120a59f70fbbe70a1145a5cb4e 100644
--- a/widget/headless/HeadlessWidget.cpp
+++ b/widget/headless/HeadlessWidget.cpp
@@ -499,5 +499,13 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPoint(
@@ -104,6 +104,8 @@ void HeadlessWidget::Destroy() {
}
}

+ SetSnapshotListener(nullptr);
+
nsBaseWidget::OnDestroy();

nsBaseWidget::Destroy();
@@ -499,5 +501,13 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPoint(
return NS_OK;
}

Expand Down

0 comments on commit 0aff9be

Please sign in to comment.