Commit 92aef640 authored by John Abd-El-Malek's avatar John Abd-El-Malek

Call IsWindowOnCurrentVirtualDesktop less frequently since it's slow.

Poll every 1 second to see if virtual desktops are enabled or not. Since for most users this isn't the case, we can skip calling IsWindowOnCurrentVirtualDesktop altogether.

Bug: 1162132
Change-Id: Ib3a89448095186a4b310e88b020dbeb7cd1b6c4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2602260Reviewed-by: default avatarDavid Bienvenu <davidbienvenu@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842199}
parent 7e349cb9
...@@ -22,8 +22,59 @@ ...@@ -22,8 +22,59 @@
#include "base/win/scoped_gdi_object.h" #include "base/win/scoped_gdi_object.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "ui/aura/window_tree_host.h" #include "ui/aura/window_tree_host.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/win/hwnd_util.h" #include "ui/gfx/win/hwnd_util.h"
const CLSID CLSID_ImmersiveShell = {
0xC2F03A33,
0x21F5,
0x47FA,
{0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39}};
const CLSID CLSID_VirtualDesktopAPI_Unknown = {
0xC5E0CDCA,
0x7B6E,
0x41B2,
{0x9F, 0xC4, 0xD9, 0x39, 0x75, 0xCC, 0x46, 0x7B}};
struct IApplicationView : public IUnknown {
public:
};
MIDL_INTERFACE("FF72FFDD-BE7E-43FC-9C03-AD81681E88E4")
IVirtualDesktop : public IUnknown {
public:
virtual HRESULT STDMETHODCALLTYPE IsViewVisible(IApplicationView * pView,
int* pfVisible) = 0;
virtual HRESULT STDMETHODCALLTYPE GetID(GUID * pGuid) = 0;
};
enum AdjacentDesktop { LeftDirection = 3, RightDirection = 4 };
MIDL_INTERFACE("F31574D6-B682-4cdc-BD56-1827860ABEC6")
IVirtualDesktopManagerInternal : public IUnknown {
public:
virtual HRESULT STDMETHODCALLTYPE GetCount(UINT * pCount) = 0;
virtual HRESULT STDMETHODCALLTYPE MoveViewToDesktop(
IApplicationView * pView, IVirtualDesktop * pDesktop) = 0;
virtual HRESULT STDMETHODCALLTYPE CanViewMoveDesktops(
IApplicationView * pView, int* pfCanViewMoveDesktops) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCurrentDesktop(IVirtualDesktop *
*desktop) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDesktops(IObjectArray * *ppDesktops) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAdjacentDesktop(
IVirtualDesktop * pDesktopReference, AdjacentDesktop uDirection,
IVirtualDesktop * *ppAdjacentDesktop) = 0;
virtual HRESULT STDMETHODCALLTYPE SwitchDesktop(IVirtualDesktop *
pDesktop) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateDesktopW(IVirtualDesktop *
*ppNewDesktop) = 0;
virtual HRESULT STDMETHODCALLTYPE RemoveDesktop(
IVirtualDesktop * pRemove, IVirtualDesktop * pFallbackDesktop) = 0;
virtual HRESULT STDMETHODCALLTYPE FindDesktop(
GUID * desktopId, IVirtualDesktop * *ppDesktop) = 0;
};
namespace aura { namespace aura {
namespace { namespace {
...@@ -32,6 +83,9 @@ namespace { ...@@ -32,6 +83,9 @@ namespace {
const base::TimeDelta kUpdateOcclusionDelay = const base::TimeDelta kUpdateOcclusionDelay =
base::TimeDelta::FromMilliseconds(16); base::TimeDelta::FromMilliseconds(16);
const base::TimeDelta kUpdateVirtualDesktopDelay =
base::TimeDelta::FromMilliseconds(1000);
// This global variable can be accessed only on main thread. // This global variable can be accessed only on main thread.
NativeWindowOcclusionTrackerWin* g_tracker = nullptr; NativeWindowOcclusionTrackerWin* g_tracker = nullptr;
...@@ -313,6 +367,19 @@ NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ...@@ -313,6 +367,19 @@ NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
if (base::win::GetVersion() >= base::win::Version::WIN10) { if (base::win::GetVersion() >= base::win::Version::WIN10) {
::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr, CLSCTX_ALL, ::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&virtual_desktop_manager_)); IID_PPV_ARGS(&virtual_desktop_manager_));
Microsoft::WRL::ComPtr<IServiceProvider> service_provider;
if (base::FeatureList::IsEnabled(
features::kCalculateNativeWinOcclusionCheckVirtualDesktopUsed) &&
SUCCEEDED(::CoCreateInstance(CLSID_ImmersiveShell, NULL,
CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS(&service_provider)))) {
service_provider->QueryService(
CLSID_VirtualDesktopAPI_Unknown,
IID_PPV_ARGS(&virtual_desktop_manager_internal_));
if (virtual_desktop_manager_internal_)
ComputeVirtualDesktopUsed();
}
} }
DETACH_FROM_SEQUENCE(sequence_checker_); DETACH_FROM_SEQUENCE(sequence_checker_);
} }
...@@ -362,6 +429,8 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ...@@ -362,6 +429,8 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
UnregisterEventHooks(); UnregisterEventHooks();
if (occlusion_update_timer_.IsRunning()) if (occlusion_update_timer_.IsRunning())
occlusion_update_timer_.Stop(); occlusion_update_timer_.Stop();
if (virtual_desktop_update_timer_.IsRunning())
virtual_desktop_update_timer_.Stop();
} }
} }
...@@ -507,13 +576,26 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ...@@ -507,13 +576,26 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
root_window_hwnds_occlusion_state_, showing_thumbnails_)); root_window_hwnds_occlusion_state_, showing_thumbnails_));
} }
void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
ComputeVirtualDesktopUsed() {
UINT count = 0;
if (SUCCEEDED(virtual_desktop_manager_internal_->GetCount(&count)))
virtual_desktops_used_ = count > 1;
}
void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
ScheduleOcclusionCalculationIfNeeded() { ScheduleOcclusionCalculationIfNeeded() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!occlusion_update_timer_.IsRunning()) if (!occlusion_update_timer_.IsRunning()) {
occlusion_update_timer_.Start( occlusion_update_timer_.Start(
FROM_HERE, kUpdateOcclusionDelay, this, FROM_HERE, kUpdateOcclusionDelay, this,
&WindowOcclusionCalculator::ComputeNativeWindowOcclusionStatus); &WindowOcclusionCalculator::ComputeNativeWindowOcclusionStatus);
if (virtual_desktop_manager_internal_) {
virtual_desktop_update_timer_.Start(
FROM_HERE, kUpdateVirtualDesktopDelay, this,
&WindowOcclusionCalculator::ComputeVirtualDesktopUsed);
}
}
} }
void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
...@@ -769,7 +851,7 @@ bool NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: ...@@ -769,7 +851,7 @@ bool NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
base::Optional<bool> NativeWindowOcclusionTrackerWin:: base::Optional<bool> NativeWindowOcclusionTrackerWin::
WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop(HWND hwnd) { WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop(HWND hwnd) {
if (!virtual_desktop_manager_) if (!virtual_desktop_manager_ || !virtual_desktops_used_)
return true; return true;
BOOL on_current_desktop; BOOL on_current_desktop;
......
...@@ -34,6 +34,8 @@ namespace gfx { ...@@ -34,6 +34,8 @@ namespace gfx {
class Rect; class Rect;
} }
struct IVirtualDesktopManagerInternal;
namespace aura { namespace aura {
// This class keeps track of whether any HWNDs are occluding any app windows. // This class keeps track of whether any HWNDs are occluding any app windows.
...@@ -134,6 +136,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin ...@@ -134,6 +136,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// their occlusion status has changed. // their occlusion status has changed.
void ComputeNativeWindowOcclusionStatus(); void ComputeNativeWindowOcclusionStatus();
// Computes if virtual desktops are used. This is used as an optimization
// since IsWindowOnCurrentVirtualDesktop is a slow call.
void ComputeVirtualDesktopUsed();
// Schedules an occlusion calculation |update_occlusion_delay_| time in the // Schedules an occlusion calculation |update_occlusion_delay_| time in the
// future, if one isn't already scheduled. // future, if one isn't already scheduled.
void ScheduleOcclusionCalculationIfNeeded(); void ScheduleOcclusionCalculationIfNeeded();
...@@ -217,6 +223,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin ...@@ -217,6 +223,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// Timer to delay occlusion update. // Timer to delay occlusion update.
base::OneShotTimer occlusion_update_timer_; base::OneShotTimer occlusion_update_timer_;
// Timer to check how many virtual desktops are present.
base::OneShotTimer virtual_desktop_update_timer_;
// Used to keep track of whether we're in the middle of getting window move // Used to keep track of whether we're in the middle of getting window move
// events, in order to wait until the window move is complete before // events, in order to wait until the window move is complete before
// calculating window occlusion. // calculating window occlusion.
...@@ -244,9 +253,18 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin ...@@ -244,9 +253,18 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// ignore windows occluded by the dragged window. // ignore windows occluded by the dragged window.
HWND moving_window_ = 0; HWND moving_window_ = 0;
// By caching if virtual desktops are in use or not we can avoid calling
// IsWindowOnCurrentVirtualDesktop which is slow. Start with an initial
// value of true so that we only optimize after we get confirmation that
// there are no virtual desktops.
bool virtual_desktops_used_ = true;
// Only used on Win10+. // Only used on Win10+.
Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_; Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_;
Microsoft::WRL::ComPtr<IVirtualDesktopManagerInternal>
virtual_desktop_manager_internal_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<WindowOcclusionCalculator> weak_factory_{this}; base::WeakPtrFactory<WindowOcclusionCalculator> weak_factory_{this};
......
...@@ -24,6 +24,10 @@ namespace features { ...@@ -24,6 +24,10 @@ namespace features {
// If enabled, calculate native window occlusion - Windows-only. // If enabled, calculate native window occlusion - Windows-only.
const base::Feature kCalculateNativeWinOcclusion{ const base::Feature kCalculateNativeWinOcclusion{
"CalculateNativeWinOcclusion", base::FEATURE_ENABLED_BY_DEFAULT}; "CalculateNativeWinOcclusion", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed{
"CalculateNativeWinOcclusionCheckVirtualDesktopUsed",
base::FEATURE_DISABLED_BY_DEFAULT};
#endif // OW_WIN #endif // OW_WIN
// Whether or not to delegate color queries to the color provider. // Whether or not to delegate color queries to the color provider.
......
...@@ -48,6 +48,8 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsUiGpuRasterizationEnabled(); ...@@ -48,6 +48,8 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsUiGpuRasterizationEnabled();
COMPONENT_EXPORT(UI_BASE_FEATURES) COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kCalculateNativeWinOcclusion; extern const base::Feature kCalculateNativeWinOcclusion;
COMPONENT_EXPORT(UI_BASE_FEATURES) COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed;
COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kElasticOverscrollWin; extern const base::Feature kElasticOverscrollWin;
COMPONENT_EXPORT(UI_BASE_FEATURES) COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kInputPaneOnScreenKeyboard; extern const base::Feature kInputPaneOnScreenKeyboard;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment