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/hardware_display_controller.h" | 5 #include "ui/gfx/ozone/dri/hardware_display_controller.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "ui/gfx/ozone/dri/dri_skbitmap.h" | 13 #include "ui/gfx/ozone/dri/dri_skbitmap.h" |
14 #include "ui/gfx/ozone/dri/dri_wrapper.h" | |
14 #include "ui/gfx/ozone/dri/dri_surface.h" | 15 #include "ui/gfx/ozone/dri/dri_surface.h" |
15 #include "ui/gfx/ozone/dri/dri_wrapper.h" | 16 #include "ui/gfx/ozone/dri/scanout_surface.h" |
16 | 17 |
17 namespace gfx { | 18 namespace gfx { |
18 | 19 |
20 static unsigned FindOverlayPlane(DriWrapper* drm) { | |
21 unsigned int plane_index; | |
22 int i; | |
23 drmModeRes* device_res = NULL; | |
24 drmModePlane* plane_info = NULL; | |
25 int crtc_id; | |
26 | |
27 device_res = drmModeGetResources(drm->get_fd()); | |
28 drmModePlaneRes* planes_res = drmModeGetPlaneResources(drm->get_fd()); | |
29 | |
30 char buffer[1024]; | |
31 | |
32 if (planes_res) { | |
33 for (plane_index = 0; plane_index < planes_res->count_planes; | |
34 ++plane_index) { | |
35 uint32_t planei = planes_res->planes[plane_index]; | |
36 plane_info = drmModeGetPlane(drm->get_fd(), planei); | |
37 if (!plane_info) | |
38 continue; | |
39 | |
40 for (unsigned int j = 0; j < plane_info->count_formats; j++) { | |
41 sprintf(buffer, " %4.4s", (char*)&plane_info->formats[j]); | |
42 LOG(ERROR) << __FUNCTION__ << " " << buffer; | |
43 } | |
44 | |
45 sprintf(buffer, | |
46 "%d\t%d\t%d\t%d,%d\t\t%d,%d\t%-8d\t0x%08x", | |
47 plane_info->plane_id, | |
48 plane_info->crtc_id, | |
49 plane_info->fb_id, | |
50 plane_info->crtc_x, | |
51 plane_info->crtc_y, | |
52 plane_info->x, | |
53 plane_info->y, | |
54 plane_info->gamma_size, | |
55 plane_info->possible_crtcs); | |
56 | |
57 LOG(ERROR) << __FUNCTION__ << " Props " << buffer; | |
58 | |
59 // Assume that every plane supports one and only one CRTC. | |
60 crtc_id = 0; | |
61 for (i = 0; i < device_res->count_crtcs; ++i) { | |
62 if (plane_info->possible_crtcs & (1UL << i)) { | |
63 crtc_id = device_res->crtcs[i]; | |
64 break; | |
65 } | |
66 } | |
67 if (crtc_id == 0) { | |
68 LOG(ERROR) << __FUNCTION__ | |
69 << "Could not find a CRTC compatible with plane"; | |
70 continue; | |
71 } | |
72 if (plane_info->possible_crtcs >> (i + 1)) { | |
73 LOG(ERROR) << __FUNCTION__ | |
74 << "Video plane %lu supports more than one CRTC"; | |
75 } | |
76 | |
77 LOG(ERROR) << __FUNCTION__ << " ---> Using video plane " | |
78 << (unsigned long)plane_info->plane_id << " on crtc " | |
79 << (unsigned long)crtc_id; | |
80 | |
81 if (plane_info->plane_id) | |
82 return plane_info->plane_id; | |
83 } | |
84 } else { | |
85 LOG(ERROR) << __FUNCTION__ << "No plain res"; | |
86 } | |
87 | |
88 return 0; | |
89 } | |
90 | |
19 HardwareDisplayController::HardwareDisplayController() | 91 HardwareDisplayController::HardwareDisplayController() |
20 : drm_(NULL), | 92 : drm_(NULL), |
21 connector_id_(0), | 93 connector_id_(0), |
22 crtc_id_(0), | 94 crtc_id_(0), |
23 mode_(), | 95 mode_(), |
24 saved_crtc_(NULL), | 96 saved_crtc_(NULL), |
25 state_(UNASSOCIATED), | 97 state_(UNASSOCIATED), |
26 surface_(), | 98 surface_(), |
27 time_of_last_flip_(0) {} | 99 time_of_last_flip_(0), |
100 overlay_plane_fb_id_(0), | |
101 overlay_plane_(0) {} | |
28 | 102 |
29 void HardwareDisplayController::SetControllerInfo( | 103 void HardwareDisplayController::SetControllerInfo( |
30 DriWrapper* drm, | 104 DriWrapper* drm, |
31 uint32_t connector_id, | 105 uint32_t connector_id, |
32 uint32_t crtc_id, | 106 uint32_t crtc_id, |
33 uint32_t dpms_property_id, | 107 uint32_t dpms_property_id, |
34 drmModeModeInfo mode) { | 108 drmModeModeInfo mode) { |
35 drm_ = drm; | 109 drm_ = drm; |
36 connector_id_ = connector_id; | 110 connector_id_ = connector_id; |
37 crtc_id_ = crtc_id; | 111 crtc_id_ = crtc_id; |
38 dpms_property_id_ = dpms_property_id; | 112 dpms_property_id_ = dpms_property_id; |
39 mode_ = mode; | 113 mode_ = mode; |
40 saved_crtc_ = drm_->GetCrtc(crtc_id_); | 114 saved_crtc_ = drm_->GetCrtc(crtc_id_); |
41 state_ = UNINITIALIZED; | 115 state_ = UNINITIALIZED; |
42 } | 116 } |
43 | 117 |
44 HardwareDisplayController::~HardwareDisplayController() { | 118 HardwareDisplayController::~HardwareDisplayController() { |
45 if (saved_crtc_) { | 119 if (saved_crtc_) { |
46 if (!drm_->SetCrtc(saved_crtc_, &connector_id_)) | 120 if (!drm_->SetCrtc(saved_crtc_, &connector_id_)) |
47 DLOG(ERROR) << "Failed to restore CRTC state: " << strerror(errno); | 121 DLOG(ERROR) << "Failed to restore CRTC state: " << strerror(errno); |
48 drm_->FreeCrtc(saved_crtc_); | 122 drm_->FreeCrtc(saved_crtc_); |
49 } | 123 } |
50 | |
51 if (surface_.get()) { | |
52 // Unregister the buffers. | |
53 for (int i = 0; i < 2; ++i) { | |
54 if (!drm_->RemoveFramebuffer(surface_->bitmaps_[i]->get_framebuffer())) | |
55 DLOG(ERROR) << "Failed to remove FB: " << strerror(errno); | |
56 } | |
57 } | |
58 } | 124 } |
59 | 125 |
60 bool | 126 bool |
61 HardwareDisplayController::BindSurfaceToController( | 127 HardwareDisplayController::BindSurfaceToController( |
62 scoped_ptr<DriSurface> surface) { | 128 scoped_ptr<ScanoutSurface> surface) { |
63 CHECK(state_ == UNINITIALIZED); | 129 CHECK(state_ == UNINITIALIZED); |
64 | 130 |
65 // Register the buffers. | |
66 for (int i = 0; i < 2; ++i) { | |
67 uint32_t fb_id; | |
68 if (!drm_->AddFramebuffer(mode_, | |
69 surface->bitmaps_[i]->GetColorDepth(), | |
70 surface->bitmaps_[i]->bytesPerPixel() << 3, | |
71 surface->bitmaps_[i]->rowBytes(), | |
72 surface->bitmaps_[i]->get_handle(), | |
73 &fb_id)) { | |
74 DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno); | |
75 state_ = FAILED; | |
76 return false; | |
77 } | |
78 surface->bitmaps_[i]->set_framebuffer(fb_id); | |
79 } | |
80 | |
81 surface_.reset(surface.release()); | 131 surface_.reset(surface.release()); |
82 state_ = SURFACE_INITIALIZED; | 132 state_ = SURFACE_INITIALIZED; |
83 return true; | 133 return true; |
84 } | 134 } |
85 | 135 |
136 bool HardwareDisplayController::AddFramebuffer( | |
137 uint8_t depth, | |
138 uint8_t bpp, | |
139 uint32_t stride, | |
140 uint32_t handle, | |
141 uint32_t* framebuffer_id) { | |
142 CHECK(state_ != UNASSOCIATED && state_ != FAILED); | |
143 if (!drm_->AddFramebuffer(mode_, | |
144 depth, | |
145 bpp, | |
146 stride, | |
147 handle, | |
148 framebuffer_id)){ | |
149 DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno); | |
150 state_ = FAILED; | |
151 return false; | |
152 } | |
153 return true; | |
154 } | |
155 | |
156 bool HardwareDisplayController::RemoveFramebuffer( | |
157 uint32_t framebuffer_id) { | |
158 CHECK(state_ != UNASSOCIATED); | |
159 if (!drm_->RemoveFramebuffer(framebuffer_id)) { | |
160 DLOG(ERROR) << "Failed to remove FB: " << strerror(errno); | |
161 return false; | |
162 } | |
163 return true; | |
164 } | |
165 | |
86 bool HardwareDisplayController::SchedulePageFlip() { | 166 bool HardwareDisplayController::SchedulePageFlip() { |
87 CHECK(state_ == SURFACE_INITIALIZED || state_ == INITIALIZED); | 167 CHECK(state_ == SURFACE_INITIALIZED || state_ == INITIALIZED); |
88 | 168 |
89 if (state_ == SURFACE_INITIALIZED) { | 169 if (state_ == SURFACE_INITIALIZED) { |
90 // Perform the initial modeset. | 170 // Perform the initial modeset. |
91 if (!drm_->SetCrtc(crtc_id_, | 171 if (!drm_->SetCrtc(crtc_id_, |
92 surface_->GetFramebufferId(), | 172 surface_->GetFramebufferId(), |
93 &connector_id_, | 173 &connector_id_, |
94 &mode_)) { | 174 &mode_)) { |
95 DLOG(ERROR) << "Cannot set CRTC: " << strerror(errno); | 175 DLOG(ERROR) << "Cannot set CRTC: " << strerror(errno); |
96 state_ = FAILED; | 176 state_ = FAILED; |
97 return false; | 177 return false; |
98 } else { | 178 } else { |
99 state_ = INITIALIZED; | 179 state_ = INITIALIZED; |
100 } | 180 } |
101 | 181 |
182 overlay_plane_ = FindOverlayPlane(drm_); | |
183 | |
102 if (dpms_property_id_) | 184 if (dpms_property_id_) |
103 drm_->ConnectorSetProperty(connector_id_, | 185 drm_->ConnectorSetProperty(connector_id_, |
104 dpms_property_id_, | 186 dpms_property_id_, |
105 DRM_MODE_DPMS_ON); | 187 DRM_MODE_DPMS_ON); |
106 } | 188 } |
107 | 189 |
108 if (!drm_->PageFlip(crtc_id_, | 190 if (!drm_->PageFlip(crtc_id_, |
109 surface_->GetFramebufferId(), | 191 surface_->GetFramebufferId(), |
192 overlay_plane_rect_, | |
dnicoara
2014/01/21 21:22:42
I know this is hacked for now and will receive muc
| |
193 overlay_plane_size_, | |
194 overlay_plane_fb_id_, | |
195 overlay_plane_, | |
110 this)) { | 196 this)) { |
111 state_ = FAILED; | 197 state_ = FAILED; |
112 LOG(ERROR) << "Cannot page flip: " << strerror(errno); | 198 LOG(ERROR) << "Cannot page flip: " << strerror(errno); |
113 return false; | 199 return false; |
114 } | 200 } |
115 | 201 |
116 return true; | 202 return true; |
117 } | 203 } |
118 | 204 |
119 void HardwareDisplayController::OnPageFlipEvent(unsigned int frame, | 205 void HardwareDisplayController::OnPageFlipEvent(unsigned int frame, |
120 unsigned int seconds, | 206 unsigned int seconds, |
121 unsigned int useconds) { | 207 unsigned int useconds) { |
122 time_of_last_flip_ = | 208 time_of_last_flip_ = |
123 static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + | 209 static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond + |
124 useconds; | 210 useconds; |
125 | 211 |
126 surface_->SwapBuffers(); | 212 surface_->SwapBuffers(); |
127 } | 213 } |
128 | 214 |
215 void HardwareDisplayController::SetOverlayPlaneInfo( | |
216 gfx::Rect overlay_plane_rect, | |
217 gfx::Size overlay_plane_size, | |
218 unsigned overlay_plane_fb_id) { | |
219 overlay_plane_rect_ = overlay_plane_rect; | |
220 overlay_plane_size_ = overlay_plane_size; | |
221 overlay_plane_fb_id_ = overlay_plane_fb_id; | |
222 } | |
223 | |
129 } // namespace gfx | 224 } // namespace gfx |
OLD | NEW |