| 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 SwapCanvas() OVERRIDE { return dri_->SchedulePageFlip(widget_); } |
| 138 virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE { |
| 139 return dri_->CreateVSyncProvider(widget_); |
| 140 } |
| 141 |
| 142 private: |
| 143 gfx::AcceleratedWidget widget_; |
| 144 DriSurfaceFactory* dri_; |
| 145 }; |
| 146 |
| 117 } // namespace | 147 } // namespace |
| 118 | 148 |
| 119 DriSurfaceFactory::DriSurfaceFactory() | 149 DriSurfaceFactory::DriSurfaceFactory() |
| 120 : drm_(), | 150 : drm_(), |
| 121 state_(UNINITIALIZED), | 151 state_(UNINITIALIZED), |
| 122 controller_() { | 152 controller_() { |
| 123 } | 153 } |
| 124 | 154 |
| 125 DriSurfaceFactory::~DriSurfaceFactory() { | 155 DriSurfaceFactory::~DriSurfaceFactory() { |
| 126 if (state_ == INITIALIZED) | 156 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. | 199 // For now just assume we have 1 display device and return it. |
| 170 if (!controller_.get()) | 200 if (!controller_.get()) |
| 171 controller_.reset(new HardwareDisplayController()); | 201 controller_.reset(new HardwareDisplayController()); |
| 172 | 202 |
| 173 // TODO(dnicoara) We only have 1 display for now, so only 1 AcceleratedWidget. | 203 // 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 | 204 // When we'll support multiple displays this needs to be changed to return a |
| 175 // different handle for every display. | 205 // different handle for every display. |
| 176 return kDefaultWidgetHandle; | 206 return kDefaultWidgetHandle; |
| 177 } | 207 } |
| 178 | 208 |
| 179 gfx::AcceleratedWidget DriSurfaceFactory::RealizeAcceleratedWidget( | 209 scoped_ptr<SurfaceOzone> DriSurfaceFactory::CreateSurfaceForWidget( |
| 180 gfx::AcceleratedWidget w) { | 210 gfx::AcceleratedWidget w) { |
| 181 CHECK(state_ == INITIALIZED); | 211 CHECK(state_ == INITIALIZED); |
| 182 // TODO(dnicoara) Once we can handle multiple displays this needs to be | 212 // TODO(dnicoara) Once we can handle multiple displays this needs to be |
| 183 // changed. | 213 // changed. |
| 184 CHECK(w == kDefaultWidgetHandle); | 214 CHECK(w == kDefaultWidgetHandle); |
| 185 | 215 |
| 186 CHECK(controller_->get_state() == | 216 CHECK(controller_->get_state() == |
| 187 HardwareDisplayController::UNASSOCIATED); | 217 HardwareDisplayController::UNASSOCIATED); |
| 188 | 218 |
| 189 // Until now the controller is just a stub. Initializing it will link it to a | 219 // Until now the controller is just a stub. Initializing it will link it to a |
| 190 // hardware display. | 220 // hardware display. |
| 191 if (!InitializeControllerForPrimaryDisplay(drm_.get(), controller_.get())) { | 221 if (!InitializeControllerForPrimaryDisplay(drm_.get(), controller_.get())) { |
| 192 LOG(ERROR) << "Failed to initialize controller"; | 222 LOG(ERROR) << "Failed to initialize controller"; |
| 193 return gfx::kNullAcceleratedWidget; | 223 return scoped_ptr<SurfaceOzone>(); |
| 194 } | 224 } |
| 195 | 225 |
| 196 // Create a surface suitable for the current controller. | 226 // Create a surface suitable for the current controller. |
| 197 scoped_ptr<DriSurface> surface(CreateSurface( | 227 scoped_ptr<DriSurface> surface(CreateSurface( |
| 198 Size(controller_->get_mode().hdisplay, | 228 Size(controller_->get_mode().hdisplay, |
| 199 controller_->get_mode().vdisplay))); | 229 controller_->get_mode().vdisplay))); |
| 200 | 230 |
| 201 if (!surface->Initialize()) { | 231 if (!surface->Initialize()) { |
| 202 LOG(ERROR) << "Failed to initialize surface"; | 232 LOG(ERROR) << "Failed to initialize surface"; |
| 203 return gfx::kNullAcceleratedWidget; | 233 return scoped_ptr<SurfaceOzone>(); |
| 204 } | 234 } |
| 205 | 235 |
| 206 // Bind the surface to the controller. This will register the backing buffers | 236 // 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 | 237 // with the hardware CRTC such that we can show the buffers. The controller |
| 208 // takes ownership of the surface. | 238 // takes ownership of the surface. |
| 209 if (!controller_->BindSurfaceToController(surface.Pass())) { | 239 if (!controller_->BindSurfaceToController(surface.Pass())) { |
| 210 LOG(ERROR) << "Failed to bind surface to controller"; | 240 LOG(ERROR) << "Failed to bind surface to controller"; |
| 211 return gfx::kNullAcceleratedWidget; | 241 return scoped_ptr<SurfaceOzone>(); |
| 212 } | 242 } |
| 213 | 243 |
| 214 return reinterpret_cast<gfx::AcceleratedWidget>(controller_->get_surface()); | 244 return make_scoped_ptr<SurfaceOzone>(new DriSurfaceAdapter(w, this)); |
| 215 } | 245 } |
| 216 | 246 |
| 217 bool DriSurfaceFactory::LoadEGLGLES2Bindings( | 247 bool DriSurfaceFactory::LoadEGLGLES2Bindings( |
| 218 AddGLLibraryCallback add_gl_library, | 248 AddGLLibraryCallback add_gl_library, |
| 219 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { | 249 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { |
| 220 return false; | 250 return false; |
| 221 } | 251 } |
| 222 | 252 |
| 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) { | 253 bool DriSurfaceFactory::SchedulePageFlip(gfx::AcceleratedWidget w) { |
| 230 CHECK(state_ == INITIALIZED); | 254 CHECK(state_ == INITIALIZED); |
| 231 // TODO(dnicoara) Change this CHECK once we're running with the threaded | 255 // TODO(dnicoara) Change this CHECK once we're running with the threaded |
| 232 // compositor. | 256 // compositor. |
| 233 CHECK(base::MessageLoopForUI::IsCurrent()); | 257 CHECK(base::MessageLoopForUI::IsCurrent()); |
| 234 | 258 |
| 235 // TODO(dnicoara) Once we can handle multiple displays this needs to be | 259 // TODO(dnicoara) Once we can handle multiple displays this needs to be |
| 236 // changed. | 260 // changed. |
| 237 CHECK(w == kDefaultWidgetHandle); | 261 CHECK(w == kDefaultWidgetHandle); |
| 238 | 262 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 254 // Note that the following call does not use any locks, so it is safe to be | 278 // 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). | 279 // made on the UI thread (thought not ideal). |
| 256 WaitForPageFlipEvent(drm_->get_fd()); | 280 WaitForPageFlipEvent(drm_->get_fd()); |
| 257 | 281 |
| 258 return true; | 282 return true; |
| 259 } | 283 } |
| 260 | 284 |
| 261 SkCanvas* DriSurfaceFactory::GetCanvasForWidget( | 285 SkCanvas* DriSurfaceFactory::GetCanvasForWidget( |
| 262 gfx::AcceleratedWidget w) { | 286 gfx::AcceleratedWidget w) { |
| 263 CHECK(state_ == INITIALIZED); | 287 CHECK(state_ == INITIALIZED); |
| 264 return reinterpret_cast<DriSurface*>(w)->GetDrawableForWidget(); | 288 CHECK_EQ(kDefaultWidgetHandle, w); |
| 289 return controller_->get_surface()->GetDrawableForWidget(); |
| 265 } | 290 } |
| 266 | 291 |
| 267 scoped_ptr<gfx::VSyncProvider> DriSurfaceFactory::CreateVSyncProvider( | 292 scoped_ptr<gfx::VSyncProvider> DriSurfaceFactory::CreateVSyncProvider( |
| 268 gfx::AcceleratedWidget w) { | 293 gfx::AcceleratedWidget w) { |
| 269 CHECK(state_ == INITIALIZED); | 294 CHECK(state_ == INITIALIZED); |
| 270 return scoped_ptr<VSyncProvider>(new DriVSyncProvider(controller_.get())); | 295 return scoped_ptr<VSyncProvider>(new DriVSyncProvider(controller_.get())); |
| 271 } | 296 } |
| 272 | 297 |
| 273 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window, | 298 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window, |
| 274 const SkBitmap& image, | 299 const SkBitmap& image, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 drmEventContext drm_event; | 386 drmEventContext drm_event; |
| 362 drm_event.version = DRM_EVENT_CONTEXT_VERSION; | 387 drm_event.version = DRM_EVENT_CONTEXT_VERSION; |
| 363 drm_event.page_flip_handler = HandlePageFlipEvent; | 388 drm_event.page_flip_handler = HandlePageFlipEvent; |
| 364 drm_event.vblank_handler = NULL; | 389 drm_event.vblank_handler = NULL; |
| 365 | 390 |
| 366 // Wait for the page-flip to complete. | 391 // Wait for the page-flip to complete. |
| 367 drmHandleEvent(fd, &drm_event); | 392 drmHandleEvent(fd, &drm_event); |
| 368 } | 393 } |
| 369 | 394 |
| 370 } // namespace gfx | 395 } // namespace gfx |
| OLD | NEW |