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_PLATFORM_H_
18 #define ANDROID_DRM_PLATFORM_H_
19 
20 #include <hardware/hardware.h>
21 #include <hardware/hwcomposer.h>
22 
23 #include <map>
24 #include <vector>
25 
26 #include "compositor/DrmDisplayComposition.h"
27 #include "drmhwcomposer.h"
28 
29 namespace android {
30 
31 class DrmDevice;
32 
33 class Planner {
34  public:
35   class PlanStage {
36    public:
~PlanStage()37     virtual ~PlanStage() {
38     }
39 
40     virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
41                                 std::map<size_t, DrmHwcLayer *> &layers,
42                                 DrmCrtc *crtc,
43                                 std::vector<DrmPlane *> *planes) = 0;
44 
45    protected:
46     // Removes and returns the next available plane from planes
PopPlane(std::vector<DrmPlane * > * planes)47     static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
48       if (planes->empty())
49         return NULL;
50       DrmPlane *plane = planes->front();
51       planes->erase(planes->begin());
52       return plane;
53     }
54 
55     static int ValidatePlane(DrmPlane *plane, DrmHwcLayer *layer);
56 
57     // Inserts the given layer:plane in the composition at the back
Emplace(std::vector<DrmCompositionPlane> * composition,std::vector<DrmPlane * > * planes,DrmCompositionPlane::Type type,DrmCrtc * crtc,std::pair<size_t,DrmHwcLayer * > layer)58     static int Emplace(std::vector<DrmCompositionPlane> *composition,
59                        std::vector<DrmPlane *> *planes,
60                        DrmCompositionPlane::Type type, DrmCrtc *crtc,
61                        std::pair<size_t, DrmHwcLayer *> layer) {
62       DrmPlane *plane = PopPlane(planes);
63       std::vector<DrmPlane *> unused_planes;
64       int ret = -ENOENT;
65       while (plane) {
66         ret = ValidatePlane(plane, layer.second);
67         if (!ret)
68           break;
69         if (!plane->zpos_property().is_immutable())
70           unused_planes.push_back(plane);
71         plane = PopPlane(planes);
72       }
73 
74       if (!ret) {
75         composition->emplace_back(type, plane, crtc, layer.first);
76         planes->insert(planes->begin(), unused_planes.begin(),
77                        unused_planes.end());
78       }
79 
80       return ret;
81     }
82   };
83 
84   // Creates a planner instance with platform-specific planning stages
85   static std::unique_ptr<Planner> CreateInstance(DrmDevice *drm);
86 
87   // Takes a stack of layers and provisions hardware planes for them. If the
88   // entire stack can't fit in hardware, FIXME
89   //
90   // @layers: a map of index:layer of layers to composite
91   // @primary_planes: a vector of primary planes available for this frame
92   // @overlay_planes: a vector of overlay planes available for this frame
93   //
94   // Returns: A tuple with the status of the operation (0 for success) and
95   //          a vector of the resulting plan (ie: layer->plane mapping).
96   std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
97       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
98       std::vector<DrmPlane *> *primary_planes,
99       std::vector<DrmPlane *> *overlay_planes);
100 
101   template <typename T, typename... A>
AddStage(A &&...args)102   void AddStage(A &&... args) {
103     stages_.emplace_back(
104         std::unique_ptr<PlanStage>(new T(std::forward(args)...)));
105   }
106 
107  private:
108   std::vector<DrmPlane *> GetUsablePlanes(
109       DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
110       std::vector<DrmPlane *> *overlay_planes);
111 
112   std::vector<std::unique_ptr<PlanStage>> stages_;
113 };
114 
115 // This plan stage extracts all protected layers and places them on dedicated
116 // planes.
117 class PlanStageProtected : public Planner::PlanStage {
118  public:
119   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
120                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
121                       std::vector<DrmPlane *> *planes);
122 };
123 
124 // This plan stage places as many layers on dedicated planes as possible (first
125 // come first serve), and then sticks the rest in a precomposition plane (if
126 // needed).
127 class PlanStageGreedy : public Planner::PlanStage {
128  public:
129   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
130                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
131                       std::vector<DrmPlane *> *planes);
132 };
133 }  // namespace android
134 #endif
135