diff --git a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_win.cc b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_win.cc index db0a57c0334f..4cbcf7336239 100644 --- a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_win.cc +++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_win.cc @@ -37,6 +37,7 @@ const UINT DWM_EC_DISABLECOMPOSITION = 0; const UINT DWM_EC_ENABLECOMPOSITION = 1; typedef HRESULT (WINAPI * DwmEnableCompositionFunc)(UINT); +typedef HRESULT (WINAPI * DwmIsCompositionEnabledFunc)(BOOL*); const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll"; @@ -102,6 +103,9 @@ class ScreenCapturerWin : public ScreenCapturer { HMODULE dwmapi_library_; DwmEnableCompositionFunc composition_func_; + DwmIsCompositionEnabledFunc composition_enabled_func_; + + bool disable_composition_; // Used to suppress duplicate logging of SetThreadExecutionState errors. bool set_thread_execution_state_failed_; @@ -118,16 +122,18 @@ ScreenCapturerWin::ScreenCapturerWin(const DesktopCaptureOptions& options) dwmapi_library_(NULL), composition_func_(NULL), set_thread_execution_state_failed_(false) { - if (options.disable_effects()) { - // Load dwmapi.dll dynamically since it is not available on XP. - if (!dwmapi_library_) - dwmapi_library_ = LoadLibrary(kDwmapiLibraryName); + // Load dwmapi.dll dynamically since it is not available on XP. + if (!dwmapi_library_) + dwmapi_library_ = LoadLibrary(kDwmapiLibraryName); - if (dwmapi_library_) { - composition_func_ = reinterpret_cast( - GetProcAddress(dwmapi_library_, "DwmEnableComposition")); - } + if (dwmapi_library_) { + composition_func_ = reinterpret_cast( + GetProcAddress(dwmapi_library_, "DwmEnableComposition")); + composition_enabled_func_ = reinterpret_cast + (GetProcAddress(dwmapi_library_, "DwmIsCompositionEnabled")); } + + disable_composition_ = options.disable_effects(); } ScreenCapturerWin::~ScreenCapturerWin() { @@ -136,9 +142,11 @@ ScreenCapturerWin::~ScreenCapturerWin() { if (memory_dc_) DeleteDC(memory_dc_); - // Restore Aero. - if (composition_func_) - (*composition_func_)(DWM_EC_ENABLECOMPOSITION); + if (disable_composition_) { + // Restore Aero. + if (composition_func_) + (*composition_func_)(DWM_EC_ENABLECOMPOSITION); + } if (dwmapi_library_) FreeLibrary(dwmapi_library_); @@ -261,11 +269,13 @@ void ScreenCapturerWin::Start(Callback* callback) { callback_ = callback; - // Vote to disable Aero composited desktop effects while capturing. Windows - // will restore Aero automatically if the process exits. This has no effect - // under Windows 8 or higher. See crbug.com/124018. - if (composition_func_) - (*composition_func_)(DWM_EC_DISABLECOMPOSITION); + if (disable_composition_) { + // Vote to disable Aero composited desktop effects while capturing. Windows + // will restore Aero automatically if the process exits. This has no effect + // under Windows 8 or higher. See crbug.com/124018. + if (composition_func_) + (*composition_func_)(DWM_EC_DISABLECOMPOSITION); + } } void ScreenCapturerWin::PrepareCaptureResources() { @@ -288,10 +298,12 @@ void ScreenCapturerWin::PrepareCaptureResources() { // So we can continue capture screen bits, just from the wrong desktop. desktop_.SetThreadDesktop(input_desktop.release()); - // Re-assert our vote to disable Aero. - // See crbug.com/124018 and crbug.com/129906. - if (composition_func_ != NULL) { - (*composition_func_)(DWM_EC_DISABLECOMPOSITION); + if (disable_composition_) { + // Re-assert our vote to disable Aero. + // See crbug.com/124018 and crbug.com/129906. + if (composition_func_ != NULL) { + (*composition_func_)(DWM_EC_DISABLECOMPOSITION); + } } } @@ -360,12 +372,24 @@ bool ScreenCapturerWin::CaptureImage() { DesktopFrameWin* current = static_cast( queue_.current_frame()->GetUnderlyingFrame()); HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap()); + DWORD rop = SRCCOPY; + if (composition_enabled_func_) { + BOOL enabled; + (*composition_enabled_func_)(&enabled); + if (!enabled) { + // Vista or Windows 7, Aero disabled + rop |= CAPTUREBLT; + } + } else { + // Windows XP, required to get layered windows + rop |= CAPTUREBLT; + } if (previous_object != NULL) { BitBlt(memory_dc_, 0, 0, screen_rect.width(), screen_rect.height(), desktop_dc_, screen_rect.left(), screen_rect.top(), - SRCCOPY | CAPTUREBLT); + rop); // Select back the previously selected object to that the device contect // could be destroyed independently of the bitmap if needed.