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.
5 #include "ui/ozone/platform/dri/screen_manager.h"
7 #include <xf86drmMode.h>
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"
18 ScreenManager::ScreenManager(
19 DriWrapper
* dri
, ScanoutSurfaceGenerator
* surface_generator
)
20 : dri_(dri
), surface_generator_(surface_generator
), last_added_widget_(0) {
23 ScreenManager::~ScreenManager() {
24 STLDeleteContainerPairSecondPointers(
25 controllers_
.begin(), controllers_
.end());
28 void ScreenManager::RemoveDisplayController(uint32_t crtc
, uint32_t connector
) {
29 HardwareDisplayControllerMap::iterator it
=
30 FindDisplayController(crtc
, connector
);
31 if (it
!= controllers_
.end()) {
33 controllers_
.erase(it
);
37 bool ScreenManager::ConfigureDisplayController(uint32_t crtc
,
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();
47 controller
= it
->second
;
48 controller
->UnbindSurfaceFromController();
51 if (it
== controllers_
.end()) {
52 controller
= new HardwareDisplayController(dri_
, connector
, crtc
);
53 controllers_
.insert(std::make_pair(++last_added_widget_
, controller
));
56 // Create a surface suitable for the current controller.
57 scoped_ptr
<ScanoutSurface
> surface(
58 surface_generator_
->Create(gfx::Size(mode
.hdisplay
, mode
.vdisplay
)));
60 if (!surface
->Initialize()) {
61 LOG(ERROR
) << "Failed to initialize surface";
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";
76 bool ScreenManager::DisableDisplayController(uint32_t crtc
,
78 HardwareDisplayControllerMap::iterator it
=
79 FindDisplayController(crtc
, connector
);
80 if (it
!= controllers_
.end()) {
81 it
->second
->Disable();
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();
96 HardwareDisplayControllerMap::iterator it
= controllers_
.find(widget
);
97 if (it
!= controllers_
.end())
98 return it
->second
->AsWeakPtr();
100 return base::WeakPtr
<HardwareDisplayController
>();
103 ScreenManager::HardwareDisplayControllerMap::iterator
104 ScreenManager::FindDisplayController(uint32_t crtc
, uint32_t connector
) {
105 for (HardwareDisplayControllerMap::iterator it
= controllers_
.begin();
106 it
!= controllers_
.end();
108 if (it
->second
->connector_id() == connector
&&
109 it
->second
->crtc_id() == crtc
)
113 return controllers_
.end();
116 void ScreenManager::ForceInitializationOfPrimaryDisplay() {
117 ScopedVector
<HardwareDisplayControllerInfo
> displays
=
118 GetAvailableDisplayControllerInfos(dri_
->get_fd());
120 CHECK_NE(0u, displays
.size());
122 drmModePropertyRes
* dpms
=
123 dri_
->GetProperty(displays
[0]->connector(), "DPMS");
125 dri_
->SetProperty(displays
[0]->connector()->connector_id
,
129 ConfigureDisplayController(displays
[0]->crtc()->crtc_id
,
130 displays
[0]->connector()->connector_id
,
131 displays
[0]->connector()->modes
[0]);