summaryrefslogtreecommitdiffstats
path: root/chromium/ui/ozone/platform/dri/screen_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/ozone/platform/dri/screen_manager.cc')
-rw-r--r--chromium/ui/ozone/platform/dri/screen_manager.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/chromium/ui/ozone/platform/dri/screen_manager.cc b/chromium/ui/ozone/platform/dri/screen_manager.cc
new file mode 100644
index 00000000000..3c1655c77d2
--- /dev/null
+++ b/chromium/ui/ozone/platform/dri/screen_manager.cc
@@ -0,0 +1,137 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/dri/screen_manager.h"
+
+#include <xf86drmMode.h>
+
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/ozone/platform/dri/dri_util.h"
+#include "ui/ozone/platform/dri/hardware_display_controller.h"
+#include "ui/ozone/platform/dri/scanout_surface.h"
+
+namespace ui {
+
+ScreenManager::ScreenManager(
+ DriWrapper* dri, ScanoutSurfaceGenerator* surface_generator)
+ : dri_(dri), surface_generator_(surface_generator), last_added_widget_(0) {
+}
+
+ScreenManager::~ScreenManager() {
+ STLDeleteContainerPairSecondPointers(
+ controllers_.begin(), controllers_.end());
+}
+
+void ScreenManager::RemoveDisplayController(uint32_t crtc, uint32_t connector) {
+ HardwareDisplayControllerMap::iterator it =
+ FindDisplayController(crtc, connector);
+ if (it != controllers_.end()) {
+ delete it->second;
+ controllers_.erase(it);
+ }
+}
+
+bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
+ uint32_t connector,
+ const drmModeModeInfo& mode) {
+ HardwareDisplayControllerMap::iterator it =
+ FindDisplayController(crtc, connector);
+ HardwareDisplayController* controller = NULL;
+ if (it != controllers_.end()) {
+ if (SameMode(mode, it->second->get_mode()))
+ return it->second->Enable();
+
+ controller = it->second;
+ controller->UnbindSurfaceFromController();
+ }
+
+ if (it == controllers_.end()) {
+ controller = new HardwareDisplayController(dri_, connector, crtc);
+ controllers_.insert(std::make_pair(++last_added_widget_, controller));
+ }
+
+ // Create a surface suitable for the current controller.
+ scoped_ptr<ScanoutSurface> surface(
+ surface_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay)));
+
+ if (!surface->Initialize()) {
+ LOG(ERROR) << "Failed to initialize surface";
+ return false;
+ }
+
+ // Bind the surface to the controller. This will register the backing buffers
+ // with the hardware CRTC such that we can show the buffers and performs the
+ // initial modeset. The controller takes ownership of the surface.
+ if (!controller->BindSurfaceToController(surface.Pass(), mode)) {
+ LOG(ERROR) << "Failed to bind surface to controller";
+ return false;
+ }
+
+ return true;
+}
+
+bool ScreenManager::DisableDisplayController(uint32_t crtc,
+ uint32_t connector) {
+ HardwareDisplayControllerMap::iterator it =
+ FindDisplayController(crtc, connector);
+ if (it != controllers_.end()) {
+ it->second->Disable();
+ return true;
+ }
+
+ return false;
+}
+
+base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
+ gfx::AcceleratedWidget widget) {
+ // 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)
+ ForceInitializationOfPrimaryDisplay();
+
+ HardwareDisplayControllerMap::iterator it = controllers_.find(widget);
+ if (it != controllers_.end())
+ return it->second->AsWeakPtr();
+
+ return base::WeakPtr<HardwareDisplayController>();
+}
+
+ScreenManager::HardwareDisplayControllerMap::iterator
+ScreenManager::FindDisplayController(uint32_t crtc, uint32_t connector) {
+ for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
+ it != controllers_.end();
+ ++it) {
+ if (it->second->connector_id() == connector &&
+ it->second->crtc_id() == crtc)
+ return it;
+ }
+
+ return controllers_.end();
+}
+
+void ScreenManager::ForceInitializationOfPrimaryDisplay() {
+ drmModeRes* resources = drmModeGetResources(dri_->get_fd());
+ DCHECK(resources) << "Failed to get DRM resources";
+ ScopedVector<HardwareDisplayControllerInfo> displays =
+ GetAvailableDisplayControllerInfos(dri_->get_fd(), resources);
+ drmModeFreeResources(resources);
+
+ CHECK_NE(0u, displays.size());
+
+ drmModePropertyRes* dpms =
+ dri_->GetProperty(displays[0]->connector(), "DPMS");
+ if (dpms)
+ dri_->SetProperty(displays[0]->connector()->connector_id,
+ dpms->prop_id,
+ DRM_MODE_DPMS_ON);
+
+ ConfigureDisplayController(displays[0]->crtc()->crtc_id,
+ displays[0]->connector()->connector_id,
+ displays[0]->connector()->modes[0]);
+}
+
+} // namespace ui