Commit f95b436f authored by dnicoara's avatar dnicoara Committed by Commit bot

[Ozone-Dri] Allocate cursor buffers on the correct DRM device

Need to keep track of changing displays and update the cursor buffers
when the window moves between DRM devices.

BUG=461105

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

Cr-Commit-Position: refs/heads/master@{#318252}
parent 0fe67ebb
......@@ -63,26 +63,6 @@ void DriWindowDelegateImpl::Initialize() {
device_manager_->UpdateDrmDevice(widget_, nullptr);
screen_manager_->AddObserver(this);
scoped_refptr<DriWrapper> drm =
device_manager_->GetDrmDevice(gfx::kNullAcceleratedWidget);
uint64_t cursor_width = 64;
uint64_t cursor_height = 64;
drm->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width);
drm->GetCapability(DRM_CAP_CURSOR_HEIGHT, &cursor_height);
SkImageInfo info = SkImageInfo::MakeN32Premul(cursor_width, cursor_height);
for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
cursor_buffers_[i] = new DriBuffer(drm);
// Don't register a framebuffer for cursors since they are special (they
// aren't modesetting buffers and drivers may fail to register them due to
// their small sizes).
if (!cursor_buffers_[i]->Initialize(
info, false /* should_register_framebuffer */)) {
LOG(ERROR) << "Failed to initialize cursor buffer";
return;
}
}
}
void DriWindowDelegateImpl::Shutdown() {
......@@ -105,6 +85,7 @@ void DriWindowDelegateImpl::OnBoundsChanged(const gfx::Rect& bounds) {
bounds_ = bounds;
controller_ = screen_manager_->GetDisplayController(bounds);
UpdateWidgetToDrmDeviceMapping();
UpdateCursorBuffers();
}
void DriWindowDelegateImpl::SetCursor(const std::vector<SkBitmap>& bitmaps,
......@@ -145,6 +126,9 @@ void DriWindowDelegateImpl::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_) {
......@@ -159,6 +143,8 @@ void DriWindowDelegateImpl::OnDisplayChanged(
}
UpdateWidgetToDrmDeviceMapping();
if (should_allocate_cursor_buffers)
UpdateCursorBuffers();
}
void DriWindowDelegateImpl::OnDisplayRemoved(
......@@ -168,22 +154,22 @@ void DriWindowDelegateImpl::OnDisplayRemoved(
}
void DriWindowDelegateImpl::ResetCursor(bool bitmap_only) {
if (!controller_)
return;
if (cursor_bitmaps_.size()) {
// Draw new cursor into backbuffer.
UpdateCursorImage(cursor_buffers_[cursor_frontbuffer_ ^ 1].get(),
cursor_bitmaps_[cursor_frame_]);
// Reset location & buffer.
if (controller_) {
if (!bitmap_only)
controller_->MoveCursor(cursor_location_);
controller_->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]);
cursor_frontbuffer_ ^= 1;
}
if (!bitmap_only)
controller_->MoveCursor(cursor_location_);
controller_->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]);
cursor_frontbuffer_ ^= 1;
} else {
// No cursor set.
if (controller_)
controller_->UnsetCursor();
controller_->UnsetCursor();
}
}
......@@ -202,4 +188,32 @@ void DriWindowDelegateImpl::UpdateWidgetToDrmDeviceMapping() {
device_manager_->UpdateDrmDevice(widget_, drm);
}
void DriWindowDelegateImpl::UpdateCursorBuffers() {
if (!controller_) {
for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
cursor_buffers_[i] = nullptr;
}
} else {
scoped_refptr<DriWrapper> drm = controller_->GetAllocationDriWrapper();
uint64_t cursor_width = 64;
uint64_t cursor_height = 64;
drm->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width);
drm->GetCapability(DRM_CAP_CURSOR_HEIGHT, &cursor_height);
SkImageInfo info = SkImageInfo::MakeN32Premul(cursor_width, cursor_height);
for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
cursor_buffers_[i] = new DriBuffer(drm);
// Don't register a framebuffer for cursors since they are special (they
// aren't modesetting buffers and drivers may fail to register them due to
// their small sizes).
if (!cursor_buffers_[i]->Initialize(
info, false /* should_register_framebuffer */)) {
LOG(FATAL) << "Failed to initialize cursor buffer";
return;
}
}
}
}
} // namespace ui
......@@ -54,6 +54,10 @@ class OZONE_EXPORT DriWindowDelegateImpl : public DriWindowDelegate,
void UpdateWidgetToDrmDeviceMapping();
// When |controller_| changes this is called to reallocate the cursor buffers
// since the allocation DRM device may have changed.
void UpdateCursorBuffers();
gfx::AcceleratedWidget widget_;
DrmDeviceManager* device_manager_; // Not owned.
......
......@@ -32,6 +32,19 @@ const uint32_t kDefaultCrtc = 1;
const uint32_t kDefaultConnector = 2;
const int kDefaultCursorSize = 64;
std::vector<skia::RefPtr<SkSurface>> GetCursorBuffers(
const scoped_refptr<ui::MockDriWrapper> drm) {
std::vector<skia::RefPtr<SkSurface>> cursor_buffers;
for (const skia::RefPtr<SkSurface>& cursor_buffer : drm->buffers()) {
if (cursor_buffer->width() == kDefaultCursorSize &&
cursor_buffer->height() == kDefaultCursorSize) {
cursor_buffers.push_back(cursor_buffer);
}
}
return cursor_buffers;
}
} // namespace
class DriWindowDelegateImplTest : public testing::Test {
......@@ -70,6 +83,8 @@ void DriWindowDelegateImplTest::SetUp() {
drm_device_manager_.get(),
screen_manager_.get()));
window_delegate->Initialize();
window_delegate->OnBoundsChanged(
gfx::Rect(gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay)));
window_delegate_manager_->AddWindowDelegate(kDefaultWidgetHandle,
window_delegate.Pass());
}
......@@ -94,14 +109,7 @@ TEST_F(DriWindowDelegateImplTest, SetCursorImage) {
->SetCursor(cursor_bitmaps, gfx::Point(4, 2), 0);
SkBitmap cursor;
std::vector<skia::RefPtr<SkSurface>> cursor_buffers;
for (const skia::RefPtr<SkSurface>& cursor_buffer : dri_->buffers()) {
if (cursor_buffer->width() == kDefaultCursorSize &&
cursor_buffer->height() == kDefaultCursorSize) {
cursor_buffers.push_back(cursor_buffer);
}
}
std::vector<skia::RefPtr<SkSurface>> cursor_buffers = GetCursorBuffers(dri_);
EXPECT_EQ(2u, cursor_buffers.size());
// Buffers 1 is the cursor backbuffer we just drew in.
......@@ -119,3 +127,20 @@ TEST_F(DriWindowDelegateImplTest, SetCursorImage) {
}
}
}
TEST_F(DriWindowDelegateImplTest, CheckCursorSurfaceAfterChangingDevice) {
// Add another device.
scoped_refptr<ui::MockDriWrapper> drm = new ui::MockDriWrapper();
screen_manager_->AddDisplayController(drm, kDefaultCrtc, kDefaultConnector);
screen_manager_->ConfigureDisplayController(
drm, kDefaultCrtc, kDefaultConnector,
gfx::Point(0, kDefaultMode.vdisplay), kDefaultMode);
// Move window to the display on the new device.
window_delegate_manager_->GetWindowDelegate(kDefaultWidgetHandle)
->OnBoundsChanged(gfx::Rect(0, kDefaultMode.vdisplay,
kDefaultMode.hdisplay,
kDefaultMode.vdisplay));
EXPECT_EQ(2u, GetCursorBuffers(drm).size());
}
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