Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / ui / ozone / platform / dri / dri_gpu_platform_support.cc
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.
4
5 #include "ui/ozone/platform/dri/dri_gpu_platform_support.h"
6
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"
17
18 namespace ui {
19
20 namespace {
21
22 class FindDisplayById {
23  public:
24   FindDisplayById(int64_t display_id) : display_id_(display_id) {}
25
26   bool operator()(const DisplaySnapshot_Params& display) const {
27     return display.display_id == display_id_;
28   }
29
30  private:
31   int64_t display_id_;
32 };
33
34 }  // namespace
35
36 DriGpuPlatformSupport::DriGpuPlatformSupport(
37     DriSurfaceFactory* dri,
38     DriWindowDelegateManager* window_manager,
39     ScreenManager* screen_manager,
40     scoped_ptr<NativeDisplayDelegateDri> ndd)
41     : sender_(NULL),
42       dri_(dri),
43       window_manager_(window_manager),
44       screen_manager_(screen_manager),
45       ndd_(ndd.Pass()) {
46 }
47
48 DriGpuPlatformSupport::~DriGpuPlatformSupport() {
49 }
50
51 void DriGpuPlatformSupport::AddHandler(scoped_ptr<GpuPlatformSupport> handler) {
52   handlers_.push_back(handler.release());
53 }
54
55 void DriGpuPlatformSupport::OnChannelEstablished(IPC::Sender* sender) {
56   sender_ = sender;
57
58   for (size_t i = 0; i < handlers_.size(); ++i)
59     handlers_[i]->OnChannelEstablished(sender);
60 }
61
62 bool DriGpuPlatformSupport::OnMessageReceived(const IPC::Message& message) {
63   bool handled = true;
64
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)
70
71   IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorSet, OnCursorSet)
72   IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorMove, OnCursorMove)
73
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);
84   IPC_END_MESSAGE_MAP()
85
86   if (!handled)
87     for (size_t i = 0; i < handlers_.size(); ++i)
88       if (handlers_[i]->OnMessageReceived(message))
89         return true;
90
91   return false;
92 }
93
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());
105   }
106 }
107
108 void DriGpuPlatformSupport::OnDestroyWindowDelegate(
109     gfx::AcceleratedWidget widget) {
110   scoped_ptr<DriWindowDelegate> delegate =
111       window_manager_->RemoveWindowDelegate(widget);
112   delegate->Shutdown();
113 }
114
115 void DriGpuPlatformSupport::OnWindowBoundsChanged(gfx::AcceleratedWidget widget,
116                                                   const gfx::Rect& bounds) {
117   window_manager_->GetWindowDelegate(widget)->OnBoundsChanged(bounds);
118 }
119
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);
125 }
126
127 void DriGpuPlatformSupport::OnCursorMove(gfx::AcceleratedWidget widget,
128                                          const gfx::Point& location) {
129   dri_->MoveHardwareCursor(widget, location);
130 }
131
132 void DriGpuPlatformSupport::OnForceDPMSOn() {
133   ndd_->ForceDPMSOn();
134 }
135
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();
140
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()));
147
148     if (it == cached_displays.end())
149       continue;
150
151     if (it->has_current_mode)
152       OnConfigureNativeDisplay(it->display_id, it->current_mode, it->origin);
153     else
154       OnDisableNativeDisplay(it->display_id);
155   }
156
157   for (size_t i = 0; i < native_displays.size(); ++i)
158     displays.push_back(GetDisplaySnapshotParams(*native_displays[i]));
159
160   sender_->Send(new OzoneHostMsg_UpdateNativeDisplays(displays));
161 }
162
163 void DriGpuPlatformSupport::OnConfigureNativeDisplay(
164     int64_t id,
165     const DisplayMode_Params& mode_param,
166     const gfx::Point& origin) {
167   DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id);
168   if (!display) {
169     LOG(ERROR) << "There is no display with ID " << id;
170     return;
171   }
172
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];
179       break;
180     }
181   }
182
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).
187   if (!mode)
188     mode = ndd_->FindDisplayMode(mode_param.size, mode_param.is_interlaced,
189                                  mode_param.refresh_rate);
190
191   if (!mode) {
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;
195     return;
196   }
197
198   ndd_->Configure(*display, mode, origin);
199 }
200
201 void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) {
202   DisplaySnapshot* display = ndd_->FindDisplaySnapshot(id);
203   if (display)
204     ndd_->Configure(*display, NULL, gfx::Point());
205   else
206     LOG(ERROR) << "There is no display with ID " << id;
207 }
208
209 void DriGpuPlatformSupport::OnTakeDisplayControl() {
210   ndd_->TakeDisplayControl();
211 }
212
213 void DriGpuPlatformSupport::OnRelinquishDisplayControl() {
214   ndd_->RelinquishDisplayControl();
215 }
216
217 }  // namespace ui