From a949e0db79744c35ff8d6e880168a70c9aecae10 Mon Sep 17 00:00:00 2001 From: lihaihong Date: Fri, 16 Aug 2024 09:40:25 +0800 Subject: [PATCH] Dump video layer Signed-off-by: lihaihong --- Android.bp | 6 +- GrallocBufferHandler.cpp | 146 +++++++++++++++++++++++++++++++++++++++ GrallocBufferHandler.h | 47 +++++++++++++ backend/Backend.cpp | 24 ++++++- backend/Backend.h | 4 +- hwc2_device/HwcLayer.h | 2 +- 6 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 GrallocBufferHandler.cpp create mode 100644 GrallocBufferHandler.h diff --git a/Android.bp b/Android.bp index cb3ac78..a8ba19b 100644 --- a/Android.bp +++ b/Android.bp @@ -51,7 +51,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", + ], header_libs: [ "android.hardware.graphics.composer3-command-buffer", @@ -111,6 +114,7 @@ filegroup { "hwc2_device/HwcDisplayConfigs.cpp", "hwc2_device/HwcLayer.cpp", "hwc2_device/hwc2_device.cpp", + "GrallocBufferHandler.cpp", ], } diff --git a/GrallocBufferHandler.cpp b/GrallocBufferHandler.cpp new file mode 100644 index 0000000..f2b39d6 --- /dev/null +++ b/GrallocBufferHandler.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "GrallocBufferHandler.h" + +#include +#include +#include +#include +namespace android { + +Gralloc1BufferHandler::Gralloc1BufferHandler() + : gralloc_(nullptr), + device_(nullptr), + create_descriptor_(nullptr), + set_consumer_usage_(nullptr), + set_dimensions_(nullptr), + set_format_(nullptr), + set_producer_usage_(nullptr), + allocate_(nullptr) { +} + +Gralloc1BufferHandler::~Gralloc1BufferHandler() { + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + gralloc1_dvc->common.close(device_); +} + +bool Gralloc1BufferHandler::Init() { + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&gralloc_); + if (ret) { + ALOGE("Failed to get gralloc module"); + return false; + } + + ret = gralloc_->methods->open(gralloc_, GRALLOC_HARDWARE_MODULE_ID, &device_); + if (ret) { + ALOGE("Failed to open gralloc module"); + return false; + } + + gralloc1_device_t *gralloc1_dvc = reinterpret_cast(device_); + + create_descriptor_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_CREATE_DESCRIPTOR)); + set_consumer_usage_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_SET_CONSUMER_USAGE)); + set_dimensions_ = + reinterpret_cast(gralloc1_dvc->getFunction( + gralloc1_dvc, GRALLOC1_FUNCTION_SET_DIMENSIONS)); + set_format_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_SET_FORMAT)); + set_producer_usage_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, + GRALLOC1_FUNCTION_SET_PRODUCER_USAGE)); + allocate_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_ALLOCATE)); + lock_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_LOCK)); + unlock_ = reinterpret_cast( + gralloc1_dvc->getFunction(gralloc1_dvc, GRALLOC1_FUNCTION_UNLOCK)); + return true; +} + +bool Gralloc1BufferHandler::CreateBuffer(uint32_t w, uint32_t h,buffer_handle_t *handle) { + uint64_t gralloc1_buffer_descriptor_t; + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + + create_descriptor_(gralloc1_dvc, &gralloc1_buffer_descriptor_t); + uint32_t usage = 0; + set_format_(gralloc1_dvc, gralloc1_buffer_descriptor_t, HAL_PIXEL_FORMAT_RGBA_8888); + + usage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER | + GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET | + GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; + + + set_consumer_usage_(gralloc1_dvc, gralloc1_buffer_descriptor_t, usage); + set_producer_usage_(gralloc1_dvc, gralloc1_buffer_descriptor_t, usage); + set_dimensions_(gralloc1_dvc, gralloc1_buffer_descriptor_t, w, h); + allocate_(gralloc1_dvc, 1, &gralloc1_buffer_descriptor_t, handle); + + return true; +} + + +void *Gralloc1BufferHandler::Map(buffer_handle_t handle, uint32_t x, uint32_t y, + uint32_t width, uint32_t height, + uint32_t * /*stride*/, void **map_data, + size_t /*plane*/) { + auto gr_handle = (struct cros_gralloc_handle *)handle; + if (!gr_handle) { + ALOGE("could not find gralloc drm handle"); + return NULL; + } + + int acquireFence = -1; + gralloc1_rect_t rect{}; + rect.left = x; + rect.top = y; + rect.width = width; + rect.height = height; + + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + uint32_t status = lock_(gralloc1_dvc, handle, + GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, + GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN | GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, + &rect, + map_data, + acquireFence); + return (GRALLOC1_ERROR_NONE == status) ? *map_data : NULL; +} + +int32_t Gralloc1BufferHandler::UnMap(buffer_handle_t handle, + void * /*map_data*/) { + auto gr_handle = (struct cros_gralloc_handle *)handle; + if (!gr_handle) { + ALOGE("could not find gralloc drm handle"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + int releaseFence = 0; + gralloc1_device_t *gralloc1_dvc = + reinterpret_cast(device_); + return unlock_(gralloc1_dvc, handle, &releaseFence); +} + +} // namespace android diff --git a/GrallocBufferHandler.h b/GrallocBufferHandler.h new file mode 100644 index 0000000..54b0fe9 --- /dev/null +++ b/GrallocBufferHandler.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OS_ANDROID_Gralloc1BufferHandler_H_ +#define OS_ANDROID_Gralloc1BufferHandler_H_ +#include + +namespace android { + +class Gralloc1BufferHandler { + public: + explicit Gralloc1BufferHandler(); + ~Gralloc1BufferHandler(); + bool Init(); + bool CreateBuffer(uint32_t w, uint32_t h, buffer_handle_t *handle); + void *Map(buffer_handle_t handle, uint32_t x, uint32_t y, uint32_t width, + uint32_t height, uint32_t *stride, void **map_data, + size_t plane); + int32_t UnMap(buffer_handle_t handle, void *map_data); + private: + const hw_module_t *gralloc_; + hw_device_t *device_; + GRALLOC1_PFN_CREATE_DESCRIPTOR create_descriptor_; + GRALLOC1_PFN_SET_CONSUMER_USAGE set_consumer_usage_; + GRALLOC1_PFN_SET_DIMENSIONS set_dimensions_; + GRALLOC1_PFN_SET_FORMAT set_format_; + GRALLOC1_PFN_SET_PRODUCER_USAGE set_producer_usage_; + GRALLOC1_PFN_ALLOCATE allocate_; + GRALLOC1_PFN_LOCK lock_; + GRALLOC1_PFN_UNLOCK unlock_; +}; + +} // namespace android +#endif // OS_ANDROID_Gralloc1BufferHandler_H_ diff --git a/backend/Backend.cpp b/backend/Backend.cpp index b8deb17..8c76af8 100644 --- a/backend/Backend.cpp +++ b/backend/Backend.cpp @@ -21,7 +21,8 @@ #include #include "BackendManager.h" #include "bufferinfo/BufferInfoGetter.h" - +#include +#include namespace android { HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types, @@ -76,6 +77,27 @@ std::tuple Backend::GetClientLayers( size_t client_size = 0; for (size_t z_order = 0; z_order < layers.size(); ++z_order) { + static int count = 0; + void* data = 0; + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)layers[z_order]->GetBufferHandle(); + + if (gr_handle && gr_handle->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER && ++count == 3000 && + gralloc_handler_.Map(layers[z_order]->GetBufferHandle(), 0,0, + gr_handle->width, + gr_handle->height,0,&data,0)) { + char filename[64] = {0}; + sprintf(filename,"/data/local/traces/hdcp-%d-%d-%zd-%d.yuv",gr_handle->width, gr_handle->height, z_order, count); + FILE *p = fopen(filename, "wb+"); + if (p) { + fwrite(data, gr_handle->width * gr_handle->height * 1.5, 1, p); + fclose(p); + } else { + ALOGE("fopen %s fail", filename); + } + gralloc_handler_.UnMap(layers[z_order]->GetBufferHandle(), 0); + break; + } + if (IsClientLayer(display, layers[z_order])) { if (client_start < 0) client_start = (int)z_order; diff --git a/backend/Backend.h b/backend/Backend.h index 82b8fca..1c8db45 100644 --- a/backend/Backend.h +++ b/backend/Backend.h @@ -18,7 +18,7 @@ #define ANDROID_BACKEND_H #include "hwc2_device/DrmHwcTwo.h" - +#include "GrallocBufferHandler.h" namespace android { class Backend { @@ -29,6 +29,7 @@ class Backend { virtual std::tuple GetClientLayers( HwcDisplay *display, const std::vector &layers); virtual bool IsClientLayer(HwcDisplay *display, HwcLayer *layer); + Backend() {gralloc_handler_.Init();}; protected: static bool HardwareSupportsLayerType(HWC2::Composition comp_type); @@ -39,6 +40,7 @@ class Backend { static std::tuple GetExtraClientRange( HwcDisplay *display, const std::vector &layers, int client_start, size_t client_size); + Gralloc1BufferHandler gralloc_handler_; }; } // namespace android diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h index 17789b5..8e38301 100644 --- a/hwc2_device/HwcLayer.h +++ b/hwc2_device/HwcLayer.h @@ -117,7 +117,7 @@ class HwcLayer { bool IsLayerUsableAsDevice() const { return !bi_get_failed_ && !fb_import_failed_ && buffer_handle_ != nullptr; } - + buffer_handle_t GetBufferHandle() {return buffer_handle_;} private: void ImportFb(); bool bi_get_failed_{};