diff --git a/Android.bp b/Android.bp index 8fbab72..ac0c7cf 100644 --- a/Android.bp +++ b/Android.bp @@ -48,7 +48,10 @@ cc_defaults { "libutils", ], - include_dirs: ["vendor/intel/external/drm-hwcomposer"], + include_dirs: [ + "vendor/intel/external/drm-hwcomposer", + "hardware/intel/external/minigbm-intel/cros_gralloc", + ], static_libs: ["libdrmhwc_utils"], diff --git a/backend/Backend.cpp b/backend/Backend.cpp index ba0518a..90aeeef 100644 --- a/backend/Backend.cpp +++ b/backend/Backend.cpp @@ -40,7 +40,6 @@ HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types, MarkValidated(layers, client_start, client_size); } else { std::tie(client_start, client_size) = GetClientLayers(display, layers); - MarkValidated(layers, client_start, client_size); bool testing_needed = !(client_start == 0 && client_size == layers.size()); @@ -49,10 +48,31 @@ HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types, if (testing_needed && display->CreateComposition(a_args) != HWC2::Error::None) { - ++display->total_stats().failed_kms_validate_; - client_start = 0; - client_size = layers.size(); - MarkValidated(layers, 0, client_size); + bool re_testing_needed = false; + uint32_t video_layer_number = 0; + uint32_t video_layer_order = 0; + for (size_t z_order = 0; z_order < layers.size(); ++z_order) { + if (layers[z_order]->IsVideoLayer()) { + video_layer_number++; + video_layer_order = z_order; + } + } + if (video_layer_number == 1 && + (video_layer_order == 0 || video_layer_order == layers.size() - 1)) { + for (size_t z_order = 0; z_order < layers.size(); ++z_order) { + if (layers[z_order]->GetValidatedType() == HWC2::Composition::Device && + !layers[z_order]->IsVideoLayer()) + layers[z_order]->SetValidatedType(HWC2::Composition::Client); + } + re_testing_needed = true; + } + if ((re_testing_needed && display->CreateComposition(a_args) != HWC2::Error::None) || + !re_testing_needed) { + ++display->total_stats().failed_kms_validate_; + client_start = 0; + client_size = layers.size(); + MarkValidated(layers, 0, client_size); + } } } @@ -86,7 +106,8 @@ bool Backend::IsClientLayer(HwcDisplay *display, HwcLayer *layer) { !layer->IsLayerUsableAsDevice() || display->color_transform_hint() != HAL_COLOR_TRANSFORM_IDENTITY || (layer->GetLayerData().pi.RequireScalingOrPhasing() && - display->GetHwc2()->GetResMan().ForcedScalingWithGpu()); + display->GetHwc2()->GetResMan().ForcedScalingWithGpu()) || + (!layer->IsVideoLayer() && !display->GetPipe().device->planes_enabling_); } bool Backend::HardwareSupportsLayerType(HWC2::Composition comp_type) { @@ -119,10 +140,16 @@ void Backend::MarkValidated(std::vector &layers, std::tuple Backend::GetExtraClientRange( HwcDisplay *display, const std::vector &layers, int client_start, size_t client_size) { - auto planes = display->GetPipe().GetUsablePlanes(); + uint32_t video_layer_number = 0; + for (size_t z_order = 0; z_order < layers.size(); ++z_order) { + if (layers[z_order]->IsVideoLayer()) + video_layer_number++; + } + auto planes = display->GetPipe().GetUsablePlanes(video_layer_number); + size_t avail_planes = planes.size(); - /* + /* * If more layers then planes, save one plane * for client composited layers */ diff --git a/compositor/DrmKmsPlan.cpp b/compositor/DrmKmsPlan.cpp index 6289b84..edaa564 100644 --- a/compositor/DrmKmsPlan.cpp +++ b/compositor/DrmKmsPlan.cpp @@ -24,11 +24,12 @@ namespace android { auto DrmKmsPlan::CreateDrmKmsPlan(DrmDisplayPipeline &pipe, - std::vector composition) + std::vector composition, + uint32_t video_layer_number) -> std::unique_ptr { auto plan = std::make_unique(); - auto avail_planes = pipe.GetUsablePlanes(); + auto avail_planes = pipe.GetUsablePlanes(video_layer_number); int z_pos = 0; for (auto &dhl : composition) { diff --git a/compositor/DrmKmsPlan.h b/compositor/DrmKmsPlan.h index 91f636e..091e37c 100644 --- a/compositor/DrmKmsPlan.h +++ b/compositor/DrmKmsPlan.h @@ -36,7 +36,8 @@ struct DrmKmsPlan { std::vector plan; static auto CreateDrmKmsPlan(DrmDisplayPipeline &pipe, - std::vector composition) + std::vector composition, + uint32_t video_layer_number) -> std::unique_ptr; }; diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp index 71cd740..dc6df98 100755 --- a/drm/DrmDevice.cpp +++ b/drm/DrmDevice.cpp @@ -163,13 +163,7 @@ auto DrmDevice::Init(const char *path) -> int { for (uint32_t i = 0; i < plane_res->count_planes; ++i) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) auto plane = DrmPlane::CreateInstance(*this, plane_res->planes[i]); - - if (!planes_enabling_) { - if (plane->GetType() == DRM_PLANE_TYPE_PRIMARY) - planes_.emplace_back(std::move(plane)); - } else { - planes_.emplace_back(std::move(plane)); - } + planes_.emplace_back(std::move(plane)); } return 0; diff --git a/drm/DrmDisplayPipeline.cpp b/drm/DrmDisplayPipeline.cpp index cee769f..f2e8526 100644 --- a/drm/DrmDisplayPipeline.cpp +++ b/drm/DrmDisplayPipeline.cpp @@ -168,15 +168,16 @@ static bool ReadUseOverlayProperty() { return strtol(use_overlay_planes_prop, nullptr, kStrtolBase) != 0; } -auto DrmDisplayPipeline::GetUsablePlanes() +auto DrmDisplayPipeline::GetUsablePlanes(uint32_t video_layer_number) -> std::vector>> { std::vector>> planes; planes.emplace_back(primary_plane); static bool use_overlay_planes = ReadUseOverlayProperty(); - if (use_overlay_planes) { int32_t planes_num = device->planes_num_ - 1; + if (!device->planes_enabling_) + planes_num = video_layer_number; for (const auto &plane : device->GetPlanes()) { if (plane->IsCrtcSupported(*crtc->Get())) { if (plane->GetType() == DRM_PLANE_TYPE_OVERLAY) { @@ -190,7 +191,6 @@ auto DrmDisplayPipeline::GetUsablePlanes() } } } - return planes; } diff --git a/drm/DrmDisplayPipeline.h b/drm/DrmDisplayPipeline.h index 9ec3e52..640ca82 100644 --- a/drm/DrmDisplayPipeline.h +++ b/drm/DrmDisplayPipeline.h @@ -72,7 +72,7 @@ struct DrmDisplayPipeline { static auto CreatePipeline(DrmConnector &connector) -> std::unique_ptr; - auto GetUsablePlanes() + auto GetUsablePlanes(uint32_t video_layer_number) -> std::vector>>; auto AtomicDisablePipeline() -> int; diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp index 5eb1f06..9887ae5 100644 --- a/hwc2_device/HwcDisplay.cpp +++ b/hwc2_device/HwcDisplay.cpp @@ -532,7 +532,10 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) { bool use_client_layer = false; uint32_t client_z_order = UINT32_MAX; std::map z_map; + uint32_t video_layer_number = 0; for (std::pair &l : layers_) { + if (l.second.IsVideoLayer()) + video_layer_number++; switch (l.second.GetValidatedType()) { case HWC2::Composition::Device: z_map.emplace(std::make_pair(l.second.GetZOrder(), &l.second)); @@ -578,7 +581,8 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) { * in between of ValidateDisplay() and PresentDisplay() calls */ current_plan_ = DrmKmsPlan::CreateDrmKmsPlan(GetPipe(), - std::move(composition_layers)); + std::move(composition_layers), + video_layer_number); if (!current_plan_) { if (!a_args.test_only) { ALOGE("Failed to create DrmKmsPlan"); diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp index 453af60..c33ab44 100644 --- a/hwc2_device/HwcLayer.cpp +++ b/hwc2_device/HwcLayer.cpp @@ -21,7 +21,7 @@ #include "HwcDisplay.h" #include "bufferinfo/BufferInfoGetter.h" #include "utils/log.h" - +#include "cros_gralloc_handle.h" namespace android { // NOLINTNEXTLINE(readability-convert-member-functions-to-static) @@ -60,6 +60,39 @@ HWC2::Error HwcLayer::SetLayerBuffer(buffer_handle_t buffer, return HWC2::Error::None; } +bool HwcLayer::IsVideoLayer() { + if (nullptr != buffer_handle_) { + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)(buffer_handle_); + if ((nullptr != gr_handle) && (IsSupportedMediaFormat(gr_handle->format))) + return true; + } + return false; +} + +bool HwcLayer::IsSupportedMediaFormat(uint32_t format) { + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV16: + case DRM_FORMAT_P010: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_AYUV: + case DRM_FORMAT_NV12_Y_TILED_INTEL: + case DRM_FORMAT_NV21: + case DRM_FORMAT_YVU420_ANDROID: + return true; + default: + break; + } + return false; +} + // NOLINTNEXTLINE(readability-convert-member-functions-to-static) HWC2::Error HwcLayer::SetLayerColor(hwc_color_t /*color*/) { // TODO(nobody): Put to client composition here? diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h index 17789b5..d42dd84 100644 --- a/hwc2_device/HwcLayer.h +++ b/hwc2_device/HwcLayer.h @@ -23,7 +23,8 @@ #include "compositor/LayerData.h" namespace android { - +#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') class HwcDisplay; class HwcLayer { @@ -62,6 +63,8 @@ class HwcLayer { return layer_data_; } + bool IsVideoLayer(); + // Layer hooks HWC2::Error SetCursorPosition(int32_t /*x*/, int32_t /*y*/); HWC2::Error SetLayerBlendMode(int32_t mode); @@ -122,7 +125,7 @@ class HwcLayer { void ImportFb(); bool bi_get_failed_{}; bool fb_import_failed_{}; - + bool IsSupportedMediaFormat(uint32_t format); /* SwapChain Cache */ public: void SwChainClearCache();