Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / ozone / platform / dri / screen_manager.cc
index f583c8c..6330387 100644 (file)
 
 namespace ui {
 
-ScreenManager::ScreenManager(
-    DriWrapper* dri, ScanoutBufferGenerator* buffer_generator)
-    : dri_(dri), buffer_generator_(buffer_generator), last_added_widget_(0) {
+ScreenManager::ScreenManager(DriWrapper* dri,
+                             ScanoutBufferGenerator* buffer_generator)
+    : dri_(dri), buffer_generator_(buffer_generator) {
 }
 
 ScreenManager::~ScreenManager() {
-  STLDeleteContainerPairSecondPointers(
-      controllers_.begin(), controllers_.end());
+}
+
+void ScreenManager::AddDisplayController(uint32_t crtc, uint32_t connector) {
+  HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
+  // TODO(dnicoara): Turn this into a DCHECK when async display configuration is
+  // properly supported. (When there can't be a race between forcing initial
+  // display configuration in ScreenManager and NativeDisplayDelegate creating
+  // the display controllers.)
+  if (it != controllers_.end()) {
+    LOG(WARNING) << "Display controller (crtc=" << crtc << ") already present.";
+    return;
+  }
+
+  controllers_.push_back(new HardwareDisplayController(
+      dri_, scoped_ptr<CrtcState>(new CrtcState(dri_, crtc, connector))));
 }
 
 void ScreenManager::RemoveDisplayController(uint32_t crtc) {
-  HardwareDisplayControllerMap::iterator it = FindDisplayController(crtc);
+  HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
   if (it != controllers_.end()) {
-    it->second->RemoveCrtc(crtc);
-    if (!it->second->HasCrtcs()) {
-      delete it->second;
+    bool is_mirrored = (*it)->IsMirrored();
+    (*it)->RemoveCrtc(crtc);
+    if (!is_mirrored)
       controllers_.erase(it);
-    }
   }
 }
 
@@ -41,94 +53,94 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
                                                uint32_t connector,
                                                const gfx::Point& origin,
                                                const drmModeModeInfo& mode) {
-  HardwareDisplayControllerMap::iterator it =
-      FindDisplayController(crtc);
-  HardwareDisplayController* controller = NULL;
-  if (it != controllers_.end()) {
-    // If nothing changed just enable the controller.
-    if (SameMode(mode, it->second->get_mode()) &&
-        origin == it->second->origin())
-      return it->second->Enable();
-
-    // Either the mode or the location of the display changed, so exit mirror
-    // mode and configure the display independently. If the caller still wants
-    // mirror mode, subsequent calls configuring the other controllers will
-    // restore mirror mode.
-    it->second->RemoveMirroredCrtcs();
-    HardwareDisplayControllerMap::iterator mirror =
-        FindDisplayControllerByOrigin(origin);
-    // Handle mirror mode.
-    if (mirror != controllers_.end() && it != mirror) {
-      DCHECK(SameMode(mode, mirror->second->get_mode()));
-      return HandleMirrorMode(it, mirror, crtc, connector);
-    }
-
-    controller = it->second;
-  } else {
-    HardwareDisplayControllerMap::iterator mirror =
-        FindDisplayControllerByOrigin(origin);
-    if (mirror != controllers_.end()) {
-      mirror->second->AddCrtc(scoped_ptr<CrtcState>(
-          new CrtcState(dri_, crtc, connector)));
-      return mirror->second->Enable();
-    }
+  gfx::Rect modeset_bounds(
+      origin.x(), origin.y(), mode.hdisplay, mode.vdisplay);
+  HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
+  DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc
+                                   << ") doesn't exist.";
+
+  HardwareDisplayController* controller = *it;
+  controller = *it;
+  // If nothing changed just enable the controller. Note, we perform an exact
+  // comparison on the mode since the refresh rate may have changed.
+  if (SameMode(mode, controller->get_mode()) &&
+      origin == controller->origin() && !controller->IsDisabled())
+    return controller->Enable();
+
+  // Either the mode or the location of the display changed, so exit mirror
+  // mode and configure the display independently. If the caller still wants
+  // mirror mode, subsequent calls configuring the other controllers will
+  // restore mirror mode.
+  if (controller->IsMirrored()) {
+    controller =
+        new HardwareDisplayController(dri_, controller->RemoveCrtc(crtc));
+    controllers_.push_back(controller);
+    it = controllers_.end() - 1;
   }
 
-  if (!controller) {
-    controller = new HardwareDisplayController(
-        dri_,
-        scoped_ptr<CrtcState>(new CrtcState(dri_, crtc, connector)));
-    controllers_.insert(std::make_pair(++last_added_widget_, controller));
-  }
+  HardwareDisplayControllers::iterator mirror =
+      FindActiveDisplayControllerByLocation(modeset_bounds);
+  // Handle mirror mode.
+  if (mirror != controllers_.end() && it != mirror)
+    return HandleMirrorMode(it, mirror, crtc, connector);
 
   return ModesetDisplayController(controller, origin, mode);
 }
 
 bool ScreenManager::DisableDisplayController(uint32_t crtc) {
-  HardwareDisplayControllerMap::iterator it = FindDisplayController(crtc);
+  HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
   if (it != controllers_.end()) {
-    it->second->Disable();
+    if ((*it)->IsMirrored()) {
+      HardwareDisplayController* controller =
+          new HardwareDisplayController(dri_, (*it)->RemoveCrtc(crtc));
+      controllers_.push_back(controller);
+    }
+
+    (*it)->Disable();
     return true;
   }
 
-  LOG(ERROR) << "Failed to find display controller"
-             << " crtc=" << crtc;
+  LOG(ERROR) << "Failed to find display controller crtc=" << crtc;
   return false;
 }
 
 base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
-    gfx::AcceleratedWidget widget) {
+    const gfx::Rect& bounds) {
   // TODO(dnicoara): Remove hack once TestScreen uses a simple Ozone display
   // configuration reader and ScreenManager is called from there to create the
   // one display needed by the content_shell target.
-  if (controllers_.empty() && last_added_widget_ == 0)
+  if (controllers_.empty())
     ForceInitializationOfPrimaryDisplay();
 
-  HardwareDisplayControllerMap::iterator it = controllers_.find(widget);
+  HardwareDisplayControllers::iterator it =
+      FindActiveDisplayControllerByLocation(bounds);
   if (it != controllers_.end())
-    return it->second->AsWeakPtr();
+    return (*it)->AsWeakPtr();
 
   return base::WeakPtr<HardwareDisplayController>();
 }
 
-ScreenManager::HardwareDisplayControllerMap::iterator
+ScreenManager::HardwareDisplayControllers::iterator
 ScreenManager::FindDisplayController(uint32_t crtc) {
-  for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
+  for (HardwareDisplayControllers::iterator it = controllers_.begin();
        it != controllers_.end();
        ++it) {
-    if (it->second->HasCrtc(crtc))
+    if ((*it)->HasCrtc(crtc))
       return it;
   }
 
   return controllers_.end();
 }
 
-ScreenManager::HardwareDisplayControllerMap::iterator
-ScreenManager::FindDisplayControllerByOrigin(const gfx::Point& origin) {
-  for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
+ScreenManager::HardwareDisplayControllers::iterator
+ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) {
+  for (HardwareDisplayControllers::iterator it = controllers_.begin();
        it != controllers_.end();
        ++it) {
-    if (it->second->origin() == origin)
+    gfx::Rect controller_bounds((*it)->origin(), (*it)->GetModeSize());
+    // We don't perform a strict check since content_shell will have windows
+    // smaller than the display size.
+    if (controller_bounds.Contains(bounds) && !(*it)->IsDisabled())
       return it;
   }
 
@@ -136,6 +148,7 @@ ScreenManager::FindDisplayControllerByOrigin(const gfx::Point& origin) {
 }
 
 void ScreenManager::ForceInitializationOfPrimaryDisplay() {
+  LOG(WARNING) << "Forcing initialization of primary display.";
   ScopedVector<HardwareDisplayControllerInfo> displays =
       GetAvailableDisplayControllerInfos(dri_->get_fd());
 
@@ -148,6 +161,8 @@ void ScreenManager::ForceInitializationOfPrimaryDisplay() {
                       dpms->prop_id,
                       DRM_MODE_DPMS_ON);
 
+  AddDisplayController(displays[0]->crtc()->crtc_id,
+                       displays[0]->connector()->connector_id);
   ConfigureDisplayController(displays[0]->crtc()->crtc_id,
                              displays[0]->connector()->connector_id,
                              gfx::Point(),
@@ -163,7 +178,7 @@ bool ScreenManager::ModesetDisplayController(
   scoped_refptr<ScanoutBuffer> buffer =
       buffer_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay));
 
-  if (!buffer) {
+  if (!buffer.get()) {
     LOG(ERROR) << "Failed to create scanout buffer";
     return false;
   }
@@ -177,13 +192,12 @@ bool ScreenManager::ModesetDisplayController(
 }
 
 bool ScreenManager::HandleMirrorMode(
-    HardwareDisplayControllerMap::iterator original,
-    HardwareDisplayControllerMap::iterator mirror,
+    HardwareDisplayControllers::iterator original,
+    HardwareDisplayControllers::iterator mirror,
     uint32_t crtc,
     uint32_t connector) {
-  mirror->second->AddCrtc(original->second->RemoveCrtc(crtc));
-  if (mirror->second->Enable()) {
-    delete original->second;
+  (*mirror)->AddCrtc((*original)->RemoveCrtc(crtc));
+  if ((*mirror)->Enable()) {
     controllers_.erase(original);
     return true;
   }
@@ -193,8 +207,8 @@ bool ScreenManager::HandleMirrorMode(
   // When things go wrong revert back to the previous configuration since
   // it is expected that the configuration would not have changed if
   // things fail.
-  original->second->AddCrtc(mirror->second->RemoveCrtc(crtc));
-  original->second->Enable();
+  (*original)->AddCrtc((*mirror)->RemoveCrtc(crtc));
+  (*original)->Enable();
   return false;
 }