зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1053264 - Do not use CAPTUREBLT when Desktop Composition is enabled. r=jimm
This commit is contained in:
Родитель
25f27d0783
Коммит
70ab7f05a1
|
@ -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<DwmEnableCompositionFunc>(
|
||||
GetProcAddress(dwmapi_library_, "DwmEnableComposition"));
|
||||
}
|
||||
if (dwmapi_library_) {
|
||||
composition_func_ = reinterpret_cast<DwmEnableCompositionFunc>(
|
||||
GetProcAddress(dwmapi_library_, "DwmEnableComposition"));
|
||||
composition_enabled_func_ = reinterpret_cast<DwmIsCompositionEnabledFunc>
|
||||
(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<DesktopFrameWin*>(
|
||||
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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче