summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordnicoara <dnicoara@chromium.org>2015-04-01 09:41:36 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-01 16:42:57 +0000
commited7491b3e66fd2c7271157e61d9b673971a2a52d (patch)
tree60eb905a878224b14d5a00bffa928ff137a9a57d
parent3e2d63d0413e2f0507f76cbe82cb1a03af451da8 (diff)
downloadchromium_src-ed7491b3e66fd2c7271157e61d9b673971a2a52d.zip
chromium_src-ed7491b3e66fd2c7271157e61d9b673971a2a52d.tar.gz
chromium_src-ed7491b3e66fd2c7271157e61d9b673971a2a52d.tar.bz2
[Ozone-Drm] Update the cursor when displays change
This change updates the logic to update the display the hardware cursor is shown on when windows move and when the display configuration changes. It also moves some of the checks from the UI thread to the GPU process. BUG=470493 Review URL: https://codereview.chromium.org/1041443002 Cr-Commit-Position: refs/heads/master@{#323257}
-rw-r--r--ui/ozone/platform/drm/gpu/display_change_observer.h26
-rw-r--r--ui/ozone/platform/drm/gpu/drm_surface_unittest.cc15
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.cc50
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.h15
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window_unittest.cc30
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager.cc72
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager.h16
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager_unittest.cc117
-rw-r--r--ui/ozone/platform/drm/host/drm_cursor.cc25
-rw-r--r--ui/ozone/platform/drm/host/drm_cursor.h5
-rw-r--r--ui/ozone/platform/drm/host/drm_window_host.cc8
-rw-r--r--ui/ozone/platform/drm/test/mock_drm_device.cc7
-rw-r--r--ui/ozone/platform/drm/test/mock_drm_device.h9
13 files changed, 199 insertions, 196 deletions
diff --git a/ui/ozone/platform/drm/gpu/display_change_observer.h b/ui/ozone/platform/drm/gpu/display_change_observer.h
deleted file mode 100644
index 9896770..0000000
--- a/ui/ozone/platform/drm/gpu/display_change_observer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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_DRM_GPU_DISPLAY_CHANGE_OBSERVER_H_
-#define UI_OZONE_PLATFORM_DRM_GPU_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_DRM_GPU_DISPLAY_CHANGE_OBSERVER_H_
diff --git a/ui/ozone/platform/drm/gpu/drm_surface_unittest.cc b/ui/ozone/platform/drm/gpu/drm_surface_unittest.cc
index 59453c4..1aaa4e3 100644
--- a/ui/ozone/platform/drm/gpu/drm_surface_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_surface_unittest.cc
@@ -43,7 +43,6 @@ class DrmSurfaceTest : public testing::Test {
scoped_ptr<ui::DrmBufferGenerator> buffer_generator_;
scoped_ptr<ui::ScreenManager> screen_manager_;
scoped_ptr<ui::DrmDeviceManager> drm_device_manager_;
- scoped_ptr<ui::DrmWindow> window_delegate_;
scoped_ptr<ui::DrmSurface> surface_;
private:
@@ -62,20 +61,24 @@ void DrmSurfaceTest::SetUp() {
drm_, kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode);
drm_device_manager_.reset(new ui::DrmDeviceManager(drm_));
- window_delegate_.reset(new ui::DrmWindow(
+ scoped_ptr<ui::DrmWindow> window(new ui::DrmWindow(
kDefaultWidgetHandle, drm_device_manager_.get(), screen_manager_.get()));
- window_delegate_->Initialize();
- window_delegate_->OnBoundsChanged(
+ window->Initialize();
+ window->OnBoundsChanged(
gfx::Rect(gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay)));
+ screen_manager_->AddWindow(kDefaultWidgetHandle, window.Pass());
- surface_.reset(new ui::DrmSurface(window_delegate_.get()));
+ surface_.reset(
+ new ui::DrmSurface(screen_manager_->GetWindow(kDefaultWidgetHandle)));
surface_->ResizeCanvas(
gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay));
}
void DrmSurfaceTest::TearDown() {
surface_.reset();
- window_delegate_->Shutdown();
+ scoped_ptr<ui::DrmWindow> window =
+ screen_manager_->RemoveWindow(kDefaultWidgetHandle);
+ window->Shutdown();
drm_ = nullptr;
message_loop_.reset();
}
diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc
index 0e8ad28..7517f09 100644
--- a/ui/ozone/platform/drm/gpu/drm_window.cc
+++ b/ui/ozone/platform/drm/gpu/drm_window.cc
@@ -61,12 +61,10 @@ void DrmWindow::Initialize() {
TRACE_EVENT1("drm", "DrmWindow::Initialize", "widget", widget_);
device_manager_->UpdateDrmDevice(widget_, nullptr);
- screen_manager_->AddObserver(this);
}
void DrmWindow::Shutdown() {
TRACE_EVENT1("drm", "DrmWindow::Shutdown", "widget", widget_);
- screen_manager_->RemoveObserver(this);
device_manager_->RemoveDrmDevice(widget_);
}
@@ -82,9 +80,7 @@ void DrmWindow::OnBoundsChanged(const gfx::Rect& bounds) {
TRACE_EVENT2("drm", "DrmWindow::OnBoundsChanged", "widget", widget_, "bounds",
bounds.ToString());
bounds_ = bounds;
- controller_ = screen_manager_->GetDisplayController(bounds);
- UpdateWidgetToDrmDeviceMapping();
- UpdateCursorBuffers();
+ screen_manager_->UpdateControllerToWindowMapping();
}
void DrmWindow::SetCursor(const std::vector<SkBitmap>& bitmaps,
@@ -120,35 +116,6 @@ void DrmWindow::MoveCursor(const gfx::Point& location) {
controller_->MoveCursor(location);
}
-void DrmWindow::OnDisplayChanged(HardwareDisplayController* controller) {
- DCHECK(controller);
-
- // If we have a new controller we need to re-allocate the buffers.
- bool should_allocate_cursor_buffers = controller_ != 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;
- }
-
- UpdateWidgetToDrmDeviceMapping();
- if (should_allocate_cursor_buffers)
- UpdateCursorBuffers();
-}
-
-void DrmWindow::OnDisplayRemoved(HardwareDisplayController* controller) {
- if (controller_ == controller)
- controller_ = nullptr;
-}
-
void DrmWindow::ResetCursor(bool bitmap_only) {
if (!controller_)
return;
@@ -176,12 +143,17 @@ void DrmWindow::OnCursorAnimationTimeout() {
ResetCursor(true);
}
-void DrmWindow::UpdateWidgetToDrmDeviceMapping() {
- scoped_refptr<DrmDevice> drm = nullptr;
- if (controller_)
- drm = controller_->GetAllocationDrmDevice();
+void DrmWindow::SetController(HardwareDisplayController* controller) {
+ if (controller_ == controller)
+ return;
- device_manager_->UpdateDrmDevice(widget_, drm);
+ controller_ = controller;
+ device_manager_->UpdateDrmDevice(
+ widget_, controller ? controller->GetAllocationDrmDevice() : nullptr);
+
+ UpdateCursorBuffers();
+ // We changed displays, so we want to update the cursor as well.
+ ResetCursor(false /* bitmap_only */);
}
void DrmWindow::UpdateCursorBuffers() {
diff --git a/ui/ozone/platform/drm/gpu/drm_window.h b/ui/ozone/platform/drm/gpu/drm_window.h
index aa01ae9..f655bbb 100644
--- a/ui/ozone/platform/drm/gpu/drm_window.h
+++ b/ui/ozone/platform/drm/gpu/drm_window.h
@@ -12,7 +12,6 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/ozone_export.h"
-#include "ui/ozone/platform/drm/gpu/display_change_observer.h"
class SkBitmap;
@@ -34,13 +33,15 @@ class ScreenManager;
// A window is associated with the display whose bounds contains the window
// bounds. If there's no suitable display, the window is disconnected and its
// contents will not be visible.
-class OZONE_EXPORT DrmWindow : public DisplayChangeObserver {
+class OZONE_EXPORT DrmWindow {
public:
DrmWindow(gfx::AcceleratedWidget widget,
DrmDeviceManager* device_manager,
ScreenManager* screen_manager);
- ~DrmWindow() override;
+ ~DrmWindow();
+
+ gfx::Rect bounds() const { return bounds_; }
void Initialize();
@@ -53,6 +54,8 @@ class OZONE_EXPORT DrmWindow : public DisplayChangeObserver {
// not cache the result as the controller may change as the window is moved.
HardwareDisplayController* GetController();
+ void SetController(HardwareDisplayController* controller);
+
// Called when the window is resized/moved.
void OnBoundsChanged(const gfx::Rect& bounds);
@@ -70,10 +73,6 @@ class OZONE_EXPORT DrmWindow : public DisplayChangeObserver {
// Move the HW cursor to the specified location.
void MoveCursor(const gfx::Point& location);
- // 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);
@@ -81,8 +80,6 @@ class OZONE_EXPORT DrmWindow : public DisplayChangeObserver {
// Draw next frame in an animated cursor.
void OnCursorAnimationTimeout();
- void UpdateWidgetToDrmDeviceMapping();
-
// When |controller_| changes this is called to reallocate the cursor buffers
// since the allocation DRM device may have changed.
void UpdateCursorBuffers();
diff --git a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
index 6ccf80c..37d9040 100644
--- a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
@@ -44,6 +44,15 @@ std::vector<skia::RefPtr<SkSurface>> GetCursorBuffers(
return cursor_buffers;
}
+SkBitmap AllocateBitmap(const gfx::Size& size) {
+ SkBitmap image;
+ SkImageInfo info = SkImageInfo::Make(size.width(), size.height(),
+ kN32_SkColorType, kPremul_SkAlphaType);
+ image.allocPixels(info);
+ image.eraseColor(SK_ColorWHITE);
+ return image;
+}
+
} // namespace
class DrmWindowTest : public testing::Test {
@@ -91,16 +100,10 @@ void DrmWindowTest::TearDown() {
}
TEST_F(DrmWindowTest, SetCursorImage) {
- SkBitmap image;
- SkImageInfo info =
- SkImageInfo::Make(6, 4, kN32_SkColorType, kPremul_SkAlphaType);
- image.allocPixels(info);
- image.eraseColor(SK_ColorWHITE);
-
- std::vector<SkBitmap> cursor_bitmaps;
- cursor_bitmaps.push_back(image);
+ const gfx::Size cursor_size(6, 4);
screen_manager_->GetWindow(kDefaultWidgetHandle)
- ->SetCursor(cursor_bitmaps, gfx::Point(4, 2), 0);
+ ->SetCursor(std::vector<SkBitmap>(1, AllocateBitmap(cursor_size)),
+ gfx::Point(4, 2), 0);
SkBitmap cursor;
std::vector<skia::RefPtr<SkSurface>> cursor_buffers = GetCursorBuffers(drm_);
@@ -113,7 +116,7 @@ TEST_F(DrmWindowTest, SetCursorImage) {
// Check that the frontbuffer is displaying the right image as set above.
for (int i = 0; i < cursor.height(); ++i) {
for (int j = 0; j < cursor.width(); ++j) {
- if (j < info.width() && i < info.height())
+ if (j < cursor_size.width() && i < cursor_size.height())
EXPECT_EQ(SK_ColorWHITE, cursor.getColor(j, i));
else
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
@@ -123,6 +126,11 @@ TEST_F(DrmWindowTest, SetCursorImage) {
}
TEST_F(DrmWindowTest, CheckCursorSurfaceAfterChangingDevice) {
+ const gfx::Size cursor_size(6, 4);
+ screen_manager_->GetWindow(kDefaultWidgetHandle)
+ ->SetCursor(std::vector<SkBitmap>(1, AllocateBitmap(cursor_size)),
+ gfx::Point(4, 2), 0);
+
// Add another device.
scoped_refptr<ui::MockDrmDevice> drm = new ui::MockDrmDevice();
screen_manager_->AddDisplayController(drm, kDefaultCrtc, kDefaultConnector);
@@ -137,4 +145,6 @@ TEST_F(DrmWindowTest, CheckCursorSurfaceAfterChangingDevice) {
kDefaultMode.vdisplay));
EXPECT_EQ(2u, GetCursorBuffers(drm).size());
+ // Make sure the cursor is showing on the new display.
+ EXPECT_NE(0u, drm->get_cursor_handle_for_crtc(kDefaultCrtc));
}
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc
index 70addbd..b8b1fd3 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager.cc
+++ b/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -99,8 +99,7 @@ void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm,
bool is_mirrored = (*it)->IsMirrored();
(*it)->RemoveCrtc(drm, crtc);
if (!is_mirrored) {
- FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
- OnDisplayRemoved(*it));
+ UpdateControllerToWindowMapping();
controllers_.erase(it);
}
}
@@ -112,6 +111,20 @@ bool ScreenManager::ConfigureDisplayController(
uint32_t connector,
const gfx::Point& origin,
const drmModeModeInfo& mode) {
+ bool status =
+ ActualConfigureDisplayController(drm, crtc, connector, origin, mode);
+ if (status)
+ UpdateControllerToWindowMapping();
+
+ return status;
+}
+
+bool ScreenManager::ActualConfigureDisplayController(
+ const scoped_refptr<DrmDevice>& drm,
+ uint32_t crtc,
+ uint32_t connector,
+ const gfx::Point& origin,
+ const drmModeModeInfo& mode) {
gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay,
mode.vdisplay);
HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc);
@@ -134,9 +147,6 @@ bool ScreenManager::ConfigureDisplayController(
// Just re-enable the controller to re-use the current state.
bool enabled = controller->Enable();
- FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
- OnDisplayChanged(controller));
-
return enabled;
}
@@ -172,6 +182,7 @@ bool ScreenManager::DisableDisplayController(
}
(*it)->Disable();
+ UpdateControllerToWindowMapping();
return true;
}
@@ -194,12 +205,14 @@ void ScreenManager::AddWindow(gfx::AcceleratedWidget widget,
std::pair<WidgetToWindowMap::iterator, bool> result =
window_map_.add(widget, window.Pass());
DCHECK(result.second) << "Window already added.";
+ UpdateControllerToWindowMapping();
}
scoped_ptr<DrmWindow> ScreenManager::RemoveWindow(
gfx::AcceleratedWidget widget) {
scoped_ptr<DrmWindow> window = window_map_.take_and_erase(widget);
DCHECK(window) << "Attempting to remove non-existing window for " << widget;
+ UpdateControllerToWindowMapping();
return window.Pass();
}
@@ -212,14 +225,6 @@ DrmWindow* ScreenManager::GetWindow(gfx::AcceleratedWidget widget) {
return nullptr;
}
-void ScreenManager::AddObserver(DisplayChangeObserver* observer) {
- observers_.AddObserver(observer);
-}
-
-void ScreenManager::RemoveObserver(DisplayChangeObserver* observer) {
- observers_.RemoveObserver(observer);
-}
-
ScreenManager::HardwareDisplayControllers::iterator
ScreenManager::FindDisplayController(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc) {
@@ -268,8 +273,6 @@ bool ScreenManager::ModesetDisplayController(
return false;
}
- FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
- OnDisplayChanged(controller));
return true;
}
@@ -281,10 +284,6 @@ bool ScreenManager::HandleMirrorMode(
uint32_t connector) {
(*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc));
if ((*mirror)->Enable()) {
- FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
- OnDisplayRemoved(*original));
- FOR_EACH_OBSERVER(DisplayChangeObserver, observers_,
- OnDisplayChanged(*mirror));
controllers_.erase(original);
return true;
}
@@ -299,4 +298,39 @@ bool ScreenManager::HandleMirrorMode(
return false;
}
+void ScreenManager::UpdateControllerToWindowMapping() {
+ std::map<DrmWindow*, HardwareDisplayController*> window_to_controller_map;
+ // First create a unique mapping between a window and a controller. Note, a
+ // controller may be associated with at most 1 window.
+ for (HardwareDisplayController* controller : controllers_) {
+ if (controller->IsDisabled())
+ continue;
+
+ DrmWindow* window = FindWindowAt(
+ gfx::Rect(controller->origin(), controller->GetModeSize()));
+ if (!window)
+ continue;
+
+ window_to_controller_map[window] = controller;
+ }
+
+ // Apply the new mapping to all windows.
+ for (auto pair : window_map_) {
+ auto it = window_to_controller_map.find(pair.second);
+ if (it != window_to_controller_map.end())
+ pair.second->SetController(it->second);
+ else
+ pair.second->SetController(nullptr);
+ }
+}
+
+DrmWindow* ScreenManager::FindWindowAt(const gfx::Rect& bounds) const {
+ for (auto pair : window_map_) {
+ if (pair.second->bounds() == bounds)
+ return pair.second;
+ }
+
+ return nullptr;
+}
+
} // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.h b/ui/ozone/platform/drm/gpu/screen_manager.h
index 75f9fdd..2732769 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager.h
+++ b/ui/ozone/platform/drm/gpu/screen_manager.h
@@ -11,7 +11,6 @@
#include "base/observer_list.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/ozone_export.h"
-#include "ui/ozone/platform/drm/gpu/display_change_observer.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
typedef struct _drmModeModeInfo drmModeModeInfo;
@@ -75,8 +74,9 @@ class OZONE_EXPORT ScreenManager {
// called only if a valid window has been associated with |widget|.
DrmWindow* GetWindow(gfx::AcceleratedWidget widget);
- void AddObserver(DisplayChangeObserver* observer);
- void RemoveObserver(DisplayChangeObserver* observer);
+ // Updates the mapping between display controllers and windows such that a
+ // controller will be associated with at most one window.
+ void UpdateControllerToWindowMapping();
private:
typedef ScopedVector<HardwareDisplayController> HardwareDisplayControllers;
@@ -90,6 +90,12 @@ class OZONE_EXPORT ScreenManager {
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc);
+ bool ActualConfigureDisplayController(const scoped_refptr<DrmDevice>& drm,
+ uint32_t crtc,
+ uint32_t connector,
+ const gfx::Point& origin,
+ const drmModeModeInfo& mode);
+
// Returns an iterator into |controllers_| for the controller located at
// |origin|.
HardwareDisplayControllers::iterator FindActiveDisplayControllerByLocation(
@@ -109,14 +115,14 @@ class OZONE_EXPORT ScreenManager {
uint32_t crtc,
uint32_t connector);
+ DrmWindow* FindWindowAt(const gfx::Rect& bounds) const;
+
ScanoutBufferGenerator* buffer_generator_; // Not owned.
// List of display controllers (active and disabled).
HardwareDisplayControllers controllers_;
WidgetToWindowMap window_map_;
- ObserverList<DisplayChangeObserver> observers_;
-
DISALLOW_COPY_AND_ASSIGN(ScreenManager);
};
diff --git a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
index 2b47cf9..83963f1 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -5,6 +5,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_buffer.h"
+#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
+#include "ui/ozone/platform/drm/gpu/drm_window.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
#include "ui/ozone/platform/drm/test/mock_drm_device.h"
@@ -20,32 +22,6 @@ const uint32_t kPrimaryConnector = 2;
const uint32_t kSecondaryCrtc = 3;
const uint32_t kSecondaryConnector = 4;
-class TestDisplayChangeObserver : public ui::DisplayChangeObserver {
- public:
- TestDisplayChangeObserver()
- : num_displays_changed_(0), num_displays_removed_(0) {}
-
- ~TestDisplayChangeObserver() override {}
-
- int num_displays_changed() const { return num_displays_changed_; }
- int num_displays_removed() const { return num_displays_removed_; }
-
- // TestDisplayChangeObserver:
- void OnDisplayChanged(ui::HardwareDisplayController* controller) override {
- num_displays_changed_++;
- }
-
- void OnDisplayRemoved(ui::HardwareDisplayController* controller) override {
- num_displays_removed_++;
- }
-
- private:
- int num_displays_changed_;
- int num_displays_removed_;
-
- DISALLOW_COPY_AND_ASSIGN(TestDisplayChangeObserver);
-};
-
} // namespace
class ScreenManagerTest : public testing::Test {
@@ -67,10 +43,8 @@ class ScreenManagerTest : public testing::Test {
drm_ = new ui::MockDrmDevice();
buffer_generator_.reset(new ui::DrmBufferGenerator());
screen_manager_.reset(new ui::ScreenManager(buffer_generator_.get()));
- screen_manager_->AddObserver(&observer_);
}
void TearDown() override {
- screen_manager_->RemoveObserver(&observer_);
screen_manager_.reset();
drm_ = nullptr;
}
@@ -80,8 +54,6 @@ class ScreenManagerTest : public testing::Test {
scoped_ptr<ui::DrmBufferGenerator> buffer_generator_;
scoped_ptr<ui::ScreenManager> screen_manager_;
- TestDisplayChangeObserver observer_;
-
private:
DISALLOW_COPY_AND_ASSIGN(ScreenManagerTest);
};
@@ -132,13 +104,9 @@ TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) {
screen_manager_->ConfigureDisplayController(
drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
kDefaultMode);
- EXPECT_EQ(1, observer_.num_displays_changed());
- EXPECT_EQ(0, observer_.num_displays_removed());
EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
screen_manager_->RemoveDisplayController(drm_, kPrimaryCrtc);
- EXPECT_EQ(1, observer_.num_displays_changed());
- EXPECT_EQ(1, observer_.num_displays_removed());
EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
}
@@ -156,9 +124,6 @@ TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) {
// Should reuse existing framebuffer.
EXPECT_EQ(framebuffer, drm_->current_framebuffer());
- EXPECT_EQ(2, observer_.num_displays_changed());
- EXPECT_EQ(0, observer_.num_displays_removed());
-
EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
}
@@ -174,9 +139,6 @@ TEST_F(ScreenManagerTest, CheckChangingMode) {
drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
new_mode);
- EXPECT_EQ(2, observer_.num_displays_changed());
- EXPECT_EQ(0, observer_.num_displays_removed());
-
gfx::Rect new_bounds(0, 0, new_mode.hdisplay, new_mode.vdisplay);
EXPECT_TRUE(screen_manager_->GetDisplayController(new_bounds));
EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
@@ -197,8 +159,6 @@ TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) {
drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
kDefaultMode);
- EXPECT_EQ(2, observer_.num_displays_changed());
- EXPECT_EQ(1, observer_.num_displays_removed());
EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
}
@@ -247,15 +207,10 @@ TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) {
drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
kDefaultMode);
- EXPECT_EQ(2, observer_.num_displays_changed());
- EXPECT_EQ(1, observer_.num_displays_removed());
-
screen_manager_->RemoveDisplayController(drm_, kSecondaryCrtc);
EXPECT_TRUE(screen_manager_->ConfigureDisplayController(
drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
kDefaultMode));
- EXPECT_EQ(3, observer_.num_displays_changed());
- EXPECT_EQ(1, observer_.num_displays_removed());
EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
@@ -351,3 +306,71 @@ TEST_F(ScreenManagerTest,
EXPECT_EQ(drm_, controller1->crtc_controllers()[0]->drm());
EXPECT_EQ(drm2, controller2->crtc_controllers()[0]->drm());
}
+
+TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithSameBounds) {
+ ui::DrmDeviceManager device_manager(drm_);
+ scoped_ptr<ui::DrmWindow> window(
+ new ui::DrmWindow(1, &device_manager, screen_manager_.get()));
+ window->Initialize();
+ window->OnBoundsChanged(GetPrimaryBounds());
+ screen_manager_->AddWindow(1, window.Pass());
+
+ screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
+ screen_manager_->ConfigureDisplayController(
+ drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
+ kDefaultMode);
+
+ EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController());
+
+ window = screen_manager_->RemoveWindow(1);
+ window->Shutdown();
+}
+
+TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithDifferentBounds) {
+ ui::DrmDeviceManager device_manager(drm_);
+ scoped_ptr<ui::DrmWindow> window(
+ new ui::DrmWindow(1, &device_manager, screen_manager_.get()));
+ window->Initialize();
+ gfx::Rect new_bounds = GetPrimaryBounds();
+ new_bounds.Inset(0, 0, 1, 1);
+ window->OnBoundsChanged(new_bounds);
+ screen_manager_->AddWindow(1, window.Pass());
+
+ screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
+ screen_manager_->ConfigureDisplayController(
+ drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
+ kDefaultMode);
+
+ EXPECT_FALSE(screen_manager_->GetWindow(1)->GetController());
+
+ window = screen_manager_->RemoveWindow(1);
+ window->Shutdown();
+}
+
+TEST_F(ScreenManagerTest,
+ CheckControllerToWindowMappingWithOverlappingWindows) {
+ ui::DrmDeviceManager device_manager(drm_);
+ const size_t kWindowCount = 2;
+ for (size_t i = 1; i < kWindowCount + 1; ++i) {
+ scoped_ptr<ui::DrmWindow> window(
+ new ui::DrmWindow(1, &device_manager, screen_manager_.get()));
+ window->Initialize();
+ window->OnBoundsChanged(GetPrimaryBounds());
+ screen_manager_->AddWindow(i, window.Pass());
+ }
+
+ screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
+ screen_manager_->ConfigureDisplayController(
+ drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
+ kDefaultMode);
+
+ bool window1_has_controller = screen_manager_->GetWindow(1)->GetController();
+ bool window2_has_controller = screen_manager_->GetWindow(2)->GetController();
+ // Only one of the windows can have a controller.
+ EXPECT_TRUE(window1_has_controller ^ window2_has_controller);
+
+ for (size_t i = 1; i < kWindowCount + 1; ++i) {
+ scoped_ptr<ui::DrmWindow> window = screen_manager_->RemoveWindow(i);
+ window->Shutdown();
+ }
+}
diff --git a/ui/ozone/platform/drm/host/drm_cursor.cc b/ui/ozone/platform/drm/host/drm_cursor.cc
index f58b8c6..ecbbe52 100644
--- a/ui/ozone/platform/drm/host/drm_cursor.cc
+++ b/ui/ozone/platform/drm/host/drm_cursor.cc
@@ -85,20 +85,6 @@ void DrmCursor::OnWindowRemoved(gfx::AcceleratedWidget window) {
}
}
-void DrmCursor::PrepareForBoundsChange(gfx::AcceleratedWidget window) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- base::AutoLock lock(state_.lock);
-
- // Bounds changes can reparent the window to a different display, so
- // we hide prior to the change so that we avoid leaving a cursor
- // behind on the old display.
- // TODO(spang): The GPU-side code should handle this.
- if (state_.window == window)
- SendCursorHideLocked();
-
- // The cursor will be shown and moved in CommitBoundsChange().
-}
-
void DrmCursor::CommitBoundsChange(
gfx::AcceleratedWidget window,
const gfx::Rect& new_display_bounds_in_screen,
@@ -113,17 +99,6 @@ void DrmCursor::CommitBoundsChange(
}
}
-void DrmCursor::ConfineCursorToBounds(gfx::AcceleratedWidget window,
- const gfx::Rect& bounds) {
- DCHECK(ui_task_runner_->BelongsToCurrentThread());
- base::AutoLock lock(state_.lock);
- if (state_.window == window) {
- state_.confined_bounds = bounds;
- SetCursorLocationLocked(state_.location);
- SendCursorShowLocked();
- }
-}
-
void DrmCursor::MoveCursorTo(gfx::AcceleratedWidget window,
const gfx::PointF& location) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
diff --git a/ui/ozone/platform/drm/host/drm_cursor.h b/ui/ozone/platform/drm/host/drm_cursor.h
index f84a6e4..2fba144 100644
--- a/ui/ozone/platform/drm/host/drm_cursor.h
+++ b/ui/ozone/platform/drm/host/drm_cursor.h
@@ -44,15 +44,10 @@ class DrmCursor : public CursorDelegateEvdev {
void OnWindowRemoved(gfx::AcceleratedWidget window);
// Handle window bounds changes.
- void PrepareForBoundsChange(gfx::AcceleratedWidget window);
void CommitBoundsChange(gfx::AcceleratedWidget window,
const gfx::Rect& new_display_bounds_in_screen,
const gfx::Rect& new_confined_bounds);
- // Confines the cursor to |confined_bounds| for |window|.
- void ConfineCursorToBounds(gfx::AcceleratedWidget window,
- const gfx::Rect& bounds);
-
// CursorDelegateEvdev:
void MoveCursorTo(gfx::AcceleratedWidget window,
const gfx::PointF& location) override;
diff --git a/ui/ozone/platform/drm/host/drm_window_host.cc b/ui/ozone/platform/drm/host/drm_window_host.cc
index 0b0f0f3..4bf3385 100644
--- a/ui/ozone/platform/drm/host/drm_window_host.cc
+++ b/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -115,7 +115,7 @@ void DrmWindowHost::ConfineCursorToBounds(const gfx::Rect& bounds) {
return;
cursor_confined_bounds_ = bounds;
- cursor_->ConfineCursorToBounds(widget_, bounds);
+ cursor_->CommitBoundsChange(widget_, bounds_, bounds);
}
bool DrmWindowHost::CanDispatchEvent(const PlatformEvent& ne) {
@@ -176,16 +176,16 @@ uint32_t DrmWindowHost::DispatchEvent(const PlatformEvent& native_event) {
void DrmWindowHost::OnChannelEstablished() {
sender_->Send(new OzoneGpuMsg_CreateWindowDelegate(widget_));
SendBoundsChange();
- cursor_->ConfineCursorToBounds(widget_, GetCursorConfinedBounds());
}
void DrmWindowHost::OnChannelDestroyed() {
}
void DrmWindowHost::SendBoundsChange() {
- cursor_->PrepareForBoundsChange(widget_);
- sender_->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_, bounds_));
+ // Update the cursor before the window so that the cursor stays within the
+ // window bounds when the window size shrinks.
cursor_->CommitBoundsChange(widget_, bounds_, GetCursorConfinedBounds());
+ sender_->Send(new OzoneGpuMsg_WindowBoundsChanged(widget_, bounds_));
}
} // namespace ui
diff --git a/ui/ozone/platform/drm/test/mock_drm_device.cc b/ui/ozone/platform/drm/test/mock_drm_device.cc
index 984089f..6af2c04 100644
--- a/ui/ozone/platform/drm/test/mock_drm_device.cc
+++ b/ui/ozone/platform/drm/test/mock_drm_device.cc
@@ -49,6 +49,8 @@ MockDrmDevice::MockDrmDevice()
remove_framebuffer_call_count_(0),
page_flip_call_count_(0),
overlay_flip_call_count_(0),
+ overlay_clear_call_count_(0),
+ allocate_buffer_count_(0),
set_crtc_expectation_(true),
add_framebuffer_expectation_(true),
page_flip_expectation_(true),
@@ -69,6 +71,7 @@ MockDrmDevice::MockDrmDevice(bool use_sync_flips,
page_flip_call_count_(0),
overlay_flip_call_count_(0),
overlay_clear_call_count_(0),
+ allocate_buffer_count_(0),
set_crtc_expectation_(true),
add_framebuffer_expectation_(true),
page_flip_expectation_(true),
@@ -183,6 +186,7 @@ ScopedDrmPropertyBlobPtr MockDrmDevice::GetPropertyBlob(
bool MockDrmDevice::SetCursor(uint32_t crtc_id,
uint32_t handle,
const gfx::Size& size) {
+ crtc_cursor_map_[crtc_id] = handle;
return true;
}
@@ -194,10 +198,11 @@ bool MockDrmDevice::CreateDumbBuffer(const SkImageInfo& info,
uint32_t* handle,
uint32_t* stride,
void** pixels) {
+ allocate_buffer_count_++;
if (!create_dumb_buffer_expectation_)
return false;
- *handle = 0;
+ *handle = allocate_buffer_count_;
*stride = info.minRowBytes();
*pixels = new char[info.getSafeSize(*stride)];
buffers_.push_back(
diff --git a/ui/ozone/platform/drm/test/mock_drm_device.h b/ui/ozone/platform/drm/test/mock_drm_device.h
index e4354d2..7745a05 100644
--- a/ui/ozone/platform/drm/test/mock_drm_device.h
+++ b/ui/ozone/platform/drm/test/mock_drm_device.h
@@ -5,6 +5,7 @@
#ifndef UI_OZONE_PLATFORM_DRM_TEST_MOCK_DRM_DEVICE_H_
#define UI_OZONE_PLATFORM_DRM_TEST_MOCK_DRM_DEVICE_H_
+#include <map>
#include <queue>
#include <vector>
@@ -51,6 +52,11 @@ class MockDrmDevice : public ui::DrmDevice {
return buffers_;
}
+ uint32_t get_cursor_handle_for_crtc(uint32_t crtc) const {
+ const auto it = crtc_cursor_map_.find(crtc);
+ return it != crtc_cursor_map_.end() ? it->second : 0;
+ }
+
void RunCallbacks();
// DrmDevice:
@@ -115,6 +121,7 @@ class MockDrmDevice : public ui::DrmDevice {
int page_flip_call_count_;
int overlay_flip_call_count_;
int overlay_clear_call_count_;
+ int allocate_buffer_count_;
bool set_crtc_expectation_;
bool add_framebuffer_expectation_;
@@ -127,6 +134,8 @@ class MockDrmDevice : public ui::DrmDevice {
std::vector<skia::RefPtr<SkSurface>> buffers_;
+ std::map<uint32_t, uint32_t> crtc_cursor_map_;
+
std::queue<PageFlipCallback> callbacks_;
DISALLOW_COPY_AND_ASSIGN(MockDrmDevice);