From b8c2ade73cb3cb824af000379f50aa67d963ef91 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Fri, 16 Jun 2023 19:04:12 +0800 Subject: [PATCH 1/8] feat(display_server): add DRM Backend --- .gitignore | 2 + build/gn/BUILD.gn | 9 + build/gn/BUILDCONFIG.gn | 3 +- build/gn/configs/system_libs/BUILD.gn | 37 + build/gn/fangtian.gni | 3 - display_server/drivers/base/buffer_handle.h | 45 + display_server/drivers/hal/BUILD.gn | 19 + display_server/drivers/hal/base/BUILD.gn | 31 + .../drivers/hal/base/current_thread.cpp | 79 ++ .../drivers/hal/base/current_thread.h | 56 ++ display_server/drivers/hal/base/log.h | 31 + display_server/drivers/hal/base/noncopyable.h | 28 + display_server/drivers/hal/base/timestamp.cpp | 109 +++ display_server/drivers/hal/base/timestamp.h | 117 +++ display_server/drivers/hal/base/types.h | 159 ++++ display_server/drivers/hal/core/BUILD.gn | 12 + .../drivers/hal/core/drm_backend/BUILD.gn | 49 ++ .../core/drm_backend/display_device/BUILD.gn | 61 ++ .../display_device/device_event_monitor.cpp | 221 +++++ .../display_device/device_event_monitor.h | 86 ++ .../display_device/drm_atomic_committer.cpp | 54 ++ .../display_device/drm_atomic_committer.h | 41 + .../drm_backend/display_device/drm_common.h | 68 ++ .../display_device/drm_connector.cpp | 202 +++++ .../display_device/drm_connector.h | 171 ++++ .../drm_backend/display_device/drm_crtc.cpp | 82 ++ .../drm_backend/display_device/drm_crtc.h | 81 ++ .../drm_backend/display_device/drm_device.cpp | 265 ++++++ .../drm_backend/display_device/drm_device.h | 156 ++++ .../display_device/drm_display.cpp | 517 +++++++++++ .../drm_backend/display_device/drm_display.h | 106 +++ .../display_device/drm_encoder.cpp | 73 ++ .../drm_backend/display_device/drm_encoder.h | 39 + .../display_device/drm_frame_buffer.cpp | 248 ++++++ .../display_device/drm_frame_buffer.h | 74 ++ .../drm_backend/display_device/drm_layer.cpp | 51 ++ .../drm_backend/display_device/drm_layer.h | 37 + .../display_device/drm_mode_info.cpp | 51 ++ .../display_device/drm_mode_info.h | 63 ++ .../drm_backend/display_device/drm_plane.cpp | 54 ++ .../drm_backend/display_device/drm_plane.h | 131 +++ .../display_device/drm_property.cpp | 110 +++ .../drm_backend/display_device/drm_property.h | 135 +++ .../display_device/hdi_display.cpp | 95 ++ .../drm_backend/display_device/hdi_display.h | 98 +++ .../drm_backend/display_device/hdi_layer.cpp | 214 +++++ .../drm_backend/display_device/hdi_layer.h | 224 +++++ .../display_device/hdi_session.cpp | 614 +++++++++++++ .../drm_backend/display_device/hdi_session.h | 106 +++ .../display_device/udev_object_helper.h | 77 ++ .../core/drm_backend/display_gralloc/BUILD.gn | 54 ++ .../drm_backend/display_gralloc/allocator.cpp | 22 + .../drm_backend/display_gralloc/allocator.h | 83 ++ .../display_gralloc/allocator_controller.cpp | 86 ++ .../display_gralloc/allocator_controller.h | 74 ++ .../display_gralloc/display_gralloc.cpp | 172 ++++ .../display_gralloc/display_gralloc_utils.cpp | 131 +++ .../display_gralloc/display_gralloc_utils.h | 55 ++ .../display_gralloc/dumb_allocator.cpp | 270 ++++++ .../display_gralloc/dumb_allocator.h | 51 ++ .../display_gralloc/gbm_allocator.cpp | 340 ++++++++ .../display_gralloc/gbm_allocator.h | 57 ++ .../display_gralloc/hi_drm_format.cpp | 260 ++++++ .../display_gralloc/hi_drm_format.h | 40 + .../display_gralloc/hi_gbm_format.cpp | 81 ++ .../display_gralloc/hi_gbm_format.h | 25 + .../display_gralloc/shm_allocator.cpp | 216 +++++ .../display_gralloc/shm_allocator.h | 49 ++ .../include/display_gralloc_private.h | 35 + .../drivers/hal/core/event_loop/BUILD.gn | 30 + .../hal/core/event_loop/event_channel.cpp | 148 ++++ .../hal/core/event_loop/event_channel.h | 147 ++++ .../hal/core/event_loop/event_loop.cpp | 207 +++++ .../drivers/hal/core/event_loop/event_loop.h | 117 +++ .../hal/core/event_loop/event_loop_thread.cpp | 67 ++ .../hal/core/event_loop/event_loop_thread.h | 46 + .../hal/core/event_loop/event_poller.cpp | 137 +++ .../hal/core/event_loop/event_poller.h | 46 + .../drivers/hal/core/event_loop/timer.cpp | 49 ++ .../drivers/hal/core/event_loop/timer.h | 100 +++ .../hal/core/event_loop/timer_queue.cpp | 184 ++++ .../drivers/hal/core/event_loop/timer_queue.h | 67 ++ display_server/drivers/hal/test/BUILD.gn | 32 + .../drivers/hal/test/system_test/main.cpp | 312 +++++++ .../drivers/interfaces/display_device.h | 691 +++++++++++++++ .../drivers/interfaces/display_gralloc.h | 200 +++++ .../drivers/interfaces/display_layer.h | 811 ++++++++++++++++++ .../drivers/interfaces/display_type.h | 689 +++++++++++++++ .../utils/sync_fence/ft_build/BUILD.gn | 55 ++ .../utils/sync_fence/src/sync_fence.cpp | 2 +- .../sync_fence/src/sync_fence_tracker.cpp | 2 + 91 files changed, 11629 insertions(+), 5 deletions(-) create mode 100644 build/gn/configs/system_libs/BUILD.gn create mode 100644 display_server/drivers/base/buffer_handle.h create mode 100644 display_server/drivers/hal/BUILD.gn create mode 100644 display_server/drivers/hal/base/BUILD.gn create mode 100644 display_server/drivers/hal/base/current_thread.cpp create mode 100644 display_server/drivers/hal/base/current_thread.h create mode 100644 display_server/drivers/hal/base/log.h create mode 100644 display_server/drivers/hal/base/noncopyable.h create mode 100644 display_server/drivers/hal/base/timestamp.cpp create mode 100644 display_server/drivers/hal/base/timestamp.h create mode 100644 display_server/drivers/hal/base/types.h create mode 100644 display_server/drivers/hal/core/BUILD.gn create mode 100644 display_server/drivers/hal/core/drm_backend/BUILD.gn create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_common.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_device.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_display.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/drm_property.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp create mode 100644 display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h create mode 100644 display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h create mode 100644 display_server/drivers/hal/core/event_loop/BUILD.gn create mode 100644 display_server/drivers/hal/core/event_loop/event_channel.cpp create mode 100644 display_server/drivers/hal/core/event_loop/event_channel.h create mode 100644 display_server/drivers/hal/core/event_loop/event_loop.cpp create mode 100644 display_server/drivers/hal/core/event_loop/event_loop.h create mode 100644 display_server/drivers/hal/core/event_loop/event_loop_thread.cpp create mode 100644 display_server/drivers/hal/core/event_loop/event_loop_thread.h create mode 100644 display_server/drivers/hal/core/event_loop/event_poller.cpp create mode 100644 display_server/drivers/hal/core/event_loop/event_poller.h create mode 100644 display_server/drivers/hal/core/event_loop/timer.cpp create mode 100644 display_server/drivers/hal/core/event_loop/timer.h create mode 100644 display_server/drivers/hal/core/event_loop/timer_queue.cpp create mode 100644 display_server/drivers/hal/core/event_loop/timer_queue.h create mode 100644 display_server/drivers/hal/test/BUILD.gn create mode 100644 display_server/drivers/hal/test/system_test/main.cpp create mode 100644 display_server/drivers/interfaces/display_device.h create mode 100644 display_server/drivers/interfaces/display_gralloc.h create mode 100644 display_server/drivers/interfaces/display_layer.h create mode 100644 display_server/drivers/interfaces/display_type.h create mode 100644 display_server/utils/sync_fence/ft_build/BUILD.gn diff --git a/.gitignore b/.gitignore index ea7c990..038e139 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ **/__pycache__ out prebuilts/build-tools +compile_commands.json +.vscode diff --git a/build/gn/BUILD.gn b/build/gn/BUILD.gn index cc6bf28..d6f2adc 100644 --- a/build/gn/BUILD.gn +++ b/build/gn/BUILD.gn @@ -15,5 +15,14 @@ group("ft_engine") { deps = [ "//display_server/utils/socketpair/ft_build:socketpair", "//display_server/rosen/modules/composer/vsync/ft_build:libvsync", + "//display_server/drivers/hal/core/drm_backend:drm_backend" ] } + +group("ft_test") { + testonly = true + + deps = [ + "//display_server/drivers/hal/test:drm_backend_test" + ] +} \ No newline at end of file diff --git a/build/gn/BUILDCONFIG.gn b/build/gn/BUILDCONFIG.gn index 59cf4d4..f96c0d9 100644 --- a/build/gn/BUILDCONFIG.gn +++ b/build/gn/BUILDCONFIG.gn @@ -46,7 +46,6 @@ declare_args() { # We add this parameter to speed up link process, enable_lto_O0 default is false. enable_lto_O0 = false - is_official_build = false # Component build. Setting to true compiles targets declared as "components" # as shared libraries loaded dynamically. This speeds up development time. @@ -76,6 +75,8 @@ declare_args() { project_root_dir = "" is_ft_build = current_os == "linux" + + sys_inc = "/usr/include" } if (use_musl_oh == true) { diff --git a/build/gn/configs/system_libs/BUILD.gn b/build/gn/configs/system_libs/BUILD.gn new file mode 100644 index 0000000..cca73cc --- /dev/null +++ b/build/gn/configs/system_libs/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2023 Huawei Device 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. + +config("c_utils_config") { + include_dirs = [ "${sys_inc}/c_utils" ] + libs = [ "utils", "sec_shared" ] +} + +config("ipc_core_config") { + include_dirs = [ "${sys_inc}/ipc_core" ] + libs = [ "ipc_core" ] +} + +config("hilog_config") { + include_dirs = [ "${sys_inc}/hilog" ] + libs = [ "hilog" ] +} + +config("hitrace_meter_config") { + include_dirs = [ "${sys_inc}/hitrace_meter" ] + libs = [ "hitrace_meter" ] +} + +config("eventhandler_config") { + include_dirs = [ "${sys_inc}/eventhandler" ] + libs = [ "eventhandler" ] +} diff --git a/build/gn/fangtian.gni b/build/gn/fangtian.gni index e1b2f44..eed273c 100755 --- a/build/gn/fangtian.gni +++ b/build/gn/fangtian.gni @@ -15,7 +15,4 @@ import("//build/gn/templates/build_targets.gni") declare_args() { is_fangtian_build = true - } - -sys_inc = "/usr/local/include" diff --git a/display_server/drivers/base/buffer_handle.h b/display_server/drivers/base/buffer_handle.h new file mode 100644 index 0000000..9d43bfd --- /dev/null +++ b/display_server/drivers/base/buffer_handle.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device 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. + */ + +#ifndef INCLUDE_BUFFER_HANDLE_H +#define INCLUDE_BUFFER_HANDLE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t fd; /**< buffer fd, -1 if not supported */ + int32_t width; /**< the width of memory */ + int32_t stride; /**< the stride of memory */ + int32_t height; /**< the height of memory */ + int32_t size; /* < size of memory */ + int32_t format; /**< the format of memory */ + uint64_t usage; /**< the usage of memory */ + void *virAddr; /**< Virtual address of memory */ + uint64_t phyAddr; /**< Physical address */ + int32_t key; /**< Shared memory key */ + uint32_t reserveFds; /**< the number of reserved fd value */ + uint32_t reserveInts; /**< the number of reserved integer value */ + int32_t reserve[0]; /**< the data */ +} BufferHandle; + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_BUFFER_HANDLE_H diff --git a/display_server/drivers/hal/BUILD.gn b/display_server/drivers/hal/BUILD.gn new file mode 100644 index 0000000..ac2bee4 --- /dev/null +++ b/display_server/drivers/hal/BUILD.gn @@ -0,0 +1,19 @@ +# Copyright (c) 2022 Huawei Device 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. + +config("oehal_public_config") { + include_dirs = [ + ".", + "./core" + ] +} diff --git a/display_server/drivers/hal/base/BUILD.gn b/display_server/drivers/hal/base/BUILD.gn new file mode 100644 index 0000000..32a418e --- /dev/null +++ b/display_server/drivers/hal/base/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (c) 2022 Huawei Device 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. + +import("//build/gn/fangtian.gni") + +ft_shared_library("oebase") { + sources = [ + "current_thread.cpp", + "timestamp.cpp", + ] + + public_configs = [ + "//build/gn/configs/system_libs:hilog_config", + "//build/gn/configs/system_libs:c_utils_config", + ] + + # public_deps = [ + # "hilog_native:libhilog", + # "c_utils:utils" + # ] +} \ No newline at end of file diff --git a/display_server/drivers/hal/base/current_thread.cpp b/display_server/drivers/hal/base/current_thread.cpp new file mode 100644 index 0000000..4c2e36b --- /dev/null +++ b/display_server/drivers/hal/base/current_thread.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "current_thread.h" + +#include +#include + +namespace oewm { +namespace detail { +static ProcessId pid = 0; +static char pidString[16]; + +inline ThreadId getThreadId() +{ + return static_cast(::syscall(SYS_gettid)); +} + +void mainThreadInit() +{ + CurrentThread::CacheTid(); + CurrentThread::t_tls.name = "main"; + pid = CurrentThread::Pid(); + int len = ::snprintf(pidString, sizeof(pidString), "%d", pid); + ASSERT(static_cast(len) < sizeof(pidString)); +} + +struct MainThreadInitializer { + MainThreadInitializer() noexcept + { + mainThreadInit(); + } +}; + +[[maybe_unused]] MainThreadInitializer mainThreadInitializer; +} // namespace detail + +namespace CurrentThread { +__thread TLS t_tls = {.tid = 0, .name = "unknown"}; + +ProcessId Pid() +{ + return ::getpid(); +} + +void CacheTid() +{ + if (t_tls.tid == 0) { + t_tls.tid = detail::getThreadId(); + } + + int len = ::snprintf(t_tls.tidString, sizeof(t_tls.tidString), "%d", t_tls.tid); + ASSERT(static_cast(len) < sizeof(t_tls.tidString)); +} + +const char *TidString() +{ + (void)Tid(); + return t_tls.tidString; +} + +const char *PidString() +{ + return detail::pidString; +} +} // namespace CurrentThread +} // namespace oewm diff --git a/display_server/drivers/hal/base/current_thread.h b/display_server/drivers/hal/base/current_thread.h new file mode 100644 index 0000000..60e3cbb --- /dev/null +++ b/display_server/drivers/hal/base/current_thread.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "types.h" + +namespace oewm { +namespace CurrentThread { +// Thread Local Storage +struct TLS { + ThreadId tid; + const char *name; + char tidString[16]; // current tid string +}; +extern __thread TLS t_tls; + +void CacheTid(); + +inline ThreadId Tid() +{ + if (OE_UNLIKELY(t_tls.tid == 0)) { + CacheTid(); + } + + return t_tls.tid; +} + +ProcessId Pid(); + +inline bool IsMainThread() +{ + return Tid() == Pid(); +} + +inline const char *Name() +{ + return t_tls.name; +} + +const char *TidString(); +const char *PidString(); +} // namespace CurrentThread +} // namespace oewm diff --git a/display_server/drivers/hal/base/log.h b/display_server/drivers/hal/base/log.h new file mode 100644 index 0000000..c5bd2c7 --- /dev/null +++ b/display_server/drivers/hal/base/log.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include + +#include "hilog/log.h" + +using namespace OHOS::HiviewDFX; + +constexpr HiLogLabel LABEL = { LOG_CORE, 0xD001400, "DrmBackend" }; + +#define LOG_FATAL(format, ...) HiLog::Fatal(LABEL, format, ##__VA_ARGS__) +#define LOG_ERROR(format, ...) HiLog::Error(LABEL, format, ##__VA_ARGS__) +#define LOG_WARN(format, ...) HiLog::Warn(LABEL, format, ##__VA_ARGS__) +#define LOG_INFO(format, ...) HiLog::Info(LABEL, format, ##__VA_ARGS__) +#define LOG_DEBUG(format, ...) HiLog::Debug(LABEL, format, ##__VA_ARGS__) +#define LOG_TRACE(format, ...) HiLog::Trace(LABEL, format, ##__VA_ARGS__) diff --git a/display_server/drivers/hal/base/noncopyable.h b/display_server/drivers/hal/base/noncopyable.h new file mode 100644 index 0000000..b73bbf5 --- /dev/null +++ b/display_server/drivers/hal/base/noncopyable.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +namespace oewm { +class NonCopyable { +public: + NonCopyable(const NonCopyable &other) = delete; + void operator=(const NonCopyable &other) = delete; + +protected: + NonCopyable() = default; + ~NonCopyable() = default; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/base/timestamp.cpp b/display_server/drivers/hal/base/timestamp.cpp new file mode 100644 index 0000000..9e48ca9 --- /dev/null +++ b/display_server/drivers/hal/base/timestamp.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "timestamp.h" + +#include +#include +#include + +namespace oewm { +namespace detail { +// Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as +// physical time moves forward and the time between ticks of this clock is constant. This clock is not related to wall +// clock time (for example, it can be time since last reboot), and is most suitable for measuring intervals. +TimeType SteadyClockMicroSeconds() +{ + auto tp = std::chrono::time_point_cast(std::chrono::steady_clock::now()); + return tp.time_since_epoch().count(); +} + +// Class std::chrono::system_clock represents the system-wide real time wall clock. +// It may not be monotonic: on most systems, the system time can be adjusted at any mo/ment. +TimeType SystemClockMicroSeconds() +{ + auto tp = std::chrono::time_point_cast(std::chrono::system_clock::now()); + return tp.time_since_epoch().count(); +} +} // namespace detail + +TimeType TimeStamp::systemStartTimePoint = detail::SystemClockMicroSeconds() - detail::SteadyClockMicroSeconds(); + +TimeStamp TimeStamp::Now() noexcept +{ + return TimeStamp(detail::SteadyClockMicroSeconds() + systemStartTimePoint); +} + +TimeStamp TimeStamp::SystemStartTime() noexcept +{ + return TimeStamp(systemStartTimePoint); +} + +std::string TimeStamp::ToString(TimePrecision precision) const noexcept +{ + TimeType seconds = microSecondsSinceEpoch_ / MICRO_SECS_PER_SECOND; + TimeType micros = microSecondsSinceEpoch_ % MICRO_SECS_PER_SECOND; + + std::stringstream ss; + ss << seconds << "." << std::setfill('0'); + switch (precision) { + case TimePrecision::SECOND: { + ss << std::setw(3) << 0; + break; + } + case TimePrecision::MILLI: { + TimeType millis = micros / MICRO_SECS_PER_MILLISECOND; + ss << std::setw(3) << millis; + break; + } + case TimePrecision::MICRO: { + ss << std::setw(6) << micros; + break; + } + default: + break; + } + + return ss.str(); +} + +std::string TimeStamp::ToFormattedString(TimePrecision precision) const noexcept +{ + TimeType seconds = microSecondsSinceEpoch_ / MICRO_SECS_PER_SECOND; + TimeType micros = microSecondsSinceEpoch_ % MICRO_SECS_PER_SECOND; + + std::stringstream ss; + ss << std::put_time(::localtime(&seconds), "%F %X") << "." << std::setfill('0'); + switch (precision) { + case TimePrecision::SECOND: { + ss << std::setw(3) << 0; + break; + } + case TimePrecision::MILLI: { + TimeType millis = micros / MICRO_SECS_PER_MILLISECOND; + ss << std::setw(3) << millis; + break; + } + case TimePrecision::MICRO: { + ss << std::setw(6) << micros; + break; + } + default: + break; + } + + return ss.str(); +} +} // namespace oewm diff --git a/display_server/drivers/hal/base/timestamp.h b/display_server/drivers/hal/base/timestamp.h new file mode 100644 index 0000000..88b8da0 --- /dev/null +++ b/display_server/drivers/hal/base/timestamp.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "types.h" + +namespace oewm { +constexpr int MILLI_SECS_PER_SECOND = 1000; +constexpr int MICRO_SECS_PER_MILLISECOND = 1000; +constexpr int MICRO_SECS_PER_SECOND = MICRO_SECS_PER_MILLISECOND * MILLI_SECS_PER_SECOND; +constexpr int NANO_SECS_PER_MICROSECOND = 1000; +constexpr int NANO_SECS_PER_MILLISECOND = NANO_SECS_PER_MICROSECOND * MICRO_SECS_PER_MILLISECOND; +constexpr int NANO_SECS_PER_SECOND = NANO_SECS_PER_MILLISECOND * MILLI_SECS_PER_SECOND; + +enum class TimePrecision { SECOND, MILLI, MICRO }; + +// copyable +class TimeStamp { +public: + TimeStamp() noexcept = default; + + constexpr explicit TimeStamp(TimeType microSecondsSinceEpoch) noexcept + : microSecondsSinceEpoch_(microSecondsSinceEpoch) + {} + + static TimeStamp SystemStartTime() noexcept; + static TimeStamp Now() noexcept; + static TimeStamp Invalid() noexcept + { + return TimeStamp(); + } + + TimeType Get() const noexcept + { + return microSecondsSinceEpoch_; + } + TimeType Micros() const noexcept + { + return Get(); + } + TimeType Nanos() const noexcept + { + return Micros() * NANO_SECS_PER_MICROSECOND; + } + TimeType Millis() const noexcept + { + return Micros() / MICRO_SECS_PER_MILLISECOND; + } + TimeType Seconds() const noexcept + { + return Millis() / MILLI_SECS_PER_SECOND; + } + + std::string ToString(TimePrecision precision = TimePrecision::MILLI) const noexcept; + std::string ToFormattedString(TimePrecision precision = TimePrecision::MILLI) const noexcept; + +private: + static TimeType systemStartTimePoint; + TimeType microSecondsSinceEpoch_ = 0; +}; + +inline bool operator==(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() == rhs.Get(); +} + +inline bool operator<(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() < rhs.Get(); +} + +inline bool operator<=(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() <= rhs.Get(); +} + +inline bool operator>(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() > rhs.Get(); +} + +inline bool operator>=(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() >= rhs.Get(); +} + +inline bool operator!=(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() != rhs.Get(); +} + +// return two timeStamps' diff in micros +inline int64_t TimeDiff(TimeStamp lhs, TimeStamp rhs) +{ + return lhs.Get() - rhs.Get(); +} + +// @micros: add micros seconds to timestamp t. +// @return: timestamp t + micro seconds +inline TimeStamp TimeAdd(TimeStamp t, TimeType micros) +{ + return TimeStamp(t.Micros() + micros); +} +} // namespace oewm diff --git a/display_server/drivers/hal/base/types.h b/display_server/drivers/hal/base/types.h new file mode 100644 index 0000000..d425c4f --- /dev/null +++ b/display_server/drivers/hal/base/types.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#define UNUSED(val) (void)val; +#ifndef NDEBUG +#include +#define ASSERT(exp) assert((exp)) +#else // NDEBUG +#define ASSERT(exp) UNUSED((exp)) +#endif // NDEBUG + +#ifdef __cplusplus +#define OE_LIKELY(x) (__builtin_expect(!!(x), true)) +#define OE_UNLIKELY(x) (__builtin_expect(!!(x), false)) +#else +#define OE_LIKELY(x) (__builtin_expect(!!(x), 1)) +#define OE_UNLIKELY(x) (__builtin_expect(!!(x), 0)) +#endif + +namespace oewm { +template +inline constexpr typename std::underlying_type::type ECast(EnumType e) +{ + return static_cast::type>(e); +} + +using ThreadId = pid_t; +using ProcessId = pid_t; +using FileSize = std::uintmax_t; +using TimeType = int64_t; + +inline constexpr bool IsInvalidFd(int fd) +{ + return fd < 0; +} + +constexpr int INVALID_FD = -1; + +template +inline Derived DownCast(Base base) +{ + return static_cast(base); +} + +template +inline void AppendFormat(std::string &out, const char *fmt, Args &&...args) +{ + static constexpr int STRING_BUFFER_SIZE = 4096; + char buf[STRING_BUFFER_SIZE] = {0}; + ::snprintf(buf, sizeof(buf) - 1, fmt, args...); + out += buf; +} + +inline std::string ErrnoToString(int errorNum) +{ + static constexpr int BUFFER_LEN = 256; + char buf[BUFFER_LEN] = {0}; + return strerror_r(errorNum, buf, sizeof(buf)); +} + +inline double Random(double low, double high) +{ + static std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_real_distribution dist(low, high); + return dist(mt); +} + +template +// Remove const, volatile and reference qualifiers from type T +using RemoveCVRefType = std::remove_cv_t>; + +// Extract type traits of FromType and ToType. +template +struct ConvertTypeTraits { + // FromType traits. + using RawFromType = RemoveCVRefType; + using FromTypeLimits = std::numeric_limits; + constexpr static auto fromTypeMax = FromTypeLimits::max(); + constexpr static auto fromTypeMin = FromTypeLimits::lowest(); + + // ToType traits. + using RawToType = RemoveCVRefType; + using ToTypeLimits = std::numeric_limits; + constexpr static auto toTypeMax = ToTypeLimits::max(); + constexpr static auto toTypeMin = ToTypeLimits::lowest(); + + // CommonType traits. + using CommonType = std::common_type_t; + using CommonTypeLimits = std::numeric_limits; + constexpr static auto commonTypeMax = CommonTypeLimits::max(); + constexpr static auto commonTypeMin = CommonTypeLimits::lowest(); + constexpr static bool isCommonTypeInteger = CommonTypeLimits::is_integer; +}; + +// Ensure that a value of FromType can be represented for ToType, +// and clamp the FromType value to the ToType's range if necessary. +template +inline constexpr RemoveCVRefType clamp(FromType value) +{ + using TypeTraits = ConvertTypeTraits; + using CommonType = typename TypeTraits::CommonType; + constexpr auto commonClampMax = + std::min(static_cast(TypeTraits::fromTypeMax), static_cast(TypeTraits::toTypeMax)); + constexpr auto commonClampMin = + std::max(static_cast(TypeTraits::fromTypeMin), static_cast(TypeTraits::toTypeMin)); + constexpr bool needClamp = + (commonClampMax != TypeTraits::fromTypeMax) || (commonClampMin != TypeTraits::fromTypeMin); + if constexpr (!needClamp) { + return static_cast(value); + } + + // Do clamp. + const auto toClampMax = static_cast(commonClampMax); + const auto toClampMin = static_cast(commonClampMin); + if (static_cast(value) <= toClampMin) { + return toClampMin; + } + if (static_cast(value) >= toClampMax) { + return toClampMax; + } + + return static_cast(value); +} + +template +inline void HashCombineOne(size_t &combinedHash, const T &value) +{ + combinedHash = (sizeof(size_t) * 8 - 1) * combinedHash + std::hash{}(value); +} + +template +inline size_t HashCombine(const Args &...args) +{ + size_t hash = 0; + (HashCombineOne(hash, args), ...); + return hash; +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/BUILD.gn b/display_server/drivers/hal/core/BUILD.gn new file mode 100644 index 0000000..3ada030 --- /dev/null +++ b/display_server/drivers/hal/core/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Huawei Device 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. diff --git a/display_server/drivers/hal/core/drm_backend/BUILD.gn b/display_server/drivers/hal/core/drm_backend/BUILD.gn new file mode 100644 index 0000000..203b33e --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2022 Huawei Device 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. +import("//build/gn/fangtian.gni") + +config("import_system_drm_config") { + cflags = [ "-DUSE_LIBUDEV=1" ] + include_dirs = [ + "/usr/include/libdrm", + "/usr/local/include/libdrm", + ] + libs = [ + "drm", + "udev", + ] +} + +config("import_system_gbm_config") { + cflags = [ "-DDRM_BACKEND_USE_GBM=1" ] + libs = [ "gbm" ] +} + +ft_source_set("display_drm_dep") { + if (current_cpu != target_cpu && target_cpu == "aarch64") { + print("[GN ERROR] TODO: cross compile for DRM") + } else { + public_configs = [ ":import_system_drm_config" ] + } +} + +group("drm_backend") { + public_configs = [ + "display_device:display_device_public_config", + "display_gralloc:display_gralloc_public_config", + ] + public_deps = [ + "display_device:display_device", + "display_gralloc:display_gralloc", + ] +} diff --git a/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn b/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn new file mode 100644 index 0000000..85c9ac4 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2022 Huawei Device 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. +import("//build/gn/fangtian.gni") + +config("display_device_public_config") { + include_dirs = [ + "//display_server/drivers/hal/core/drm_backend/display_device", + "//display_server/drivers/hal/core/drm_backend/include", + + "//display_server/drivers/interfaces", + "//display_server/drivers/base", + ] +} + +ft_shared_library("display_device") { + sources = [ + "device_event_monitor.cpp", + "drm_atomic_committer.cpp", + "drm_connector.cpp", + "drm_crtc.cpp", + "drm_device.cpp", + "drm_display.cpp", + "drm_encoder.cpp", + "drm_frame_buffer.cpp", + "drm_layer.cpp", + "drm_mode_info.cpp", + "drm_plane.cpp", + "drm_property.cpp", + "hdi_display.cpp", + "hdi_layer.cpp", + "hdi_session.cpp", + ] + + configs = [ + "//display_server/drivers/hal:oehal_public_config", + ] + public_configs = [ + ":display_device_public_config", + "//display_server/drivers/hal/core/drm_backend:import_system_gbm_config" + ] + + public_deps = [ + "//display_server/drivers/hal/core/drm_backend:display_drm_dep", + "//display_server/drivers/hal/base:oebase", + ] + + deps = [ + "//display_server/utils/sync_fence/ft_build:sync_fence", + "//display_server/drivers/hal/core/event_loop:event_loop", + ] +} diff --git a/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp b/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp new file mode 100644 index 0000000..c149a4f --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "device_event_monitor.h" + +#include "drm_atomic_committer.h" +#include "hdi_display.h" +#include "base/log.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +namespace detail { +// GetFrameCnt for soft vsync. +uint32_t GetFrameCnt() +{ + static std::atomic frame{0}; + return frame++; +} +} // namespace detail + +#ifdef USE_LIBUDEV +DeviceEventMonitor::DeviceEventMonitor( + struct udev *udevice, + std::shared_ptr drmDevice, + HotPlugEventCallback hotPlugEventCallback, + TimeType softVsyncPeriod) + : loopThread_("DeviceMonitorLoopThread"), + drmDevice_(std::move(drmDevice)), + udev_(udevice), + udevMonitor_(udev_monitor_new_from_netlink(udev_, "udev"), udev_monitor_unref), + hotplugEventCallback_(std::move(hotPlugEventCallback)), + drmEventContext_(std::make_unique()), + softVsyncPeriod_(softVsyncPeriod) +{} +#else // USE_LIBUDEV +DeviceEventMonitor::DeviceEventMonitor(std::shared_ptr drmDevice, TimeType softVsyncPeriod) + : loopThread_("DeviceMonitorLoopThread"), + drmDevice_(std::move(drmDevice)), + drmEventContext_(std::make_unique()), + softVsyncPeriod_(softVsyncPeriod) +{} +#endif // USE_LIBUDEV + +DeviceEventMonitor::~DeviceEventMonitor() noexcept +{ + if (loop_ == nullptr) { + return; + } + + if (softVsyncTimer_ != nullptr) { + loop_->Cancel(softVsyncTimer_); + } + + auto future = loop_->Schedule([this]() { + vsyncChannel_->DisableAll(); + hotplugChannel_->DisableAll(); + }); + future.wait(); +} + +bool DeviceEventMonitor::CheckDeviceStatus() +{ + if (drmDevice_ == nullptr) { + LOG_ERROR("DeviceEventMonitor::Init failed: drmDevice_ is nullptr."); + return false; + } + dupDrmFd_ = OHOS::UniqueFd(::dup(drmDevice_->Fd())); + +#ifdef USE_LIBUDEV + if (udev_ == nullptr) { + LOG_ERROR("DeviceEventMonitor::Init failed: udev_ is nullptr."); + return false; + } + + if (udevMonitor_ == nullptr) { + LOG_ERROR("DeviceEventMonitor::Init failed: udevMonitor_ is nullptr."); + return false; + } + + udev_monitor_filter_add_match_subsystem_devtype(udevMonitor_.Get(), "drm", nullptr); + udevMonitorFd_ = OHOS::UniqueFd(udev_monitor_get_fd(udevMonitor_.Get())); + if (IsInvalidFd(udevMonitorFd_)) { + LOG_ERROR("DeviceEventMonitor::Init failed: udevMonitorFd_(%{public}i) is invalid.", udevMonitorFd_.Get()); + return false; + } +#endif // USE_LIBUDEV + + return true; +} + +#ifdef USE_LIBUDEV +void DeviceEventMonitor::OnUdevMonitorEvent(TimeStamp timeStamp) +{ + UdevObject event(udev_monitor_receive_device(udevMonitor_.Get()), udev_device_unref); + if (event == nullptr) { + return; + } + + // check if this event is hotplug event. + const char *val = udev_device_get_property_value(event.Get(), "HOTPLUG"); + if (val == nullptr || strcmp(val, "1") != 0) { + return; + } + + if (hotplugEventCallback_ != nullptr) { + hotplugEventCallback_(timeStamp, event.Get()); + } +} + +bool DeviceEventMonitor::RegisterUdevMonitorEventHandler() +{ + hotplugChannel_ = std::make_unique(udevMonitorFd_, loop_); + hotplugChannel_->SetReadCallback([this](TimeStamp timestamp) { OnUdevMonitorEvent(timestamp); }); + hotplugChannel_->EnableReading(true); + + auto ret = udev_monitor_enable_receiving(udevMonitor_.Get()); + if (ret < 0) { + LOG_ERROR("Failed to enable udev-monitor receiving, err: %{public}s", ErrnoToString(errno).c_str()); + return false; + } + + return true; +} +#endif // USE_LIBUDEV + +void DeviceEventMonitor::DrmPageFlipHandler(int fd, uint32_t sequence, uint32_t sec, uint32_t usec, void *data) +{ + auto display = reinterpret_cast(data); + if (OE_UNLIKELY(display == nullptr)) { + LOG_ERROR("DeviceEventMonitor::DrmPageFlipHandler: can not find display instance, user data is nullptr!"); + return; + } + + UNUSED(fd); + + // DRM timestamp is MONOTONIC and our timestamp is REALTIME. + TimeStamp timeStamp( + static_cast(sec) * MICRO_SECS_PER_SECOND + static_cast(usec)); + LOG_DEBUG("DeviceEventMonitor::DrmPageFlipHandler, timestamp: %{public}s", timeStamp.ToFormattedString().c_str()); + display->OnVSync(sequence, static_cast(timeStamp.Nanos())); +} + +void DeviceEventMonitor::OnDrmVsyncEvent(TimeStamp timeStamp) +{ + UNUSED(timeStamp); + drmHandleEvent(dupDrmFd_, drmEventContext_.get()); +} + +void DeviceEventMonitor::OnSoftVsyncEvent(TimeStamp monotonicTimeStamp) +{ + auto frame = detail::GetFrameCnt(); + auto displays = drmDevice_->GetDisplays(); + for (auto &[displayId, display] : displays) { + // LOG_DEBUG("display %{public}u vsync...", displayId); + display->OnVSync(frame, static_cast(monotonicTimeStamp.Nanos())); + } +} + +void DeviceEventMonitor::RegisterVsyncEventHandler() +{ +#ifdef ENABLE_HARDWARE_VSYNC + if (drmDevice_->SupportAtomicModeSet()) { + // TODO: drmEventContext VERSION + drmEventContext_->version = 3; + drmEventContext_->page_flip_handler = DrmPageFlipHandler; + vsyncChannel_ = std::make_unique(dupDrmFd_, loop_); + vsyncChannel_->SetReadCallback([this](TimeStamp timestamp) { OnDrmVsyncEvent(timestamp); }); + vsyncChannel_->EnableReading(true); + LOG_INFO("DeviceEventMonitor::RegisterVsyncEventHandler done by atomic mode setting."); + } else { +#endif // ENABLE_HARDWARE_VSYNC + // use soft vsync. + softVsyncTimer_ = loop_->RunEvery([this]() { + TimeStamp timestamp(TimeDiff(TimeStamp::Now(), TimeStamp::SystemStartTime())); + OnSoftVsyncEvent(timestamp); + }, softVsyncPeriod_); + LOG_INFO("DeviceEventMonitor::RegisterVsyncEventHandler done by soft timer."); +#ifdef ENABLE_HARDWARE_VSYNC + } +#endif // ENABLE_HARDWARE_VSYNC +} + +bool DeviceEventMonitor::Init() +{ + loop_ = loopThread_.Start(); + if (loop_ == nullptr) { + LOG_ERROR("Failed to start loop thread %{public}s", loopThread_.Name().c_str()); + return false; + } + + auto future = loop_->Schedule([this]() -> bool { + if (!CheckDeviceStatus()) { + return false; + } + +#ifdef USE_LIBUDEV + if (!RegisterUdevMonitorEventHandler()) { + return false; + } +#endif // USE_LIBUDEV + RegisterVsyncEventHandler(); + return true; + }); + return future.get(); +} +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h b/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h new file mode 100644 index 0000000..51386d3 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "drm_common.h" +#include "drm_device.h" +#include "event_loop/event_loop_thread.h" +#include "udev_object_helper.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +class DeviceEventMonitor : NonCopyable { +public: +#ifdef USE_LIBUDEV + using HotPlugEventCallback = std::function; +#endif // USE_LIBUDEV + using VsyncEventCallback = std::function; + // If drm device do not support atomic caps, we will use soft vsync, + // and the soft refresh rate would be solid to 60Hz. + static constexpr TimeType DEFAULT_SOFTWARE_VSYNC_PERIOD = 16667; // micro seconds. + +public: +#ifdef USE_LIBUDEV + DeviceEventMonitor( + struct udev *udevice, + std::shared_ptr drmDevice, + HotPlugEventCallback hotPlugEventCallback, + TimeType softVsyncPeriod = DEFAULT_SOFTWARE_VSYNC_PERIOD); +#else // USE_LIBUDEV + DeviceEventMonitor( + std::shared_ptr drmDevice, + TimeType softVsyncPeriod = DEFAULT_SOFTWARE_VSYNC_PERIOD); +#endif // USE_LIBUDEV + ~DeviceEventMonitor() noexcept; + + bool Init(); + +private: +#ifdef USE_LIBUDEV + void OnUdevMonitorEvent(TimeStamp timeStamp); + bool RegisterUdevMonitorEventHandler(); +#endif // USE_LIBUDEV + static void DrmPageFlipHandler(int fd, uint32_t sequence, uint32_t sec, uint32_t usec, void *data); + void OnDrmVsyncEvent(TimeStamp timeStamp); + void OnSoftVsyncEvent(TimeStamp monotonicTimeStamp); + void RegisterVsyncEventHandler(); + bool CheckDeviceStatus(); + + EventLoopThread loopThread_; + EventLoop *loop_ = nullptr; + + std::shared_ptr drmDevice_; + OHOS::UniqueFd dupDrmFd_; + std::unique_ptr hotplugChannel_; + +#ifdef USE_LIBUDEV + struct udev *udev_ = nullptr; + OHOS::UniqueFd udevMonitorFd_; + UdevObject udevMonitor_; + HotPlugEventCallback hotplugEventCallback_ = nullptr; +#endif // USE_LIBUDEV + + // for drm vsync event if drm device supported atomic modesetting. + std::unique_ptr drmEventContext_; + std::unique_ptr vsyncChannel_; + // for soft vsync. + TimeType softVsyncPeriod_ = DEFAULT_SOFTWARE_VSYNC_PERIOD; + TimerId softVsyncTimer_; +}; +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp new file mode 100644 index 0000000..41b79ac --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_atomic_committer.h" + +#include "drm_display.h" +#include "base/log.h" + +namespace oewm { +namespace drm { +DrmAtomicCommitter::DrmAtomicCommitter(int drmFd, int flags, void *userData) + : drmFd_(drmFd), req_(drmModeAtomicAlloc()), flags_(flags), userData_(userData) +{} + +DrmAtomicCommitter::~DrmAtomicCommitter() noexcept +{ + drmModeAtomicFree(req_); +} + +void DrmAtomicCommitter::AddAtomicProperty(uint32_t objId, uint32_t propId, uint64_t value) +{ + if (OE_UNLIKELY(req_ == nullptr)) { + LOG_ERROR("DrmAtomicCommitter::AddAtomicProperty: req_ is nullptr!"); + return; + } + + int ret = drmModeAtomicAddProperty(req_, objId, propId, value); + if (ret < 0) { + LOG_WARN("drmModeAtomicAddProperty failed, err: %{public}s", ErrnoToString(errno).c_str()); + } +} + +void DrmAtomicCommitter::Commit() +{ + LOG_DEBUG("DrmAtomicCommitter::Commit: drmFd: %{public}i, flags: %{public}i, userData: %{public}p", drmFd_, flags_, userData_); + int ret = drmModeAtomicCommit(drmFd_, req_, flags_, userData_); + if (ret < 0) { + LOG_ERROR("DrmAtomicCommitter::Commit: failed, err: %{public}d, %{public}s", ret, ErrnoToString(errno).c_str()); + } +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h new file mode 100644 index 0000000..852fd15 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "drm_common.h" + +namespace oewm { +namespace drm { +// RAII object for drm auto atomic committing. +class DrmAtomicCommitter : NonCopyable { +public: + explicit DrmAtomicCommitter( + int drmFd, + int flags, + void *userData = nullptr); + ~DrmAtomicCommitter() noexcept; + + void AddAtomicProperty(uint32_t objId, uint32_t propId, uint64_t value); + void Commit(); + +private: + int drmFd_ = INVALID_FD; + drmModeAtomicReqPtr req_; + int flags_; + void *userData_ = nullptr; +}; +} // namespace drm +} // namespace oewm \ No newline at end of file diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_common.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_common.h new file mode 100644 index 0000000..fcf4a3f --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_common.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include "base/noncopyable.h" +#include "base/types.h" + +namespace oewm { +namespace drm { +constexpr uint32_t DRM_INVALID_OBJECT_ID = 0; +constexpr uint32_t DRM_INVALID_OBJECT_TYPE = 0; +constexpr uint32_t DRM_INVALID_PROP_ID = 0; +constexpr uint32_t DRM_INVLIAD_SIZE = 0; +constexpr uint64_t DRM_INVLIAD_VALUE = ~(0x0); + +template +using IdMapPtr = std::unordered_map>; + +inline std::string DrmObjTypeToString(uint32_t objType) +{ + switch (objType) { + case DRM_MODE_OBJECT_CRTC: + return "DRM_MODE_OBJECT_CRTC"; + case DRM_MODE_OBJECT_CONNECTOR: + return "DRM_MODE_OBJECT_CONNECTOR"; + case DRM_MODE_OBJECT_ENCODER: + return "DRM_MODE_OBJECT_ENCODER"; + case DRM_MODE_OBJECT_MODE: + return "DRM_MODE_OBJECT_MODE"; + case DRM_MODE_OBJECT_PROPERTY: + return "DRM_MODE_OBJECT_PROPERTY"; + case DRM_MODE_OBJECT_FB: + return "DRM_MODE_OBJECT_FB"; + case DRM_MODE_OBJECT_BLOB: + return "DRM_MODE_OBJECT_BLOB"; + case DRM_MODE_OBJECT_PLANE: + return "DRM_MODE_OBJECT_PLANE"; + case DRM_MODE_OBJECT_ANY: + return "DRM_MODE_OBJECT_ANY"; + default: + return "DRM_MODE_OBJECT_UNKNOWN"; + } +} + +inline std::string ObjInfoDump(uint32_t objId, uint32_t objType) +{ + return "DrmObject [id: " + std::to_string(objId) + ", type: " + DrmObjTypeToString(objType) + "]"; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp new file mode 100644 index 0000000..f20ee9c --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_connector.h" + +#include "display_type.h" +#include "drm_mode.h" +#include "base/log.h" +#include "drm_property.h" + +namespace oewm { +namespace drm { +DrmConnector::DrmConnector(int drmFd, uint32_t connectorId) : drmFd_(drmFd), id_(connectorId) +{ + auto conn = drmModeGetConnector(drmFd_, id_); + if (conn == nullptr) { + LOG_ERROR("Failed to get drm connector for connector id: %{public}u", id_); + return; + } + ParseFrom(conn); + drmModeFreeConnector(conn); +} + +DrmConnector::~DrmConnector() noexcept {} + +bool DrmConnector::FindCrtcId(const IdMapPtr &encoders, const IdMapPtr &crtcs, uint32_t &crtcId) +{ + if (encoders.count(encoderId_) != 0) { + if (encoders.at(encoderId_)->FindCrtcId(crtcs, crtcId)) { + return true; + } + } + + for (auto encoderId : possibleEncoders_) { + if (encoders.count(encoderId) != 0) { + if (encoders.at(encoderId)->FindCrtcId(crtcs, crtcId)) { + return true; + } + } + } + + LOG_ERROR("cannot find a suitable crtc for connector %{public}u", id_); + return false; +} + +InterfaceType DrmConnector::ToHdiConnType(uint32_t drmConnType) +{ + switch (drmConnType) { + case DRM_MODE_CONNECTOR_VGA: + return DISP_INTF_VGA; + case DRM_MODE_CONNECTOR_DSI: + return DISP_INTF_MIPI; + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + return DISP_INTF_HDMI; + default: + return DISP_INTF_BUTT; + } +} + +std::string DrmConnector::TypeToName(uint32_t connType, uint32_t connTypeId) +{ + static std::unordered_map connTypeNames = { + {DRM_MODE_CONNECTOR_Unknown, "Unknown"}, + {DRM_MODE_CONNECTOR_VGA, "VGA"}, + {DRM_MODE_CONNECTOR_DVII, "DVI-I"}, + {DRM_MODE_CONNECTOR_DVID, "DVI-D"}, + {DRM_MODE_CONNECTOR_DVIA, "DVI-A"}, + {DRM_MODE_CONNECTOR_Composite, "Composite"}, + {DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO"}, + {DRM_MODE_CONNECTOR_LVDS, "LVDS"}, + {DRM_MODE_CONNECTOR_Component, "Component"}, + {DRM_MODE_CONNECTOR_9PinDIN, "DIN"}, + {DRM_MODE_CONNECTOR_DisplayPort, "DP"}, + {DRM_MODE_CONNECTOR_HDMIA, "HDMI-A"}, + {DRM_MODE_CONNECTOR_HDMIB, "HDMI-B"}, + {DRM_MODE_CONNECTOR_TV, "TV"}, + {DRM_MODE_CONNECTOR_eDP, "eDP"}, + {DRM_MODE_CONNECTOR_VIRTUAL, "Virtual"}, + {DRM_MODE_CONNECTOR_DSI, "DSI"}, + {DRM_MODE_CONNECTOR_DPI, "DPI"}, + {DRM_MODE_CONNECTOR_WRITEBACK, "WriteBack"}}; + // {DRM_MODE_CONNECTOR_SPI, "SPI"}, + // {DRM_MODE_CONNECTOR_USB, "USB"}}; + + std::string id = std::to_string(connTypeId); + if (connTypeNames.count(connType) == 0) { + return "Unknown-" + id; + } + + return connTypeNames[connType] + "-" + id; +} + +void DrmConnector::InitModes(drmModeConnectorPtr const &conn) +{ + for (int i = 0; i != conn->count_modes; ++i) { + modes_.push_back(std::make_unique(conn->modes[i], i, drmFd_)); + } +} + +void DrmConnector::ParseFrom(const drmModeConnectorPtr &conn) +{ + encoderId_ = conn->encoder_id; + for (int i = 0; i < conn->count_encoders; i++) { + possibleEncoders_.push_back(conn->encoders[i]); + } + connType_ = conn->connector_type; + connTypeId_ = conn->connector_type_id; + connStatus_ = conn->connection; + phyWidth_ = conn->mmWidth; + phyHeight_ = conn->mmHeight; + subPixel_ = conn->subpixel; + InitModes(conn); + DrmObjectPropertyFetcher connPropFetcher(drmFd_, id_, DRM_MODE_OBJECT_CONNECTOR); + crtcPropId_ = connPropFetcher.GetPropId(PROP_CRTCID); + dpmsPropId_ = connPropFetcher.GetPropId(PROP_DPMS); + dpms_ = connPropFetcher.GetPropValue(PROP_DPMS); + brightnessPropId_ = connPropFetcher.GetPropId(PROP_BRIGHTNESS); + brightness_ = connPropFetcher.GetPropValue(PROP_BRIGHTNESS); +} + +uint64_t DrmConnector::BlobId() const +{ + if (OE_UNLIKELY(activeModeId_ > modes_.size())) { + return DRM_INVALID_OBJECT_ID; + } + + return modes_[activeModeId_]->BlobId(); +} + +void DrmConnector::GetDisplayCapability(DisplayCapability *cap) const +{ + auto typeName = TypeToName(connType_, connTypeId_); + std::move(typeName.begin(), typeName.end(), cap->name); + cap->type = ToHdiConnType(connType_); + cap->phyWidth = phyWidth_; + cap->phyHeight = phyHeight_; + + // these are not supported yet. + cap->supportLayers = 0; + cap->virtualDispCount = 0; + cap->propertyCount = 0; + cap->props = nullptr; +} + +void DrmConnector::GetSupportedModes(uint32_t *num, DisplayModeInfo *modes) const +{ + *num = static_cast(modes_.size()); + + if (modes == nullptr) { + return; + } + for (uint32_t i = 0; i != *num; ++i) { + modes[i] = modes_[i]->ToHdiModeInfo(); + } +} + +bool DrmConnector::SetActiveModeId(uint32_t modeId) +{ + if (modeId >= static_cast(modes_.size())) { + LOG_ERROR("DrmConnector::SetActiveModeId invalid modeId(%{public}u) by range [0, %{public}zu]", modeId, modes_.size()); + return false; + } + activeModeId_ = modeId; + return true; +} + +bool DrmConnector::SetDpms(uint64_t dpms) +{ + int ret = drmModeConnectorSetProperty(drmFd_, id_, dpmsPropId_, dpms); + if (ret != 0) { + LOG_ERROR("DrmConnector::SetDpms drmModeConnectorSetProperty failed, err: %{public}s", ErrnoToString(errno).c_str()); + return false; + } + dpms_ = dpms; + return true; +} + +bool DrmConnector::SetBrightness(uint64_t brightness) +{ + int ret = drmModeConnectorSetProperty(drmFd_, id_, brightnessPropId_, brightness); + if (ret != 0) { + LOG_ERROR("DrmConnector::SetBrightness drmModeConnectorSetProperty failed, err: %{public}s", ErrnoToString(errno).c_str()); + return false; + } + brightness_ = brightness; + return true; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h new file mode 100644 index 0000000..7dcb8ac --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "display_type.h" +#include "drm_mode_info.h" +#include "drm_encoder.h" +#include "drm_crtc.h" + +namespace oewm { +namespace drm { +// prop for connector +constexpr char PROP_CRTCID[] = "CRTC_ID"; +constexpr char PROP_DPMS[] = "DPMS"; +constexpr char PROP_BRIGHTNESS[] = "brightness"; +// typedef struct _drmModeConnector { +// uint32_t connector_id; +// uint32_t encoder_id; /**< Encoder currently connected to */ +// uint32_t connector_type; +// uint32_t connector_type_id; +// drmModeConnection connection; +// uint32_t mmWidth, mmHeight; /**< HxW in millimeters */ +// drmModeSubPixel subpixel; + +// int count_modes; +// drmModeModeInfoPtr modes; + +// int count_props; +// uint32_t *props; /**< List of property ids */ +// uint64_t *prop_values; /**< List of property values */ + +// int count_encoders; +// uint32_t *encoders; /**< List of encoder ids */ +// } drmModeConnector, *drmModeConnectorPtr; +class DrmConnector : NonCopyable { +public: + DrmConnector(int drmFd, uint32_t connectorId); + ~DrmConnector() noexcept; + + uint32_t Id() const + { + return id_; + } + + uint32_t EncoderId() const + { + return encoderId_; + } + + uint32_t ConnType() const + { + return connType_; + } + + uint32_t ConnTypeId() const + { + return connTypeId_; + } + + bool Connected() const + { + return connStatus_ == DRM_MODE_CONNECTED; + } + + // physical width in millimetres + uint32_t PhyWidth() const + { + return phyWidth_; + } + + // physical height in millimetres + uint32_t PhyHeight() const + { + return phyHeight_; + } + + uint32_t CrtcPropId() const + { + return crtcPropId_; + } + + uint32_t DpmsPropId() const + { + return dpmsPropId_; + } + + uint64_t Dpms() const + { + return dpms_; + } + + uint32_t BrightnessPropId() const + { + return brightnessPropId_; + } + + uint64_t brightness() const + { + return brightness_; + } + + uint64_t BlobId() const; + + void GetDisplayCapability(DisplayCapability *cap) const; + void GetSupportedModes(uint32_t *num, DisplayModeInfo *modes) const; + uint32_t GetActiveModeId() const + { + return activeModeId_; + } + bool SetActiveModeId(uint32_t modeId); + // display power manager status + uint64_t GetDpms() const + { + return dpms_; + } + bool SetDpms(uint64_t dpms); + uint64_t GetBrightness() const + { + return brightness_; + } + bool SetBrightness(uint64_t brightness); + + bool FindCrtcId(const IdMapPtr &encoders, const IdMapPtr &crtcs, uint32_t &crtcId); + bool FindPlane(const IdMapPtr &encoders, const IdMapPtr &crtcs, uint32_t &crtcId); + void GetMode(uint32_t modeId, drmModeModeInfo *mode) const + { + *mode = modes_[modeId]->ModeInfo(); + } + +private: + static InterfaceType ToHdiConnType(uint32_t drmConnType); + static std::string TypeToName(uint32_t connType, uint32_t connTypeId); + void InitModes(const drmModeConnectorPtr &conn); + void ParseFrom(const drmModeConnectorPtr &conn); + + int drmFd_ = INVALID_FD; + uint32_t id_ = DRM_INVALID_OBJECT_ID; + uint32_t encoderId_ = DRM_INVALID_OBJECT_ID; + std::vector possibleEncoders_; + uint32_t connType_ = DRM_MODE_CONNECTOR_Unknown; + uint32_t connTypeId_ = DRM_INVALID_OBJECT_ID; + drmModeConnection connStatus_ = DRM_MODE_CONNECTED; + uint32_t phyWidth_ = DRM_INVLIAD_SIZE; + uint32_t phyHeight_ = DRM_INVLIAD_SIZE; + drmModeSubPixel subPixel_; + uint32_t crtcPropId_ = DRM_INVALID_PROP_ID; + uint32_t dpmsPropId_ = DRM_INVALID_PROP_ID; + uint64_t dpms_ = DRM_INVLIAD_VALUE; + uint32_t brightnessPropId_ = DRM_INVALID_PROP_ID; + uint64_t brightness_ = DRM_INVLIAD_VALUE; + std::vector> modes_; + uint32_t activeModeId_ = 0; // mode 3 is 1920*1080 +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp new file mode 100644 index 0000000..9d93838 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_crtc.h" + +#include "hdi_display.h" +#include "base/log.h" +#include "drm_property.h" + +namespace oewm { +namespace drm { +DrmCrtc::DrmCrtc(int drmFd, uint32_t crtcId, uint32_t pipe) : drmFd_(drmFd), id_(crtcId), pipe_(pipe) +{ + auto crtc = drmModeGetCrtc(drmFd_, id_); + if (crtc == nullptr) { + LOG_ERROR("Failed to get drm crtc for crtc id: %{public}i", id_); + return; + } + ParseFrom(crtc); + drmModeFreeCrtc(crtc); +} + +DrmCrtc::~DrmCrtc() noexcept {} + +bool DrmCrtc::BindToDisplay(uint32_t id) +{ + if (displayId_ != HDI::DISPLAY::INVALID_DISPLAY_ID) { + LOG_ERROR("the crtc has bind to display id: %{public}" PRIu32 ".", displayId_); + return false; + } + displayId_ = id; + LOG_DEBUG("the crtc : %i bind to display id: %u", id_, displayId_); + return true; +} + +void DrmCrtc::UnBindDisplay(uint32_t id) +{ + if (displayId_ == id) { + displayId_ = HDI::DISPLAY::INVALID_DISPLAY_ID; + } else { + LOG_ERROR("can not unbind"); + } +} + +bool DrmCrtc::CanBind() +{ + return (displayId_ == HDI::DISPLAY::INVALID_DISPLAY_ID); +} + +// typedef struct _drmModeCrtc { +// uint32_t crtc_id; +// uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */ +// +// uint32_t x, y; /**< Position on the framebuffer */ +// uint32_t width, height; +// int mode_valid; +// drmModeModeInfo mode; +// +// int gamma_size; /**< Number of gamma stops */ +// +//} drmModeCrtc, *drmModeCrtcPtr; +void DrmCrtc::ParseFrom(drmModeCrtcPtr const &crtc) +{ + DrmObjectPropertyFetcher crtcPropFetcher(drmFd_, id_, DRM_MODE_OBJECT_CRTC); + modeIdPropId_ = crtcPropFetcher.GetPropId(PROP_MODEID); + activePropId_ = crtcPropFetcher.GetPropId(PROP_ACTIVE); + outFencePropId_ = crtcPropFetcher.GetPropId(PROP_OUTFENCE); +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h new file mode 100644 index 0000000..aadd9ec --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "base/noncopyable.h" +#include "drm_common.h" +#include "drm_property.h" +#include "hdi_display.h" + +namespace oewm { +namespace drm { +// prop for crtc +constexpr char PROP_MODEID[] = "MODE_ID"; +constexpr char PROP_ACTIVE[] = "ACTIVE"; +constexpr char PROP_OUTFENCE[] = "OUT_FENCE_PTR"; +// typedef struct _drmModeCrtc { +// uint32_t crtc_id; +// uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */ +// +// uint32_t x, y; /**< Position on the framebuffer */ +// uint32_t width, height; +// int mode_valid; +// drmModeModeInfo mode; +// +// int gamma_size; /**< Number of gamma stops */ +// +//} drmModeCrtc, *drmModeCrtcPtr; +class DrmCrtc : NonCopyable { +public: + DrmCrtc(int drmFd, uint32_t crtcId, uint32_t pipe); + ~DrmCrtc() noexcept; + int Id() const + { + return id_; + } + uint32_t ModeIdPropId() const + { + return modeIdPropId_; + } + uint32_t ActivePropId() const + { + return activePropId_; + } + uint32_t OutFencePropId() const + { + return outFencePropId_; + } + bool BindToDisplay(uint32_t id); + void UnBindDisplay(uint32_t id); + bool CanBind(); + uint32_t Pipe() const + { + return pipe_; + } + +private: + void ParseFrom(const drmModeCrtcPtr &crtc); + + int drmFd_ = INVALID_FD; + int id_ = DRM_INVALID_OBJECT_ID; + uint32_t modeIdPropId_ = DRM_INVALID_PROP_ID; + uint32_t activePropId_ = DRM_INVALID_PROP_ID; + uint32_t outFencePropId_ = DRM_INVALID_PROP_ID; + uint32_t displayId_ = HDI::DISPLAY::INVALID_DISPLAY_ID; + uint32_t pipe_ = 0; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp new file mode 100644 index 0000000..aa41ab9 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_device.h" + +#include +#include + +#include "drm_display.h" +#include "base/log.h" + +namespace oewm { +namespace drm { +std::shared_ptr DrmDevice::Create(std::string devicePath) +{ + std::shared_ptr device(new DrmDevice(std::move(devicePath))); + if (!device->Init()) { + return nullptr; + } + + return device; +} + +DrmDevice::DrmDevice(std::string devicePath) + : devicePath_(std::move(devicePath)), fd_(::open(devicePath_.c_str(), O_RDWR | O_CLOEXEC)) +{} + +DrmDevice::~DrmDevice() noexcept +{ + if (drmResource_ != nullptr) { + drmModeFreeResources(drmResource_); + } + +#ifdef DRM_BACKEND_USE_GBM + if (gbmDevice_ != nullptr) { + gbm_device_destroy(gbmDevice_); + } +#endif // DRM_BACKEND_USE_GBM +} + +void DrmDevice::SetupAllCrtcs() +{ + for (int i = 0; i != drmResource_->count_crtcs; ++i) { + auto crtcId = drmResource_->crtcs[i]; + crtcs_[crtcId] = std::make_shared(fd_, crtcId, i); + } +} + +void DrmDevice::SetupAllConnectors() +{ + for (int i = 0; i != drmResource_->count_connectors; ++i) { + auto connectorId = drmResource_->connectors[i]; + connectors_[connectorId] = std::make_shared(fd_, connectorId); + } +} + +void DrmDevice::SetupAllEncoders() +{ + for (int i = 0; i != drmResource_->count_encoders; ++i) { + auto encoderId = drmResource_->encoders[i]; + encoders_[encoderId] = std::make_shared(fd_, encoderId); + } +} + +void DrmDevice::SetupAllPlanes() +{ + drmModePlaneResPtr planeRes = drmModeGetPlaneResources(fd_); + if (planeRes == nullptr) { + LOG_ERROR("Failed to get plane resources."); + return; + } + for (uint32_t i = 0; i != planeRes->count_planes; ++i) { + auto planeId = planeRes->planes[i]; + planes_[planeId] = std::make_shared(fd_, planeId); + } +} + +bool DrmDevice::InitKmsCaps() +{ + uint64_t cap = DRM_INVLIAD_VALUE; + /** + * DRM_CAP_TIMESTAMP_MONOTONIC + * Starting from kernel version 2.6.39, the default value for this capability + * is 1. Starting kernel version 4.15, this capability is always set to 1. + */ + int ret = drmGetCap(fd_, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); + if (ret != 0 || cap != 1) { + LOG_ERROR("%{public}s DRM KMS does not support DRM_CAP_TIMESTAMP_MONOTONIC!", devicePath_.c_str()); + return false; + } + + ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if (ret) { + LOG_ERROR("%{public}s DRM KMS doesn't support universal planes! error: %{public}s", + devicePath_.c_str(), ErrnoToString(errno).c_str()); + return false; + } + + ret = drmGetCap(fd_, DRM_CAP_DUMB_BUFFER, &cap); + if (ret != 0 || cap == 0) { + LOG_ERROR("%{public}s DRM KMS doesn't support dumb buffers! error: %{public}s", + devicePath_.c_str(), ErrnoToString(errno).c_str()); + } + supportDumbBuffer_ = (cap != 0); + + if (::getenv("OEWM_DISABLE_ATOMIC") == nullptr) { + ret = drmGetCap(fd_, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap); + if (ret != 0) { + cap = 0; + } + ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_ATOMIC, 1); + // we will use legacy method to present fb to screens if supportAtomicModeSet_ = false. + supportAtomicModeSet_ = ((ret == 0) && (cap != 0)); + LOG_DEBUG("%{public}s supportAtomicModeSet: %{public}i", devicePath_.c_str(), supportAtomicModeSet_); + } + + if (::getenv("OEWM_DISABLE_GBM_MODIFIERS") == nullptr) { + ret = drmGetCap(fd_, DRM_CAP_ADDFB2_MODIFIERS, &cap); + if (ret == 0) { + supportGbmModifiers_ = (cap != 0); + } + } + + ret = drmGetCap(fd_, DRM_PRIME_CAP_IMPORT, &cap); + if (ret == 0) { + supportPrimeImport_ = (cap != 0); + } + + ret = drmGetCap(fd_, DRM_PRIME_CAP_EXPORT, &cap); + if (ret == 0) { + supportPrimeExport_ = (cap != 0); + } + + ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1); + if (ret != 0) { + LOG_WARN("%{public}s DRM KMS doesn't writeback connectors. error: %{public}s", devicePath_.c_str(), ErrnoToString(errno).c_str()); + } + + ret = drmSetClientCap(fd_, DRM_CLIENT_CAP_ASPECT_RATIO, 1); + if (ret == 0) { + supportAspectRatio_ = true; + } + + ret = drmGetCap(fd_, DRM_CAP_CURSOR_WIDTH, &cap); + if (ret == 0) { + cursorWidth_ = static_cast(cap); + } + + ret = drmGetCap(fd_, DRM_CAP_CURSOR_HEIGHT, &cap); + if (ret == 0) { + cursorHeight_ = static_cast(cap); + } + + return true; +} + +bool DrmDevice::Init() +{ + LOG_DEBUG("DrmDevice::Init"); + + if (IsInvalidFd(fd_)) { + LOG_ERROR("DrmDevice::Init: failed to open drm_device: %{public}s", devicePath_.c_str()); + return false; + } + +#ifdef DRM_BACKEND_USE_GBM + gbmDevice_ = gbm_create_device(fd_); + if (gbmDevice_ == nullptr) { + LOG_ERROR("DrmDevice::Init: failed to create gbm device."); + return false; + } +#endif // DRM_BACKEND_USE_GBM + + drmResource_ = drmModeGetResources(fd_); + if (drmResource_ == nullptr) { + return false; + } + + if (drmResource_->count_crtcs <= 0 || drmResource_->count_connectors <= 0 || drmResource_->count_encoders <= 0) { + LOG_ERROR("Drm device %{public}s is invalid.", devicePath_.c_str()); + return false; + } + + if (!InitKmsCaps()) { + return false; + } + + SetupAllCrtcs(); + SetupAllConnectors(); + SetupAllEncoders(); + SetupAllPlanes(); + DiscoveryDisplays(); + + LOG_DEBUG("DrmDevice::Init: done."); + + return true; +} + +std::shared_ptr DrmDevice::BuildHdiDisplayFromConnector( + uint32_t connectorIndex, + const std::shared_ptr &connector) +{ + uint32_t crtcId = 0; + if (!connector->FindCrtcId(encoders_, crtcs_, crtcId)) { + return nullptr; + } + + const auto &crtc = crtcs_.at(crtcId); + auto displayId = static_cast(connectorIndex); + crtc->BindToDisplay(displayId); + auto display = std::make_shared(fd_, displayId, connector, crtc); + if (!display->Init()) { + LOG_ERROR("DrmDevice::BuildHdiDisplayFromConnector display init failed"); + return nullptr; + } + + for (const auto &[planeId, plane] : planes_) { + UNUSED(planeId); + if (plane->GetPossibleCrtcs() & (1 << crtc->Pipe()) && plane->GetPlaneType() == DRM_PLANE_TYPE_PRIMARY) { + display->SetPrimaryPlane(plane); + } + } + + return display; +} + +void DrmDevice::DiscoveryDisplays() +{ + for (int i = 0; i != drmResource_->count_connectors; ++i) { + auto connectorId = drmResource_->connectors[i]; + if (connectors_.count(connectorId) == 0) { + LOG_ERROR("DrmDevice::DiscoveryDisplays: unexpected error: can not find connector for conId %{public}" PRIu32 ".", + connectorId); + continue; + } + + const auto &connector = connectors_.at(connectorId); + if (!connector->Connected()) { + LOG_INFO("DrmDevice::DiscoveryDisplays: ignore unused connector %{public}" PRIu32 ".", + connectorId); + continue; + } + + auto display = BuildHdiDisplayFromConnector(static_cast(i), connector); + if (display != nullptr) { + std::lock_guard lock(mutex_); + LOG_INFO("DrmDevice::DiscoveryDisplays: added display(%{public}u).", display->Id()); + displays_[display->Id()] = std::move(display); + } + } +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_device.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_device.h new file mode 100644 index 0000000..0e2e2be --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_device.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#ifdef DRM_BACKEND_USE_GBM +#include +#endif // DRM_BACKEND_USE_GBM + +#include "hdi_display.h" +#include "unique_fd.h" +#include "drm_crtc.h" +#include "drm_connector.h" +#include "drm_encoder.h" +#include "drm_plane.h" + +namespace oewm { +namespace drm { +class DrmDevice : private NonCopyable { +public: + static std::shared_ptr Create(std::string devicePath); + ~DrmDevice() noexcept; + + int Fd() const + { + return fd_; + } + + drmModeResPtr GetModeResources() const + { + return drmResource_; + } + + const std::string &DevicePath() const + { + return devicePath_; + } + + bool SupportDumbBuffer() const + { + return supportDumbBuffer_; + } + + bool SupportAtomicModeSet() const + { + return supportAtomicModeSet_; + } + + bool SupportGbmModifiers() const + { + return supportGbmModifiers_; + } + + bool SupportAspectRatio() const + { + return supportAspectRatio_; + } + + bool SupportPrimeImport() const + { + return supportPrimeImport_; + } + + bool SupportPrimeExport() const + { + return supportPrimeExport_; + } + + // TODO: SetCursorSize + int GetCursorWidth() const + { + return cursorWidth_; + } + int GetCursorHeight() const + { + return cursorHeight_; + } + + const std::unordered_map> &GetDisplays() const + { + std::lock_guard lock(mutex_); + return displays_; + } + std::unordered_map> &GetMutableDisplays() + { + std::lock_guard lock(mutex_); + return displays_; + } + +#ifdef DRM_BACKEND_USE_GBM + struct gbm_device *GetGbmDevice() const + { + return gbmDevice_; + } +#endif // DRM_BACKEND_USE_GBM + +private: + explicit DrmDevice(std::string devicePath); + bool InitKmsCaps(); + void SetupAllCrtcs(); + void SetupAllConnectors(); + void SetupAllEncoders(); + void SetupAllPlanes(); + std::shared_ptr BuildHdiDisplayFromConnector( + uint32_t connectorIndex, + const std::shared_ptr &connector); + void DiscoveryDisplays(); + bool Init(); + + std::string devicePath_; + OHOS::UniqueFd fd_; + +#ifdef DRM_BACKEND_USE_GBM + struct gbm_device *gbmDevice_ = nullptr; +#endif // DRM_BACKEND_USE_GBM + + static constexpr int DEFAULT_CURSOR_WIDTH = 64; + static constexpr int DEFAULT_CURSOR_HEIGHT = 64; + int cursorWidth_ = DEFAULT_CURSOR_WIDTH; + int cursorHeight_ = DEFAULT_CURSOR_HEIGHT; + + drmModeResPtr drmResource_ = nullptr; + + // drm capabilities + bool supportAtomicModeSet_ = false; + bool supportDumbBuffer_ = false; + bool supportGbmModifiers_ = false; + bool supportPrimeImport_ = false; + bool supportPrimeExport_ = false; + bool supportAspectRatio_ = false; + + IdMapPtr crtcs_; + IdMapPtr connectors_; + IdMapPtr encoders_; + IdMapPtr planes_; + + mutable std::mutex mutex_; + IdMapPtr displays_; // guarded by mutex_; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp new file mode 100644 index 0000000..8c9250a --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "drm_display.h" + +#include "sync_fence.h" +#include "drm_atomic_committer.h" +#include "base/log.h" + +#include "hdi_session.h" + +namespace oewm { +namespace drm { +DrmDisplay::DrmDisplay( + int drmFd, + HdiDisplayId id, + std::shared_ptr connector, + std::shared_ptr crtc) + : drmFd_(drmFd), id_(id), connector_(std::move(connector)), crtc_(std::move(crtc)) +{} + +DrmDisplay::~DrmDisplay() noexcept {} + +bool DrmDisplay::Init() +{ + LOG_DEBUG("DrmDisplay::Init"); + return HdiDisplay::Init(); +} + +int32_t DrmDisplay::GetDisplayCapability(DisplayCapability *info) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::GetDisplayCapability: connector for display id %{public}u is null!", id_); + return DISPLAY_NULL_PTR; + } + + connector_->GetDisplayCapability(info); + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::GetDisplaySupportedModes: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + connector_->GetSupportedModes(num, modes); + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayMode(uint32_t *modeId) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::GetDisplayMode: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + *modeId = connector_->GetActiveModeId(); + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayMode(uint32_t modeId) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::SetDisplayMode: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + if (!connector_->SetActiveModeId(modeId)) { + return DISPLAY_PARAM_ERR; + } + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayPowerStatus(DispPowerStatus *status) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::GetDisplayPowerStatus: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + *status = ToDispPowerStatus(connector_->GetDpms()); + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayPowerStatus(DispPowerStatus status) +{ + auto dpms = ToDpms(status); + if (dpms == DRM_INVLIAD_VALUE) { + LOG_ERROR("DrmDisplay::SetDisplayPowerStatus: status invalid!"); + return DISPLAY_PARAM_ERR; + } + + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::SetDisplayPowerStatus: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + if (!connector_->SetDpms(dpms)) { + return DISPLAY_FAILURE; + } + + return DISPLAY_SUCCESS; +} + +DispPowerStatus DrmDisplay::ToDispPowerStatus(uint64_t dpms) +{ + switch (dpms) { + case DRM_MODE_DPMS_OFF: + return POWER_STATUS_OFF; + case DRM_MODE_DPMS_ON: + return POWER_STATUS_ON; + case DRM_MODE_DPMS_STANDBY: + return POWER_STATUS_STANDBY; + case DRM_MODE_DPMS_SUSPEND: + return POWER_STATUS_SUSPEND; + default: + return POWER_STATUS_BUTT; + } +} + +uint64_t DrmDisplay::ToDpms(DispPowerStatus status) +{ + switch (status) { + case POWER_STATUS_OFF: + return DRM_MODE_DPMS_OFF; + case POWER_STATUS_ON: + return DRM_MODE_DPMS_ON; + case POWER_STATUS_STANDBY: + return DRM_MODE_DPMS_STANDBY; + case POWER_STATUS_SUSPEND: + return DRM_MODE_DPMS_SUSPEND; + default: + return DRM_INVLIAD_VALUE; + } +} + +std::unique_ptr DrmDisplay::CreateHdiLayer(HDI::DISPLAY::LayerId id, LayerType type) +{ + LOG_DEBUG("DrmDisplay::CreateHdiLayer"); + return std::make_unique(id, type); +} + +int32_t DrmDisplay::GetDisplayBacklight(uint32_t *value) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::GetDisplayBacklight: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + *value = static_cast(connector_->GetBrightness()); + + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayBacklight(uint32_t value) +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::SetDisplayBacklight: connector for display id %{public}" PRIu32 " is null!", id_); + return DISPLAY_NULL_PTR; + } + + if (!connector_->SetBrightness(static_cast(value))) { + return DISPLAY_FAILURE; + } + + return DISPLAY_SUCCESS; +} + +bool DrmDisplay::IsConnected() +{ + if (OE_UNLIKELY(connector_ == nullptr)) { + LOG_ERROR("DrmDisplay::IsConnected: connector for display id %{public}" PRIu32 " is null!", id_); + return false; + } + + return connector_->Connected(); +} + +void DrmDisplay::InitReservedFb() +{ + const auto &displayDevice = oewm::HDI::DISPLAY::HdiSession::GetInstance().GetDisplayDevice(); + ASSERT(displayDevice != nullptr); + + auto modeId = connector_->GetActiveModeId(); + drmModeModeInfo mode{}; + connector_->GetMode(modeId, &mode); + auto width = static_cast(mode.hdisplay); + auto height = static_cast(mode.vdisplay); + uint64_t usage = HBM_USE_CPU_READ | HBM_USE_MEM_DMA | HBM_USE_MEM_FB | HBM_USE_CPU_WRITE; + + // Use Dumb Buffer as reversed fb is enough for now. + reservedFb_ = DrmFrameBuffer::CreateAsDumb(drmFd_, width, height, usage, true); +} + +int32_t DrmDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void *data) +{ + bool isFirstReg = false; + { + std::lock_guard lock(mutex_); + vSyncCallBack_ = cb; + vsyncUserData_ = data; + if (!vSyncCbEverReged_) { + isFirstReg = true; + vSyncCbEverReged_ = true; + } + } + + // if this is the first time to register vsync callback of this dispay, + // we should do a commit to schdule the pageflip event. + if (isFirstReg) { + // TODO: create from gralloc + InitReservedFb(); + if (reservedFb_ == nullptr) { + LOG_ERROR("DrmDisplay::RegDisplayVBlankCallback: failed to schdule the pageflip event(fb create failed)."); + return DISPLAY_FAILURE; + } + + const auto &displayDevice = oewm::HDI::DISPLAY::HdiSession::GetInstance().GetDisplayDevice(); + ASSERT(displayDevice != nullptr); + + int fenceFd = INVALID_FD; + if (displayDevice->SupportAtomicModeSet()) { + CommitAtomic(&fenceFd, reservedFb_.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET); +#ifdef ENABLE_HARDWARE_VSYNC + CommitAtomic(&fenceFd, reservedFb_.get(), DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_PAGE_FLIP_EVENT); +#else + CommitAtomic(&fenceFd, reservedFb_.get(), DRM_MODE_ATOMIC_ALLOW_MODESET); +#endif // ENABLE_HARDWARE_VSYNC + } else { + CommitLegacy(&fenceFd, reservedFb_.get()); + } + + LOG_DEBUG("First commit Fence %{public}i", fenceFd); + OHOS::SyncFence fence(fenceFd); + fence.Wait(3000); + } + + return DISPLAY_SUCCESS; +} + +void DrmDisplay::OnVSync(uint32_t sequence, uint64_t timeStamp) +{ + VBlankCallback cb = nullptr; + void *data = nullptr; + { + std::lock_guard lock(mutex_); + cb = vSyncCallBack_; + data = vsyncUserData_; + } + + if (cb != nullptr) { + cb(sequence, timeStamp, data); + } +} + +int32_t DrmDisplay::SetDisplayVsyncEnabled(bool enabled) +{ +#ifdef ENABLE_HARDWARE_VSYNC + if (enabled) { + commitFlag_ |= DRM_MODE_PAGE_FLIP_EVENT; + } else { + commitFlag_ &= (~DRM_MODE_PAGE_FLIP_EVENT); + } + enableVsync_ = enabled; +#endif // ENABLE_HARDWARE_VSYNC + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences) +{ + *num = layers_.size(); + uint32_t i = 0; + for (auto &[layerId, layer] : layers_) { + if (layers != nullptr && fences != nullptr) { + *(layers + i) = layerId; + *(fences + i) = dup(layer->GetReleaseFenceFd()); + LOG_DEBUG("DrmDisplay::GetDisplayReleaseFence layerId %{public}u, fencefd %{public}i", layerId, layer->GetReleaseFenceFd()); + } + i++; + } + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplaySupportedColorGamuts(uint32_t *num, ColorGamut *gamuts) +{ + UNUSED(num); + UNUSED(gamuts); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayColorGamut(ColorGamut *gamut) +{ + UNUSED(gamut); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayColorGamut(ColorGamut gamut) +{ + UNUSED(gamut); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayGamutMap(GamutMap *gamutMap) +{ + UNUSED(gamutMap); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayGamutMap(GamutMap gamutMap) +{ + UNUSED(gamutMap); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetHDRCapabilityInfos(HDRCapability *info) +{ + // mock data + info->formatCount = 1; + std::vector formats; + formats.resize(info->formatCount); + formats.push_back(HDR10); + info->formats = formats.data(); + info->maxLum = 1000; + info->minLum = 100; + info->maxAverageLum = 600; + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetSupportedMetadataKey(uint32_t *num, HDRMetadataKey *keys) +{ + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence) +{ + // LOG_DEBUG("DrmDisplay::SetDisplayClientBuffer handle fd: %{public}i", buffer->fd); + clientLayer_->SetBuffer(buffer, fence); + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::PrepareDisplayLayers(bool *needFlushFb) +{ + changeLayers_.clear(); + std::vector layers; + for (auto &[layerId, layer] : layers_) { + UNUSED(layerId); + layers.push_back(layer.get()); + } + sort( + layers.begin(), + layers.end(), + [](const oewm::HDI::DISPLAY::HdiLayer *lhs, const oewm::HDI::DISPLAY::HdiLayer *rhs) { + return lhs->GetZOrder() < rhs->GetZOrder(); + }); // sort by Zorder + for (auto &layer : layers) { + LOG_DEBUG("DrmDisplay::PrepareDisplayLayers layer id %{public}u, ZOrder %{public}u" + , layer->GetId(), layer->GetZOrder()); + } + + for (auto &layer : layers) { + if (layer->GetCompositionType() != COMPOSITION_CURSOR && layer->GetCompositionType() != COMPOSITION_VIDEO && + layer->GetCompositionType() != COMPOSITION_TUNNEL) { + layer->SetDeviceSelect(COMPOSITION_CLIENT); + } else { + layer->SetDeviceSelect(layer->GetCompositionType()); + } + + // get the change layers + if (layer->GetDeviceSelect() != layer->GetCompositionType()) { + LOG_DEBUG("DrmDisplay::PrepareDisplayLayers layer compositionType from %{public}i to %{public}i", + layer->GetCompositionType(), layer->GetDeviceSelect()); + layer->SetCompositionType(layer->GetDeviceSelect()); + changeLayers_.push_back(layer); + } + } + + *needFlushFb = true; + return DISPLAY_SUCCESS; +} + +int32_t DrmDisplay::GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type) +{ + *num = changeLayers_.size(); + for (uint32_t i = 0; i < changeLayers_.size(); i++) { + if (layers != nullptr && type != nullptr) { + *(layers + i) = changeLayers_[i]->GetId(); + *(type + i) = changeLayers_[i]->GetCompositionType(); + LOG_DEBUG("DrmDisplay::GetDisplayCompChange layerId %{public}u, fencefd %{public}i", + changeLayers_[i]->GetId(), changeLayers_[i]->GetCompositionType()); + } + } + + return DISPLAY_SUCCESS; +} + +void DrmDisplay::CommitAtomic(int32_t *fence, const DrmFrameBuffer *fb, int commitFlag) +{ + ASSERT(fb != nullptr); + auto width = fb->GetFbWidth(); + auto height = fb->GetFbHeight(); + auto fbId = fb->GetFbId(); + + LOG_DEBUG("DrmDisplay::CommitAtomic. \n" + "Connector Id: %{public}u, " + "CRTC Id: %{public}d, " + "CRTC Mode Blob Id: %{public}lu, " + "CRTC Active: 1, " + "CRTC OutFence: %{public}lu, " + "Plain Id: %{public}u, " + "Plain FB Id: %{public}u, " + "Plain SRC W: %{public}u, " + "Plain SRC H: %{public}u, " + "Plain CRTC W: %{public}u, " + "Plain CRTC H: %{public}u, " + "Commit flag: %{public}d.", + connector_->Id(), crtc_->Id(), connector_->BlobId(), (uint64_t)fence, + primaryPlane_->Id(), fbId, width << 16, height << 16, width, height, commitFlag); + + DrmAtomicCommitter atomicAutoCommitter(drmFd_, commitFlag, this); + + /* set id of the CRTC id that the connector is using */ + atomicAutoCommitter.AddAtomicProperty(connector_->Id(), connector_->CrtcPropId(), crtc_->Id()); + + /* set the mode id of the CRTC; this property receives the id of a blob + * property that holds the struct that actually contains the mode info */ + atomicAutoCommitter.AddAtomicProperty(crtc_->Id(), crtc_->ModeIdPropId(), connector_->BlobId()); + + /* set the CRTC object as active */ + atomicAutoCommitter.AddAtomicProperty(crtc_->Id(), crtc_->ActivePropId(), 1); + + atomicAutoCommitter.AddAtomicProperty(crtc_->Id(), crtc_->OutFencePropId(), (uint64_t)fence); + + /* set properties of the plane related to the CRTC and the framebuffer */ + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->FBPropId(), fbId); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->CrtcPropId(), crtc_->Id()); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->SrcXPropId(), 0); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->SrcYPropId(), 0); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->SrcWPropId(), width << 16); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->SrcHPropId(), height << 16); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->CrtcXPropId(), 0); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->CrtcYPropId(), 0); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->CrtcWPropId(), width); + atomicAutoCommitter.AddAtomicProperty(primaryPlane_->Id(), primaryPlane_->CrtcHPropId(), height); + atomicAutoCommitter.Commit(); + + clientLayer_->SetReleaseFence(*fence); + LOG_DEBUG("DrmDisplay::CommitAtomic: done."); +} + +void DrmDisplay::CommitLegacy(int32_t *fence, const DrmFrameBuffer *fb) +{ + ASSERT(fb != nullptr); + + auto fbId = fb->GetFbId(); + uint32_t ctrcId = crtc_->Id(); + uint32_t connId = connector_->Id(); + drmModeModeInfo mode; + auto modeId = connector_->GetActiveModeId(); + connector_->GetMode(modeId, &mode); + + auto width = fb->GetFbWidth(); + auto height = fb->GetFbHeight(); + + LOG_DEBUG("DrmDisplay::CommitLegacy connectorId: %{public}" PRIu32 ", crtcId: %{public}" PRIu32 ", modeId: %{public}" PRIu32 ", fbWidth: %{public}" PRIu32 ", fbHeight: %{public}" PRIu32 ".", + connId, ctrcId, modeId, width, height); + + if (drmModeSetCrtc(drmFd_, ctrcId, fbId, 0, 0, &connId, 1, &mode) != 0) { + LOG_WARN("DrmDisplay::CommitLegacy drmModeSetCrtc failed, error: %{public}s", ErrnoToString(errno).c_str()); + } + LOG_DEBUG("DrmDisplay::CommitLegacy done"); +} + +int32_t DrmDisplay::Commit(int32_t *fence) +{ + DrmLayer *layer = DownCast(clientLayer_.get()); + if (layer == nullptr) { + LOG_ERROR("DrmDisplay::Commit: client layer nullptr."); + 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."); + fb = reservedFb_.get(); + } + + if (oewm::HDI::DISPLAY::HdiSession::GetInstance().GetDisplayDevice()->SupportAtomicModeSet()) { + CommitAtomic(fence, fb, commitFlag_); + } else { + // legacy + CommitLegacy(fence, fb); + } + + return DISPLAY_SUCCESS; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_display.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_display.h new file mode 100644 index 0000000..1a32010 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_display.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "drm_connector.h" +#include "drm_layer.h" +#include "drm_mode.h" +#include "drm_plane.h" +#include "hdi_display.h" + +namespace oewm { +namespace drm { +class DrmDisplay : public HdiDisplay { +public: + DrmDisplay(int drmFd, HdiDisplayId id, std::shared_ptr connector, std::shared_ptr crtc); + ~DrmDisplay() noexcept; + + bool Init() override; + void SetPrimaryPlane(const std::shared_ptr &primaryPlane) + { + primaryPlane_ = primaryPlane; + } + + HdiDisplayId Id() const override + { + return id_; + } + bool IsConnected() override; + + int32_t GetDisplayCapability(DisplayCapability *info) override; + int32_t GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes) override; + int32_t GetDisplayMode(uint32_t *modeId) override; + int32_t SetDisplayMode(uint32_t modeId) override; + int32_t GetDisplayPowerStatus(DispPowerStatus *status) override; + int32_t SetDisplayPowerStatus(DispPowerStatus status) override; + int32_t GetDisplayBacklight(uint32_t *value) override; + int32_t SetDisplayBacklight(uint32_t value) override; + int32_t RegDisplayVBlankCallback(VBlankCallback cb, void *data) override; + void OnVSync(uint32_t sequence, uint64_t timeStamp) override; + int32_t SetDisplayVsyncEnabled(bool enabled) override; + int32_t GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences) override; + int32_t GetDisplaySupportedColorGamuts(uint32_t *num, ColorGamut *gamuts) override; + int32_t GetDisplayColorGamut(ColorGamut *gamut) override; + int32_t SetDisplayColorGamut(ColorGamut gamut) override; + int32_t GetDisplayGamutMap(GamutMap *gamutMap) override; + int32_t SetDisplayGamutMap(GamutMap gamutMap) override; + int32_t GetHDRCapabilityInfos(HDRCapability *info) override; + int32_t GetSupportedMetadataKey(uint32_t *num, HDRMetadataKey *keys) override; + int32_t SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence) override; + + int32_t PrepareDisplayLayers(bool *needFlushFb) override; + int32_t GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type) override; + int32_t Commit(int32_t *fence) override; + +private: + // convert drm DPMS(display power manager status) to hdi DispPowerStatus. + static DispPowerStatus ToDispPowerStatus(uint64_t dpms); + // convert hdi DispPowerStatus to drm DPMS(display power manager status). + static uint64_t ToDpms(DispPowerStatus status); + + std::unique_ptr CreateHdiLayer(HDI::DISPLAY::LayerId id, LayerType type) override; + + void CommitAtomic(int32_t *fence, const DrmFrameBuffer *fb, int commitFlag); + void CommitLegacy(int32_t *fence, const DrmFrameBuffer *fb); + + int drmFd_ = INVALID_FD; + + HdiDisplayId id_; + std::shared_ptr connector_; + std::shared_ptr crtc_; + std::shared_ptr primaryPlane_; + + mutable std::mutex mutex_; + VBlankCallback vSyncCallBack_ = nullptr; // guarded by mutex_; + void *vsyncUserData_ = nullptr; // guarded by mutex_; + bool vSyncCbEverReged_ = false; // guarded by mutex_; +#ifdef ENABLE_HARDWARE_VSYNC + // bool enableVsync_ = true; +#endif // ENABLE_HARDWARE_VSYNC + + void InitReservedFb(); + std::unique_ptr reservedFb_; // to do first commit to enable vsync. +#ifdef ENABLE_HARDWARE_VSYNC + int commitFlag_ = DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK; +#else + int commitFlag_ = DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK; +#endif // ENABLE_HARDWARE_VSYNC +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp new file mode 100644 index 0000000..cfb5308 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_encoder.h" + +#include +#include + +#include "base/log.h" + +namespace oewm { +namespace drm { +DrmEncoder::DrmEncoder(int drmFd, uint32_t encoderId) : drmFd_(drmFd), id_(encoderId) +{ + auto encoder = drmModeGetEncoder(drmFd_, id_); + if (encoder == nullptr) { + LOG_ERROR("Failed to get drm encoder for encoder id: %{public}" PRIu32, id_); + return; + } + ParseFrom(encoder); + drmModeFreeEncoder(encoder); +} + +DrmEncoder::~DrmEncoder() noexcept {} + +bool DrmEncoder::FindCrtcId(const IdMapPtr &crtcs, uint32_t &crtcId) +{ + if (crtcs.count(crtcId_) != 0 && crtcs.at(crtcId_)->CanBind()) { + crtcId = crtcId_; + return true; + } + + auto res = drmModeGetResources(drmFd_); + if (res == nullptr) { + return false; + } + bool found = false; + for (int i = 0; i != res->count_crtcs; ++i) { + auto id = res->crtcs[i]; + if (crtcs.count(id) == 0) { + continue; + } + const auto &crtc = crtcs.at(id); + if (possibleCrtcs_ & (1 << i) && crtc->CanBind()) { + crtcId = id; + found = true; + break; + } + } + drmModeFreeResources(res); + + return found; +} + +void DrmEncoder::ParseFrom(drmModeEncoderPtr const &encoder) +{ + crtcId_ = encoder->crtc_id; + possibleCrtcs_ = encoder->possible_crtcs; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h new file mode 100644 index 0000000..09db35f --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "base/noncopyable.h" +#include "drm_common.h" +#include "drm_crtc.h" + +namespace oewm { +namespace drm { +class DrmEncoder : NonCopyable { +public: + DrmEncoder(int drmFd, uint32_t encoderId); + ~DrmEncoder() noexcept; + bool FindCrtcId(const IdMapPtr &crtcs, uint32_t &crtcId); + +private: + void ParseFrom(const drmModeEncoderPtr &encoder); + + int drmFd_ = INVALID_FD; + uint32_t id_ = DRM_INVALID_OBJECT_ID; + uint32_t crtcId_ = DRM_INVALID_OBJECT_ID; + uint32_t possibleCrtcs_ = DRM_INVALID_OBJECT_ID; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp new file mode 100644 index 0000000..97f4e62 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_frame_buffer.h" + +#include +#include + +#include "base/log.h" + +namespace oewm { +namespace drm { +namespace detail { +// add fbId to fbInfo +bool AddFb(int drmFd, uint32_t fbHandle, FrameBufferInfo &fbInfo) +{ + ASSERT(!IsInvalidFd(drmFd)); + ASSERT(fbHandle != DRM_INVALID_OBJECT_ID); + + uint32_t handles[4] = {}; + uint32_t pitches[4] = {}; + uint32_t offsets[4] = {}; + + handles[0] = fbHandle; + 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()); + 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; +} + +bool RemoveFb(int drmFd, uint32_t fbId) +{ + ASSERT(!IsInvalidFd(drmFd)); + ASSERT(fbId != DRM_INVALID_OBJECT_ID); + + if (::drmModeRmFB(drmFd, fbId) != 0) { + LOG_ERROR("drmModeRmFB failed, error: %{public}s", ErrnoToString(errno).c_str()); + return false; + } + + return true; +} + +bool DestroyDumbHandle(int drmFd, uint32_t fbHandle) +{ + ASSERT(!IsInvalidFd(drmFd)); + ASSERT(fbHandle != DRM_INVALID_OBJECT_ID); + + struct drm_mode_destroy_dumb dumb {}; + dumb.handle = fbHandle; + if (::drmIoctl(drmFd, DRM_IOCTL_MODE_DESTROY_DUMB, &dumb) != 0) { + LOG_ERROR("DRM_IOCTL_MODE_DESTROY_DUMB error: %{public}s", ErrnoToString(errno).c_str()); + return false; + } + + return true; +} +} // namespace detail + +std::unique_ptr DrmFrameBuffer::CreateAsDumb( + int drmFd, + uint32_t width, + uint32_t height, + uint64_t usage, + bool cleanup/* = true */) +{ + if (IsInvalidFd(drmFd)) { + LOG_ERROR("DrmFrameBuffer::CreateAsDumb error: invalid drm fd!"); + return nullptr; + } + + if (width == 0 || height == 0) { + LOG_ERROR("DrmFrameBuffer::CreateAsDumb error: invalid width(%{public}" PRIu32 ") or height(%{public}" PRIu32 ")!", width, height); + return nullptr; + } + + // Create Dumb Buffer as the buffer of fb + struct drm_mode_create_dumb create {}; + create.width = width; + create.height = height; + create.bpp = 32; + create.flags = 0; + if (drmIoctl(drmFd, DRM_IOCTL_MODE_CREATE_DUMB, &create) != 0) { + LOG_ERROR("DrmFrameBuffer::CreateAsDumb error: failed to create DRM dumb: %{public}s", ErrnoToString(errno).c_str()); + return nullptr; + } + + // Create fb class + FrameBufferInfo fbInfo{}; + fbInfo.width = width; + fbInfo.height = height; + fbInfo.usage = usage; + fbInfo.stride = create.pitch; + fbInfo.size = create.size; + if (!detail::AddFb(drmFd, create.handle, fbInfo)) { + LOG_ERROR("DrmFrameBuffer::CreateAsDumb: AddFb failed!"); + (void)detail::DestroyDumbHandle(drmFd, create.handle); + return nullptr; + } + auto fb = std::unique_ptr(new DrmFrameBuffer(drmFd, fbInfo, create.handle)); + + // Perform cleanup as white + if (cleanup == true) { + fb->Cleanup(0xffffffff); + } + + return fb; +} + +std::unique_ptr DrmFrameBuffer::CreateFromBufferHandle(int drmFd, const BufferHandle &handle) +{ + if (IsInvalidFd(drmFd)) { + LOG_ERROR("DrmFrameBuffer::CreateFromBufferHandle error: invalid drm fd!"); + return nullptr; + } + + if (handle.width <= 0 || handle.height <= 0) { + LOG_ERROR("DrmFrameBuffer::CreateFromBufferHandle error: invalid width(%{public}" PRIu32 ") or height(%{public}" PRIu32 ")!", handle.width, handle.height); + return nullptr; + } + + FrameBufferInfo fbInfo{}; + fbInfo.width = static_cast(handle.width); + fbInfo.height = static_cast(handle.height); + fbInfo.usage = handle.usage; + fbInfo.stride = handle.stride; + fbInfo.size = static_cast(handle.size); + fbInfo.virAddr = handle.virAddr; + auto fbHandle = static_cast(handle.key); + if (!detail::AddFb(drmFd, fbHandle, fbInfo)) { + LOG_ERROR("DrmFrameBuffer::CreateFromBufferHandle: AddFb failed!"); + return nullptr; + } + + return std::unique_ptr(new DrmFrameBuffer(drmFd, fbInfo)); +} + +DrmFrameBuffer::~DrmFrameBuffer() noexcept +{ + if (IsInvalidFd(drmFd_)) { + return; + } + + std::string funInfo = "DrmFrameBuffer::~DrmFrameBuffer(fbId: " + std::to_string(info_.fbId) + "): "; + // LOG_DEBUG("%{public}s Removing fb...", funInfo.c_str()); + + // Remove fb + if (info_.fbId != DRM_INVALID_OBJECT_ID) { + if (!detail::RemoveFb(drmFd_, info_.fbId)) { + LOG_ERROR("%{public}s free fdId failed, error: %{public}s", funInfo.c_str(), ErrnoToString(errno).c_str()); + } + } + + // Free dumb buffer + if (isCreateFromBufferHandle_ == false && fbHandle_ != DRM_INVALID_OBJECT_ID) { + // unmap + if (info_.virAddr != nullptr) { + if (::munmap(info_.virAddr, info_.size) != 0) { + LOG_ERROR("%{public}s munmap failed, error: %{public}s", funInfo.c_str(), ErrnoToString(errno).c_str()); + } + } + // destroy dumb + if (!detail::DestroyDumbHandle(drmFd_, fbHandle_)) { + LOG_ERROR("%{public}s DestroyDumbHandle failed, error: %{public}s", funInfo.c_str(), ErrnoToString(errno).c_str()); + } + } +} + +DrmFrameBuffer::DrmFrameBuffer(int drmFd, const FrameBufferInfo &fbInfo, uint32_t fbHandle) + : drmFd_(drmFd), info_(fbInfo), isCreateFromBufferHandle_(false), fbHandle_(fbHandle) +{} + +DrmFrameBuffer::DrmFrameBuffer(int drmFd, const FrameBufferInfo &fbInfo) + : drmFd_(drmFd), info_(fbInfo), isCreateFromBufferHandle_(true) +{} + +void DrmFrameBuffer::Cleanup(uint32_t color) +{ + if (isCreateFromBufferHandle_ == true) { + LOG_WARN("DrmFrameBuffer::Clean: Cannot cleanup fb created from buffer handle!"); + return; + } + + // Mmap + if (info_.virAddr == nullptr) { + void *virAddr = nullptr; + + if (fbHandle_ != DRM_INVALID_OBJECT_ID) { + struct drm_mode_map_dumb map {}; + map.handle = fbHandle_; + if (drmIoctl(drmFd_, DRM_IOCTL_MODE_MAP_DUMB, &map) != 0) { + LOG_ERROR("DrmFrameBuffer::Clean: Failed to map DRM dumb buffer: %{public}s", ErrnoToString(errno).c_str()); + return; + } + virAddr = ::mmap(virAddr, info_.size, PROT_READ | PROT_WRITE, MAP_SHARED, drmFd_, map.offset); + if (virAddr == MAP_FAILED) { + LOG_ERROR("DrmFrameBuffer::Clean: Failed to mmap DRM dumb buffer: %{public}s", ErrnoToString(errno).c_str()); + return; + } + } + + info_.virAddr = virAddr; + } + + // Fill with given color + if (info_.virAddr != nullptr) { + std::fill( + reinterpret_cast(info_.virAddr), reinterpret_cast(info_.virAddr) + info_.size, color); + } + + // Unmap + if (info_.virAddr != nullptr) { + if (::munmap(info_.virAddr, info_.size) != 0) { + LOG_ERROR("DrmFrameBuffer::Clean: munmap failed, error: %{public}s", ErrnoToString(errno).c_str()); + } + info_.virAddr = nullptr; + } +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h new file mode 100644 index 0000000..1efd184 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "buffer_handle.h" +#include "display_type.h" +#include "drm_common.h" + +namespace oewm { +namespace drm { +struct FrameBufferInfo { + uint32_t fbId = DRM_INVALID_OBJECT_ID; + void *virAddr = nullptr; + uint64_t usage = 0; + uint32_t width = 0; + uint32_t height = 0; + uint32_t stride = 0; // framebuffer stride: how many bytes per line. + uint64_t size = 0; // framebuffer total size(in bytes). +}; + +class DrmFrameBuffer : NonCopyable { +public: + static std::unique_ptr CreateAsDumb(int drmFd, uint32_t width, uint32_t height, uint64_t usage, bool cleanup = true); + static std::unique_ptr CreateFromBufferHandle(int drmFd, const BufferHandle &handle); + + ~DrmFrameBuffer() noexcept; + + uint32_t GetFbId() const + { + return info_.fbId; + } + uint32_t GetFbWidth() const + { + return info_.width; + } + uint32_t GetFbHeight() const + { + return info_.height; + } + +private: + // we hide these constructors to ensure that all DrmFrameBuffer instances are valid. + DrmFrameBuffer(int drmFd, const FrameBufferInfo &fbInfo, uint32_t fbHandle); + DrmFrameBuffer(int drmFd, const FrameBufferInfo &fbInfo); + + void Cleanup(uint32_t color); + +private: + // common + int drmFd_ = INVALID_FD; + FrameBufferInfo info_; + bool isCreateFromBufferHandle_; + + // dumb fb object + uint32_t fbHandle_ = DRM_INVALID_OBJECT_ID; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp new file mode 100644 index 0000000..37d40b6 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_layer.h" + +#include "base/log.h" + +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; + } + + HdiLayerBuffer *layerBuffer = GetCurrentBuffer(); + if (layerBuffer == nullptr) { + LOG_ERROR("DrmLayer::GetFrameBuffer: GetCurrentBuffer is nullptr"); + return nullptr; + } + + lastFrameBuffer_ = std::move(currentFrameBuffer_); + + const auto &bufferHandle = layerBuffer->GetBufferHandle(); + currentFrameBuffer_ = DrmFrameBuffer::CreateFromBufferHandle(drmFd, bufferHandle); + if (currentFrameBuffer_ == nullptr) { + LOG_ERROR("DrmLayer::GetFrameBuffer: create framebuffer from BufferHandle failed."); + return nullptr; + } + + return currentFrameBuffer_.get(); +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h new file mode 100644 index 0000000..6e370fe --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include + +#include "drm_frame_buffer.h" +#include "hdi_layer.h" + +namespace oewm { +namespace drm { +class DrmLayer : public HdiLayer { +public: + DrmLayer(HdiLayerId id, LayerType type) : HdiLayer(id, type) {} + ~DrmLayer() noexcept override = default; + + DrmFrameBuffer *GetFrameBuffer(int drmFd); + +private: + std::unique_ptr lastFrameBuffer_; + std::unique_ptr currentFrameBuffer_; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp new file mode 100644 index 0000000..fbc3fbf --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_mode_info.h" + +#include "base/log.h" + +namespace oewm { +namespace drm { +DrmModeInfo::DrmModeInfo(const drmModeModeInfo &modeInfo, int id, int drmFd) + : modeInfo_(modeInfo), id_(id), drmFd_(drmFd) +{ + // LOG_DEBUG << "DrmModeInfo::DrmModeInfo: modeId: " << id_ << ", vrefresh: " << modeInfo_.vrefresh + // << ", vdisplay: " << modeInfo_.vdisplay << ", hdisplay:" << modeInfo_.hdisplay; + int ret = drmModeCreatePropertyBlob(drmFd, &modeInfo_, sizeof(modeInfo), &blobId_); + if (ret != 0) { + LOG_WARN("DrmModeInfo create property blob failed: %{public}s", ErrnoToString(errno).c_str()); + } +} + +DrmModeInfo::~DrmModeInfo() noexcept +{ + int ret = drmModeDestroyPropertyBlob(drmFd_, blobId_); + if (ret != 0) { + LOG_WARN("DrmModeInfo destroy property blob failed: %{public}s", ErrnoToString(errno).c_str()); + } +} + +DisplayModeInfo DrmModeInfo::ToHdiModeInfo() const +{ + DisplayModeInfo res; + res.width = modeInfo_.hdisplay; + res.height = modeInfo_.vdisplay; + res.id = Id(); + res.freshRate = modeInfo_.vrefresh; + return res; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h new file mode 100644 index 0000000..63bff7b --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "base/noncopyable.h" + +#include "display_type.h" +#include "drm_common.h" + +namespace oewm { +namespace drm { +// typedef struct _drmModeModeInfo { +// uint32_t clock; +// uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew; +// uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan; + +// uint32_t vrefresh; + +// uint32_t flags; +// uint32_t type; +// char name[DRM_DISPLAY_MODE_LEN]; +// } drmModeModeInfo, *drmModeModeInfoPtr; +class DrmModeInfo : NonCopyable { +public: + DrmModeInfo(const drmModeModeInfo &modeInfo, int id, int drmFd); + ~DrmModeInfo() noexcept; + + int Id() const + { + return id_; + } + uint32_t BlobId() const + { + return blobId_; + } + drmModeModeInfo ModeInfo() const + { + return modeInfo_; + } + + DisplayModeInfo ToHdiModeInfo() const; + +private: + drmModeModeInfo modeInfo_; + int id_ = -1; + int drmFd_ = INVALID_FD; + uint32_t blobId_ = DRM_INVALID_OBJECT_ID; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp new file mode 100644 index 0000000..df62ab7 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_plane.h" + +#include "drm_mode.h" +#include "base/log.h" + +namespace oewm { +namespace drm { +DrmPlane::DrmPlane(int drmFd, uint32_t planeId) : drmFd_(drmFd), id_(planeId) +{ + auto plane = drmModeGetPlane(drmFd_, id_); + if (plane == nullptr) { + LOG_ERROR("Failed to get drm plane for plane id: %{public}" PRIu32, id_); + return; + } + ParseFrom(plane); + drmModeFreePlane(plane); +} + +DrmPlane::~DrmPlane() noexcept {} + +void DrmPlane::ParseFrom(drmModePlanePtr const &plane) +{ + DrmObjectPropertyFetcher planePropFetcher(drmFd_, id_, DRM_MODE_OBJECT_PLANE); + fbPropId_ = planePropFetcher.GetPropId(PROP_FBID); + crtcPropId_ = planePropFetcher.GetPropId(PROP_CRTC_ID); + typePropId_ = planePropFetcher.GetPropId(PROP_TYPE); + crtcXPropId_ = planePropFetcher.GetPropId(PROP_CRTC_X_ID); + crtcYPropId_ = planePropFetcher.GetPropId(PROP_CRTC_Y_ID); + crtcWPropId_ = planePropFetcher.GetPropId(PROP_CRTC_W_ID); + crtcHPropId_ = planePropFetcher.GetPropId(PROP_CRTC_H_ID); + srcXPropId_ = planePropFetcher.GetPropId(PROP_SRC_X_ID); + srcYPropId_ = planePropFetcher.GetPropId(PROP_SRC_Y_ID); + srcWPropId_ = planePropFetcher.GetPropId(PROP_SRC_W_ID); + srcHPropId_ = planePropFetcher.GetPropId(PROP_SRC_H_ID); + type_ = planePropFetcher.GetPropValue(PROP_TYPE); + possibleCrtcs_ = plane->possible_crtcs; +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h new file mode 100644 index 0000000..c0c8214 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "base/noncopyable.h" +#include "drm_common.h" +#include "drm_property.h" + +namespace oewm { +namespace drm { +// prop for plane +constexpr char PROP_FBID[] = "FB_ID"; +constexpr char PROP_CRTC_ID[] = "CRTC_ID"; +constexpr char PROP_TYPE[] = "type"; +constexpr char PROP_CRTC_X_ID[] = "CRTC_X"; +constexpr char PROP_CRTC_Y_ID[] = "CRTC_Y"; +constexpr char PROP_CRTC_W_ID[] = "CRTC_W"; +constexpr char PROP_CRTC_H_ID[] = "CRTC_H"; +constexpr char PROP_SRC_X_ID[] = "SRC_X"; +constexpr char PROP_SRC_Y_ID[] = "SRC_Y"; +constexpr char PROP_SRC_W_ID[] = "SRC_W"; +constexpr char PROP_SRC_H_ID[] = "SRC_H"; +// typedef struct _drmModePlane { +// uint32_t count_formats; +// uint32_t *formats; +// uint32_t plane_id; + +// uint32_t crtc_id; +// uint32_t fb_id; + +// uint32_t crtc_x, crtc_y; +// uint32_t x, y; + +// uint32_t possible_crtcs; +// uint32_t gamma_size; +// } drmModePlane, *drmModePlanePtr; +class DrmPlane : NonCopyable { +public: + DrmPlane(int drmFd, uint32_t planeId); + ~DrmPlane() noexcept; + uint64_t GetPlaneType() const + { + return type_; + } + uint32_t Id() const + { + return id_; + } + uint32_t FBPropId() const + { + return fbPropId_; + } + uint32_t CrtcPropId() const + { + return crtcPropId_; + } + uint32_t TypePropId() const + { + return typePropId_; + } + uint32_t CrtcXPropId() const + { + return crtcXPropId_; + } + uint32_t CrtcYPropId() const + { + return crtcYPropId_; + } + uint32_t CrtcWPropId() const + { + return crtcWPropId_; + } + uint32_t CrtcHPropId() const + { + return crtcHPropId_; + } + uint32_t SrcXPropId() const + { + return srcXPropId_; + } + uint32_t SrcYPropId() const + { + return srcYPropId_; + } + uint32_t SrcWPropId() const + { + return srcWPropId_; + } + uint32_t SrcHPropId() const + { + return srcHPropId_; + } + uint32_t GetPossibleCrtcs() const + { + return possibleCrtcs_; + } + +private: + void ParseFrom(const drmModePlanePtr &plane); + + int drmFd_ = INVALID_FD; + uint32_t id_ = DRM_INVALID_OBJECT_ID; + uint32_t fbPropId_ = DRM_INVALID_PROP_ID; + uint32_t crtcPropId_ = DRM_INVALID_PROP_ID; + uint32_t typePropId_ = DRM_INVALID_PROP_ID; + uint32_t crtcXPropId_ = DRM_INVALID_PROP_ID; + uint32_t crtcYPropId_ = DRM_INVALID_PROP_ID; + uint32_t crtcWPropId_ = DRM_INVALID_PROP_ID; + uint32_t crtcHPropId_ = DRM_INVALID_PROP_ID; + uint32_t srcXPropId_ = DRM_INVALID_PROP_ID; + uint32_t srcYPropId_ = DRM_INVALID_PROP_ID; + uint32_t srcWPropId_ = DRM_INVALID_PROP_ID; + uint32_t srcHPropId_ = DRM_INVALID_PROP_ID; + uint64_t type_ = DRM_INVLIAD_VALUE; + uint32_t possibleCrtcs_ = 0; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp new file mode 100644 index 0000000..826b762 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "drm_property.h" + +#include "base/log.h" + +namespace oewm { +namespace drm { +DrmProperty::DrmProperty(int drmFd, uint32_t propId, uint64_t propValue) + : prop_(::drmModeGetProperty(drmFd, propId)), propId_(propId), value_(propValue) +{ + if (prop_ == nullptr) { + LOG_ERROR("Failed to get property of propId: %{public}" PRIu32 ", err: %{public}s", propId_, ErrnoToString(errno).c_str()); + return; + } + + ParseProp(); +} + +DrmProperty::~DrmProperty() noexcept +{ + if (prop_ != nullptr) { + ::drmModeFreeProperty(prop_); + } +} + +void DrmProperty::ParseProp() +{ + flags_ = prop_->flags; + name_ = prop_->name; + for (int i = 0; i < prop_->count_values; ++i) { + values_.push_back(prop_->values[i]); + } + for (int i = 0; i < prop_->count_enums; ++i) { + enums_.push_back(DrmPropertyEnum(prop_->enums[i])); + } + for (int i = 0; i < prop_->count_blobs; ++i) { + blobIds_.push_back(prop_->blob_ids[i]); + } +} + +DrmObjectPropertyFetcher::DrmObjectPropertyFetcher(int drmFd, uint32_t objId, uint32_t objType) + : props_(::drmModeObjectGetProperties(drmFd, objId, objType)), + drmFd_(drmFd), + objId_(objId), + objType_(objType), + objInfo_(ObjInfoDump(objId_, objType_)) +{ + if (props_ == nullptr) { + LOG_ERROR("Failed to get properties for %{public}s", objInfo_.c_str()); + return; + } + + BuildPropsMap(); +} + +DrmObjectPropertyFetcher::~DrmObjectPropertyFetcher() noexcept +{ + if (props_ != nullptr) { + ::drmModeFreeObjectProperties(props_); + } +} + +void DrmObjectPropertyFetcher::BuildPropsMap() +{ + for (uint32_t i = 0; i != props_->count_props; ++i) { + auto propId = props_->props[i]; + auto propValue = props_->prop_values[i]; + auto prop = std::make_unique(drmFd_, propId, propValue); + if (prop == nullptr) { + continue; + } + propsMap_[prop->Name()] = std::move(prop); + } +} + +uint32_t DrmObjectPropertyFetcher::GetPropId(const std::string &name) const +{ + if (propsMap_.count(name) == 0) { + LOG_WARN("Failed to get propId of name: %{public}s for %{public}s", name.c_str(), objInfo_.c_str()); + return DRM_INVALID_PROP_ID; + } + + return propsMap_.at(name)->Id(); +} + +uint64_t DrmObjectPropertyFetcher::GetPropValue(const std::string &name) const +{ + if (propsMap_.count(name) == 0) { + LOG_WARN("Failed to get propValue of name: %{public}s for %{public}s", name.c_str(), objInfo_.c_str()); + return DRM_INVLIAD_VALUE; + } + + return propsMap_.at(name)->Value(); +} +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_property.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_property.h new file mode 100644 index 0000000..c940a41 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_property.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include + +#include "drm_common.h" + +namespace oewm { +namespace drm { +enum class DrmPropertyType { + DRM_PROPERTY_TYPE_RANGE, + DRM_PROPERTY_TYPE_ENUM, + DRM_PROPERTY_TYPE_OBJECT, + DRM_PROPERTY_TYPE_BLOB, + DRM_PROPERTY_TYPE_BITMASK, + DRM_PROPERTY_TYPE_INVALID, +}; + +// copyable +class DrmPropertyEnum { +public: + explicit DrmPropertyEnum(const drm_mode_property_enum &e) : value(e.value), name(e.name) {} + ~DrmPropertyEnum() noexcept {}; + + uint64_t value; + std::string name; +}; + +class DrmProperty : NonCopyable { +public: + DrmProperty(int drmFd, uint32_t propId, uint64_t propValue); + ~DrmProperty() noexcept; + bool operator!() const + { + return prop_ == nullptr; + } + bool operator==(std::nullptr_t) const + { + return prop_ == nullptr; + } + bool operator!=(std::nullptr_t) const + { + return prop_ != nullptr; + } + uint32_t Id() const + { + return propId_; + } + uint64_t Value() const + { + return value_; + } + uint32_t Flags() const + { + return flags_; + } + const std::string &Name() const + { + return name_; + } + const std::vector &GetValues() const + { + return values_; + } + const std::vector &GetEnums() const + { + return enums_; + } + const std::vector &GetBlobIds() const + { + return blobIds_; + } + +private: + void ParseProp(); + + drmModePropertyPtr prop_ = nullptr; + + uint32_t propId_; + uint64_t value_; + uint32_t flags_; + std::string name_; + std::vector values_; + std::vector enums_; + std::vector blobIds_; +}; + +class DrmObjectPropertyFetcher : NonCopyable { +public: + DrmObjectPropertyFetcher(int drmFd, uint32_t objId, uint32_t objType); + ~DrmObjectPropertyFetcher() noexcept; + + bool operator!() const + { + return props_ == nullptr; + } + bool operator==(std::nullptr_t) const + { + return props_ == nullptr; + } + bool operator!=(std::nullptr_t) const + { + return props_ != nullptr; + } + + uint32_t GetPropId(const std::string &name) const; + uint64_t GetPropValue(const std::string &name) const; + +private: + void BuildPropsMap(); + drmModeObjectPropertiesPtr props_ = nullptr; + int drmFd_; + uint32_t objId_; + uint32_t objType_; + std::string objInfo_; + std::unordered_map> propsMap_; +}; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp b/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp new file mode 100644 index 0000000..15400c4 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device 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 "hdi_display.h" + +#include "base/log.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +HdiDisplay::HdiDisplay() {} + +bool HdiDisplay::Init() +{ + LOG_DEBUG("HdiDisplay::Init"); + + auto id = GenerateLayerId(); + auto layer = CreateHdiLayer(id, LAYER_TYPE_GRAPHIC); + if (layer.get() == nullptr) { + LOG_ERROR("HdiDisplay::HdiDisplay CreateHdiLayer failed"); + return false; + } + clientLayer_ = std::move(layer); + return true; +} + +LayerId HdiDisplay::GenerateLayerId() +{ + if (!freeLayerIds_.empty()) { + LayerId id = freeLayerIds_.front(); + freeLayerIds_.pop(); + return id; + } + + return maxLayerIdEver_++; +} + +std::unique_ptr HdiDisplay::CreateHdiLayer(LayerId id, LayerType type) +{ + return std::make_unique(id, type); +} + +int32_t HdiDisplay::CreateLayer(const LayerInfo *layerInfo, LayerId *layerId) +{ + auto type = (layerInfo == nullptr ? LAYER_TYPE_GRAPHIC : layerInfo->type); + auto id = GenerateLayerId(); + *layerId = id; + layers_[id] = CreateHdiLayer(id, type); + return DISPLAY_SUCCESS; +} + +int32_t HdiDisplay::CloseLayer(LayerId layerId) +{ + auto ret = layers_.erase(layerId); + if (ret == 0) { + LOG_INFO("HdiDisplay::CloseLayer: can not find layer for id %{public}" PRIu32 " to close.", layerId); + return DISPLAY_FAILURE; + } + freeLayerIds_.push(layerId); + return DISPLAY_SUCCESS; +} + +int32_t HdiDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences) +{ + return DISPLAY_SUCCESS; +} + +int32_t HdiDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence) +{ + return DISPLAY_SUCCESS; +} + +HdiLayer *HdiDisplay::GetHdiLayer(LayerId id) +{ + if (layers_.count(id) == 0) { + return nullptr; + } + + return layers_.at(id).get(); +} +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h b/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h new file mode 100644 index 0000000..d59293d --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "display_device.h" +#include "hdi_layer.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +using DisplayId = uint32_t; +constexpr DisplayId INVALID_DISPLAY_ID = ~0x0; +constexpr uint32_t DISPLAY_TYPE_DRM = (1 << 31); + +class VsyncCallBack { +public: + VsyncCallBack(VBlankCallback cb, void *data, uint32_t pipe); + virtual void Vsync(unsigned int sequence, uint64_t ns); + virtual ~VsyncCallBack() {} + uint32_t GetPipe() + { + return mPipe; + } + +private: + VBlankCallback mVBlankCb; + void *mData; + uint32_t mPipe; +}; + +class HdiDisplay { +public: + HdiDisplay(); + virtual ~HdiDisplay() noexcept = default; + + virtual bool Init(); + virtual DisplayId Id() const = 0; + virtual bool IsConnected() = 0; + virtual int32_t GetDisplayCapability(DisplayCapability *info) = 0; + virtual int32_t GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes) = 0; + virtual int32_t GetDisplayMode(uint32_t *modeId) = 0; + virtual int32_t SetDisplayMode(uint32_t modeId) = 0; + virtual int32_t GetDisplayPowerStatus(DispPowerStatus *status) = 0; + virtual int32_t SetDisplayPowerStatus(DispPowerStatus status) = 0; + virtual int32_t GetDisplayBacklight(uint32_t *value) = 0; + virtual int32_t SetDisplayBacklight(uint32_t value) = 0; + virtual int32_t RegDisplayVBlankCallback(VBlankCallback cb, void *data) = 0; + virtual void OnVSync(uint32_t sequence, uint64_t timeStamp) = 0; + virtual int32_t SetDisplayVsyncEnabled(bool enabled) = 0; + virtual int32_t GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences) = 0; + virtual int32_t GetDisplaySupportedColorGamuts(uint32_t *num, ColorGamut *gamuts) = 0; + virtual int32_t GetDisplayColorGamut(ColorGamut *gamut) = 0; + virtual int32_t SetDisplayColorGamut(ColorGamut gamut) = 0; + virtual int32_t GetDisplayGamutMap(GamutMap *gamutMap) = 0; + virtual int32_t SetDisplayGamutMap(GamutMap gamutMap) = 0; + virtual int32_t GetHDRCapabilityInfos(HDRCapability *info) = 0; + virtual int32_t GetSupportedMetadataKey(uint32_t *num, HDRMetadataKey *keys) = 0; + virtual int32_t SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence) = 0; + + virtual int32_t CreateLayer(const LayerInfo *layerInfo, LayerId *layerId); + virtual int32_t CloseLayer(LayerId layerId); + + virtual int32_t PrepareDisplayLayers(bool *needFlushFb) = 0; + virtual int32_t GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type) = 0; + virtual int32_t Commit(int32_t *fence) = 0; + + HdiLayer *GetHdiLayer(LayerId id); + +protected: + LayerId GenerateLayerId(); + virtual std::unique_ptr CreateHdiLayer(LayerId id, LayerType type); + std::queue freeLayerIds_; + LayerId maxLayerIdEver_ = 0; + std::unordered_map> layers_; + std::unique_ptr clientLayer_; + std::vector changeLayers_; +}; +} // namespace DISPLAY +} // namespace HDI +using HdiDisplayId = HDI::DISPLAY::DisplayId; +using HdiDisplay = HDI::DISPLAY::HdiDisplay; +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp b/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp new file mode 100644 index 0000000..e30bc01 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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 "hdi_layer.h" + +#include + +#include "refbase.h" +#include "sync_fence.h" +#include "base/log.h" +#include "base/types.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +HdiLayerBuffer::HdiLayerBuffer(const BufferHandle &handle) + : handle_(handle), + phyAddr_(handle.phyAddr), + virAddr_(handle.virAddr), + height_(handle.height), + width_(handle.width), + size_(handle.size), + stride_(handle.stride), + format_(handle.format) +{ + if (!IsInvalidFd(handle.fd)) { + fd_ = OHOS::UniqueFd(::dup(handle.fd)); + if (fd_ < 0) { + LOG_ERROR("Failed to dup from fd: %{public}i, err: %{public}s, errno: %{public}i", + handle.fd, ErrnoToString(errno).c_str(), errno); + } + } + + // LOG_DEBUG << "HdiLayerBuffer handle width: " << width_ << ", height: " << height_ << ", fd: " << fd_; +} + +HdiLayerBuffer::~HdiLayerBuffer() noexcept {} + +HdiLayer::HdiLayer(LayerId id, LayerType type) : id_(id), type_(type) {} + +int32_t HdiLayer::SetSize(IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("HdiLayer::SetSize: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + // LOG_DEBUG << "HdiLayer::SetSize: id: " << id_ + // << Fmt(", rect x: %d y : %d w : %d h : %d", rect->x, rect->y, rect->w, rect->h); + + displayRect_ = *rect; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetCrop(IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("HdiLayer::SetCrop: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + // LOG_DEBUG << "HdiLayer::SetCrop: id: " << id_ + // << Fmt(", crop x: %d y : %d w : %d h : %d", rect->x, rect->y, rect->w, rect->h); + + crop_ = *rect; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetZOrder(uint32_t zOrder) +{ + // LOG_DEBUG << "HdiLayer::SetZOrder: id: " << id_ << ", zOrder: " << zOrder; + zOrder_ = zOrder; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetPreMulti(bool preMul) +{ + // LOG_DEBUG << "HdiLayer::SetPreMulti: id: " << id_ << ", preMul: " << preMul; + preMulti_ = preMul; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetAlpha(LayerAlpha *alpha) +{ + if (alpha == nullptr) { + LOG_ERROR("HdiLayer::SetAlpha: alpha is nullptr."); + return DISPLAY_PARAM_ERR; + } + + // LOG_DEBUG << "HdiLayer::SetPreMulti: id: " << id_ << ", alpha: " << alpha->enGlobalAlpha + // << ", gAlpha: " << alpha->gAlpha; + + alpha_ = *alpha; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetTransformMode(TransformType type) +{ + // LOG_DEBUG << "HdiLayer::TransformType: id: " << id_ << ", type: " << type; + + transformType_ = type; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetDirtyRegion(IRect *region) +{ + if (region == nullptr) { + LOG_ERROR("HdiLayer::SetDirtyRegion: region is nullptr."); + return DISPLAY_PARAM_ERR; + } + + // LOG_DEBUG << "HdiLayer::SetDirtyRegion: id: " << id_ + // << Fmt(", region x: %d, y: %d, w: %d, h: %d", region->x, region->y, region->w, region->h); + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetVisibleRegion(uint32_t num, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("HdiLayer::SetVisibleRegion: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + // LOG_DEBUG << "HdiLayer::SetVisibleRegion: id: " << id_ + // << Fmt(", rect x: %d, y: %d, w: %d, h: %d", rect->x, rect->y, rect->w, rect->h); + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetBuffer(const BufferHandle *handle, int32_t fence) +{ + if (handle == nullptr) { + LOG_ERROR("HdiLayer::SetBuffer: handle is nullptr."); + return DISPLAY_PARAM_ERR; + } + + hdiBuffer_ = std::make_unique(*handle); + acquireFence_ = OHOS::UniqueFd(dup(fence)); + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetCompositionType(CompositionType type) +{ + // LOG_DEBUG << "HdiLayer::SetCompositionType: id: " << id_ << ", type: " << type; + compositionType_ = type; + return DISPLAY_SUCCESS; +} + +int32_t HdiLayer::SetBlendType(BlendType type) +{ + // LOG_DEBUG << "HdiLayer::SetBlendType: id: " << id_ << ", type: " << type; + blendType_ = type; + return DISPLAY_SUCCESS; +} + +void HdiLayer::SetPixel(const BufferHandle &handle, int x, int y, uint32_t color) +{ + const int32_t pixelBytes = 4; + if (handle.format <= 0) { + LOG_ERROR("HdiLayer::SetPixel: not supported format: %{public}i", handle.format); + return; + } + + if (handle.virAddr == nullptr) { + LOG_ERROR("HdiLayer::SetPixel: virAddr is nullptr."); + return; + } + + if (x < 0 || x >= handle.width || y < 0 || y >= handle.height) { + LOG_ERROR("HdiLayer::SetPixel: invalid parameter: x: %{public}d, bufWidth: %{public}d, y: %{public}d, bufHeight: %{public}d", + x, handle.width, y, handle.height); + return; + } + + int32_t position = y * handle.width + x; + if ((position * pixelBytes) > handle.size) { + LOG_ERROR("HdiLayer::SetPixel: position %{public}i is outside the buffer.", position); + return; + } + uint32_t *pixel = reinterpret_cast(handle.virAddr) + position; + *pixel = color; +} + +void HdiLayer::ClearColor(uint32_t color) +{ + // LOG_DEBUG << "HdiLayer::ClearColor, color: " << color; + const auto &handle = hdiBuffer_->GetBufferHandle(); + for (int32_t x = 0; x < handle.width; x++) { + for (int32_t y = 0; y < handle.height; y++) { + SetPixel(hdiBuffer_->GetBufferHandle(), x, y, color); + } + } +} + +void HdiLayer::WaitAcquireFence() +{ + OHOS::sptr fence(new OHOS::SyncFence(acquireFence_.Release())); + if (fence->IsValid()) { + fence->Wait(fenceTimeOut_); + } +} +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h b/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h new file mode 100644 index 0000000..f313cfa --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "unique_fd.h" +#include "buffer_handle.h" +#include "display_type.h" +#include "base/noncopyable.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +const uint32_t INVALID_VALUE = ~0x0; +using LayerId = uint32_t; +constexpr LayerId INVALID_LAYER_ID = ~0x0; +const int FENCE_TIMEOUT = 3000; + +struct HdiLayerBuffer : NonCopyable { +public: + explicit HdiLayerBuffer(const BufferHandle &handle); + virtual ~HdiLayerBuffer() noexcept; + + const BufferHandle &GetBufferHandle() const + { + return handle_; + } + void *GetVirtualAddr() const + { + return virAddr_; + } + uint64_t GetPhysicalAddr() const + { + return phyAddr_; + } + int32_t GetHeight() const + { + return height_; + } + int32_t GetWight() const + { + return width_; + } + int32_t GetSize() const + { + return size_; + } + int32_t GetStride() const + { + return stride_; + } + int32_t GetFormat() const + { + return format_; + } + int Fd() const + { + return fd_; + } + +private: + BufferHandle handle_; + uint64_t phyAddr_ = 0; + void *virAddr_ = nullptr; + int32_t height_ = 0; + int32_t width_ = 0; + int32_t size_ = 0; + int32_t stride_ = 0; + int32_t format_ = 0; + OHOS::UniqueFd fd_; +}; + +class HdiLayer : NonCopyable { +public: + HdiLayer(LayerId id, LayerType type = LAYER_TYPE_GRAPHIC); + virtual ~HdiLayer() noexcept = default; + + uint32_t GetId() const + { + return id_; + } + uint32_t GetZOrder() const + { + return zOrder_; + } + const IRect &GetLayerDisplayRect() const + { + return displayRect_; + } + const IRect &GetLayerCrop() const + { + return crop_; + } + bool GetLayerPreMulti() const + { + return preMulti_; + } + const LayerAlpha &GetAlpha() const + { + return alpha_; + } + LayerType GetType() const + { + return type_; + } + TransformType GetTransFormType() const + { + return transformType_; + } + BlendType GetLayerBlenType() const + { + return blendType_; + } + CompositionType GetCompositionType() const + { + return compositionType_; + } + void SetDeviceSelect(CompositionType type) + { + deviceSelect_ = type; + } + CompositionType GetDeviceSelect() const + { + return deviceSelect_; + } + int GetAcquireFenceFd() + { + return acquireFence_.Get(); + } + int GetReleaseFenceFd() + { + return releaseFence_.Get(); + } + void SetReleaseFence(int fd) + { + releaseFence_ = OHOS::UniqueFd(::dup(fd)); + }; + + void ClearColor(uint32_t color); + void SetPixel(const BufferHandle &handle, int x, int y, uint32_t color); + + void WaitAcquireFence(); + virtual int32_t SetSize(IRect *rect); + virtual int32_t SetCrop(IRect *rect); + virtual int32_t SetZOrder(uint32_t zOrder); + virtual int32_t SetPreMulti(bool preMul); + virtual int32_t SetAlpha(LayerAlpha *alpha); + virtual int32_t SetTransformMode(TransformType type); + virtual int32_t SetDirtyRegion(IRect *region); + virtual int32_t SetVisibleRegion(uint32_t num, IRect *rect); + virtual int32_t SetBuffer(const BufferHandle *handle, int32_t fence); + virtual int32_t SetCompositionType(CompositionType type); + virtual int32_t SetBlendType(BlendType type); + virtual HdiLayerBuffer *GetCurrentBuffer() + { + return hdiBuffer_.get(); + } + + int32_t SetTunnelHandle(ExtDataHandle *handle) + { + tunnelHandle_ = handle; + return DISPLAY_SUCCESS; + } + ExtDataHandle *tunnelHandle_ = nullptr; + +private: + uint32_t id_ = INVALID_LAYER_ID; + LayerType type_ = LAYER_TYPE_GRAPHIC; + OHOS::UniqueFd acquireFence_; + OHOS::UniqueFd releaseFence_; + + IRect displayRect_ = {}; + IRect crop_ = {}; + uint32_t zOrder_ = INVALID_VALUE; + bool preMulti_ = false; + LayerAlpha alpha_ = {}; + int fenceTimeOut_ = FENCE_TIMEOUT; + TransformType transformType_ = ROTATE_BUTT; + CompositionType compositionType_ = COMPOSITION_CLIENT; + CompositionType deviceSelect_ = COMPOSITION_CLIENT; + BlendType blendType_ = BLEND_NONE; + std::unique_ptr hdiBuffer_; +}; + +inline bool operator<(const HdiLayer &lhs, const HdiLayer &rhs) +{ + return lhs.GetZOrder() < rhs.GetZOrder(); +} +inline bool operator<=(const HdiLayer &lhs, const HdiLayer &rhs) +{ + return lhs.GetZOrder() <= rhs.GetZOrder(); +} +inline bool operator>(const HdiLayer &lhs, const HdiLayer &rhs) +{ + return !(lhs <= rhs); +} +inline bool operator>=(const HdiLayer &lhs, const HdiLayer &rhs) +{ + return !(lhs < rhs); +} +} // namespace DISPLAY +} // namespace HDI + +namespace drm { +using HdiLayerId = HDI::DISPLAY::LayerId; +using HdiLayer = HDI::DISPLAY::HdiLayer; +using HdiLayerBuffer = HDI::DISPLAY::HdiLayerBuffer; +} // namespace drm +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp b/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp new file mode 100644 index 0000000..613ecb6 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "hdi_session.h" + +#include + +#include "display_layer.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { +namespace detail { +constexpr char DEFAULT_DRM_DEVICE_PATH[] = "/dev/dri/card0"; + +#ifdef USE_LIBUDEV +std::shared_ptr FindPrimaryDevice(struct udev *udevice, std::string seatId = defaultSeat) +{ + if (udevice == nullptr) { + LOG_ERROR("Failed to initialize udev context."); + return nullptr; + } + + std::shared_ptr drmDevice; + UdevObject udevEnum(udev_enumerate_new(udevice), udev_enumerate_unref); + + udev_enumerate_add_match_subsystem(udevEnum.Get(), "drm"); + udev_enumerate_add_match_sysname(udevEnum.Get(), "card[0-9]*"); + udev_enumerate_scan_devices(udevEnum.Get()); + + struct udev_list_entry *entry = nullptr; + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udevEnum.Get())) + { + const char *devicePath = udev_list_entry_get_name(entry); + UdevObject device(udev_device_new_from_syspath(udevice, devicePath), udev_device_unref); + if (device == nullptr) { + continue; + } + + const char *deviceSeat = udev_device_get_property_value(device.Get(), "ID_SEAT"); + if (deviceSeat == nullptr) { + deviceSeat = defaultSeat; + } + if (deviceSeat != seatId) { + continue; + } + + if (IsBootVGADevice(device.Get())) { + // If we create a drmDevice from this devicePath which indicate the boot vga device successfully, + // then we can break the enumeration immediately. + const char *filePath = udev_device_get_devnode(device.Get()); + auto tmpDrmDevice = drm::DrmDevice::Create(filePath); + if (tmpDrmDevice != nullptr) { + drmDevice = tmpDrmDevice; + break; + } + } + } + + return drmDevice; +} +#endif // USE_LIBUDEV +} // namespace detail + +HdiSession &HdiSession::GetInstance() +{ + static HdiSession instance; + return instance; +} + +HdiSession::HdiSession() +#ifdef USE_LIBUDEV + : udev_(udev_new(), udev_unref) +#endif // USE_LIBUDEV +{ +#ifdef USE_LIBUDEV + displayDevice_ = detail::FindPrimaryDevice(udev_.Get()); + if (displayDevice_ == nullptr) { + displayDevice_ = drm::DrmDevice::Create(detail::DEFAULT_DRM_DEVICE_PATH); + } +#else // USE_LIBUDEV + displayDevice_ = drm::DrmDevice::Create(detail::DEFAULT_DRM_DEVICE_PATH); +#endif // USE_LIBUDEV + + if (displayDevice_ == nullptr) { + LOG_FATAL("Failed to find primary display device!"); + } + +#ifdef USE_LIBUDEV + deviceEventMonitor_ = std::make_shared( + udev_.Get(), displayDevice_, [this](TimeStamp timeStamp, struct udev_device *event) { + OnHotPlugEvent(timeStamp, event); + }); +#else // USE_LIBUDEV + deviceEventMonitor_ = std::make_shared(displayDevice_); +#endif // USE_LIBUDEV +} + +HdiSession::~HdiSession() noexcept {} + +int32_t HdiSession::RegHotPlugCallback(HotPlugCallback callback, void *data) +{ + if (callback == nullptr) { + LOG_ERROR("HdiSession::RegHotPlugCallback: param callback is nullptr."); + return DISPLAY_PARAM_ERR; + } + + if (hotPlugCallback_ != nullptr) { + LOG_ERROR("HdiSession::RegHotPlugCallback: callback already registered."); + return DISPLAY_SUCCESS; + } + + hotPlugCallback_ = callback; + hotPlugUserData_ = data; + const auto &displays = displayDevice_->GetDisplays(); + for (const auto &[id, display] : displays) { + DoHotPlugCallback(id, display->IsConnected()); + } + + if (!deviceEventMonitor_->Init()) { + LOG_ERROR("HdiSession::RegHotPlugCallback Failed to init device event monitor!"); + } + return DISPLAY_SUCCESS; +} + +void HdiSession::DoHotPlugCallback(uint32_t devId, bool connect) +{ + if (hotPlugCallback_ == nullptr) { + LOG_ERROR("HdiSession::DoHotPlugCallback: callback is nullptr."); + return; + } + hotPlugCallback_(devId, connect, hotPlugUserData_); +} + +#ifdef USE_LIBUDEV +// TODO:Implement this function +void HdiSession::OnHotPlugEvent(TimeStamp timeStamp, struct udev_device *event) {} +// FIXME: ifndef USE_LIBUDEV +#endif // USE_LIBUDEV +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm + +using namespace oewm::HDI::DISPLAY; +static int32_t RegHotPlugCallback(HotPlugCallback callback, void *data) +{ + HdiSession::GetInstance().RegHotPlugCallback(callback, data); + return DISPLAY_SUCCESS; +} + +static int32_t GetDisplayCapability(uint32_t devId, DisplayCapability *info) +{ + if (info == nullptr) { + LOG_ERROR("GetDisplayCapability: info is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCapability, info); +} + +static int32_t GetDisplaySupportedModes(uint32_t devId, uint32_t *num, DisplayModeInfo *modes) +{ + if (num == nullptr) { + LOG_ERROR("GetDisplaySupportedModes: num is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplaySupportedModes, num, modes); +} + +static int32_t GetDisplayMode(uint32_t devId, uint32_t *mode) +{ + if (mode == nullptr) { + LOG_ERROR("GetDisplayMode: mode is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayMode, mode); +} + +static int32_t SetDisplayMode(uint32_t devId, uint32_t mode) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayMode, mode); +} + +static int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus *status) +{ + if (status == nullptr) { + LOG_ERROR("GetDisplayPowerStatus: status is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayPowerStatus, status); +} + +static int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayPowerStatus, status); +} + +static int32_t GetDisplayBacklight(uint32_t devId, uint32_t *value) +{ + if (value == nullptr) { + LOG_ERROR("GetDisplayBacklight: value is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayBacklight, value); +} + +static int32_t SetDisplayBacklight(uint32_t devId, uint32_t value) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayBacklight, value); +} + +static int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t *value) +{ + UNUSED(id); + UNUSED(value); + + return DISPLAY_NOT_SUPPORT; +} + +static int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value) +{ + UNUSED(id); + UNUSED(value); + return DISPLAY_NOT_SUPPORT; +} + +static int32_t PrepareDisplayLayers(uint32_t devId, bool *needFlushFb) +{ + if (needFlushFb == nullptr) { + LOG_ERROR("PrepareDisplayLayers: needFlushFb is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::PrepareDisplayLayers, needFlushFb); +} + +static int32_t GetDisplayCompChange(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *type) +{ + if (num == nullptr) { + LOG_ERROR("GetDisplayCompChange: num is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCompChange, num, layers, type); +} + +static int32_t SetDisplayClientCrop(uint32_t devId, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("SetDisplayClientCrop: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return DISPLAY_NOT_SUPPORT; +} + +static int32_t SetDisplayClientDestRect(uint32_t devId, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("SetDisplayClientDestRect: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return DISPLAY_NOT_SUPPORT; +} + +static int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle *buffer, int32_t fence) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayClientBuffer, buffer, fence); +} + +static int32_t SetDisplayClientDamage(uint32_t devId, uint32_t num, IRect *rect) +{ + UNUSED(num); + UNUSED(rect); + return DISPLAY_NOT_SUPPORT; +} + +static int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayVsyncEnabled, enabled); +} + +static int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback callback, void *data) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::RegDisplayVBlankCallback, callback, data); +} + +static int32_t GetDisplayReleaseFence(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *fences) +{ + if (num == nullptr) { + LOG_ERROR("GetDisplayReleaseFence: num is nullptr."); + return DISPLAY_PARAM_ERR; + } + return HdiSession::GetInstance().CallDisplayFunction( + devId, &HdiDisplay::GetDisplayReleaseFence, num, layers, fences); +} + +static int32_t GetDisplaySupportedColorGamuts(uint32_t devId, uint32_t *num, ColorGamut *gamuts) +{ + if (num == nullptr) { + LOG_ERROR("GetDisplaySupportedColorGamuts: num is nullptr."); + return DISPLAY_PARAM_ERR; + } + return HdiSession::GetInstance().CallDisplayFunction( + devId, &HdiDisplay::GetDisplaySupportedColorGamuts, num, gamuts); +} + +static int32_t GetDisplayColorGamut(uint32_t devId, ColorGamut *gamut) +{ + if (gamut == nullptr) { + LOG_ERROR("GetDisplayColorGamut: gamut is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayColorGamut, gamut); +} + +static int32_t SetDisplayColorGamut(uint32_t devId, ColorGamut gamut) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayColorGamut, gamut); +} + +static int32_t GetDisplayGamutMap(uint32_t devId, GamutMap *gamutMap) +{ + if (gamutMap == nullptr) { + LOG_ERROR("GetDisplayGamutMap: gamutMap is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayGamutMap, gamutMap); +} + +static int32_t SetDisplayGamutMap(uint32_t devId, GamutMap gamutMap) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayGamutMap, gamutMap); +} + +static int32_t GetHDRCapabilityInfos(uint32_t devId, HDRCapability *info) +{ + if (info == nullptr) { + LOG_ERROR("GetHDRCapabilityInfos: info is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetHDRCapabilityInfos, info); +} + +static int32_t GetSupportedMetadataKey(uint32_t devId, uint32_t *num, HDRMetadataKey *keys) +{ + if (num == nullptr) { + LOG_ERROR("GetSupportedMetadataKey: num is nullptr."); + return DISPLAY_PARAM_ERR; + } + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetSupportedMetadataKey, num, keys); +} + +static int32_t Commit(uint32_t devId, int32_t *fence) +{ + if (fence == nullptr) { + LOG_ERROR("Commit: fence is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::Commit, fence); +} + +static int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format, uint32_t *devId) +{ + return DISPLAY_NOT_SUPPORT; +} +static int32_t DestroyVirtualDisplay(uint32_t devId) +{ + return DISPLAY_NOT_SUPPORT; +} +static int32_t SetVirtualDisplayBuffer(uint32_t devId, BufferHandle *buffer, int32_t releaseFence) +{ + return DISPLAY_NOT_SUPPORT; +} + +// Layer function +static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId) +{ + if (layerId == nullptr) { + LOG_ERROR("CreateLayer: layerId is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CreateLayer, layerInfo, layerId); +} + +static int32_t CloseLayer(uint32_t devId, uint32_t layerId) +{ + return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CloseLayer, layerId); +} + +static int32_t SetLayerSize(uint32_t devId, uint32_t layerId, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("SetLayerSize: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetSize, rect); +} + +static int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("SetLayerCrop: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetCrop, rect); +} + +static int32_t SetLayerZOrder(uint32_t devId, uint32_t layerId, uint32_t zOrder) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetZOrder, zOrder); +} + +static int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetPreMulti, preMul); +} + +static int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, LayerAlpha *alpha) +{ + if (alpha == nullptr) { + LOG_ERROR("SetLayerAlpha: alpha is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetAlpha, alpha); +} + +static int32_t SetTransformMode(uint32_t devId, uint32_t layerId, TransformType type) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTransformMode, type); +} + +static int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, IRect *region) +{ + if (region == nullptr) { + LOG_ERROR("SetLayerDirtyRegion: region is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetDirtyRegion, region); +} + +static int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, uint32_t num, IRect *rect) +{ + if (rect == nullptr) { + LOG_ERROR("SetLayerVisibleRegion: rect is nullptr."); + return DISPLAY_PARAM_ERR; + } + + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetVisibleRegion, num, rect); +} + +static int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle *buffer, int32_t fence) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetBuffer, buffer, fence); +} + +static int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetCompositionType, type); +} + +static int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetBlendType, type); +} + +static int32_t SetLayerTunnelHandle(uint32_t devId, uint32_t layerId, ExtDataHandle *handle) +{ + return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTunnelHandle, handle); +} + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus +int32_t DeviceInitialize(DeviceFuncs **funcs) +{ + LOG_INFO("hdi device initialize begin."); + if (funcs == nullptr) { + LOG_ERROR("DeviceInitialize: param funcs is nullptr."); + return DISPLAY_PARAM_ERR; + } + + auto deviceFuncs = (DeviceFuncs *)calloc(1, sizeof(DeviceFuncs)); + if (deviceFuncs == nullptr) { + LOG_ERROR("DeviceInitialize: deviceFuncs alloc failed, err: %{public}s", oewm::ErrnoToString(errno).c_str()); + return DISPLAY_FAILURE; + } + + deviceFuncs->RegHotPlugCallback = RegHotPlugCallback; + deviceFuncs->GetDisplayCapability = GetDisplayCapability; + deviceFuncs->GetDisplaySupportedModes = GetDisplaySupportedModes; + deviceFuncs->GetDisplayMode = GetDisplayMode; + deviceFuncs->SetDisplayMode = SetDisplayMode; + deviceFuncs->GetDisplayPowerStatus = GetDisplayPowerStatus; + deviceFuncs->SetDisplayPowerStatus = SetDisplayPowerStatus; + deviceFuncs->PrepareDisplayLayers = PrepareDisplayLayers; + deviceFuncs->GetDisplayBacklight = GetDisplayBacklight; + deviceFuncs->SetDisplayBacklight = SetDisplayBacklight; + deviceFuncs->GetDisplayProperty = GetDisplayProperty; + deviceFuncs->GetDisplayCompChange = GetDisplayCompChange; + deviceFuncs->SetDisplayClientCrop = SetDisplayClientCrop; + deviceFuncs->SetDisplayClientDestRect = SetDisplayClientDestRect; + deviceFuncs->SetDisplayClientBuffer = SetDisplayClientBuffer; + deviceFuncs->SetDisplayClientDamage = SetDisplayClientDamage; + deviceFuncs->SetDisplayVsyncEnabled = SetDisplayVsyncEnabled; + deviceFuncs->RegDisplayVBlankCallback = RegDisplayVBlankCallback; + deviceFuncs->GetDisplayReleaseFence = GetDisplayReleaseFence; + deviceFuncs->GetDisplaySupportedColorGamuts = GetDisplaySupportedColorGamuts; + deviceFuncs->GetDisplayColorGamut = GetDisplayColorGamut; + deviceFuncs->SetDisplayColorGamut = SetDisplayColorGamut; + deviceFuncs->GetDisplayGamutMap = GetDisplayGamutMap; + deviceFuncs->SetDisplayGamutMap = SetDisplayGamutMap; + deviceFuncs->GetHDRCapabilityInfos = GetHDRCapabilityInfos; + deviceFuncs->GetSupportedMetadataKey = GetSupportedMetadataKey; + deviceFuncs->CreateVirtualDisplay = CreateVirtualDisplay; + deviceFuncs->DestroyVirtualDisplay = DestroyVirtualDisplay; + deviceFuncs->SetVirtualDisplayBuffer = SetVirtualDisplayBuffer; + deviceFuncs->SetDisplayProperty = SetDisplayProperty; + + deviceFuncs->Commit = Commit; + *funcs = deviceFuncs; + LOG_INFO("hdi device initialize succeed."); + return DISPLAY_SUCCESS; +} + +int32_t DeviceUnInitialize(DeviceFuncs *funcs) +{ + if (funcs == nullptr) { + LOG_ERROR("DeviceUnInitialize: param funcs is nullptr."); + return DISPLAY_PARAM_ERR; + } + + free(funcs); + LOG_INFO("hdi device unInitialize succeed."); + + return DISPLAY_SUCCESS; +} + +int32_t LayerInitialize(LayerFuncs **funcs) +{ + LOG_INFO("hdi layer initialize begin."); + if (funcs == nullptr) { + LOG_ERROR("LayerInitialize: param funcs is nullptr."); + return DISPLAY_PARAM_ERR; + } + + LayerFuncs *layerFuncs = (LayerFuncs *)calloc(1, sizeof(LayerFuncs)); + if (layerFuncs == nullptr) { + LOG_ERROR("LayerInitialize: layerFuncs alloc failed, err: %{public}s", oewm::ErrnoToString(errno).c_str()); + return DISPLAY_FAILURE; + } + + layerFuncs->SetLayerAlpha = SetLayerAlpha; + layerFuncs->CreateLayer = CreateLayer; + layerFuncs->CloseLayer = CloseLayer; + layerFuncs->SetLayerSize = SetLayerSize; + layerFuncs->SetLayerCrop = SetLayerCrop; + layerFuncs->SetLayerZorder = SetLayerZOrder; + layerFuncs->SetLayerPreMulti = SetLayerPreMulti; + layerFuncs->SetTransformMode = SetTransformMode; + layerFuncs->SetLayerDirtyRegion = SetLayerDirtyRegion; + layerFuncs->SetLayerVisibleRegion = SetLayerVisibleRegion; + layerFuncs->SetLayerBuffer = SetLayerBuffer; + layerFuncs->SetLayerCompositionType = SetLayerCompositionType; + layerFuncs->SetLayerBlendType = SetLayerBlendType; + layerFuncs->SetLayerTunnelHandle = SetLayerTunnelHandle; + + *funcs = layerFuncs; + LOG_INFO("hdi layer initialize succeed."); + return DISPLAY_SUCCESS; +} + +int32_t LayerUnInitialize(LayerFuncs *funcs) +{ + if (funcs == nullptr) { + LOG_ERROR("LayerUnInitialize: param funcs is nullptr."); + return DISPLAY_PARAM_ERR; + } + + free(funcs); + + LOG_INFO("layer unInitialize succeed."); + + return DISPLAY_SUCCESS; +} +#if defined(__cplusplus) +} +#endif // __cplusplus diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h b/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h new file mode 100644 index 0000000..fb4617b --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "device_event_monitor.h" +#include "display_device.h" +#include "display_type.h" +#include "hdi_display.h" +#include "base/log.h" + +#ifdef USE_LIBUDEV +#include "udev_object_helper.h" +#endif // USE_LIBUDEV + +namespace oewm { +namespace HDI { +namespace DISPLAY { +// singleton +class HdiSession : NonCopyable { +public: + ~HdiSession() noexcept; + static HdiSession &GetInstance(); + + const std::shared_ptr &GetDisplayDevice() const + { + return displayDevice_; + } + + const std::shared_ptr &GetDeviceEventMonitor() const + { + return deviceEventMonitor_; + } + + template + int32_t CallDisplayFunction(DisplayId devId, int32_t (HdiDisplay::*member)(Args...), Args... args) + { + if (devId == INVALID_DISPLAY_ID) { + LOG_ERROR("HdiSession::CallDisplayFunction: invalid device id."); + return DISPLAY_PARAM_ERR; + } + auto &displays = displayDevice_->GetMutableDisplays(); + if (displays.count(devId) == 0) { + LOG_ERROR("HdiSession::CallDisplayFunction: can not find display for device id %{public}" PRIu32, devId); + return DISPLAY_FAILURE; + } + auto display = displays.at(devId).get(); + return (display->*member)(std::forward(args)...); + } + + template + int32_t CallLayerFunction(DisplayId devId, LayerId layerId, int32_t (HdiLayer::*member)(Args...), Args... args) + { + if (devId == INVALID_DISPLAY_ID) { + LOG_ERROR("HdiSession::CallLayerFunction: invalid device id."); + return DISPLAY_PARAM_ERR; + } + + const auto &displays = displayDevice_->GetDisplays(); + if (displays.count(devId) == 0) { + LOG_ERROR("HdiSession::CallLayerFunction: can not find display for device id %{public}" PRIu32, devId); + return DISPLAY_FAILURE; + } + + auto &display = displays.at(devId); + auto layer = display->GetHdiLayer(layerId); + if (layer == nullptr) { + LOG_ERROR("HdiSession::CallLayerFunction: can not find layer(id: %{public}" PRIu32 ") for display %{public}" PRIu32, + layerId, devId); + return DISPLAY_FAILURE; + } + + return (layer->*member)(std::forward(args)...); + } + + int32_t RegHotPlugCallback(HotPlugCallback callback, void *data); + +private: + HdiSession(); + + void DoHotPlugCallback(uint32_t devId, bool connect); +#ifdef USE_LIBUDEV + void OnHotPlugEvent(TimeStamp timeStamp, struct udev_device *event); + UdevObject udev_; +#endif // USE_LIBUDEV + std::shared_ptr deviceEventMonitor_; + std::shared_ptr displayDevice_; + + HotPlugCallback hotPlugCallback_ = nullptr; + void *hotPlugUserData_ = nullptr; +}; +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h b/display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h new file mode 100644 index 0000000..7269b5d --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include + +#include "base/types.h" + +namespace oewm { +static constexpr char defaultSeat[] = "seat0"; + +// RAII for udev objects to do auto unref. +template +class UdevObject : NonCopyable { +public: + using UdevObjectUnRefFunc = T *(*)(T *); + using Pointer = T *; + +public: + UdevObject() = default; + UdevObject(Pointer obj, UdevObjectUnRefFunc unrefFunc) : obj_(obj), unrefFunc_(unrefFunc) {} + ~UdevObject() noexcept + { + if (OE_LIKELY(obj_ != nullptr) && OE_LIKELY(unrefFunc_ != nullptr)) { + unrefFunc_(obj_); + } + } + + Pointer Get() const + { + return obj_; + } + bool operator==(std::nullptr_t) const + { + return obj_ == nullptr; + } + bool operator!=(std::nullptr_t) const + { + return obj_ != nullptr; + } + +private: + Pointer obj_ = nullptr; + UdevObjectUnRefFunc unrefFunc_ = nullptr; +}; + +inline bool IsBootVGADevice(struct udev_device *device) +{ + struct udev_device *pciDevice = udev_device_get_parent_with_subsystem_devtype(device, "pci", nullptr); + if (pciDevice == nullptr) { + return false; + } + + const char *bootVGAId = udev_device_get_sysattr_value(pciDevice, "boot_vga"); + if (bootVGAId == nullptr) { + return false; + } + + return strcmp(bootVGAId, "1") == 0; +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn b/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn new file mode 100644 index 0000000..9131c69 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (c) 2022 Huawei Device 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. +import("//build/gn/fangtian.gni") + +config("display_gralloc_public_config") { + include_dirs = [ + "//display_server/drivers/hal/core/drm_backend/display_gralloc", + "//display_server/drivers/hal/core/drm_backend/include", + + "//display_server/drivers/interfaces", + "//display_server/drivers/base", + ] +} + +ft_shared_library("display_gralloc") { + sources = [ + "allocator.cpp", + "allocator_controller.cpp", + "display_gralloc.cpp", + "display_gralloc_utils.cpp", + "dumb_allocator.cpp", + "gbm_allocator.cpp", + "hi_drm_format.cpp", + "hi_gbm_format.cpp", + "shm_allocator.cpp", + ] + + configs = [ + "//display_server/drivers/hal:oehal_public_config" + ] + + public_configs = [ + ":display_gralloc_public_config", + "//display_server/drivers/hal/core/drm_backend:import_system_gbm_config" + ] + + public_deps = [ + "//display_server/drivers/hal/core/drm_backend:display_drm_dep", + "//display_server/drivers/hal/base:oebase" + ] + deps = [ + "//display_server/drivers/hal/core/drm_backend/display_device:display_device", + ] +} diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp new file mode 100644 index 0000000..1afc5fb --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "allocator.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY {} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h new file mode 100644 index 0000000..90c5273 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "display_type.h" + +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +class Allocator { +public: + Allocator() = default; + virtual ~Allocator() noexcept = default; + + virtual int32_t Init() + { + return DISPLAY_SUCCESS; + } + + /** + * @brief Allocates memory based on the parameters passed by the GUI. + * + * @param info Indicates the pointer to the description info of the memory to allocate. + * @param bufferPtr Indicates the double pointer to the buffer of the memory to allocate. + * @return Returns DISPLAY_SUCCESS(0) if the operation is successful; returns an error code otherwise. + */ + virtual int32_t AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) = 0; + /** + * @brief Releases memory. + * + * @param buffer Indicates the pointer to the buffer of the memory to release. + * @return Returns DISPLAY_SUCCESS(0) if the operation is successful; returns an error code otherwise. + */ + virtual int32_t FreeMem(BufferHandle *buffer) = 0; + /** + * @brief Maps memory to memory without cache in the process's address space. + * + * @param buffer Indicates the pointer to the buffer of the memory to map. + * @return Returns the pointer to a valid address if the operation is successful; returns nullptr otherwise. + */ + virtual void *Mmap(BufferHandle &buffer) = 0; + /** + * @brief Unmaps memory, that is, removes any mappings from the process's address space. + * + * @param buffer Indicates the pointer to the buffer of the memory to unmap. + * @return Returns DISPLAY_SUCCESS(0) if the operation is successful; returns an error code defined otherwise. + */ + virtual int32_t Unmap(BufferHandle &buffer) = 0; + /** + * @brief Flushes data from the cache mapped via Mmap() to memory and invalidates the data in the cache. + * + * @param buffer Indicates the pointer to the buffer of the cache to flush. + * @return Returns DISPLAY_SUCCESS(0) if the operation is successful; returns an error code defined otherwise. + */ + virtual int32_t FlushCache(BufferHandle &buffer) = 0; + /** + * @brief Invalidates the cache to update it from memory. + * + * @param buffer Indicates the pointer to the buffer of the cache, which will been invalidated. + * @return Returns DISPLAY_SUCCESS(0) if the operation is successful; returns an error code defined otherwise. + */ + virtual int32_t InvalidateCache(BufferHandle &buffer) = 0; +}; + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp new file mode 100644 index 0000000..e5d10b5 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "allocator_controller.h" + +#include "gbm_allocator.h" +#include "dumb_allocator.h" +#include "shm_allocator.h" +#include "display_type.h" +#include "base/log.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +int32_t AllocatorController::Init() +{ + LOG_DEBUG("[Gralloc::AllocatorController::Init] Init."); + + gbmAllocator_.reset(new GbmAllocator()); + gbmAllocator_->Init(); + dumbAllocator_.reset(new DumbAllocator()); + dumbAllocator_->Init(); + shmAllocator_.reset(new ShmAllocator()); + shmAllocator_->Init(); + + isEnabled_ = true; + return DISPLAY_SUCCESS; +} + +int32_t AllocatorController::Uninit() +{ + LOG_DEBUG("[Gralloc::AllocatorController::Uninit] Uninit."); + + gbmAllocator_.reset(); + dumbAllocator_.reset(); + shmAllocator_.reset(); + + isEnabled_ = false; + return DISPLAY_SUCCESS; +} + +std::shared_ptr AllocatorController::GetAllocator(uint64_t usage) +{ + // If user need DMA buffer, we could alloc buffer by: + // * DRM: Dumb Buffer for CPU Rendering (when usage include `CPU_WRITE`) + // * GBM: Smart Buffer for GPU Rendering (other case) + if (usage & HBM_USE_MEM_DMA) { + if (usage & HBM_USE_CPU_WRITE) { + LOG_DEBUG("[Gralloc::AllocatorController::GetAllocator] Choose Dumb Allocator."); + return dumbAllocator_; + } else { +#ifdef DRM_BACKEND_USE_GBM + LOG_DEBUG("[Gralloc::AllocatorController::GetAllocator] Choose GBM Allocator."); + return gbmAllocator_; +#else + LOG_ERROR("[Gralloc::AllocatorController::GetAllocator] DRM Backend not support GBM."); + return nullptr; +#endif // DRM_BACKEND_USE_GBM + } + } + + // If user need CPU buffer for CPU Rendering, we will provide shared memory. + if (!(usage & HBM_USE_MEM_DMA) && (usage & HBM_USE_CPU_WRITE)) { + return shmAllocator_; + } + + LOG_ERROR("[Gralloc::AllocatorController::GetAllocator] This usage is not supported: %{public}" PRIu64, usage); + return nullptr; +} + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm \ No newline at end of file diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h new file mode 100644 index 0000000..962436e --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "allocator.h" + +#include +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +// singleton +class AllocatorController { +public: + static AllocatorController &GetInstance() + { + static AllocatorController instance; + return instance; + } + + AllocatorController(const AllocatorController &) = delete; + ~AllocatorController() noexcept = default; + + /** + * @brief Init AllocatorController + * + * init it before call `GetAllocator()`. + * @return int32_t DispErrCode + */ + int32_t Init(); + /** + * @brief Uninit AllocatorController + * + * free allocators. + * @return int32_t DispErrCode + */ + int32_t Uninit(); + /** + * @brief Get the buffer allocator depending on buffer usage. + * + * @param usage Buffer usage + * @return std::shared_ptr return Allocator. If failed, return nullptr. + */ + std::shared_ptr GetAllocator(uint64_t usage); + +private: + AllocatorController() {} + +private: + bool isEnabled_ = false; + + std::shared_ptr gbmAllocator_ = nullptr; + std::shared_ptr dumbAllocator_ = nullptr; + std::shared_ptr shmAllocator_ = nullptr; +}; + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp new file mode 100644 index 0000000..1103cee --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +// Tips: +// Current Gralloc Module only support usage below: +// * "HBM_USE_MEM_DMA": if you try to allocate DMABUF, it'll provide GBM for GPU Rendering and provide DRM Dumb Buffer +// for CPU Rendering. +// * "HBM_USE_CPU_WRITE & !HBM_USE_MEM_DMA": if you try to allocate a buffer which will be rendered by CPU, it can't be +// a DMABUF. +// * Other: not support yet. +// +// Recommanded usage: +// * GPU Rendering: "HBM_USE_MEM_DMA" + "HBM_USE_MEM_FB" +// * CPU Rendering: "HBM_USE_CPU_READ" + "HBM_USE_CPU_WRITE" + "HBM_USE_MEM_DMA" + "HBM_USE_MEM_FB" + +#include "display_gralloc.h" + +#include "allocator_controller.h" +#include "display_type.h" +#include "base/log.h" + +using namespace oewm::HDI::DISPLAY; + +int32_t AllocMem(const AllocInfo *info, BufferHandle **handle) +{ + /** + * the memory should complete some important tasks below: + * 1. create buffer depends on buffer usage & local env + * 2. get buffer fd for interprocess transfering + */ + + if (info == nullptr) { + LOG_ERROR("Get nullptr param: `info`"); + return DISPLAY_PARAM_ERR; + } + + if (handle == nullptr) { + LOG_ERROR("Get nullptr param: `handle`"); + return DISPLAY_PARAM_ERR; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(info->usage); + if (allocator == nullptr) { + return DISPLAY_NULL_PTR; + } + + return allocator->AllocMem(*info, handle); +} + +void FreeMem(BufferHandle *handle) +{ + if (handle == nullptr) { + LOG_ERROR("[Gralloc::FreeMem] Get nullptr param: `handle`"); + return; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(handle->usage); + if (allocator == nullptr) { + return; + } + + allocator->FreeMem(handle); +} + +void *Mmap(BufferHandle *handle) +{ + if (handle == nullptr) { + LOG_ERROR("[Gralloc::Mmap] Get nullptr param: `handle`"); + return nullptr; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(handle->usage); + if (allocator == nullptr) { + return nullptr; + } + + return allocator->Mmap(*handle); +} + +int32_t Unmap(BufferHandle *handle) +{ + if (handle == nullptr) { + LOG_ERROR("[Gralloc::Unmap] Get nullptr param: `handle`"); + return DISPLAY_PARAM_ERR; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(handle->usage); + if (allocator == nullptr) { + return DISPLAY_NULL_PTR; + } + + return allocator->InvalidateCache(*handle); +} + +int32_t FlushCache(BufferHandle *handle) +{ + if (handle == nullptr) { + LOG_ERROR("[Gralloc::FlushCache] Get nullptr param: `handle`"); + return DISPLAY_PARAM_ERR; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(handle->usage); + if (allocator == nullptr) { + return DISPLAY_NULL_PTR; + } + + return allocator->FlushCache(*handle); +} + +int32_t InvalidateCache(BufferHandle *handle) +{ + if (handle == nullptr) { + LOG_ERROR("[Gralloc::InvalidateCache] Get nullptr param: `handle`"); + return DISPLAY_PARAM_ERR; + } + + auto allocator = AllocatorController::GetInstance().GetAllocator(handle->usage); + if (allocator == nullptr) { + return DISPLAY_NULL_PTR; + } else { + return allocator->InvalidateCache(*handle); + } +} + +int32_t GrallocUninitialize(GrallocFuncs *funcs) +{ + if (funcs == nullptr) { + LOG_ERROR("[Gralloc::GrallocUninitialize] Get nullptr param: `funcs`"); + return DISPLAY_PARAM_ERR; + } + + delete funcs; + + return AllocatorController::GetInstance().Uninit(); +} + +int32_t GrallocInitialize(GrallocFuncs **funcs) +{ + if (funcs == nullptr) { + LOG_ERROR("[Gralloc::GrallocInitialize] Get nullptr param: `funcs`"); + return DISPLAY_PARAM_ERR; + } + + if (AllocatorController::GetInstance().Init() != DISPLAY_SUCCESS) { + LOG_ERROR("[Gralloc::GrallocInitialize] Failed to init allocator controller"); + return DISPLAY_FAILURE; + } + + GrallocFuncs *grallocFuncs = new GrallocFuncs(); + + grallocFuncs->AllocMem = AllocMem; + grallocFuncs->FreeMem = FreeMem; + grallocFuncs->Mmap = Mmap; + grallocFuncs->Unmap = Unmap; + grallocFuncs->InvalidateCache = InvalidateCache; + grallocFuncs->FlushCache = FlushCache; + *funcs = grallocFuncs; + + return DISPLAY_SUCCESS; +} \ No newline at end of file diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp new file mode 100644 index 0000000..6e17577 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "display_gralloc_utils.h" + +#include "base/log.h" +#include "hdi_session.h" + +// driver +#include + +namespace GrallocUtils { +int GetDrmFdFromSession() +{ + const auto &session = oewm::HDI::DISPLAY::HdiSession::GetInstance(); + const auto &device = session.GetDisplayDevice(); + if (device == nullptr) { + LOG_ERROR("[Gralloc] Get empty DRM device from HdiSession."); + return -1; + } + + return device->Fd(); +} + +int32_t DmaBufferSync(const BufferHandle *handle, bool isStart) +{ + // LOG_DEBUG << "[Gralloc] Sync DMA-BUF mmap cache : " << (isStart ? "invalidate" : "flush"); + const int RETRY_TIMES = 6; + + struct dma_buf_sync syncFlag = {.flags = 0}; + + /* set read/write flag */ + if (handle->usage & HBM_USE_CPU_WRITE) { + syncFlag.flags |= DMA_BUF_SYNC_WRITE; + } + if (handle->usage & HBM_USE_CPU_READ) { + syncFlag.flags |= DMA_BUF_SYNC_READ; + } + + /* set start/end flag */ + if (isStart) { + syncFlag.flags |= DMA_BUF_SYNC_START; + } else { + syncFlag.flags |= DMA_BUF_SYNC_END; + } + + /* try DMA-BUF ioctl sync */ + int retry = RETRY_TIMES; + int ret; + do { + ret = ioctl(handle->fd, DMA_BUF_IOCTL_SYNC, &syncFlag); + } while ((retry--) && (ret != -EAGAIN) && (ret != -EINTR)); + // error code ref: https://docs.kernel.org/driver-api/dma-buf.html + + if (ret < 0) { + LOG_ERROR("[Gralloc] Failed to sync DMA-BUF"); + return DISPLAY_SYS_BUSY; + } + return DISPLAY_SUCCESS; +} + +int ReopenDrmFd(int drmFd, bool enableRenderNode /*= true*/) +{ + /* Try to open render node */ + char *deviceName = nullptr; + if (enableRenderNode == true) { + deviceName = drmGetRenderDeviceNameFromFd(drmFd); + } + + /* Try to open primary node if previous operation failed */ + if (deviceName == nullptr) { + // Either the DRM device has no render node, either the caller wants + // a primary node + deviceName = drmGetDeviceNameFromFd2(drmFd); + if (deviceName == nullptr) { + LOG_ERROR("[Gralloc] Failed to get device name from DRM fd: %{public}i", drmFd); + return -1; + } + } + + /* Reopen DRM fd */ + int newFd = ::open(deviceName, O_RDWR | O_CLOEXEC); + if (newFd < 0) { + LOG_ERROR("[Gralloc] Failed to reopen DRM node: %{public}s", deviceName); + free(deviceName); + return -1; + } + + LOG_INFO("[Gralloc::GbmUtils::ReopenDrmFd] Reopen new device '%{public}s'(%{public}d) from DRM fd(%{public}d).", + deviceName, newFd, drmFd); + + /* Clear */ + free(deviceName); + + /** + * Auth for new DRM fd permission + * + * If we're using a DRM primary node (e.g. because we're running under the + * to use the legacy DRM authentication mechanism to have the permission to + * manipulate buffers. + */ + if (drmGetNodeTypeFromFd(newFd) == DRM_NODE_PRIMARY) { + drm_magic_t magic; + if (drmGetMagic(newFd, &magic) < 0) { + LOG_ERROR("[Gralloc] Failed to get DRM magic."); + ::close(newFd); + return -1; + } + + if (drmAuthMagic(drmFd, magic) < 0) { + LOG_ERROR("[Gralloc] Failed to auth DRM magic."); + ::close(newFd); + return -1; + } + } + + return newFd; +} +} // namespace GrallocUtils diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h new file mode 100644 index 0000000..be4302c --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "buffer_handle.h" + +#include +#include + +namespace GrallocUtils { + +/** + * @brief Internal func: Get the DRM fd from HdiSession Singleton + * + * @return int DRM fd + */ +int GetDrmFdFromSession(); + +/** + * @brief Internal func: sync DMA-buffer for CPU access. + * + * For more information, please see comment of dma_buf_sync in + * @param handle buffer handle + * @param isStart start or stop of a map access session. + * @return Display ErrCode + */ +int32_t DmaBufferSync(const BufferHandle *handle, bool isStart); + +/** + * @brief Reopen the DRM node. + * + * This function is aim to avoid GEM handle ref'counting issues + * (ref: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/110) + * + * Generally, we'll get /dev/dri/renderD128 after reopen drm_fd /dev/dri/card0. + * @param drmFd + * @param enableRenderNode use render node if true. Otherwise, use primary node. + * @return int new fd + */ +int ReopenDrmFd(int drmFd, bool enableRenderNode = true); + +} // namespace GrallocUtils diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp new file mode 100644 index 0000000..2fb1414 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "dumb_allocator.h" + +// std +#include // mmap +#include +// drm +#include +#include +#include +#include + +#include "display_gralloc_utils.h" +#include "hi_drm_format.h" +#include "display_gralloc.h" +#include "display_type.h" +#include "display_gralloc_private.h" +#include "hdi_session.h" +#include "base/log.h" + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +int32_t DumbAllocator::Init() +{ + // Get DRM fd from HDI Session + int drmFd = GrallocUtils::GetDrmFdFromSession(); + if (IsInvalidFd(drmFd)) { + LOG_ERROR("[Gralloc::DumbAllocator::Init] Failed to get DRM fd from HdiSession!"); + return DISPLAY_FD_ERR; + } + drmFd_ = drmFd; + + // TODO: enable reopen DrmFd + // int newFd = GrallocUtils::ReopenDrmFd(drmFd); + // if (IsInvalidFd(newFd)) { + // LOG_ERROR << "[Gralloc::DumbAllocator::Init] Failed to reopen DRM fd!"; + // return DISPLAY_FD_ERR; + // } + // drmFd_ = newFd; + + return DISPLAY_SUCCESS; +} + +int32_t DumbAllocator::AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) +{ + if (bufferPtr == nullptr) { + LOG_ERROR("[Gralloc::DumbAllocator::AllocMem] Get nullptr param: `buffer`"); + return DISPLAY_PARAM_ERR; + } + + /* Get format info */ + LOG_DEBUG("[Gralloc::DumbAllocator::AllocMem] Get format info"); + uint32_t drmFmt = DrmFormat::ConvertPixelFormatToDrmFormat(info.format); + if (drmFmt == DRM_FORMAT_INVALID) { + LOG_DEBUG("[Gralloc::DumbAllocator::AllocMem] Create dumb buffer"); + } + const DrmFormat::DrmFormatInfo *fmtInfo = DrmFormat::GetDrmFormatInfo(drmFmt); + + { + std::lock_guard lock(mutex_); + + /* DRM RAW: Create dumb buffer */ + LOG_DEBUG("[Gralloc::DumbAllocator::AllocMem] Create dumb buffer"); + struct drm_mode_create_dumb create {}; + create.height = info.height; + create.width = info.width; + create.bpp = fmtInfo->bpp; // bits per pixel + + if (drmIoctl(drmFd_, DRM_IOCTL_MODE_CREATE_DUMB, &create) != 0) { + LOG_ERROR("[Gralloc::DumbAllocator::AllocMem] Failed to create DRM dumb buffer: %{public}s" + , ErrnoToString(errno).c_str()); + return DISPLAY_NOMEM; + } + + /* Convert GEM dumb buffer handle to DMA-BUF prime fd + * + * tips: If DRM doesn't support "DRM_CAP_ADDFB2_MODIFIERS" capability, "drmPrimeHandleToFD()" function will + * cause crash. Thus, we have to check "supportGbmModifiers_" of DrmDevice which represents + * "DRM_CAP_ADDFB2_MODIFIERS" cap support. + */ + int primeFd = -1; + PriBufferHandle *priBuffer = new PriBufferHandle(); + LOG_DEBUG("[Gralloc::DumbAllocator::AllocMem] convert GEM dumb buffer handle to DMA-BUF prime fd"); + if (drmPrimeHandleToFD(drmFd_, create.handle, DRM_CLOEXEC, &primeFd) != 0) { + LOG_WARN("[Gralloc::DumbAllocator::AllocMem] Failed to convert GEM handle %{public}u on DRM %{public}d : %{public}s", + create.handle, drmFd_, ErrnoToString(errno).c_str()); + // return DISPLAY_FD_ERR; // For now, DumbBufferAllocator won't promise fd is available. + } + + /* Set buffer handle rst */ + LOG_DEBUG("[Gralloc::DumbAllocator::AllocMem] set buffer handle rst"); + priBuffer->hdl.fd = primeFd; + priBuffer->hdl.width = create.width; + priBuffer->hdl.stride = create.pitch; + priBuffer->hdl.height = create.height; + priBuffer->hdl.size = create.size; + priBuffer->hdl.format = info.format; + priBuffer->hdl.usage = info.usage; + priBuffer->hdl.virAddr = nullptr; + priBuffer->hdl.key = static_cast(create.handle); // set DMA handle to key + // set to default value + priBuffer->hdl.phyAddr = 0; + priBuffer->hdl.reserveFds = 0; + priBuffer->hdl.reserveInts = 0; + + *bufferPtr = &priBuffer->hdl; + } + + return DISPLAY_SUCCESS; +} + +int32_t DumbAllocator::FreeMem(BufferHandle *buffer) +{ + if (buffer == nullptr) { + LOG_ERROR("Get nullptr param: `buffer`"); + return DISPLAY_PARAM_ERR; + } + + /* Perform memory unmapping if mmap is not clear */ + if ((buffer->virAddr != nullptr) && Unmap(*buffer) != DISPLAY_SUCCESS) { + LOG_ERROR("[Gralloc::DumbAllocator::FreeMem] Failed to unmap buffer"); + } + + /* Close Dumb buffer fds & handle*/ + // close current Dumb buffer fd + if (buffer->fd >= 0) { + ::close(buffer->fd); + buffer->fd = -1; + } + // close reserved Dumb buffer fd + const uint32_t reserveFds = buffer->reserveFds; + for (uint32_t i = 0; i < reserveFds; i++) { + if (buffer->reserve[i] >= 0) { + close(buffer->reserve[i]); + buffer->reserve[i] = -1; + } + } + // close current Dumb buffer handle + DestroyGemDumbHandle(static_cast(buffer->key)); + + /* Free BufferHandle */ + delete buffer; + + return DISPLAY_SUCCESS; +} + +void *DumbAllocator::Mmap(BufferHandle &buffer) +{ + if (buffer.virAddr != nullptr) { + LOG_ERROR("Get err param: buffer.virAddr is not null"); + return nullptr; + } + + /** + * Get GEM Dumb buffer handle. + * + * tips: In some case, "drmPrimeHandleToFD()" function will cause crash. When converion failed, we will directly + * use handle in BufferHandle.key. This behavior might cause "MAP DUMB" failed when the buffer handle is + * passed across processes. + */ + uint32_t handle; + LOG_DEBUG("[Gralloc::DumbAllocator::Mmap] Try DMA-BUF prime fd to GEM dumb buffer handle"); + if (drmPrimeFDToHandle(drmFd_, buffer.fd, &handle) != 0) { + LOG_WARN("[Gralloc::DumbAllocator::Mmap] Failed to convert DMA-BUF prime fd: %{public}i", buffer.fd); + handle = buffer.key; + } + + /* Prepare buffer for mmap */ + LOG_DEBUG("[Gralloc::DumbAllocator::Mmap] prepare buffer for mmap"); + struct drm_mode_map_dumb map {}; + map.handle = handle; + if (drmIoctl(drmFd_, DRM_IOCTL_MODE_MAP_DUMB, &map) != 0) { + LOG_ERROR("[Gralloc::DumbAllocator::Mmap] Failed to map DRM dumb buffer: %{public}s", ErrnoToString(errno).c_str()); + return nullptr; + } + + /* Perform memory mapping */ + LOG_DEBUG("[Gralloc::DumbAllocator::Mmap] perform memory mapping"); + void *newVirAddr = + mmap(static_cast(0), buffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, drmFd_, map.offset); + if (newVirAddr == MAP_FAILED) { + LOG_ERROR("[Gralloc::DumbAllocator::Mmap] Failed to map buffer on DRM fd(%{public}d): %{public}s", + drmFd_, ErrnoToString(errno).c_str()); + return nullptr; + } + + /* Set new map to buffer struct */ + LOG_DEBUG("[Gralloc::DumbAllocator::Mmap] set new map to buffer struct"); + buffer.virAddr = newVirAddr; + + return newVirAddr; +} + +int32_t DumbAllocator::Unmap(BufferHandle &buffer) +{ + if (buffer.virAddr == nullptr) { + LOG_ERROR("[Gralloc::DumbAllocator::Mmap] Get null buffer.virAddr"); + return DISPLAY_NULL_PTR; + } + + if (buffer.size < 0) { + LOG_ERROR("[Gralloc::DumbAllocator::Mmap] Get st0 buffer.size"); + return DISPLAY_PARAM_ERR; + } + + if (munmap(buffer.virAddr, buffer.size) != 0) { + LOG_ERROR("[Gralloc::DumbAllocator::Mmap] Failed to do munmap(): %{public}s", ErrnoToString(errno).c_str()); + return DISPLAY_FAILURE; + } + buffer.virAddr = nullptr; + + return DISPLAY_SUCCESS; +} + +int32_t DumbAllocator::FlushCache(BufferHandle &buffer) +{ + // TODO: FlushCache is not supported yet. + // return GrallocUtils::DmaBufferSync(&buffer, false); + UNUSED(buffer); + return DISPLAY_SUCCESS; +} + +int32_t DumbAllocator::InvalidateCache(BufferHandle &buffer) +{ + // TODO: FlushCache is not supported yet. + // return GrallocUtils::DmaBufferSync(&buffer, true); + UNUSED(buffer); + return DISPLAY_SUCCESS; +} + +int32_t DumbAllocator::DestroyGemDumbHandle(unsigned int handle) +{ + struct drm_mode_destroy_dumb destroy = {.handle = handle}; + if (drmIoctl(drmFd_, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy) != 0) { + LOG_WARN("[Gralloc::DumbAllocator::DestroyGemDumbHandle] Failed to destory GEM handle: %{public}u", handle); + return DISPLAY_FAILURE; + } + + return DISPLAY_SUCCESS; +} + +bool DumbAllocator::GetSupportGbmModifyFromSession() +{ + auto &session = oewm::HDI::DISPLAY::HdiSession::GetInstance(); + const std::shared_ptr device = session.GetDisplayDevice(); + if (device == nullptr) { + LOG_ERROR("[Gralloc::DumbAllocator::DestroyGemDumbHandle] Get empty DRM device from HdiSession."); + return false; + } + return device->SupportGbmModifiers(); +} +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h new file mode 100644 index 0000000..af36a1a --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "allocator.h" + +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +class DumbAllocator : public Allocator { +public: + DumbAllocator() = default; + ~DumbAllocator() noexcept = default; + + virtual int32_t Init() override; + + virtual int32_t AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) override; + virtual int32_t FreeMem(BufferHandle *buffer) override; + virtual void *Mmap(BufferHandle &buffer) override; + virtual int32_t Unmap(BufferHandle &buffer) override; + virtual int32_t FlushCache(BufferHandle &buffer) override; + virtual int32_t InvalidateCache(BufferHandle &buffer) override; + +private: + int32_t DestroyGemDumbHandle(unsigned int handle); + bool GetSupportGbmModifyFromSession(); + +private: + std::mutex mutex_; + int drmFd_ = -1; +}; + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp new file mode 100644 index 0000000..cbffff7 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "gbm_allocator.h" + +#include "display_gralloc_utils.h" +#include "display_gralloc_private.h" +#include "hi_gbm_format.h" +#include "display_type.h" +#include "buffer_handle.h" +#include "base/log.h" +#include "base/types.h" + +#include +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { +GbmAllocator::~GbmAllocator() noexcept +{ + if (gbmContext_ != nullptr) { + gbm_device_destroy(gbmContext_); + gbmContext_ = nullptr; + } +} + +int32_t GbmAllocator::Init() +{ + LOG_DEBUG("[Gralloc::GbmAllocator::Init] Initing..."); + + /* Get DRM fd */ + int drmFd = GrallocUtils::GetDrmFdFromSession(); + if (IsInvalidFd(drmFd)) { + LOG_ERROR("[Gralloc::GbmAllocator::Init] Failed to get DRM fd from HdiSession"); + return DISPLAY_FAILURE; + } + + // TODO: reopen DRM fd + + /* create gbm device */ + gbmContext_ = gbm_create_device(drmFd); + if (gbmContext_ == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::Init] Failed to create gbm device: %{public}s", ErrnoToString(errno).c_str()); + return DISPLAY_FAILURE; + } + + LOG_INFO("[Gralloc::GbmAllocator::Init] Created GBM device with backend: %{public}s", + gbm_device_get_backend_name(gbmContext_)); + char *drmName = drmGetDeviceNameFromFd2(drmFd); + LOG_INFO("[Gralloc::GbmAllocator::Init] Using DRM node: %{public}s", drmName); + free(drmName); + + LOG_DEBUG("[Gralloc::GbmAllocator::Init] Init done."); + + return DISPLAY_SUCCESS; +} + +int32_t GbmAllocator::AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::AllocMem] Alloc Mem."); + + if (bufferPtr == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::AllocMem] Get nullptr param: `buffer`"); + return DISPLAY_PARAM_ERR; + } + + // TODO: support multi format. + // /* Get format info */ + // LOG_DEBUG << "[Gralloc::GbmAllocator::AllocMem] Get format info"; + // uint32_t gbmFmt = GbmFormat::ConvertPixelFormatToGbmFormat(info.format); + + /* Decide flag depending on buffer usage */ + uint32_t gbmFlag = 0; + if (info.usage & HBM_USE_MEM_FB) { + gbmFlag |= GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT; + } + + // On some vm, it might failed to create GBM BO while allocating memory. In this case, we choose to create + // Dumb buffer by `GBM_BO_USE_WRITE` flag. + if (AllocMemWithUsage(info, bufferPtr, gbmFlag) != DISPLAY_SUCCESS) { + LOG_WARN("[Gralloc::GbmAllocator::AllocMem] Gbm GL buffer allocation failed! Try to allocate dumb."); + // Buffer can be used for gbm_bo_write. This is guaranteed to work + // with GBM_BO_USE_CURSOR, but may not work for other combinations. + // **This will create Dumb Buffer!** + gbmFlag |= GBM_BO_USE_WRITE; + + if (AllocMemWithUsage(info, bufferPtr, gbmFlag) != DISPLAY_SUCCESS) { + LOG_ERROR("[Gralloc::GbmAllocator::AllocMem] Gbm Dumb buffer allocation failed!"); + return DISPLAY_FAILURE; + } + } + + LOG_DEBUG("[Gralloc::GbmAllocator::AllocMem] Alloc Mem done."); + + return DISPLAY_SUCCESS; +} + +int32_t GbmAllocator::FreeMem(BufferHandle *buffer) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::FreeMem] Free Mem."); + + if (buffer == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::FreeMem] Get nullptr param: `buffer`"); + return DISPLAY_NULL_PTR; + } + + /* perform memory unmapping if mmap is not clear */ + if ((buffer->virAddr != nullptr) && Unmap(*buffer) != DISPLAY_SUCCESS) { + LOG_WARN("[Gralloc::GbmAllocator::FreeMem] Failed to unmap buffer."); + } + + /* close DMA-BUF fds*/ + // close current DMABUF fd + if (buffer->fd >= 0) { + ::close(buffer->fd); + buffer->fd = -1; + } + // close reserved DMABUF fd + const uint32_t reserveFds = buffer->reserveFds; + for (uint32_t i = 0; i < reserveFds; i++) { + if (buffer->reserve[i] >= 0) { + ::close(buffer->reserve[i]); + buffer->reserve[i] = -1; + } + } + + /* destroy gbm bo */ + int handle = buffer->key; + if (DestroyGbmBo(handle) == false) { + LOG_WARN("[Gralloc::GbmAllocator::FreeMem] Failed to destroy gbm bo."); + } + + /* free buffer handle */ + delete buffer; + + LOG_DEBUG("[Gralloc::GbmAllocator::FreeMem] Free Mem done."); + + return DISPLAY_SUCCESS; +} + +void *GbmAllocator::Mmap(BufferHandle &buffer) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::Mmap] Mmap."); + + auto handle = static_cast(buffer.key); + auto gbmBo = GetGbmBo(handle); + if (gbmBo == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::Mmap] Get null gbmBo of this buffer!"); + return nullptr; + } + + if (buffer.virAddr != nullptr) { + LOG_WARN("[Gralloc::GbmAllocator::Mmap] `buffer.virAddr` is not null!"); + return buffer.virAddr; + } + + // Decide mmap flags + uint32_t transferFlags = 0; + if (buffer.usage & HBM_USE_CPU_READ) { + // Buffer contents read back (or accessed directly) at transfer create time. + transferFlags |= GBM_BO_TRANSFER_READ; + } + if (buffer.usage & HBM_USE_CPU_WRITE) { + // Buffer contents will be written back at unmap time (or modified as a result of being accessed directly). + transferFlags |= GBM_BO_TRANSFER_WRITE; + } + + // Check if current GBM buffer has impl `GBM_BO_USE_WRITE` flag. + if (transferFlags == 0) { + LOG_ERROR("[Gralloc::GbmAllocator::Mmap] GBM buffer without GBM_BO_USE_WRITE cannot be mmaped!"); + return nullptr; + } + + uint32_t outStride = 0; + void *mapData = nullptr; + void *virAddr = gbm_bo_map( + gbmBo, + 0, + 0, + buffer.width, + buffer.height, + transferFlags, + &outStride, + &mapData); // map_data & return address is the same + + buffer.virAddr = virAddr; + LOG_DEBUG("[Gralloc::GbmAllocator::Mmap] Mmap done."); + return virAddr; +} + +int32_t GbmAllocator::Unmap(BufferHandle &buffer) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::Unmap] Unmap."); + + if (buffer.virAddr == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::Unmap] Get null buffer.virAddr!"); + return DISPLAY_NULL_PTR; + } + + if (buffer.size < 0) { + LOG_ERROR("[Gralloc::GbmAllocator::Unmap] Get st0 buffer.size!"); + return DISPLAY_PARAM_ERR; + } + + auto handle = static_cast(buffer.key); + auto gbmBo = GetGbmBo(handle); + if (gbmBo == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::Unmap] Get null gbmBo of this buffer!"); + return DISPLAY_NULL_PTR; + } + + gbm_bo_unmap(gbmBo, buffer.virAddr); + buffer.virAddr = nullptr; + + LOG_DEBUG("[Gralloc::GbmAllocator::Unmap] Unmap done."); + + return DISPLAY_SUCCESS; +} + +int32_t GbmAllocator::FlushCache(BufferHandle &buffer) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::FlushCache] Flush Cache."); + + // TODO: FlushCache is not supported yet. + UNUSED(buffer); + + LOG_DEBUG("[Gralloc::GbmAllocator::FlushCache] Flush Cache done."); + return DISPLAY_SUCCESS; +} + +int32_t GbmAllocator::InvalidateCache(BufferHandle &buffer) +{ + LOG_DEBUG("[Gralloc::GbmAllocator::InvalidateCache] Invalidate Cache."); + + // TODO: InvalidateCache is not supported yet. + UNUSED(buffer); + + LOG_DEBUG("[Gralloc::GbmAllocator::InvalidateCache] Invalidate Cache done."); + + return DISPLAY_SUCCESS; +} + +bool GbmAllocator::AddGbmBo(int32_t handle, struct gbm_bo *gbmBo) +{ + std::lock_guard lock(mutex_); + if (boMap_.count(handle) != 0) { + return false; + } + + boMap_.insert({handle, gbmBo}); + return true; +} + +struct gbm_bo *GbmAllocator::GetGbmBo(int32_t handle) +{ + std::lock_guard lock(mutex_); + if (boMap_.count(handle) == 0) { + return nullptr; + } + + return boMap_.at(handle); +} + +bool GbmAllocator::DestroyGbmBo(int32_t handle) +{ + std::lock_guard lock(mutex_); + if (boMap_.count(handle) == 0) { + return false; + } + + auto gbmBo = boMap_.at(handle); + boMap_.erase(handle); + if (gbmBo != nullptr) { + gbm_bo_destroy(gbmBo); + } + + return true; +} + +int32_t GbmAllocator::AllocMemWithUsage(const AllocInfo &info, BufferHandle **bufferPtr, uint32_t usage) +{ + /* CORE: gbm bo */ + // TODO: create with modifiers + LOG_DEBUG("[Gralloc::GbmAllocator::AllocMemWithUsage] create GBM buffer object."); + struct gbm_bo *gbmBo = gbm_bo_create( + gbmContext_, + info.width, + info.height, + GBM_FORMAT_XRGB8888, // Q: Why Must be GBM_FORMAT_XRGB8888? + usage); + if (gbmBo == nullptr) { + LOG_ERROR("[Gralloc::GbmAllocator::AllocMemWithUsage] Failed to create GBM buffer object."); + return DISPLAY_FAILURE; + } + + /* Set buffer handle rst */ + LOG_DEBUG("[Gralloc::GbmAllocator::AllocMemWithUsage] Set buffer handle rst"); + PriBufferHandle *priBuffer = new PriBufferHandle(); + auto boHandle = static_cast(gbm_bo_get_handle(gbmBo).u32); + + priBuffer->hdl.fd = gbm_bo_get_fd(gbmBo); // TODO: use planes' fd + if (priBuffer->hdl.fd < 0) { + LOG_WARN("[Gralloc::GbmAllocator::AllocMemWithUsage] Failed to get fd from gbm bo."); + // return DISPLAY_FAILURE; + } + priBuffer->hdl.stride = gbm_bo_get_stride(gbmBo); + priBuffer->hdl.width = info.width; + priBuffer->hdl.height = info.height; + priBuffer->hdl.usage = info.usage; + priBuffer->hdl.format = info.format; + priBuffer->hdl.virAddr = nullptr; + priBuffer->hdl.size = priBuffer->hdl.stride * priBuffer->hdl.height; + priBuffer->hdl.key = boHandle; + // set to default value + priBuffer->hdl.phyAddr = 0; + priBuffer->hdl.reserveFds = 0; + priBuffer->hdl.reserveInts = 0; + + *bufferPtr = &priBuffer->hdl; + + AddGbmBo(boHandle, gbmBo); + + return DISPLAY_SUCCESS; +} +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h new file mode 100644 index 0000000..3db681e --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "allocator.h" + +#include +#include +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +class GbmAllocator : public Allocator { +public: + GbmAllocator() = default; + ~GbmAllocator() noexcept override; + + virtual int32_t Init() override; + + virtual int32_t AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) override; + virtual int32_t FreeMem(BufferHandle *buffer) override; + virtual void *Mmap(BufferHandle &buffer) override; + virtual int32_t Unmap(BufferHandle &buffer) override; + virtual int32_t FlushCache(BufferHandle &buffer) override; + virtual int32_t InvalidateCache(BufferHandle &buffer) override; + +private: + bool AddGbmBo(int32_t handle, struct gbm_bo *gbmBo); + struct gbm_bo *GetGbmBo(int32_t handle); + bool DestroyGbmBo(int32_t handle); + + int32_t AllocMemWithUsage(const AllocInfo &info, BufferHandle **bufferPtr, uint32_t usage); + +private: + std::mutex mutex_; + + struct gbm_device *gbmContext_ = nullptr; + std::unordered_map boMap_; // handle -> gbm bo +}; +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp new file mode 100644 index 0000000..f95c9ad --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "hi_drm_format.h" + +#include +#include + +namespace DrmFormat { +/* Format Convert */ +struct DrmFormatConvertTbl { + uint32_t drmFormat; + PixelFormat pixFormat; +}; + +struct ValueStrMap { + uint32_t value; + const char *str; +}; + +const char *GetHdiPixelFmtStr(PixelFormat format) +{ + static const ValueStrMap pixelStrMaps[] = { + {PIXEL_FMT_CLUT8, "PIXEL_FMT_CLUT8"}, + {PIXEL_FMT_CLUT1, "PIXEL_FMT_CLUT1"}, + {PIXEL_FMT_CLUT4, "PIXEL_FMT_CLUT4"}, + {PIXEL_FMT_RGB_565, "PIXEL_FMT_RGB_565"}, + {PIXEL_FMT_RGBA_5658, "IXEL_FMT_RGBA_5658"}, + {PIXEL_FMT_RGBX_4444, "PIXEL_FMT_RGBX_4444"}, + {PIXEL_FMT_RGBA_4444, "PIXEL_FMT_RGBA_4444"}, + {PIXEL_FMT_RGB_444, "PIXEL_FMT_RGB_444"}, + {PIXEL_FMT_RGBX_5551, "PIXEL_FMT_RGBX_5551"}, + {PIXEL_FMT_RGBA_5551, "PIXEL_FMT_RGBA_5551"}, + {PIXEL_FMT_RGB_555, "PIXEL_FMT_RGB_555"}, + {PIXEL_FMT_RGBX_8888, "PIXEL_FMT_RGBX_8888"}, + {PIXEL_FMT_RGBA_8888, "PIXEL_FMT_RGBA_8888"}, + {PIXEL_FMT_RGB_888, "PIXEL_FMT_RGB_888"}, + {PIXEL_FMT_BGR_565, "PIXEL_FMT_BGR_565"}, + {PIXEL_FMT_BGRX_4444, "PIXEL_FMT_BGRX_4444"}, + {PIXEL_FMT_BGRA_4444, "PIXEL_FMT_BGRA_4444"}, + {PIXEL_FMT_BGRX_5551, "PIXEL_FMT_BGRX_5551"}, + {PIXEL_FMT_BGRA_5551, "PIXEL_FMT_BGRA_5551"}, + {PIXEL_FMT_BGRX_8888, "PIXEL_FMT_BGRX_8888"}, + {PIXEL_FMT_BGRA_8888, "PIXEL_FMT_BGRA_8888"}, + // {PIXEL_FMT_ARGB_8888, "PIXEL_FMT_ARGB_8888"}, + {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, + {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, + {PIXEL_FMT_YCBCR_422_SP, "PIXEL_FMT_YCBCR_422_SP"}, + {PIXEL_FMT_YCRCB_422_SP, "PIXEL_FMT_YCRCB_422_SP"}, + {PIXEL_FMT_YCBCR_420_SP, "PIXEL_FMT_YCBCR_420_SP"}, + {PIXEL_FMT_YCRCB_420_SP, "PIXEL_FMT_YCRCB_420_SP"}, + {PIXEL_FMT_YCBCR_422_P, "PIXEL_FMT_YCBCR_422_P"}, + {PIXEL_FMT_YCRCB_422_P, "PIXEL_FMT_YCRCB_422_P"}, + {PIXEL_FMT_YCBCR_420_P, "PIXEL_FMT_YCBCR_420_P"}, + {PIXEL_FMT_YCRCB_420_P, "PIXEL_FMT_YCRCB_420_P"}, + {PIXEL_FMT_YUYV_422_PKG, "PIXEL_FMT_YUYV_422_PKG"}, + {PIXEL_FMT_UYVY_422_PKG, "PIXEL_FMT_UYVY_422_PKG"}, + {PIXEL_FMT_YVYU_422_PKG, "PIXEL_FMT_YVYU_422_PKG"}, + {PIXEL_FMT_VYUY_422_PKG, "PIXEL_FMT_VYUY_422_PKG"}, + {PIXEL_FMT_BUTT, "PIXEL_FMT_BUTT"}, + }; + static const char *unknown = "unknown format"; + for (uint32_t i = 0; i < sizeof(pixelStrMaps) / sizeof(pixelStrMaps[0]); i++) { + if (pixelStrMaps[i].value == format) { + return pixelStrMaps[i].str; + } + } + LOG_WARN("GetHdiPixelFmtStr unknown format: %{public}u", format); + return unknown; +} + +const char *GetDrmFmtStr(uint32_t format) +{ + static const ValueStrMap formatStrMaps[] = { + {DRM_FORMAT_C8, "DRM_FORMAT_C8"}, + {DRM_FORMAT_R8, "DRM_FORMAT_R8"}, + {DRM_FORMAT_R16, "DRM_FORMAT_R16"}, + {DRM_FORMAT_RG88, "DRM_FORMAT_RG88"}, + {DRM_FORMAT_GR88, "DRM_FORMAT_GR88"}, + {DRM_FORMAT_RG1616, "DRM_FORMAT_RG1616"}, + {DRM_FORMAT_GR1616, "DRM_FORMAT_GR1616"}, + {DRM_FORMAT_RGB332, "DRM_FORMAT_RGB332"}, + {DRM_FORMAT_BGR233, "DRM_FORMAT_BGR233"}, + {DRM_FORMAT_XRGB4444, "DRM_FORMAT_XRGB4444"}, + {DRM_FORMAT_XBGR4444, "DRM_FORMAT_XBGR4444"}, + {DRM_FORMAT_RGBX4444, "DRM_FORMAT_RGBX4444"}, + {DRM_FORMAT_BGRX4444, "DRM_FORMAT_BGRX4444"}, + {DRM_FORMAT_ARGB4444, "DRM_FORMAT_ARGB4444"}, + {DRM_FORMAT_ABGR4444, "DRM_FORMAT_ABGR4444"}, + {DRM_FORMAT_RGBA4444, "DRM_FORMAT_RGBA4444"}, + {DRM_FORMAT_BGRA4444, "DRM_FORMAT_BGRA4444"}, + {DRM_FORMAT_XRGB1555, "DRM_FORMAT_XRGB1555"}, + {DRM_FORMAT_XBGR1555, "DRM_FORMAT_XBGR1555"}, + {DRM_FORMAT_RGBX5551, "DRM_FORMAT_RGBX5551"}, + {DRM_FORMAT_BGRX5551, "DRM_FORMAT_BGRX5551"}, + {DRM_FORMAT_ARGB1555, "DRM_FORMAT_ARGB1555"}, + {DRM_FORMAT_ABGR1555, "DRM_FORMAT_ABGR1555"}, + {DRM_FORMAT_RGBA5551, "DRM_FORMAT_RGBA5551"}, + {DRM_FORMAT_BGRA5551, "DRM_FORMAT_BGRA5551"}, + {DRM_FORMAT_RGB565, "DRM_FORMAT_RGB565"}, + {DRM_FORMAT_BGR565, "DRM_FORMAT_BGR565"}, + {DRM_FORMAT_RGB888, "DRM_FORMAT_RGB888"}, + {DRM_FORMAT_BGR888, "DRM_FORMAT_BGR888"}, + {DRM_FORMAT_XRGB8888, "DRM_FORMAT_XRGB8888"}, + {DRM_FORMAT_XBGR8888, "DRM_FORMAT_XBGR8888"}, + {DRM_FORMAT_RGBX8888, "DRM_FORMAT_RGBX8888"}, + {DRM_FORMAT_BGRX8888, "DRM_FORMAT_BGRX8888"}, + {DRM_FORMAT_ARGB8888, "DRM_FORMAT_ARGB8888"}, + {DRM_FORMAT_ABGR8888, "DRM_FORMAT_ABGR8888"}, + {DRM_FORMAT_RGBA8888, "DRM_FORMAT_RGBA8888"}, + {DRM_FORMAT_BGRA8888, "DRM_FORMAT_BGRA8888"}, + {DRM_FORMAT_XRGB2101010, "DRM_FORMAT_XRGB2101010"}, + {DRM_FORMAT_BGRX1010102, "DRM_FORMAT_BGRX1010102"}, + {DRM_FORMAT_ARGB2101010, "DRM_FORMAT_ARGB2101010"}, + {DRM_FORMAT_ABGR2101010, "DRM_FORMAT_ABGR2101010"}, + {DRM_FORMAT_RGBA1010102, "DRM_FORMAT_RGBA1010102"}, + {DRM_FORMAT_YVYU, "DRM_FORMAT_YVYU"}, + {DRM_FORMAT_UYVY, "DRM_FORMAT_UYVY"}, + {DRM_FORMAT_VYUY, "DRM_FORMAT_VYUY"}, + {DRM_FORMAT_AYUV, "DRM_FORMAT_AYUV"}, + {DRM_FORMAT_NV12, "DRM_FORMAT_NV12"}, + {DRM_FORMAT_NV21, "DRM_FORMAT_NV21"}, + {DRM_FORMAT_NV16, "DRM_FORMAT_NV16"}, + {DRM_FORMAT_NV61, "DRM_FORMAT_NV61"}, + {DRM_FORMAT_NV24, "DRM_FORMAT_NV24"}, + {DRM_FORMAT_NV42, "DRM_FORMAT_NV42"}, + {DRM_FORMAT_YUV410, "DRM_FORMAT_YUV410"}, + {DRM_FORMAT_YVU410, "DRM_FORMAT_YVU410"}, + {DRM_FORMAT_YUV411, "DRM_FORMAT_YUV411"}, + {DRM_FORMAT_YVU411, "DRM_FORMAT_YVU411"}, + {DRM_FORMAT_YUV420, "DRM_FORMAT_YUV420"}, + {DRM_FORMAT_YVU420, "DRM_FORMAT_YVU420"}, + {DRM_FORMAT_YUV422, "DRM_FORMAT_YUV422"}, + {DRM_FORMAT_YVU422, "DRM_FORMAT_YVU422"}, + {DRM_FORMAT_YUV444, "DRM_FORMAT_YUV444"}, + {DRM_FORMAT_YVU444, "DRM_FORMAT_YVU444"}, + }; + + static const char *unknown = "unknown drm format"; + for (uint32_t i = 0; i < sizeof(formatStrMaps) / sizeof(formatStrMaps[0]); i++) { + if (formatStrMaps[i].value == format) { + return formatStrMaps[i].str; + } + } + LOG_WARN("GetDrmFmtStr unknown format: %{public}u", format); + return unknown; +} + +static const DrmFormatConvertTbl convertTable[] = { + {DRM_FORMAT_RGBX8888, PIXEL_FMT_RGBX_8888}, {DRM_FORMAT_RGBA8888, PIXEL_FMT_RGBA_8888}, + {DRM_FORMAT_RGB888, PIXEL_FMT_RGB_888}, {DRM_FORMAT_RGB565, PIXEL_FMT_BGR_565}, + {DRM_FORMAT_BGRX4444, PIXEL_FMT_BGRX_4444}, {DRM_FORMAT_BGRA4444, PIXEL_FMT_BGRA_4444}, + {DRM_FORMAT_RGBA4444, PIXEL_FMT_RGBA_4444}, {DRM_FORMAT_RGBX4444, PIXEL_FMT_RGBX_4444}, + {DRM_FORMAT_BGRX5551, PIXEL_FMT_BGRX_5551}, {DRM_FORMAT_BGRA5551, PIXEL_FMT_BGRA_5551}, + {DRM_FORMAT_BGRX8888, PIXEL_FMT_BGRX_8888}, {DRM_FORMAT_BGRA8888, PIXEL_FMT_BGRA_8888}, + {DRM_FORMAT_NV12, PIXEL_FMT_YCBCR_420_SP}, {DRM_FORMAT_NV21, PIXEL_FMT_YCRCB_420_SP}, + {DRM_FORMAT_YUV420, PIXEL_FMT_YCBCR_420_P}, {DRM_FORMAT_YVU420, PIXEL_FMT_YCRCB_420_P}, + {DRM_FORMAT_NV16, PIXEL_FMT_YCBCR_422_SP}, {DRM_FORMAT_NV61, PIXEL_FMT_YCRCB_422_SP}, + {DRM_FORMAT_YUV422, PIXEL_FMT_YCBCR_422_P}, {DRM_FORMAT_YVU422, PIXEL_FMT_YCRCB_422_P}, + // {DRM_FORMAT_ARGB8888, PIXEL_FMT_ARGB_8888}, +}; + +uint32_t ConvertPixelFormatToDrmFormat(PixelFormat fmtIn) +{ + uint32_t fmtOut = DRM_FORMAT_INVALID; + for (uint32_t i = 0; i < sizeof(convertTable) / sizeof(convertTable[0]); i++) { + if (convertTable[i].pixFormat == fmtIn) { + fmtOut = convertTable[i].drmFormat; + break; + } + } + // LOG_DEBUG << "Convert pixelFormat(" << fmtIn << " : " << GetHdiPixelFmtStr(fmtIn) << ") to DrmFormat(" << fmtOut + // << " : " << GetDrmFmtStr(fmtOut) << ")"; + // LOG_DEBUG << oewm::Fmt( + // "Convert PixelFormat(%u:%s) to DrmFormat(%u:%s)", + // oewm::ECast(fmtIn), + // GetHdiPixelFmtStr(fmtIn), + // fmtOut, + // GetDrmFmtStr(fmtOut)); + return fmtOut; +} + +PixelFormat ConvertDrmFormatToPixelFormat(uint32_t fmtIn) +{ + PixelFormat fmtOut = PIXEL_FMT_BUTT; + for (uint32_t i = 0; i < sizeof(convertTable) / sizeof(convertTable[0]); i++) { + if (convertTable[i].drmFormat == fmtIn) { + fmtOut = convertTable[i].pixFormat; + break; + } + } + // LOG_DEBUG << oewm::Fmt( + // "Convert DrmFormat(%u:%s) to PixelFormat(%u:%s)", + // fmtIn, + // GetDrmFmtStr(fmtIn), + // oewm::ECast(fmtOut), + // GetHdiPixelFmtStr(fmtOut)); + return fmtOut; +} + +/* Format Info */ + +static const PlaneLayoutInfo g_yuv420SPLayout = { + .numPlanes = 2, + .radio = {4, 2}, +}; + +static const PlaneLayoutInfo g_yuv420PLayout = { + .numPlanes = 3, + .radio = {4, 1, 1}, +}; + +static const PlaneLayoutInfo g_yuv422SPLayout = { + .numPlanes = 2, + .radio = {4, 4}, +}; + +static const PlaneLayoutInfo g_yuv422PLayout = { + .numPlanes = 3, + .radio = {4, 2, 2}, +}; + +static const DrmFormatInfo fmtInfos[] = { + {DRM_FORMAT_RGBX8888, 32, nullptr}, {DRM_FORMAT_RGBA8888, 32, nullptr}, + {DRM_FORMAT_BGRX8888, 32, nullptr}, {DRM_FORMAT_BGRA8888, 32, nullptr}, + {DRM_FORMAT_RGB888, 24, nullptr}, {DRM_FORMAT_RGB565, 16, nullptr}, + {DRM_FORMAT_BGRX4444, 16, nullptr}, {DRM_FORMAT_BGRA4444, 16, nullptr}, + {DRM_FORMAT_RGBA4444, 16, nullptr}, {DRM_FORMAT_RGBX4444, 16, nullptr}, + {DRM_FORMAT_BGRX5551, 16, nullptr}, {DRM_FORMAT_BGRA5551, 16, nullptr}, + {DRM_FORMAT_NV12, 8, &g_yuv420SPLayout}, {DRM_FORMAT_NV21, 8, &g_yuv420SPLayout}, + {DRM_FORMAT_NV16, 8, &g_yuv422SPLayout}, {DRM_FORMAT_NV61, 8, &g_yuv422SPLayout}, + {DRM_FORMAT_YUV420, 8, &g_yuv420PLayout}, {DRM_FORMAT_YVU420, 8, &g_yuv420PLayout}, + {DRM_FORMAT_YUV422, 8, &g_yuv422PLayout}, {DRM_FORMAT_YVU422, 8, &g_yuv422PLayout}, +}; + +const DrmFormatInfo *GetDrmFormatInfo(uint32_t format) +{ + constexpr size_t fmtInfosSize = sizeof(fmtInfos) / sizeof(DrmFormatInfo); + + for (uint32_t i = 0; i < fmtInfosSize; i++) { + if (fmtInfos[i].format == format) { + return &fmtInfos[i]; + } + } + LOG_WARN("Failed to find format: %{public}u", format); + return nullptr; +} +} // namespace DrmFormat diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h new file mode 100644 index 0000000..8fdf3af --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "display_type.h" +#include "base/log.h" + +#include + +namespace DrmFormat { +#define DRM_MAX_PLANES 3 + +struct PlaneLayoutInfo { + uint32_t numPlanes; + uint32_t radio[DRM_MAX_PLANES]; +}; + +struct DrmFormatInfo { + uint32_t format; + uint32_t bpp; // bits per pixel for first plane + const PlaneLayoutInfo *planes; +}; + +const DrmFormatInfo *GetDrmFormatInfo(uint32_t format); +const char *GetDrmFmtStr(uint32_t format); +const char *GetHdiPixelFmtStr(PixelFormat format); +uint32_t ConvertPixelFormatToDrmFormat(PixelFormat fmtIn); +PixelFormat ConvertDrmFormatToPixelFormat(uint32_t fmtIn); +} // namespace DrmFormat diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp new file mode 100644 index 0000000..7c785e0 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "hi_gbm_format.h" + +#include "hi_drm_format.h" +#include "gbm.h" + +namespace GbmFormat { + +struct PixelFormatConvertTbl { + uint32_t drmFormat; + PixelFormat pixFormat; +}; + +struct ValueStrMap { + uint32_t value; + const char *str; +}; + +const char *GetDrmFmtStr(uint32_t format) +{ + static const ValueStrMap formatStrMaps[] = { + {GBM_FORMAT_RGBX8888, "GBM_FORMAT_RGBX8888"}, {GBM_FORMAT_RGBA8888, "GBM_FORMAT_RGBA8888"}, + {GBM_FORMAT_RGB888, "GBM_FORMAT_RGB888"}, {GBM_FORMAT_BGR565, "GBM_FORMAT_BGR565"}, + {GBM_FORMAT_BGRX4444, "GBM_FORMAT_BGRX4444"}, {GBM_FORMAT_BGRA4444, "GBM_FORMAT_BGRA4444"}, + {GBM_FORMAT_RGBA4444, "GBM_FORMAT_RGBA4444"}, {GBM_FORMAT_RGBX4444, "GBM_FORMAT_RGBX4444"}, + {GBM_FORMAT_BGRX5551, "GBM_FORMAT_BGRX5551"}, {GBM_FORMAT_BGRA5551, "GBM_FORMAT_BGRA5551"}, + {GBM_FORMAT_BGRX8888, "GBM_FORMAT_BGRX8888"}, {GBM_FORMAT_BGRA8888, "GBM_FORMAT_BGRA8888"}, + {GBM_FORMAT_NV12, "GBM_FORMAT_NV12"}, {GBM_FORMAT_NV21, "GBM_FORMAT_NV21"}, + {GBM_FORMAT_YUV420, "GBM_FORMAT_YUV420"}, {GBM_FORMAT_YVU420, "GBM_FORMAT_YVU420"}, + {GBM_FORMAT_NV16, "GBM_FORMAT_NV16"}, {GBM_FORMAT_NV61, "GBM_FORMAT_NV61"}, + {GBM_FORMAT_YUV422, "GBM_FORMAT_YUV422"}, {GBM_FORMAT_YVU422, "GBM_FORMAT_YVU422"}, + }; + + for (uint32_t i = 0; i < sizeof(formatStrMaps) / sizeof(formatStrMaps[0]); i++) { + if (formatStrMaps[i].value == format) { + return formatStrMaps[i].str; + } + } + LOG_WARN("GetGbmFmtStr unknown format: %{public}u", format); + return "unknown gbm format"; +} + +uint32_t ConvertPixelFormatToGbmFormat(PixelFormat fmtIn) +{ + static const PixelFormatConvertTbl convertTable[] = { + {GBM_FORMAT_RGBX8888, PIXEL_FMT_RGBX_8888}, {GBM_FORMAT_RGBA8888, PIXEL_FMT_RGBA_8888}, + {GBM_FORMAT_RGB888, PIXEL_FMT_RGB_888}, {GBM_FORMAT_BGR565, PIXEL_FMT_BGR_565}, + {GBM_FORMAT_BGRX4444, PIXEL_FMT_BGRX_4444}, {GBM_FORMAT_BGRA4444, PIXEL_FMT_BGRA_4444}, + {GBM_FORMAT_RGBA4444, PIXEL_FMT_RGBA_4444}, {GBM_FORMAT_RGBX4444, PIXEL_FMT_RGBX_4444}, + {GBM_FORMAT_BGRX5551, PIXEL_FMT_BGRX_5551}, {GBM_FORMAT_BGRA5551, PIXEL_FMT_BGRA_5551}, + {GBM_FORMAT_BGRX8888, PIXEL_FMT_BGRX_8888}, {GBM_FORMAT_BGRA8888, PIXEL_FMT_BGRA_8888}, + {GBM_FORMAT_NV12, PIXEL_FMT_YCBCR_420_SP}, {GBM_FORMAT_NV21, PIXEL_FMT_YCRCB_420_SP}, + {GBM_FORMAT_YUV420, PIXEL_FMT_YCBCR_420_P}, {GBM_FORMAT_YVU420, PIXEL_FMT_YCRCB_420_P}, + {GBM_FORMAT_NV16, PIXEL_FMT_YCBCR_422_SP}, {GBM_FORMAT_NV61, PIXEL_FMT_YCRCB_422_SP}, + {GBM_FORMAT_YUV422, PIXEL_FMT_YCBCR_422_P}, {GBM_FORMAT_YVU422, PIXEL_FMT_YCRCB_422_P}, + }; + uint32_t fmtOut = 0; + for (uint32_t i = 0; i < sizeof(convertTable) / sizeof(convertTable[0]); i++) { + if (convertTable[i].pixFormat == fmtIn) { + fmtOut = convertTable[i].drmFormat; + } + } + // LOG_DEBUG << "Convert pixelFormat(" << fmtIn << " : " << DrmFormat::GetHdiPixelFmtStr(fmtIn) << ") to DrmFormat(" + // << fmtOut << " : " << GetDrmFmtStr(fmtOut) << ")"; + return fmtOut; +} +} // namespace GbmFormat diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h new file mode 100644 index 0000000..6d9a8a4 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "display_type.h" +#include "base/log.h" + +#include + +namespace GbmFormat { +uint32_t ConvertPixelFormatToGbmFormat(PixelFormat fmtIn); +} \ No newline at end of file diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp b/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp new file mode 100644 index 0000000..73c0a7b --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "shm_allocator.h" + +#include "display_gralloc_private.h" +#include "display_gralloc_utils.h" +#include "base/log.h" +#include "base/types.h" +#include "hi_drm_format.h" // TMP + +#include +#include // for shm_xxx + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +#define RANDNAME_PATTERN "/oewm-shm-XXXXXX" + +int32_t ShmAllocator::AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) +{ + if (bufferPtr == nullptr) { + LOG_ERROR("[Gralloc::ShmAllocator::AllocMem] Get nullptr param: `buffer`"); + return DISPLAY_PARAM_ERR; + } + + PriBufferHandle *priBuffer = new PriBufferHandle(); + + /* Get format info */ + // TODO: only get bpp from PixelFormat + LOG_DEBUG("[Gralloc::ShmAllocator::AllocMem] Get format info for bpp."); + uint32_t drmFmt = DrmFormat::ConvertPixelFormatToDrmFormat(info.format); + const DrmFormat::DrmFormatInfo *fmtInfo = DrmFormat::GetDrmFormatInfo(drmFmt); + + uint32_t bytesPerPixel = fmtInfo->bpp / 8; + int32_t stride = static_cast(info.width * bytesPerPixel); // TODO: align? + int32_t size = stride * static_cast(info.height); + + if (size != static_cast(info.expectedSize)) { + LOG_WARN("[Gralloc::ShmAllocator::AllocMem] size(%{public}d) is not equal to user expected size(%{public}u)!", + size, info.expectedSize); + } + + { + std::lock_guard lock(mutex_); + + /* Create shm anonymous file */ + int32_t shmFd = static_cast(AllocateShmFile(static_cast(size))); + if (shmFd < 0) { + LOG_ERROR("[Gralloc::ShmAllocator::AllocMem] Failed to create shm file for %{public}" PRId32 " Bytes", size); + return DISPLAY_FD_ERR; + } + + /* Set buffer handle rst */ + priBuffer->hdl.fd = shmFd; + priBuffer->hdl.reserveFds = 0; + priBuffer->hdl.reserveInts = 0; + priBuffer->hdl.stride = stride; + priBuffer->hdl.width = info.width; + priBuffer->hdl.height = info.height; + priBuffer->hdl.usage = info.usage; + priBuffer->hdl.format = info.format; + priBuffer->hdl.virAddr = nullptr; + priBuffer->hdl.size = size; + + *bufferPtr = &priBuffer->hdl; + } + + return DISPLAY_SUCCESS; +} + +int32_t ShmAllocator::FreeMem(BufferHandle *buffer) +{ + if (buffer == nullptr) { + LOG_ERROR("[Gralloc::ShmAllocator::FreeMem] Get nullptr param: `buffer`"); + return DISPLAY_PARAM_ERR; + } + + /* perform memory unmapping if mmap is not clear */ + if ((buffer->virAddr != nullptr) && Unmap(*buffer) != DISPLAY_SUCCESS) { + LOG_ERROR("[Gralloc::ShmAllocator::FreeMem] Failed to free shm buffer mmap!"); + } + + /* close shm fd */ + if (buffer->fd >= 0) { + ::close(buffer->fd); + } + + return DISPLAY_SUCCESS; +} + +void *ShmAllocator::Mmap(BufferHandle &buffer) +{ + if (buffer.size < 0) { + LOG_ERROR("[Gralloc::ShmAllocator::Mmap] Get st0 buffer.size"); + return nullptr; + } + if (buffer.fd < 0) { + LOG_ERROR("[Gralloc::ShmAllocator::Mmap] Get st0 buffer.fd"); + return nullptr; + } + if (buffer.virAddr != nullptr) { + LOG_WARN("[Gralloc::ShmAllocator::Mmap] buffer.virAddr is not empty"); + return buffer.virAddr; + } + + void *data = mmap(nullptr, buffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0); + if (data == MAP_FAILED) { + LOG_ERROR("[Gralloc::ShmAllocator::Mmap] Failed to mmap for shm fd: %{public}i", buffer.fd); + return nullptr; + } + + buffer.virAddr = data; + + return data; +} + +int32_t ShmAllocator::Unmap(BufferHandle &buffer) +{ + if (buffer.virAddr == nullptr) { + LOG_ERROR("[Gralloc::ShmAllocator::Unmap] Get null buffer.virAddr"); + return DISPLAY_NULL_PTR; + } + + if (buffer.size < 0) { + LOG_ERROR("[Gralloc::ShmAllocator::Unmap] Get st0 buffer.size"); + return DISPLAY_PARAM_ERR; + } + + if (munmap(buffer.virAddr, static_cast(buffer.size)) != 0) { + LOG_ERROR("[Gralloc::ShmAllocator::Unmap] Failed to unmap shm buffer (%{public}p)", buffer.virAddr); + return DISPLAY_FAILURE; + } + + return DISPLAY_SUCCESS; +} + +int32_t ShmAllocator::FlushCache(BufferHandle &buffer) +{ + // TODO: FlushCache is not supported yet. + UNUSED(buffer); + return DISPLAY_FAILURE; +} + +int32_t ShmAllocator::InvalidateCache(BufferHandle &buffer) +{ + // TODO: InvalidateCache is not supported yet. + UNUSED(buffer); + return DISPLAY_FAILURE; +} + +void ShmAllocator::Randname(char *buf) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + long r = ts.tv_nsec; + for (int i = 0; i < 6; ++i) { + buf[i] = 'A' + (r & 15) + (r & 16) * 2; + r >>= 5; + } +} + +int ShmAllocator::ExclShmOpen(char *name) +{ + int retries = 100; + do { + Randname(name + strlen(RANDNAME_PATTERN) - 6); + + --retries; + // CLOEXEC is guaranteed to be set by shm_open + int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd >= 0) { + return fd; + } + } while (retries > 0 && errno == EEXIST); + + return -1; +} + +int ShmAllocator::AllocateShmFile(size_t size) +{ + char name[] = RANDNAME_PATTERN; + int fd = ExclShmOpen(name); + if (fd < 0) { + return -1; + } + shm_unlink(name); + + int ret; + do { + ret = ftruncate(fd, size); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + close(fd); + return -1; + } + + return fd; +} + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h b/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h new file mode 100644 index 0000000..f31bd1c --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include "allocator.h" + +#include + +namespace oewm { +namespace HDI { +namespace DISPLAY { + +class ShmAllocator : public Allocator { +public: + ShmAllocator() = default; + ~ShmAllocator() noexcept override = default; + + virtual int32_t AllocMem(const AllocInfo &info, BufferHandle **bufferPtr) override; + virtual int32_t FreeMem(BufferHandle *buffer) override; + virtual void *Mmap(BufferHandle &buffer) override; + virtual int32_t Unmap(BufferHandle &buffer) override; + virtual int32_t FlushCache(BufferHandle &buffer) override; + virtual int32_t InvalidateCache(BufferHandle &buffer) override; + +private: + void Randname(char *buf); + int ExclShmOpen(char *name); + int AllocateShmFile(size_t size); + +private: + std::mutex mutex_; +}; + +} // namespace DISPLAY +} // namespace HDI +} // namespace oewm diff --git a/display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h b/display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h new file mode 100644 index 0000000..2c80479 --- /dev/null +++ b/display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device 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. + */ + +#ifndef DISPLAY_GRALLOC_INTERNAL_H +#define DISPLAY_GRALLOC_INTERNAL_H +#include "display_type.h" +#ifdef __cplusplus +extern "C" { +#endif +#define GRALLOC_NUM_FDS 1 +#define GRALLOC_NUM_INTS ((sizeof(struct PrivBufferHandle) - sizeof(BufferHandle)) / sizeof(int) - GRALLOC_NUM_FDS) + +#define INVALID_PIXEL_FMT 0 + +typedef struct { + BufferHandle hdl; +} PriBufferHandle; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/display_server/drivers/hal/core/event_loop/BUILD.gn b/display_server/drivers/hal/core/event_loop/BUILD.gn new file mode 100644 index 0000000..5a14b44 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/BUILD.gn @@ -0,0 +1,30 @@ +# +# Copyright (c) 2022 Huawei Device 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. +import("//build/gn/fangtian.gni") + +ft_shared_library("event_loop") { + sources = [ + "event_channel.cpp", + "event_loop.cpp", + "event_loop_thread.cpp", + "event_poller.cpp", + "timer.cpp", + "timer_queue.cpp", + ] + configs = [ "//display_server/drivers/hal:oehal_public_config" ] + deps = [ + "//display_server/drivers/hal/base:oebase", + # "//display_server/drivers/hal/log:oelog", + ] +} diff --git a/display_server/drivers/hal/core/event_loop/event_channel.cpp b/display_server/drivers/hal/core/event_loop/event_channel.cpp new file mode 100644 index 0000000..8d1f01e --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_channel.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "event_channel.h" + +#include "event_loop.h" +#include "base/log.h" + +namespace oewm { +EventChannel::EventChannel(int fd, EventLoop *eventLoop) : fd_(fd), eventLoop_(eventLoop) +{ + if (eventLoop_ == nullptr) { + LOG_FATAL("EventChannel::ctor: EventLoop is null!"); + } +} + +EventChannel::~EventChannel() noexcept {} + +void EventChannel::AssertInLoopThread() const +{ + ASSERT(eventLoop_ != nullptr); + eventLoop_->AssertInLoopThread(); +} + +void EventChannel::Remove() +{ + ASSERT(HasNoEvent()); + addedToLoop_ = false; + eventLoop_->RemoveChannel(fd_); +} + +void EventChannel::EnableReading(bool toUpdate) +{ + listeningEvents_ |= ECast(EventType::READ_EVENT); + + if (toUpdate) { + Update(); + } +} + +void EventChannel::DisableReading(bool toUpdate) +{ + listeningEvents_ &= (~ECast(EventType::READ_EVENT)); + + if (toUpdate) { + Update(); + } +} + +void EventChannel::EnableWriting(bool toUpdate) +{ + listeningEvents_ |= ECast(EventType::WRITE_EVENT); + + if (toUpdate) { + Update(); + } +} + +void EventChannel::DisableWriting(bool toUpdate) +{ + listeningEvents_ &= (~ECast(EventType::WRITE_EVENT)); + + if (toUpdate) { + Update(); + } +} + +void EventChannel::DisableAll(bool toRemove) +{ + listeningEvents_ = ECast(EventType::NONE); + + if (toRemove) { + Update(); + } +} + +void EventChannel::Update() +{ + if (HasNoEvent()) { + Remove(); + } else { + addedToLoop_ = true; + eventLoop_->UpdateChannel(this); + } +} + +void EventChannel::HandleEvent(TimeStamp receivedTime) +{ + AssertInLoopThread(); + + if (tied_) { + // make sure the owner object will not be destroyed. + std::shared_ptr guard = ownerObj_.lock(); + if (guard == nullptr) { + LOG_WARN("EventChannel::HandleEvent: the owner object was dead, do nothing."); + return; + } + HandleEventInner(receivedTime); + } else { + HandleEventInner(receivedTime); + } +} + +void EventChannel::HandleEventInner(TimeStamp receivedTime) +{ + if ((receivedEvents_ & EPOLLHUP) && !(receivedEvents_ & EPOLLIN)) { + LOG_DEBUG("close event in channel %{public}i.", fd_); + if (closeCallback_ != nullptr) { + closeCallback_(); + return; + } + } + + if (receivedEvents_ & EPOLLERR) { + LOG_DEBUG("error event in channel %{public}i.", fd_); + if (errorCallback_ != nullptr) { + errorCallback_(); + return; + } + } + + if (receivedEvents_ & (EPOLLIN | EPOLLPRI | EPOLLRDHUP)) { + // LOG_DEBUG("read event in channel %{public}i.", fd_); + if (readCallback_ != nullptr) { + readCallback_(receivedTime); + } + } + + if (receivedEvents_ & EPOLLOUT) { + LOG_DEBUG("write event in channel %{public}i.", fd_); + if (writeCallback_ != nullptr) { + writeCallback_(); + } + } +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_channel.h b/display_server/drivers/hal/core/event_loop/event_channel.h new file mode 100644 index 0000000..e86a437 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_channel.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include "base/noncopyable.h" +#include "base/timestamp.h" + +namespace oewm { +using EventCallback = std::function; +using ReadCallback = std::function; + +class EventPoller; +class EventLoop; + +// use EPOLL_EVENTS to define channel event types. +enum class EventType : uint32_t { + NONE = 0x0, + READ_EVENT = EPOLLIN | EPOLLPRI, + WRITE_EVENT = EPOLLOUT, + EDGE_EVENT = EPOLLET, +}; + +// The EventChannel class not own the fd, so we must make sure that +// the fd is valid when an EventChannel object holds it. +class EventChannel : NonCopyable { +public: + EventChannel(int fd, EventLoop *eventLoop); + ~EventChannel() noexcept; + + void HandleEvent(TimeStamp receivedTime); + + int Fd() const + { + return fd_; + } + EventLoop *GetOwnerLoop() const + { + return eventLoop_; + } + + // not thread safe. + void SetReadCallback(ReadCallback cb) + { + readCallback_ = std::move(cb); + } + // not thread safe. + void SetWriteCallback(EventCallback cb) + { + writeCallback_ = std::move(cb); + } + // not thread safe. + void SetErrorCallback(EventCallback cb) + { + errorCallback_ = std::move(cb); + } + // not thread safe. + void SetCloseCallback(EventCallback cb) + { + closeCallback_ = std::move(cb); + } + + bool HasNoEvent() const + { + return ListeningEvents() == ECast(EventType::NONE); + } + bool IsWriting() const + { + return ListeningEvents() & ECast(EventType::WRITE_EVENT); + } + bool IsReading() const + { + return ListeningEvents() & ECast(EventType::READ_EVENT); + } + + // @toUpdate: whether to update the channel in poller or not, true by default. + void EnableReading(bool toUpdate = true); + // @toUpdate: whether to update the channel in poller or not, true by default. + void DisableReading(bool toUpdate = true); + // @toUpdate: whether to update the channel in poller or not, true by default. + void EnableWriting(bool toUpdate = true); + // @toUpdate: whether to update the channel in poller or not, true by default. + void DisableWriting(bool toUpdate = true); + // @toRemove: whether to remove the channel in poller or not, true by default. + void DisableAll(bool toRemove = true); + + void Update(); + void Remove(); + + // the owner object should call this function + // to prevent itself from being destroyed in handleEvent. + void Tie(std::weak_ptr ownerObj) + { + ownerObj_ = ownerObj; + tied_ = true; + } + +protected: + // will abort if not in loop thread. + void AssertInLoopThread() const; + + void HandleEventInner(TimeStamp receivedTime); + + friend class EventPoller; + uint32_t ListeningEvents() const + { + return listeningEvents_; + } + void SetReceivedEvents(uint32_t events) + { + receivedEvents_ = events; + } + + int fd_ = -1; + EventLoop *eventLoop_ = nullptr; + std::atomic addedToLoop_{false}; + + uint32_t listeningEvents_ = ECast(EventType::NONE); + uint32_t receivedEvents_ = ECast(EventType::NONE); + + ReadCallback readCallback_; + EventCallback writeCallback_; + EventCallback errorCallback_; + EventCallback closeCallback_; + + std::weak_ptr ownerObj_; + std::atomic tied_{false}; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_loop.cpp b/display_server/drivers/hal/core/event_loop/event_loop.cpp new file mode 100644 index 0000000..7e26f28 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_loop.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "event_loop.h" + +#include +#include + +#include "base/current_thread.h" +#include "base/log.h" + +namespace oewm { +namespace detail { +int CreateEventFdOrDie() +{ + int fd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + if (fd < 0) { + LOG_FATAL("Create eventFd failed: %{public}s.", ErrnoToString(errno).c_str()); + } + + return fd; +} +} // namespace detail +__thread EventLoop *t_currLoop = nullptr; // current thread's event_loop + +EventLoop::EventLoop() + : tid_(CurrentThread::Tid()), + poller_(std::make_unique(this)), + wakeUpFd_(detail::CreateEventFdOrDie()), + wakeUpChannel_(std::make_unique(wakeUpFd_.Get(), this)), + timerQueue_(std::make_unique(this)) +{ + if (t_currLoop != nullptr) { + LOG_FATAL("Construct EventLoop failed: current thread already have a loop(%{public}p)!", &t_currLoop); + } + + // wakeUpCallback do not need TimeStamp + wakeUpChannel_->SetReadCallback([this](TimeStamp) { WakeUpCallback(); }); + wakeUpChannel_->EnableReading(); + t_currLoop = this; +} + +EventLoop::~EventLoop() noexcept +{ + wakeUpChannel_->DisableAll(); + Stop(); + t_currLoop = nullptr; +} + +void EventLoop::Stop() noexcept +{ + if (!running_) { + return; + } + + running_ = false; + + if (!IsInLoopThread()) { + WakeUp(); + } +} + +void EventLoop::UpdateChannel(EventChannel *channel) +{ + if (channel == nullptr) { + LOG_WARN("EventLoop::%{public}s: channel is null!", __func__); + return; + } + + RunInLoop([this, channel]() mutable { poller_->UpdateChannel(channel); }); +} + +void EventLoop::RemoveChannel(int channelFd) +{ + RunInLoop([=]() { poller_->RemoveChannel(channelFd); }); +} + +void EventLoop::ExecPendingFunctors() +{ + AssertInLoopThread(); + + executingPendingFunctors_ = true; + std::vector funcs; + { + std::lock_guard lock(mutex_); + funcs.swap(pendingFunctors_); + } + + for (const auto &func : funcs) { + func(); + } + executingPendingFunctors_ = false; +} + +void EventLoop::QueueToLoop(Functor func) +{ + { + std::lock_guard lock(mutex_); + pendingFunctors_.push_back(std::move(func)); + } + + if (!IsInLoopThread() || executingPendingFunctors_) { + WakeUp(); + } +} + +void EventLoop::RunInLoop(Functor func) +{ + if (IsInLoopThread()) { + func(); + } else { + QueueToLoop(std::move(func)); + } +} + +TimerId EventLoop::RunAt(Functor func, TimeStamp dstTime) +{ + return timerQueue_->AddTimer(std::move(func), dstTime); +} + +TimerId EventLoop::RunAfter(Functor func, TimeType delay) +{ + return timerQueue_->AddTimer(std::move(func), TimeAdd(TimeStamp::Now(), delay)); +} + +TimerId EventLoop::RunEvery(Functor func, TimeType interval, TimeType delay) +{ + return timerQueue_->AddTimer(std::move(func), TimeAdd(TimeStamp::Now(), delay), interval); +} + +void EventLoop::Cancel(const TimerId &timerId) +{ + timerQueue_->CancelTimer(timerId); +} + +void EventLoop::Start() +{ + AssertInLoopThread(); + + running_ = true; + while (running_) { + std::vector activeChannels; + TimeStamp pollTime = poller_->PollOnce(activeChannels, -1); + for (const auto &channel : activeChannels) { + if (channel != nullptr) { + channel->HandleEvent(pollTime); + } + } + + ExecPendingFunctors(); + } +} + +bool EventLoop::IsInLoopThread() const +{ + return CurrentThread::Tid() == tid_; +} + +void EventLoop::AssertInLoopThread() const +{ + if (OE_UNLIKELY(!IsInLoopThread())) { + LOG_FATAL("assertInLoopThread failed!"); + } +} + +void EventLoop::AssertNotInLoopThread() const +{ + if (OE_UNLIKELY(IsInLoopThread())) { + LOG_FATAL("assertNotInLoopThread failed!"); + } +} + +void EventLoop::WakeUp() +{ + uint64_t buf = 1; + int len = TEMP_FAILURE_RETRY(::write(wakeUpChannel_->Fd(), &buf, sizeof(buf))); + if (OE_UNLIKELY(len != sizeof(buf))) { + LOG_WARN("should write %{public}lu bytes, but %{public}i wrote.", sizeof(buf), len); + } +} + +void EventLoop::WakeUpCallback() +{ + uint64_t buf = 0; + int len = TEMP_FAILURE_RETRY(::read(wakeUpChannel_->Fd(), &buf, sizeof(buf))); + if (OE_UNLIKELY(len != sizeof(buf))) { + LOG_WARN("should read %{public}lu bytes, but %{public}i read.", sizeof(buf), len); + } +} + +EventLoop *EventLoop::EventLoopOfCurrThread() +{ + return t_currLoop; +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_loop.h b/display_server/drivers/hal/core/event_loop/event_loop.h new file mode 100644 index 0000000..12242c1 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_loop.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "event_poller.h" +#include "timer_queue.h" + +namespace oewm { +using Functor = std::function; + +namespace detail { +template +class PackagedTask : NonCopyable { + using Return = std::invoke_result_t; + +public: + ~PackagedTask() noexcept = default; + + static auto Create(Callable &&cb) + { + std::shared_ptr> t(new PackagedTask(std::forward(cb))); + return std::make_pair(t, t->cb_.get_future()); + } + + void Run() + { + cb_(); + } + +private: + explicit PackagedTask(Callable &&cb) : cb_(std::move(cb)) {} + + std::packaged_task cb_; +}; +} // namespace detail + +class EventLoop : NonCopyable { +public: + EventLoop(); + ~EventLoop() noexcept; + void Start(); + void Stop() noexcept; + void UpdateChannel(EventChannel *channel); + void RemoveChannel(int channelFd); + + template > + std::future Schedule(Task task) + { + auto [packagedTask, future] = detail::PackagedTask::Create(std::move(task)); + RunInLoop([t(std::move(packagedTask))]() { t->Run(); }); + return std::move(future); + } + + // run func immediately if in loop thread, or call queueToLoop() if in other thread. + void RunInLoop(Functor func); + + // add this func to the last of the loop's pending functors. + void QueueToLoop(Functor func); + + TimerId RunAt(Functor func, TimeStamp dstTime); + + // delay in micro seconds, 0 means run immediately + TimerId RunAfter(Functor func, TimeType delay); + + // delay in micro seconds, 0 means run immediately + // interval in micro seconds, 0 means only run once. + TimerId RunEvery(Functor func, TimeType interval, TimeType delay = 0); + + void Cancel(const TimerId &timerId); + + static EventLoop *EventLoopOfCurrThread(); + + bool IsInLoopThread() const; + + // will abort if not in loop thread. + void AssertInLoopThread() const; + // will abort if in loop thread. + void AssertNotInLoopThread() const; + +private: + void WakeUp(); + void WakeUpCallback(); + + void ExecPendingFunctors(); + + ThreadId tid_ = -1; // indicates which thread is this loop in. + + mutable std::mutex mutex_; + std::atomic running_{false}; + + std::unique_ptr poller_; + + OHOS::UniqueFd wakeUpFd_; + std::unique_ptr wakeUpChannel_; + + std::atomic executingPendingFunctors_{false}; + std::vector pendingFunctors_; + + std::unique_ptr timerQueue_; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_loop_thread.cpp b/display_server/drivers/hal/core/event_loop/event_loop_thread.cpp new file mode 100644 index 0000000..c8526d9 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_loop_thread.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "event_loop_thread.h" + +#include "base/log.h" + +namespace oewm { +EventLoopThread::EventLoopThread() : EventLoopThread("OEWMEventLoopThread") {} + +EventLoopThread::EventLoopThread(std::string name) : name_(std::move(name)) {} + +EventLoopThread::~EventLoopThread() noexcept +{ + { + std::lock_guard lock(mutex_); + if (loop_ != nullptr) { + loop_->Stop(); + } + } + + if (thread_.joinable()) { + thread_.join(); + } + + LOG_DEBUG("%{public}s Stopped.", name_.c_str()); +} + +EventLoop *EventLoopThread::Start() +{ + thread_ = std::thread([this]() { LoopThreadFunc(); }); + + std::unique_lock lock(mutex_); + cond_.wait(lock, [this]() -> bool { return loop_ != nullptr; }); + return loop_; +} + +void EventLoopThread::LoopThreadFunc() +{ + EventLoop loop; + + { + std::lock_guard lock(mutex_); + loop_ = &loop; + cond_.notify_one(); + } + + loop.Start(); + + { + std::lock_guard lock(mutex_); + loop_ = nullptr; + } +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_loop_thread.h b/display_server/drivers/hal/core/event_loop/event_loop_thread.h new file mode 100644 index 0000000..78cd62d --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_loop_thread.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include + +#include "event_loop.h" + +namespace oewm { +class EventLoopThread : NonCopyable { +public: + EventLoopThread(); + explicit EventLoopThread(std::string name); + ~EventLoopThread() noexcept; + + EventLoop *Start(); + const std::string &Name() const + { + return name_; + } + +private: + void LoopThreadFunc(); + + mutable std::mutex mutex_; + std::condition_variable cond_; + std::string name_; + std::thread thread_; + EventLoop *loop_ = nullptr; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_poller.cpp b/display_server/drivers/hal/core/event_loop/event_poller.cpp new file mode 100644 index 0000000..9794364 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_poller.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "event_poller.h" + +#include "base/types.h" +#include "event_loop.h" + +#include "base/log.h" + +namespace oewm { +namespace detail { +std::string EpollOperationToString(int operation) +{ + switch (operation) { + case EPOLL_CTL_ADD: + return "EpollCtlAdd"; + case EPOLL_CTL_MOD: + return "EpollCtlMod"; + case EPOLL_CTL_DEL: + return "EpollCtlDel"; + default: + return "UnknownEpollCtl"; + } +} +} // namespace detail + +std::size_t EventPoller::eventSize_ = 32; + +EventPoller::EventPoller(EventLoop *eventLoop) + : eventLoop_(eventLoop), epollFd_(::epoll_create1(EPOLL_CLOEXEC)), activeEvents_(eventSize_) +{ + if (eventLoop_ == nullptr) { + LOG_FATAL("EventLoop is null!"); + } +} + +EventPoller::~EventPoller() noexcept {} + +TimeStamp EventPoller::PollOnce(std::vector &activeChannels, int timeOutMs) +{ + auto cnt = TEMP_FAILURE_RETRY(::epoll_wait(epollFd_.Get(), activeEvents_.data(), eventSize_, timeOutMs)); + auto pollTime = TimeStamp::Now(); + if (cnt < 0) { + LOG_WARN("epoll_wait error: %{public}s.", ErrnoToString(errno).c_str()); + } else { + for (int i = 0; i < cnt; ++i) { + const auto &event = activeEvents_[i]; + int fd = event.data.fd; + if (channels_.count(fd) == 0 && channels_.at(fd) == nullptr) { + LOG_WARN("epoll_wait returned a channel that is not in poller(%{public}i).", epollFd_.Get()); + continue; + } + + const auto &channel = channels_.at(fd); + channel->SetReceivedEvents(event.events); + activeChannels.emplace_back(channel); + } + + if (static_cast(cnt) == eventSize_) { + eventSize_ *= 2; + activeEvents_.resize(eventSize_); + } + } + + return pollTime; +} + +void EventPoller::AssertInLoopThread() +{ + ASSERT(eventLoop_ != nullptr); + eventLoop_->AssertInLoopThread(); +} + +void EventPoller::EpollCtl(EventChannel *channel, int operation) +{ + ASSERT(channel != nullptr); + int fd = channel->Fd(); + epoll_event epollEvent; + epollEvent.events = channel->ListeningEvents(); + epollEvent.data.fd = fd; + int ret = TEMP_FAILURE_RETRY(::epoll_ctl(epollFd_.Get(), operation, fd, &epollEvent)); + if (ret < 0) { + LOG_ERROR("%{public}s failed for EventPoller(fd: %{public}i): %{public}s.", + detail::EpollOperationToString(operation).c_str(), fd, ErrnoToString(errno).c_str()); + } +} + +void EventPoller::UpdateChannel(EventChannel *channel) +{ + if (channel == nullptr) { + return; + } + + eventLoop_->AssertInLoopThread(); + + int fd = channel->Fd(); + if (channel->HasNoEvent()) { + eventLoop_->RemoveChannel(fd); + return; + } + + if (channels_.count(fd) == 0) { + // new channel + EpollCtl(channel, EPOLL_CTL_ADD); + channels_[fd] = channel; + } else { + // modify channel + EpollCtl(channels_[fd], EPOLL_CTL_MOD); + } +} + +void EventPoller::RemoveChannel(int fd) +{ + eventLoop_->AssertInLoopThread(); + + if (channels_.count(fd) == 0) { + LOG_WARN("Can't find channel %{public}i in poller %{public}i.", fd, epollFd_.Get()); + return; + } + + EpollCtl(channels_[fd], EPOLL_CTL_DEL); + channels_.erase(fd); +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/event_poller.h b/display_server/drivers/hal/core/event_loop/event_poller.h new file mode 100644 index 0000000..54f8b83 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/event_poller.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include + +#include "unique_fd.h" +#include "event_channel.h" + +namespace oewm { +class EventLoop; + +class EventPoller : NonCopyable { +public: + explicit EventPoller(EventLoop *eventLoop); + ~EventPoller() noexcept; + + TimeStamp PollOnce(std::vector &activeChannels, int timeOutMs); + void UpdateChannel(EventChannel *channel); + void RemoveChannel(int fd); + +private: + void AssertInLoopThread(); + + void EpollCtl(EventChannel *channel, int operation); + EventLoop *eventLoop_ = nullptr; + OHOS::UniqueFd epollFd_; + static std::size_t eventSize_; + std::vector activeEvents_; // to receive events from epoll_wait. + std::unordered_map channels_; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/timer.cpp b/display_server/drivers/hal/core/event_loop/timer.cpp new file mode 100644 index 0000000..3eec296 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/timer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "timer.h" + +#include + +namespace oewm { +namespace detail { +uint64_t GenSequenceId() +{ + static std::atomic id(0); + return id++; +} +} // namespace detail + +Timer::Timer(TimerCallback callback, TimeStamp expireTime, TimeType interval) + : cb_(std::move(callback)), + expireTime_(expireTime), + interval_(interval), + repeat_(interval > 0), + id_(detail::GenSequenceId(), this) +{} + +void Timer::Execute() +{ + if (cb_ != nullptr) { + cb_(); + } +} + +void Timer::Restart(TimeStamp now) +{ + ASSERT(IsRepeat()); + expireTime_ = TimeAdd(now, interval_); +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/timer.h b/display_server/drivers/hal/core/event_loop/timer.h new file mode 100644 index 0000000..f5d90f3 --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/timer.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include + +#include "base/noncopyable.h" +#include "base/timestamp.h" + +namespace oewm { +class Timer; + +// NonCopyable +struct TimerId { + TimerId() = default; + TimerId(uint64_t id, Timer *timer) : id(id), timer(timer) {} + + uint64_t id = 0; + Timer *timer = nullptr; + bool operator!() const + { + return timer == nullptr; + } + bool operator==(std::nullptr_t) const + { + return timer == nullptr; + } + bool operator!=(std::nullptr_t) const + { + return timer != nullptr; + } + bool operator==(const TimerId &other) const + { + return id == other.id && timer == other.timer; + } + bool operator<(const TimerId &other) const + { + return id < other.id || timer < other.timer; + } +}; + +using TimerCallback = std::function; + +class Timer : NonCopyable { +public: + // @callback: TimerCallback + // @expireTime: expire TimeStamp + // @interval: interval in micro seconds, 0 for only run once. + Timer(TimerCallback callback, TimeStamp expireTime, TimeType interval = 0); + ~Timer() noexcept = default; + + TimerId Id() const + { + return id_; + } + bool IsRepeat() const + { + return repeat_; + } + + TimeStamp ExpireTime() const + { + return expireTime_; + } + + // only valid when the timer is repeated. + void Restart(TimeStamp now); + void Execute(); + +private: + TimerCallback cb_; + TimeStamp expireTime_; + TimeType interval_ = 0; + bool repeat_ = false; + TimerId id_; +}; +} // namespace oewm + +namespace std { +template <> +struct hash { + std::size_t operator()(oewm::TimerId timerId) const + { + return static_cast(timerId.id ^ reinterpret_cast(timerId.timer)); + } +}; +} // namespace std diff --git a/display_server/drivers/hal/core/event_loop/timer_queue.cpp b/display_server/drivers/hal/core/event_loop/timer_queue.cpp new file mode 100644 index 0000000..161320c --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/timer_queue.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2022 Huawei Device 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 "timer_queue.h" + +#include + +#include "event_loop.h" +#include "base/log.h" + +namespace oewm { +namespace detail { +int CreateTimerFd() +{ + int fd = TEMP_FAILURE_RETRY(::timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC)); + if (IsInvalidFd(fd)) { + LOG_FATAL("Create timerFd error: %{public}s", ErrnoToString(errno).c_str()); + } + + return fd; +} + +itimerspec GenerateTimerSpec(TimeStamp dstTime) +{ + itimerspec newValue{}; + + auto diffMicros = TimeDiff(dstTime, TimeStamp::Now()); + // set minimum diffMicros to 1 us to make sure the timer can be triggered. + diffMicros = std::max(decltype(diffMicros)(1), diffMicros); + + newValue.it_value.tv_sec = diffMicros / MICRO_SECS_PER_SECOND; + newValue.it_value.tv_nsec = (diffMicros * NANO_SECS_PER_MICROSECOND) % NANO_SECS_PER_SECOND; + return newValue; +} +} // namespace detail + +TimerQueue::TimerQueue(EventLoop *loop) + : loop_(loop), + timerFd_(detail::CreateTimerFd()), + timerFdChannel_(std::make_unique(timerFd_.Get(), loop_)) +{ + timerFdChannel_->SetReadCallback([this](TimeStamp t) { HandleRead(t); }); + timerFdChannel_->EnableReading(); +} + +TimerQueue::~TimerQueue() noexcept +{ + timerFdChannel_->DisableAll(); +} + +TimerId TimerQueue::AddTimer(TimerCallback callback, TimeStamp expireTime, TimeType interval) +{ + auto future = loop_->Schedule([=, cb(std::move(callback))]() mutable -> TimerId { + auto newTimer = std::make_unique(std::move(cb), expireTime, interval); + TimerId id = newTimer->Id(); + AddTimerInLoop(std::move(newTimer)); + return id; + }); + return future.get(); +} + +void TimerQueue::AddTimerInLoop(std::unique_ptr &&timer) +{ + ASSERT(timer != nullptr); + AssertInLoopThread(); + + TimeStamp expireTime = timer->ExpireTime(); + bool needToResetTimerFd = (timerEntries_.empty() || expireTime < timerEntries_.cbegin()->first); + + TimerId timerId = timer->Id(); + timerEntries_.insert(std::make_pair(expireTime, timerId)); + timers_[timerId] = std::move(timer); + + if (needToResetTimerFd) { + TimerFdReset(expireTime); + } +} + +void TimerQueue::CancelTimer(const TimerId &timerId) +{ + loop_->RunInLoop([=]() { CancelTimerInLoop(timerId); }); +} + +void TimerQueue::CancelTimerInLoop(const TimerId &timerId) +{ + AssertInLoopThread(); + + auto timer = timerId.timer; + if (timer == nullptr) { + return; + } + + auto timerEntry = std::make_pair(timer->ExpireTime(), timerId); + if (timers_.count(timerId) == 0 || timerEntries_.count(timerEntry) == 0) { + return; + } + + LOG_DEBUG("Cancel Timer(id: %{public}lu).", timerId.id); + bool needToResetTimerFd = (timerEntry == *timerEntries_.cbegin()); + timers_.erase(timerId); + timerEntries_.erase(timerEntry); + + if (needToResetTimerFd) { + TimerFdReset(timerEntries_.cbegin()->first); + } +} + +void TimerQueue::AssertInLoopThread() +{ + ASSERT(loop_ != nullptr); + loop_->AssertInLoopThread(); +} + +std::vector TimerQueue::GetExpiredTimers(TimeStamp receivedTime) +{ + std::vector expiredTimers; + + TimerEntry pivot = std::make_pair(receivedTime, TimerId(0, nullptr)); + auto it = timerEntries_.lower_bound(pivot); + ASSERT(receivedTime <= it->first || it == timerEntries_.cend()); + std::copy(timerEntries_.begin(), it, std::back_inserter(expiredTimers)); + timerEntries_.erase(timerEntries_.begin(), it); + + return expiredTimers; +} + +void TimerQueue::HandleRead(TimeStamp receivedTime) +{ + AssertInLoopThread(); + TimerFdRead(); + + { + auto expiredTimers = GetExpiredTimers(receivedTime); + for (const auto &[timestamp, timerId] : expiredTimers) { + ASSERT(timers_.count(timerId) > 0); + auto &timer = timers_.at(timerId); + ASSERT(timer != nullptr); + if (timer->IsRepeat()) { + // restart the timer and insert it back to the timer_queue. + timer->Restart(timestamp); + timerEntries_.insert(std::make_pair(timer->ExpireTime(), timerId)); + } else { + timers_.erase(timerId); + } + + timer->Execute(); + } + } + + auto nextExpiredTime = timerEntries_.cbegin()->first; + TimerFdReset(nextExpiredTime); +} + +void TimerQueue::TimerFdRead() +{ + uint64_t one = 0; + int len = TEMP_FAILURE_RETRY(::read(timerFd_.Get(), &one, sizeof(one))); + if (len != sizeof(one)) { + LOG_WARN("Read from timerFd(%{public}i) %{public}i bytes, should be %{public}lu bytes.", + timerFd_.Get(), len, sizeof(one)); + } +} + +void TimerQueue::TimerFdReset(TimeStamp expireTime) +{ + auto newValue = detail::GenerateTimerSpec(expireTime); + int ret = TEMP_FAILURE_RETRY(::timerfd_settime(timerFd_.Get(), 0, &newValue, nullptr)); + if (ret != 0) { + LOG_FATAL("TimerFd set time error: %{public}s", ErrnoToString(errno).c_str()); + } +} +} // namespace oewm diff --git a/display_server/drivers/hal/core/event_loop/timer_queue.h b/display_server/drivers/hal/core/event_loop/timer_queue.h new file mode 100644 index 0000000..e48fccf --- /dev/null +++ b/display_server/drivers/hal/core/event_loop/timer_queue.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +#pragma once + +#include +#include +#include + +#include "unique_fd.h" +#include "event_channel.h" +#include "timer.h" + +namespace oewm { +class EventLoop; + +using TimerPtr = std::unique_ptr; +using TimerMap = std::unordered_map; // To hold timers, manager the timers' ownership. +using TimerEntry = std::pair; // Make sure every TimerEntry is unique. +using TimerEntrySet = std::set; // To sort timers ordered by expireTime + +class TimerQueue : NonCopyable { +public: + explicit TimerQueue(EventLoop *loop); + ~TimerQueue() noexcept; + + // @callback: TimerCallback + // @expireTime: expire TimeStamp + // @interval: interval in micro seconds, 0 for only run once. + // @return: TimerId + TimerId AddTimer(TimerCallback callback, TimeStamp expireTime, TimeType interval = 0); + + // @timerId: TimerId to cancel + // can only be called in loop thread + void CancelTimer(const TimerId &timerId); + +private: + void AssertInLoopThread(); + + void AddTimerInLoop(std::unique_ptr &&timer); + void CancelTimerInLoop(const TimerId &timerId); + std::vector GetExpiredTimers(TimeStamp receivedTime); + + void HandleRead(TimeStamp receivedTime); + void TimerFdRead(); + void TimerFdReset(TimeStamp expireTime); + + EventLoop *loop_ = nullptr; + OHOS::UniqueFd timerFd_; + std::unique_ptr timerFdChannel_; + + TimerMap timers_; + TimerEntrySet timerEntries_; +}; +} // namespace oewm diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn new file mode 100644 index 0000000..e9968f0 --- /dev/null +++ b/display_server/drivers/hal/test/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2023 Huawei Device 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. + +import("//build/gn/fangtian.gni") + +ft_executable("drm_backend_test") { + testonly = true + + sources = [ + "system_test/main.cpp" + ] + + deps = [ + "//display_server/drivers/hal/core/drm_backend:drm_backend", + "//display_server/drivers/hal/core/event_loop:event_loop", + "//display_server/utils/sync_fence/ft_build:sync_fence", + ] + + configs = [ + "//display_server/drivers/hal:oehal_public_config" + ] +} diff --git a/display_server/drivers/hal/test/system_test/main.cpp b/display_server/drivers/hal/test/system_test/main.cpp new file mode 100644 index 0000000..785bc8d --- /dev/null +++ b/display_server/drivers/hal/test/system_test/main.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2023 Huawei Device 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" + +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_CPU_READ | HBM_USE_MEM_FB | HBM_USE_CPU_WRITE, // allocate dumb buffer with "HBM_USE_CPU_WRITE" + .format = PIXEL_FMT_BGRA_8888}; // TODO: format + 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; + } + + /* Mmap buffer */ + void* addr = allocator->Mmap(**handle); + if (addr == nullptr) { + printf("CreateBuffer: Failed to mmap fb.\n"); + return false; + } + + printf("CreateBuffer: end. handle fd: %i.\n", (*handle)->fd); + return true; +} + +void DrawBaseColor(void *image, uint32_t width, uint32_t height) +{ + uint32_t *pixels = static_cast(image); + static std::vector colors = {0xff0000ff, 0xffff00ff, 0xaa00ff00, 0xff00ffaa, 0xff0f0f00}; + + static uint32_t index = 0; + if (index++ > 4) { + index = 0; + } + + for (uint32_t x = 0; x < width; x++) { + for (uint32_t y = 0; y < height; y++) { + *pixels++ = colors[index]; + } + } +} + +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)); + } + + // // Fill fb with plain color + // DrawBaseColor( + // screen->fb[screen->fbIdx]->handle->virAddr, + // 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; + // } + } + screen->firstFrame = false; + + // Fill fb with plain color + DrawBaseColor( + screen->fb[screen->fbIdx]->handle->virAddr, + 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; +} diff --git a/display_server/drivers/interfaces/display_device.h b/display_server/drivers/interfaces/display_device.h new file mode 100644 index 0000000..2813071 --- /dev/null +++ b/display_server/drivers/interfaces/display_device.h @@ -0,0 +1,691 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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. + */ + +/** + * @addtogroup Display + * @{ + * + * @brief Defines driver functions of the display module. + * + * This module provides driver functions for the graphics subsystem, including graphics layer management, + * device control, graphics hardware acceleration, display memory management, and callbacks. + * @since 1.0 + * @version 2.0 + */ + + /** + * @file display_device.h + * + * @brief Declares control functions of the display device. + * + * @since 1.0 + * @version 2.0 + */ + +#ifndef DISPLAY_DEVICE_H +#define DISPLAY_DEVICE_H +#include "display_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* * + * @brief Called when a hot plug event occurs. + * + * This callback must be registered by calling RegHotPlugCallback. + * + * @param devId Indicates the ID of the display device. This ID is generated by the HDI implementation layer and + * transferred to the graphics service through the current callback. It identifies the display device to connect. + * @param connected Indicates the connection status of the display device. The value true means that the + * display device is connected, and false means the opposite. + * @param data Indicates the private data carried by the graphics service. This parameter carries the private data + * address transferred when RegHotPlugCallback is called. For details, see {@link RegHotPlugCallback}. + * + * + * @since 1.0 + * @version 1.0 + */ +typedef void (*HotPlugCallback)(uint32_t devId, bool connected, void *data); + +/* * + * @brief Called when a VBLANK event occurs. + * + * This callback must be registered by calling RegDisplayVBlankCallback. + * + * @param sequence Indicates the VBLANK sequence, which is an accumulated value. + * @param ns Indicates the timestamp (in ns) of the VBLANK event. + * @param data Indicates the pointer to the private data carried by the graphics service. This parameter carries + * the address passed when RegDisplayVBlankCallback is called. + * + * @since 1.0 + * @version 1.0 + */ +typedef void (*VBlankCallback)(unsigned int sequence, uint64_t ns, void *data); + +/* * + * @brief Called when the graphics service needs to refresh data frames. + * + * This callback must be registered by calling RegDisplayRefreshCallback. + * + * @param devId Indicates the ID of the display device. + * @param data Indicates the pointer to the private data carried by the graphics service. This parameter carries + * the address passed when RegDisplayRefreshCallback is called. + * + * @since 1.0 + * @version 1.0 + */ +typedef void (*RefreshCallback)(uint32_t devId, void *data); + +typedef void (*ComposerDeathCallback)(void *data); + +/** + * @brief Defines pointers to the functions of the display device. + */ +typedef struct { + /* * + * @brief Registers the callback to be invoked when a hot plug event occurs. + * + * @param callback Indicates the instance used to notify the graphics service of a hot plug event occurred. + * @param data Indicates the pointer to the private data returned to the graphics service in the + * HotPlugCallback callback. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*RegHotPlugCallback)(HotPlugCallback callback, void *data); + + /* * + * @brief Registers the callback to be invoked when a VBLANK event occurs. + * + * @param devId Indicates the ID of the display device. + * @param callback Indicates the instance used to notify the graphics service of the VBLANK event occurred when + * DisplayVsync is enabled. + * @param data Indicates the pointer to the private data returned to the graphics service in the + * VBlankCallback callback. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*RegDisplayVBlankCallback)(uint32_t devId, VBlankCallback callback, void *data); + + /* * + * @brief Called when the graphics service needs to refresh data frames. + * + * @param devId Indicates the ID of the display device. + * @param callback Indicates the instance used to notify the graphics service of the request for refreshing + * data frames. + * @param data Indicates the pointer to the private data returned to the graphics service in the + * RefreshCallback callback. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*RegDisplayRefreshCallback)(uint32_t devId, RefreshCallback callback, void *data); + + /* * + * @brief Obtains the capabilities of a display device. + * + * @param devId Indicates the ID of the display device. + * @param info Indicates the pointer to the capabilities supported by the display device. For details, + * see {@link DisplayCapability}. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayCapability)(uint32_t devId, DisplayCapability *info); + + /* * + * @brief Obtains the display modes supported by a display device. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the pointer to the number of modes supported by the display device. + * @param modes Indicates the pointer to the information about all modes supported by the display device, + * including all supported resolutions and refresh rates. Each mode has an ID, which will be used when + * the mode is set or obtained. For details, see {@link DisplayModeInfo}. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplaySupportedModes)(uint32_t devId, uint32_t *num, DisplayModeInfo *modes); + + /* * + * @brief Obtains the current display mode of a display device. + * + * @param devId Indicates the ID of the display device. + * @param modeId indicates the pointer to the ID of the current display mode of the device. The display mode ID + * is written by this API. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayMode)(uint32_t devId, uint32_t *modeId); + + /* * + * @brief Sets the display mode of a display device. + * + * @param devId Indicates the ID of the display device. + * @param modeId Indicates the ID of the display mode. The device is switched to the display mode specified by + * this parameter in this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayMode)(uint32_t devId, uint32_t modeId); + + /* * + * @brief Obtains the power status of a display device. + * + * @param devId Indicates the ID of the display device. + * @param status Indicates the pointer to the power status of the device. The status is written by this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayPowerStatus)(uint32_t devId, DispPowerStatus *status); + + /* * + * @brief Sets the power status of a display device. + * + * @param devId Indicates the ID of the display device. + * @param status Indicates the power status to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayPowerStatus)(uint32_t devId, DispPowerStatus status); + + /* * + * @brief Obtains the backlight value of a display device. + * + * @param devId Indicates the ID of the display device. + * @param level Indicates the pointer to the backlight value of the device. The backlight value is written + * by this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayBacklight)(uint32_t devId, uint32_t *level); + + /* * + * @brief Sets the backlight value for a display device. + * + * @param devId Indicates the ID of the display device. + * @param level Indicates the backlight value to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayBacklight)(uint32_t devId, uint32_t level); + + /* * + * @brief Obtains the property for a display device. + * + * @param devId Indicates the ID of the display device. + * @param id Indicates the property ID returned by GetDisplayCapability. + * @param value Indicates the property to get. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayProperty)(uint32_t devId, uint32_t id, uint64_t *value); + + /* * + * @brief Sets the property for a display device. + * + * @param devId Indicates the ID of the display device. + * @param id Indicates the property ID returned by GetDisplayCapability. + * @param value Indicates the property to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayProperty)(uint32_t devId, uint32_t id, uint64_t value); + + /* * + * @brief Prepares for the composition to be performed by a display device. + * + * Before the composition, the graphics service needs to notify the display device of the preparation to be made + * through this interface. + * + * @param devId Indicates the ID of the display device. + * @param needFlushFb Indicates the pointer that specifies whether the graphics service needs to reset the display + * framebuffer by using SetDisplayClientBuffer before the commit operation. + * The value true means that the framebuffer needs to be reset, and false means the opposite. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*PrepareDisplayLayers)(uint32_t devId, bool *needFlushFb); + + /* * + * @brief Obtains the layers whose composition types have changed. + * + * In the preparation for composition, the display device changes the composition type for each layer based on + * the composition capability of the device. This function returns the layers whose composition types have changed. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the pointer to the number of layers whose composition types have changed. + * @param Layers Indicates the pointer to the start address of the layer array. + * @param type Indicates the pointer to the start address of the composition type array. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayCompChange)(uint32_t devId, uint32_t *num, uint32_t *Layers, int32_t *type); + + /* * + * @brief Sets the cropped region for a display device. + * + * You can use this interface to set the cropped region of the client buffer of the display device. + * The cropped region cannot exceed the size of the client buffer. + * + * @param devId Indicates the ID of the display device. + * @param rect Indicates the pointer to the cropped region of the client buffer. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayClientCrop)(uint32_t devId, IRect *rect); + + /* * + * @brief Sets the display region for a display device. + * + * @param devId Indicates the ID of the display device. + * @param rect Indicates the pointer to the display region. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayClientDestRect)(uint32_t devId, IRect *rect); + + /* * + * @brief Sets the display buffer for a display device. + * + * The display buffer stores the hardware composition result of the display device. + * + * @param devId Indicates the ID of the display device. + * @param buffer Indicates the pointer to the display buffer. + * @param fence Indicates the sync fence that specifies whether the display buffer can be accessed. The display + * buffer is created and released by the graphics service. It can be accessed only when the sync fence is in the + * signaled state. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayClientBuffer)(uint32_t devId, const BufferHandle *buffer, int32_t fence); + + /* * + * @brief Sets the dirty region for a display device. + * + * The dirty region consists of multiple rectangular regions. The rectangular regions can be refreshed based on + * the settings. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the number of rectangles. + * @param rect Indicates the pointer to the start address of the rectangle array. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayClientDamage)(uint32_t devId, uint32_t num, IRect *rect); + + /* * + * @brief Enables or disables the vertical sync signal. + * + * When the vertical sync signal is generated, the VBlankCallback callback registered + * by RegDisplayVBlankCallback will be invoked. The vertical sync signal must be enabled when the graphics + * service needs to refresh the display, and disabled when display refresh is not required. The display does not + * need to refresh when VBlankCallback is invoked and the graphics service composes layers and sends the + * composition result to the device for display. + * + * @param devId Indicates the ID of the display device. + * @param enabled Specifies whether to enable the vertical sync signal. The value true means to enable the + * vertical sync signal, and false means to disable it. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode}otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayVsyncEnabled)(uint32_t devId, bool enabled); + + /* * + * @brief Obtains the fences of the display layers after the commit operation. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the pointer to the number of layers. + * @param layers Indicates the pointer to the start address of the layer array. + * @param fences Indicates the pointer to the start address of the fence array. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayReleaseFence)(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *fences); + + /* * + * @brief Obtains the color gamuts supported by a display device. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the pointer to the number of color gamuts supported by the display device. + * @param gamuts Indicates the pointer to the information about all color gamuts supported by the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplaySupportedColorGamuts)(uint32_t devId, uint32_t *num, ColorGamut *gamuts); + + /* * + * @brief Obtains the color gamut of a display device. + * + * @param devId Indicates the ID of the display device. + * @param gamut Indicates the pointer to the color gamut of the device. The color gamut is written + * by this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayColorGamut)(uint32_t devId, ColorGamut *gamut); + + /* * + * @brief Sets the color gamut for a display device. + * + * @param devId Indicates the ID of the display device. + * @param gamut Indicates the color gamut to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayColorGamut)(uint32_t devId, ColorGamut gamut); + + /* * + * @brief Obtains the gamut map of a display device. + * + * @param devId Indicates the ID of the display device. + * @param gamutMap Indicates the pointer to the gamut map of the device. The gamut map is written + * by this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayGamutMap)(uint32_t devId, GamutMap *gamutMap); + + /* * + * @brief Sets the gamut map for a display device. + * + * @param devId Indicates the ID of the display device. + * @param gamutMap Indicates the gamut map to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayGamutMap)(uint32_t devId, GamutMap gamutMap); + + /* * + * @brief Sets a 4x4 color transformation matrix for a display device. + * + * @param devId Indicates the ID of the display device. + * @param matrix Indicates the pointer to the 4x4 color transformation matrix to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetDisplayColorTransform)(uint32_t devId, const float *matrix); + + /* * + * @brief Obtains the HDR capability of a display device. + * + * @param devId Indicates the ID of the display device. + * @param info Indicates the pointer to the HDR capability of the device. The info is written + * by this interface. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetHDRCapabilityInfos)(uint32_t devId, HDRCapability *info); + + /* * + * @brief Obtains the HDR metadata keys supported by a display device. + * + * @param devId Indicates the ID of the display device. + * @param num Indicates the pointer to the number of metadata keys supported by the display device. + * @param keys Indicates the pointer to the information about all HDR metadata keys supported by the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetSupportedMetadataKey)(uint32_t devId, uint32_t *num, HDRMetadataKey *keys); + + /* * + * @brief Commits the request for composition and display. + * + * If there is a hardware composition layer, the composition is performed and the composition result is sent to + * the hardware for display. + * + * @param devId Indicates the ID of the display device. + * @param fences Indicates the pointer to the start address of the fence array. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*Commit)(uint32_t devId, int32_t *fence); + + /* * + * @brief Invokes the display device commands. + * + * This function extends the APIs between the graphics service and implementation layer, eliminating the need + * to add new APIs. + * + * @param devId Indicates the ID of the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*InvokeDisplayCmd)(uint32_t devId, ...); + + /* * + * @brief Creates a virtual display device. + * + * @param width Indicates the pixel width of the display device. + * @param height Indicates the pixel height of the display device. + * @param format Indicates the pointer to the pixel format of the display device. + * For details, see {@link PixelFormat}. The format can be modified based on hardware requirements and + * returned to the graphics service. + * @param devId Indicates the pointer to the ID of the virtual display device created. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*CreateVirtualDisplay)(uint32_t width, uint32_t height, int32_t *format, uint32_t *devId); + + /* * + * @brief Destroys a virtual display device. + * + * @param devId Indicates the ID of the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*DestroyVirtualDisplay)(uint32_t devId); + + /* * + * @brief Sets the output buffer for a virtual display device. + * + * This buffer stores the output of the virtual display device. The buffer can be used only after the sync fence + * is in the signaled state. + * + * @param devId Indicates the ID of the display device. + * @param buffer Indicates the pointer to the output buffer. + * @param fence Indicates the sync fence. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetVirtualDisplayBuffer)(uint32_t devId, BufferHandle *buffer, int32_t fence); + + /* * + * @brief Obtains the writeback frame of a display device. + * + * This function is used to obtain data of the writeback endpoint specified by devId. The data is written + * to the specified buffer by this interface. + * + * @param devId Indicates the ID of the display device. + * @param buffer Indicates the pointer to the buffer of the writeback endpoint data. + * @param fence Indicates the pointer to the sync fence. When calling this interface, the graphics service needs + * to pass the release fence of the buffer to + * specify whether data can be written to the buffer. Then, acquire fence of the buffer needs to be written + * and sent to the graphics service to specify whether the writeback data has been written to the buffer. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetWriteBackFrame)(uint32_t devId, BufferHandle *buffer, int32_t *fence); + + /* * + * @brief Creates a writeback endpoint for a display device. + * + * If the number of writeback endpoints exceeds the limit, a failure message will be returned. + * + * @param devId Indicates the pointer to the ID of the display device. After a writeback endpoint is created, the + * device ID of the writeback endpoint is written in this parameter and returned to the graphics service. + * @param width Indicates the writeback pixel width. + * @param height Indicates the writeback pixel height. + * @param format Indicates the pointer to the writeback point data format. For details, see {@link PixelFormat}. + * The format can be modified based on hardware requirements and returned to the graphics service. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*CreateWriteBack)(uint32_t *devId, uint32_t width, uint32_t height, int32_t *format); + + /* * + * @brief Destroys the writeback endpoint of a display device. + * + * @param devId Indicates the ID of the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*DestroyWriteBack)(uint32_t devId); +} DeviceFuncs; + +/** + * @brief Initializes the control functions of a display device. You can apply for resources for + * using control functions and then operate the display device by using the control functions. + * + * @param funcs Indicates the double pointer to the control functions of the display device. The caller obtains + * the double pointer to operate the display device. The memory is allocated during initialization, and therefore + * the caller does not need to allocate the memory. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * + * @since 1.0 + * @version 1.0 + */ +int32_t DeviceInitialize(DeviceFuncs **funcs); + +/** + * @brief Uninitializes control functions of the display device. The resources used by the control functions will be + * released. In other words, the memory allocated during initialization of the control functions will be released. + * + * @param funcs Indicates the double pointer to the control functions of the display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined + * in {@link DispErrCode} otherwise. + * @since 1.0 + * @version 1.0 + */ +int32_t DeviceUninitialize(DeviceFuncs *funcs); + +int32_t RegComposerDeathCallback(ComposerDeathCallback callback, void *data); + +#ifdef __cplusplus +} +#endif +#endif +/* @} */ diff --git a/display_server/drivers/interfaces/display_gralloc.h b/display_server/drivers/interfaces/display_gralloc.h new file mode 100644 index 0000000..48339fc --- /dev/null +++ b/display_server/drivers/interfaces/display_gralloc.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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. + */ + +/** + * @addtogroup Display + * @{ + * + * @brief Defines driver functions of the display module. + * + * This module provides driver functions for the graphics subsystem, including graphics layer management, + * device control, graphics hardware acceleration, display memory management, and callbacks. + * @since 1.0 + * @version 2.0 + */ + + +/** + * @file display_gralloc.h + * + * @brief Declares the driver functions for memory. + * + * @since 1.0 + * @version 2.0 + */ + +#ifndef DISPLAY_GRALLOC_H +#define DISPLAY_GRALLOC_H +#include "display_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines pointers to the memory driver functions. + */ +typedef struct { + /** + * @brief Allocates memory based on the parameters passed by the GUI. + * + * @param info Indicates the pointer to the description info of the memory to allocate. + * @param handle Indicates the double pointer to the buffer of the memory to allocate. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*AllocMem)(const AllocInfo* info, BufferHandle** handle); + + /** + * @brief Releases memory. + * + * @param handle Indicates the pointer to the buffer of the memory to release. + * + * @since 1.0 + * @version 1.0 + */ + void (*FreeMem)(BufferHandle *handle); + + /** + * @brief Maps memory to memory without cache in the process's address space. + * + * @param handle Indicates the pointer to the buffer of the memory to map. + * + * @return Returns the pointer to a valid address if the operation is successful; returns NULL otherwise. + * @since 1.0 + * @version 1.0 + */ + void *(*Mmap)(BufferHandle *handle); + + /** + * @brief Maps memory to memory with cache in the process's address space. + * + * @param handle Indicates the pointer to the buffer of the memory to map. + * + * @return Returns the pointer to a valid address if the operation is successful; returns NULL otherwise. + * @since 1.0 + * @version 1.0 + */ + void *(*MmapCache)(BufferHandle *handle); + + /** + * @brief Unmaps memory, that is, removes any mappings from the process's address space. + * + * @param handle Indicates the pointer to the buffer of the memory to unmap. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*Unmap)(BufferHandle *handle); + + /** + * @brief Flushes data from the cache to memory and invalidates the data in the cache. + * + * @param handle Indicates the pointer to the buffer of the cache to flush. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*FlushCache)(BufferHandle *handle); + + /** + * @brief Flushes data from the cache mapped via {@link Mmap} to memory and invalidates the data in the cache. + * + * @param handle Indicates the pointer to the buffer of the cache to flush. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*FlushMCache)(BufferHandle *handle); + + /** + * @brief Invalidates the cache to update it from memory. + * + * @param handle Indicates the pointer to the buffer of the cache, which will been invalidated. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*InvalidateCache)(BufferHandle* handle); + + /** + * @brief Checks whether the given VerifyAllocInfo array is allocatable. + * + * @param num Indicates the size of infos array. + * @param infos Indicates the pointer to the VerifyAllocInfo array. + * @param supporteds Indicates the pointer to the array that can be allocated. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*IsSupportedAlloc)(uint32_t num, const VerifyAllocInfo *infos, bool *supporteds); + + /** + * @brief Maps memory for YUV. + * + * @param handle Indicates the pointer to the buffer of the memory to map. + * @param info Indicates the pointer to the YUVDescInfo of the memory to map. + * + * @return Returns the pointer to a valid address if the operation is successful; returns NULL otherwise. + * @since 3.2 + * @version 1.0 + */ + void *(*MmapYUV)(BufferHandle *handle, YUVDescInfo *info); +} GrallocFuncs; + +/** + * @brief Initializes the memory module to obtain the pointer to functions for memory operations. + * + * @param funcs Indicates the double pointer to functions for memory operations. Memory is allocated automatically when + * you initiate the memory module initialization, so you can simply use the pointer to gain access to the functions. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ +int32_t GrallocInitialize(GrallocFuncs **funcs); + +/** + * @brief Deinitializes the memory module to release the memory allocated to the pointer to functions for memory + * operations. + * + * @param funcs Indicates the pointer to functions for memory operations. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ +int32_t GrallocUninitialize(GrallocFuncs *funcs); + +#ifdef __cplusplus +} +#endif +#endif +/** @} */ diff --git a/display_server/drivers/interfaces/display_layer.h b/display_server/drivers/interfaces/display_layer.h new file mode 100644 index 0000000..23b1bc1 --- /dev/null +++ b/display_server/drivers/interfaces/display_layer.h @@ -0,0 +1,811 @@ +/* + * Copyright (c) 2020-2021 Huawei Device 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. + */ + +/** + * @addtogroup Display + * @{ + * + * @brief Defines driver functions of the display module. + * + * This module provides driver functions for the graphics subsystem, including graphics layer management, + * device control, graphics hardware acceleration, display memory management, and callbacks. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file display_layer.h + * + * @brief Declares the driver functions for implementing layer operations. + * + * @since 1.0 + * @version 2.0 + */ + +#ifndef DISPLAY_LAYTER_H +#define DISPLAY_LAYTER_H +#include "display_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines pointers to the layer driver functions. + */ +typedef struct { + /** + * @brief Initializes a display device. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see DeinitDisplay + * @since 1.0 + * @version 1.0 + */ + int32_t (*InitDisplay)(uint32_t devId); + + /** + * @brief Deinitializes a display device. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see InitDisplay + * @since 1.0 + * @version 1.0 + */ + int32_t (*DeinitDisplay)(uint32_t devId); + + /** + * @brief Obtains information about a display device. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param dispInfo Indicates the pointer to the display device information obtained. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetDisplayInfo)(uint32_t devId, DisplayInfo *dispInfo); + + /** + * @brief Opens a layer on a specified display device. + * + * Before using a layer on the GUI, you must open the layer based on the layer information. After the layer is + * opened, you can obtain the layer ID and then use other functions based on the layer ID. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerInfo Indicates the pointer to the layer information passed to open a layer, including the layer + * type, layer size, and pixel format. + * @param layerId Indicates the pointer to the layer ID, which uniquely identifies a layer. The layer ID is returned + * to the GUI after the layer is successfully opened. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see CloseLayer + * @since 1.0 + * @version 1.0 + */ + + int32_t (*CreateLayer)(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId); + /** + * @brief Closes a layer that is no longer required on a specified display device. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see OpenLayer + * @since 1.0 + * @version 1.0 + */ + int32_t (*CloseLayer)(uint32_t devId, uint32_t layerId); + + /** + * @brief Sets whether a layer is visible. + * + * A visible layer is displayed on the screen, whereas an invisible layer is not displayed on the screen. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param visible Indicates the visibility to set for the layer. The value true means to set the layer to be + * visible, and false means the opposite. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerVisibleState + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerVisible)(uint32_t devId, uint32_t layerId, bool visible); + + /** + * @brief Checks whether a layer is visible. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param visible Indicates the pointer to the obtained layer visibility. The value true indicates that the + * layer is visible, and false indicates that the layer is invisible. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerVisible + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerVisibleState)(uint32_t devId, uint32_t layerId, bool *visible); + + /** + * @brief Sets the size of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param rect Indicates the pointer to the layer size to set, in pixels. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerSize + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerSize)(uint32_t devId, uint32_t layerId, IRect *rect); + + /** + * @brief Obtains the size of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param rect Indicates the pointer to the obtained layer size. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerSize + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerSize)(uint32_t devId, uint32_t layerId, IRect *rect); + + /** + * @brief Sets the rectangular area to crop for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param rect Indicates the pointer to the rectangular area to crop. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerCrop)(uint32_t devId, uint32_t layerId, IRect *rect); + + /** + * @brief Sets the z-order for a layer. + * + * A larger z-order value indicates a higher layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param zorder Indicates the z-order to set. The value is an integer ranging from 0 to 255. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerZorder + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerZorder)(uint32_t devId, uint32_t layerId, uint32_t zorder); + + /** + * @brief Obtains the z-order of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param zorder Indicates the pointer to the obtained z-order. The value is an integer ranging from 0 to 255. + * A larger z-order value indicates a higher layer. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerZorder + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerZorder)(uint32_t devId, uint32_t layerId, uint32_t *zorder); + + /** + * @brief Sets layer premultiplication. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param preMul Specifies whether to enable layer premultiplication. The value 1 means to enable layer + * premultiplication, and 0 means the opposite. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerPreMulti + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerPreMulti)(uint32_t devId, uint32_t layerId, bool preMul); + + /** + * @brief Obtains the premultiplication flag of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param preMul Indicates the pointer to the obtained layer premultiplication flag. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerPreMulti + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerPreMulti)(uint32_t devId, uint32_t layerId, bool *preMul); + + /** + * @brief Sets the alpha value for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param alpha Indicates the pointer to the alpha value to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerAlpha + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerAlpha)(uint32_t devId, uint32_t layerId, LayerAlpha *alpha); + + /** + * @brief Obtains the alpha value of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param alpha Indicates the pointer to the obtained alpha value. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerAlpha + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerAlpha)(uint32_t devId, uint32_t layerId, LayerAlpha *alpha); + + /** + * @brief Sets the color key for a layer. The color key is used during layer overlay. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param enable Specify whether to enable the color key. + * @param key Indicates the color key. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerColorKey + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerColorKey)(uint32_t devId, uint32_t layerId, bool enable, uint32_t key); + + /** + * @brief Obtains the color key of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param enable Indicates the pointer to the color key enable bit. + * @param key Indicates the pointer to the color key. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerColorKey + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerColorKey)(uint32_t devId, uint32_t layerId, bool *enable, uint32_t *key); + + /** + * @brief Sets the palette for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param palette Indicates the pointer to the palette to set. + * @param len Indicates the length of the palette. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerPalette + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerPalette)(uint32_t devId, uint32_t layerId, uint32_t *palette, uint32_t len); + + /** + * @brief Obtains the palette of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param palette Indicates the pointer to the obtained palette. + * @param len Indicates the length of the palette. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerPalette + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerPalette)(uint32_t devId, uint32_t layerId, uint32_t *palette, uint32_t len); + + /** + * @brief Sets the transform mode for rotating, scaling, or moving a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param type Indicates the transformation mode to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetTransformMode)(uint32_t devId, uint32_t layerId, TransformType type); + + /** + * @brief Sets the compression feature for a layer. + * + * In specific scenarios, images need to be compressed. You can set whether to enable layer compression. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param compType Specifies whether to enable the compression feature. The value true>/b> means to enable + * compression, and false> means the opposite. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see GetLayerCompression + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerCompression)(uint32_t devId, uint32_t layerId, int32_t compType); + + /** + * @brief Checks whether the compression feature is enabled for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param compType Indicates the pointer to the variable specifying whether the compression feature is enabled. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see SetLayerCompression + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerCompression)(uint32_t devId, uint32_t layerId, int32_t *compType); + + /** + * @brief Sets the flushing area for a layer. + * + * After the GUI draws an image, you must set the layer flushing area before calling the {@link Flush} function to + * flush the screen. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param region Indicates the pointer to the flushing area to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerDirtyRegion)(uint32_t devId, uint32_t layerId, IRect *region); + + /** + * @brief Obtains the buffer of a layer. + * + * After drawing a picture in the buffer, the application calls the {@link Flush} function to display the picture + * on the screen. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param buffer Indicates the pointer to the obtained buffer. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see Flush + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerBuffer)(uint32_t devId, uint32_t layerId, LayerBuffer *buffer); + + /** + * @brief Flushes a layer. + * + * Display data in the buffer is flushed to a specified layer so that the image data is displayed on the screen. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param buffer Indicates the pointer to the buffer in which the display data is to flush. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*Flush)(uint32_t devId, uint32_t layerId, LayerBuffer *buffer); + + /** + * @brief Waits for the arrival of vertical blanking. + * + * This function blocks the process until vertical blanking arrives, implementing the synchronization between + * software and hardware. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param timeOut Indicates the maximum duration that the process waits for the arrival of vertical blanking. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*WaitForVBlank)(uint32_t devId, uint32_t layerId, int32_t timeOut); + + /** + * @brief Implements the snapshot feature. + * + * This function saves the screenshot of image data on the display device to the buffer for debugging or as + * requested by applications. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param buffer Indicates the pointer to the buffer for saving screenshots. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SnapShot)(uint32_t devId, LayerBuffer *buffer); + + /** + * @brief Set the visible region for a layer + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param num Indicates the count of rect. the region contains multiple IRect, the num means how much rects in the + * region. + * @param rect Indicates the pointer of the rectes. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 2.0 + * @version 2.0 + */ + int32_t (*SetLayerVisibleRegion)(uint32_t devId, uint32_t layerId, uint32_t num, IRect *rect); + + /** + * @brief Set the buffer for a layer. + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param buffer Indicates the pointer of the buffer handle. The buffer handle should contain all information of the + * buffer which will be used for composition. + * @param fence Indicates the fd of a sync file. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 2.0 + * @version 2.0 + */ + int32_t (*SetLayerBuffer)(uint32_t devId, uint32_t layerId, const BufferHandle *buffer, int32_t fence); + + /** + * @brief Extension interface + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param cmd Indicates extension cmd to be used to identify different intention. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 2.0 + * @version 2.0 + */ + int32_t (*InvokeLayerCmd)(uint32_t devId, uint32_t layerId, uint32_t cmd, ...); + + /** + * @brief set the composition type which the client expect + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param type Indicates the composition type which the client expect. It may vary with the implementation. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 2.0 + * @version 2.0 + */ + int32_t (*SetLayerCompositionType)(uint32_t devId, uint32_t layerId, CompositionType type); + + /** + * @brief set the blend type + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param type Indicates blend type + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 2.0 + * @version 2.0 + */ + int32_t (*SetLayerBlendType)(uint32_t devId, uint32_t layerId, BlendType type); + + /** + * @brief Sets a 4x4 color transformation matrix. + * + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param matrix Indicates the 4x4 color transformation matrix. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerColorTransform)(uint32_t devId, uint32_t layerId, const float *matrix); + + /** + * @brief Sets a color data space for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param colorSpace Indicates the color data space to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerColorDataSpace)(uint32_t devId, uint32_t layerId, ColorDataSpace colorSpace); + + /** + * @brief Obtains the color data space of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param colorSpace Indicates the pointer to the color data space obtained. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetLayerColorDataSpace)(uint32_t devId, uint32_t layerId, ColorDataSpace *colorSpace); + + /** + * @brief Sets metadata for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param num Indicates the number of metadata records. + * @param metaData Indicates the pointer to the metadata to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerMetaData)(uint32_t devId, uint32_t layerId, uint32_t num, const HDRMetaData *metaData); + + /** + * @brief Sets a metadata set for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param key Indicates the metadata key. + * @param num Indicates the number of metadata records. + * @param metaData Indicates the pointer to the metadata set of the uint8_t type to set. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*SetLayerMetaDataSet)(uint32_t devId, uint32_t layerId, HDRMetadataKey key, uint32_t num, + const uint8_t *metaData); + + /** + * @brief Obtains the hardware display present timestamp type supported by a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param type Indicates the pointer to the present timestamp type obtained. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetSupportedPresentTimestamp)(uint32_t devId, uint32_t layerId, PresentTimestampType *type); + + /** + * @brief Obtains the hardware display present timestamp of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param pts Indicates the pointer to the present timestamp obtained. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 1.0 + * @version 1.0 + */ + int32_t (*GetHwPresentTimestamp)(uint32_t devId, uint32_t layerId, PresentTimestamp *pts); + /** + * @brief Sets a tunnel handle for a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param handle Indicates the handle of ExtDataHandle. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 3.2 + * @version 1.0 + */ + int32_t (*SetLayerTunnelHandle)(uint32_t devId, uint32_t layerId, ExtDataHandle *handle); + /** + * @brief Obtains the release fence of a layer. + * + * @param devId Indicates the ID of the display device. The value ranges from 0 to 4, where 0 indicates the first + * display device, and 4 indicates the last display device. + * @param layerId Indicates the layer ID, which uniquely identifies a layer. You can perform operations on the layer + * with the specified layer ID. + * @param fence Indicates the pointer to the release fence obtained. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @since 3.2 + * @version 1.0 + */ + int32_t (*GetLayerReleaseFence)(uint32_t devId, uint32_t layerId, int32_t *fence); +} LayerFuncs; + +/** + * @brief Initializes the layer to apply for resources used by the layer and obtain the pointer to functions for + * layer operations. + * + * @param funcs Indicates the double pointer to functions for layer operations. Memory is allocated automatically when + * you initiate the layer module, so you can simply use the pointer to gain access to the functions. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see LayerUninitialize + * @since 1.0 + * @version 1.0 + */ +int32_t LayerInitialize(LayerFuncs **funcs); + +/** + * @brief Deinitializes the layer module to release the memory allocated to the pointer to functions for + * layer operations. + * + * @param funcs Indicates the pointer to functions for layer operations. + * + * @return Returns 0 if the operation is successful; returns an error code defined in {@link DispErrCode} + * otherwise. + * @see LayerInitialize + * @since 1.0 + * @version 1.0 + */ +int32_t LayerUninitialize(LayerFuncs *funcs); + +#ifdef __cplusplus +} +#endif +#endif +/** @} */ diff --git a/display_server/drivers/interfaces/display_type.h b/display_server/drivers/interfaces/display_type.h new file mode 100644 index 0000000..d36bcdd --- /dev/null +++ b/display_server/drivers/interfaces/display_type.h @@ -0,0 +1,689 @@ +/* + * Copyright (c) 2021-2022 Huawei Device 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. + */ + +/** + * @addtogroup Display + * @{ + * + * @brief Defines driver functions of the display module. + * + * This module provides driver functions for the graphics subsystem, including graphics layer management, + * device control, graphics hardware acceleration, display memory management, and callbacks. + * + * @since 1.0 + * @version 2.0 + */ + +/** + * @file display_type.h + * + * @brief Declares the data types used by the display driver functions. + * + * @since 1.0 + * @version 2.0 + */ + +#ifndef DISPLAY_TYPE_H +#define DISPLAY_TYPE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "buffer_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerates return values of the functions. + * + */ +typedef enum { + DISPLAY_SUCCESS = 0, /**< Success */ + DISPLAY_FAILURE = -1, /**< Failure */ + DISPLAY_FD_ERR = -2, /**< File handle (FD) error */ + DISPLAY_PARAM_ERR = -3, /**< Parameter error */ + DISPLAY_NULL_PTR = -4, /**< Null pointer */ + DISPLAY_NOT_SUPPORT = -5, /**< Unsupported feature */ + DISPLAY_NOMEM = -6, /**< Insufficient memory */ + DISPLAY_SYS_BUSY = -7, /**< System busy */ + DISPLAY_NOT_PERM = -8 /**< Forbidden operation */ +} DispErrCode; + +/** + * @brief Enumerates layer types. + * + */ +typedef enum { + LAYER_TYPE_GRAPHIC, /**< Graphic layer */ + LAYER_TYPE_OVERLAY, /**< Overlay layer */ + LAYER_TYPE_SIDEBAND, /**< Sideband layer */ + LAYER_TYPE_CURSOR, /**< Cursor Layer */ + LAYER_TYPE_BUTT /**< Empty layer */ +} LayerType; + +/* * + * @brief Defines the buffer usage. + * + */ +typedef enum { + HBM_USE_CPU_READ = (1ULL << 0), /**< CPU read buffer */ + HBM_USE_CPU_WRITE = (1ULL << 1), /**< CPU write memory */ + HBM_USE_MEM_MMZ = (1ULL << 2), /**< Media memory zone (MMZ) */ + HBM_USE_MEM_DMA = (1ULL << 3), /**< Direct memory access (DMA) buffer */ + HBM_USE_MEM_SHARE = (1ULL << 4), /**< Shared memory buffer*/ + HBM_USE_MEM_MMZ_CACHE = (1ULL << 5), /**< MMZ with cache*/ + HBM_USE_MEM_FB = (1ULL << 6), /**< Framebuffer */ + HBM_USE_ASSIGN_SIZE = (1ULL << 7), /**< Memory assigned */ + HBM_USE_HW_RENDER = (1ULL << 8), /**< For GPU write case */ + HBM_USE_HW_TEXTURE = (1ULL << 9), /**< For GPU read case */ + HBM_USE_HW_COMPOSER = (1ULL << 10), /**< For hardware composer */ + HBM_USE_PROTECTED = (1ULL << 11), /**< For safe buffer case, such as DRM */ + HBM_USE_CAMERA_READ = (1ULL << 12), /**< For camera read case */ + HBM_USE_CAMERA_WRITE = (1ULL << 13), /**< For camera write case */ + HBM_USE_VIDEO_ENCODER = (1ULL << 14), /**< For encode case */ + HBM_USE_VIDEO_DECODER = (1ULL << 15), /**< For decode case */ + HBM_USE_VENDOR_PRI0 = (1ULL << 44), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI1 = (1ULL << 45), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI2 = (1ULL << 46), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI3 = (1ULL << 47), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI4 = (1ULL << 48), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI5 = (1ULL << 49), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI6 = (1ULL << 50), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI7 = (1ULL << 51), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI8 = (1ULL << 52), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI9 = (1ULL << 53), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI10 = (1ULL << 54), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI11 = (1ULL << 55), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI12 = (1ULL << 56), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI13 = (1ULL << 57), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI14 = (1ULL << 58), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI15 = (1ULL << 59), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI16 = (1ULL << 60), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI17 = (1ULL << 61), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI18 = (1ULL << 62), /**< Reserverd for vendor */ + HBM_USE_VENDOR_PRI19 = (1ULL << 63), /**< Reserverd for vendor */ +} DisplayBufferUsage; + +/** + * @brief Enumerates pixel formats. + * + */ +typedef enum { + PIXEL_FMT_CLUT8 = 0, /**< CLUT8 format */ + PIXEL_FMT_CLUT1, /**< CLUT1 format */ + PIXEL_FMT_CLUT4, /**< CLUT4 format */ + PIXEL_FMT_RGB_565, /**< RGB565 format */ + PIXEL_FMT_RGBA_5658, /**< RGBA5658 format */ + PIXEL_FMT_RGBX_4444, /**< RGBX4444 format */ + PIXEL_FMT_RGBA_4444, /**< RGBA4444 format */ + PIXEL_FMT_RGB_444, /**< RGB444 format */ + PIXEL_FMT_RGBX_5551, /**< RGBX5551 format */ + PIXEL_FMT_RGBA_5551, /**< RGBA5551 format */ + PIXEL_FMT_RGB_555, /**< RGB555 format */ + PIXEL_FMT_RGBX_8888, /**< RGBX8888 format */ + PIXEL_FMT_RGBA_8888, /**< RGBA8888 format */ + PIXEL_FMT_RGB_888, /**< RGB888 format */ + PIXEL_FMT_BGR_565, /**< BGR565 format */ + PIXEL_FMT_BGRX_4444, /**< BGRX4444 format */ + PIXEL_FMT_BGRA_4444, /**< BGRA4444 format */ + PIXEL_FMT_BGRX_5551, /**< BGRX5551 format */ + PIXEL_FMT_BGRA_5551, /**< BGRA5551 format */ + PIXEL_FMT_BGRX_8888, /**< BGRX8888 format */ + PIXEL_FMT_BGRA_8888, /**< BGRA8888 format */ + PIXEL_FMT_YUV_422_I, /**< YUV422 interleaved format */ + PIXEL_FMT_YCBCR_422_SP, /**< YCBCR422 semi-planar format */ + PIXEL_FMT_YCRCB_422_SP, /**< YCRCB422 semi-planar format */ + PIXEL_FMT_YCBCR_420_SP, /**< YCBCR420 semi-planar format */ + PIXEL_FMT_YCRCB_420_SP, /**< YCRCB420 semi-planar format */ + PIXEL_FMT_YCBCR_422_P, /**< YCBCR422 planar format */ + PIXEL_FMT_YCRCB_422_P, /**< YCRCB422 planar format */ + PIXEL_FMT_YCBCR_420_P, /**< YCBCR420 planar format */ + PIXEL_FMT_YCRCB_420_P, /**< YCRCB420 planar format */ + PIXEL_FMT_YUYV_422_PKG, /**< YUYV422 packed format */ + PIXEL_FMT_UYVY_422_PKG, /**< UYVY422 packed format */ + PIXEL_FMT_YVYU_422_PKG, /**< YVYU422 packed format */ + PIXEL_FMT_VYUY_422_PKG, /**< VYUY422 packed format */ + PIXEL_FMT_VENDER_MASK = 0X7FFF0000, /**< vendor mask format */ + PIXEL_FMT_BUTT = 0X7FFFFFFF /**< Invalid pixel format */ +} PixelFormat; + +/** + * @brief Enumerates transform types of images. + * + */ +typedef enum { + ROTATE_NONE = 0, /**< No rotation */ + ROTATE_90, /**< Rotation by 90 degrees */ + ROTATE_180, /**< Rotation by 180 degrees */ + ROTATE_270, /**< Rotation by 270 degrees */ + MIRROR_H, /**< Mirror transform horizontally */ + MIRROR_V, /**< Mirror transform vertically */ + MIRROR_H_ROTATE_90, /**< Mirror transform horizontally, rotation by 90 degrees */ + MIRROR_V_ROTATE_90, /**< Mirror transform vertically, rotation by 90 degrees */ + ROTATE_BUTT /**< Invalid operation */ +} TransformType; + +/** + * @brief Enumerates image blending types. + * + * The system combines images based on a specified blending type during hardware acceleration. + * + */ +typedef enum { + BLEND_NONE = 0, /**< No blending */ + BLEND_CLEAR, /**< CLEAR blending */ + BLEND_SRC, /**< SRC blending */ + BLEND_SRCOVER, /**< SRC_OVER blending */ + BLEND_DSTOVER, /**< DST_OVER blending */ + BLEND_SRCIN, /**< SRC_IN blending */ + BLEND_DSTIN, /**< DST_IN blending */ + BLEND_SRCOUT, /**< SRC_OUT blending */ + BLEND_DSTOUT, /**< DST_OUT blending */ + BLEND_SRCATOP, /**< SRC_ATOP blending */ + BLEND_DSTATOP, /**< DST_ATOP blending */ + BLEND_ADD, /**< ADD blending */ + BLEND_XOR, /**< XOR blending */ + BLEND_DST, /**< DST blending */ + BLEND_AKS, /**< AKS blending */ + BLEND_AKD, /**< AKD blending */ + BLEND_BUTT /**< Null operation */ +} BlendType; + +/** + * @brief Enumerates ROP types supported by hardware acceleration. + * + * ROP performs bitwise Boolean operations (including bitwise AND and bitwise OR) on the RGB color and + * alpha values of the foreground bitmap with those of the background bitmap, and then outputs the result. + * + */ +typedef enum { + ROP_BLACK = 0, /**< Blackness */ + ROP_NOTMERGEPEN, /**< ~(S2+S1) */ + ROP_MASKNOTPEN, /**< ~S2&S1 */ + ROP_NOTCOPYPEN, /**< ~S2 */ + ROP_MASKPENNOT, /**< S2&~S1 */ + ROP_NOT, /**< ~S1 */ + ROP_XORPEN, /**< S2^S1 */ + ROP_NOTMASKPEN, /**< ~(S2&S1) */ + ROP_MASKPEN, /**< S2&S1 */ + ROP_NOTXORPEN, /**< ~(S2^S1) */ + ROP_NOP, /**< S1 */ + ROP_MERGENOTPEN, /**< ~S2+S1 */ + ROP_COPYPE, /**< S2 */ + ROP_MERGEPENNOT, /**< S2+~S1 */ + ROP_MERGEPEN, /**< S2+S1 */ + ROP_WHITE, /**< Whiteness */ + ROP_BUTT /**< Invalid ROP type */ +} RopType; + +/** + * @brief Enumerates color key types supported by hardware acceleration. + * + */ +typedef enum { + CKEY_NONE = 0, /**< No color key */ + CKEY_SRC, /**< Source color key */ + CKEY_DST, /**< Destination color key */ + CKEY_BUTT /**< Null operation */ +} ColorKey; + +/** + * @brief Enumerates mirror types supported by hardware acceleration. + * + */ +typedef enum { + MIRROR_NONE = 0, /**< No mirror */ + MIRROR_LR, /**< Left and right mirrors */ + MIRROR_TB, /**< Top and bottom mirrors */ + MIRROR_BUTT /**< Null operation */ +} MirrorType; + +/** + * @brief Enumerates connection types of hot plugging. + * + */ +typedef enum { + CON_INVALID = 0, /**< Invalid connection */ + CONNECTED, /**< Connected */ + DISCONNECTED /**< Disconnected */ +} Connection; + +/** + * @brief Defines display information. + * + */ +typedef struct { + uint32_t width; /**< Display width */ + uint32_t height; /**< Display height */ + int32_t rotAngle; /**< Rotation angle of the display */ +} DisplayInfo; + +/** + * @brief Defines layer information. + * + * LayerInfo must be passed to the {@link OpenLayer} function, which creates a layer based on the layer + * information. + * + */ +typedef struct { + int32_t width; /**< Layer width */ + int32_t height; /**< Layer height */ + LayerType type; /**< Layer type, which can be a graphic layer, overlay layer, or sideband layer */ + int32_t bpp; /**< Number of bits occupied by each pixel */ + PixelFormat pixFormat; /**< Pixel format of the layer */ +} LayerInfo; + +/** + * @brief Defines alpha information about a layer. + * + */ +typedef struct { + bool enGlobalAlpha; /**< Global alpha enable bit */ + bool enPixelAlpha; /**< Pixel alpha enable bit */ + uint8_t alpha0; /**< Alpha0 value, ranging from 0 to 255 */ + uint8_t alpha1; /**< Alpha1 value, ranging from 0 to 255 */ + uint8_t gAlpha; /**< Global alpha value, ranging from 0 to 255 */ +} LayerAlpha; + + +/** + * @brief Defines buffer data of a layer, including the virtual and physical memory addresses. + * + */ +typedef struct { + uint64_t phyAddr; /**< Physical memory address */ + void *virAddr; /**< Virtual memory address */ +} BufferData; + +/** + * @brief Defines the buffer, which is used to store layer data. + * + */ +typedef struct { + int32_t fenceId; /**< Fence ID of the buffer */ + int32_t width; /**< Buffer width */ + int32_t height; /**< Buffer height */ + int32_t pitch; /**< Number of bytes from one row of pixels in memory to the next */ + PixelFormat pixFormat; /**< Pixel format of the buffer */ + BufferData data; /**< Layer buffer data */ + BufferHandle* hdl; /**< Layer buffer handle */ +} LayerBuffer; + +/** + * @brief Defines the information about a rectangle. + * + */ +typedef struct { + int32_t x; /**< Start X coordinate of the rectangle */ + int32_t y; /**< Start Y coordinate of the rectangle */ + int32_t w; /**< Width of the rectangle */ + int32_t h; /**< Height of the rectangle */ +} IRect; + +/** + * @brief Stores surface information for hardware acceleration, such as draw image and bit blit. + * + */ +typedef struct { + uint64_t phyAddr; /**< Start physical address of an image */ + int32_t height; /**< Image height */ + int32_t width; /**< Image width */ + int32_t stride; /**< Image stride */ + PixelFormat enColorFmt; /**< Image format */ + bool bYCbCrClut; /**< Whether the color lookup table (CLUT) is in the YCbCr space */ + bool bAlphaMax255; /**< Maximum alpha value of an image (255 or 128) */ + bool bAlphaExt1555; /**< ARGB1555 alpha extension enable bit */ + uint8_t alpha0; /**< Value of alpha0, ranging from 0 to 255 */ + uint8_t alpha1; /**< Value of alpha1, ranging from 0 to 255 */ + uint64_t cbcrPhyAddr; /**< CbCr physical address */ + int32_t cbcrStride; /**< CbCr stride */ + uint64_t clutPhyAddr; /**< Start physical address of the CLUT, used for color extension or correction */ +} ISurface; + +/** + * @brief Describes a line to help draw lines in hardware acceleration. + * + */ +typedef struct { + int32_t x0; /**< X coordinate of the start point of a line */ + int32_t y0; /**< Y coordinate of the start point of a line */ + int32_t x1; /**< X coordinate of the end point of a line */ + int32_t y1; /**< Y coordinate of the end point of a line */ + uint32_t color; /**< Line color */ +} ILine; + +/** + * @brief Describes a circle to help draw circles in hardware acceleration. + * + */ +typedef struct { + int32_t x; /**< X coordinate of a circle center */ + int32_t y; /**< Y coordinate of a circle center */ + int32_t r; /**< Radius of a circle */ + uint32_t color; /**< Circle color */ +} ICircle; + +/** + * @brief Describes a rectangle to help draw rectangles in hardware acceleration. + * + */ +typedef struct { + IRect rect; /**< Bounds of a rectangle */ + uint32_t color; /**< Rectangle color */ +} Rectangle; + +/** + * @brief Defines hardware acceleration options. + * + */ +typedef struct { + bool enGlobalAlpha; /**< Global alpha enable bit */ + uint32_t globalAlpha; /**< Global alpha value */ + bool enPixelAlpha; /**< Pixel alpha enable bit */ + BlendType blendType; /**< Blending type */ + ColorKey colorKeyFrom; /**< Color key mode */ + bool enableRop; /**< Raster operations pipeline (ROP) enable bit */ + RopType colorRopType; /**< Color ROP type */ + RopType alphaRopType; /**< Alpha ROP type */ + bool enableScale; /**< Scaling enable bit */ + TransformType rotateType; /**< Rotation type */ + MirrorType mirrorType; /**< Mirror type */ +} GfxOpt; + +#define PROPERTY_NAME_LEN 50 + +/** + * @brief Defines property object which contains name, property id and value. + * + */ +typedef struct { + char name[PROPERTY_NAME_LEN]; /**< Name of the property */ + uint32_t propId; /**< Property id which was decided in the DRM internal */ + uint64_t value; /**< the value of property */ +} PropertyObject; + +/** + * @brief Enumerates interface types. + * + */ +typedef enum { + DISP_INTF_HDMI = 0, /**< HDMI interface */ + DISP_INTF_LCD, /**< LCD interface */ + DISP_INTF_BT1120, /**< BT1120 interface */ + DISP_INTF_BT656, /**< BT656 interface */ + DISP_INTF_YPBPR, /**< YPBPR interface */ + DISP_INTF_RGB, /**< RGB interface */ + DISP_INTF_CVBS, /**< CVBS interface */ + DISP_INTF_SVIDEO, /**< SVIDEO interface */ + DISP_INTF_VGA, /**< VGA interface */ + DISP_INTF_MIPI, /**< MIPI interface */ + DISP_INTF_PANEL, /**< PANEL interface */ + DISP_INTF_BUTT, +} InterfaceType; + +/** + * @brief Defines the capability of the output. + */ +typedef struct { + char name[PROPERTY_NAME_LEN]; /**< Name of the display device */ + InterfaceType type; /**< Interface type of panel */ + uint32_t phyWidth; /**< Physical width */ + uint32_t phyHeight; /**< Physical height */ + uint32_t supportLayers; /**< Number of supported layers */ + uint32_t virtualDispCount; /**< Count of virtual displays supported */ + bool supportWriteBack; /**< Whether writeback is supported */ + uint32_t propertyCount; /**< Count of properties */ + PropertyObject* props; /**< Array of property objects */ +} DisplayCapability; + +/** + * @brief Defines output mode info. + */ +typedef struct { + int32_t width; /**< Width in pixel */ + int32_t height; /**< Height in pixel */ + uint32_t freshRate; /**< Fresh rate per second */ + int32_t id; /**< ID of the mode */ +} DisplayModeInfo; + +/** + * @brief Defines information about the memory to allocate. + * + */ +typedef struct { + uint32_t width; /**< Width of the requested memory */ + uint32_t height; /**< Height of the requested memory */ + uint64_t usage; /**< Usage of the requested memory */ + PixelFormat format; /**< Format of the requested memory */ + uint32_t expectedSize; /**< Size assigned by memory requester */ +} AllocInfo; +/** + * @brief Enumerates power status. + */ + +typedef enum { + POWER_STATUS_ON, /**< The power status is on. */ + POWER_STATUS_STANDBY, /**< The power status is standby. */ + POWER_STATUS_SUSPEND, /**< The power status is suspended. */ + POWER_STATUS_OFF, /**< The power status is off. */ + POWER_STATUS_BUTT +} DispPowerStatus; + +/** + * @brief Enumerates the composition types of the special layer. + */ +typedef enum { + COMPOSITION_CLIENT, /**< Client composition type. The composer should be the CPU or GPU. */ + COMPOSITION_DEVICE, /**< Device composition type. The composer should be the hardware. */ + COMPOSITION_CURSOR, /**< Cursor composition type, used for cursor. */ + COMPOSITION_VIDEO, /**< Cursor composition type, used for video. */ + COMPOSITION_DEVICE_CLEAR, /**< Device clear composition type, the device will clear the target region. */ + COMPOSITION_CLIENT_CLEAR, /**< Client clear composition type, the service will clear the target region. */ + COMPOSITION_TUNNEL, /**< Tunnel composition type, used for tunnel. */ + COMPOSITION_BUTT +} CompositionType; + +/** + * @brief Enumerates the color gamuts. + * + */ +typedef enum { + COLOR_GAMUT_INVALID = -1, /**< Invalid */ + COLOR_GAMUT_NATIVE = 0, /**< Native or default */ + COLOR_GAMUT_STANDARD_BT601 = 1, /**< Standard BT601 */ + COLOR_GAMUT_STANDARD_BT709 = 2, /**< Standard BT709 */ + COLOR_GAMUT_DCI_P3 = 3, /**< DCI P3 */ + COLOR_GAMUT_SRGB = 4, /**< SRGB */ + COLOR_GAMUT_ADOBE_RGB = 5, /**< Adobe RGB */ + COLOR_GAMUT_DISPLAY_P3 = 6, /**< display P3 */ + COLOR_GAMUT_BT2020 = 7, /**< BT2020 */ + COLOR_GAMUT_BT2100_PQ = 8, /**< BT2100 PQ */ + COLOR_GAMUT_BT2100_HLG = 9, /**< BT2100 HLG */ + COLOR_GAMUT_DISPLAY_BT2020 = 10, /**< Display BT2020 */ +} ColorGamut; + +/** + * @brief Enumerates the color gamut maps. + * + */ +typedef enum { + GAMUT_MAP_CONSTANT = 0, + GAMUT_MAP_EXPANSION = 1, + GAMUT_MAP_HDR_CONSTANT = 2, + GAMUT_MAP_HDR_EXPANSION = 3, +} GamutMap; + +/** + * @brief Enumerates the color data spaces. + * + */ + +typedef enum { + COLOR_DATA_SPACE_UNKNOWN = 0, + GAMUT_BT601 = 0x00000001, + GAMUT_BT709 = 0x00000002, + GAMUT_DCI_P3 = 0x00000003, + GAMUT_SRGB = 0x00000004, + GAMUT_ADOBE_RGB = 0x00000005, + GAMUT_DISPLAY_P3 = 0x00000006, + GAMUT_BT2020 = 0x00000007, + GAMUT_BT2100_PQ = 0x00000008, + GAMUT_BT2100_HLG = 0x00000009, + GAMUT_DISPLAY_BT2020 = 0x0000000a, + TRANSFORM_FUNC_UNSPECIFIED = 0x00000100, + TRANSFORM_FUNC_LINEAR = 0x00000200, + TRANSFORM_FUNC_SRGB = 0x00000300, + TRANSFORM_FUNC_SMPTE_170M = 0x00000400, + TRANSFORM_FUNC_GM2_2 = 0x00000500, + TRANSFORM_FUNC_GM2_6 = 0x00000600, + TRANSFORM_FUNC_GM2_8 = 0x00000700, + TRANSFORM_FUNC_ST2084 = 0x00000800, + TRANSFORM_FUNC_HLG = 0x00000900, + PRECISION_UNSPECIFIED = 0x00010000, + PRECISION_FULL = 0x00020000, + PRESION_LIMITED = 0x00030000, + PRESION_EXTENDED = 0x00040000, + BT601_SMPTE170M_FULL = GAMUT_BT601 | TRANSFORM_FUNC_SMPTE_170M | PRECISION_FULL, + BT601_SMPTE170M_LIMITED = GAMUT_BT601 | TRANSFORM_FUNC_SMPTE_170M | PRESION_LIMITED, + BT709_LINEAR_FULL = GAMUT_BT709 | TRANSFORM_FUNC_LINEAR | PRECISION_FULL, + BT709_LINEAR_EXTENDED = GAMUT_BT709 | TRANSFORM_FUNC_LINEAR | PRESION_EXTENDED, + BT709_SRGB_FULL = GAMUT_BT709 | TRANSFORM_FUNC_SRGB | PRECISION_FULL, + BT709_SRGB_EXTENDED = GAMUT_BT709 | TRANSFORM_FUNC_SRGB | PRESION_EXTENDED, + BT709_SMPTE170M_LIMITED = GAMUT_BT709 | TRANSFORM_FUNC_SMPTE_170M | PRESION_LIMITED, + DCI_P3_LINEAR_FULL = GAMUT_DCI_P3 | TRANSFORM_FUNC_LINEAR | PRECISION_FULL, + DCI_P3_GAMMA26_FULL = GAMUT_DCI_P3 | TRANSFORM_FUNC_GM2_6 | PRECISION_FULL, + DISPLAY_P3_LINEAR_FULL = GAMUT_DISPLAY_P3 | TRANSFORM_FUNC_LINEAR | PRECISION_FULL, + DCI_P3_SRGB_FULL = GAMUT_DCI_P3 | TRANSFORM_FUNC_SRGB | PRECISION_FULL, + ADOBE_RGB_GAMMA22_FULL = GAMUT_ADOBE_RGB | TRANSFORM_FUNC_GM2_2 | PRECISION_FULL, + BT2020_LINEAR_FULL = GAMUT_BT2020 | TRANSFORM_FUNC_LINEAR | PRECISION_FULL, + BT2020_SRGB_FULL = GAMUT_BT2020 | TRANSFORM_FUNC_SRGB | PRECISION_FULL, + BT2020_SMPTE170M_FULL = GAMUT_BT2020 | TRANSFORM_FUNC_SMPTE_170M | PRECISION_FULL, + BT2020_ST2084_FULL = GAMUT_BT2020 | TRANSFORM_FUNC_ST2084 | PRECISION_FULL, + BT2020_HLG_FULL = GAMUT_BT2020 | TRANSFORM_FUNC_HLG | PRECISION_FULL, + BT2020_ST2084_LIMITED = GAMUT_BT2020 | TRANSFORM_FUNC_ST2084 | PRESION_LIMITED, +} ColorDataSpace; + +/** + * @brief Enumerates the HDR formats. + * + */ +typedef enum { + NOT_SUPPORT_HDR = 0, + DOLBY_VISION = 1, + HDR10 = 2, + HLG = 3, + HDR10_PLUS = 4, + HDR_VIVID = 5, +} HDRFormat; + +/** + * @brief Defines the HDR capability. + * + */ +typedef struct { + uint32_t formatCount; + HDRFormat* formats; + float maxLum; + float maxAverageLum; + float minLum; +} HDRCapability; + +/** + * @brief Enumerates the HDR metadata keys. + * + */ +typedef enum { + MATAKEY_RED_PRIMARY_X = 0, + MATAKEY_RED_PRIMARY_Y = 1, + MATAKEY_GREEN_PRIMARY_X = 2, + MATAKEY_GREEN_PRIMARY_Y = 3, + MATAKEY_BLUE_PRIMARY_X = 4, + MATAKEY_BLUE_PRIMARY_Y = 5, + MATAKEY_WHITE_PRIMARY_X = 6, + MATAKEY_WHITE_PRIMARY_Y = 7, + MATAKEY_MAX_LUMINANCE = 8, + MATAKEY_MIN_LUMINANCE = 9, + MATAKEY_MAX_CONTENT_LIGHT_LEVEL = 10, + MATAKEY_MAX_FRAME_AVERAGE_LIGHT_LEVEL = 11, + MATAKEY_HDR10_PLUS = 12, + MATAKEY_HDR_VIVID = 13, +} HDRMetadataKey; + +/** + * @brief Defines the HDR metadata. + * + */ +typedef struct { + HDRMetadataKey key; + float value; +} HDRMetaData; + +/** + * @brief Defines information for verifying the memory to allocate. + * + */ +typedef struct { + uint32_t width; /**< Width of the memory to allocate */ + uint32_t height; /**< Height of the memory to allocate */ + uint64_t usage; /**< Usage of the memory */ + PixelFormat format; /**< Format of the memory to allocate */ +} VerifyAllocInfo; + +/** + * @brief Enumerates the present timestamp types. + * + */ +typedef enum { + HARDWARE_DISPLAY_PTS_UNSUPPORTED = 0, /**< Unsupported */ + HARDWARE_DISPLAY_PTS_DELAY = 1 << 0, /**< Delay */ + HARDWARE_DISPLAY_PTS_TIMESTAMP = 1 << 1, /**< Timestamp */ +} PresentTimestampType; + +/** + * @brief Defines the present timestamp. + * + */ +typedef struct { + PresentTimestampType type; /**< Present timestamp type */ + int64_t time; /**< Present timestamp value */ +} PresentTimestamp; + +typedef struct { + int32_t fd; /**< Handle fd, -1 if not supported */ + uint32_t reserveInts; /**< the number of reserved integer value */ + int32_t reserve[0]; /**< the reserved data */ +} __attribute__((__packed__)) ExtDataHandle; + +typedef struct { + void *baseAddr; /**< Base address of memory */ + size_t yOffset; /**< Offset of Y */ + size_t uOffset; /**< Offset of U */ + size_t vOffset; /**< Offset of V */ + size_t yStride; /**< Stride of Y */ + size_t uvStride; /**< Stride of UV */ + size_t uvStep; /**< Step of UV */ +} __attribute__((__packed__)) YUVDescInfo; +#ifdef __cplusplus +} +#endif +#endif +/* @} */ diff --git a/display_server/utils/sync_fence/ft_build/BUILD.gn b/display_server/utils/sync_fence/ft_build/BUILD.gn new file mode 100644 index 0000000..dce5832 --- /dev/null +++ b/display_server/utils/sync_fence/ft_build/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2022 Huawei Device 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. + +import("//build/gn/fangtian.gni") + +config("sync_fence_config") { + visibility = [ ":sync_fence" ] + + cflags = [ + "-Wall", + "-Werror", + "-g3", + "-Wno-error=missing-braces", + "-Wno-error=#warnings", + ] +} + +config("sync_fence_public_config") { + include_dirs = [ + "../export", + "//display_server/utils/log", + ] +} + +ft_shared_library("sync_fence") { + sources = [ + "../src/sync_fence.cpp", + "../src/sync_fence_timeline.cpp", + "../src/sync_fence_tracker.cpp", + ] + + configs = [ ":sync_fence_config" ] + + public_configs = [ + ":sync_fence_public_config", + "//build/gn/configs/system_libs:c_utils_config", + "//build/gn/configs/system_libs:hilog_config", + "//build/gn/configs/system_libs:eventhandler_config", + "//build/gn/configs/system_libs:hitrace_meter_config", + "//build/gn/configs/system_libs:ipc_core_config", + ] + + part_name = "graphic_standard" + subsystem_name = "graphic" +} diff --git a/display_server/utils/sync_fence/src/sync_fence.cpp b/display_server/utils/sync_fence/src/sync_fence.cpp index 42ddcfc..9538661 100644 --- a/display_server/utils/sync_fence/src/sync_fence.cpp +++ b/display_server/utils/sync_fence/src/sync_fence.cpp @@ -136,7 +136,7 @@ int32_t SyncFence::Wait(uint32_t timeout) int SyncFence::SyncMerge(const char *name, int fd1, int fd2) { int retCode = -1; - struct sync_merge_data syncMergeData = {0}; + struct sync_merge_data syncMergeData = { {0} }; syncMergeData.fd2 = fd2; if (strcpy_s(syncMergeData.name, sizeof(syncMergeData.name), name)) { HiLog::Error(LABEL, "SyncMerge ctrcpy fence name failed."); diff --git a/display_server/utils/sync_fence/src/sync_fence_tracker.cpp b/display_server/utils/sync_fence/src/sync_fence_tracker.cpp index f6b6f6b..9c20594 100644 --- a/display_server/utils/sync_fence/src/sync_fence_tracker.cpp +++ b/display_server/utils/sync_fence/src/sync_fence_tracker.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ +#include + #include "sync_fence_tracker.h" #include "hilog/log.h" #include "rs_trace.h" -- Gitee From 7fc7f3471275f342acf8af903de4fd6a88167067 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 10:14:22 +0800 Subject: [PATCH 2/8] feat(build): add DRM Backend deps --- build/configs/system_deps.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/configs/system_deps.toml b/build/configs/system_deps.toml index 224e18a..e72473e 100755 --- a/build/configs/system_deps.toml +++ b/build/configs/system_deps.toml @@ -26,4 +26,7 @@ package_deps = [ "llvm-devel", "python3", "tar", + # DRM Backend + "libdrm-devel", + "mesa-libgbm-devel", ] -- Gitee From 3c0e51f242c2cb94ebd0c11d2fc7ebb4ab75ec53 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 11:31:12 +0800 Subject: [PATCH 3/8] fix: change system include dir --- build/gn/BUILDCONFIG.gn | 2 +- build/prebuild.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/build/gn/BUILDCONFIG.gn b/build/gn/BUILDCONFIG.gn index f96c0d9..cb69f15 100644 --- a/build/gn/BUILDCONFIG.gn +++ b/build/gn/BUILDCONFIG.gn @@ -76,7 +76,7 @@ declare_args() { is_ft_build = current_os == "linux" - sys_inc = "/usr/include" + sys_inc = "/usr/local/include" } if (use_musl_oh == true) { diff --git a/build/prebuild.sh b/build/prebuild.sh index 74fab2d..8f09e83 100755 --- a/build/prebuild.sh +++ b/build/prebuild.sh @@ -59,6 +59,12 @@ echo -e "\e[36m[-] Prepare system packages...\e[0m" # Check & Install required system packages python3 ${PROJECT_DIR}/build/builder.py check --install-packages $* +# ============================================================================= +# Prebuild +# ============================================================================= +# +# download prebuild files + # install prebuild library if [ ! -d ${PROJECT_DIR}/prebuilts/libs ]; then git clone https://gitee.com/yanansong/ft_engine_prebuild.git ${PROJECT_DIR}/prebuilts/libs -- Gitee From e94b15e25eeee3ba1047607d8e22dbe33c8b3c83 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 11:51:19 +0800 Subject: [PATCH 4/8] chore(display_server): remove buffer_handle.h --- build/prebuild.sh | 17 ++++++++ display_server/drivers/base/buffer_handle.h | 45 --------------------- 2 files changed, 17 insertions(+), 45 deletions(-) delete mode 100644 display_server/drivers/base/buffer_handle.h diff --git a/build/prebuild.sh b/build/prebuild.sh index 8f09e83..6deb360 100755 --- a/build/prebuild.sh +++ b/build/prebuild.sh @@ -88,4 +88,21 @@ sudo cp -fr * /usr/local/include cd ${PROJECT_DIR} rm -fr ${PROJECT_DIR}/prebuilts/inc +# install ft_surface_wrapper +if [ ! -d ${PROJECT_DIR}/prebuilts/rpm/ft_surface_wrapper ]; then + git clone https://gitee.com/ShaoboFeng/ft_surface_wrapper.git ${PROJECT_DIR}/prebuilts/rpm/ft_surface_wrapper +fi +cd ${PROJECT_DIR}/prebuilts/rpm/ft_surface_wrapper/ +if [ ! -d ${PROJECT_DIR}/prebuilts/rpm/ft_surface_wrapper/build ]; then + mkdir build +fi +cd build +cmake .. +make -j6 +sudo make install +rm -fr ${PROJECT_DIR}/prebuilts/rpm/ft_surface_wrapper +cd ${PROJECT_DIR} + +# ============================================================================= + echo -e "\033[32m[*] Pre-build Done. You need exec 'build.sh'.\033[0m" diff --git a/display_server/drivers/base/buffer_handle.h b/display_server/drivers/base/buffer_handle.h deleted file mode 100644 index 9d43bfd..0000000 --- a/display_server/drivers/base/buffer_handle.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device 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. - */ - -#ifndef INCLUDE_BUFFER_HANDLE_H -#define INCLUDE_BUFFER_HANDLE_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - int32_t fd; /**< buffer fd, -1 if not supported */ - int32_t width; /**< the width of memory */ - int32_t stride; /**< the stride of memory */ - int32_t height; /**< the height of memory */ - int32_t size; /* < size of memory */ - int32_t format; /**< the format of memory */ - uint64_t usage; /**< the usage of memory */ - void *virAddr; /**< Virtual address of memory */ - uint64_t phyAddr; /**< Physical address */ - int32_t key; /**< Shared memory key */ - uint32_t reserveFds; /**< the number of reserved fd value */ - uint32_t reserveInts; /**< the number of reserved integer value */ - int32_t reserve[0]; /**< the data */ -} BufferHandle; - -#ifdef __cplusplus -} -#endif - -#endif // INCLUDE_BUFFER_HANDLE_H -- Gitee From 786f661f82ba3b3d604583bdb22e65915bba58de Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 12:40:09 +0800 Subject: [PATCH 5/8] fix: add system deps : cmake --- build/configs/system_deps.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/configs/system_deps.toml b/build/configs/system_deps.toml index e72473e..27af6dc 100755 --- a/build/configs/system_deps.toml +++ b/build/configs/system_deps.toml @@ -26,6 +26,7 @@ package_deps = [ "llvm-devel", "python3", "tar", + "cmake", # DRM Backend "libdrm-devel", "mesa-libgbm-devel", -- Gitee From 3f65c917053bb830944f98965cdb09474f615518 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 14:06:01 +0800 Subject: [PATCH 6/8] fix(build): add system deps : udev --- build/configs/system_deps.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/configs/system_deps.toml b/build/configs/system_deps.toml index 27af6dc..29daea2 100755 --- a/build/configs/system_deps.toml +++ b/build/configs/system_deps.toml @@ -29,5 +29,6 @@ package_deps = [ "cmake", # DRM Backend "libdrm-devel", + "systemd-devel", "mesa-libgbm-devel", ] -- Gitee From 528a5dd9b5530589fc83b94dc47592d02fbd324b Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 14:48:58 +0800 Subject: [PATCH 7/8] chore: remove unnecessary codes --- display_server/drivers/hal/BUILD.gn | 2 +- display_server/drivers/hal/base/BUILD.gn | 7 +------ .../core/drm_backend/display_device/BUILD.gn | 4 ++-- .../display_device/drm_connector.h | 20 +------------------ .../drm_backend/display_device/drm_crtc.cpp | 12 ----------- .../core/drm_backend/display_gralloc/BUILD.gn | 4 ++-- .../drivers/hal/core/event_loop/BUILD.gn | 5 ++--- display_server/drivers/hal/test/BUILD.gn | 2 +- .../utils/sync_fence/ft_build/BUILD.gn | 3 --- 9 files changed, 10 insertions(+), 49 deletions(-) diff --git a/display_server/drivers/hal/BUILD.gn b/display_server/drivers/hal/BUILD.gn index ac2bee4..49aa6dd 100644 --- a/display_server/drivers/hal/BUILD.gn +++ b/display_server/drivers/hal/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -config("oehal_public_config") { +config("hal_public_config") { include_dirs = [ ".", "./core" diff --git a/display_server/drivers/hal/base/BUILD.gn b/display_server/drivers/hal/base/BUILD.gn index 32a418e..d670153 100644 --- a/display_server/drivers/hal/base/BUILD.gn +++ b/display_server/drivers/hal/base/BUILD.gn @@ -13,7 +13,7 @@ import("//build/gn/fangtian.gni") -ft_shared_library("oebase") { +ft_shared_library("hal_base") { sources = [ "current_thread.cpp", "timestamp.cpp", @@ -23,9 +23,4 @@ ft_shared_library("oebase") { "//build/gn/configs/system_libs:hilog_config", "//build/gn/configs/system_libs:c_utils_config", ] - - # public_deps = [ - # "hilog_native:libhilog", - # "c_utils:utils" - # ] } \ No newline at end of file diff --git a/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn b/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn index 85c9ac4..46695cd 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn +++ b/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn @@ -42,7 +42,7 @@ ft_shared_library("display_device") { ] configs = [ - "//display_server/drivers/hal:oehal_public_config", + "//display_server/drivers/hal:hal_public_config", ] public_configs = [ ":display_device_public_config", @@ -51,7 +51,7 @@ ft_shared_library("display_device") { public_deps = [ "//display_server/drivers/hal/core/drm_backend:display_drm_dep", - "//display_server/drivers/hal/base:oebase", + "//display_server/drivers/hal/base:hal_base", ] deps = [ diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h index 7dcb8ac..db242f3 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h @@ -29,25 +29,7 @@ namespace drm { constexpr char PROP_CRTCID[] = "CRTC_ID"; constexpr char PROP_DPMS[] = "DPMS"; constexpr char PROP_BRIGHTNESS[] = "brightness"; -// typedef struct _drmModeConnector { -// uint32_t connector_id; -// uint32_t encoder_id; /**< Encoder currently connected to */ -// uint32_t connector_type; -// uint32_t connector_type_id; -// drmModeConnection connection; -// uint32_t mmWidth, mmHeight; /**< HxW in millimeters */ -// drmModeSubPixel subpixel; - -// int count_modes; -// drmModeModeInfoPtr modes; - -// int count_props; -// uint32_t *props; /**< List of property ids */ -// uint64_t *prop_values; /**< List of property values */ - -// int count_encoders; -// uint32_t *encoders; /**< List of encoder ids */ -// } drmModeConnector, *drmModeConnectorPtr; + class DrmConnector : NonCopyable { public: DrmConnector(int drmFd, uint32_t connectorId); diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp index 9d93838..dc5d3b8 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp +++ b/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp @@ -59,18 +59,6 @@ bool DrmCrtc::CanBind() return (displayId_ == HDI::DISPLAY::INVALID_DISPLAY_ID); } -// typedef struct _drmModeCrtc { -// uint32_t crtc_id; -// uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */ -// -// uint32_t x, y; /**< Position on the framebuffer */ -// uint32_t width, height; -// int mode_valid; -// drmModeModeInfo mode; -// -// int gamma_size; /**< Number of gamma stops */ -// -//} drmModeCrtc, *drmModeCrtcPtr; void DrmCrtc::ParseFrom(drmModeCrtcPtr const &crtc) { DrmObjectPropertyFetcher crtcPropFetcher(drmFd_, id_, DRM_MODE_OBJECT_CRTC); diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn b/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn index 9131c69..eb2a085 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn +++ b/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn @@ -36,7 +36,7 @@ ft_shared_library("display_gralloc") { ] configs = [ - "//display_server/drivers/hal:oehal_public_config" + "//display_server/drivers/hal:hal_public_config" ] public_configs = [ @@ -46,7 +46,7 @@ ft_shared_library("display_gralloc") { public_deps = [ "//display_server/drivers/hal/core/drm_backend:display_drm_dep", - "//display_server/drivers/hal/base:oebase" + "//display_server/drivers/hal/base:hal_base" ] deps = [ "//display_server/drivers/hal/core/drm_backend/display_device:display_device", diff --git a/display_server/drivers/hal/core/event_loop/BUILD.gn b/display_server/drivers/hal/core/event_loop/BUILD.gn index 5a14b44..55fad97 100644 --- a/display_server/drivers/hal/core/event_loop/BUILD.gn +++ b/display_server/drivers/hal/core/event_loop/BUILD.gn @@ -22,9 +22,8 @@ ft_shared_library("event_loop") { "timer.cpp", "timer_queue.cpp", ] - configs = [ "//display_server/drivers/hal:oehal_public_config" ] + configs = [ "//display_server/drivers/hal:hal_public_config" ] deps = [ - "//display_server/drivers/hal/base:oebase", - # "//display_server/drivers/hal/log:oelog", + "//display_server/drivers/hal/base:hal_base", ] } diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn index e9968f0..f1a590a 100644 --- a/display_server/drivers/hal/test/BUILD.gn +++ b/display_server/drivers/hal/test/BUILD.gn @@ -27,6 +27,6 @@ ft_executable("drm_backend_test") { ] configs = [ - "//display_server/drivers/hal:oehal_public_config" + "//display_server/drivers/hal:hal_public_config" ] } diff --git a/display_server/utils/sync_fence/ft_build/BUILD.gn b/display_server/utils/sync_fence/ft_build/BUILD.gn index dce5832..abe40c8 100644 --- a/display_server/utils/sync_fence/ft_build/BUILD.gn +++ b/display_server/utils/sync_fence/ft_build/BUILD.gn @@ -49,7 +49,4 @@ ft_shared_library("sync_fence") { "//build/gn/configs/system_libs:hitrace_meter_config", "//build/gn/configs/system_libs:ipc_core_config", ] - - part_name = "graphic_standard" - subsystem_name = "graphic" } -- Gitee From 9e8e8c821dff1282f3189a985e81a1e81406f322 Mon Sep 17 00:00:00 2001 From: fseeeye Date: Mon, 19 Jun 2023 15:32:48 +0800 Subject: [PATCH 8/8] refactor: change DRM Backend dir structure --- build/gn/BUILD.gn | 2 +- display_server/drivers/hal/BUILD.gn | 1 - display_server/drivers/hal/base/BUILD.gn | 18 ++++++++++++++++-- .../hal/base/{ => includes}/current_thread.h | 0 .../includes}/event_loop/event_channel.h | 4 ++-- .../includes}/event_loop/event_loop.h | 0 .../includes}/event_loop/event_loop_thread.h | 0 .../includes}/event_loop/event_poller.h | 0 .../{core => base/includes}/event_loop/timer.h | 4 ++-- .../includes}/event_loop/timer_queue.h | 0 .../drivers/hal/base/{ => includes}/log.h | 0 .../hal/base/{ => includes}/noncopyable.h | 0 .../hal/base/{ => includes}/timestamp.h | 0 .../drivers/hal/base/{ => includes}/types.h | 0 .../hal/base/{ => src}/current_thread.cpp | 0 .../hal/{core => base/src}/event_loop/BUILD.gn | 2 +- .../src}/event_loop/event_channel.cpp | 2 +- .../src}/event_loop/event_loop.cpp | 4 ++-- .../src}/event_loop/event_loop_thread.cpp | 2 +- .../src}/event_loop/event_poller.cpp | 4 ++-- .../{core => base/src}/event_loop/timer.cpp | 0 .../src}/event_loop/timer_queue.cpp | 2 +- .../drivers/hal/base/{ => src}/timestamp.cpp | 0 display_server/drivers/hal/core/BUILD.gn | 12 ------------ .../hal/{core => }/drm_backend/BUILD.gn | 0 .../drm_backend/display_device/BUILD.gn | 9 ++++----- .../display_device/device_event_monitor.cpp | 2 +- .../display_device/device_event_monitor.h | 0 .../display_device/drm_atomic_committer.cpp | 2 +- .../display_device/drm_atomic_committer.h | 0 .../drm_backend/display_device/drm_common.h | 4 ++-- .../display_device/drm_connector.cpp | 2 +- .../drm_backend/display_device/drm_connector.h | 0 .../drm_backend/display_device/drm_crtc.cpp | 2 +- .../drm_backend/display_device/drm_crtc.h | 2 +- .../drm_backend/display_device/drm_device.cpp | 2 +- .../drm_backend/display_device/drm_device.h | 0 .../drm_backend/display_device/drm_display.cpp | 2 +- .../drm_backend/display_device/drm_display.h | 0 .../drm_backend/display_device/drm_encoder.cpp | 2 +- .../drm_backend/display_device/drm_encoder.h | 2 +- .../display_device/drm_frame_buffer.cpp | 2 +- .../display_device/drm_frame_buffer.h | 0 .../drm_backend/display_device/drm_layer.cpp | 2 +- .../drm_backend/display_device/drm_layer.h | 0 .../display_device/drm_mode_info.cpp | 2 +- .../drm_backend/display_device/drm_mode_info.h | 2 +- .../drm_backend/display_device/drm_plane.cpp | 2 +- .../drm_backend/display_device/drm_plane.h | 2 +- .../display_device/drm_property.cpp | 2 +- .../drm_backend/display_device/drm_property.h | 0 .../drm_backend/display_device/hdi_display.cpp | 2 +- .../drm_backend/display_device/hdi_display.h | 0 .../drm_backend/display_device/hdi_layer.cpp | 4 ++-- .../drm_backend/display_device/hdi_layer.h | 2 +- .../drm_backend/display_device/hdi_session.cpp | 0 .../drm_backend/display_device/hdi_session.h | 2 +- .../display_device/udev_object_helper.h | 2 +- .../drm_backend/display_gralloc/BUILD.gn | 10 +++++----- .../drm_backend/display_gralloc/allocator.cpp | 0 .../drm_backend/display_gralloc/allocator.h | 0 .../display_gralloc/allocator_controller.cpp | 2 +- .../display_gralloc/allocator_controller.h | 0 .../display_gralloc/display_gralloc.cpp | 2 +- .../display_gralloc/display_gralloc_utils.cpp | 2 +- .../display_gralloc/display_gralloc_utils.h | 0 .../display_gralloc/dumb_allocator.cpp | 2 +- .../display_gralloc/dumb_allocator.h | 0 .../display_gralloc/gbm_allocator.cpp | 4 ++-- .../display_gralloc/gbm_allocator.h | 0 .../display_gralloc/hi_drm_format.cpp | 0 .../display_gralloc/hi_drm_format.h | 2 +- .../display_gralloc/hi_gbm_format.cpp | 0 .../display_gralloc/hi_gbm_format.h | 2 +- .../display_gralloc/shm_allocator.cpp | 4 ++-- .../display_gralloc/shm_allocator.h | 0 .../include/display_gralloc_private.h | 0 display_server/drivers/hal/test/BUILD.gn | 4 ++-- 78 files changed, 74 insertions(+), 74 deletions(-) rename display_server/drivers/hal/base/{ => includes}/current_thread.h (100%) rename display_server/drivers/hal/{core => base/includes}/event_loop/event_channel.h (98%) rename display_server/drivers/hal/{core => base/includes}/event_loop/event_loop.h (100%) rename display_server/drivers/hal/{core => base/includes}/event_loop/event_loop_thread.h (100%) rename display_server/drivers/hal/{core => base/includes}/event_loop/event_poller.h (100%) rename display_server/drivers/hal/{core => base/includes}/event_loop/timer.h (97%) rename display_server/drivers/hal/{core => base/includes}/event_loop/timer_queue.h (100%) rename display_server/drivers/hal/base/{ => includes}/log.h (100%) rename display_server/drivers/hal/base/{ => includes}/noncopyable.h (100%) rename display_server/drivers/hal/base/{ => includes}/timestamp.h (100%) rename display_server/drivers/hal/base/{ => includes}/types.h (100%) rename display_server/drivers/hal/base/{ => src}/current_thread.cpp (100%) rename display_server/drivers/hal/{core => base/src}/event_loop/BUILD.gn (96%) rename display_server/drivers/hal/{core => base/src}/event_loop/event_channel.cpp (99%) rename display_server/drivers/hal/{core => base/src}/event_loop/event_loop.cpp (98%) rename display_server/drivers/hal/{core => base/src}/event_loop/event_loop_thread.cpp (98%) rename display_server/drivers/hal/{core => base/src}/event_loop/event_poller.cpp (98%) rename display_server/drivers/hal/{core => base/src}/event_loop/timer.cpp (100%) rename display_server/drivers/hal/{core => base/src}/event_loop/timer_queue.cpp (99%) rename display_server/drivers/hal/base/{ => src}/timestamp.cpp (100%) delete mode 100644 display_server/drivers/hal/core/BUILD.gn rename display_server/drivers/hal/{core => }/drm_backend/BUILD.gn (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/BUILD.gn (81%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/device_event_monitor.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/device_event_monitor.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_atomic_committer.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_atomic_committer.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_common.h (97%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_connector.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_connector.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_crtc.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_crtc.h (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_device.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_device.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_display.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_display.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_encoder.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_encoder.h (97%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_frame_buffer.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_frame_buffer.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_layer.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_layer.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_mode_info.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_mode_info.h (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_plane.cpp (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_plane.h (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_property.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/drm_property.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_display.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_display.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_layer.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_layer.h (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_session.cpp (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/hdi_session.h (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_device/udev_object_helper.h (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/BUILD.gn (78%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/allocator.cpp (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/allocator.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/allocator_controller.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/allocator_controller.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/display_gralloc.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/display_gralloc_utils.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/display_gralloc_utils.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/dumb_allocator.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/dumb_allocator.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/gbm_allocator.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/gbm_allocator.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/hi_drm_format.cpp (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/hi_drm_format.h (98%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/hi_gbm_format.cpp (100%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/hi_gbm_format.h (97%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/shm_allocator.cpp (99%) rename display_server/drivers/hal/{core => }/drm_backend/display_gralloc/shm_allocator.h (100%) rename display_server/drivers/hal/{core => }/drm_backend/include/display_gralloc_private.h (100%) diff --git a/build/gn/BUILD.gn b/build/gn/BUILD.gn index d6f2adc..18c45f2 100644 --- a/build/gn/BUILD.gn +++ b/build/gn/BUILD.gn @@ -15,7 +15,7 @@ group("ft_engine") { deps = [ "//display_server/utils/socketpair/ft_build:socketpair", "//display_server/rosen/modules/composer/vsync/ft_build:libvsync", - "//display_server/drivers/hal/core/drm_backend:drm_backend" + "//display_server/drivers/hal/drm_backend:drm_backend" ] } diff --git a/display_server/drivers/hal/BUILD.gn b/display_server/drivers/hal/BUILD.gn index 49aa6dd..737a62d 100644 --- a/display_server/drivers/hal/BUILD.gn +++ b/display_server/drivers/hal/BUILD.gn @@ -14,6 +14,5 @@ config("hal_public_config") { include_dirs = [ ".", - "./core" ] } diff --git a/display_server/drivers/hal/base/BUILD.gn b/display_server/drivers/hal/base/BUILD.gn index d670153..d5faf8e 100644 --- a/display_server/drivers/hal/base/BUILD.gn +++ b/display_server/drivers/hal/base/BUILD.gn @@ -13,13 +13,27 @@ import("//build/gn/fangtian.gni") +config("hal_base_public_config") { + include_dirs = [ + "./includes", + "./includes/event_loop" + ] +} + ft_shared_library("hal_base") { sources = [ - "current_thread.cpp", - "timestamp.cpp", + "./src/current_thread.cpp", + "./src/timestamp.cpp", + "./src/event_loop/event_channel.cpp", + "./src/event_loop/event_loop.cpp", + "./src/event_loop/event_loop_thread.cpp", + "./src/event_loop/event_poller.cpp", + "./src/event_loop/timer.cpp", + "./src/event_loop/timer_queue.cpp", ] public_configs = [ + ":hal_base_public_config", "//build/gn/configs/system_libs:hilog_config", "//build/gn/configs/system_libs:c_utils_config", ] diff --git a/display_server/drivers/hal/base/current_thread.h b/display_server/drivers/hal/base/includes/current_thread.h similarity index 100% rename from display_server/drivers/hal/base/current_thread.h rename to display_server/drivers/hal/base/includes/current_thread.h diff --git a/display_server/drivers/hal/core/event_loop/event_channel.h b/display_server/drivers/hal/base/includes/event_loop/event_channel.h similarity index 98% rename from display_server/drivers/hal/core/event_loop/event_channel.h rename to display_server/drivers/hal/base/includes/event_loop/event_channel.h index e86a437..93a554f 100644 --- a/display_server/drivers/hal/core/event_loop/event_channel.h +++ b/display_server/drivers/hal/base/includes/event_loop/event_channel.h @@ -21,8 +21,8 @@ #include #include -#include "base/noncopyable.h" -#include "base/timestamp.h" +#include "noncopyable.h" +#include "timestamp.h" namespace oewm { using EventCallback = std::function; diff --git a/display_server/drivers/hal/core/event_loop/event_loop.h b/display_server/drivers/hal/base/includes/event_loop/event_loop.h similarity index 100% rename from display_server/drivers/hal/core/event_loop/event_loop.h rename to display_server/drivers/hal/base/includes/event_loop/event_loop.h diff --git a/display_server/drivers/hal/core/event_loop/event_loop_thread.h b/display_server/drivers/hal/base/includes/event_loop/event_loop_thread.h similarity index 100% rename from display_server/drivers/hal/core/event_loop/event_loop_thread.h rename to display_server/drivers/hal/base/includes/event_loop/event_loop_thread.h diff --git a/display_server/drivers/hal/core/event_loop/event_poller.h b/display_server/drivers/hal/base/includes/event_loop/event_poller.h similarity index 100% rename from display_server/drivers/hal/core/event_loop/event_poller.h rename to display_server/drivers/hal/base/includes/event_loop/event_poller.h diff --git a/display_server/drivers/hal/core/event_loop/timer.h b/display_server/drivers/hal/base/includes/event_loop/timer.h similarity index 97% rename from display_server/drivers/hal/core/event_loop/timer.h rename to display_server/drivers/hal/base/includes/event_loop/timer.h index f5d90f3..5a1641e 100644 --- a/display_server/drivers/hal/core/event_loop/timer.h +++ b/display_server/drivers/hal/base/includes/event_loop/timer.h @@ -17,8 +17,8 @@ #include -#include "base/noncopyable.h" -#include "base/timestamp.h" +#include "noncopyable.h" +#include "timestamp.h" namespace oewm { class Timer; diff --git a/display_server/drivers/hal/core/event_loop/timer_queue.h b/display_server/drivers/hal/base/includes/event_loop/timer_queue.h similarity index 100% rename from display_server/drivers/hal/core/event_loop/timer_queue.h rename to display_server/drivers/hal/base/includes/event_loop/timer_queue.h diff --git a/display_server/drivers/hal/base/log.h b/display_server/drivers/hal/base/includes/log.h similarity index 100% rename from display_server/drivers/hal/base/log.h rename to display_server/drivers/hal/base/includes/log.h diff --git a/display_server/drivers/hal/base/noncopyable.h b/display_server/drivers/hal/base/includes/noncopyable.h similarity index 100% rename from display_server/drivers/hal/base/noncopyable.h rename to display_server/drivers/hal/base/includes/noncopyable.h diff --git a/display_server/drivers/hal/base/timestamp.h b/display_server/drivers/hal/base/includes/timestamp.h similarity index 100% rename from display_server/drivers/hal/base/timestamp.h rename to display_server/drivers/hal/base/includes/timestamp.h diff --git a/display_server/drivers/hal/base/types.h b/display_server/drivers/hal/base/includes/types.h similarity index 100% rename from display_server/drivers/hal/base/types.h rename to display_server/drivers/hal/base/includes/types.h diff --git a/display_server/drivers/hal/base/current_thread.cpp b/display_server/drivers/hal/base/src/current_thread.cpp similarity index 100% rename from display_server/drivers/hal/base/current_thread.cpp rename to display_server/drivers/hal/base/src/current_thread.cpp diff --git a/display_server/drivers/hal/core/event_loop/BUILD.gn b/display_server/drivers/hal/base/src/event_loop/BUILD.gn similarity index 96% rename from display_server/drivers/hal/core/event_loop/BUILD.gn rename to display_server/drivers/hal/base/src/event_loop/BUILD.gn index 55fad97..94ff499 100644 --- a/display_server/drivers/hal/core/event_loop/BUILD.gn +++ b/display_server/drivers/hal/base/src/event_loop/BUILD.gn @@ -13,7 +13,7 @@ # limitations under the License. import("//build/gn/fangtian.gni") -ft_shared_library("event_loop") { +ft_shared_library("hal_event_loop") { sources = [ "event_channel.cpp", "event_loop.cpp", diff --git a/display_server/drivers/hal/core/event_loop/event_channel.cpp b/display_server/drivers/hal/base/src/event_loop/event_channel.cpp similarity index 99% rename from display_server/drivers/hal/core/event_loop/event_channel.cpp rename to display_server/drivers/hal/base/src/event_loop/event_channel.cpp index 8d1f01e..54901a1 100644 --- a/display_server/drivers/hal/core/event_loop/event_channel.cpp +++ b/display_server/drivers/hal/base/src/event_loop/event_channel.cpp @@ -16,7 +16,7 @@ #include "event_channel.h" #include "event_loop.h" -#include "base/log.h" +#include "log.h" namespace oewm { EventChannel::EventChannel(int fd, EventLoop *eventLoop) : fd_(fd), eventLoop_(eventLoop) diff --git a/display_server/drivers/hal/core/event_loop/event_loop.cpp b/display_server/drivers/hal/base/src/event_loop/event_loop.cpp similarity index 98% rename from display_server/drivers/hal/core/event_loop/event_loop.cpp rename to display_server/drivers/hal/base/src/event_loop/event_loop.cpp index 7e26f28..97e7273 100644 --- a/display_server/drivers/hal/core/event_loop/event_loop.cpp +++ b/display_server/drivers/hal/base/src/event_loop/event_loop.cpp @@ -18,8 +18,8 @@ #include #include -#include "base/current_thread.h" -#include "base/log.h" +#include "current_thread.h" +#include "log.h" namespace oewm { namespace detail { diff --git a/display_server/drivers/hal/core/event_loop/event_loop_thread.cpp b/display_server/drivers/hal/base/src/event_loop/event_loop_thread.cpp similarity index 98% rename from display_server/drivers/hal/core/event_loop/event_loop_thread.cpp rename to display_server/drivers/hal/base/src/event_loop/event_loop_thread.cpp index c8526d9..d7078ae 100644 --- a/display_server/drivers/hal/core/event_loop/event_loop_thread.cpp +++ b/display_server/drivers/hal/base/src/event_loop/event_loop_thread.cpp @@ -15,7 +15,7 @@ #include "event_loop_thread.h" -#include "base/log.h" +#include "log.h" namespace oewm { EventLoopThread::EventLoopThread() : EventLoopThread("OEWMEventLoopThread") {} diff --git a/display_server/drivers/hal/core/event_loop/event_poller.cpp b/display_server/drivers/hal/base/src/event_loop/event_poller.cpp similarity index 98% rename from display_server/drivers/hal/core/event_loop/event_poller.cpp rename to display_server/drivers/hal/base/src/event_loop/event_poller.cpp index 9794364..d17ba62 100644 --- a/display_server/drivers/hal/core/event_loop/event_poller.cpp +++ b/display_server/drivers/hal/base/src/event_loop/event_poller.cpp @@ -15,10 +15,10 @@ #include "event_poller.h" -#include "base/types.h" +#include "types.h" #include "event_loop.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace detail { diff --git a/display_server/drivers/hal/core/event_loop/timer.cpp b/display_server/drivers/hal/base/src/event_loop/timer.cpp similarity index 100% rename from display_server/drivers/hal/core/event_loop/timer.cpp rename to display_server/drivers/hal/base/src/event_loop/timer.cpp diff --git a/display_server/drivers/hal/core/event_loop/timer_queue.cpp b/display_server/drivers/hal/base/src/event_loop/timer_queue.cpp similarity index 99% rename from display_server/drivers/hal/core/event_loop/timer_queue.cpp rename to display_server/drivers/hal/base/src/event_loop/timer_queue.cpp index 161320c..7966dab 100644 --- a/display_server/drivers/hal/core/event_loop/timer_queue.cpp +++ b/display_server/drivers/hal/base/src/event_loop/timer_queue.cpp @@ -18,7 +18,7 @@ #include #include "event_loop.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace detail { diff --git a/display_server/drivers/hal/base/timestamp.cpp b/display_server/drivers/hal/base/src/timestamp.cpp similarity index 100% rename from display_server/drivers/hal/base/timestamp.cpp rename to display_server/drivers/hal/base/src/timestamp.cpp diff --git a/display_server/drivers/hal/core/BUILD.gn b/display_server/drivers/hal/core/BUILD.gn deleted file mode 100644 index 3ada030..0000000 --- a/display_server/drivers/hal/core/BUILD.gn +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2022 Huawei Device 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. diff --git a/display_server/drivers/hal/core/drm_backend/BUILD.gn b/display_server/drivers/hal/drm_backend/BUILD.gn similarity index 100% rename from display_server/drivers/hal/core/drm_backend/BUILD.gn rename to display_server/drivers/hal/drm_backend/BUILD.gn diff --git a/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn b/display_server/drivers/hal/drm_backend/display_device/BUILD.gn similarity index 81% rename from display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn rename to display_server/drivers/hal/drm_backend/display_device/BUILD.gn index 46695cd..23d7b4a 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/BUILD.gn +++ b/display_server/drivers/hal/drm_backend/display_device/BUILD.gn @@ -14,8 +14,8 @@ import("//build/gn/fangtian.gni") config("display_device_public_config") { include_dirs = [ - "//display_server/drivers/hal/core/drm_backend/display_device", - "//display_server/drivers/hal/core/drm_backend/include", + "//display_server/drivers/hal/drm_backend/display_device", + "//display_server/drivers/hal/drm_backend/include", "//display_server/drivers/interfaces", "//display_server/drivers/base", @@ -46,16 +46,15 @@ ft_shared_library("display_device") { ] public_configs = [ ":display_device_public_config", - "//display_server/drivers/hal/core/drm_backend:import_system_gbm_config" + "//display_server/drivers/hal/drm_backend:import_system_gbm_config" ] public_deps = [ - "//display_server/drivers/hal/core/drm_backend:display_drm_dep", + "//display_server/drivers/hal/drm_backend:display_drm_dep", "//display_server/drivers/hal/base:hal_base", ] deps = [ "//display_server/utils/sync_fence/ft_build:sync_fence", - "//display_server/drivers/hal/core/event_loop:event_loop", ] } diff --git a/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp b/display_server/drivers/hal/drm_backend/display_device/device_event_monitor.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp rename to display_server/drivers/hal/drm_backend/display_device/device_event_monitor.cpp index c149a4f..592f0fc 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/device_event_monitor.cpp @@ -17,7 +17,7 @@ #include "drm_atomic_committer.h" #include "hdi_display.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h b/display_server/drivers/hal/drm_backend/display_device/device_event_monitor.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/device_event_monitor.h rename to display_server/drivers/hal/drm_backend/display_device/device_event_monitor.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_atomic_committer.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_atomic_committer.cpp index 41b79ac..025154f 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_atomic_committer.cpp @@ -16,7 +16,7 @@ #include "drm_atomic_committer.h" #include "drm_display.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h b/display_server/drivers/hal/drm_backend/display_device/drm_atomic_committer.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_atomic_committer.h rename to display_server/drivers/hal/drm_backend/display_device/drm_atomic_committer.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_common.h b/display_server/drivers/hal/drm_backend/display_device/drm_common.h similarity index 97% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_common.h rename to display_server/drivers/hal/drm_backend/display_device/drm_common.h index fcf4a3f..0a64ec0 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_common.h +++ b/display_server/drivers/hal/drm_backend/display_device/drm_common.h @@ -20,8 +20,8 @@ #include #include -#include "base/noncopyable.h" -#include "base/types.h" +#include "noncopyable.h" +#include "types.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_connector.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_connector.cpp index f20ee9c..3137808 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_connector.cpp @@ -17,7 +17,7 @@ #include "display_type.h" #include "drm_mode.h" -#include "base/log.h" +#include "log.h" #include "drm_property.h" namespace oewm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h b/display_server/drivers/hal/drm_backend/display_device/drm_connector.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_connector.h rename to display_server/drivers/hal/drm_backend/display_device/drm_connector.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_crtc.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_crtc.cpp index dc5d3b8..2368336 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_crtc.cpp @@ -16,7 +16,7 @@ #include "drm_crtc.h" #include "hdi_display.h" -#include "base/log.h" +#include "log.h" #include "drm_property.h" namespace oewm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h b/display_server/drivers/hal/drm_backend/display_device/drm_crtc.h similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h rename to display_server/drivers/hal/drm_backend/display_device/drm_crtc.h index aadd9ec..7efbd46 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_crtc.h +++ b/display_server/drivers/hal/drm_backend/display_device/drm_crtc.h @@ -15,7 +15,7 @@ #pragma once -#include "base/noncopyable.h" +#include "noncopyable.h" #include "drm_common.h" #include "drm_property.h" #include "hdi_display.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_device.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_device.cpp index aa41ab9..4666672 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_device.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_device.cpp @@ -19,7 +19,7 @@ #include #include "drm_display.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_device.h b/display_server/drivers/hal/drm_backend/display_device/drm_device.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_device.h rename to display_server/drivers/hal/drm_backend/display_device/drm_device.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_display.cpp index 8c9250a..9f1c359 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_display.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_display.cpp @@ -17,7 +17,7 @@ #include "sync_fence.h" #include "drm_atomic_committer.h" -#include "base/log.h" +#include "log.h" #include "hdi_session.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_display.h b/display_server/drivers/hal/drm_backend/display_device/drm_display.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_display.h rename to display_server/drivers/hal/drm_backend/display_device/drm_display.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_encoder.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_encoder.cpp index cfb5308..3552715 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_encoder.cpp @@ -18,7 +18,7 @@ #include #include -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h b/display_server/drivers/hal/drm_backend/display_device/drm_encoder.h similarity index 97% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h rename to display_server/drivers/hal/drm_backend/display_device/drm_encoder.h index 09db35f..ab566e0 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_encoder.h +++ b/display_server/drivers/hal/drm_backend/display_device/drm_encoder.h @@ -15,7 +15,7 @@ #pragma once -#include "base/noncopyable.h" +#include "noncopyable.h" #include "drm_common.h" #include "drm_crtc.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp index 97f4e62..85d65bc 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.cpp @@ -18,7 +18,7 @@ #include #include -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h b/display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_frame_buffer.h rename to display_server/drivers/hal/drm_backend/display_device/drm_frame_buffer.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp index 37d40b6..e14b04a 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_layer.cpp @@ -15,7 +15,7 @@ #include "drm_layer.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h b/display_server/drivers/hal/drm_backend/display_device/drm_layer.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_layer.h rename to display_server/drivers/hal/drm_backend/display_device/drm_layer.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_mode_info.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_mode_info.cpp index fbc3fbf..0362ac5 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_mode_info.cpp @@ -15,7 +15,7 @@ #include "drm_mode_info.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h b/display_server/drivers/hal/drm_backend/display_device/drm_mode_info.h similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h rename to display_server/drivers/hal/drm_backend/display_device/drm_mode_info.h index 63bff7b..8e20a44 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_mode_info.h +++ b/display_server/drivers/hal/drm_backend/display_device/drm_mode_info.h @@ -15,7 +15,7 @@ #pragma once -#include "base/noncopyable.h" +#include "noncopyable.h" #include "display_type.h" #include "drm_common.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_plane.cpp similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_plane.cpp index df62ab7..485129f 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_plane.cpp @@ -16,7 +16,7 @@ #include "drm_plane.h" #include "drm_mode.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h b/display_server/drivers/hal/drm_backend/display_device/drm_plane.h similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h rename to display_server/drivers/hal/drm_backend/display_device/drm_plane.h index c0c8214..35c3961 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_plane.h +++ b/display_server/drivers/hal/drm_backend/display_device/drm_plane.h @@ -15,7 +15,7 @@ #pragma once -#include "base/noncopyable.h" +#include "noncopyable.h" #include "drm_common.h" #include "drm_property.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp b/display_server/drivers/hal/drm_backend/display_device/drm_property.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp rename to display_server/drivers/hal/drm_backend/display_device/drm_property.cpp index 826b762..a50fc7b 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/drm_property.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/drm_property.cpp @@ -15,7 +15,7 @@ #include "drm_property.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace drm { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/drm_property.h b/display_server/drivers/hal/drm_backend/display_device/drm_property.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/drm_property.h rename to display_server/drivers/hal/drm_backend/display_device/drm_property.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp b/display_server/drivers/hal/drm_backend/display_device/hdi_display.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp rename to display_server/drivers/hal/drm_backend/display_device/hdi_display.cpp index 15400c4..05904a7 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/hdi_display.cpp @@ -15,7 +15,7 @@ #include "hdi_display.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h b/display_server/drivers/hal/drm_backend/display_device/hdi_display.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_display.h rename to display_server/drivers/hal/drm_backend/display_device/hdi_display.h diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp b/display_server/drivers/hal/drm_backend/display_device/hdi_layer.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp rename to display_server/drivers/hal/drm_backend/display_device/hdi_layer.cpp index e30bc01..fd7f1e5 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.cpp +++ b/display_server/drivers/hal/drm_backend/display_device/hdi_layer.cpp @@ -19,8 +19,8 @@ #include "refbase.h" #include "sync_fence.h" -#include "base/log.h" -#include "base/types.h" +#include "log.h" +#include "types.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h b/display_server/drivers/hal/drm_backend/display_device/hdi_layer.h similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h rename to display_server/drivers/hal/drm_backend/display_device/hdi_layer.h index f313cfa..ee1de04 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/hdi_layer.h +++ b/display_server/drivers/hal/drm_backend/display_device/hdi_layer.h @@ -21,7 +21,7 @@ #include "unique_fd.h" #include "buffer_handle.h" #include "display_type.h" -#include "base/noncopyable.h" +#include "noncopyable.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp b/display_server/drivers/hal/drm_backend/display_device/hdi_session.cpp similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_session.cpp rename to display_server/drivers/hal/drm_backend/display_device/hdi_session.cpp diff --git a/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h b/display_server/drivers/hal/drm_backend/display_device/hdi_session.h similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h rename to display_server/drivers/hal/drm_backend/display_device/hdi_session.h index fb4617b..716c4a9 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/hdi_session.h +++ b/display_server/drivers/hal/drm_backend/display_device/hdi_session.h @@ -19,7 +19,7 @@ #include "display_device.h" #include "display_type.h" #include "hdi_display.h" -#include "base/log.h" +#include "log.h" #ifdef USE_LIBUDEV #include "udev_object_helper.h" diff --git a/display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h b/display_server/drivers/hal/drm_backend/display_device/udev_object_helper.h similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h rename to display_server/drivers/hal/drm_backend/display_device/udev_object_helper.h index 7269b5d..3adbc7d 100644 --- a/display_server/drivers/hal/core/drm_backend/display_device/udev_object_helper.h +++ b/display_server/drivers/hal/drm_backend/display_device/udev_object_helper.h @@ -20,7 +20,7 @@ #include -#include "base/types.h" +#include "types.h" namespace oewm { static constexpr char defaultSeat[] = "seat0"; diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn b/display_server/drivers/hal/drm_backend/display_gralloc/BUILD.gn similarity index 78% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn rename to display_server/drivers/hal/drm_backend/display_gralloc/BUILD.gn index eb2a085..5e7ca58 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/BUILD.gn +++ b/display_server/drivers/hal/drm_backend/display_gralloc/BUILD.gn @@ -14,8 +14,8 @@ import("//build/gn/fangtian.gni") config("display_gralloc_public_config") { include_dirs = [ - "//display_server/drivers/hal/core/drm_backend/display_gralloc", - "//display_server/drivers/hal/core/drm_backend/include", + "//display_server/drivers/hal/drm_backend/display_gralloc", + "//display_server/drivers/hal/drm_backend/include", "//display_server/drivers/interfaces", "//display_server/drivers/base", @@ -41,14 +41,14 @@ ft_shared_library("display_gralloc") { public_configs = [ ":display_gralloc_public_config", - "//display_server/drivers/hal/core/drm_backend:import_system_gbm_config" + "//display_server/drivers/hal/drm_backend:import_system_gbm_config" ] public_deps = [ - "//display_server/drivers/hal/core/drm_backend:display_drm_dep", + "//display_server/drivers/hal/drm_backend:display_drm_dep", "//display_server/drivers/hal/base:hal_base" ] deps = [ - "//display_server/drivers/hal/core/drm_backend/display_device:display_device", + "//display_server/drivers/hal/drm_backend/display_device:display_device", ] } diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/allocator.cpp similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/allocator.cpp diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h b/display_server/drivers/hal/drm_backend/display_gralloc/allocator.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/allocator.h rename to display_server/drivers/hal/drm_backend/display_gralloc/allocator.h diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/allocator_controller.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/allocator_controller.cpp index e5d10b5..9bb9f43 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/allocator_controller.cpp @@ -19,7 +19,7 @@ #include "dumb_allocator.h" #include "shm_allocator.h" #include "display_type.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h b/display_server/drivers/hal/drm_backend/display_gralloc/allocator_controller.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/allocator_controller.h rename to display_server/drivers/hal/drm_backend/display_gralloc/allocator_controller.h diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc.cpp index 1103cee..564b37a 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc.cpp @@ -29,7 +29,7 @@ #include "allocator_controller.h" #include "display_type.h" -#include "base/log.h" +#include "log.h" using namespace oewm::HDI::DISPLAY; diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc_utils.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc_utils.cpp index 6e17577..9f17e51 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc_utils.cpp @@ -15,7 +15,7 @@ #include "display_gralloc_utils.h" -#include "base/log.h" +#include "log.h" #include "hdi_session.h" // driver diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h b/display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc_utils.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/display_gralloc_utils.h rename to display_server/drivers/hal/drm_backend/display_gralloc/display_gralloc_utils.h diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/dumb_allocator.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/dumb_allocator.cpp index 2fb1414..4151108 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/dumb_allocator.cpp @@ -30,7 +30,7 @@ #include "display_type.h" #include "display_gralloc_private.h" #include "hdi_session.h" -#include "base/log.h" +#include "log.h" namespace oewm { namespace HDI { diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h b/display_server/drivers/hal/drm_backend/display_gralloc/dumb_allocator.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/dumb_allocator.h rename to display_server/drivers/hal/drm_backend/display_gralloc/dumb_allocator.h diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/gbm_allocator.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/gbm_allocator.cpp index cbffff7..949de1d 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/gbm_allocator.cpp @@ -20,8 +20,8 @@ #include "hi_gbm_format.h" #include "display_type.h" #include "buffer_handle.h" -#include "base/log.h" -#include "base/types.h" +#include "log.h" +#include "types.h" #include #include diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h b/display_server/drivers/hal/drm_backend/display_gralloc/gbm_allocator.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/gbm_allocator.h rename to display_server/drivers/hal/drm_backend/display_gralloc/gbm_allocator.h diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/hi_drm_format.cpp similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/hi_drm_format.cpp diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h b/display_server/drivers/hal/drm_backend/display_gralloc/hi_drm_format.h similarity index 98% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h rename to display_server/drivers/hal/drm_backend/display_gralloc/hi_drm_format.h index 8fdf3af..a6f98b9 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_drm_format.h +++ b/display_server/drivers/hal/drm_backend/display_gralloc/hi_drm_format.h @@ -14,7 +14,7 @@ */ #include "display_type.h" -#include "base/log.h" +#include "log.h" #include diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/hi_gbm_format.cpp similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/hi_gbm_format.cpp diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h b/display_server/drivers/hal/drm_backend/display_gralloc/hi_gbm_format.h similarity index 97% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h rename to display_server/drivers/hal/drm_backend/display_gralloc/hi_gbm_format.h index 6d9a8a4..d2a5317 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/hi_gbm_format.h +++ b/display_server/drivers/hal/drm_backend/display_gralloc/hi_gbm_format.h @@ -16,7 +16,7 @@ #pragma once #include "display_type.h" -#include "base/log.h" +#include "log.h" #include diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp b/display_server/drivers/hal/drm_backend/display_gralloc/shm_allocator.cpp similarity index 99% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp rename to display_server/drivers/hal/drm_backend/display_gralloc/shm_allocator.cpp index 73c0a7b..ee979b7 100644 --- a/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.cpp +++ b/display_server/drivers/hal/drm_backend/display_gralloc/shm_allocator.cpp @@ -17,8 +17,8 @@ #include "display_gralloc_private.h" #include "display_gralloc_utils.h" -#include "base/log.h" -#include "base/types.h" +#include "log.h" +#include "types.h" #include "hi_drm_format.h" // TMP #include diff --git a/display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h b/display_server/drivers/hal/drm_backend/display_gralloc/shm_allocator.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/display_gralloc/shm_allocator.h rename to display_server/drivers/hal/drm_backend/display_gralloc/shm_allocator.h diff --git a/display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h b/display_server/drivers/hal/drm_backend/include/display_gralloc_private.h similarity index 100% rename from display_server/drivers/hal/core/drm_backend/include/display_gralloc_private.h rename to display_server/drivers/hal/drm_backend/include/display_gralloc_private.h diff --git a/display_server/drivers/hal/test/BUILD.gn b/display_server/drivers/hal/test/BUILD.gn index f1a590a..5e1de02 100644 --- a/display_server/drivers/hal/test/BUILD.gn +++ b/display_server/drivers/hal/test/BUILD.gn @@ -21,8 +21,8 @@ ft_executable("drm_backend_test") { ] deps = [ - "//display_server/drivers/hal/core/drm_backend:drm_backend", - "//display_server/drivers/hal/core/event_loop:event_loop", + "//display_server/drivers/hal/drm_backend:drm_backend", + "//display_server/drivers/hal/base:hal_base", "//display_server/utils/sync_fence/ft_build:sync_fence", ] -- Gitee