Commit bde7f92c authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Add the Display Observer for Direct Composition in Windows.

The purpose is to observe the events of monitor plugged-in/unplugged for
Direct Composition overlays so we can update the hardware overlay caps
upon display change. DisplayAdded() and DisplayRemoved() are added to
DirectCompositionSurfaceWin.

The display observer goes through the GPU data manager in the browser
process first. It will then notify the GPU switch observer in the GPU
process through Mojo.

This CL is limited to Windows only. The display observer might work (not
tested yet) for Mac if we need it later. (But no code support for Linux.)


Bug: 1042989
Change-Id: I53dc1689795d569ea60290c13dacfcc7f3ee9152
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2011134
Commit-Queue: Maggie Chen <magchen@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#735009}
parent 4f0592d4
...@@ -162,6 +162,10 @@ class TestGpuService : public mojom::GpuService { ...@@ -162,6 +162,10 @@ class TestGpuService : public mojom::GpuService {
void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override {} void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override {}
void DisplayAdded() override {}
void DisplayRemoved() override {}
void DestroyAllChannels() override {} void DestroyAllChannels() override {}
void OnBackgroundCleanup() override {} void OnBackgroundCleanup() override {}
......
...@@ -848,6 +848,20 @@ void GpuServiceImpl::GpuSwitched(gl::GpuPreference active_gpu_heuristic) { ...@@ -848,6 +848,20 @@ void GpuServiceImpl::GpuSwitched(gl::GpuPreference active_gpu_heuristic) {
active_gpu_heuristic); active_gpu_heuristic);
} }
void GpuServiceImpl::DisplayAdded() {
DVLOG(1) << "GPU: A monitor is plugged in";
if (!in_host_process())
ui::GpuSwitchingManager::GetInstance()->NotifyDisplayAdded();
}
void GpuServiceImpl::DisplayRemoved() {
DVLOG(1) << "GPU: A monitor is unplugged ";
if (!in_host_process())
ui::GpuSwitchingManager::GetInstance()->NotifyDisplayRemoved();
}
void GpuServiceImpl::DestroyAllChannels() { void GpuServiceImpl::DestroyAllChannels() {
if (io_runner_->BelongsToCurrentThread()) { if (io_runner_->BelongsToCurrentThread()) {
main_runner_->PostTask( main_runner_->PostTask(
......
...@@ -169,6 +169,8 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate, ...@@ -169,6 +169,8 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
const std::string& data) override; const std::string& data) override;
void WakeUpGpu() override; void WakeUpGpu() override;
void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override; void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
void DisplayAdded() override;
void DisplayRemoved() override;
void DestroyAllChannels() override; void DestroyAllChannels() override;
void OnBackgroundCleanup() override; void OnBackgroundCleanup() override;
void OnBackgrounded() override; void OnBackgrounded() override;
......
...@@ -69,14 +69,12 @@ void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate( ...@@ -69,14 +69,12 @@ void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate(
private_->RequestVideoMemoryUsageStatsUpdate(std::move(callback)); private_->RequestVideoMemoryUsageStatsUpdate(std::move(callback));
} }
void GpuDataManagerImpl::AddObserver( void GpuDataManagerImpl::AddObserver(GpuDataManagerObserver* observer) {
GpuDataManagerObserver* observer) {
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
private_->AddObserver(observer); private_->AddObserver(observer);
} }
void GpuDataManagerImpl::RemoveObserver( void GpuDataManagerImpl::RemoveObserver(GpuDataManagerObserver* observer) {
GpuDataManagerObserver* observer) {
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
private_->RemoveObserver(observer); private_->RemoveObserver(observer);
} }
...@@ -198,8 +196,7 @@ void GpuDataManagerImpl::AddLogMessage(int level, ...@@ -198,8 +196,7 @@ void GpuDataManagerImpl::AddLogMessage(int level,
private_->AddLogMessage(level, header, message); private_->AddLogMessage(level, header, message);
} }
void GpuDataManagerImpl::ProcessCrashed( void GpuDataManagerImpl::ProcessCrashed(base::TerminationStatus exit_code) {
base::TerminationStatus exit_code) {
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
private_->ProcessCrashed(exit_code); private_->ProcessCrashed(exit_code);
} }
...@@ -225,8 +222,8 @@ bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& top_origin_url, ...@@ -225,8 +222,8 @@ bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& top_origin_url,
int render_frame_id, int render_frame_id,
ThreeDAPIType requester) { ThreeDAPIType requester) {
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
return private_->Are3DAPIsBlocked( return private_->Are3DAPIsBlocked(top_origin_url, render_process_id,
top_origin_url, render_process_id, render_frame_id, requester); render_frame_id, requester);
} }
void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) { void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
...@@ -265,6 +262,16 @@ void GpuDataManagerImpl::SetApplicationVisible(bool is_visible) { ...@@ -265,6 +262,16 @@ void GpuDataManagerImpl::SetApplicationVisible(bool is_visible) {
private_->SetApplicationVisible(is_visible); private_->SetApplicationVisible(is_visible);
} }
void GpuDataManagerImpl::OnDisplayAdded(const display::Display& new_display) {
base::AutoLock auto_lock(lock_);
private_->OnDisplayAdded(new_display);
}
void GpuDataManagerImpl::OnDisplayRemoved(const display::Display& old_display) {
base::AutoLock auto_lock(lock_);
private_->OnDisplayRemoved(old_display);
}
GpuDataManagerImpl::GpuDataManagerImpl() GpuDataManagerImpl::GpuDataManagerImpl()
: private_(std::make_unique<GpuDataManagerImplPrivate>(this)) {} : private_(std::make_unique<GpuDataManagerImplPrivate>(this)) {}
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h" #include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_mode.h" #include "gpu/config/gpu_mode.h"
#include "ui/display/display_observer.h"
class GURL; class GURL;
...@@ -40,7 +41,8 @@ namespace content { ...@@ -40,7 +41,8 @@ namespace content {
class GpuDataManagerImplPrivate; class GpuDataManagerImplPrivate;
class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager { class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager,
public display::DisplayObserver {
public: public:
// Getter for the singleton. This will return NULL on failure. // Getter for the singleton. This will return NULL on failure.
static GpuDataManagerImpl* GetInstance(); static GpuDataManagerImpl* GetInstance();
...@@ -159,6 +161,10 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager { ...@@ -159,6 +161,10 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
// whether we are in the foreground or background. // whether we are in the foreground or background.
void SetApplicationVisible(bool is_visible); void SetApplicationVisible(bool is_visible);
// DisplayObserver overrides.
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const display::Display& old_display) override;
private: private:
friend class GpuDataManagerImplPrivate; friend class GpuDataManagerImplPrivate;
friend class GpuDataManagerImplPrivateTest; friend class GpuDataManagerImplPrivateTest;
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "gpu/vulkan/buildflags.h" #include "gpu/vulkan/buildflags.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#include "ui/display/screen.h"
#include "ui/gfx/switches.h" #include "ui/gfx/switches.h"
#include "ui/gl/buildflags.h" #include "ui/gl/buildflags.h"
#include "ui/gl/gl_implementation.h" #include "ui/gl/gl_implementation.h"
...@@ -349,6 +350,12 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner) ...@@ -349,6 +350,12 @@ GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_); CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
#endif // OS_MACOSX #endif // OS_MACOSX
#if defined(OS_WIN)
if (BrowserThread::CurrentlyOn(BrowserThread::UI) &&
display::Screen::GetScreen())
display::Screen::GetScreen()->AddObserver(owner_);
#endif
// For testing only. // For testing only.
if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs))
domain_blocking_enabled_ = false; domain_blocking_enabled_ = false;
...@@ -365,6 +372,11 @@ GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() { ...@@ -365,6 +372,11 @@ GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_); CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
#endif #endif
#if defined(OS_WIN)
if (display::Screen::GetScreen())
display::Screen::GetScreen()->RemoveObserver(owner_);
#endif
} }
void GpuDataManagerImplPrivate::InitializeGpuModes() { void GpuDataManagerImplPrivate::InitializeGpuModes() {
...@@ -907,8 +919,9 @@ void GpuDataManagerImplPrivate::OnGpuBlocked() { ...@@ -907,8 +919,9 @@ void GpuDataManagerImplPrivate::OnGpuBlocked() {
NotifyGpuInfoUpdate(); NotifyGpuInfoUpdate();
} }
void GpuDataManagerImplPrivate::AddLogMessage( void GpuDataManagerImplPrivate::AddLogMessage(int level,
int level, const std::string& header, const std::string& message) { const std::string& header,
const std::string& message) {
// Some clients emit many log messages. This has been observed to consume GBs // Some clients emit many log messages. This has been observed to consume GBs
// of memory in the wild // of memory in the wild
// https://bugs.chromium.org/p/chromium/issues/detail?id=798012. Use a limit // https://bugs.chromium.org/p/chromium/issues/detail?id=798012. Use a limit
...@@ -955,6 +968,32 @@ void GpuDataManagerImplPrivate::HandleGpuSwitch() { ...@@ -955,6 +968,32 @@ void GpuDataManagerImplPrivate::HandleGpuSwitch() {
active_gpu_heuristic_)); active_gpu_heuristic_));
} }
void GpuDataManagerImplPrivate::OnDisplayAdded(
const display::Display& new_display) {
base::AutoUnlock unlock(owner_->lock_);
// Notify observers in the browser process.
ui::GpuSwitchingManager::GetInstance()->NotifyDisplayAdded();
// Pass the notification to the GPU process to notify observers there.
GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED, false /* force_create */,
base::BindOnce([](GpuProcessHost* host) {
if (host)
host->gpu_service()->DisplayAdded();
}));
}
void GpuDataManagerImplPrivate::OnDisplayRemoved(
const display::Display& old_display) {
base::AutoUnlock unlock(owner_->lock_);
// Notify observers in the browser process.
ui::GpuSwitchingManager::GetInstance()->NotifyDisplayRemoved();
// Pass the notification to the GPU process to notify observers there.
GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED, false /* force_create */,
base::BindOnce([](GpuProcessHost* host) {
if (host)
host->gpu_service()->DisplayRemoved();
}));
}
bool GpuDataManagerImplPrivate::UpdateActiveGpu(uint32_t vendor_id, bool GpuDataManagerImplPrivate::UpdateActiveGpu(uint32_t vendor_id,
uint32_t device_id) { uint32_t device_id) {
// Heuristics for dual-GPU detection. // Heuristics for dual-GPU detection.
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/values.h" #include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h"
#include "ui/display/display_observer.h"
#include "ui/gl/gpu_preference.h" #include "ui/gl/gpu_preference.h"
namespace base { namespace base {
...@@ -122,6 +123,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { ...@@ -122,6 +123,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void SetApplicationVisible(bool is_visible); void SetApplicationVisible(bool is_visible);
void OnDisplayAdded(const display::Display& new_display);
void OnDisplayRemoved(const display::Display& old_display);
private: private:
friend class GpuDataManagerImplPrivateTest; friend class GpuDataManagerImplPrivateTest;
......
...@@ -104,6 +104,8 @@ class TestGpuService : public viz::mojom::GpuService { ...@@ -104,6 +104,8 @@ class TestGpuService : public viz::mojom::GpuService {
const std::string& data) override {} const std::string& data) override {}
void WakeUpGpu() override {} void WakeUpGpu() override {}
void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override {} void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override {}
void DisplayAdded() override {}
void DisplayRemoved() override {}
void DestroyAllChannels() override {} void DestroyAllChannels() override {}
void OnBackgroundCleanup() override {} void OnBackgroundCleanup() override {}
void OnBackgrounded() override {} void OnBackgrounded() override {}
......
...@@ -120,6 +120,13 @@ interface GpuService { ...@@ -120,6 +120,13 @@ interface GpuService {
// is reconfigured, for example. // is reconfigured, for example.
GpuSwitched(gl.mojom.GpuPreference active_gpu_heuristic); GpuSwitched(gl.mojom.GpuPreference active_gpu_heuristic);
// Tells GPU that host has seen a monitor being plugged in.
DisplayAdded();
// Tells GPU that host has seen a monitor being unplugged.
DisplayRemoved();
// Tells GPU that all GPU channels are to be destroyed.
DestroyAllChannels(); DestroyAllChannels();
// Called by the browser shortly after the application is backgrounded. The // Called by the browser shortly after the application is backgrounded. The
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ui/gl/gl_angle_util_win.h" #include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_surface_presentation_helper.h" #include "ui/gl/gl_surface_presentation_helper.h"
#include "ui/gl/gl_switches.h" #include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
#include "ui/gl/vsync_thread_win.h" #include "ui/gl/vsync_thread_win.h"
#ifndef EGL_ANGLE_flexible_surface_compatibility #ifndef EGL_ANGLE_flexible_surface_compatibility
...@@ -227,9 +228,11 @@ DirectCompositionSurfaceWin::DirectCompositionSurfaceWin( ...@@ -227,9 +228,11 @@ DirectCompositionSurfaceWin::DirectCompositionSurfaceWin(
// Call GetWeakPtr() on main thread before calling on vsync thread so that the // Call GetWeakPtr() on main thread before calling on vsync thread so that the
// internal weak reference is initialized in a thread-safe way. // internal weak reference is initialized in a thread-safe way.
weak_ptr_ = weak_factory_.GetWeakPtr(); weak_ptr_ = weak_factory_.GetWeakPtr();
ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
} }
DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() { DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() {
ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this);
Destroy(); Destroy();
} }
...@@ -756,6 +759,13 @@ void DirectCompositionSurfaceWin::HandleVSyncOnMainThread( ...@@ -756,6 +759,13 @@ void DirectCompositionSurfaceWin::HandleVSyncOnMainThread(
} }
} }
void DirectCompositionSurfaceWin::OnGpuSwitched(
gl::GpuPreference active_gpu_heuristic) {}
void DirectCompositionSurfaceWin::OnDisplayAdded() {}
void DirectCompositionSurfaceWin::OnDisplayRemoved() {}
scoped_refptr<base::TaskRunner> scoped_refptr<base::TaskRunner>
DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() {
return child_window_.GetTaskRunnerForTesting(); return child_window_.GetTaskRunnerForTesting();
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ui/gl/child_window_win.h" #include "ui/gl/child_window_win.h"
#include "ui/gl/gl_export.h" #include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface_egl.h" #include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gpu_switching_observer.h"
#include "ui/gl/vsync_observer.h" #include "ui/gl/vsync_observer.h"
namespace gl { namespace gl {
...@@ -24,7 +25,8 @@ class GLSurfacePresentationHelper; ...@@ -24,7 +25,8 @@ class GLSurfacePresentationHelper;
class VSyncThreadWin; class VSyncThreadWin;
class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL, class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL,
public VSyncObserver { public VSyncObserver,
public ui::GpuSwitchingObserver {
public: public:
using VSyncCallback = using VSyncCallback =
base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>; base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>;
...@@ -129,6 +131,11 @@ class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL, ...@@ -129,6 +131,11 @@ class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL,
// VSyncObserver implementation. // VSyncObserver implementation.
void OnVSync(base::TimeTicks vsync_time, base::TimeDelta interval) override; void OnVSync(base::TimeTicks vsync_time, base::TimeDelta interval) override;
// Implements GpuSwitchingObserver.
void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
void OnDisplayAdded() override;
void OnDisplayRemoved() override;
HWND window() const { return window_; } HWND window() const { return window_; }
scoped_refptr<base::TaskRunner> GetWindowTaskRunnerForTesting(); scoped_refptr<base::TaskRunner> GetWindowTaskRunnerForTesting();
......
...@@ -29,4 +29,14 @@ void GpuSwitchingManager::NotifyGpuSwitched( ...@@ -29,4 +29,14 @@ void GpuSwitchingManager::NotifyGpuSwitched(
observer.OnGpuSwitched(active_gpu_heuristic); observer.OnGpuSwitched(active_gpu_heuristic);
} }
void GpuSwitchingManager::NotifyDisplayAdded() {
for (GpuSwitchingObserver& observer : observer_list_)
observer.OnDisplayAdded();
}
void GpuSwitchingManager::NotifyDisplayRemoved() {
for (GpuSwitchingObserver& observer : observer_list_)
observer.OnDisplayRemoved();
}
} // namespace ui } // namespace ui
...@@ -33,6 +33,12 @@ class GL_EXPORT GpuSwitchingManager { ...@@ -33,6 +33,12 @@ class GL_EXPORT GpuSwitchingManager {
// If this heuristic fails, then kDefault is passed as argument. // If this heuristic fails, then kDefault is passed as argument.
void NotifyGpuSwitched(gl::GpuPreference active_gpu_heuristic); void NotifyGpuSwitched(gl::GpuPreference active_gpu_heuristic);
// Called when a monitor is plugged in.
void NotifyDisplayAdded();
// Called when a monitor is unplugged.
void NotifyDisplayRemoved();
private: private:
friend struct base::DefaultSingletonTraits<GpuSwitchingManager>; friend struct base::DefaultSingletonTraits<GpuSwitchingManager>;
......
...@@ -14,6 +14,12 @@ class GL_EXPORT GpuSwitchingObserver { ...@@ -14,6 +14,12 @@ class GL_EXPORT GpuSwitchingObserver {
public: public:
// Called for any observer when the system switches to a different GPU. // Called for any observer when the system switches to a different GPU.
virtual void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) {} virtual void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) {}
// Called for any observer when a monitor is plugged in.
virtual void OnDisplayAdded() {}
// Called for any observer when a monitor is unplugged.
virtual void OnDisplayRemoved() {}
}; };
} // namespace ui } // namespace ui
......
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