1/*
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#ifndef ANDROID_DRM_DISPLAY_COMPOSITION_H_
18#define ANDROID_DRM_DISPLAY_COMPOSITION_H_
19
20#include "drmcrtc.h"
21#include "drmhwcomposer.h"
22#include "drmplane.h"
23#include "glworker.h"
24
25#include <sstream>
26#include <vector>
27
28#include <hardware/gralloc.h>
29#include <hardware/hardware.h>
30#include <hardware/hwcomposer.h>
31
32namespace android {
33
34class Importer;
35class Planner;
36class SquashState;
37
38enum DrmCompositionType {
39  DRM_COMPOSITION_TYPE_EMPTY,
40  DRM_COMPOSITION_TYPE_FRAME,
41  DRM_COMPOSITION_TYPE_DPMS,
42  DRM_COMPOSITION_TYPE_MODESET,
43};
44
45struct DrmCompositionRegion {
46  DrmHwcRect<int> frame;
47  std::vector<size_t> source_layers;
48};
49
50class DrmCompositionPlane {
51 public:
52  enum class Type : int32_t {
53    kDisable,
54    kLayer,
55    kPrecomp,
56    kSquash,
57  };
58
59  DrmCompositionPlane() = default;
60  DrmCompositionPlane(DrmCompositionPlane &&rhs) = default;
61  DrmCompositionPlane &operator=(DrmCompositionPlane &&other) = default;
62  DrmCompositionPlane(Type type, DrmPlane *plane, DrmCrtc *crtc)
63      : type_(type), plane_(plane), crtc_(crtc) {
64  }
65  DrmCompositionPlane(Type type, DrmPlane *plane, DrmCrtc *crtc,
66                      size_t source_layer)
67      : type_(type),
68        plane_(plane),
69        crtc_(crtc),
70        source_layers_(1, source_layer) {
71  }
72
73  Type type() const {
74    return type_;
75  }
76
77  DrmPlane *plane() const {
78    return plane_;
79  }
80  void set_plane(DrmPlane *plane) {
81    plane_ = plane;
82  }
83
84  DrmCrtc *crtc() const {
85    return crtc_;
86  }
87
88  std::vector<size_t> &source_layers() {
89    return source_layers_;
90  }
91
92  const std::vector<size_t> &source_layers() const {
93    return source_layers_;
94  }
95
96 private:
97  Type type_ = Type::kDisable;
98  DrmPlane *plane_ = NULL;
99  DrmCrtc *crtc_ = NULL;
100  std::vector<size_t> source_layers_;
101};
102
103class DrmDisplayComposition {
104 public:
105  DrmDisplayComposition() = default;
106  DrmDisplayComposition(const DrmDisplayComposition &) = delete;
107  ~DrmDisplayComposition();
108
109  int Init(DrmResources *drm, DrmCrtc *crtc, Importer *importer,
110           Planner *planner, uint64_t frame_no);
111
112  int SetLayers(DrmHwcLayer *layers, size_t num_layers, bool geometry_changed);
113  int AddPlaneComposition(DrmCompositionPlane plane);
114  int AddPlaneDisable(DrmPlane *plane);
115  int SetDpmsMode(uint32_t dpms_mode);
116  int SetDisplayMode(const DrmMode &display_mode);
117
118  int Plan(SquashState *squash, std::vector<DrmPlane *> *primary_planes,
119           std::vector<DrmPlane *> *overlay_planes);
120
121  int FinalizeComposition();
122
123  int CreateNextTimelineFence();
124  int SignalSquashDone() {
125    return IncreaseTimelineToPoint(timeline_squash_done_);
126  }
127  int SignalPreCompDone() {
128    return IncreaseTimelineToPoint(timeline_pre_comp_done_);
129  }
130  int SignalCompositionDone() {
131    return IncreaseTimelineToPoint(timeline_);
132  }
133
134  std::vector<DrmHwcLayer> &layers() {
135    return layers_;
136  }
137
138  std::vector<DrmCompositionRegion> &squash_regions() {
139    return squash_regions_;
140  }
141
142  std::vector<DrmCompositionRegion> &pre_comp_regions() {
143    return pre_comp_regions_;
144  }
145
146  std::vector<DrmCompositionPlane> &composition_planes() {
147    return composition_planes_;
148  }
149
150  bool geometry_changed() const {
151    return geometry_changed_;
152  }
153
154  uint64_t frame_no() const {
155    return frame_no_;
156  }
157
158  DrmCompositionType type() const {
159    return type_;
160  }
161
162  uint32_t dpms_mode() const {
163    return dpms_mode_;
164  }
165
166  const DrmMode &display_mode() const {
167    return display_mode_;
168  }
169
170  DrmCrtc *crtc() const {
171    return crtc_;
172  }
173
174  Importer *importer() const {
175    return importer_;
176  }
177
178  Planner *planner() const {
179    return planner_;
180  }
181
182  void Dump(std::ostringstream *out) const;
183
184 private:
185  bool validate_composition_type(DrmCompositionType desired);
186
187  int IncreaseTimelineToPoint(int point);
188
189  int FinalizeComposition(DrmHwcRect<int> *exclude_rects,
190                          size_t num_exclude_rects);
191  void SeparateLayers(DrmHwcRect<int> *exclude_rects, size_t num_exclude_rects);
192  int CreateAndAssignReleaseFences();
193
194  DrmResources *drm_ = NULL;
195  DrmCrtc *crtc_ = NULL;
196  Importer *importer_ = NULL;
197  Planner *planner_ = NULL;
198
199  DrmCompositionType type_ = DRM_COMPOSITION_TYPE_EMPTY;
200  uint32_t dpms_mode_ = DRM_MODE_DPMS_ON;
201  DrmMode display_mode_;
202
203  int timeline_fd_ = -1;
204  int timeline_ = 0;
205  int timeline_current_ = 0;
206  int timeline_squash_done_ = 0;
207  int timeline_pre_comp_done_ = 0;
208
209  bool geometry_changed_;
210  std::vector<DrmHwcLayer> layers_;
211  std::vector<DrmCompositionRegion> squash_regions_;
212  std::vector<DrmCompositionRegion> pre_comp_regions_;
213  std::vector<DrmCompositionPlane> composition_planes_;
214
215  uint64_t frame_no_ = 0;
216};
217}
218
219#endif  // ANDROID_DRM_DISPLAY_COMPOSITION_H_
220