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