Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / ozone / platform / dri / hardware_display_controller.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/hardware_display_controller.h"
6
7 #include <errno.h>
8 #include <string.h>
9
10 #include "base/basictypes.h"
11 #include "base/debug/trace_event.h"
12 #include "base/logging.h"
13 #include "base/time/time.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "ui/gfx/geometry/point.h"
16 #include "ui/ozone/platform/dri/dri_buffer.h"
17 #include "ui/ozone/platform/dri/dri_surface.h"
18 #include "ui/ozone/platform/dri/dri_wrapper.h"
19
20 namespace ui {
21
22 HardwareDisplayController::HardwareDisplayController(
23     DriWrapper* drm,
24     uint32_t connector_id,
25     uint32_t crtc_id)
26     : drm_(drm),
27       connector_id_(connector_id),
28       crtc_id_(crtc_id),
29       surface_(),
30       time_of_last_flip_(0) {}
31
32 HardwareDisplayController::~HardwareDisplayController() {
33   // Reset the cursor.
34   UnsetCursor();
35   UnbindSurfaceFromController();
36 }
37
38 bool
39 HardwareDisplayController::BindSurfaceToController(
40     scoped_ptr<DriSurface> surface, drmModeModeInfo mode) {
41   CHECK(surface);
42
43   if (!RegisterFramebuffers(surface.get(), mode))
44     return false;
45
46   if (!drm_->SetCrtc(crtc_id_,
47                      surface->GetFramebufferId(),
48                      &connector_id_,
49                      &mode)) {
50     LOG(ERROR) << "Failed to modeset: crtc=" << crtc_id_ << " connector="
51                << connector_id_ << " framebuffer_id="
52                << surface->GetFramebufferId();
53     return false;
54   }
55
56   surface_.reset(surface.release());
57   mode_ = mode;
58   return true;
59 }
60
61 void HardwareDisplayController::UnbindSurfaceFromController() {
62   if (surface_)
63     UnregisterFramebuffers(surface_.get());
64   surface_.reset();
65 }
66
67 bool HardwareDisplayController::SchedulePageFlip() {
68   CHECK(surface_);
69
70   if (!drm_->PageFlip(crtc_id_,
71                       surface_->GetFramebufferId(),
72                       this)) {
73     LOG(ERROR) << "Cannot page flip: " << strerror(errno);
74     return false;
75   }
76
77   return true;
78 }
79
80 void HardwareDisplayController::OnPageFlipEvent(unsigned int frame,
81                                                 unsigned int seconds,
82                                                 unsigned int useconds) {
83   time_of_last_flip_ =
84       static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond +
85       useconds;
86
87   surface_->SwapBuffers();
88 }
89
90 bool HardwareDisplayController::SetCursor(DriSurface* surface) {
91   bool ret = drm_->SetCursor(crtc_id_,
92                          surface->GetHandle(),
93                          surface->size().width(),
94                          surface->size().height());
95   surface->SwapBuffers();
96   return ret;
97 }
98
99 bool HardwareDisplayController::UnsetCursor() {
100   return drm_->SetCursor(crtc_id_, 0, 0, 0);
101 }
102
103 bool HardwareDisplayController::MoveCursor(const gfx::Point& location) {
104   return drm_->MoveCursor(crtc_id_, location.x(), location.y());
105 }
106
107 bool HardwareDisplayController::RegisterFramebuffers(DriSurface* surface,
108                                                      drmModeModeInfo mode) {
109   // Register the buffers.
110   for (size_t i = 0; i < arraysize(surface->bitmaps_); ++i) {
111     uint32_t fb_id;
112     if (!drm_->AddFramebuffer(
113             mode,
114             surface->bitmaps_[i]->GetColorDepth(),
115             surface->bitmaps_[i]->canvas()->imageInfo().bytesPerPixel() << 3,
116             surface->bitmaps_[i]->stride(),
117             surface->bitmaps_[i]->handle(),
118             &fb_id)) {
119       DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno);
120       return false;
121     }
122     surface->bitmaps_[i]->set_framebuffer(fb_id);
123   }
124
125   return true;
126 }
127
128 void HardwareDisplayController::UnregisterFramebuffers(DriSurface* surface) {
129   // Unregister the buffers.
130   for (size_t i = 0; i < arraysize(surface->bitmaps_); ++i) {
131     if (!drm_->RemoveFramebuffer(surface->bitmaps_[i]->framebuffer()))
132       DLOG(ERROR) << "Failed to remove FB: " << strerror(errno);
133   }
134 }
135
136 }  // namespace ui