Home | History | Annotate | Download | only in dri
      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
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gfx/ozone/dri/hardware_display_controller.h"
      6 
      7 #include <errno.h>
      8 #include <string.h>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/logging.h"
     12 #include "base/time/time.h"
     13 #include "ui/gfx/ozone/dri/dri_skbitmap.h"
     14 #include "ui/gfx/ozone/dri/dri_surface.h"
     15 #include "ui/gfx/ozone/dri/dri_wrapper.h"
     16 
     17 namespace gfx {
     18 
     19 HardwareDisplayController::HardwareDisplayController()
     20     : drm_(NULL),
     21       connector_id_(0),
     22       crtc_id_(0),
     23       mode_(),
     24       saved_crtc_(NULL),
     25       state_(UNASSOCIATED),
     26       surface_(),
     27       time_of_last_flip_(0) {}
     28 
     29 void HardwareDisplayController::SetControllerInfo(
     30     DriWrapper* drm,
     31     uint32_t connector_id,
     32     uint32_t crtc_id,
     33     uint32_t dpms_property_id,
     34     drmModeModeInfo mode) {
     35   drm_ = drm;
     36   connector_id_ = connector_id;
     37   crtc_id_ = crtc_id;
     38   dpms_property_id_ = dpms_property_id;
     39   mode_ = mode;
     40   saved_crtc_ = drm_->GetCrtc(crtc_id_);
     41   state_ = UNINITIALIZED;
     42 }
     43 
     44 HardwareDisplayController::~HardwareDisplayController() {
     45   if (saved_crtc_) {
     46     if (!drm_->SetCrtc(saved_crtc_, &connector_id_))
     47       DLOG(ERROR) << "Failed to restore CRTC state: " << strerror(errno);
     48     drm_->FreeCrtc(saved_crtc_);
     49   }
     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 }
     59 
     60 bool
     61 HardwareDisplayController::BindSurfaceToController(
     62     scoped_ptr<DriSurface> surface) {
     63   CHECK(state_ == UNINITIALIZED);
     64 
     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());
     82   state_ = SURFACE_INITIALIZED;
     83   return true;
     84 }
     85 
     86 bool HardwareDisplayController::SchedulePageFlip() {
     87   CHECK(state_ == SURFACE_INITIALIZED || state_ == INITIALIZED);
     88 
     89   if (state_ == SURFACE_INITIALIZED) {
     90     // Perform the initial modeset.
     91     if (!drm_->SetCrtc(crtc_id_,
     92                        surface_->GetFramebufferId(),
     93                        &connector_id_,
     94                        &mode_)) {
     95       DLOG(ERROR) << "Cannot set CRTC: " << strerror(errno);
     96       state_ = FAILED;
     97       return false;
     98     } else {
     99       state_ = INITIALIZED;
    100     }
    101 
    102     if (dpms_property_id_)
    103       drm_->ConnectorSetProperty(connector_id_,
    104                                  dpms_property_id_,
    105                                  DRM_MODE_DPMS_ON);
    106   }
    107 
    108   if (!drm_->PageFlip(crtc_id_,
    109                       surface_->GetFramebufferId(),
    110                       this)) {
    111     state_ = FAILED;
    112     LOG(ERROR) << "Cannot page flip: " << strerror(errno);
    113     return false;
    114   }
    115 
    116   return true;
    117 }
    118 
    119 void HardwareDisplayController::OnPageFlipEvent(unsigned int frame,
    120                                                 unsigned int seconds,
    121                                                 unsigned int useconds) {
    122   time_of_last_flip_ =
    123       static_cast<uint64_t>(seconds) * base::Time::kMicrosecondsPerSecond +
    124       useconds;
    125 
    126   surface_->SwapBuffers();
    127 }
    128 
    129 }  // namespace gfx
    130