Skip to content

Commit

Permalink
Add dumpBuffer feature in drm-hwc
Browse files Browse the repository at this point in the history
Enable dumpBuffer for debug purpose. when necessary,
DumpBuffer() function is called to execute.

The property of drm.dumpbuffer.on should be set to 1 and
after "setenforce 0" is executed in the shell, dumpfiles
will be generated in the /data/local/tarce directory

Tracked-On: OAM-111122
Signed-off-by: manxiaoliang <[email protected]>
  • Loading branch information
manxiaoliang committed Jul 12, 2023
1 parent 97d8f8b commit 90d7933
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 4 deletions.
3 changes: 2 additions & 1 deletion Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ filegroup {
srcs: [
"bufferinfo/BufferInfoGetter.cpp",
"bufferinfo/BufferInfoMapperMetadata.cpp",

"compositor/DrmKmsPlan.cpp",

"drm/DrmAtomicStateManager.cpp",
Expand Down Expand Up @@ -132,6 +132,7 @@ cc_library_shared {
":drm_hwcomposer_common",
"bufferinfo/legacy/BufferInfoMinigbm.cpp",
],
cflags: ["-DHWC_DUMP_BUFFER"],
}

// Used by hwcomposer.drm_imagination
Expand Down
89 changes: 89 additions & 0 deletions bufferinfo/legacy/BufferInfoMinigbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,93 @@ 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, BufferInfo buffer_info) {
if (NULL == handle)
return;
char dump_file[256] = {0};
buffer_handle_t handle_copy;
uint8_t* pixels = nullptr;
gralloc1_rect_t accessRegion = {0, 0, (int32_t)buffer_info.width, (int32_t)buffer_info.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<void**>(&pixels), 0);
if (ret) {
ALOGE("gralloc->lock failed: %d", ret);
return;
} else {
char ctime[32];
time_t t = time(0);
static int i = 0;
if (i >= 1000) {
i = 0;
}
strftime(ctime, sizeof(ctime), "%Y-%m-%d", localtime(&t));
sprintf(dump_file, "/data/local/traces/dump_%dx%d_0x%x_%s_%d", buffer_info.width, buffer_info.height, buffer_info.format, 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 {
uint32_t bytes = 64;
size_t size = buffer_info.width * buffer_info.height * bytes;
ALOGE("write file buffer_info.size = %zu", size);
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
27 changes: 27 additions & 0 deletions bufferinfo/legacy/BufferInfoMinigbm.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,43 @@
#define BUFFERINFOMINIGBM_H_

#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>

#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 {
public:
using LegacyBufferInfoGetter::LegacyBufferInfoGetter;
auto GetBoInfo(buffer_handle_t handle) -> std::optional<BufferInfo> override;
int ValidateGralloc() override;
static void InitializeGralloc1(DrmDevice *drmDevice);
static void DumpBuffer(DrmDevice *drmDevice, buffer_handle_t handle, BufferInfo buffer_info);
};

} // namespace android
Expand Down
1 change: 1 addition & 0 deletions drm/DrmDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class DrmDevice {
bool preferred_mode_limit_;
bool planes_enabling_;
int32_t planes_num_;
void *dri_drm_;
};
} // namespace android

Expand Down
8 changes: 6 additions & 2 deletions hwc2_device/HwcDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
#include "bufferinfo/BufferInfoGetter.h"
#include "utils/log.h"
#include "utils/properties.h"

#ifdef HWC_DUMP_BUFFER
#include "bufferinfo/legacy/BufferInfoMinigbm.h"
#endif
namespace android {

std::string HwcDisplay::DumpDelta(HwcDisplay::Stats delta) {
Expand Down Expand Up @@ -132,7 +134,9 @@ void HwcDisplay::Deinit() {

HWC2::Error HwcDisplay::Init() {
ChosePreferredConfig();

#ifdef HWC_DUMP_BUFFER
BufferInfoMinigbm::InitializeGralloc1(pipeline_->device);
#endif
int ret = vsync_worker_.Init(pipeline_, [this](int64_t timestamp) {
const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
if (vsync_event_en_) {
Expand Down
17 changes: 16 additions & 1 deletion hwc2_device/HwcLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
#include "HwcDisplay.h"
#include "bufferinfo/BufferInfoGetter.h"
#include "utils/log.h"

#ifdef HWC_DUMP_BUFFER
#include "bufferinfo/legacy/BufferInfoMinigbm.h"
#include "utils/properties.h"
#endif
namespace android {

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
Expand Down Expand Up @@ -252,6 +255,18 @@ void HwcLayer::ImportFb() {
return;
}

#ifdef HWC_DUMP_BUFFER
char status[PROPERTY_VALUE_MAX];
if (property_get("drm.dumpbuffer.on", status, NULL) > 0) {
ALOGE("drm.dumpbuffer.on does support");
if (status != "0") {
BufferInfoMinigbm::DumpBuffer(parent_->GetPipe().device, buffer_handle_, layer_data_.bi.value());
} else {
ALOGE("DumpBuffer does not support");
}
}
#endif

layer_data_
.fb = parent_->GetPipe().device->GetDrmFbImporter().GetOrCreateFbId(
&layer_data_.bi.value());
Expand Down

0 comments on commit 90d7933

Please sign in to comment.