Home | History | Annotate | Download | only in dri
      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/screen_manager.h"
      6 
      7 #include <xf86drmMode.h>
      8 
      9 #include "ui/gfx/geometry/point.h"
     10 #include "ui/gfx/geometry/rect.h"
     11 #include "ui/gfx/geometry/size.h"
     12 #include "ui/ozone/platform/dri/dri_util.h"
     13 #include "ui/ozone/platform/dri/hardware_display_controller.h"
     14 #include "ui/ozone/platform/dri/scanout_surface.h"
     15 
     16 namespace ui {
     17 
     18 ScreenManager::ScreenManager(
     19     DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator)
     20     : dri_(dri), surface_generator_(surface_generator), last_added_widget_(0) {
     21 }
     22 
     23 ScreenManager::~ScreenManager() {
     24   STLDeleteContainerPairSecondPointers(
     25       controllers_.begin(), controllers_.end());
     26 }
     27 
     28 void ScreenManager::RemoveDisplayController(uint32_t crtc, uint32_t connector) {
     29   HardwareDisplayControllerMap::iterator it =
     30       FindDisplayController(crtc, connector);
     31   if (it != controllers_.end()) {
     32     delete it->second;
     33     controllers_.erase(it);
     34   }
     35 }
     36 
     37 bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
     38                                                uint32_t connector,
     39                                                const drmModeModeInfo& mode) {
     40   HardwareDisplayControllerMap::iterator it =
     41       FindDisplayController(crtc, connector);
     42   HardwareDisplayController* controller = NULL;
     43   if (it != controllers_.end()) {
     44     if (SameMode(mode, it->second->get_mode()))
     45       return it->second->Enable();
     46 
     47     controller = it->second;
     48     controller->UnbindSurfaceFromController();
     49   }
     50 
     51   if (it == controllers_.end()) {
     52     controller = new HardwareDisplayController(dri_, connector, crtc);
     53     controllers_.insert(std::make_pair(++last_added_widget_, controller));
     54   }
     55 
     56   // Create a surface suitable for the current controller.
     57   scoped_ptr<ScanoutSurface> surface(
     58       surface_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay)));
     59 
     60   if (!surface->Initialize()) {
     61     LOG(ERROR) << "Failed to initialize surface";
     62     return false;
     63   }
     64 
     65   // Bind the surface to the controller. This will register the backing buffers
     66   // with the hardware CRTC such that we can show the buffers and performs the
     67   // initial modeset. The controller takes ownership of the surface.
     68   if (!controller->BindSurfaceToController(surface.Pass(), mode)) {
     69     LOG(ERROR) << "Failed to bind surface to controller";
     70     return false;
     71   }
     72 
     73   return true;
     74 }
     75 
     76 bool ScreenManager::DisableDisplayController(uint32_t crtc,
     77                                              uint32_t connector) {
     78   HardwareDisplayControllerMap::iterator it =
     79       FindDisplayController(crtc, connector);
     80   if (it != controllers_.end()) {
     81     it->second->Disable();
     82     return true;
     83   }
     84 
     85   return false;
     86 }
     87 
     88 base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
     89     gfx::AcceleratedWidget widget) {
     90   // TODO(dnicoara): Remove hack once TestScreen uses a simple Ozone display
     91   // configuration reader and ScreenManager is called from there to create the
     92   // one display needed by the content_shell target.
     93   if (controllers_.empty() && last_added_widget_ == 0)
     94     ForceInitializationOfPrimaryDisplay();
     95 
     96   HardwareDisplayControllerMap::iterator it = controllers_.find(widget);
     97   if (it != controllers_.end())
     98     return it->second->AsWeakPtr();
     99 
    100   return base::WeakPtr<HardwareDisplayController>();
    101 }
    102 
    103 ScreenManager::HardwareDisplayControllerMap::iterator
    104 ScreenManager::FindDisplayController(uint32_t crtc, uint32_t connector) {
    105   for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
    106        it != controllers_.end();
    107        ++it) {
    108     if (it->second->connector_id() == connector &&
    109         it->second->crtc_id() == crtc)
    110       return it;
    111   }
    112 
    113   return controllers_.end();
    114 }
    115 
    116 void ScreenManager::ForceInitializationOfPrimaryDisplay() {
    117   drmModeRes* resources = drmModeGetResources(dri_->get_fd());
    118   DCHECK(resources) << "Failed to get DRM resources";
    119   ScopedVector<HardwareDisplayControllerInfo> displays =
    120       GetAvailableDisplayControllerInfos(dri_->get_fd(), resources);
    121   drmModeFreeResources(resources);
    122 
    123   CHECK_NE(0u, displays.size());
    124 
    125   drmModePropertyRes* dpms =
    126       dri_->GetProperty(displays[0]->connector(), "DPMS");
    127   if (dpms)
    128     dri_->SetProperty(displays[0]->connector()->connector_id,
    129                       dpms->prop_id,
    130                       DRM_MODE_DPMS_ON);
    131 
    132   ConfigureDisplayController(displays[0]->crtc()->crtc_id,
    133                              displays[0]->connector()->connector_id,
    134                              displays[0]->connector()->modes[0]);
    135 }
    136 
    137 }  // namespace ui
    138