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