diff --git a/Android.bp b/Android.bp index cb3ac78c..9b662a02 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", @@ -140,6 +143,7 @@ cc_library_shared { ], cppflags: [ "-DHEADLESS_RESOLUTION_2560_1600", + "-DHWC_DUMP_BUFFER", ], } diff --git a/backend/Backend.cpp b/backend/Backend.cpp index b8deb17a..e1ce3cec 100644 --- a/backend/Backend.cpp +++ b/backend/Backend.cpp @@ -21,7 +21,10 @@ #include #include "BackendManager.h" #include "bufferinfo/BufferInfoGetter.h" - +#ifdef HWC_DUMP_BUFFER +#include "bufferinfo/legacy/BufferInfoMinigbm.h" +#include "utils/properties.h" +#endif namespace android { HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types, @@ -35,6 +38,15 @@ HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types, if ((uint32_t)l->GetSfType() == (uint32_t)aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION) return HWC2::Error::Unsupported; } + +#ifdef HWC_DUMP_BUFFER + char status[PROPERTY_VALUE_MAX] = {0}; + property_get("drm.dumpbuffer.on", status, "1"); + for (size_t z_order = 0; z_order < layers.size(); ++z_order) { + if (status[0] != '0') + BufferInfoMinigbm::DumpBuffer(display->GetPipe().device, layers[z_order]->GetBufferHandle(), z_order); + } +#endif int client_start = -1; size_t client_size = 0; diff --git a/bufferinfo/legacy/BufferInfoMinigbm.cpp b/bufferinfo/legacy/BufferInfoMinigbm.cpp index c5a9e98b..d43a5e9e 100644 --- a/bufferinfo/legacy/BufferInfoMinigbm.cpp +++ b/bufferinfo/legacy/BufferInfoMinigbm.cpp @@ -25,6 +25,8 @@ #include #include "utils/log.h" +#include +#include namespace android { LEGACY_BUFFER_INFO_GETTER(BufferInfoMinigbm); @@ -122,4 +124,91 @@ int BufferInfoMinigbm::ValidateGralloc() { return 0; } +void BufferInfoMinigbm::InitializeGralloc1(DrmDevice *drmDevice) { + hw_device_t *device; + + struct dri2_drm_display *dri_drm = (struct dri2_drm_display *)calloc(1, sizeof(*dri_drm)); + if (!dri_drm) + return; + + dri_drm->fd = -1; + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&dri_drm->gralloc); + if (ret) { + return; + } + + dri_drm->gralloc_version = dri_drm->gralloc->common.module_api_version; + if (dri_drm->gralloc_version == HARDWARE_MODULE_API_VERSION(1, 0)) { + ret = dri_drm->gralloc->common.methods->open(&dri_drm->gralloc->common, GRALLOC_HARDWARE_MODULE_ID, &device); + if (ret) { + ALOGE("Failed to open device"); + return; + } else { + ALOGE("success to open device, Initialize"); + dri_drm->gralloc1_dvc = (gralloc1_device_t *)device; + dri_drm->pfn_lock = (GRALLOC1_PFN_LOCK)dri_drm->gralloc1_dvc->getFunction(dri_drm->gralloc1_dvc, GRALLOC1_FUNCTION_LOCK); + dri_drm->pfn_importBuffer = (GRALLOC1_PFN_IMPORT_BUFFER)dri_drm->gralloc1_dvc->getFunction(dri_drm->gralloc1_dvc, GRALLOC1_FUNCTION_IMPORT_BUFFER); + dri_drm->pfn_release = (GRALLOC1_PFN_RELEASE)dri_drm->gralloc1_dvc->getFunction(dri_drm->gralloc1_dvc, GRALLOC1_FUNCTION_RELEASE); + dri_drm->pfn_unlock = (GRALLOC1_PFN_UNLOCK)dri_drm->gralloc1_dvc->getFunction(dri_drm->gralloc1_dvc, GRALLOC1_FUNCTION_UNLOCK); + dri_drm->pfn_get_stride = (GRALLOC1_PFN_GET_STRIDE)dri_drm->gralloc1_dvc->getFunction(dri_drm->gralloc1_dvc, GRALLOC1_FUNCTION_GET_STRIDE); + drmDevice->dri_drm_ = (void *)dri_drm; + } + } + return; +} + +void BufferInfoMinigbm::DumpBuffer(DrmDevice *drmDevice, buffer_handle_t handle, int z_order) { + if (NULL == handle) + return; + char dump_file[256] = {0}; + buffer_handle_t handle_copy; + uint8_t* pixels = nullptr; + cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle; + gralloc1_rect_t accessRegion = {0, 0, (int32_t)gr_handle->width, (int32_t)gr_handle->height};; + + struct dri2_drm_display *dri_drm = (struct dri2_drm_display *)drmDevice->dri_drm_; + + assert (dri_drm == nullptr || + dri_drm->pfn_importBuffer == nullptr || + dri_drm->pfn_lock == nullptr || + dri_drm->pfn_unlock == nullptr || + dri_drm->pfn_release == nullptr || + dri_drm->pfn_get_stride); + + int ret = dri_drm->pfn_importBuffer(dri_drm->gralloc1_dvc, handle, &handle_copy); + if (ret) { + ALOGE("Gralloc importBuffer failed"); + return; + } + ret = dri_drm->pfn_lock(dri_drm->gralloc1_dvc, handle_copy, + GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_NEVER, + &accessRegion, reinterpret_cast(&pixels), 0); + if (ret) { + ALOGE("gralloc->lock failed: %d", ret); + return; + } else { + char ctime[32]; + time_t t = time(0); + static int i = 0; + strftime(ctime, sizeof(ctime), "%Y-%m-%d", localtime(&t)); + sprintf(dump_file, "/data/local/traces/dump_%d_%dx%d_%s_%d", z_order, gr_handle->width, gr_handle->height, ctime,i++); + int file_fd = 0; + file_fd = open(dump_file, O_RDWR|O_CREAT, 0666); + if (file_fd == -1) { + ALOGE("Failed to open %s while dumping", dump_file); + } else { + size_t size = 0; + if (gr_handle->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) + size = gr_handle->width * gr_handle->height * 1.5; + else + size = gr_handle->width * gr_handle->height * 4; + write(file_fd, pixels, size); + close(file_fd); + } + int outReleaseFence = 0; + dri_drm->pfn_unlock(dri_drm->gralloc1_dvc, handle_copy, &outReleaseFence); + dri_drm->pfn_release(dri_drm->gralloc1_dvc, handle_copy); + } +} } // namespace android diff --git a/bufferinfo/legacy/BufferInfoMinigbm.h b/bufferinfo/legacy/BufferInfoMinigbm.h index 40d99261..de5a1542 100644 --- a/bufferinfo/legacy/BufferInfoMinigbm.h +++ b/bufferinfo/legacy/BufferInfoMinigbm.h @@ -18,9 +18,33 @@ #define BUFFERINFOMINIGBM_H_ #include - +#include #include "bufferinfo/BufferInfoGetter.h" +#define DRV_MAX_PLANES 4 +#define DRV_MAX_FDS (DRV_MAX_PLANES + 1) + +enum INITIALIZE_ERROR{ + INITIALIZE_CALLOC_ERROR = 1, + INITIALIZE_GET_MODULE_ERROR, + INITIALIZE_OPEN_DEVICE_ERROR, + INITIALIZE_NONE = 0, +}; + +struct dri2_drm_display +{ + int fd; + const gralloc_module_t *gralloc; + uint16_t gralloc_version; + gralloc1_device_t *gralloc1_dvc; + GRALLOC1_PFN_LOCK pfn_lock; + GRALLOC1_PFN_GET_FORMAT pfn_getFormat; + GRALLOC1_PFN_UNLOCK pfn_unlock; + GRALLOC1_PFN_IMPORT_BUFFER pfn_importBuffer; + GRALLOC1_PFN_RELEASE pfn_release; + GRALLOC1_PFN_GET_STRIDE pfn_get_stride; +}; + namespace android { class BufferInfoMinigbm : public LegacyBufferInfoGetter { @@ -28,6 +52,8 @@ class BufferInfoMinigbm : public LegacyBufferInfoGetter { using LegacyBufferInfoGetter::LegacyBufferInfoGetter; auto GetBoInfo(buffer_handle_t handle) -> std::optional override; int ValidateGralloc() override; + static void InitializeGralloc1(DrmDevice *drmDevice); + static void DumpBuffer(DrmDevice *drmDevice, buffer_handle_t handle, int z_order); }; } // namespace android diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h index 4208ab23..c834a5ba 100644 --- a/drm/DrmDevice.h +++ b/drm/DrmDevice.h @@ -136,6 +136,7 @@ class DrmDevice { bool planes_enabling_; uint32_t planes_num_; bool color_adjustment_enabling_; + void *dri_drm_; }; } // namespace android diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp index 6a250e85..8525aaa3 100644 --- a/hwc2_device/HwcDisplay.cpp +++ b/hwc2_device/HwcDisplay.cpp @@ -27,7 +27,9 @@ #include "utils/properties.h" #include #include - +#ifdef HWC_DUMP_BUFFER +#include "bufferinfo/legacy/BufferInfoMinigbm.h" +#endif namespace android { std::string HwcDisplay::DumpDelta(HwcDisplay::Stats delta) { @@ -168,7 +170,9 @@ HWC2::Error HwcDisplay::Init() { } client_layer_.SetLayerBlendMode(HWC2_BLEND_MODE_PREMULTIPLIED); - +#ifdef HWC_DUMP_BUFFER + BufferInfoMinigbm::InitializeGralloc1(pipeline_->device); +#endif return HWC2::Error::None; } diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h index 17789b54..dc3cc4a2 100644 --- a/hwc2_device/HwcLayer.h +++ b/hwc2_device/HwcLayer.h @@ -118,6 +118,7 @@ class HwcLayer { return !bi_get_failed_ && !fb_import_failed_ && buffer_handle_ != nullptr; } + buffer_handle_t GetBufferHandle() {return buffer_handle_;} private: void ImportFb(); bool bi_get_failed_{};