summaryrefslogtreecommitdiff
path: root/platform.h
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2016-05-10 04:19:24 -0400
committerSean Paul <seanpaul@chromium.org>2016-05-16 17:04:44 -0400
commit4c4646e7b8a5cffdc8a2d53374b5340c07d14012 (patch)
tree51d19599c6bba8326ed6d30069e842dd87edcef5 /platform.h
parent4f4ef69e539c8f0c7352f12247b7551936736d04 (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.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/platform.h b/platform.h
index 059c40e..da6b7cb 100644
--- a/platform.h
+++ b/platform.h
@@ -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