• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "drmdisplaycomposition.h"
21 #include "drmhwcomposer.h"
22 
23 #include <hardware/hardware.h>
24 #include <hardware/hwcomposer.h>
25 
26 #include <map>
27 #include <vector>
28 
29 namespace android {
30 
31 class DrmDevice;
32 
33 class Importer {
34  public:
~Importer()35   virtual ~Importer() {
36   }
37 
38   // Creates a platform-specific importer instance
39   static Importer *CreateInstance(DrmDevice *drm);
40 
41   // Imports the buffer referred to by handle into bo.
42   //
43   // Note: This can be called from a different thread than ReleaseBuffer. The
44   //       implementation is responsible for ensuring thread safety.
45   virtual int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
46 
47   // Releases the buffer object (ie: does the inverse of ImportBuffer)
48   //
49   // Note: This can be called from a different thread than ImportBuffer. The
50   //       implementation is responsible for ensuring thread safety.
51   virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
52 
53   // Checks if importer can import the buffer.
54   virtual bool CanImportBuffer(buffer_handle_t handle) = 0;
55 };
56 
57 class Planner {
58  public:
59   class PlanStage {
60    public:
~PlanStage()61     virtual ~PlanStage() {
62     }
63 
64     virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
65                                 std::map<size_t, DrmHwcLayer *> &layers,
66                                 DrmCrtc *crtc,
67                                 std::vector<DrmPlane *> *planes) = 0;
68 
69    protected:
70     // Removes and returns the next available plane from planes
PopPlane(std::vector<DrmPlane * > * planes)71     static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
72       if (planes->empty())
73         return NULL;
74       DrmPlane *plane = planes->front();
75       planes->erase(planes->begin());
76       return plane;
77     }
78 
79     static int ValidatePlane(DrmPlane *plane, DrmHwcLayer *layer);
80 
81     // 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)82     static int Emplace(std::vector<DrmCompositionPlane> *composition,
83                        std::vector<DrmPlane *> *planes,
84                        DrmCompositionPlane::Type type, DrmCrtc *crtc,
85                        std::pair<size_t, DrmHwcLayer *> layer) {
86       DrmPlane *plane = PopPlane(planes);
87       std::vector<DrmPlane *> unused_planes;
88       int ret = -ENOENT;
89       while (plane) {
90         ret = ValidatePlane(plane, layer.second);
91         if (!ret)
92           break;
93         if (!plane->zpos_property().is_immutable())
94           unused_planes.push_back(plane);
95         plane = PopPlane(planes);
96       }
97 
98       if (!ret) {
99         composition->emplace_back(type, plane, crtc, layer.first);
100         planes->insert(planes->begin(), unused_planes.begin(),
101                        unused_planes.end());
102       }
103 
104       return ret;
105     }
106   };
107 
108   // Creates a planner instance with platform-specific planning stages
109   static std::unique_ptr<Planner> CreateInstance(DrmDevice *drm);
110 
111   // Takes a stack of layers and provisions hardware planes for them. If the
112   // entire stack can't fit in hardware, FIXME
113   //
114   // @layers: a map of index:layer of layers to composite
115   // @primary_planes: a vector of primary planes available for this frame
116   // @overlay_planes: a vector of overlay planes available for this frame
117   //
118   // Returns: A tuple with the status of the operation (0 for success) and
119   //          a vector of the resulting plan (ie: layer->plane mapping).
120   std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
121       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
122       std::vector<DrmPlane *> *primary_planes,
123       std::vector<DrmPlane *> *overlay_planes);
124 
125   template <typename T, typename... A>
AddStage(A &&...args)126   void AddStage(A &&... args) {
127     stages_.emplace_back(
128         std::unique_ptr<PlanStage>(new T(std::forward(args)...)));
129   }
130 
131  private:
132   std::vector<DrmPlane *> GetUsablePlanes(
133       DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
134       std::vector<DrmPlane *> *overlay_planes);
135 
136   std::vector<std::unique_ptr<PlanStage>> stages_;
137 };
138 
139 // This plan stage extracts all protected layers and places them on dedicated
140 // planes.
141 class PlanStageProtected : public Planner::PlanStage {
142  public:
143   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
144                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
145                       std::vector<DrmPlane *> *planes);
146 };
147 
148 // This plan stage places as many layers on dedicated planes as possible (first
149 // come first serve), and then sticks the rest in a precomposition plane (if
150 // needed).
151 class PlanStageGreedy : public Planner::PlanStage {
152  public:
153   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
154                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
155                       std::vector<DrmPlane *> *planes);
156 };
157 }  // namespace android
158 #endif
159