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 
32 namespace android {
33 
34 class Importer;
35 class Planner;
36 class SquashState;
37 
38 enum DrmCompositionType {
39   DRM_COMPOSITION_TYPE_EMPTY,
40   DRM_COMPOSITION_TYPE_FRAME,
41   DRM_COMPOSITION_TYPE_DPMS,
42   DRM_COMPOSITION_TYPE_MODESET,
43 };
44 
45 struct DrmCompositionRegion {
46   DrmHwcRect<int> frame;
47   std::vector<size_t> source_layers;
48 };
49 
50 class 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;
DrmCompositionPlane(Type type,DrmPlane * plane,DrmCrtc * crtc)62   DrmCompositionPlane(Type type, DrmPlane *plane, DrmCrtc *crtc)
63       : type_(type), plane_(plane), crtc_(crtc) {
64   }
DrmCompositionPlane(Type type,DrmPlane * plane,DrmCrtc * crtc,size_t source_layer)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 
type()73   Type type() const {
74     return type_;
75   }
76 
plane()77   DrmPlane *plane() const {
78     return plane_;
79   }
set_plane(DrmPlane * plane)80   void set_plane(DrmPlane *plane) {
81     plane_ = plane;
82   }
83 
crtc()84   DrmCrtc *crtc() const {
85     return crtc_;
86   }
87 
source_layers()88   std::vector<size_t> &source_layers() {
89     return source_layers_;
90   }
91 
source_layers()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 
103 class 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();
SignalSquashDone()124   int SignalSquashDone() {
125     return IncreaseTimelineToPoint(timeline_squash_done_);
126   }
SignalPreCompDone()127   int SignalPreCompDone() {
128     return IncreaseTimelineToPoint(timeline_pre_comp_done_);
129   }
SignalCompositionDone()130   int SignalCompositionDone() {
131     return IncreaseTimelineToPoint(timeline_);
132   }
133 
layers()134   std::vector<DrmHwcLayer> &layers() {
135     return layers_;
136   }
137 
squash_regions()138   std::vector<DrmCompositionRegion> &squash_regions() {
139     return squash_regions_;
140   }
141 
pre_comp_regions()142   std::vector<DrmCompositionRegion> &pre_comp_regions() {
143     return pre_comp_regions_;
144   }
145 
composition_planes()146   std::vector<DrmCompositionPlane> &composition_planes() {
147     return composition_planes_;
148   }
149 
geometry_changed()150   bool geometry_changed() const {
151     return geometry_changed_;
152   }
153 
frame_no()154   uint64_t frame_no() const {
155     return frame_no_;
156   }
157 
type()158   DrmCompositionType type() const {
159     return type_;
160   }
161 
dpms_mode()162   uint32_t dpms_mode() const {
163     return dpms_mode_;
164   }
165 
display_mode()166   const DrmMode &display_mode() const {
167     return display_mode_;
168   }
169 
crtc()170   DrmCrtc *crtc() const {
171     return crtc_;
172   }
173 
importer()174   Importer *importer() const {
175     return importer_;
176   }
177 
planner()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