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 @@
#include "base/win/scoped_gdi_object.h"
#include "base/win/windows_version.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ui_base_features.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 {
......@@ -32,6 +83,9 @@ namespace {
const base::TimeDelta kUpdateOcclusionDelay =
base::TimeDelta::FromMilliseconds(16);
const base::TimeDelta kUpdateVirtualDesktopDelay =
base::TimeDelta::FromMilliseconds(1000);
// This global variable can be accessed only on main thread.
NativeWindowOcclusionTrackerWin* g_tracker = nullptr;
......@@ -313,6 +367,19 @@ NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
if (base::win::GetVersion() >= base::win::Version::WIN10) {
::CoCreateInstance(__uuidof(VirtualDesktopManager), nullptr, CLSCTX_ALL,
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_);
}
......@@ -362,6 +429,8 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
UnregisterEventHooks();
if (occlusion_update_timer_.IsRunning())
occlusion_update_timer_.Stop();
if (virtual_desktop_update_timer_.IsRunning())
virtual_desktop_update_timer_.Stop();
}
}
......@@ -507,13 +576,26 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
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::
ScheduleOcclusionCalculationIfNeeded() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!occlusion_update_timer_.IsRunning())
if (!occlusion_update_timer_.IsRunning()) {
occlusion_update_timer_.Start(
FROM_HERE, kUpdateOcclusionDelay, this,
&WindowOcclusionCalculator::ComputeNativeWindowOcclusionStatus);
if (virtual_desktop_manager_internal_) {
virtual_desktop_update_timer_.Start(
FROM_HERE, kUpdateVirtualDesktopDelay, this,
&WindowOcclusionCalculator::ComputeVirtualDesktopUsed);
}
}
}
void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
......@@ -769,7 +851,7 @@ bool NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
base::Optional<bool> NativeWindowOcclusionTrackerWin::
WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop(HWND hwnd) {
if (!virtual_desktop_manager_)
if (!virtual_desktop_manager_ || !virtual_desktops_used_)
return true;
BOOL on_current_desktop;
......
......@@ -34,6 +34,8 @@ namespace gfx {
class Rect;
}
struct IVirtualDesktopManagerInternal;
namespace aura {
// This class keeps track of whether any HWNDs are occluding any app windows.
......@@ -134,6 +136,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// their occlusion status has changed.
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
// future, if one isn't already scheduled.
void ScheduleOcclusionCalculationIfNeeded();
......@@ -217,6 +223,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// Timer to delay occlusion update.
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
// events, in order to wait until the window move is complete before
// calculating window occlusion.
......@@ -244,9 +253,18 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin
// ignore windows occluded by the dragged window.
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+.
Microsoft::WRL::ComPtr<IVirtualDesktopManager> virtual_desktop_manager_;
Microsoft::WRL::ComPtr<IVirtualDesktopManagerInternal>
virtual_desktop_manager_internal_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<WindowOcclusionCalculator> weak_factory_{this};
......
......@@ -24,6 +24,10 @@ namespace features {
// If enabled, calculate native window occlusion - Windows-only.
const base::Feature kCalculateNativeWinOcclusion{
"CalculateNativeWinOcclusion", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed{
"CalculateNativeWinOcclusionCheckVirtualDesktopUsed",
base::FEATURE_DISABLED_BY_DEFAULT};
#endif // OW_WIN
// Whether or not to delegate color queries to the color provider.
......
......@@ -48,6 +48,8 @@ COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsUiGpuRasterizationEnabled();
COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kCalculateNativeWinOcclusion;
COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kCalculateNativeWinOcclusionCheckVirtualDesktopUsed;
COMPONENT_EXPORT(UI_BASE_FEATURES)
extern const base::Feature kElasticOverscrollWin;
COMPONENT_EXPORT(UI_BASE_FEATURES)
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