1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/dri/dri_gpu_platform_support.h"
7 #include "ipc/ipc_message_macros.h"
8 #include "ui/display/types/display_mode.h"
9 #include "ui/display/types/display_snapshot.h"
10 #include "ui/ozone/common/display_util.h"
11 #include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
12 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
13 #include "ui/ozone/platform/dri/dri_surface_factory.h"
14 #include "ui/ozone/platform/dri/dri_window_delegate_impl.h"
15 #include "ui/ozone/platform/dri/dri_window_delegate_manager.h"
16 #include "ui/ozone/platform/dri/native_display_delegate_dri.h"
22 class FindDisplayById {
24 FindDisplayById(int64_t display_id) : display_id_(display_id) {}
26 bool operator()(const DisplaySnapshot_Params& display) const {
27 return display.display_id == display_id_;
36 DriGpuPlatformSupport::DriGpuPlatformSupport(
37 DriSurfaceFactory* dri,
38 DriWindowDelegateManager* window_manager,
39 ScreenManager* screen_manager,
40 scoped_ptr<NativeDisplayDelegateDri> ndd)
43 window_manager_(window_manager),
44 screen_manager_(screen_manager),
48 DriGpuPlatformSupport::~DriGpuPlatformSupport() {
51 void DriGpuPlatformSupport::AddHandler(scoped_ptr<GpuPlatformSupport> handler) {
52 handlers_.push_back(handler.release());
55 void DriGpuPlatformSupport::OnChannelEstablished(IPC::Sender* sender) {
58 for (size_t i = 0; i < handlers_.size(); ++i)
59 handlers_[i]->OnChannelEstablished(sender);
62 bool DriGpuPlatformSupport::OnMessageReceived(const IPC::Message& message) {
65 IPC_BEGIN_MESSAGE_MAP(DriGpuPlatformSupport, message)
66 IPC_MESSAGE_HANDLER(OzoneGpuMsg_CreateWindowDelegate, OnCreateWindowDelegate)
67 IPC_MESSAGE_HANDLER(OzoneGpuMsg_DestroyWindowDelegate,
68 OnDestroyWindowDelegate)
69 IPC_MESSAGE_HANDLER(OzoneGpuMsg_WindowBoundsChanged, OnWindowBoundsChanged)
71 IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorSet, OnCursorSet)
72 IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorMove, OnCursorMove)
74 IPC_MESSAGE_HANDLER(OzoneGpuMsg_ForceDPMSOn, OnForceDPMSOn)
75 IPC_MESSAGE_HANDLER(OzoneGpuMsg_RefreshNativeDisplays,
76 OnRefreshNativeDisplays)
77 IPC_MESSAGE_HANDLER(OzoneGpuMsg_ConfigureNativeDisplay,
78 OnConfigureNativeDisplay)
79 IPC_MESSAGE_HANDLER(OzoneGpuMsg_DisableNativeDisplay, OnDisableNativeDisplay)
80 IPC_MESSAGE_HANDLER(OzoneGpuMsg_TakeDisplayControl, OnTakeDisplayControl)
81 IPC_MESSAGE_HANDLER(OzoneGpuMsg_RelinquishDisplayControl,
82 OnRelinquishDisplayControl)
83 IPC_MESSAGE_UNHANDLED(handled = false);
87 for (size_t i = 0; i < handlers_.size(); ++i)
88 if (handlers_[i]->OnMessageReceived(message))
94 void DriGpuPlatformSupport::OnCreateWindowDelegate(
95 gfx::AcceleratedWidget widget) {
96 // Due to how the GPU process starts up this IPC call may happen after the IPC
97 // to create a surface. Since a surface wants to know the window associated
98 // with it, we create it ahead of time. So when this call happens we do not
99 // create a delegate if it already exists.
100 if (!window_manager_->HasWindowDelegate(widget)) {
101 scoped_ptr<DriWindowDelegate> delegate(
102 new DriWindowDelegateImpl(widget, screen_manager_));
103 delegate->Initialize();
104 window_manager_->AddWindowDelegate(widget, delegate.Pass());
108 void DriGpuPlatformSupport::OnDestroyWindowDelegate(
109 gfx::AcceleratedWidget widget) {
110 scoped_ptr<DriWindowDelegate> delegate =
111 window_manager_->RemoveWindowDelegate(widget);
112 delegate->Shutdown();
115 void DriGpuPlatformSupport::OnWindowBoundsChanged(gfx::AcceleratedWidget widget,
116 const gfx::Rect& bounds) {
117 window_manager_->GetWindowDelegate(widget)->OnBoundsChanged(bounds);
120 void DriGpuPlatformSupport::OnCursorSet(gfx::AcceleratedWidget widget,
121 const std::vector<SkBitmap>& bitmaps,
122 const gfx::Point& location,
123 int frame_delay_ms) {
124 dri_->SetHardwareCursor(widget, bitmaps, location, frame_delay_ms);
127 void DriGpuPlatformSupport::OnCursorMove(gfx::AcceleratedWidget widget,
128 const gfx::Point& location) {
129 dri_->MoveHardwareCursor(widget, location);
132 void DriGpuPlatformSupport::OnForceDPMSOn() {
136 void DriGpuPlatformSupport::OnRefreshNativeDisplays(
137 const std::vector<DisplaySnapshot_Params>& cached_displays) {
138 std::vector<DisplaySnapshot_Params> displays;
139 std::vector<DisplaySnapshot*> native_displays = ndd_->GetDisplays();
141 // If any of the cached displays are in the list of new displays then apply
142 // their configuration immediately.
143 for (size_t i = 0; i < native_displays.size(); ++i) {
144 std::vector<DisplaySnapshot_Params>::const_iterator it =
145 std::find_if(cached_displays.begin(), cached_displays.end(),
146 FindDisplayById(native_displays[i]->display_id()));
148 if (it == cached_displays.end())
151 if (it->has_current_mode)
152 OnConfigureNativeDisplay(it->display_id, it->current_mode, it->origin);
154 OnDisableNativeDisplay(it->display_id);
157 for (size_t i = 0; i < native_displays.size(); ++i)
158 displays.push_back(GetDisplaySnapshotParams(*native_displays[i]));
160 sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(displays));
163 void DriGpuPlatformSupport::OnConfigureNativeDisplay(
165 const DisplayMode_Params& mode_param,
166 const gfx::Point& origin) {
167 DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id);
169 LOG(ERROR) << "There is no display with ID " << id;
173 const DisplayMode* mode = NULL;
174 for (size_t i = 0; i < display->modes().size(); ++i) {
175 if (mode_param.size == display->modes()[i]->size() &&
176 mode_param.is_interlaced == display->modes()[i]->is_interlaced() &&
177 mode_param.refresh_rate == display->modes()[i]->refresh_rate()) {
178 mode = display->modes()[i];
183 // If the display doesn't have the mode natively, then lookup the mode from
184 // other displays and try using it on the current display (some displays
185 // support panel fitting and they can use different modes even if the mode
186 // isn't explicitly declared).
188 mode = ndd_->FindDisplayMode(mode_param.size, mode_param.is_interlaced,
189 mode_param.refresh_rate);
192 LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString()
193 << " is_interlaced=" << mode_param.is_interlaced
194 << " refresh_rate=" << mode_param.refresh_rate;
198 ndd_->Configure(*display, mode, origin);
201 void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) {
202 DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id);
204 ndd_->Configure(*display, NULL, gfx::Point());
206 LOG(ERROR) << "There is no display with ID " << id;
209 void DriGpuPlatformSupport::OnTakeDisplayControl() {
210 ndd_->TakeDisplayControl();
213 void DriGpuPlatformSupport::OnRelinquishDisplayControl() {
214 ndd_->RelinquishDisplayControl();