2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef ANDROID_DRM_PLATFORM_H_
18 #define ANDROID_DRM_PLATFORM_H_
20 #include "drmdisplaycomposition.h"
21 #include "drmhwcomposer.h"
23 #include <hardware/hardware.h>
24 #include <hardware/hwcomposer.h>
38 // Creates a platform-specific importer instance
39 static Importer *CreateInstance(DrmResources *drm);
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;
45 // Imports the buffer referred to by handle into bo.
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;
51 // Releases the buffer object (ie: does the inverse of ImportBuffer)
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;
62 virtual ~PlanStage() {
65 virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
66 std::map<size_t, DrmHwcLayer *> &layers,
68 std::vector<DrmPlane *> *planes) = 0;
71 // Removes and returns the next available plane from planes
72 static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
75 DrmPlane *plane = planes->front();
76 planes->erase(planes->begin());
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())
89 // Inserts the given layer:plane in the composition right before the precomp
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);
99 auto precomp = GetPrecompIter(composition);
100 composition->emplace(precomp, type, plane, crtc, source_layer);
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;
114 // Creates a planner instance with platform-specific planning stages
115 static std::unique_ptr<Planner> CreateInstance(DrmResources *drm);
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.
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
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);
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)...)));
143 std::vector<DrmPlane *> GetUsablePlanes(
144 DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
145 std::vector<DrmPlane *> *overlay_planes);
147 std::vector<std::unique_ptr<PlanStage>> stages_;
150 // This plan stage extracts all protected layers and places them on dedicated
152 class PlanStageProtected : public Planner::PlanStage {
154 int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
155 std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
156 std::vector<DrmPlane *> *planes);
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 {
166 int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
167 std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
168 std::vector<DrmPlane *> *planes);
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
174 class PlanStageGreedy : public Planner::PlanStage {
176 int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
177 std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
178 std::vector<DrmPlane *> *planes);