From efbf3d65f3343c40092d6dac009b71860d851747 Mon Sep 17 00:00:00 2001 From: ShaoboFeng Date: Sun, 25 Jun 2023 18:08:30 +0800 Subject: [PATCH 1/5] gpu test --- build/gn/BUILD.gn | 4 +- display_server/drivers/hal/test/BUILD.gn | 20 ++ .../hal/test/system_test/gpu_backend_test.cpp | 279 ++++++++++++++++++ 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 display_server/drivers/hal/test/system_test/gpu_backend_test.cpp diff --git a/build/gn/BUILD.gn b/build/gn/BUILD.gn index 61fb063..c948791 100644 --- a/build/gn/BUILD.gn +++ b/build/gn/BUILD.gn @@ -32,6 +32,8 @@ group("ft_test") { "//display_server/drivers/hal/test:drm_backend_test", "//display_server/frameworks/surface/test/ft_build:test", "//display_server/rosen/samples/composer/ft_build:hello_composer", - "//display_server/rosen/modules/render_service_client/test/ft_build:render_service_client_rs_demo" + "//display_server/rosen/modules/render_service_client/test/ft_build:render_service_client_rs_demo", + + "//display_server/drivers/hal/test:gpu_backend_test", ] } diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn index c4dc771..78f62fd 100644 --- a/display_server/drivers/hal/test/BUILD.gn +++ b/display_server/drivers/hal/test/BUILD.gn @@ -32,3 +32,23 @@ ft_executable("drm_backend_test") { "//display_server/drivers/hal:hal_public_config" ] } + +ft_executable("gpu_backend_test") { + testonly = true + + sources = [ + "system_test/gpu_backend_test.cpp" + ] + + deps = [ + "//display_server/drivers/hal/drm_backend:drm_backend", + "//display_server/drivers/hal/base:hal_base", + "//display_server/utils/sync_fence/ft_build:sync_fence", + ] + + configs = [ + "//build/gn/configs/system_libs:ipc_core_config", + "//display_server/drivers/hal:hal_public_config" + ] +} + diff --git a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp new file mode 100644 index 0000000..60da2ce --- /dev/null +++ b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2023 Huawei Technologies Co., Ltd. + * 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 + +#include "display_device.h" +#include "event_loop/event_loop.h" +#include "hdi_display.h" +#include "hdi_session.h" +#include "sync_fence.h" +#include "allocator_controller.h" +#include + + +oewm::HDI::DISPLAY::HdiSession& g_session = oewm::HDI::DISPLAY::HdiSession::GetInstance(); +oewm::HDI::DISPLAY::AllocatorController& g_alloc_controller = oewm::HDI::DISPLAY::AllocatorController::GetInstance(); +oewm::EventLoop g_mainLoop = oewm::EventLoop(); + +bool DestoryBufferHandle(BufferHandle **handle); + +struct FrameBuffer { + BufferHandle *handle; +}; + +class Screen { +public: + ~Screen() noexcept { + if (fb[0]) { + DestoryBufferHandle(&fb[0]->handle); + } + if (fb[1]) { + DestoryBufferHandle(&fb[1]->handle); + } + } + static void OnVsync(uint32_t sequence, uint64_t timestamp, void *data); + +public: + uint32_t devId = ~0x0; + bool firstFrame = false; + uint32_t fbIdx = 0; + std::shared_ptr fb[2]; +}; +std::unordered_map g_screens; + +bool CreateBuffer(uint32_t devId, BufferHandle **handle) +{ + printf("CreateBuffer: start\n"); + + /* Get Display modes */ + std::vector displayModeInfos = {}; + uint32_t num = 0; + + int32_t ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::GetDisplaySupportedModes, + &num, + (DisplayModeInfo*)nullptr + ); + if (ret != DISPLAY_SUCCESS) { + printf("CreateBuffer: Failed to get display supported modes, ret=%d\n", ret); + return false; + } + if (num <= 0) { + printf("CreateBuffer: display modes is %d, exited.\n", num); + return false; + } + printf("CreateBuffer: display modes num=%d\n", num); + + displayModeInfos.resize(num); + ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::GetDisplaySupportedModes, + &num, + displayModeInfos.data() + ); + if (ret != DISPLAY_SUCCESS) { + printf("CreateBuffer: Failed to get screen supported modes, ret=%d\n", ret); + return false; + } + + /* Alloc buffer for framebuffer */ + // Choose mode + static const uint32_t DEFAULT_MODE_INDEX = 0; + uint32_t width = displayModeInfos[DEFAULT_MODE_INDEX].width; + uint32_t height = displayModeInfos[DEFAULT_MODE_INDEX].height; + ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::SetDisplayMode, + DEFAULT_MODE_INDEX); + if (ret != DISPLAY_SUCCESS) { + printf("Draw: Failed to set display mode, ret=%d\n", ret); + return false; + } + printf("CreateBuffer: choose display mode 0 to create fb: width=%d, height=%d.\n", width, height); + + // Get allocator + AllocInfo info = { + .width = width, + .height = height, + .usage = HBM_USE_MEM_DMA | HBM_USE_MEM_FB , // allocate gbm buffer + .format = PIXEL_FMT_BGRA_8888}; + auto allocator = g_alloc_controller.GetAllocator(info.usage); + if (allocator == nullptr) { + printf("CreateBuffer: Failed to get buffer allocator.\n"); + return false; + } + + // Do allocate memory + ret = allocator->AllocMem(info, handle); + if (*handle == nullptr || ret != DISPLAY_SUCCESS) { + printf("CreateBuffer: Failed to alloc fb.\n"); + return false; + } + + printf("CreateBuffer: end. handle fd: %i.\n", (*handle)->fd); + return true; +} + +void DrawBaseColor(BufferHandle *handle, uint32_t width, uint32_t height) +{ + + return; +} + +void SignalHandler(int signum) { + printf("Interrupt signal (%d) received.\n", signum); + + g_mainLoop.Stop(); + printf("Stop main loop done.\n"); + + for (auto& screen : g_screens) { + if (screen.second) { + delete screen.second; + } + } + + exit(signum); +} + +bool DestoryBufferHandle(BufferHandle **handle) +{ + printf("DestoryBufferHandle.\n"); + + if (handle == nullptr) { + return false; + } + + auto allocator = g_alloc_controller.GetAllocator((*handle)->usage); + if (allocator == nullptr) { + printf("DestoryBufferHandle: Failed to get buffer allocator.\n"); + return false; + } + + // Unmap buffer & Close fd + allocator->FreeMem(*handle); + printf("DestoryBufferHandle: free buffer done.\n"); + *handle = nullptr; + return true; +} + +void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) +{ + Screen *screen = static_cast(data); + if (screen == nullptr) { + printf("OnVSync: screen is null\n"); + return; + } + + // Print first frames + static int i = 0; + if (i < 3) { + printf("OnVSync: screen devId=%d, sequence=%u, timestamp=%lu\n", screen->devId, sequence, timestamp); + LOG_DEBUG("DRM Backend Test: OnVSync: screen devId=%{public}d, sequence=%{public}u, timestamp=%{public}lu", + screen->devId, sequence, timestamp); + ++i; + } + + // Do draw in main loop + g_mainLoop.RunInLoop([screen]() { + uint32_t devId = screen->devId; + int32_t fenceFd = -1; + int32_t ret; + + // Create two framebuffers on first frame + if (screen->firstFrame) { + if (screen->fb[0] == nullptr) { + screen->fb[0] = std::make_shared(); + CreateBuffer(devId, &(screen->fb[0]->handle)); + } + if (screen->fb[1] == nullptr) { + screen->fb[1] = std::make_shared(); + CreateBuffer(devId, &(screen->fb[1]->handle)); + } + } + screen->firstFrame = false; + + // Fill fb with plain color + DrawBaseColor( + screen->fb[screen->fbIdx]->handle, + screen->fb[screen->fbIdx]->handle->width, + screen->fb[screen->fbIdx]->handle->height); + + // Set fb as screen's current buffer + ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::SetDisplayClientBuffer, + static_cast(screen->fb[screen->fbIdx]->handle), + fenceFd); + if (ret != DISPLAY_SUCCESS) { + printf("Draw: Failed to set display client buffer, ret=%d\n", ret); + return; + } + + // Commit + ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::Commit, + &fenceFd); + if (fenceFd >= 0) { + auto fence = OHOS::SyncFence(fenceFd); + } else { + auto fence = OHOS::SyncFence(-1); + } + + screen->fbIdx ^= 1; + }); +} + +static void OnHotPlug(uint32_t devId, bool connected, void *data) +{ + printf("OnHotPlug: screen devId=%d, connected=%s\n", devId, connected ? "True" : "False"); + LOG_DEBUG("DRM Backend Test: OnHotPlug: screen devId=%d, connected=%s", devId, connected ? "True" : "False"); + + // Store screen + Screen* screen = new Screen(); + screen->devId = devId; + screen->firstFrame = true; + g_screens[devId] = screen; + + // Register VSync callback + int32_t ret = g_session.CallDisplayFunction( + devId, + &oewm::HDI::DISPLAY::HdiDisplay::RegDisplayVBlankCallback, + Screen::OnVsync, + static_cast(g_screens.at(devId)) + ); + if (ret != DISPLAY_SUCCESS) { + printf("OnHotPlug: Failed to Register VSync callback, ret=%d\n", ret); + return; + } +} + +int main() +{ + signal(SIGINT, SignalHandler); + + printf("session pointer in main: %p, displays size : %lu.", &g_session, g_session.GetDisplayDevice()->GetDisplays().size()); + g_alloc_controller.Init(); + + // Register HotPlug callback + g_session.RegHotPlugCallback(OnHotPlug, nullptr); + + // Start main loop + g_mainLoop.Start(); + + return 0; +} -- Gitee From 38e1125f14e3e4d498d019abccf24179001e79e9 Mon Sep 17 00:00:00 2001 From: ShaoboFeng Date: Mon, 26 Jun 2023 00:06:09 +0800 Subject: [PATCH 2/5] add egl --- .../drivers/hal/test/system_test/gpu_backend_test.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp index 60da2ce..2934712 100644 --- a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp +++ b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp @@ -53,6 +53,7 @@ public: std::shared_ptr fb[2]; }; std::unordered_map g_screens; +EGLDisplay defaultDisplay; bool CreateBuffer(uint32_t devId, BufferHandle **handle) { @@ -203,6 +204,10 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) screen->fb[1] = std::make_shared(); CreateBuffer(devId, &(screen->fb[1]->handle)); } + defaultDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + int major, minor; + eglInitialize(defaultDisplay, &major, &minor); + printf("%d %d", major, minor); } screen->firstFrame = false; -- Gitee From 3d4ffe6eb0596a48b29b4287986e20447aee259c Mon Sep 17 00:00:00 2001 From: ShaoboFeng Date: Mon, 26 Jun 2023 14:32:22 +0800 Subject: [PATCH 3/5] test gbm backend --- display_server/drivers/hal/test/BUILD.gn | 1 + .../hal/test/system_test/gpu_backend_test.cpp | 134 ++++++++++++++---- 2 files changed, 110 insertions(+), 25 deletions(-) diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn index 78f62fd..d5241b1 100644 --- a/display_server/drivers/hal/test/BUILD.gn +++ b/display_server/drivers/hal/test/BUILD.gn @@ -50,5 +50,6 @@ ft_executable("gpu_backend_test") { "//build/gn/configs/system_libs:ipc_core_config", "//display_server/drivers/hal:hal_public_config" ] + libs = [ "EGL", "GLESv2" ] } diff --git a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp index 2934712..d421ee8 100644 --- a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp +++ b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp @@ -22,7 +22,8 @@ #include "sync_fence.h" #include "allocator_controller.h" #include - +#include +#include oewm::HDI::DISPLAY::HdiSession& g_session = oewm::HDI::DISPLAY::HdiSession::GetInstance(); oewm::HDI::DISPLAY::AllocatorController& g_alloc_controller = oewm::HDI::DISPLAY::AllocatorController::GetInstance(); @@ -40,9 +41,6 @@ public: if (fb[0]) { DestoryBufferHandle(&fb[0]->handle); } - if (fb[1]) { - DestoryBufferHandle(&fb[1]->handle); - } } static void OnVsync(uint32_t sequence, uint64_t timestamp, void *data); @@ -52,12 +50,65 @@ public: uint32_t fbIdx = 0; std::shared_ptr fb[2]; }; + std::unordered_map g_screens; -EGLDisplay defaultDisplay; +static EGLDisplay defaultDisplay; +static struct gbm_device *gbm_device; +static EGLContext context; +static struct gbm_surface *gbm_surface; +static EGLSurface egl_surface; + +EGLConfig GetEGLConfig() +{ + EGLint egl_config_attribs[] = { + EGL_BUFFER_SIZE, 32, //EGL_BUFFER_SIZE:指定缓冲区的位数为32位。 + EGL_DEPTH_SIZE, EGL_DONT_CARE, //EGL_DEPTH_SIZE:深度缓冲区大小,使用EGL_DONT_CARE表示不关心具体大小。 + EGL_STENCIL_SIZE, EGL_DONT_CARE, //EGL_STENCIL_SIZE:模板缓冲区大小 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //EGL_RENDERABLE_TYPE:指定可渲染的类型为OpenGL ES 2.0 + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, //EGL_SURFACE_TYPE:指定表面类型为窗口。 + EGL_NONE, //EGL_NONE:属性数组的结束标志。 + }; + + EGLint num_configs; //调用eglGetConfigs函数获取系统中可用的EGL配置数量,将结果保存在num_configs变量中 + assert(eglGetConfigs(defaultDisplay, NULL, 0, &num_configs) == EGL_TRUE); + + EGLConfig *configs = (EGLConfig *)malloc(num_configs * sizeof(EGLConfig)); + + assert(eglChooseConfig(defaultDisplay, egl_config_attribs, + configs, num_configs, &num_configs) == EGL_TRUE); + assert(num_configs); //确保至少存在一个满足条件的配置 + printf("num config %d\n", num_configs); + + for (int i = 0; i < num_configs; ++i) { + EGLint gbm_format; + + assert(eglGetConfigAttrib(defaultDisplay, configs[i], + EGL_NATIVE_VISUAL_ID, &gbm_format) == EGL_TRUE); + printf("gbm format %x\n", gbm_format); + /*如果找到与目标GBM格式(GBM_FORMAT_ARGB8888)匹配的配置, + 即gbm_format等于目标格式,就释放configs的内存并返回该配置。*/ + if (gbm_format == GBM_FORMAT_ARGB8888) { + EGLConfig ret = configs[i]; + free(configs); + return ret; + } + } + // 未找到匹配的配置,调用abort函数终止程序。 + abort(); +} + +void SwapBuffer(BufferHandle *handle) { + //交换EGL表面的前后缓冲区。 + eglSwapBuffers (defaultDisplay, egl_surface); + //锁定GBM表面的前端缓冲区,以便进行后续操作。 + struct gbm_bo *bo = gbm_surface_lock_front_buffer (gbm_surface); + //获取前端缓冲区的句柄 + handle->key = gbm_bo_get_handle(bo).u32; +} -bool CreateBuffer(uint32_t devId, BufferHandle **handle) +bool InitEGL(uint32_t devId, BufferHandle **handle) { - printf("CreateBuffer: start\n"); + printf("InitEGL\n"); /* Get Display modes */ std::vector displayModeInfos = {}; @@ -106,6 +157,7 @@ bool CreateBuffer(uint32_t devId, BufferHandle **handle) } printf("CreateBuffer: choose display mode 0 to create fb: width=%d, height=%d.\n", width, height); + /* // Get allocator AllocInfo info = { .width = width, @@ -124,14 +176,42 @@ bool CreateBuffer(uint32_t devId, BufferHandle **handle) printf("CreateBuffer: Failed to alloc fb.\n"); return false; } - printf("CreateBuffer: end. handle fd: %i.\n", (*handle)->fd); + */ + gbm_device = g_session.GetDisplayDevice()->GetGbmDevice(); + defaultDisplay = eglGetDisplay(gbm_device); + int major, minor; + eglInitialize(defaultDisplay, &major, &minor); + printf("%d %d", major, minor); + + eglBindAPI(EGL_OPENGL_ES2_BIT); + EGLConfig config = GetEGLConfig(); + context = eglCreateContext (defaultDisplay, config, EGL_NO_CONTEXT, NULL); + + // create the GBM and EGL surface + gbm_surface = gbm_surface_create (gbm_device, width, height, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_LINEAR|GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING); + //创建EGL窗口表面对象,将GBM表面与EGL绑定 + egl_surface = eglCreateWindowSurface (defaultDisplay, config, gbm_surface, NULL); + //将OpenGL上下文与EGL表面进行绑定,使其成为当前上下文。 + eglMakeCurrent (defaultDisplay, egl_surface, egl_surface, context); + + static BufferHandle tmp; + *handle = &tmp; + tmp.virAddr = nullptr; + tmp.stride= width; + tmp.usage = HBM_USE_MEM_DMA | HBM_USE_MEM_FB; + tmp.format = GBM_BO_FORMAT_XRGB8888; + tmp.height= height; + tmp.width = width; + tmp.size = tmp.height * tmp.stride; + return true; } -void DrawBaseColor(BufferHandle *handle, uint32_t width, uint32_t height) +void DrawBaseColor(float progress) { - + glClearColor (1.0f-progress, progress, 0.0, 1.0); + glClear (GL_COLOR_BUFFER_BIT); return; } @@ -152,6 +232,13 @@ void SignalHandler(int signum) { bool DestoryBufferHandle(BufferHandle **handle) { + eglDestroySurface (defaultDisplay, egl_surface); + gbm_surface_destroy (gbm_surface); + eglDestroyContext (defaultDisplay, context); + eglTerminate (defaultDisplay); + gbm_device_destroy (gbm_device); + + /* printf("DestoryBufferHandle.\n"); if (handle == nullptr) { @@ -168,6 +255,7 @@ bool DestoryBufferHandle(BufferHandle **handle) allocator->FreeMem(*handle); printf("DestoryBufferHandle: free buffer done.\n"); *handle = nullptr; + */ return true; } @@ -198,30 +286,26 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) if (screen->firstFrame) { if (screen->fb[0] == nullptr) { screen->fb[0] = std::make_shared(); - CreateBuffer(devId, &(screen->fb[0]->handle)); + InitEGL(devId, &(screen->fb[0]->handle)); } - if (screen->fb[1] == nullptr) { - screen->fb[1] = std::make_shared(); - CreateBuffer(devId, &(screen->fb[1]->handle)); - } - defaultDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - int major, minor; - eglInitialize(defaultDisplay, &major, &minor); - printf("%d %d", major, minor); } screen->firstFrame = false; // Fill fb with plain color - DrawBaseColor( - screen->fb[screen->fbIdx]->handle, - screen->fb[screen->fbIdx]->handle->width, - screen->fb[screen->fbIdx]->handle->height); + if (screen->fbIdx == 100) { + screen->fbIdx = 0; + } + DrawBaseColor(screen->fbIdx / 100.0); + screen->fbIdx++; + + // swap buffer + SwapBuffer(screen->fb[0]->handle); // Set fb as screen's current buffer ret = g_session.CallDisplayFunction( devId, &oewm::HDI::DISPLAY::HdiDisplay::SetDisplayClientBuffer, - static_cast(screen->fb[screen->fbIdx]->handle), + static_cast(screen->fb[0]->handle), fenceFd); if (ret != DISPLAY_SUCCESS) { printf("Draw: Failed to set display client buffer, ret=%d\n", ret); @@ -239,7 +323,7 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) auto fence = OHOS::SyncFence(-1); } - screen->fbIdx ^= 1; + screen->fbIdx++; }); } -- Gitee From e7f39960fdf8534c5a0537791f2cc737302e4d21 Mon Sep 17 00:00:00 2001 From: ShaoboFeng Date: Mon, 26 Jun 2023 17:14:44 +0800 Subject: [PATCH 4/5] test gbm backend ok --- .../display_device/drm_display.cpp | 1 - .../display_device/drm_frame_buffer.cpp | 18 +-- .../drm_backend/display_device/drm_layer.cpp | 4 - .../hal/test/system_test/gpu_backend_test.cpp | 107 +++++++----------- 4 files changed, 43 insertions(+), 87 deletions(-) diff --git a/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp index 9f1c359..1f8be31 100644 --- a/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp @@ -497,7 +497,6 @@ int32_t DrmDisplay::Commit(int32_t *fence) return DISPLAY_NULL_PTR; } - // const DrmFrameBuffer *fb = reservedFb_.get(); const DrmFrameBuffer *fb = layer->GetFrameBuffer(drmFd_); if (fb == nullptr) { LOG_ERROR("DrmDisplay::Commit: failed to get framebuffer, use reservedFb_ instead."); diff --git a/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp index 56b538a..8244fd8 100644 --- a/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp @@ -37,21 +37,13 @@ bool AddFb(int drmFd, uint32_t fbHandle, FrameBufferInfo &fbInfo) pitches[0] = fbInfo.stride; offsets[0] = 0; - if (drmModeAddFB2( - drmFd, - fbInfo.width, - fbInfo.height, - DRM_FORMAT_XRGB8888, // need use DRM_FORMAT_XRGB8888 - handles, - pitches, - offsets, - &fbInfo.fbId, - 0) != 0) { - LOG_ERROR("drmModeAddFB2 failed, error: %{public}s", ErrnoToString(errno).c_str()); + printf("AddFb: fd=%d, width=%u, height=%u, pixel_format=DRM_FORMAT_XRGB8888, handle=%u, pitch=%u, offset=%u, fbId=%u\n", + drmFd, fbInfo.width, fbInfo.height, handles[0], pitches[0], offsets[0], fbInfo.fbId); + if (drmModeAddFB2(drmFd, fbInfo.width, fbInfo.height, DRM_FORMAT_XRGB8888, // need use DRM_FORMAT_XRGB8888 + handles, pitches, offsets, &fbInfo.fbId, 0) != 0) { + printf("drmModeAddFB2 failed, error: %s\n", ErrnoToString(errno).c_str()); return false; } - LOG_DEBUG("AddFb: fd=%{public}d, width=%{public}u, height=%{public}u, pixel_format=DRM_FORMAT_XRGB8888, handle=%{public}u, pitch=%{public}u, offset=%{public}u, fbId=%{public}u", - drmFd, fbInfo.width, fbInfo.height, handles[0], pitches[0], offsets[0], fbInfo.fbId); return true; } diff --git a/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp index b47d154..4229b9b 100644 --- a/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp @@ -21,10 +21,6 @@ namespace oewm { namespace drm { DrmFrameBuffer *DrmLayer::GetFrameBuffer(int drmFd) { - // if (currentFrameBuffer_ != nullptr) { - // return currentFrameBuffer_.get(); - // } - if (IsInvalidFd(drmFd)) { LOG_ERROR("DrmLayer::GetFrameBuffer: invalid drm fd"); return nullptr; diff --git a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp index d421ee8..8688995 100644 --- a/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp +++ b/display_server/drivers/hal/test/system_test/gpu_backend_test.cpp @@ -57,6 +57,7 @@ static struct gbm_device *gbm_device; static EGLContext context; static struct gbm_surface *gbm_surface; static EGLSurface egl_surface; +static BufferHandle tmpBufferHandle; EGLConfig GetEGLConfig() { @@ -85,25 +86,46 @@ EGLConfig GetEGLConfig() assert(eglGetConfigAttrib(defaultDisplay, configs[i], EGL_NATIVE_VISUAL_ID, &gbm_format) == EGL_TRUE); printf("gbm format %x\n", gbm_format); - /*如果找到与目标GBM格式(GBM_FORMAT_ARGB8888)匹配的配置, - 即gbm_format等于目标格式,就释放configs的内存并返回该配置。*/ if (gbm_format == GBM_FORMAT_ARGB8888) { EGLConfig ret = configs[i]; free(configs); return ret; } } - // 未找到匹配的配置,调用abort函数终止程序。 + // not find config, exit. abort(); } -void SwapBuffer(BufferHandle *handle) { +struct gbm_bo* SwapBuffer(BufferHandle *handle) +{ //交换EGL表面的前后缓冲区。 eglSwapBuffers (defaultDisplay, egl_surface); + //锁定GBM表面的前端缓冲区,以便进行后续操作。 struct gbm_bo *bo = gbm_surface_lock_front_buffer (gbm_surface); + if (bo == nullptr) { + printf("gbm bo is null\n"); + return nullptr; + } //获取前端缓冲区的句柄 handle->key = gbm_bo_get_handle(bo).u32; + handle->stride = gbm_bo_get_stride(bo); + handle->size = handle->stride * handle->height; + handle->format = gbm_bo_get_format(bo); + return bo; +} + +static struct gbm_bo *previous_bo = NULL; +static uint32_t previous_fb; + +void ReleaseBuffer(struct gbm_bo* bo) +{ + if (previous_bo) { //检查是否存在前一个帧缓冲区对象。 + //释放前一个GBM表面的缓冲区。 + gbm_surface_release_buffer (gbm_surface, previous_bo); + } + //更新前一个帧缓冲区对象为当前帧缓冲区对象 + previous_bo = bo; } bool InitEGL(uint32_t devId, BufferHandle **handle) @@ -157,32 +179,11 @@ bool InitEGL(uint32_t devId, BufferHandle **handle) } printf("CreateBuffer: choose display mode 0 to create fb: width=%d, height=%d.\n", width, height); - /* - // Get allocator - AllocInfo info = { - .width = width, - .height = height, - .usage = HBM_USE_MEM_DMA | HBM_USE_MEM_FB , // allocate gbm buffer - .format = PIXEL_FMT_BGRA_8888}; - auto allocator = g_alloc_controller.GetAllocator(info.usage); - if (allocator == nullptr) { - printf("CreateBuffer: Failed to get buffer allocator.\n"); - return false; - } - - // Do allocate memory - ret = allocator->AllocMem(info, handle); - if (*handle == nullptr || ret != DISPLAY_SUCCESS) { - printf("CreateBuffer: Failed to alloc fb.\n"); - return false; - } - printf("CreateBuffer: end. handle fd: %i.\n", (*handle)->fd); - */ gbm_device = g_session.GetDisplayDevice()->GetGbmDevice(); defaultDisplay = eglGetDisplay(gbm_device); int major, minor; eglInitialize(defaultDisplay, &major, &minor); - printf("%d %d", major, minor); + printf("EGL version:%d.%d\n", major, minor); eglBindAPI(EGL_OPENGL_ES2_BIT); EGLConfig config = GetEGLConfig(); @@ -195,15 +196,10 @@ bool InitEGL(uint32_t devId, BufferHandle **handle) //将OpenGL上下文与EGL表面进行绑定,使其成为当前上下文。 eglMakeCurrent (defaultDisplay, egl_surface, egl_surface, context); - static BufferHandle tmp; - *handle = &tmp; - tmp.virAddr = nullptr; - tmp.stride= width; - tmp.usage = HBM_USE_MEM_DMA | HBM_USE_MEM_FB; - tmp.format = GBM_BO_FORMAT_XRGB8888; - tmp.height= height; - tmp.width = width; - tmp.size = tmp.height * tmp.stride; + *handle = &tmpBufferHandle; + tmpBufferHandle.virAddr = nullptr; + tmpBufferHandle.height= height; + tmpBufferHandle.width = width; return true; } @@ -212,7 +208,6 @@ void DrawBaseColor(float progress) { glClearColor (1.0f-progress, progress, 0.0, 1.0); glClear (GL_COLOR_BUFFER_BIT); - return; } void SignalHandler(int signum) { @@ -238,24 +233,6 @@ bool DestoryBufferHandle(BufferHandle **handle) eglTerminate (defaultDisplay); gbm_device_destroy (gbm_device); - /* - printf("DestoryBufferHandle.\n"); - - if (handle == nullptr) { - return false; - } - - auto allocator = g_alloc_controller.GetAllocator((*handle)->usage); - if (allocator == nullptr) { - printf("DestoryBufferHandle: Failed to get buffer allocator.\n"); - return false; - } - - // Unmap buffer & Close fd - allocator->FreeMem(*handle); - printf("DestoryBufferHandle: free buffer done.\n"); - *handle = nullptr; - */ return true; } @@ -267,17 +244,8 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) return; } - // Print first frames - static int i = 0; - if (i < 3) { - printf("OnVSync: screen devId=%d, sequence=%u, timestamp=%lu\n", screen->devId, sequence, timestamp); - LOG_DEBUG("DRM Backend Test: OnVSync: screen devId=%{public}d, sequence=%{public}u, timestamp=%{public}lu", - screen->devId, sequence, timestamp); - ++i; - } - // Do draw in main loop - g_mainLoop.RunInLoop([screen]() { + g_mainLoop.RunInLoop([screen, sequence, timestamp]() { uint32_t devId = screen->devId; int32_t fenceFd = -1; int32_t ret; @@ -297,9 +265,11 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) } DrawBaseColor(screen->fbIdx / 100.0); screen->fbIdx++; + printf("OnVSync %d: screen devId=%d, sequence=%u, timestamp=%lu\n", screen->fbIdx, screen->devId, sequence, timestamp); + usleep(100000); // swap buffer - SwapBuffer(screen->fb[0]->handle); + struct gbm_bo *bo = SwapBuffer(screen->fb[0]->handle); // Set fb as screen's current buffer ret = g_session.CallDisplayFunction( @@ -322,15 +292,14 @@ void Screen::OnVsync(uint32_t sequence, uint64_t timestamp, void *data) } else { auto fence = OHOS::SyncFence(-1); } - - screen->fbIdx++; + + ReleaseBuffer(bo); }); } static void OnHotPlug(uint32_t devId, bool connected, void *data) { printf("OnHotPlug: screen devId=%d, connected=%s\n", devId, connected ? "True" : "False"); - LOG_DEBUG("DRM Backend Test: OnHotPlug: screen devId=%d, connected=%s", devId, connected ? "True" : "False"); // Store screen Screen* screen = new Screen(); @@ -342,7 +311,7 @@ static void OnHotPlug(uint32_t devId, bool connected, void *data) int32_t ret = g_session.CallDisplayFunction( devId, &oewm::HDI::DISPLAY::HdiDisplay::RegDisplayVBlankCallback, - Screen::OnVsync, + Screen::OnVsync, static_cast(g_screens.at(devId)) ); if (ret != DISPLAY_SUCCESS) { -- Gitee From c9daf5024b0ee254d103c8348fff80323a49886c Mon Sep 17 00:00:00 2001 From: ShaoboFeng Date: Tue, 27 Jun 2023 19:28:14 +0800 Subject: [PATCH 5/5] test gbm backend ok --- display_server/drivers/hal/test/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn index d5241b1..4c23998 100644 --- a/display_server/drivers/hal/test/BUILD.gn +++ b/display_server/drivers/hal/test/BUILD.gn @@ -44,10 +44,10 @@ ft_executable("gpu_backend_test") { "//display_server/drivers/hal/drm_backend:drm_backend", "//display_server/drivers/hal/base:hal_base", "//display_server/utils/sync_fence/ft_build:sync_fence", + "//build/gn/configs/system_libs:ipc_core", ] configs = [ - "//build/gn/configs/system_libs:ipc_core_config", "//display_server/drivers/hal:hal_public_config" ] libs = [ "EGL", "GLESv2" ] -- Gitee