aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-23 07:30:52 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-23 07:30:52 +0000
commit355dcd51e45591493252e3cf4e0384aefeba5884 (patch)
tree77cc667dea0ff19ee47aefb6147ee6da9daed298
parent8d005ef27262713be1e174b69e9e9be253de04bf (diff)
parent48c27f347ee4a34a84a7d39b1c63b422166834f1 (diff)
downloaddrm_hwcomposer-oreo-dr3-release.tar.gz
Change-Id: Ie9bab2a65b1d15ca8b5d401676b107e97e8a67c7
-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 4a3a957..d3e5d70 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>
@@ -199,6 +200,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>();
@@ -283,4 +285,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 678ccfa..3c1f49e 100644
--- a/platformnv.h
+++ b/platformnv.h
@@ -72,6 +72,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