blob: 805fd2601589cb5da3ca60eae79e268a47f52f3a [file] [log] [blame]
Sean Paulb386f1b2015-05-13 06:33:23 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "hwc-drm-composition"
18
19#include "drmcomposition.h"
20#include "drmcrtc.h"
21#include "drmplane.h"
22#include "drmresources.h"
23
24#include <stdlib.h>
25
26#include <cutils/log.h>
27#include <sw_sync.h>
28#include <sync/sync.h>
29
30namespace android {
31
Sean Paulc51b0c52015-06-10 14:32:51 -040032static const bool kUseOverlayPlanes = true;
Sean Paulb386f1b2015-05-13 06:33:23 -070033
Sean Paul98e73c82015-06-24 14:38:49 -070034DrmComposition::DrmComposition(DrmResources *drm, Importer *importer)
35 : drm_(drm), importer_(importer) {
Sean Paulb386f1b2015-05-13 06:33:23 -070036 for (DrmResources::PlaneIter iter = drm_->begin_planes();
37 iter != drm_->end_planes(); ++iter) {
38 if ((*iter)->type() == DRM_PLANE_TYPE_PRIMARY)
39 primary_planes_.push_back(*iter);
40 else if (kUseOverlayPlanes && (*iter)->type() == DRM_PLANE_TYPE_OVERLAY)
41 overlay_planes_.push_back(*iter);
42 }
43}
44
45DrmComposition::~DrmComposition() {
Sean Paulb386f1b2015-05-13 06:33:23 -070046}
47
48int DrmComposition::Init() {
Sean Paul98e73c82015-06-24 14:38:49 -070049 for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
50 iter != drm_->end_connectors(); ++iter) {
51 int display = (*iter)->display();
52 composition_map_[display].reset(new DrmDisplayComposition());
53 if (!composition_map_[display]) {
54 ALOGE("Failed to allocate new display composition\n");
55 return -ENOMEM;
56 }
57 int ret = composition_map_[(*iter)->display()]->Init(drm_, importer_);
58 if (ret) {
59 ALOGE("Failed to init display composition for %d", (*iter)->display());
60 return ret;
61 }
Sean Paulb386f1b2015-05-13 06:33:23 -070062 }
Sean Paulb386f1b2015-05-13 06:33:23 -070063 return 0;
64}
65
66unsigned DrmComposition::GetRemainingLayers(int display,
67 unsigned num_needed) const {
68 DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
69 if (!crtc) {
Sean Paul98e73c82015-06-24 14:38:49 -070070 ALOGE("Failed to find crtc for display %d", display);
Sean Paulb386f1b2015-05-13 06:33:23 -070071 return 0;
72 }
73
74 unsigned num_planes = 0;
75 for (std::vector<DrmPlane *>::const_iterator iter = primary_planes_.begin();
76 iter != primary_planes_.end(); ++iter) {
77 if ((*iter)->GetCrtcSupported(*crtc))
78 ++num_planes;
79 }
Sean Paul9099aa52015-07-09 17:51:50 -040080 for (std::vector<DrmPlane *>::const_iterator iter = overlay_planes_.begin();
Sean Paulb386f1b2015-05-13 06:33:23 -070081 iter != overlay_planes_.end(); ++iter) {
82 if ((*iter)->GetCrtcSupported(*crtc))
83 ++num_planes;
84 }
85 return std::min(num_planes, num_needed);
86}
87
88int DrmComposition::AddLayer(int display, hwc_layer_1_t *layer,
89 hwc_drm_bo *bo) {
Sean Paulb386f1b2015-05-13 06:33:23 -070090 DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
91 if (!crtc) {
Sean Paul98e73c82015-06-24 14:38:49 -070092 ALOGE("Failed to find crtc for display %d", display);
Sean Paulb386f1b2015-05-13 06:33:23 -070093 return -ENODEV;
94 }
95
Sean Paul98e73c82015-06-24 14:38:49 -070096 // Find a plane for the layer
97 DrmPlane *plane = NULL;
Sean Paulb386f1b2015-05-13 06:33:23 -070098 for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
99 iter != primary_planes_.end(); ++iter) {
100 if ((*iter)->GetCrtcSupported(*crtc)) {
Sean Paul98e73c82015-06-24 14:38:49 -0700101 plane = *iter;
Sean Paulb386f1b2015-05-13 06:33:23 -0700102 primary_planes_.erase(iter);
103 break;
104 }
105 }
Sean Paul9099aa52015-07-09 17:51:50 -0400106 for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin();
Sean Paul98e73c82015-06-24 14:38:49 -0700107 !plane && iter != overlay_planes_.end(); ++iter) {
Sean Paulb386f1b2015-05-13 06:33:23 -0700108 if ((*iter)->GetCrtcSupported(*crtc)) {
Sean Paul98e73c82015-06-24 14:38:49 -0700109 plane = *iter;
Sean Paulb386f1b2015-05-13 06:33:23 -0700110 overlay_planes_.erase(iter);
111 break;
112 }
113 }
Sean Paul98e73c82015-06-24 14:38:49 -0700114 if (!plane) {
115 ALOGE("Failed to find plane for display %d", display);
Sean Paulb386f1b2015-05-13 06:33:23 -0700116 return -ENOENT;
117 }
Sean Paul98e73c82015-06-24 14:38:49 -0700118 return composition_map_[display]->AddLayer(layer, bo, crtc, plane);
Sean Paulb386f1b2015-05-13 06:33:23 -0700119}
120
Sean Pauldb7a17d2015-06-24 18:46:05 -0700121int DrmComposition::AddDpmsMode(int display, uint32_t dpms_mode) {
122 return composition_map_[display]->AddDpmsMode(dpms_mode);
123}
124
Sean Paul98e73c82015-06-24 14:38:49 -0700125std::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition(
126 int display) {
127 return std::move(composition_map_[display]);
Sean Paulb386f1b2015-05-13 06:33:23 -0700128}
Sean Paul2e46fbd2015-07-09 17:22:22 -0400129
130int DrmComposition::DisableUnusedPlanes() {
131 for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
132 iter != drm_->end_connectors(); ++iter) {
133 int display = (*iter)->display();
134 DrmDisplayComposition *comp = GetDisplayComposition(display);
135
136 /*
137 * Leave empty compositions alone
138 * TODO: re-visit this and potentially disable leftover planes after the
139 * active compositions have gobbled up all they can
140 */
141 if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY)
142 continue;
143
144 DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
145 if (!crtc) {
146 ALOGE("Failed to find crtc for display %d", display);
147 continue;
148 }
149
150 for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
151 iter != primary_planes_.end(); ++iter) {
152 if ((*iter)->GetCrtcSupported(*crtc)) {
153 comp->AddPlaneDisable(*iter);
154 primary_planes_.erase(iter);
155 break;
156 }
157 }
158 for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin();
159 iter != overlay_planes_.end();) {
160 if ((*iter)->GetCrtcSupported(*crtc)) {
161 comp->AddPlaneDisable(*iter);
162 iter = overlay_planes_.erase(iter);
163 } else {
164 iter++;
165 }
166 }
167 }
168 return 0;
169}
170
171DrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) {
172 return composition_map_[display].get();
173}
Sean Paulb386f1b2015-05-13 06:33:23 -0700174}