OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/ozone/dri/dri_surface_factory.h" | 5 #include "ui/gfx/ozone/dri/dri_surface_factory.h" |
6 | 6 |
7 #include <drm.h> | 7 #include <drm.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <xf86drm.h> | 9 #include <xf86drm.h> |
10 | 10 |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
13 #include "third_party/skia/include/core/SkDevice.h" | 13 #include "third_party/skia/include/core/SkDevice.h" |
14 #include "ui/gfx/native_widget_types.h" | 14 #include "ui/gfx/native_widget_types.h" |
15 #include "ui/gfx/ozone/dri/dri_skbitmap.h" | 15 #include "ui/gfx/ozone/dri/dri_skbitmap.h" |
16 #include "ui/gfx/ozone/dri/dri_surface.h" | 16 #include "ui/gfx/ozone/dri/dri_surface.h" |
17 #include "ui/gfx/ozone/dri/dri_vsync_provider.h" | 17 #include "ui/gfx/ozone/dri/dri_vsync_provider.h" |
18 #include "ui/gfx/ozone/dri/dri_wrapper.h" | 18 #include "ui/gfx/ozone/dri/dri_wrapper.h" |
19 #include "ui/gfx/ozone/dri/hardware_display_controller.h" | 19 #include "ui/gfx/ozone/dri/hardware_display_controller.h" |
| 20 #include "ui/gfx/ozone/surface_ozone.h" |
20 | 21 |
21 namespace gfx { | 22 namespace gfx { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; | 26 const char kDefaultGraphicsCardPath[] = "/dev/dri/card0"; |
26 const char kDPMSProperty[] = "DPMS"; | 27 const char kDPMSProperty[] = "DPMS"; |
27 | 28 |
28 const gfx::AcceleratedWidget kDefaultWidgetHandle = 1; | 29 const gfx::AcceleratedWidget kDefaultWidgetHandle = 1; |
29 | 30 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 SkCanvas* canvas = cursor->GetDrawableForWidget(); | 108 SkCanvas* canvas = cursor->GetDrawableForWidget(); |
108 canvas->clear(SK_ColorTRANSPARENT); | 109 canvas->clear(SK_ColorTRANSPARENT); |
109 | 110 |
110 SkRect clip; | 111 SkRect clip; |
111 clip.set( | 112 clip.set( |
112 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); | 113 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); |
113 canvas->clipRect(clip, SkRegion::kReplace_Op); | 114 canvas->clipRect(clip, SkRegion::kReplace_Op); |
114 canvas->drawBitmapRectToRect(image, &damage, damage); | 115 canvas->drawBitmapRectToRect(image, &damage, damage); |
115 } | 116 } |
116 | 117 |
| 118 // Adapter from SurfaceOzone to DriSurfaceFactory |
| 119 // |
| 120 // This class is derived from SurfaceOzone and owned by the compositor. |
| 121 // |
| 122 // For DRI the hadware surface & canvas are owned by the platform, so |
| 123 // the compositor merely owns this proxy object. |
| 124 // |
| 125 // TODO(spang): Should the compositor own any bits of the DriSurface? |
| 126 class DriSurfaceAdapter : public SurfaceOzone { |
| 127 public: |
| 128 DriSurfaceAdapter(gfx::AcceleratedWidget w, DriSurfaceFactory* dri) |
| 129 : widget_(w), dri_(dri) {} |
| 130 virtual ~DriSurfaceAdapter() {} |
| 131 |
| 132 // SurfaceOzone: |
| 133 virtual bool InitializeCanvas() OVERRIDE { return true; } |
| 134 virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE { |
| 135 return skia::SharePtr(dri_->GetCanvasForWidget(widget_)); |
| 136 } |
| 137 virtual bool PresentCanvas() OVERRIDE { |
| 138 return dri_->SchedulePageFlip(widget_); |
| 139 } |
| 140 virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE { |
| 141 return dri_->CreateVSyncProvider(widget_); |
| 142 } |
| 143 |
| 144 private: |
| 145 gfx::AcceleratedWidget widget_; |
| 146 DriSurfaceFactory* dri_; |
| 147 }; |
| 148 |
117 } // namespace | 149 } // namespace |
118 | 150 |
119 DriSurfaceFactory::DriSurfaceFactory() | 151 DriSurfaceFactory::DriSurfaceFactory() |
120 : drm_(), | 152 : drm_(), |
121 state_(UNINITIALIZED), | 153 state_(UNINITIALIZED), |
122 controller_() { | 154 controller_() { |
123 } | 155 } |
124 | 156 |
125 DriSurfaceFactory::~DriSurfaceFactory() { | 157 DriSurfaceFactory::~DriSurfaceFactory() { |
126 if (state_ == INITIALIZED) | 158 if (state_ == INITIALIZED) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // For now just assume we have 1 display device and return it. | 201 // For now just assume we have 1 display device and return it. |
170 if (!controller_.get()) | 202 if (!controller_.get()) |
171 controller_.reset(new HardwareDisplayController()); | 203 controller_.reset(new HardwareDisplayController()); |
172 | 204 |
173 // TODO(dnicoara) We only have 1 display for now, so only 1 AcceleratedWidget. | 205 // TODO(dnicoara) We only have 1 display for now, so only 1 AcceleratedWidget. |
174 // When we'll support multiple displays this needs to be changed to return a | 206 // When we'll support multiple displays this needs to be changed to return a |
175 // different handle for every display. | 207 // different handle for every display. |
176 return kDefaultWidgetHandle; | 208 return kDefaultWidgetHandle; |
177 } | 209 } |
178 | 210 |
179 gfx::AcceleratedWidget DriSurfaceFactory::RealizeAcceleratedWidget( | 211 scoped_ptr<SurfaceOzone> DriSurfaceFactory::CreateSurfaceForWidget( |
180 gfx::AcceleratedWidget w) { | 212 gfx::AcceleratedWidget w) { |
181 CHECK(state_ == INITIALIZED); | 213 CHECK(state_ == INITIALIZED); |
182 // TODO(dnicoara) Once we can handle multiple displays this needs to be | 214 // TODO(dnicoara) Once we can handle multiple displays this needs to be |
183 // changed. | 215 // changed. |
184 CHECK(w == kDefaultWidgetHandle); | 216 CHECK(w == kDefaultWidgetHandle); |
185 | 217 |
186 CHECK(controller_->get_state() == | 218 CHECK(controller_->get_state() == |
187 HardwareDisplayController::UNASSOCIATED); | 219 HardwareDisplayController::UNASSOCIATED); |
188 | 220 |
189 // Until now the controller is just a stub. Initializing it will link it to a | 221 // Until now the controller is just a stub. Initializing it will link it to a |
190 // hardware display. | 222 // hardware display. |
191 if (!InitializeControllerForPrimaryDisplay(drm_.get(), controller_.get())) { | 223 if (!InitializeControllerForPrimaryDisplay(drm_.get(), controller_.get())) { |
192 LOG(ERROR) << "Failed to initialize controller"; | 224 LOG(ERROR) << "Failed to initialize controller"; |
193 return gfx::kNullAcceleratedWidget; | 225 return scoped_ptr<SurfaceOzone>(); |
194 } | 226 } |
195 | 227 |
196 // Create a surface suitable for the current controller. | 228 // Create a surface suitable for the current controller. |
197 scoped_ptr<DriSurface> surface(CreateSurface( | 229 scoped_ptr<DriSurface> surface(CreateSurface( |
198 Size(controller_->get_mode().hdisplay, | 230 Size(controller_->get_mode().hdisplay, |
199 controller_->get_mode().vdisplay))); | 231 controller_->get_mode().vdisplay))); |
200 | 232 |
201 if (!surface->Initialize()) { | 233 if (!surface->Initialize()) { |
202 LOG(ERROR) << "Failed to initialize surface"; | 234 LOG(ERROR) << "Failed to initialize surface"; |
203 return gfx::kNullAcceleratedWidget; | 235 return scoped_ptr<SurfaceOzone>(); |
204 } | 236 } |
205 | 237 |
206 // Bind the surface to the controller. This will register the backing buffers | 238 // Bind the surface to the controller. This will register the backing buffers |
207 // with the hardware CRTC such that we can show the buffers. The controller | 239 // with the hardware CRTC such that we can show the buffers. The controller |
208 // takes ownership of the surface. | 240 // takes ownership of the surface. |
209 if (!controller_->BindSurfaceToController(surface.Pass())) { | 241 if (!controller_->BindSurfaceToController(surface.Pass())) { |
210 LOG(ERROR) << "Failed to bind surface to controller"; | 242 LOG(ERROR) << "Failed to bind surface to controller"; |
211 return gfx::kNullAcceleratedWidget; | 243 return scoped_ptr<SurfaceOzone>(); |
212 } | 244 } |
213 | 245 |
214 return reinterpret_cast<gfx::AcceleratedWidget>(controller_->get_surface()); | 246 return make_scoped_ptr<SurfaceOzone>(new DriSurfaceAdapter(w, this)); |
215 } | 247 } |
216 | 248 |
217 bool DriSurfaceFactory::LoadEGLGLES2Bindings( | 249 bool DriSurfaceFactory::LoadEGLGLES2Bindings( |
218 AddGLLibraryCallback add_gl_library, | 250 AddGLLibraryCallback add_gl_library, |
219 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { | 251 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { |
220 return false; | 252 return false; |
221 } | 253 } |
222 | 254 |
223 bool DriSurfaceFactory::AttemptToResizeAcceleratedWidget( | |
224 gfx::AcceleratedWidget w, | |
225 const gfx::Rect& bounds) { | |
226 return false; | |
227 } | |
228 | |
229 bool DriSurfaceFactory::SchedulePageFlip(gfx::AcceleratedWidget w) { | 255 bool DriSurfaceFactory::SchedulePageFlip(gfx::AcceleratedWidget w) { |
230 CHECK(state_ == INITIALIZED); | 256 CHECK(state_ == INITIALIZED); |
231 // TODO(dnicoara) Change this CHECK once we're running with the threaded | 257 // TODO(dnicoara) Change this CHECK once we're running with the threaded |
232 // compositor. | 258 // compositor. |
233 CHECK(base::MessageLoopForUI::IsCurrent()); | 259 CHECK(base::MessageLoopForUI::IsCurrent()); |
234 | 260 |
235 // TODO(dnicoara) Once we can handle multiple displays this needs to be | 261 // TODO(dnicoara) Once we can handle multiple displays this needs to be |
236 // changed. | 262 // changed. |
237 CHECK(w == kDefaultWidgetHandle); | 263 CHECK(w == kDefaultWidgetHandle); |
238 | 264 |
(...skipping 15 matching lines...) Expand all Loading... |
254 // Note that the following call does not use any locks, so it is safe to be | 280 // Note that the following call does not use any locks, so it is safe to be |
255 // made on the UI thread (thought not ideal). | 281 // made on the UI thread (thought not ideal). |
256 WaitForPageFlipEvent(drm_->get_fd()); | 282 WaitForPageFlipEvent(drm_->get_fd()); |
257 | 283 |
258 return true; | 284 return true; |
259 } | 285 } |
260 | 286 |
261 SkCanvas* DriSurfaceFactory::GetCanvasForWidget( | 287 SkCanvas* DriSurfaceFactory::GetCanvasForWidget( |
262 gfx::AcceleratedWidget w) { | 288 gfx::AcceleratedWidget w) { |
263 CHECK(state_ == INITIALIZED); | 289 CHECK(state_ == INITIALIZED); |
264 return reinterpret_cast<DriSurface*>(w)->GetDrawableForWidget(); | 290 CHECK_EQ(kDefaultWidgetHandle, w); |
| 291 return controller_->get_surface()->GetDrawableForWidget(); |
265 } | 292 } |
266 | 293 |
267 scoped_ptr<gfx::VSyncProvider> DriSurfaceFactory::CreateVSyncProvider( | 294 scoped_ptr<gfx::VSyncProvider> DriSurfaceFactory::CreateVSyncProvider( |
268 gfx::AcceleratedWidget w) { | 295 gfx::AcceleratedWidget w) { |
269 CHECK(state_ == INITIALIZED); | 296 CHECK(state_ == INITIALIZED); |
270 return scoped_ptr<VSyncProvider>(new DriVSyncProvider(controller_.get())); | 297 return scoped_ptr<VSyncProvider>(new DriVSyncProvider(controller_.get())); |
271 } | 298 } |
272 | 299 |
273 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window, | 300 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window, |
274 const SkBitmap& image, | 301 const SkBitmap& image, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 drmEventContext drm_event; | 388 drmEventContext drm_event; |
362 drm_event.version = DRM_EVENT_CONTEXT_VERSION; | 389 drm_event.version = DRM_EVENT_CONTEXT_VERSION; |
363 drm_event.page_flip_handler = HandlePageFlipEvent; | 390 drm_event.page_flip_handler = HandlePageFlipEvent; |
364 drm_event.vblank_handler = NULL; | 391 drm_event.vblank_handler = NULL; |
365 | 392 |
366 // Wait for the page-flip to complete. | 393 // Wait for the page-flip to complete. |
367 drmHandleEvent(fd, &drm_event); | 394 drmHandleEvent(fd, &drm_event); |
368 } | 395 } |
369 | 396 |
370 } // namespace gfx | 397 } // namespace gfx |
OLD | NEW |