blob: e417bf785a2cbea8288d9973564fbbb3fae4fedd [file] [log] [blame]
Sean Paulda6270d2015-06-01 14:11:52 -04001/*
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
Sean Paul5d8acfc2016-04-21 16:26:27 -040017#ifndef ANDROID_DRM_PLATFORM_H_
18#define ANDROID_DRM_PLATFORM_H_
Sean Paulda6270d2015-06-01 14:11:52 -040019
Sean Paul4c4646e2016-05-10 04:19:24 -040020#include "drmdisplaycomposition.h"
Zach Reizner7642c922015-10-29 10:11:16 -070021#include "drmhwcomposer.h"
Sean Paulda6270d2015-06-01 14:11:52 -040022
23#include <hardware/hardware.h>
24#include <hardware/hwcomposer.h>
25
Sean Paul4c4646e2016-05-10 04:19:24 -040026#include <map>
27#include <vector>
28
Sean Paulda6270d2015-06-01 14:11:52 -040029namespace android {
30
31class DrmResources;
32
33class Importer {
34 public:
35 virtual ~Importer() {
36 }
37
38 // Creates a platform-specific importer instance
39 static Importer *CreateInstance(DrmResources *drm);
40
Rob Clark90f92d82016-10-19 10:48:14 -040041 // 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
Sean Paulda6270d2015-06-01 14:11:52 -040045 // 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};
Sean Paul4c4646e2016-05-10 04:19:24 -040057
58class 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.
152class 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
Adrian Salido45002322017-04-10 21:44:21 -0700159// 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).
164class 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
Sean Paul4c4646e2016-05-10 04:19:24 -0400171// 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).
174class 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};
Sean Paulda6270d2015-06-01 14:11:52 -0400180}
Sean Paulda6270d2015-06-01 14:11:52 -0400181#endif