diff options
author | Sean Paul <seanpaul@chromium.org> | 2016-05-10 04:19:24 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-05-16 17:04:44 -0400 |
commit | 4c4646e7b8a5cffdc8a2d53374b5340c07d14012 (patch) | |
tree | 51d19599c6bba8326ed6d30069e842dd87edcef5 /platform.h | |
parent | 4f4ef69e539c8f0c7352f12247b7551936736d04 (diff) |
drm_hwcomposer: Introduce Planner interface
This patch introduces a new Planner interface to the platform specific
code. This new interface will allow for platform-specific plane provisioning
decisions to cover various hardware quirks.
Each platform must provide a Planner with one or more PlanStage steps. These
stages are run in order and are used to move the given layers onto composition
planes.
There are two generic stages provided by the platform:
- Protected: Places layers on dedicated planes
- Greedy: Provisions as many layers to planes and sticks the rest in precomp
There is also one platform-specific stage included:
- ProtectedRotated: Places any protected & rotated layer on the primary plane
BUG=b/28117135
TEST=Tested on ryu with a variety of window layouts
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Change-Id: Ib6062ab4779166753afaf122450bb63126bf9161
Diffstat (limited to 'platform.h')
-rw-r--r-- | platform.h | 115 |
1 files changed, 115 insertions, 0 deletions
@@ -17,11 +17,15 @@ #ifndef ANDROID_DRM_PLATFORM_H_ #define ANDROID_DRM_PLATFORM_H_ +#include "drmdisplaycomposition.h" #include "drmhwcomposer.h" #include <hardware/hardware.h> #include <hardware/hwcomposer.h> +#include <map> +#include <vector> + namespace android { class DrmResources; @@ -46,5 +50,116 @@ class Importer { // implementation is responsible for ensuring thread safety. virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0; }; + +class Planner { + public: + class PlanStage { + public: + virtual ~PlanStage() { + } + + virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition, + std::map<size_t, DrmHwcLayer *> &layers, + DrmCrtc *crtc, + std::vector<DrmPlane *> *planes) = 0; + + protected: + // Removes and returns the next available plane from planes + static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) { + if (planes->empty()) + return NULL; + DrmPlane *plane = planes->front(); + planes->erase(planes->begin()); + return plane; + } + + // Finds and returns the squash layer from the composition + static DrmCompositionPlane *GetPrecomp( + std::vector<DrmCompositionPlane> *composition) { + auto l = GetPrecompIter(composition); + if (l == composition->end()) + return NULL; + return &(*l); + } + + // Inserts the given layer:plane in the composition right before the precomp + // layer + static int Emplace(std::vector<DrmCompositionPlane> *composition, + std::vector<DrmPlane *> *planes, + DrmCompositionPlane::Type type, DrmCrtc *crtc, + size_t source_layer) { + DrmPlane *plane = PopPlane(planes); + if (!plane) + return -ENOENT; + + auto precomp = GetPrecompIter(composition); + composition->emplace(precomp, type, plane, crtc, source_layer); + return 0; + } + + private: + static std::vector<DrmCompositionPlane>::iterator GetPrecompIter( + std::vector<DrmCompositionPlane> *composition) { + return std::find_if(composition->begin(), composition->end(), + [](const DrmCompositionPlane &p) { + return p.type() == DrmCompositionPlane::Type::kPrecomp; + }); + } + }; + + // Creates a planner instance with platform-specific planning stages + static std::unique_ptr<Planner> CreateInstance(DrmResources *drm); + + // Takes a stack of layers and provisions hardware planes for them. If the + // entire stack can't fit in hardware, the Planner may place the remaining + // layers in a PRECOMP plane. Layers in the PRECOMP plane will be composited + // using GL. PRECOMP planes should be placed above any 1:1 layer:plane + // compositions. If use_squash_fb is true, the Planner should try to reserve a + // plane at the highest z-order with type SQUASH. + // + // @layers: a map of index:layer of layers to composite + // @use_squash_fb: reserve a squash framebuffer + // @primary_planes: a vector of primary planes available for this frame + // @overlay_planes: a vector of overlay planes available for this frame + // + // Returns: A tuple with the status of the operation (0 for success) and + // a vector of the resulting plan (ie: layer->plane mapping). + std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes( + std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb, + DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes, + std::vector<DrmPlane *> *overlay_planes); + + template <typename T, typename... A> + void AddStage(A &&... args) { + stages_.emplace_back( + std::unique_ptr<PlanStage>(new T(std::forward(args)...))); + } + + private: + std::vector<DrmPlane *> GetUsablePlanes( + DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes, + std::vector<DrmPlane *> *overlay_planes); + + std::vector<std::unique_ptr<PlanStage>> stages_; +}; + +// This plan stage extracts all protected layers and places them on dedicated +// planes. +class PlanStageProtected : public Planner::PlanStage { + public: + int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition, + std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, + std::vector<DrmPlane *> *planes); +}; + +// This plan stage places as many layers on dedicated planes as possible (first +// come first serve), and then sticks the rest in a precomposition plane (if +// needed). +class PlanStageGreedy : public Planner::PlanStage { + public: + int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition, + std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc, + std::vector<DrmPlane *> *planes); +}; } #endif |