OSDN Git Service

drm_hwcomposer: Move eglCreateImageKHR into Importer
[android-x86/external-drm_hwcomposer.git] / platform.h
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 DrmResources;
32
33 class Importer {
34  public:
35   virtual ~Importer() {
36   }
37
38   // Creates a platform-specific importer instance
39   static Importer *CreateInstance(DrmResources *drm);
40
41   // Imports EGLImage for glcompositor, since NV handles this in non-standard
42   // way, and fishing out the details is specific to the gralloc used.
43   virtual EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) = 0;
44
45   // Imports the buffer referred to by handle into bo.
46   //
47   // Note: This can be called from a different thread than ReleaseBuffer. The
48   //       implementation is responsible for ensuring thread safety.
49   virtual int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
50
51   // Releases the buffer object (ie: does the inverse of ImportBuffer)
52   //
53   // Note: This can be called from a different thread than ImportBuffer. The
54   //       implementation is responsible for ensuring thread safety.
55   virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
56 };
57
58 class Planner {
59  public:
60   class PlanStage {
61    public:
62     virtual ~PlanStage() {
63     }
64
65     virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
66                                 std::map<size_t, DrmHwcLayer *> &layers,
67                                 DrmCrtc *crtc,
68                                 std::vector<DrmPlane *> *planes) = 0;
69
70    protected:
71     // Removes and returns the next available plane from planes
72     static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
73       if (planes->empty())
74         return NULL;
75       DrmPlane *plane = planes->front();
76       planes->erase(planes->begin());
77       return plane;
78     }
79
80     // Finds and returns the squash layer from the composition
81     static DrmCompositionPlane *GetPrecomp(
82         std::vector<DrmCompositionPlane> *composition) {
83       auto l = GetPrecompIter(composition);
84       if (l == composition->end())
85         return NULL;
86       return &(*l);
87     }
88
89     // Inserts the given layer:plane in the composition right before the precomp
90     // layer
91     static int Emplace(std::vector<DrmCompositionPlane> *composition,
92                        std::vector<DrmPlane *> *planes,
93                        DrmCompositionPlane::Type type, DrmCrtc *crtc,
94                        size_t source_layer) {
95       DrmPlane *plane = PopPlane(planes);
96       if (!plane)
97         return -ENOENT;
98
99       auto precomp = GetPrecompIter(composition);
100       composition->emplace(precomp, type, plane, crtc, source_layer);
101       return 0;
102     }
103
104    private:
105     static std::vector<DrmCompositionPlane>::iterator GetPrecompIter(
106         std::vector<DrmCompositionPlane> *composition) {
107       return std::find_if(composition->begin(), composition->end(),
108                           [](const DrmCompositionPlane &p) {
109         return p.type() == DrmCompositionPlane::Type::kPrecomp;
110       });
111     }
112   };
113
114   // Creates a planner instance with platform-specific planning stages
115   static std::unique_ptr<Planner> CreateInstance(DrmResources *drm);
116
117   // Takes a stack of layers and provisions hardware planes for them. If the
118   // entire stack can't fit in hardware, the Planner may place the remaining
119   // layers in a PRECOMP plane. Layers in the PRECOMP plane will be composited
120   // using GL. PRECOMP planes should be placed above any 1:1 layer:plane
121   // compositions. If use_squash_fb is true, the Planner should try to reserve a
122   // plane at the highest z-order with type SQUASH.
123   //
124   // @layers: a map of index:layer of layers to composite
125   // @use_squash_fb: reserve a squash framebuffer
126   // @primary_planes: a vector of primary planes available for this frame
127   // @overlay_planes: a vector of overlay planes available for this frame
128   //
129   // Returns: A tuple with the status of the operation (0 for success) and
130   //          a vector of the resulting plan (ie: layer->plane mapping).
131   std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
132       std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb,
133       DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
134       std::vector<DrmPlane *> *overlay_planes);
135
136   template <typename T, typename... A>
137   void AddStage(A &&... args) {
138     stages_.emplace_back(
139         std::unique_ptr<PlanStage>(new T(std::forward(args)...)));
140   }
141
142  private:
143   std::vector<DrmPlane *> GetUsablePlanes(
144       DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
145       std::vector<DrmPlane *> *overlay_planes);
146
147   std::vector<std::unique_ptr<PlanStage>> stages_;
148 };
149
150 // This plan stage extracts all protected layers and places them on dedicated
151 // planes.
152 class PlanStageProtected : public Planner::PlanStage {
153  public:
154   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
155                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
156                       std::vector<DrmPlane *> *planes);
157 };
158
159 // This plan stage provisions the precomp plane with any remaining layers that
160 // are on top of the current precomp layers. This stage should be included in
161 // all platforms before loosely allocating layers (i.e. PlanStageGreedy) if
162 // any previous plan could have modified the precomp plane layers
163 // (ex. PlanStageProtected).
164 class PlanStagePrecomp : public Planner::PlanStage {
165  public:
166   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
167                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
168                       std::vector<DrmPlane *> *planes);
169 };
170
171 // This plan stage places as many layers on dedicated planes as possible (first
172 // come first serve), and then sticks the rest in a precomposition plane (if
173 // needed).
174 class PlanStageGreedy : public Planner::PlanStage {
175  public:
176   int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
177                       std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
178                       std::vector<DrmPlane *> *planes);
179 };
180 }
181 #endif