Chromium Code Reviews| Index: webrtc/modules/desktop_capture/screen_drawer_win.cc |
| diff --git a/webrtc/modules/desktop_capture/screen_drawer_win.cc b/webrtc/modules/desktop_capture/screen_drawer_win.cc |
| index 48b770d14b6ea64ad8e9e4861fa1c382009fb9ce..37e465720fea9a889994ceeec997260820e84a43 100644 |
| --- a/webrtc/modules/desktop_capture/screen_drawer_win.cc |
| +++ b/webrtc/modules/desktop_capture/screen_drawer_win.cc |
| @@ -19,6 +19,41 @@ namespace webrtc { |
| namespace { |
| +static constexpr TCHAR kMutexName[] = |
| + TEXT("Local\\ScreenDrawerWin-da834f82-8044-11e6-ac81-73dcdd1c1869"); |
| + |
| +// A cross application lock to ensure only one ScreenDrawerWin can be used at a |
| +// certain time. |
| +struct ScreenDrawerLock { |
| + // Blocks current thread until a global lock is acquired. |
| + ScreenDrawerLock(); |
| + // Releases the global lock acquired. |
| + ~ScreenDrawerLock(); |
| + |
| + private: |
| + HANDLE mutex_; |
| +}; |
| + |
| +ScreenDrawerLock::ScreenDrawerLock() { |
|
Sergey Ulanov
2016/10/14 17:38:25
it looks like this code is duplicated between the
Hzj_jie
2016/10/19 00:46:47
Yes, part of the logic is shareable. I will make a
|
| + while (true) { |
| + mutex_ = CreateMutex(NULL, FALSE, kMutexName); |
| + if (GetLastError() != ERROR_ALREADY_EXISTS && mutex_ != NULL) { |
| + break; |
| + } else { |
| + if (mutex_) { |
| + CloseHandle(mutex_); |
| + } |
| + SleepMs(1000); |
| + } |
| + } |
| +} |
| + |
| +ScreenDrawerLock::~ScreenDrawerLock() { |
| + CloseHandle(mutex_); |
| +} |
| + |
| +std::unique_ptr<ScreenDrawerLock> g_screen_drawer_lock; |
| + |
| DesktopRect GetScreenRect() { |
| HDC hdc = GetDC(NULL); |
| DesktopRect rect = DesktopRect::MakeWH(GetDeviceCaps(hdc, HORZRES), |
| @@ -51,8 +86,13 @@ class ScreenDrawerWin : public ScreenDrawer { |
| void DrawRectangle(DesktopRect rect, RgbaColor color) override; |
| void Clear() override; |
| void WaitForPendingDraws() override; |
| + bool MayDrawIncompleteShapes() override; |
| private: |
| + // Bring the window to the front, this can help to avoid the impact from other |
| + // windows or shadow effects. |
| + void BringToFront(); |
| + |
| // Draw a line with |color|. |
| void DrawLine(DesktopVector start, DesktopVector end, RgbaColor color); |
| @@ -76,12 +116,14 @@ ScreenDrawerWin::ScreenDrawerWin() |
| // Always use stock pen (DC_PEN) and brush (DC_BRUSH). |
| SelectObject(hdc_, GetStockObject(DC_PEN)); |
| SelectObject(hdc_, GetStockObject(DC_BRUSH)); |
| + BringToFront(); |
| } |
| ScreenDrawerWin::~ScreenDrawerWin() { |
| ReleaseDC(NULL, hdc_); |
| DestroyWindow(window_); |
| // Unfortunately there is no EnableProcessWindowsGhosting() API. |
| + g_screen_drawer_lock.reset(); |
| } |
| DesktopRect ScreenDrawerWin::DrawableRegion() { |
| @@ -114,9 +156,14 @@ void ScreenDrawerWin::Clear() { |
| // TODO(zijiehe): Find the right signal to indicate the finish of all pending |
| // paintings. |
| void ScreenDrawerWin::WaitForPendingDraws() { |
| + BringToFront(); |
| SleepMs(50); |
| } |
| +bool ScreenDrawerWin::MayDrawIncompleteShapes() { |
| + return true; |
| +} |
| + |
| void ScreenDrawerWin::DrawLine(DesktopVector start, |
| DesktopVector end, |
| RgbaColor color) { |
| @@ -133,10 +180,15 @@ void ScreenDrawerWin::DrawDot(DesktopVector vect, RgbaColor color) { |
| SetPixel(hdc_, vect.x(), vect.y(), ColorToRef(color)); |
| } |
| +void ScreenDrawerWin::BringToFront() { |
| + BringWindowToTop(window_); |
| +} |
| + |
| } // namespace |
| // static |
| std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { |
| + g_screen_drawer_lock.reset(new ScreenDrawerLock()); |
| return std::unique_ptr<ScreenDrawer>(new ScreenDrawerWin()); |
| } |