Bug 1498205 - Move PlatformUIThread from rtc_base to video_engine; r=pehrsons
authorDan Minor <dminor@mozilla.com>
Fri, 30 Nov 2018 17:46:38 +0000
changeset 505492 65bf3e37a4409f3ca0350366d7be19368adfa21b
parent 505491 b9dcfde98e47814fdcefc6329e65b8337c74ae3d
child 505493 00269c0edf56d1a920d1b0dfd757ae9221c40e30
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1498205
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1498205 - Move PlatformUIThread from rtc_base to video_engine; r=pehrsons PlatformUIThread is only used by the video_engine code, so it makes sense to move it there rather than maintain it as a diff against upstream webrtc.org. Differential Revision: https://phabricator.services.mozilla.com/D13531
dom/media/systemservices/moz.build
dom/media/systemservices/video_engine/desktop_capture_impl.cc
dom/media/systemservices/video_engine/desktop_capture_impl.h
dom/media/systemservices/video_engine/platform_uithread.cc
dom/media/systemservices/video_engine/platform_uithread.h
media/webrtc/trunk/webrtc/rtc_base/platform_thread.cc
media/webrtc/trunk/webrtc/rtc_base/platform_thread.h
--- a/dom/media/systemservices/moz.build
+++ b/dom/media/systemservices/moz.build
@@ -24,16 +24,17 @@ if CONFIG['MOZ_WEBRTC']:
         '/media/webrtc/signaling',
         '/media/webrtc/trunk',
         '/media/webrtc/trunk/webrtc',
     ]
 
     if CONFIG['OS_TARGET'] != 'Android':
         UNIFIED_SOURCES += [
             'video_engine/desktop_capture_impl.cc',
+            'video_engine/platform_uithread.cc',
         ]
 
 if CONFIG['OS_TARGET'] == 'Android':
     DEFINES['WEBRTC_ANDROID'] = True
 
 
 if CONFIG['OS_TARGET'] == 'Android':
     EXPORTS += [
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.cc
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.cc
@@ -25,16 +25,22 @@
 #include "rtc_base/trace_event.h"
 #include "video_engine/desktop_capture_impl.h"
 #include "modules/desktop_capture/desktop_frame.h"
 #include "modules/desktop_capture/desktop_device_info.h"
 #include "modules/desktop_capture/app_capturer.h"
 #include "modules/desktop_capture/desktop_capture_options.h"
 #include "modules/video_capture/video_capture.h"
 
+#if defined(_WIN32)
+#include "platform_uithread.h"
+#else
+#include "rtc_base/platform_thread.h"
+#endif
+
 namespace webrtc {
 
 ScreenDeviceInfoImpl::ScreenDeviceInfoImpl(const int32_t id) : _id(id) {}
 
 ScreenDeviceInfoImpl::~ScreenDeviceInfoImpl(void) {}
 
 int32_t ScreenDeviceInfoImpl::Init() {
   desktop_device_info_ =
--- a/dom/media/systemservices/video_engine/desktop_capture_impl.h
+++ b/dom/media/systemservices/video_engine/desktop_capture_impl.h
@@ -19,24 +19,29 @@
 #include <memory>
 
 #include "api/video/video_frame.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
 #include "modules/video_capture/video_capture_config.h"
 #include "modules/desktop_capture/shared_memory.h"
 #include "modules/desktop_capture/desktop_device_info.h"
 #include "modules/desktop_capture/desktop_and_cursor_composer.h"
-#include "rtc_base/criticalsection.h"
-#include "rtc_base/platform_thread.h"
-#include "rtc_base/scoped_ref_ptr.h"
 #include "system_wrappers/include/event_wrapper.h"
 #include <set>
 
 using namespace webrtc::videocapturemodule;
 
+namespace rtc {
+#if defined(_WIN32)
+class PlatformUIThread;
+#else
+class PlatformThread;
+#endif
+}  // namespace rtc
+
 namespace webrtc {
 
 class VideoCaptureEncodeInterface;
 
 // simulate deviceInfo interface for video engine, bridge screen/application and
 // real screen/application device info
 
 class ScreenDeviceInfoImpl : public VideoCaptureModule::DeviceInfo {
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/video_engine/platform_uithread.cc
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "platform_uithread.h"
+
+namespace rtc {
+
+#if defined(WEBRTC_WIN)
+// For use in ThreadWindowsUI callbacks
+static UINT static_reg_windows_msg = RegisterWindowMessageW(L"WebrtcWindowsUIThreadEvent");
+// timer id used in delayed callbacks
+static const UINT_PTR kTimerId = 1;
+static const wchar_t kThisProperty[] = L"ThreadWindowsUIPtr";
+static const wchar_t kThreadWindow[] = L"WebrtcWindowsUIThread";
+
+bool PlatformUIThread::InternalInit() {
+  // Create an event window for use in generating callbacks to capture
+  // objects.
+  CritScope scoped_lock(&cs_);
+  if (hwnd_ == NULL) {
+    WNDCLASSW wc;
+    HMODULE hModule = GetModuleHandle(NULL);
+    if (!GetClassInfoW(hModule, kThreadWindow, &wc)) {
+      ZeroMemory(&wc, sizeof(WNDCLASSW));
+      wc.hInstance = hModule;
+      wc.lpfnWndProc = EventWindowProc;
+      wc.lpszClassName = kThreadWindow;
+      RegisterClassW(&wc);
+    }
+    hwnd_ = CreateWindowW(kThreadWindow, L"",
+                          0, 0, 0, 0, 0,
+                          NULL, NULL, hModule, NULL);
+    RTC_DCHECK(hwnd_);
+    SetPropW(hwnd_, kThisProperty, this);
+
+    if (timeout_) {
+      // if someone set the timer before we started
+      RequestCallbackTimer(timeout_);
+    }
+  }
+  return !!hwnd_;
+}
+
+void PlatformUIThread::RequestCallback() {
+  RTC_DCHECK(hwnd_);
+  RTC_DCHECK(static_reg_windows_msg);
+  PostMessage(hwnd_, static_reg_windows_msg, 0, 0);
+}
+
+bool PlatformUIThread::RequestCallbackTimer(unsigned int milliseconds) {
+  CritScope scoped_lock(&cs_);
+  if (!hwnd_) {
+    // There is a condition that thread_ (PlatformUIThread) has been
+    // created but PlatformUIThread::Run() hasn't been run yet (hwnd_ is
+    // null while thread_ is not). If we do RTC_DCHECK(!thread_) here,
+    // it would lead to crash in this condition.
+
+    // set timer once thread starts
+  } else {
+    if (timerid_) {
+      KillTimer(hwnd_, timerid_);
+    }
+    timerid_ = SetTimer(hwnd_, kTimerId, milliseconds, NULL);
+  }
+  timeout_ = milliseconds;
+  return !!timerid_;
+}
+
+void PlatformUIThread::Stop() {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  // Shut down the dispatch loop and let the background thread exit.
+  if (timerid_) {
+    KillTimer(hwnd_, timerid_);
+    timerid_ = 0;
+  }
+
+  PostMessage(hwnd_, WM_CLOSE, 0, 0);
+
+  hwnd_ = NULL;
+
+  PlatformThread::Stop();
+}
+
+void PlatformUIThread::Run() {
+  RTC_CHECK(InternalInit()); // always evaluates
+  do {
+    // The interface contract of Start/Stop is that for a successful call to
+    // Start, there should be at least one call to the run function.  So we
+    // call the function before checking |stop_|.
+    run_function_deprecated_(obj_);
+
+    // Alertable sleep to permit RaiseFlag to run and update |stop_|.
+    if (MsgWaitForMultipleObjectsEx(0, nullptr, INFINITE, QS_ALLINPUT,
+                                    MWMO_ALERTABLE | MWMO_INPUTAVAILABLE) ==
+        WAIT_OBJECT_0) {
+      MSG msg;
+      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+        if (msg.message == WM_QUIT) {
+          stop_ = true;
+          break;
+        }
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+      }
+    }
+
+  } while (!stop_);
+}
+
+void PlatformUIThread::NativeEventCallback() {
+  if (!run_function_deprecated_) {
+    stop_ = true;
+    return;
+  }
+  run_function_deprecated_(obj_);
+}
+
+/* static */
+LRESULT CALLBACK
+PlatformUIThread::EventWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+  if (uMsg == WM_DESTROY) {
+    RemovePropW(hwnd, kThisProperty);
+    PostQuitMessage(0);
+    return 0;
+  }
+
+  PlatformUIThread *twui = static_cast<PlatformUIThread*>(GetPropW(hwnd, kThisProperty));
+  if (!twui) {
+    return DefWindowProc(hwnd, uMsg, wParam, lParam);
+  }
+
+  if ((uMsg == static_reg_windows_msg && uMsg != WM_NULL) ||
+      (uMsg == WM_TIMER && wParam == kTimerId)) {
+    twui->NativeEventCallback();
+    return 0;
+  }
+
+  return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+#endif
+
+}  // namespace rtc
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/video_engine/platform_uithread.h
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_PLATFORM_UITHREAD_H_
+#define RTC_BASE_PLATFORM_UITHREAD_H_
+
+#include "rtc_base/platform_thread.h"
+
+namespace rtc {
+
+#if defined(WEBRTC_WIN)
+class PlatformUIThread : public PlatformThread {
+ public:
+  PlatformUIThread(ThreadRunFunctionDeprecated func, void* obj,
+                   const char* thread_name)
+      : PlatformThread(func, obj, thread_name),
+        hwnd_(nullptr),
+        timerid_(0),
+        timeout_(0) {}
+  virtual ~PlatformUIThread() {}
+
+  void Stop() override;
+
+  /**
+   * Request an async callback soon.
+   */
+  void RequestCallback();
+
+  /**
+   * Request a recurring callback.
+   */
+  bool RequestCallbackTimer(unsigned int milliseconds);
+
+ protected:
+  void Run() override;
+
+ private:
+  static LRESULT CALLBACK EventWindowProc(HWND, UINT, WPARAM, LPARAM);
+  void NativeEventCallback();
+  bool InternalInit();
+
+  HWND hwnd_;
+  UINT_PTR timerid_;
+  unsigned int timeout_;
+};
+#endif
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_PLATFORM_UITHREAD_H_
--- a/media/webrtc/trunk/webrtc/rtc_base/platform_thread.cc
+++ b/media/webrtc/trunk/webrtc/rtc_base/platform_thread.cc
@@ -23,25 +23,16 @@
 #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) // WEBRTC_BSD
 #include <pthread_np.h>
 #elif defined(__NetBSD__) // WEBRTC_BSD
 #include <lwp.h>
 #endif
 
 namespace rtc {
 
-#if defined(WEBRTC_WIN)
-// For use in ThreadWindowsUI callbacks
-static UINT static_reg_windows_msg = RegisterWindowMessageW(L"WebrtcWindowsUIThreadEvent");
-// timer id used in delayed callbacks
-static const UINT_PTR kTimerId = 1;
-static const wchar_t kThisProperty[] = L"ThreadWindowsUIPtr";
-static const wchar_t kThreadWindow[] = L"WebrtcWindowsUIThread";
-#endif
-
 PlatformThreadId CurrentThreadId() {
   PlatformThreadId ret;
 #if defined(WEBRTC_WIN)
   ret = GetCurrentThreadId();
 #elif defined(WEBRTC_POSIX)
 #if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
   ret = pthread_mach_thread_np(pthread_self());
 #elif defined(WEBRTC_ANDROID)
@@ -148,69 +139,16 @@ PlatformThread::~PlatformThread() {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
 #if defined(WEBRTC_WIN)
   RTC_DCHECK(!thread_);
   RTC_DCHECK(!thread_id_);
 #endif  // defined(WEBRTC_WIN)
 }
 
 #if defined(WEBRTC_WIN)
-bool PlatformUIThread::InternalInit() {
-  // Create an event window for use in generating callbacks to capture
-  // objects.
-  CritScope scoped_lock(&cs_);
-  if (hwnd_ == NULL) {
-    WNDCLASSW wc;
-    HMODULE hModule = GetModuleHandle(NULL);
-    if (!GetClassInfoW(hModule, kThreadWindow, &wc)) {
-      ZeroMemory(&wc, sizeof(WNDCLASSW));
-      wc.hInstance = hModule;
-      wc.lpfnWndProc = EventWindowProc;
-      wc.lpszClassName = kThreadWindow;
-      RegisterClassW(&wc);
-    }
-    hwnd_ = CreateWindowW(kThreadWindow, L"",
-                          0, 0, 0, 0, 0,
-                          NULL, NULL, hModule, NULL);
-    RTC_DCHECK(hwnd_);
-    SetPropW(hwnd_, kThisProperty, this);
-
-    if (timeout_) {
-      // if someone set the timer before we started
-      RequestCallbackTimer(timeout_);
-    }
-  }
-  return !!hwnd_;
-}
-
-void PlatformUIThread::RequestCallback() {
-  RTC_DCHECK(hwnd_);
-  RTC_DCHECK(static_reg_windows_msg);
-  PostMessage(hwnd_, static_reg_windows_msg, 0, 0);
-}
-
-bool PlatformUIThread::RequestCallbackTimer(unsigned int milliseconds) {
-  CritScope scoped_lock(&cs_);
-  if (!hwnd_) {
-    // There is a condition that thread_ (PlatformUIThread) has been
-    // created but PlatformUIThread::Run() hasn't been run yet (hwnd_ is
-    // null while thread_ is not). If we do RTC_DCHECK(!thread_) here,
-    // it would lead to crash in this condition.
-
-    // set timer once thread starts
-  } else {
-    if (timerid_) {
-      KillTimer(hwnd_, timerid_);
-    }
-    timerid_ = SetTimer(hwnd_, kTimerId, milliseconds, NULL);
-  }
-  timeout_ = milliseconds;
-  return !!timerid_;
-}
-
 DWORD WINAPI PlatformThread::StartThread(void* param) {
   // The GetLastError() function only returns valid results when it is called
   // after a Win32 API function that returns a "failed" result. A crash dump
   // contains the result from GetLastError() and to make sure it does not
   // falsely report a Windows error we call SetLastError here.
   ::SetLastError(ERROR_SUCCESS);
   static_cast<PlatformThread*>(param)->Run();
   return 0;
@@ -282,33 +220,16 @@ void PlatformThread::Stop() {
   RTC_CHECK_EQ(0, pthread_join(thread_, nullptr));
   if (!run_function_)
     AtomicOps::ReleaseStore(&stop_flag_, 0);
   thread_ = 0;
 #endif  // defined(WEBRTC_WIN)
   spawned_thread_checker_.DetachFromThread();
 }
 
-#ifdef WEBRTC_WIN
-void PlatformUIThread::Stop() {
-  RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  // Shut down the dispatch loop and let the background thread exit.
-  if (timerid_) {
-    KillTimer(hwnd_, timerid_);
-    timerid_ = 0;
-  }
-
-  PostMessage(hwnd_, WM_CLOSE, 0, 0);
-
-  hwnd_ = NULL;
-
-  PlatformThread::Stop();
-}
-#endif
-
 // TODO(tommi): Deprecate the loop behavior in PlatformThread.
 // * Introduce a new callback type that returns void.
 // * Remove potential for a busy loop in PlatformThread.
 // * Delegate the responsibility for how to stop the thread, to the
 //   implementation that actually uses the thread.
 // All implementations will need to be aware of how the thread should be stopped
 // and encouraging a busy polling loop, can be costly in terms of power and cpu.
 void PlatformThread::Run() {
@@ -368,75 +289,16 @@ void PlatformThread::Run() {
 #else
     static const struct timespec ts_null = {0};
     nanosleep(&ts_null, nullptr);
 #endif
   } while (!AtomicOps::AcquireLoad(&stop_flag_));
 #endif  // defined(WEBRTC_WIN)
 }
 
-#if defined(WEBRTC_WIN)
-void PlatformUIThread::Run() {
-  RTC_CHECK(InternalInit()); // always evaluates
-  do {
-    // The interface contract of Start/Stop is that for a successful call to
-    // Start, there should be at least one call to the run function.  So we
-    // call the function before checking |stop_|.
-    run_function_deprecated_(obj_);
-
-    // Alertable sleep to permit RaiseFlag to run and update |stop_|.
-    if (MsgWaitForMultipleObjectsEx(0, nullptr, INFINITE, QS_ALLINPUT,
-                                    MWMO_ALERTABLE | MWMO_INPUTAVAILABLE) ==
-        WAIT_OBJECT_0) {
-      MSG msg;
-      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
-        if (msg.message == WM_QUIT) {
-          stop_ = true;
-          break;
-        }
-        TranslateMessage(&msg);
-        DispatchMessage(&msg);
-      }
-    }
-
-  } while (!stop_);
-}
-
-void PlatformUIThread::NativeEventCallback() {
-  if (!run_function_deprecated_) {
-    stop_ = true;
-    return;
-  }
-  run_function_deprecated_(obj_);
-}
-
-/* static */
-LRESULT CALLBACK
-PlatformUIThread::EventWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-  if (uMsg == WM_DESTROY) {
-    RemovePropW(hwnd, kThisProperty);
-    PostQuitMessage(0);
-    return 0;
-  }
-
-  PlatformUIThread *twui = static_cast<PlatformUIThread*>(GetPropW(hwnd, kThisProperty));
-  if (!twui) {
-    return DefWindowProc(hwnd, uMsg, wParam, lParam);
-  }
-
-  if ((uMsg == static_reg_windows_msg && uMsg != WM_NULL) ||
-      (uMsg == WM_TIMER && wParam == kTimerId)) {
-    twui->NativeEventCallback();
-    return 0;
-  }
-
-  return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-#endif
-
 bool PlatformThread::SetPriority(ThreadPriority priority) {
 #if RTC_DCHECK_IS_ON
   if (run_function_) {
     // The non-deprecated way of how this function gets called, is that it must
     // be called on the worker thread itself.
     RTC_DCHECK(!thread_checker_.CalledOnValidThread());
     RTC_DCHECK(spawned_thread_checker_.CalledOnValidThread());
   } else {
--- a/media/webrtc/trunk/webrtc/rtc_base/platform_thread.h
+++ b/media/webrtc/trunk/webrtc/rtc_base/platform_thread.h
@@ -114,49 +114,11 @@ class PlatformThread {
   // An atomic flag that we use to stop the thread. Only modified on the
   // controlling thread and checked on the worker thread.
   volatile int stop_flag_ = 0;
   pthread_t thread_ = 0;
 #endif  // defined(WEBRTC_WIN)
   RTC_DISALLOW_COPY_AND_ASSIGN(PlatformThread);
 };
 
-#if defined(WEBRTC_WIN)
-class PlatformUIThread : public PlatformThread {
- public:
-  PlatformUIThread(ThreadRunFunctionDeprecated func, void* obj,
-		  const char* thread_name) :
-  PlatformThread(func, obj, thread_name),
-  hwnd_(nullptr),
-  timerid_(0),
-  timeout_(0) {
- }
- virtual ~PlatformUIThread() {}
-
- void Stop() override;
-
- /**
-  * Request an async callback soon.
-  */
- void RequestCallback();
-
- /**
-  * Request a recurring callback.
-  */
- bool RequestCallbackTimer(unsigned int milliseconds);
-
- protected:
-  void Run() override;
-
- private:
-  static LRESULT CALLBACK EventWindowProc(HWND, UINT, WPARAM, LPARAM);
-  void NativeEventCallback();
-  bool InternalInit();
-
-  HWND hwnd_;
-  UINT_PTR timerid_;
-  unsigned int timeout_;
-};
-#endif
-
 }  // namespace rtc
 
 #endif  // RTC_BASE_PLATFORM_THREAD_H_