Chromium Code Reviews| 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 |