Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Ozone-DRI] Add display observer
Browse files Browse the repository at this point in the history
Introduce a display change observer and make the window delegates update
their cached HardwareDisplayController pointer as a result of changes in
ScreenManager.

BUG=446184
NOTRY=true

Review URL: https://codereview.chromium.org/844343002

Cr-Commit-Position: refs/heads/master@{#311112}

Review URL: https://codereview.chromium.org/855153002

Cr-Commit-Position: refs/branch-heads/2272@{#40}
Cr-Branched-From: 827a380-refs/heads/master@{#310958}
  • Loading branch information
mspang committed Jan 16, 2015
1 parent 642f5df commit 5644d4c
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 27 deletions.
1 change: 1 addition & 0 deletions ui/ozone/platform/dri/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ source_set("dri_common") {
"channel_observer.h",
"crtc_controller.cc",
"crtc_controller.h",
"display_change_observer.h",
"display_manager.cc",
"display_manager.h",
"display_mode_dri.cc",
Expand Down
26 changes: 26 additions & 0 deletions ui/ozone/platform/dri/display_change_observer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_OZONE_PLATFORM_DRI_DISPLAY_CHANGE_OBSERVER_H_
#define UI_OZONE_PLATFORM_DRI_DISPLAY_CHANGE_OBSERVER_H_

namespace ui {

class HardwareDisplayController;

class DisplayChangeObserver {
public:
virtual ~DisplayChangeObserver() {}

// Called when |controller| was changed/added.
virtual void OnDisplayChanged(HardwareDisplayController* controller) = 0;

// Called just before |controller| is removed. Observers that cached
// |controller| must invalidate it at this point.
virtual void OnDisplayRemoved(HardwareDisplayController* controller) = 0;
};

} // namespace ui

#endif // UI_OZONE_PLATFORM_DRI_DISPLAY_CHANGE_OBSERVER_H_
1 change: 1 addition & 0 deletions ui/ozone/platform/dri/dri.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
'channel_observer.h',
'crtc_controller.cc',
'crtc_controller.h',
'display_change_observer.h',
'display_manager.cc',
'display_manager.h',
'display_mode_dri.cc',
Expand Down
30 changes: 29 additions & 1 deletion ui/ozone/platform/dri/dri_window_delegate_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ DriWindowDelegateImpl::~DriWindowDelegateImpl() {
void DriWindowDelegateImpl::Initialize() {
TRACE_EVENT1("dri", "DriWindowDelegateImpl::Initialize", "widget", widget_);

screen_manager_->AddObserver(this);

uint64_t cursor_width = 64;
uint64_t cursor_height = 64;
drm_->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width);
Expand All @@ -78,19 +80,21 @@ void DriWindowDelegateImpl::Initialize() {

void DriWindowDelegateImpl::Shutdown() {
TRACE_EVENT1("dri", "DriWindowDelegateImpl::Shutdown", "widget", widget_);
screen_manager_->RemoveObserver(this);
}

gfx::AcceleratedWidget DriWindowDelegateImpl::GetAcceleratedWidget() {
return widget_;
}

HardwareDisplayController* DriWindowDelegateImpl::GetController() {
return controller_.get();
return controller_;
}

void DriWindowDelegateImpl::OnBoundsChanged(const gfx::Rect& bounds) {
TRACE_EVENT2("dri", "DriWindowDelegateImpl::OnBoundsChanged", "widget",
widget_, "bounds", bounds.ToString());
bounds_ = bounds;
controller_ = screen_manager_->GetDisplayController(bounds);
}

Expand Down Expand Up @@ -128,6 +132,30 @@ void DriWindowDelegateImpl::MoveCursor(const gfx::Point& location) {
controller_->MoveCursor(location);
}

void DriWindowDelegateImpl::OnDisplayChanged(
HardwareDisplayController* controller) {
DCHECK(controller);

gfx::Rect controller_bounds =
gfx::Rect(controller->origin(), controller->GetModeSize());
if (controller_) {
if (controller_ != controller)
return;

if (controller->IsDisabled() || bounds_ != controller_bounds)
controller_ = nullptr;
} else {
if (bounds_ == controller_bounds && !controller->IsDisabled())
controller_ = controller;
}
}

void DriWindowDelegateImpl::OnDisplayRemoved(
HardwareDisplayController* controller) {
if (controller_ == controller)
controller_ = nullptr;
}

void DriWindowDelegateImpl::ResetCursor(bool bitmap_only) {
if (cursor_bitmaps_.size()) {
// Draw new cursor into backbuffer.
Expand Down
21 changes: 14 additions & 7 deletions ui/ozone/platform/dri/dri_window_delegate_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
#ifndef UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_IMPL_H_
#define UI_OZONE_PLATFORM_DRI_DRI_WINDOW_DELEGATE_IMPL_H_

#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/dri/display_change_observer.h"
#include "ui/ozone/platform/dri/dri_window_delegate.h"

namespace gfx {
class Rect;
} // namespace gfx

namespace ui {

class DriBuffer;
Expand All @@ -23,7 +20,8 @@ class DriWrapper;
class HardwareDisplayController;
class ScreenManager;

class DriWindowDelegateImpl : public DriWindowDelegate {
class DriWindowDelegateImpl : public DriWindowDelegate,
public DisplayChangeObserver {
public:
DriWindowDelegateImpl(gfx::AcceleratedWidget widget,
DriWrapper* drm,
Expand All @@ -44,6 +42,10 @@ class DriWindowDelegateImpl : public DriWindowDelegate {
const gfx::Point& location) override;
void MoveCursor(const gfx::Point& location) override;

// DisplayChangeObserver:
void OnDisplayChanged(HardwareDisplayController* controller) override;
void OnDisplayRemoved(HardwareDisplayController* controller) override;

private:
// Draw the last set cursor & update the cursor plane.
void ResetCursor(bool bitmap_only);
Expand All @@ -57,7 +59,12 @@ class DriWindowDelegateImpl : public DriWindowDelegate {
DriWindowDelegateManager* window_manager_; // Not owned.
ScreenManager* screen_manager_; // Not owned.

base::WeakPtr<HardwareDisplayController> controller_;
// The current bounds of the window.
gfx::Rect bounds_;

// The controller associated with the current window. This may be nullptr if
// the window isn't over an active display.
HardwareDisplayController* controller_;

base::RepeatingTimer<DriWindowDelegateImpl> cursor_timer_;

Expand Down
28 changes: 23 additions & 5 deletions ui/ozone/platform/dri/screen_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ void ScreenManager::RemoveDisplayController(uint32_t crtc) {
if (it != controllers_.end()) {
bool is_mirrored = (*it)->IsMirrored();
(*it)->RemoveCrtc(crtc);
if (!is_mirrored)
if (!is_mirrored) {
FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
OnDisplayRemoved(*it));
controllers_.erase(it);
}
}
}

Expand All @@ -105,7 +108,6 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
<< ") doesn't exist.";

HardwareDisplayController* controller = *it;
controller = *it;
// If nothing changed just enable the controller. Note, we perform an exact
// comparison on the mode since the refresh rate may have changed.
if (SameMode(mode, controller->get_mode()) &&
Expand All @@ -119,6 +121,8 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
return HandleMirrorMode(it, mirror, crtc, connector);
}

FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
OnDisplayChanged(controller));
// Just re-enable the controller to re-use the current state.
return controller->Enable();
}
Expand Down Expand Up @@ -159,7 +163,7 @@ bool ScreenManager::DisableDisplayController(uint32_t crtc) {
return false;
}

base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
HardwareDisplayController* ScreenManager::GetDisplayController(
const gfx::Rect& bounds) {
// TODO(dnicoara): Remove hack once TestScreen uses a simple Ozone display
// configuration reader and ScreenManager is called from there to create the
Expand All @@ -170,9 +174,17 @@ base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
HardwareDisplayControllers::iterator it =
FindActiveDisplayControllerByLocation(bounds);
if (it != controllers_.end())
return (*it)->AsWeakPtr();
return *it;

return nullptr;
}

void ScreenManager::AddObserver(DisplayChangeObserver* observer) {
observers_.AddObserver(observer);
}

return base::WeakPtr<HardwareDisplayController>();
void ScreenManager::RemoveObserver(DisplayChangeObserver* observer) {
observers_.RemoveObserver(observer);
}

ScreenManager::HardwareDisplayControllers::iterator
Expand Down Expand Up @@ -244,6 +256,8 @@ bool ScreenManager::ModesetDisplayController(
return false;
}

FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
OnDisplayChanged(controller));
return true;
}

Expand All @@ -254,6 +268,10 @@ bool ScreenManager::HandleMirrorMode(
uint32_t connector) {
(*mirror)->AddCrtc((*original)->RemoveCrtc(crtc));
if ((*mirror)->Enable()) {
FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
OnDisplayRemoved(*original));
FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
OnDisplayChanged(*mirror));
controllers_.erase(original);
return true;
}
Expand Down
18 changes: 10 additions & 8 deletions ui/ozone/platform/dri/screen_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "ui/ozone/platform/dri/display_change_observer.h"
#include "ui/ozone/platform/dri/hardware_display_controller.h"

typedef struct _drmModeModeInfo drmModeModeInfo;
Expand Down Expand Up @@ -49,13 +50,12 @@ class ScreenManager {
bool DisableDisplayController(uint32_t crtc);

// Returns a reference to the display controller configured to display within
// |bounds|.
// This returns a weak reference since the display controller may be destroyed
// at any point in time, but the changes are propagated to the compositor much
// later (Compositor owns SurfaceOzone*, which is responsible for updating the
// display surface).
base::WeakPtr<HardwareDisplayController> GetDisplayController(
const gfx::Rect& bounds);
// |bounds|. If the caller caches the controller it must also register as an
// observer to be notified when the controller goes out of scope.
HardwareDisplayController* GetDisplayController(const gfx::Rect& bounds);

void AddObserver(DisplayChangeObserver* observer);
void RemoveObserver(DisplayChangeObserver* observer);

// On non CrOS builds there is no display configurator to look-up available
// displays and initialize the HDCs. In such cases this is called internally
Expand Down Expand Up @@ -92,6 +92,8 @@ class ScreenManager {
// List of display controllers (active and disabled).
HardwareDisplayControllers controllers_;

ObserverList<DisplayChangeObserver> observers_;

DISALLOW_COPY_AND_ASSIGN(ScreenManager);
};

Expand Down
Loading

0 comments on commit 5644d4c

Please sign in to comment.