aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-20 23:54:53 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-20 23:54:53 +0000
commitdea16c4bd3a81c2ead77d9b9552841b7fe3c52f9 (patch)
tree9b86dc78451a2f172588c4db120afb2c49908d63
parentf855ecf217ef686e2bda6a8208faff4635a26cd5 (diff)
parentd7aa8adad5e96a0a849678a3edf873244b9db2eb (diff)
downloaddrm_hwcomposer-oreo-r3-release.tar.gz
Change-Id: Ie7ce56fc2915e78fca4f280f533154e74fc786fd
-rw-r--r--platformnv.cpp69
-rw-r--r--platformnv.h13
2 files changed, 82 insertions, 0 deletions
diff --git a/platformnv.cpp b/platformnv.cpp
index 084d4f0..9ea1467 100644
--- a/platformnv.cpp
+++ b/platformnv.cpp
@@ -22,6 +22,7 @@
#include <cinttypes>
#include <stdatomic.h>
+#include <drm/drm_fourcc.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -188,6 +189,7 @@ int NvImporter::GrallocSetNvBuffer(buffer_handle_t handle, NvBuffer_t *buf) {
// static
std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) {
std::unique_ptr<Planner> planner(new Planner);
+ planner->AddStage<PlanStageNvLimits>();
planner->AddStage<PlanStageProtectedRotated>();
planner->AddStage<PlanStageProtected>();
planner->AddStage<PlanStagePrecomp>();
@@ -272,4 +274,71 @@ int PlanStageProtectedRotated::ProvisionPlanes(
}
return 0;
}
+
+bool PlanStageNvLimits::CheckLayer(DrmHwcLayer *layer) {
+ auto src_w = layer->source_crop.width();
+ auto src_h = layer->source_crop.height();
+ auto dst_w = layer->display_frame.width();
+ auto dst_h = layer->display_frame.height();
+ int h_limit = 4;
+ int v_limit;
+
+ switch (layer->buffer->format) {
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_BGR565:
+ v_limit = 4;
+ break;
+ default:
+ v_limit = 2;
+ break;
+ }
+
+ if (layer->transform &
+ (DrmHwcTransform::kRotate90 | DrmHwcTransform::kRotate270))
+ std::swap(dst_w, dst_h);
+
+ // check for max supported down scaling
+ if (((src_w / dst_w) > h_limit) || ((src_h / dst_h) > v_limit))
+ return false;
+
+ return true;
+}
+
+int PlanStageNvLimits::ProvisionPlanes(
+ std::vector<DrmCompositionPlane> *composition,
+ std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
+ std::vector<DrmPlane *> *planes) {
+ int ret;
+
+ for (auto i = layers.begin(); i != layers.end();) {
+ // Skip layer if supported
+ if (CheckLayer(i->second)) {
+ i++;
+ continue;
+ }
+
+ if (i->second->protected_usage()) {
+ // Drop the layer if unsupported and protected, this will just display
+ // black in the area of this layer but it's better than failing miserably
+ i = layers.erase(i);
+ continue;
+ }
+
+ // If there's no precomp layer already queued, queue one now.
+ DrmCompositionPlane *precomp = GetPrecomp(composition);
+ if (precomp) {
+ precomp->source_layers().emplace_back(i->first);
+ } else if (!planes->empty()) {
+ DrmPlane *precomp_plane = planes->back();
+ planes->pop_back();
+ composition->emplace_back(DrmCompositionPlane::Type::kPrecomp,
+ precomp_plane, crtc, i->first);
+ } else {
+ ALOGE("Not enough planes to reserve for precomp fb");
+ }
+ i = layers.erase(i);
+ }
+
+ return 0;
+}
}
diff --git a/platformnv.h b/platformnv.h
index a9e5d39..df2a242 100644
--- a/platformnv.h
+++ b/platformnv.h
@@ -71,6 +71,19 @@ class PlanStageProtectedRotated : public Planner::PlanStage {
std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
std::vector<DrmPlane *> *planes);
};
+
+// This stage looks for layers that would not be supported by Tegra driver due
+// to limitations such as downscaling. If the layer is unprotected it will be
+// punted for precomp to handle, other wise if protected it will be dropped as
+// it cannot be supported by any means.
+class PlanStageNvLimits : public Planner::PlanStage {
+ public:
+ int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
+ std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
+ std::vector<DrmPlane *> *planes);
+ protected:
+ bool CheckLayer(DrmHwcLayer *layer);
+};
}
#endif