diff --git a/LICENSE b/LICENSE
new file mode 100755
index 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100755
index 0000000000000000000000000000000000000000..5c2643786ecfd65c083b689a61aef1aaa80b063a
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+ LICENSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hardware/BUILD.gn b/hardware/BUILD.gn
new file mode 100755
index 0000000000000000000000000000000000000000..a134d34f00ffe6af1f054b239184a46f7ca10617
--- /dev/null
+++ b/hardware/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright (C) 2021 HiHope Open Source Organization .
+# 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/ohos.gni")
+
+group("hardware_group") {
+ deps = [
+ "//device/soc/rockchip/hardware/isp:isp",
+ "//device/soc/rockchip/hardware/mpp:mpp",
+ "//device/soc/rockchip/hardware/wifi:ap6xxx",
+ ]
+}
diff --git a/hardware/README.en.md b/hardware/README.en.md
new file mode 100644
index 0000000000000000000000000000000000000000..6dd5fcd548bae504026ef2223c23d2862755ffed
--- /dev/null
+++ b/hardware/README.en.md
@@ -0,0 +1,14 @@
+# rockchip hardware
+
+## Introduction
+Media and wifi southbound interface implementation, framework and docking layer library directory。
+## Constraints
+
+Currently, rk3568 are supported.
+## Repositories Involved
+1. device_soc_rockchip/hardware/display
+2. device_soc_rockchip/hardware/gpu
+3. device_soc_rockchip/hardware/isp
+4. device_soc_rockchip/hardware/mpp
+5. device_soc_rockchip/hardware/rga
+6. device_soc_rockchip/hardware/wifi
diff --git a/hardware/README.zh.md b/hardware/README.zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..d9e1468affb8f2f2df34af6ab75d5c42222b5c2d
--- /dev/null
+++ b/hardware/README.zh.md
@@ -0,0 +1,14 @@
+# rockchip hardware组件
+
+#### 简介
+媒体及wifi南向接口实现、框架及对接层库目录。
+#### 约束
+目前支持rk3568
+#### 对应仓库
+
+1. device_soc_rockchip/hardware/display
+2. device_soc_rockchip/hardware/gpu
+3. device_soc_rockchip/hardware/isp
+4. device_soc_rockchip/hardware/mpp
+5. device_soc_rockchip/hardware/rga
+6. device_soc_rockchip/hardware/wifi
diff --git a/hardware/display/BUILD.gn b/hardware/display/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..c66724712d856b48d560816dcc66958b3cdee9ba
--- /dev/null
+++ b/hardware/display/BUILD.gn
@@ -0,0 +1,165 @@
+# Copyright (C) 2021 HiHope Open Source Organization .
+# 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/ohos.gni")
+
+group("display_group") {
+ deps = [
+ ":display_device",
+ ":display_gfx",
+ ":display_gralloc",
+ ":higbm",
+ ]
+}
+
+ohos_static_library("higbm") {
+ sources = [ "src/display_gralloc/hi_gbm.c" ]
+ include_dirs = [
+ "include",
+ "//utils/native/base/include",
+ "//base/hiviewdfx/interfaces/innerkits/libhilog/include",
+ ]
+ output_name = "higbm"
+ cflags = [
+ "-DGRALLOC_GBM_SUPPORT",
+ "-Wno-macro-redefined",
+ ]
+ deps = [
+ "//third_party/libdrm:libdrm",
+ "//utils/native/base:utils",
+ ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+}
+
+ohos_shared_library("display_gralloc") {
+ sources = [
+ "src/display_gralloc/display_gralloc.c",
+ "src/display_gralloc/display_gralloc_gbm.c",
+ "src/display_gralloc/wayland_drm_auth_client.c",
+ ]
+ include_dirs = [
+ "include",
+ "//drivers/peripheral/display/interfaces/include",
+ "//drivers/peripheral/base",
+ "//drivers/framework/include/utils",
+ "//drivers/adapter/uhdf2/osal/include",
+ "//utils/native/base/include",
+ "//foundation/graphic/standard/utils/include",
+ "//foundation/graphic/standard/prebuilts/librarys/drm/include",
+ "//base/hiviewdfx/interfaces/innerkits/libhilog/include",
+ ]
+ output_name = "display_gralloc"
+ cflags = [
+ "-DGRALLOC_GBM_SUPPORT",
+ "-Wno-macro-redefined",
+ ]
+ deps = [
+ ":higbm",
+ "//third_party/libdrm:libdrm",
+ "//third_party/wayland_standard:libwayland_client",
+ "//third_party/weston:drm_auth_protocol",
+ "//utils/native/base:utils",
+ ]
+
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ install_enable = true
+ install_images = [ chipset_base_dir ]
+ subsystem_name = "hdf"
+ part_name = "display_device_driver"
+}
+
+ohos_shared_library("display_gfx") {
+ sources = [ "src/display_gfx/display_gfx.c" ]
+ include_dirs = [
+ "include",
+ "//drivers/peripheral/display/interfaces/include",
+ "//drivers/peripheral/base",
+ "//drivers/framework/include/utils",
+ "//drivers/adapter/uhdf2/adapter/osal/include/",
+ "//utils/native/base/include",
+ "//foundation/graphic/standard/utils/include",
+ "//device/soc/rockchip/hardware/rga/include/",
+ "//base/hiviewdfx/interfaces/innerkits/libhilog/include",
+ ]
+ output_name = "display_gfx"
+ cflags = [ "-Wno-macro-redefined" ]
+ deps = [
+ ":display_gralloc",
+ "//device/soc/rockchip/hardware/rga:librga",
+ "//utils/native/base:utils",
+ ]
+
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ install_enable = true
+ install_images = [ chipset_base_dir ]
+ subsystem_name = "hdf"
+ part_name = "display_device_driver"
+}
+
+ohos_shared_library("display_device") {
+ sources = [
+ "src/display_device/drm_connector.cpp",
+ "src/display_device/drm_crtc.cpp",
+ "src/display_device/drm_device.cpp",
+ "src/display_device/drm_display.cpp",
+ "src/display_device/drm_encoder.cpp",
+ "src/display_device/drm_plane.cpp",
+ "src/display_device/drm_vsync_worker.cpp",
+ "src/display_device/hdi_composer.cpp",
+ "src/display_device/hdi_device_interface.cpp",
+ "src/display_device/hdi_display.cpp",
+ "src/display_device/hdi_drm_composition.cpp",
+ "src/display_device/hdi_drm_layer.cpp",
+ "src/display_device/hdi_gfx_composition.cpp",
+ "src/display_device/hdi_layer.cpp",
+ "src/display_device/hdi_netlink_monitor.cpp",
+ "src/display_device/hdi_session.cpp",
+ ]
+ output_name = "display_device"
+ include_dirs = [
+ "src/display_device",
+ "include",
+ "//drivers/peripheral/display/interfaces/include",
+ "//drivers/peripheral/base",
+ "//drivers/framework/include/utils",
+ "//drivers/adapter/uhdf2/osal/include",
+ "//utils/native/base/include",
+ "//foundation/graphic/standard/utils/include",
+ "//foundation/graphic/standard/prebuilts/librarys/drm/include",
+ "//base/hiviewdfx/interfaces/innerkits/libhilog/include",
+ ]
+ deps = [
+ ":display_gfx",
+ ":display_gralloc",
+ "//third_party/libdrm:libdrm",
+ "//utils/native/base:utils",
+ ]
+ cflags = [ "-Wno-unused-function" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ install_enable = true
+ install_images = [ chipset_base_dir ]
+ subsystem_name = "hdf"
+ part_name = "display_device_driver"
+}
+
+group("display_layer") {
+ deps = [
+ ":display_device",
+ ":display_gfx",
+ ":display_gralloc",
+ ":higbm",
+ ]
+}
diff --git a/hardware/display/include/display_common.h b/hardware/display/include/display_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae6fefa945f5a4d1e68d57a0d73d380de765731d
--- /dev/null
+++ b/hardware/display/include/display_common.h
@@ -0,0 +1,120 @@
+/*
+ * 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 DISP_COMMON_H
+#define DISP_COMMON_H
+#include
+#include
+#include "hilog/log.h"
+#include "stdio.h"
+#ifdef HDF_LOG_TAG
+#undef HDF_LOG_TAG
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#undef LOG_TAG
+#undef LOG_DOMAIN
+#define LOG_TAG "DISP"
+#define LOG_DOMAIN 0xD001400
+
+#ifndef DISPLAY_UNUSED
+#define DISPLAY_UNUSED(x) (void)(x)
+#endif
+
+#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__)
+
+#ifndef DISPLAY_DEBUGLOG
+#define DISPLAY_DEBUGLOG(format, ...) \
+ do { \
+ HILOG_DEBUG(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#ifndef DISPLAY_LOGI
+#define DISPLAY_LOGI(format, ...) \
+ do { \
+ HILOG_INFO(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#ifndef DISPLAY_LOGW
+#define DISPLAY_LOGW(format, ...) \
+ do { \
+ HILOG_WARN(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, __FILENAME__, __LINE__, \
+ ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#ifndef DISPLAY_LOGE
+#define DISPLAY_LOGE(format, ...) \
+ do { \
+ HILOG_ERROR(LOG_CORE, \
+ "\033[0;32;31m" \
+ "[%{public}s@%{public}s:%{public}d] " format "\033[m" \
+ "\n", \
+ __FUNCTION__, __FILENAME__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#ifndef CHECK_NULLPOINTER_RETURN_VALUE
+#define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret) \
+ do { \
+ if ((pointer) == NULL) { \
+ DISPLAY_LOGE("pointer is null and return ret\n"); \
+ return (ret); \
+ } \
+ } while (0)
+#endif
+
+#ifndef CHECK_NULLPOINTER_RETURN
+#define CHECK_NULLPOINTER_RETURN(pointer) \
+ do { \
+ if ((pointer) == NULL) { \
+ DISPLAY_LOGE("pointer is null and return\n"); \
+ return; \
+ } \
+ } while (0)
+#endif
+
+#ifndef DISPLAY_CHK_RETURN
+#define DISPLAY_CHK_RETURN(val, ret, ...) \
+ do { \
+ if (val) { \
+ __VA_ARGS__; \
+ return (ret); \
+ } \
+ } while (0)
+#endif
+
+#ifndef DISPLAY_CHK_RETURN_NOT_VALUE
+#define DISPLAY_CHK_RETURN_NOT_VALUE(val, ret, ...) \
+ do { \
+ if (val) { \
+ __VA_ARGS__; \
+ return; \
+ } \
+ } while (0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DISP_COMMON_H */
diff --git a/hardware/display/include/display_gralloc_private.h b/hardware/display/include/display_gralloc_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5ce9e0cefa946019050cd4a37de2c428dad1a50
--- /dev/null
+++ b/hardware/display/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/hardware/display/src/display_device/drm_connector.cpp b/hardware/display/src/display_device/drm_connector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e13595a1ee1a277cd94b4a8f0e74af4e08d29f3
--- /dev/null
+++ b/hardware/display/src/display_device/drm_connector.cpp
@@ -0,0 +1,352 @@
+/*
+ * 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_connector.h"
+#include
+#include
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+void DrmMode::ConvertToHdiMode(DisplayModeInfo &hdiMode)
+{
+ hdiMode.height = mModeInfo.vdisplay;
+ hdiMode.width = mModeInfo.hdisplay;
+ hdiMode.freshRate = mModeInfo.vrefresh;
+ hdiMode.id = mId;
+}
+
+DrmConnector::DrmConnector(drmModeConnector c, FdPtr &fd)
+ : mId(c.connector_id),
+ mPhyWidth(c.mmWidth),
+ mPhyHeight(c.mmHeight),
+ mEncoderId(c.encoder_id),
+ mConnectState(c.connection),
+ mDrmFdPtr(fd)
+{
+ DISPLAY_DEBUGLOG("encoder_id %{public}d", mEncoderId);
+ DISPLAY_DEBUGLOG("the connect state is %{public}d", mConnectState);
+
+ for (int i = 0; i < c.count_encoders; i++) {
+ mPossibleEncoders.push_back(c.encoders[i]);
+ DISPLAY_DEBUGLOG("add possible encoder id %{public}d", c.encoders[i]);
+ }
+
+ ConvertToHdiType(c.connector_type, mType);
+ ConvertTypeToName(mType, mName);
+ InitModes(c);
+ DISPLAY_DEBUGLOG("name %{public}s", mName.c_str());
+}
+
+void DrmConnector::InitModes(drmModeConnector c)
+{
+ DISPLAY_DEBUGLOG("id %{public}d", mId);
+ mModes.clear();
+ mPreferenceId = INVALID_MODE_ID;
+ for (int i = 0; i < c.count_modes; i++) {
+ drmModeModeInfoPtr mode = c.modes + i;
+ DISPLAY_DEBUGLOG("mode: hdisplay %{public}d, vdisplay %{public}d vrefresh %{public}d type %{public}d",
+ mode->hdisplay, mode->vdisplay, mode->vrefresh, mode->type);
+ if ((mPreferenceId == INVALID_MODE_ID) && (mode->type & DRM_MODE_TYPE_PREFERRED)) {
+ DISPLAY_DEBUGLOG("set it to prefernce id %{public}d", i);
+ mPreferenceId = i;
+ }
+ mModes.emplace(i, DrmMode { *mode, i });
+ }
+ DISPLAY_DEBUGLOG("mode count %{public}zd", mModes.size());
+}
+
+int32_t DrmConnector::Init(DrmDevice &drmDevice)
+{
+ int32_t ret;
+ DrmProperty prop;
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((mDrmFdPtr == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the mDrmFdPtr is NULL"));
+ DISPLAY_CHK_RETURN((mDrmFdPtr->GetFd() == -1), DISPLAY_FAILURE, DISPLAY_LOGE("the drm fd is -1"));
+ // find dpms prop
+ ret = drmDevice.GetConnectorProperty(*this, PROP_DPMS, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get mode prop id"));
+ mPropDpmsId = prop.propId;
+ mDpmsState = prop.value;
+ DISPLAY_DEBUGLOG("dpms state : %{public}" PRIu64 "", mDpmsState);
+ // find the crtcid
+ ret = drmDevice.GetConnectorProperty(*this, PROP_CRTCID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id"));
+ mPropCrtcId = prop.propId;
+ DISPLAY_DEBUGLOG("encoder_id %{public}d", mEncoderId);
+ DISPLAY_DEBUGLOG("mPropCrtcId %{public}d", mPropCrtcId);
+ // find the brightness
+ ret = drmDevice.GetConnectorProperty(*this, PROP_BRIGHTNESS, prop);
+ if (ret == DISPLAY_SUCCESS) {
+ mPropBrightnessId = prop.propId;
+ mBrightnessLevel = static_cast(prop.value);
+ DISPLAY_DEBUGLOG("prop brightness is %{public}d, level is %{public}d", mPropBrightnessId, mBrightnessLevel);
+ } else {
+ DISPLAY_LOGW("can not get the brightness prop, can not set the brightness");
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmConnector::GetBrightness(uint32_t& level)
+{
+ if (mPropBrightnessId == DRM_INVALID_ID) {
+ DISPLAY_LOGE("the prop id of brightness is invalid");
+ return DISPLAY_NOT_SUPPORT;
+ }
+ level = mBrightnessLevel;
+ return DISPLAY_SUCCESS;
+}
+
+const int BACKLIGHT_MIN = 10;
+int32_t DrmConnector::SetBrightness(uint32_t level)
+{
+ static int32_t brFd = 0;
+ const int32_t buffer_size = 10; /* buffer size */
+ char buffer[buffer_size];
+
+ DISPLAY_DEBUGLOG("set %{public}d", level);
+ if (mPropBrightnessId == DRM_INVALID_ID) {
+ DISPLAY_LOGE("the prop id of brightness is invalid");
+ return DISPLAY_NOT_SUPPORT;
+ }
+ if (brFd <= 0) {
+ brFd = open("/sys/class/backlight/backlight/brightness", O_RDWR);
+ if (brFd < 0) {
+ DISPLAY_LOGE("oepn Brightness file failed\n");
+ return DISPLAY_NOT_SUPPORT;
+ }
+ }
+ errno_t ret = memset_s(buffer, sizeof(buffer), 0, sizeof(buffer));
+ if (ret != EOK) {
+ DISPLAY_LOGE("memset_s failed\n");
+ return DISPLAY_FAILURE;
+ }
+ if (level < BACKLIGHT_MIN) {
+ level = BACKLIGHT_MIN;
+ }
+ int bytes = sprintf_s(buffer, sizeof(buffer), "%d\n", level);
+ if (bytes < 0) {
+ DISPLAY_LOGE("change failed\n");
+ return DISPLAY_FAILURE;
+ }
+ write(brFd, buffer, bytes);
+ mBrightnessLevel = level;
+ return DISPLAY_SUCCESS;
+}
+
+void DrmConnector::GetDisplayCap(DisplayCapability &cap)
+{
+ cap.phyHeight = mPhyHeight;
+ cap.phyWidth = mPhyWidth;
+ cap.type = mType;
+ memcpy_s(cap.name, sizeof(cap.name), mName.c_str(), mName.size());
+ if (mName.size() >= sizeof(cap.name)) {
+ cap.name[sizeof(cap.name) - 1] = 0;
+ } else {
+ cap.name[mName.size()] = 0;
+ }
+ cap.supportLayers = mSupportLayers;
+ cap.virtualDispCount = mVirtualDispCount;
+ cap.supportWriteBack = mSupportWriteBack;
+ cap.propertyCount = mPropertyCount;
+}
+
+void DrmConnector::ConvertTypeToName(uint32_t type, std::string &name)
+{
+ DISPLAY_DEBUGLOG("type %{public}d", type);
+ switch (type) {
+ case DISP_INTF_VGA:
+ name = "VGA";
+ break;
+ case DISP_INTF_HDMI:
+ name = "HDMI";
+ break;
+ case DISP_INTF_MIPI:
+ name = "MIPI";
+ break;
+ default:
+ name = "Unknown";
+ break;
+ }
+}
+
+void DrmConnector::ConvertToHdiType(uint32_t type, InterfaceType &hdiType)
+{
+ switch (type) {
+ case DRM_MODE_CONNECTOR_VGA:
+ hdiType = DISP_INTF_VGA;
+ break;
+ case DRM_MODE_CONNECTOR_DSI:
+ hdiType = DISP_INTF_MIPI;
+ break;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ hdiType = DISP_INTF_HDMI;
+ break;
+ default:
+ hdiType = DISP_INTF_BUTT;
+ break;
+ }
+}
+int32_t DrmConnector::TryPickEncoder(IdMapPtr &encoders, uint32_t encoderId, IdMapPtr &crtcs,
+ uint32_t &crtcId)
+{
+ int ret;
+ auto encoderIter = encoders.find(encoderId);
+ if (encoderIter == encoders.end()) {
+ DISPLAY_LOGW("can not find encoder for id : %{public}d", encoderId);
+ return DISPLAY_FAILURE;
+ }
+
+ auto &encoder = encoderIter->second;
+ DISPLAY_DEBUGLOG("connector : %{public}d encoder : %{public}d", mId, encoder->GetId());
+ ret = encoder->PickIdleCrtcId(crtcs, crtcId);
+ DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS,
+ DISPLAY_DEBUGLOG("connector : %{public}d pick encoder : %{public}d", mId, encoder->GetId()));
+ return DISPLAY_FAILURE;
+}
+
+int32_t DrmConnector::PickIdleCrtcId(IdMapPtr &encoders, IdMapPtr &crtcs, uint32_t &crtcId)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_DEBUGLOG("encoder_id %{public}d", mEncoderId);
+ int ret = TryPickEncoder(encoders, mEncoderId, crtcs, crtcId);
+ DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS,
+ DISPLAY_DEBUGLOG("connector : %{public}d pick endcoder : %{public}d crtcId : %{public}d",
+ mId, mEncoderId, crtcId));
+
+ for (auto encoder : mPossibleEncoders) {
+ ret = TryPickEncoder(encoders, encoder, crtcs, crtcId);
+ DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS,
+ DISPLAY_DEBUGLOG("connector : %{public}d pick endcoder : %{public}d crtcId : %{public}d", mId, mEncoderId,
+ crtcId));
+ }
+
+ DISPLAY_LOGW("can not pick a crtc for connector");
+ return DISPLAY_FAILURE;
+}
+
+int32_t DrmConnector::UpdateModes()
+{
+ int drmFd = mDrmFdPtr->GetFd();
+ drmModeConnectorPtr c = drmModeGetConnector(drmFd, mId);
+ DISPLAY_CHK_RETURN((c == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get connector"));
+ mConnectState = c->connection;
+ // init the modes
+ InitModes(*c);
+ drmModeFreeConnector(c);
+ return DISPLAY_SUCCESS;
+}
+
+bool DrmConnector::HandleHotplug()
+{
+ int drmFd = mDrmFdPtr->GetFd();
+ drmModeConnectorPtr c = drmModeGetConnector(drmFd, mId);
+ DISPLAY_CHK_RETURN((c == nullptr), false, DISPLAY_LOGE("can not get connector"));
+ if (mConnectState == c->connection) {
+ drmModeFreeConnector(c);
+ return false;
+ } else {
+ mConnectState = c->connection;
+ InitModes(*c);
+ drmModeFreeConnector(c);
+ return true;
+ }
+}
+int32_t DrmConnector::GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes)
+{
+ DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
+ *num = static_cast(mModes.size());
+ if (modes != nullptr) {
+ int i = 0;
+ for (const auto &modeMap : mModes) {
+ DrmMode mode = modeMap.second;
+ mode.ConvertToHdiMode(*(modes + i));
+ i++;
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmConnector::SetDpmsState(uint64_t dmps)
+{
+ DISPLAY_DEBUGLOG("dmps %{public}" PRIu64 "", dmps);
+ int ret = drmModeConnectorSetProperty(mDrmFdPtr->GetFd(), mId, mPropDpmsId, dmps);
+ DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("can not set dpms"));
+ mDpmsState = dmps;
+ return DISPLAY_SUCCESS;
+}
+
+bool DrmConnector::IsConnected()
+{
+ return (mConnectState == DRM_MODE_CONNECTED);
+}
+
+int32_t DrmConnector::GetModeFromId(int32_t id, DrmMode &mode)
+{
+ DISPLAY_DEBUGLOG();
+ auto iter = mModes.find(id);
+ if (iter == mModes.end()) {
+ return DISPLAY_FAILURE;
+ }
+ mode = mModes[id];
+ return DISPLAY_SUCCESS;
+}
+
+std::unique_ptr DrmConnector::GetModeBlockFromId(int32_t id)
+{
+ DISPLAY_DEBUGLOG("id %{public}d", id);
+ auto iter = mModes.find(id);
+ DISPLAY_CHK_RETURN((iter == mModes.end()), nullptr, DISPLAY_LOGE("can not the mode %{public}d", id));
+ return std::make_unique(mModes[id]);
+}
+
+DrmModeBlock::DrmModeBlock(DrmMode &mode)
+{
+ DISPLAY_DEBUGLOG();
+ Init(mode);
+}
+
+int32_t DrmModeBlock::Init(DrmMode &mode)
+{
+ int ret;
+ int drmFd;
+ drmFd = DrmDevice::GetDrmFd();
+ DISPLAY_CHK_RETURN((drmFd < 0), DISPLAY_FAILURE, DISPLAY_LOGE("the drm fd is invalid"));
+ drmModeModeInfo modeInfo = *(mode.GetModeInfoPtr());
+ ret = drmModeCreatePropertyBlob(drmFd, static_cast(&modeInfo), sizeof(modeInfo), &mBlockId);
+ DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("create property blob failed"));
+ DISPLAY_DEBUGLOG("mBlockId %{public}d", mBlockId);
+ return DISPLAY_SUCCESS;
+}
+
+DrmModeBlock::~DrmModeBlock()
+{
+ DISPLAY_DEBUGLOG("mBlockId %{public}d", mBlockId);
+ int drmFd;
+ drmFd = DrmDevice::GetDrmFd();
+ if ((mBlockId != DRM_INVALID_ID) && (drmFd >= 0)) {
+ int ret = drmModeDestroyPropertyBlob(drmFd, mBlockId);
+ if (ret != 0) {
+ DISPLAY_LOGE("destroy property blob failed errno %{public}d", errno);
+ }
+ } else {
+ DISPLAY_LOGE("can not destruct the block id %{public}d drmFd %{public}d", mBlockId, drmFd);
+ }
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_connector.h b/hardware/display/src/display_device/drm_connector.h
new file mode 100644
index 0000000000000000000000000000000000000000..b282a755d19446c3930e6f2d8eb7a0f9d6df697f
--- /dev/null
+++ b/hardware/display/src/display_device/drm_connector.h
@@ -0,0 +1,138 @@
+/*
+ * 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 DRM_CONNECTOR_H
+#define DRM_CONNECTOR_H
+#include
+#include
+#include
+#include
+#include
+#include "display_type.h"
+#include "drm_encoder.h"
+#include "hdi_device_common.h"
+#include "hdi_shared_fd.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const std::string PROP_DPMS = "DPMS";
+const std::string PROP_CRTCID = "CRTC_ID";
+const std::string PROP_BRIGHTNESS = "brightness";
+class DrmDevice;
+class DrmModeBlock;
+
+class DrmMode {
+public:
+ DrmMode() {};
+ DrmMode(drmModeModeInfo &modeInfo, uint32_t id) : mModeInfo(modeInfo), mId(id) {}
+ virtual ~DrmMode() {};
+ drmModeModeInfoPtr GetModeInfoPtr()
+ {
+ return &mModeInfo;
+ }
+ void ConvertToHdiMode(DisplayModeInfo &hdiMode);
+
+private:
+ drmModeModeInfo mModeInfo = { 0 };
+ int32_t mId = -1;
+};
+
+class DrmModeBlock {
+public:
+ explicit DrmModeBlock(DrmMode &mode);
+ virtual ~DrmModeBlock();
+ int32_t Init(DrmMode &mode);
+ uint32_t GetBlockId() const
+ {
+ return mBlockId;
+ }
+
+private:
+ uint32_t mBlockId = DRM_INVALID_ID;
+};
+
+class DrmConnector {
+public:
+ DrmConnector(drmModeConnector c, FdPtr &fd);
+ virtual ~DrmConnector() {};
+ uint32_t GetId() const
+ {
+ return mId;
+ }
+ uint32_t GetEncoderId() const
+ {
+ return mEncoderId;
+ }
+ void GetDisplayCap(DisplayCapability &cap);
+ int32_t Init(DrmDevice &drmDevice);
+ int32_t PickIdleCrtcId(IdMapPtr &encoders, IdMapPtr &crtcs, uint32_t &crtcId);
+ int32_t GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes);
+ int32_t GetPreferenceId() const
+ {
+ return mPreferenceId;
+ }
+ uint32_t GetPropCrtcId() const
+ {
+ return mPropCrtcId;
+ }
+ int32_t TryPickEncoder(IdMapPtr &encoders, uint32_t encoderId, IdMapPtr &crtcs,
+ uint32_t &crtcId);
+ // update modes will reset the preference mode id and active mode id
+ int32_t UpdateModes();
+ std::unique_ptr GetModeBlockFromId(int32_t id);
+ int32_t GetModeFromId(int32_t id, DrmMode &mode);
+ uint64_t GetDpmsState() const
+ {
+ return mDpmsState;
+ }
+ int32_t SetDpmsState(uint64_t dmps);
+ bool IsConnected();
+ bool HandleHotplug();
+
+ int32_t GetBrightness(uint32_t& level);
+ int32_t SetBrightness(uint32_t level);
+
+private:
+ static void ConvertTypeToName(uint32_t type, std::string &name);
+ static void ConvertToHdiType(uint32_t type, InterfaceType &hdiType);
+
+ void InitModes(drmModeConnector c);
+ uint32_t mId;
+ InterfaceType mType;
+ uint32_t mPhyWidth;
+ uint32_t mPhyHeight;
+ uint32_t mSupportLayers = 0;
+ uint32_t mVirtualDispCount = 0;
+ bool mSupportWriteBack = false;
+ uint32_t mPropertyCount = 0;
+ uint32_t mEncoderId;
+ std::vector mPossibleEncoders;
+ std::string mName;
+ drmModeConnection mConnectState;
+ uint32_t mPropDpmsId = DRM_INVALID_ID;
+ uint64_t mDpmsState = 0;
+ uint32_t mPropCrtcId = DRM_INVALID_ID;
+ uint32_t mPropBrightnessId = DRM_INVALID_ID;
+ uint32_t mBrightnessLevel = 0;
+ std::unordered_map mModes;
+ int32_t mPreferenceId = INVALID_MODE_ID;
+
+ FdPtr mDrmFdPtr;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+#endif // DRM_CONNECTOR_H
diff --git a/hardware/display/src/display_device/drm_crtc.cpp b/hardware/display/src/display_device/drm_crtc.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..42a4c8551d8633029657c2dd720658dcf557758a
--- /dev/null
+++ b/hardware/display/src/display_device/drm_crtc.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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_crtc.h"
+#include "display_common.h"
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+struct PlaneMaskName planeMaskNames[] = {
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER0_MASK, "Cluster0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER1_MASK, "Cluster1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART0_MASK, "Esmart0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART1_MASK, "Esmart1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART0_MASK, "Smart0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART1_MASK, "Smart1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_Unknown, "unknown" },
+};
+
+DrmCrtc::DrmCrtc(drmModeCrtcPtr c, uint32_t pipe) : mId(c->crtc_id), mPipe(pipe), mPlaneMask(0)
+{
+}
+
+int32_t DrmCrtc::Init(DrmDevice &drmDevice)
+{
+ DISPLAY_DEBUGLOG();
+ int32_t ret;
+ DrmProperty prop;
+ ret = drmDevice.GetCrtcProperty(*this, PROP_MODEID, prop);
+ mModePropId = prop.propId;
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get mode prop id"));
+
+ ret = drmDevice.GetCrtcProperty(*this, PROP_OUTFENCE, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id"));
+ mOutFencePropId = prop.propId;
+
+ ret = drmDevice.GetCrtcProperty(*this, PROP_ACTIVE, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get out fence prop id"));
+ mActivePropId = prop.propId;
+
+ // Plane mask
+ mPlaneMask = 0;
+ ret = drmDevice.GetCrtcProperty(*this, "PLANE_MASK", prop);
+ if (ret != DISPLAY_SUCCESS) {
+ DISPLAY_LOGE("Failed to get plane_mask property");
+ } else {
+ for (int i = 0; i < static_cast(ARRAY_SIZE(planeMaskNames)); i++) {
+ for (auto &drmEnum : prop.enums) {
+ if (!strncmp(drmEnum.name.c_str(), (const char*)planeMaskNames[i].name,
+ strlen(drmEnum.name.c_str())) && (prop.value & (1LL << drmEnum.value)) > 0) {
+ mPlaneMask |= static_cast(planeMaskNames[i].mask);
+ DISPLAY_LOGI("crtc id %{public}d, plane name %{public}s value %{public}llx",
+ GetId(), (const char*)planeMaskNames[i].name,
+ (long long)planeMaskNames[i].mask);
+ }
+ }
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmCrtc::BindToDisplay(uint32_t id)
+{
+ DISPLAY_CHK_RETURN((mDisplayId != INVALIDE_DISPLAY_ID), DISPLAY_FAILURE,
+ DISPLAY_LOGE("the crtc has bind to %{public}d", mDisplayId));
+ mDisplayId = id;
+ return DISPLAY_SUCCESS;
+}
+
+void DrmCrtc::UnBindDisplay(uint32_t id)
+{
+ DISPLAY_DEBUGLOG();
+ if (mDisplayId == id) {
+ mDisplayId = INVALIDE_DISPLAY_ID;
+ } else {
+ DISPLAY_LOGE("can not unbind");
+ }
+}
+
+bool DrmCrtc::CanBind()
+{
+ return (mDisplayId == INVALIDE_DISPLAY_ID);
+}
+
+int32_t DrmCrtc::SetActivieMode(int32_t id)
+{
+ DISPLAY_DEBUGLOG("set activie modeid to %{public}d", id);
+ DISPLAY_CHK_RETURN((id > 0), DISPLAY_PARAM_ERR, DISPLAY_LOGE("id %{public}d is invalid ", id));
+ if (mActiveModeId != id) {
+ mNeedModeSet = true;
+ }
+ mActiveModeId = id;
+ return DISPLAY_SUCCESS;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_crtc.h b/hardware/display/src/display_device/drm_crtc.h
new file mode 100755
index 0000000000000000000000000000000000000000..8f923326860ea4b04c8c21d073c525f203ae543e
--- /dev/null
+++ b/hardware/display/src/display_device/drm_crtc.h
@@ -0,0 +1,90 @@
+/*
+ * 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 DRM_CRTC_H
+#define DRM_CRTC_H
+#include
+#include
+#include
+#include
+#include "hdi_device_common.h"
+#include "hdi_display.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const std::string PROP_ACTIVE = "ACTIVE";
+const std::string PROP_MODEID = "MODE_ID";
+const std::string PROP_OUTFENCE = "OUT_FENCE_PTR";
+
+class DrmDevice;
+
+class DrmCrtc {
+public:
+ DrmCrtc(drmModeCrtcPtr c, uint32_t pipe);
+ virtual ~DrmCrtc() {};
+ int32_t BindToDisplay(uint32_t id);
+ void UnBindDisplay(uint32_t id);
+ bool CanBind();
+ uint32_t GetId() const
+ {
+ return mId;
+ }
+ uint32_t GetModePropId() const
+ {
+ return mModePropId;
+ }
+ uint32_t GetOutFencePropId() const
+ {
+ return mOutFencePropId;
+ }
+ uint32_t GetActivePropId() const
+ {
+ return mActivePropId;
+ }
+ uint32_t GetPipe() const
+ {
+ return mPipe;
+ }
+ int32_t Init(DrmDevice &drmDevice);
+ int32_t SetActivieMode(int32_t id);
+ int32_t GetActiveModeId() const
+ {
+ return mActiveModeId;
+ }
+ bool NeedModeSet()
+ {
+ return mNeedModeSet;
+ }
+ uint32_t GetPlaneMask()
+ {
+ return mPlaneMask;
+ }
+private:
+ uint32_t mId = 0;
+ uint32_t mModePropId = 0;
+ uint32_t mOutFencePropId = 0;
+ uint32_t mActivePropId = 0;
+ uint32_t mDisplayId = INVALIDE_DISPLAY_ID;
+ uint32_t mPipe = 0;
+ int32_t mActiveModeId = INVALID_MODE_ID;
+ bool mNeedModeSet = false;
+ uint32_t mPlaneMask = 0;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // DRM_CRTC_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/drm_device.cpp b/hardware/display/src/display_device/drm_device.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..fafe456f24b849392d5797f513810558b35152c6
--- /dev/null
+++ b/hardware/display/src/display_device/drm_device.cpp
@@ -0,0 +1,360 @@
+/*
+ * 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_device.h"
+#include
+#include
+#include
+#include
+#include
+#include "display_common.h"
+#include "drm_display.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+FdPtr DrmDevice::mDrmFd = nullptr;
+std::shared_ptr DrmDevice::mInstance;
+
+std::shared_ptr DrmDevice::Create()
+{
+ DISPLAY_DEBUGLOG();
+ if (mDrmFd == nullptr) {
+ const std::string name("rockchip");
+ int drmFd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); // drmOpen(name.c_str(), nullptr);
+ if (drmFd < 0) {
+ DISPLAY_LOGE("drm file:%{public}s open failed %{public}s", name.c_str(), strerror(errno));
+ return nullptr;
+ }
+ DISPLAY_DEBUGLOG("the drm fd is %{public}d", drmFd);
+ mDrmFd = std::make_shared(drmFd);
+ }
+ if (mInstance == nullptr) {
+ mInstance = std::make_shared();
+ }
+ return mInstance;
+}
+
+int DrmDevice::GetDrmFd()
+{
+ if (mDrmFd == nullptr) {
+ DISPLAY_LOGE("the drmfd is null not open");
+ return -1;
+ }
+ return mDrmFd->GetFd();
+}
+
+using PixelFormatConvertTbl = struct PixFmtConvertTbl {
+ uint32_t drmFormat;
+ PixelFormat pixFormat;
+};
+
+uint32_t DrmDevice::ConvertToDrmFormat(PixelFormat fmtIn)
+{
+ static const PixelFormatConvertTbl convertTable[] = {
+ {DRM_FORMAT_XBGR8888, PIXEL_FMT_RGBX_8888}, {DRM_FORMAT_ABGR8888, 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_ARGB8888, 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},
+ };
+ 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;
+ }
+ }
+ DISPLAY_DEBUGLOG("fmtIn %{public}d, outFmt %{public}d", fmtIn, fmtOut);
+ return fmtOut;
+}
+
+DrmDevice::DrmDevice() {}
+
+int32_t DrmDevice::GetCrtcProperty(const DrmCrtc &crtc, const std::string &name, DrmProperty &prop)
+{
+ return GetProperty(crtc.GetId(), DRM_MODE_OBJECT_CRTC, name, prop);
+}
+
+int32_t DrmDevice::GetConnectorProperty(const DrmConnector &connector, const std::string &name, DrmProperty &prop)
+{
+ return GetProperty(connector.GetId(), DRM_MODE_OBJECT_CONNECTOR, name, prop);
+}
+
+int32_t DrmDevice::GetPlaneProperty(const DrmPlane &plane, const std::string &name, DrmProperty &prop)
+{
+ return GetProperty(plane.GetId(), DRM_MODE_OBJECT_PLANE, name, prop);
+}
+
+int32_t DrmDevice::GetProperty(uint32_t objId, uint32_t objType, const std::string &name, DrmProperty &prop)
+{
+ drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(GetDrmFd(), objId, objType);
+ DISPLAY_CHK_RETURN((!props), DISPLAY_FAILURE, DISPLAY_LOGE("can not get properties"));
+ bool found = false;
+ for (uint32_t i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr p = drmModeGetProperty(GetDrmFd(), props->props[i]);
+ if (strcmp(p->name, name.c_str()) == 0) {
+ found = true;
+ prop.propId = p->prop_id;
+ prop.value = props->prop_values[i];
+ prop.name = p->name;
+ prop.flags = p->flags;
+
+ for (int i = 0; i < p->count_values; ++i) {
+ prop.values.push_back(p->values[i]);
+ }
+ for (int i = 0; i < p->count_enums; ++i) {
+ prop.enums.push_back(DrmPropertyEnum(&p->enums[i]));
+ }
+
+ for (int i = 0; i < p->count_blobs; ++i) {
+ prop.blob_ids.push_back(p->blob_ids[i]);
+ }
+ if (prop.flags & DRM_MODE_PROP_RANGE) {
+ prop.type = static_cast(DrmPropertyType::DRM_PROPERTY_TYPE_INT);
+ } else if (prop.flags & DRM_MODE_PROP_ENUM) {
+ prop.type = static_cast(DrmPropertyType::DRM_PROPERTY_TYPE_ENUM);
+ } else if (prop.flags & DRM_MODE_PROP_OBJECT) {
+ prop.type = static_cast(DrmPropertyType::DRM_PROPERTY_TYPE_OBJECT);
+ } else if (prop.flags & DRM_MODE_PROP_BLOB) {
+ prop.type = static_cast(DrmPropertyType::DRM_PROPERTY_TYPE_BLOB);
+ } else if (prop.flags & DRM_MODE_PROP_BITMASK) {
+ prop.type = static_cast(DrmPropertyType::DRM_PROPERTY_TYPE_BITMASK);
+ }
+ }
+ drmModeFreeProperty(p);
+ }
+ drmModeFreeObjectProperties(props);
+ return found ? DISPLAY_SUCCESS : DISPLAY_NOT_SUPPORT;
+}
+
+int32_t DrmDevice::Init()
+{
+ int ret = drmSetClientCap(GetDrmFd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ DISPLAY_CHK_RETURN((ret), DISPLAY_FAILURE,
+ DISPLAY_LOGE("DRM_CLIENT_CAP_UNIVERSAL_PLANES set failed %{public}s", strerror(errno)));
+ ret = drmSetClientCap(GetDrmFd(), DRM_CLIENT_CAP_ATOMIC, 1);
+ DISPLAY_CHK_RETURN((ret), DISPLAY_FAILURE,
+ DISPLAY_LOGE("DRM_CLIENT_CAP_ATOMIC set failed %{public}s", strerror(errno)));
+
+ ret = drmSetMaster(GetDrmFd());
+ DISPLAY_CHK_RETURN((ret), DISPLAY_FAILURE, DISPLAY_LOGE("can not set to master errno : %{public}d", errno));
+ DISPLAY_LOGE("chenyf master");
+ ret = drmIsMaster(GetDrmFd());
+ DISPLAY_CHK_RETURN((!ret), DISPLAY_FAILURE, DISPLAY_LOGE("is not master : %{public}d", errno));
+
+ return DISPLAY_SUCCESS;
+}
+
+void DrmDevice::DeInit()
+{
+ mDisplays.clear();
+ mCrtcs.clear();
+}
+
+void DrmDevice::FindAllCrtc(const drmModeResPtr &res)
+{
+ DISPLAY_CHK_RETURN_NOT_VALUE((res == nullptr), DISPLAY_LOGE("the res is null"));
+ mCrtcs.clear();
+ for (int i = 0; i < res->count_crtcs; i++) {
+ drmModeCrtcPtr crtc = drmModeGetCrtc(GetDrmFd(), res->crtcs[i]);
+ if (!crtc) {
+ DISPLAY_LOGE("can not get crtc %{public}d", i);
+ continue;
+ }
+ uint32_t crtc_id = crtc->crtc_id;
+ std::shared_ptr drmCrtc = std::make_shared(crtc, i);
+ int ret = drmCrtc->Init(*this);
+ drmModeFreeCrtc(crtc);
+ if (ret != DISPLAY_SUCCESS) {
+ DISPLAY_LOGE("crtc %{public}d init failed", i);
+ continue;
+ }
+ mCrtcs.emplace(crtc_id, std::move(drmCrtc));
+ }
+}
+
+void DrmDevice::FindAllEncoder(const drmModeResPtr &res)
+{
+ DISPLAY_CHK_RETURN_NOT_VALUE((res == nullptr), DISPLAY_LOGE("the res is null"));
+ mEncoders.clear();
+ for (int i = 0; i < res->count_encoders; i++) {
+ drmModeEncoderPtr encoder = drmModeGetEncoder(GetDrmFd(), res->encoders[i]);
+ if (!encoder) {
+ DISPLAY_LOGE("can not get encoder %{public}d", i);
+ continue;
+ }
+ std::shared_ptr drmEncoder = std::make_shared(*encoder);
+ mEncoders.emplace(encoder->encoder_id, std::move(drmEncoder));
+ drmModeFreeEncoder(encoder);
+ }
+ DISPLAY_DEBUGLOG("find encoder count %{public}zd", mEncoders.size());
+}
+
+void DrmDevice::FindAllConnector(const drmModeResPtr &res)
+{
+ DISPLAY_CHK_RETURN_NOT_VALUE((res == nullptr), DISPLAY_LOGE("the res is null"));
+ mConnectors.clear();
+ int ret;
+ for (int i = 0; i < res->count_connectors; i++) {
+ drmModeConnectorPtr connector = drmModeGetConnector(GetDrmFd(), res->connectors[i]);
+ if (!connector) {
+ DISPLAY_LOGE("can not get connector mode %{public}d", i);
+ continue;
+ }
+ std::shared_ptr drmConnector = std::make_shared(*connector, mDrmFd);
+ ret = drmConnector->Init(*this);
+ drmModeFreeConnector(connector);
+ if (ret != DISPLAY_SUCCESS) {
+ continue;
+ }
+ int connectorId = drmConnector->GetId();
+ mConnectors.emplace(connectorId, std::move(drmConnector));
+ }
+ DISPLAY_DEBUGLOG("find connector count %{public}zd", mConnectors.size());
+}
+
+void DrmDevice::FindAllPlane()
+{
+ mPlanes.clear();
+ int ret;
+ drmModePlaneResPtr planeRes = drmModeGetPlaneResources(GetDrmFd());
+ DISPLAY_CHK_RETURN_NOT_VALUE((planeRes == nullptr), DISPLAY_LOGE("can not get plane resource"));
+ DISPLAY_DEBUGLOG("count_planes %{public}d", planeRes->count_planes);
+ for (uint32_t i = 0; i < planeRes->count_planes; i++) {
+ drmModePlanePtr p = drmModeGetPlane(GetDrmFd(), planeRes->planes[i]);
+ if (!p) {
+ DISPLAY_LOGE("can not get plane %{public}d", i);
+ continue;
+ }
+ std::shared_ptr drmPlane = std::make_shared(*p);
+ DISPLAY_DEBUGLOG();
+ ret = drmPlane->Init(*this);
+ DISPLAY_DEBUGLOG();
+ drmModeFreePlane(p);
+ if (ret != DISPLAY_SUCCESS) {
+ DISPLAY_LOGE("drm plane %{public}d init failed", i);
+ continue;
+ }
+ mPlanes.emplace_back(std::move(drmPlane));
+ }
+ DISPLAY_DEBUGLOG("find plane count %{public}zd", mPlanes.size());
+}
+
+std::shared_ptr DrmDevice::GetDrmEncoderFromId(uint32_t id)
+{
+ return nullptr;
+}
+
+std::shared_ptr DrmDevice::GetDrmConnectorFromId(uint32_t id)
+{
+ return nullptr;
+}
+
+std::shared_ptr DrmDevice::GetDrmCrtcFromId(uint32_t id)
+{
+ return nullptr;
+}
+
+std::vector> DrmDevice::GetDrmPlane(uint32_t pipe, uint32_t type)
+{
+ std::vector> planes;
+ for (const auto &plane : mPlanes) {
+ if (plane->IsIdle() && ((1 << pipe) & plane->GetPossibleCrtcs()) && (type == plane->GetType())) {
+ planes.push_back(plane);
+ }
+ }
+ DISPLAY_DEBUGLOG("the planes count %{public}zd", planes.size());
+ return planes;
+}
+
+bool DrmDevice::HandleHotplug(uint32_t dispId, bool plugIn)
+{
+ uint32_t find = 0;
+ uint32_t connectorId;
+
+ for (auto &dispConnectorIdMap : dispConnectorIdMaps_) {
+ if (dispConnectorIdMap.first == dispId) {
+ connectorId = dispConnectorIdMap.second;
+ find = 1;
+ break;
+ }
+ }
+ if (find) {
+ for (auto &connectorPair : mConnectors) {
+ auto connector = connectorPair.second;
+ if (connectorId == connector->GetId()) {
+ if (connector->HandleHotplug() == true) {
+ connector->Init(*this);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+std::unordered_map> DrmDevice::DiscoveryDisplay()
+{
+ uint32_t dispId;
+ uint32_t connectorId;
+
+ dispConnectorIdMaps_.clear();
+ mDisplays.clear();
+ drmModeResPtr res = drmModeGetResources(GetDrmFd());
+ DISPLAY_CHK_RETURN((res == nullptr), mDisplays, DISPLAY_LOGE("can not get drm resource"));
+ // discovery all drm resource
+ FindAllCrtc(res);
+ FindAllEncoder(res);
+ FindAllConnector(res);
+ FindAllPlane();
+ DISPLAY_DEBUGLOG();
+ // travel all connector
+ for (auto &connectorPair : mConnectors) {
+ auto connector = connectorPair.second;
+ uint32_t crtcId = 0;
+ int32_t ret = connector->PickIdleCrtcId(mEncoders, mCrtcs, crtcId);
+ if (ret != DISPLAY_SUCCESS) {
+ continue;
+ }
+ DISPLAY_DEBUGLOG();
+
+ auto crtcIter = mCrtcs.find(crtcId);
+ if (crtcIter == mCrtcs.end()) {
+ DISPLAY_LOGE("can not find crtc for the id %{public}d", connector->GetId());
+ continue;
+ }
+ DISPLAY_DEBUGLOG();
+ auto crtc = crtcIter->second;
+ DISPLAY_DEBUGLOG("crtc %{public}p", crtc.get());
+ // create the display
+ std::shared_ptr display = std::make_shared(connector, crtc, mInstance);
+ DISPLAY_DEBUGLOG();
+ display->Init();
+ dispId = display->GetId();
+ connectorId = connector->GetId();
+ mDisplays.emplace(dispId, std::move(display));
+ dispConnectorIdMaps_.emplace(dispId, connectorId);
+ }
+ DISPLAY_DEBUGLOG("find display size %{public}zd", mDisplays.size());
+ return mDisplays;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_device.h b/hardware/display/src/display_device/drm_device.h
new file mode 100755
index 0000000000000000000000000000000000000000..875cacb5c9b22a6f079b9ba4397955e30139c7e7
--- /dev/null
+++ b/hardware/display/src/display_device/drm_device.h
@@ -0,0 +1,100 @@
+/*
+ * 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 DRM_DEVICE_H
+#define DRM_DEVICE_H
+#include
+#include
+#include
+#include
+#include "drm_connector.h"
+#include "drm_crtc.h"
+#include "drm_encoder.h"
+#include "drm_plane.h"
+#include "hdi_device_common.h"
+#include "hdi_device_interface.h"
+#include "hdi_display.h"
+#include "hdi_shared_fd.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+class DrmPropertyEnum {
+public:
+ explicit DrmPropertyEnum(drm_mode_property_enum *e) : value(e->value), name(e->name) {
+ }
+ ~DrmPropertyEnum() {};
+
+ uint64_t value;
+ std::string name;
+};
+
+struct DrmProperty {
+ uint32_t propId;
+ uint64_t value;
+ uint32_t type;
+ uint32_t flags;
+ std::string name;
+ std::vector values;
+ std::vector enums;
+ std::vector blob_ids;
+};
+
+class DrmDevice : public HdiDeviceInterface, std::enable_shared_from_this {
+public:
+ static std::shared_ptr Create();
+ static uint32_t ConvertToDrmFormat(PixelFormat fmtIn);
+ static int GetDrmFd();
+ DrmDevice();
+ ~DrmDevice() override {}
+
+ std::vector> GetDrmPlane(uint32_t pipe, uint32_t type);
+
+ int32_t GetCrtcProperty(const DrmCrtc &crtc, const std::string &name, DrmProperty &prop);
+ int32_t GetConnectorProperty(const DrmConnector &connector, const std::string &name, DrmProperty &prop);
+ int32_t GetPlaneProperty(const DrmPlane &plane, const std::string &name, DrmProperty &prop);
+
+ int32_t GetProperty(uint32_t objId, uint32_t objType, const std::string &name, DrmProperty &prop);
+ std::shared_ptr GetDrmEncoderFromId(uint32_t id);
+ std::shared_ptr GetDrmConnectorFromId(uint32_t id);
+ std::shared_ptr GetDrmCrtcFromId(uint32_t id);
+ void CreateCrtc(drmModeCrtcPtr c);
+ std::unordered_map> DiscoveryDisplay() override;
+ int32_t Init() override;
+ void DeInit() override;
+ bool HandleHotplug(uint32_t dispId, bool plugIn) override;
+
+private:
+ static FdPtr mDrmFd;
+ static std::shared_ptr mInstance;
+ void FindAllCrtc(const drmModeResPtr &drmRes);
+ void FindAllEncoder(const drmModeResPtr &drmRes);
+ void FindAllConnector(const drmModeResPtr &drmRes);
+ void FindAllPlane();
+ int InitNetLink();
+ IdMapPtr mDisplays;
+ IdMapPtr mCrtcs;
+ IdMapPtr mEncoders;
+ IdMapPtr mConnectors;
+ std::vector> mPlanes;
+ std::unordered_map dispConnectorIdMaps_;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // DRM_DEVICE_H
diff --git a/hardware/display/src/display_device/drm_display.cpp b/hardware/display/src/display_device/drm_display.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0d794449d731586984f565595eba8c4e0fdb6b2
--- /dev/null
+++ b/hardware/display/src/display_device/drm_display.cpp
@@ -0,0 +1,289 @@
+/*
+ * 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
+#include
+#include
+#include
+#include
+#include "display_gralloc.h"
+#include "display_common.h"
+#include "drm_device.h"
+#include "drm_vsync_worker.h"
+#include "hdi_drm_composition.h"
+#include "hdi_gfx_composition.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+DrmDisplay::DrmDisplay(std::shared_ptr connector, std::shared_ptr crtc,
+ std::shared_ptr drmDevice)
+ : mDrmDevice(drmDevice), mConnector(connector), mCrtc(crtc)
+{}
+
+DrmDisplay::~DrmDisplay()
+{
+ if (mCrtc != nullptr) {
+ mCrtc->UnBindDisplay(GetId());
+ }
+}
+
+int32_t DrmDisplay::Init()
+{
+ int ret;
+ DISPLAY_CHK_RETURN((mCrtc == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("crtc is null"));
+ DISPLAY_CHK_RETURN((mConnector == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("connector is null"));
+ DISPLAY_CHK_RETURN((mDrmDevice == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("drmDevice is null"));
+
+ ret = HdiDisplay::Init();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("init failed"));
+ auto preComp = std::make_unique();
+ DISPLAY_CHK_RETURN((preComp == nullptr), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not new HdiGfxComposition errno %{public}d", errno));
+ ret = preComp->Init();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not init HdiGfxComposition"));
+
+ auto postComp = std::make_unique(mConnector, mCrtc, mDrmDevice);
+ DISPLAY_CHK_RETURN((postComp == nullptr), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not new HdiDrmComposition errno %{public}d", errno));
+ ret = postComp->Init();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not init HdiDrmComposition"));
+ mComposer = std::make_unique(std::move(preComp), std::move(postComp));
+ ret = mCrtc->BindToDisplay(GetId());
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("bind crtc failed"));
+
+ ret = ChosePreferenceMode();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("choose preference mode fialed"));
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::GetDisplayCapability(DisplayCapability *info)
+{
+ mConnector->GetDisplayCap(*info);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes)
+{
+ mConnector->GetDisplaySupportedModes(num, modes);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::GetDisplayMode(uint32_t *modeId)
+{
+ DISPLAY_CHK_RETURN((modeId == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the in modeId is nullptr"));
+ *modeId = mCrtc->GetActiveModeId();
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::SetDisplayMode(uint32_t modeId)
+{
+ return mCrtc->SetActivieMode(modeId);
+}
+
+int32_t DrmDisplay::GetDisplayPowerStatus(DispPowerStatus *status)
+{
+ DISPLAY_CHK_RETURN((status == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("status is nullptr"));
+ return ConvertToHdiPowerState(mConnector->GetDpmsState(), *status);
+}
+
+int32_t DrmDisplay::SetDisplayPowerStatus(DispPowerStatus status)
+{
+ static int32_t fb_fd = -1;
+ int32_t err = -1;
+ const uint32_t FBIOBLANK = 0x4611; /* arg: 0 or vesa level + 1 */
+ const uint32_t FB_BLANK_UNBLANK = 0; /* screen: unblanked, hsync: on, vsync: on */
+ const uint32_t FB_BLANK_POWERDOWN = 4; /* screen: blanked, hsync: off, vsync: off */
+
+ DISPLAY_DEBUGLOG("SetDisplayPowerStatus power state %{public}u", status);
+ if (fb_fd < 0) {
+ fb_fd = open("/dev/graphics/fb0", O_RDWR);
+ if (fb_fd < 0) {
+ DISPLAY_LOGE("oepn fb0 file failed\n");
+ return DISPLAY_NOT_SUPPORT;
+ }
+ }
+ switch (status) {
+ case POWER_STATUS_OFF:
+ case POWER_STATUS_STANDBY:
+ case POWER_STATUS_SUSPEND:
+ err = ioctl(fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN);
+ break;
+ case POWER_STATUS_ON:
+ err = ioctl(fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
+ break;
+ default:
+ err = DISPLAY_FAILURE;
+ break;
+ }
+ if (err < 0) {
+ DISPLAY_LOGE("ioctl fb0 failed\n");
+ return DISPLAY_FAILURE;
+ }
+
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::ConvertToHdiPowerState(uint32_t drmPowerState, DispPowerStatus &hdiPowerState)
+{
+ int32_t ret = DISPLAY_SUCCESS;
+ switch (drmPowerState) {
+ case DRM_MODE_DPMS_OFF:
+ hdiPowerState = POWER_STATUS_OFF;
+ break;
+ case DRM_MODE_DPMS_ON:
+ hdiPowerState = POWER_STATUS_ON;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ hdiPowerState = POWER_STATUS_STANDBY;
+ break;
+ case DRM_MODE_DPMS_SUSPEND:
+ hdiPowerState = POWER_STATUS_SUSPEND;
+ break;
+ default:
+ hdiPowerState = POWER_STATUS_BUTT;
+ ret = DISPLAY_FAILURE;
+ break;
+ }
+ DISPLAY_DEBUGLOG("hdi power state %{public}u", hdiPowerState);
+ return ret;
+}
+
+int32_t DrmDisplay::ConvertToDrmPowerState(DispPowerStatus hdiPowerState, uint32_t &drmPowerState)
+{
+ int32_t ret = DISPLAY_SUCCESS;
+ switch (hdiPowerState) {
+ case POWER_STATUS_OFF:
+ drmPowerState = DRM_MODE_DPMS_OFF;
+ break;
+ case POWER_STATUS_ON:
+ drmPowerState = DRM_MODE_DPMS_ON;
+ break;
+ case POWER_STATUS_STANDBY:
+ drmPowerState = DRM_MODE_DPMS_STANDBY;
+ break;
+ case POWER_STATUS_SUSPEND:
+ drmPowerState = DRM_MODE_DPMS_SUSPEND;
+ break;
+ default:
+ ret = DISPLAY_FAILURE;
+ break;
+ }
+ return ret;
+}
+
+std::unique_ptr DrmDisplay::CreateHdiLayer(LayerType type)
+{
+ DISPLAY_DEBUGLOG();
+ return std::make_unique(type);
+}
+
+int32_t DrmDisplay::WaitForVBlank(uint64_t *ns)
+{
+ int ret;
+ constexpr uint64_t nPerS = 1000000000;
+ constexpr uint64_t nPerUS = 1000;
+ drmVBlank vbl = {
+ .request.type = DRM_VBLANK_RELATIVE,
+ .request.sequence = 0,
+ .request.signal = 0,
+ };
+ DISPLAY_CHK_RETURN((ns == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in ns is nullptr"));
+ ret = drmWaitVBlank(mDrmDevice->GetDrmFd(), &vbl);
+ DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("wait vblank failed errno %{public}d", errno));
+ *ns = static_cast(vbl.reply.tval_sec * nPerS + vbl.reply.tval_usec * nPerUS);
+ return DISPLAY_SUCCESS;
+}
+
+bool DrmDisplay::IsConnected()
+{
+ DISPLAY_DEBUGLOG("conneted %{public}d", mConnector->IsConnected());
+ return mConnector->IsConnected();
+}
+
+int32_t DrmDisplay::PushFirstFrame()
+{
+ GrallocFuncs *grallocFucs = nullptr;
+ int ret = GrallocInitialize(&grallocFucs);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Gralloc init failed"));
+ DrmMode mode;
+ ret = mConnector->GetModeFromId(mCrtc->GetActiveModeId(), mode);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not get the mode from id %{public}d", mCrtc->GetActiveModeId()));
+ AllocInfo info = {
+ .width = mode.GetModeInfoPtr()->hdisplay,
+ .height = mode.GetModeInfoPtr()->vdisplay,
+ .usage = HBM_USE_MEM_DMA | HBM_USE_CPU_READ | HBM_USE_CPU_WRITE,
+ .format = PIXEL_FMT_BGRA_8888
+ };
+
+ BufferHandle *buffer = nullptr;
+ ret = grallocFucs->AllocMem(&info, &buffer);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not alloc memory"));
+ mClientLayer->SetLayerBuffer(buffer, -1);
+
+ std::vector layers;
+ HdiDrmComposition *drmComp = static_cast(mComposer->GetPostCompostion());
+ drmComp->SetLayers(layers, *mClientLayer);
+ drmComp->Apply(true);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::ChosePreferenceMode()
+{
+ int32_t ret;
+ int32_t modeId = mConnector->GetPreferenceId();
+ if (modeId == INVALID_MODE_ID) {
+ uint32_t num = 0;
+ ret = GetDisplaySupportedModes(&num, nullptr);
+ DISPLAY_CHK_RETURN((num == 0) && (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get modes"));
+ modeId = 0;
+ }
+ ret = SetDisplayMode(modeId);
+ // Push first frame to the drm, for that the vblank must init all the componet.
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("set display mode failed"));
+ return PushFirstFrame();
+}
+
+int32_t DrmDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void *data)
+{
+ DISPLAY_DEBUGLOG("the VBlankCallback %{public}p ", cb);
+ (void)data;
+ std::shared_ptr vsyncCb = std::make_shared(cb, nullptr, mCrtc->GetPipe());
+ DrmVsyncWorker::GetInstance().ReqesterVBlankCb(vsyncCb);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::SetDisplayVsyncEnabled(bool enabled)
+{
+ DISPLAY_DEBUGLOG("enable %{public}d", enabled);
+ DrmVsyncWorker::GetInstance().EnableVsync(enabled);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DrmDisplay::GetDisplayBacklight(uint32_t *value)
+{
+ DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
+ return mConnector->GetBrightness(*value);
+}
+
+int32_t DrmDisplay::SetDisplayBacklight(uint32_t value)
+{
+ return mConnector->SetBrightness(value);
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_display.h b/hardware/display/src/display_device/drm_display.h
new file mode 100644
index 0000000000000000000000000000000000000000..31b3bb40b4276598721b3f9d7a34b0ba32e88458
--- /dev/null
+++ b/hardware/display/src/display_device/drm_display.h
@@ -0,0 +1,68 @@
+/*
+ * 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 DRM_DISPLAY_H
+#define DRM_DISPLAY_H
+#include
+#include
+#include "drm_connector.h"
+#include "drm_crtc.h"
+#include "drm_device.h"
+#include "drm_plane.h"
+#include "hdi_composer.h"
+#include "hdi_drm_composition.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class DrmDisplay : public HdiDisplay {
+public:
+ DrmDisplay(std::shared_ptr connector, std::shared_ptr crtc,
+ std::shared_ptr drmDevice);
+
+ ~DrmDisplay() override;
+
+ int32_t Init() 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 ChosePreferenceMode();
+ int32_t RegDisplayVBlankCallback(VBlankCallback cb, void *data) override;
+ int32_t WaitForVBlank(uint64_t *ns) override;
+ bool IsConnected() override;
+ int32_t SetDisplayVsyncEnabled(bool enabled) override;
+ HdiDrmComposition *GetDrmComposition();
+
+protected:
+ std::unique_ptr CreateHdiLayer(LayerType type) override;
+
+private:
+ int32_t PushFirstFrame();
+ int32_t ConvertToHdiPowerState(uint32_t drmPowerState, DispPowerStatus &hdiPowerState);
+ int32_t ConvertToDrmPowerState(DispPowerStatus hdiPowerState, uint32_t &drmPowerState);
+ std::shared_ptr mDrmDevice;
+ std::shared_ptr mConnector;
+ std::shared_ptr mCrtc;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_DISPLAY_H
diff --git a/hardware/display/src/display_device/drm_encoder.cpp b/hardware/display/src/display_device/drm_encoder.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..c69882a5b3aba33f74639fd9bbf539a527922142
--- /dev/null
+++ b/hardware/display/src/display_device/drm_encoder.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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_encoder.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+DrmEncoder::DrmEncoder(drmModeEncoder e)
+{
+ mEncoderId = e.encoder_id;
+ mCrtcId = e.crtc_id;
+ mPossibleCrtcs = e.possible_crtcs;
+}
+
+int32_t DrmEncoder::PickIdleCrtcId(IdMapPtr &crtcs, uint32_t &crtcId)
+{
+ // find the crtc id;
+ DISPLAY_DEBUGLOG("crtcs szie %{public}zu", crtcs.size());
+ std::shared_ptr crtc;
+ auto crtcIter = crtcs.find(mCrtcId);
+ if (crtcIter == crtcs.end()) {
+ DISPLAY_LOGW("can not find crtc for id %{public}d", mCrtcId);
+ crtcIter = crtcs.begin();
+ return DISPLAY_FAILURE;
+ }
+ DISPLAY_CHK_RETURN((crtcIter == crtcs.end()), DISPLAY_FAILURE,
+ DISPLAY_LOGE("have no crtc %{public}zu ", crtcs.size()));
+ crtc = crtcIter->second;
+ DISPLAY_CHK_RETURN((crtc == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("crtc is null"));
+
+ if (!crtc->CanBind()) {
+ crtc = nullptr;
+ for (const auto &posCrtcPair : crtcs) {
+ auto &posCrts = posCrtcPair.second;
+ DISPLAY_DEBUGLOG("try crtc id : %{public}d", posCrts->GetId());
+ if (posCrts->CanBind() && ((1 << posCrts->GetPipe()) & mPossibleCrtcs)) {
+ crtc = posCrts;
+ }
+ }
+ }
+ DISPLAY_CHK_RETURN((crtc == nullptr), DISPLAY_FAILURE,
+ DISPLAY_LOGE("encoder %{public}d can not bind to idle crtc", mEncoderId));
+ crtcId = crtc->GetId();
+ return DISPLAY_SUCCESS;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_encoder.h b/hardware/display/src/display_device/drm_encoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f35578a54ef9ac26439f1ebf19cf342307fa509
--- /dev/null
+++ b/hardware/display/src/display_device/drm_encoder.h
@@ -0,0 +1,59 @@
+/*
+ * 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 DRM_ENCODER_H
+#define DRM_ENCODER_H
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class DrmEncoder {
+public:
+ explicit DrmEncoder(drmModeEncoder e);
+ virtual ~DrmEncoder() {}
+ uint32_t GetCrtcId() const
+ {
+ return mCrtcId;
+ }
+ void SetCrtcId(uint32_t id)
+ {
+ mCrtcId = id;
+ }
+ uint32_t GetPossibleCrtcs() const
+ {
+ return mPossibleCrtcs;
+ }
+ int32_t PickIdleCrtcId(IdMapPtr &crtcs, uint32_t &crtcId);
+ uint32_t GetId() const
+ {
+ return mEncoderId;
+ }
+
+private:
+ uint32_t mEncoderId;
+ uint32_t mCrtcId;
+ uint32_t mPossibleCrtcs;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // DRM_ENCODER_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/drm_plane.cpp b/hardware/display/src/display_device/drm_plane.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..8735a3e2671eb966bc1eb62461030dc6d1fcb8f4
--- /dev/null
+++ b/hardware/display/src/display_device/drm_plane.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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_plane.h"
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+struct PlaneTypeName planeTypeNames[] = {
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER0_WIN0, "Cluster0-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER0_WIN1, "Cluster0-win1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER1_WIN0, "Cluster1-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_CLUSTER1_WIN1, "Cluster1-win1" },
+
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART0_WIN0, "Esmart0-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART0_WIN1, "Esmart0-win1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART0_WIN2, "Esmart0-win2" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART0_WIN3, "Esmart0-win3" },
+
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART1_WIN0, "Esmart1-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART1_WIN1, "Esmart1-win1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART1_WIN2, "Esmart1-win2" },
+ { DrmPlaneType::DRM_PLANE_TYPE_ESMART1_WIN3, "Esmart1-win3" },
+
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART0_WIN0, "Smart0-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART0_WIN1, "Smart0-win1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART0_WIN2, "Smart0-win2" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART0_WIN3, "Smart0-win3" },
+
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART1_WIN0, "Smart1-win0" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART1_WIN1, "Smart1-win1" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART1_WIN2, "Smart1-win2" },
+ { DrmPlaneType::DRM_PLANE_TYPE_SMART1_WIN3, "Smart1-win3" },
+
+ { DrmPlaneType::DRM_PLANE_TYPE_Unknown, "unknown" },
+};
+
+DrmPlane::DrmPlane(drmModePlane &p)
+ : mId(p.plane_id), mPossibleCrtcs(p.possible_crtcs), mCrtcId(p.crtc_id),
+ mFormats(p.formats, p.formats + p.count_formats)
+{}
+
+DrmPlane::~DrmPlane()
+{
+ DISPLAY_DEBUGLOG();
+}
+
+int DrmPlane::GetCrtcProp(DrmDevice &drmDevice)
+{
+ int32_t ret;
+ int32_t crtc_x, crtc_y, crtc_w, crtc_h;
+ DrmProperty prop;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_CRTC_X_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc_x prop id"));
+ mPropCrtc_xId = prop.propId;
+ crtc_x = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_CRTC_Y_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc_y prop id"));
+ mPropCrtc_yId = prop.propId;
+ crtc_y = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_CRTC_W_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc_w prop id"));
+ mPropCrtc_wId = prop.propId;
+ crtc_w = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_CRTC_H_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc_h prop id"));
+ mPropCrtc_hId = prop.propId;
+ crtc_h = prop.value;
+
+ DISPLAY_LOGE("plane %{public}d crtc_x %{public}d crtc_y %{public}d crtc_w %{public}d crtc_h %{public}d",
+ GetId(), crtc_x, crtc_y, crtc_w, crtc_h);
+
+ return 0;
+}
+
+int DrmPlane::GetSrcProp(DrmDevice &drmDevice)
+{
+ int32_t ret;
+ int32_t src_x, src_y, src_w, src_h;
+ DrmProperty prop;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_SRC_X_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane src_x prop id"));
+ mPropSrc_xId = prop.propId;
+ src_x = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_SRC_Y_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane src_y prop id"));
+ mPropSrc_yId = prop.propId;
+ src_y = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_SRC_W_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane src_w prop id"));
+ mPropSrc_wId = prop.propId;
+ src_w = prop.value;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_SRC_H_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane src_h prop id"));
+ mPropSrc_hId = prop.propId;
+ src_h = prop.value;
+
+ DISPLAY_LOGE("plane %{public}d src_x %{public}d src_y %{public}d src_w %{public}d src_h %{public}d",
+ GetId(), src_x, src_y, src_w, src_h);
+
+ return 0;
+}
+
+int32_t DrmPlane::Init(DrmDevice &drmDevice)
+{
+ DISPLAY_DEBUGLOG();
+ int32_t ret;
+ uint32_t find_name = 0;
+ DrmProperty prop;
+ GetCrtcProp(drmDevice);
+ GetSrcProp(drmDevice);
+ ret = drmDevice.GetPlaneProperty(*this, PROP_FBID, prop);
+ mPropFbId = prop.propId;
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not get plane fb id"));
+ ret = drmDevice.GetPlaneProperty(*this, PROP_IN_FENCE_FD, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get plane in fence prop id"));
+ mPropFenceInId = prop.propId;
+ ret = drmDevice.GetPlaneProperty(*this, PROP_CRTC_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc prop id"));
+ mPropCrtcId = prop.propId;
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_ZPOS_ID, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc prop id"));
+ mPropZposId = prop.propId;
+
+ ret = drmDevice.GetPlaneProperty(*this, "NAME", prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc prop id"));
+
+ for (int i = 0; i < static_castARRAY_SIZE(planeTypeNames); i++) {
+ find_name = 0;
+
+ for (auto &drmEnum : prop.enums) {
+ if (!strncmp(drmEnum.name.c_str(), (const char*)planeTypeNames[i].name,
+ strlen(planeTypeNames[i].name))) {
+ find_name = (1LL << drmEnum.value);
+ }
+ }
+
+ if (find_name) {
+ DISPLAY_LOGI("find plane id %{public}d, type %{public}x %{public}s",
+ GetId(), planeTypeNames[i].type, planeTypeNames[i].name);
+ mWinType = planeTypeNames[i].type;
+ mName = planeTypeNames[i].name;
+ break;
+ }
+ }
+
+ ret = drmDevice.GetPlaneProperty(*this, PROP_TYPE, prop);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("cat not get pane crtc prop id"));
+ switch (prop.value) {
+ case DRM_PLANE_TYPE_OVERLAY:
+ case DRM_PLANE_TYPE_PRIMARY:
+ case DRM_PLANE_TYPE_CURSOR:
+ mType = static_cast(prop.value);
+ break;
+ default:
+ DISPLAY_LOGE("unknown type value %{public}" PRIu64 "", prop.value);
+ return DISPLAY_FAILURE;
+ }
+ return DISPLAY_SUCCESS;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/drm_plane.h b/hardware/display/src/display_device/drm_plane.h
new file mode 100755
index 0000000000000000000000000000000000000000..8b29d3913c913a05c721edaa88f579cd65aa3aaf
--- /dev/null
+++ b/hardware/display/src/display_device/drm_plane.h
@@ -0,0 +1,227 @@
+/*
+ * 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 DRM_PLANE_H
+#define DRM_PLANE_H
+#include
+#include
+#include
+#include
+#include
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+enum class DrmPropertyType {
+ DRM_PROPERTY_TYPE_INT,
+ DRM_PROPERTY_TYPE_ENUM,
+ DRM_PROPERTY_TYPE_OBJECT,
+ DRM_PROPERTY_TYPE_BLOB,
+ DRM_PROPERTY_TYPE_BITMASK,
+ DRM_PROPERTY_TYPE_INVALID,
+};
+
+enum class DrmPlaneType {
+ DRM_PLANE_TYPE_CLUSTER0_WIN0 = 1 << 0,
+ DRM_PLANE_TYPE_CLUSTER0_WIN1 = 1 << 1,
+
+ DRM_PLANE_TYPE_CLUSTER1_WIN0 = 1 << 2,
+ DRM_PLANE_TYPE_CLUSTER1_WIN1 = 1 << 3,
+
+ DRM_PLANE_TYPE_ESMART0_WIN0 = 1 << 4,
+ DRM_PLANE_TYPE_ESMART0_WIN1 = 1 << 5,
+ DRM_PLANE_TYPE_ESMART0_WIN2 = 1 << 6,
+ DRM_PLANE_TYPE_ESMART0_WIN3 = 1 << 7,
+
+ DRM_PLANE_TYPE_ESMART1_WIN0 = 1 << 8,
+ DRM_PLANE_TYPE_ESMART1_WIN1 = 1 << 9,
+ DRM_PLANE_TYPE_ESMART1_WIN2 = 1 << 10,
+ DRM_PLANE_TYPE_ESMART1_WIN3 = 1 << 11,
+
+ DRM_PLANE_TYPE_SMART0_WIN0 = 1 << 12,
+ DRM_PLANE_TYPE_SMART0_WIN1 = 1 << 13,
+ DRM_PLANE_TYPE_SMART0_WIN2 = 1 << 14,
+ DRM_PLANE_TYPE_SMART0_WIN3 = 1 << 15,
+
+ DRM_PLANE_TYPE_SMART1_WIN0 = 1 << 16,
+ DRM_PLANE_TYPE_SMART1_WIN1 = 1 << 17,
+ DRM_PLANE_TYPE_SMART1_WIN2 = 1 << 18,
+ DRM_PLANE_TYPE_SMART1_WIN3 = 1 << 19,
+
+ DRM_PLANE_TYPE_CLUSTER0_MASK = 0x3,
+ DRM_PLANE_TYPE_CLUSTER1_MASK = 0xc,
+ DRM_PLANE_TYPE_CLUSTER_MASK = 0xf,
+ DRM_PLANE_TYPE_ESMART0_MASK = 0xf0,
+ DRM_PLANE_TYPE_ESMART1_MASK = 0xf00,
+ DRM_PLANE_TYPE_SMART0_MASK = 0xf000,
+ DRM_PLANE_TYPE_SMART1_MASK = 0xf0000,
+ DRM_PLANE_TYPE_Unknown = 0xffffffff,
+};
+
+struct PlaneMaskName {
+ DrmPlaneType mask;
+ const char *name;
+};
+
+struct PlaneTypeName {
+ DrmPlaneType type;
+ const char *name;
+};
+
+const std::string PROP_FBID = "FB_ID";
+const std::string PROP_IN_FENCE_FD = "IN_FENCE_FD";
+const std::string PROP_CRTC_ID = "CRTC_ID";
+const std::string PROP_TYPE = "type";
+
+const std::string PROP_CRTC_X_ID = "CRTC_X";
+const std::string PROP_CRTC_Y_ID = "CRTC_Y";
+const std::string PROP_CRTC_W_ID = "CRTC_W";
+const std::string PROP_CRTC_H_ID = "CRTC_H";
+
+const std::string PROP_SRC_X_ID = "SRC_X";
+const std::string PROP_SRC_Y_ID = "SRC_Y";
+const std::string PROP_SRC_W_ID = "SRC_W";
+const std::string PROP_SRC_H_ID = "SRC_H";
+
+const std::string PROP_ZPOS_ID = "zpos";
+
+class DrmDevice;
+
+class DrmPlane {
+public:
+ explicit DrmPlane(drmModePlane &p);
+ virtual ~DrmPlane();
+ int32_t Init(DrmDevice &drmDevice);
+ int GetCrtcProp(DrmDevice &drmDevice);
+ int GetSrcProp(DrmDevice &drmDevice);
+ uint32_t GetId() const
+ {
+ return mId;
+ }
+ uint32_t GetPropFbId() const
+ {
+ return mPropFbId;
+ }
+ uint32_t GetPropCrtc_xId() const
+ {
+ return mPropCrtc_xId;
+ }
+ uint32_t GetPropCrtc_yId() const
+ {
+ return mPropCrtc_yId;
+ }
+ uint32_t GetPropCrtc_wId() const
+ {
+ return mPropCrtc_wId;
+ }
+ uint32_t GetPropCrtc_hId() const
+ {
+ return mPropCrtc_hId;
+ }
+ uint32_t GetPropSrc_xId() const
+ {
+ return mPropSrc_xId;
+ }
+ uint32_t GetPropSrc_yId() const
+ {
+ return mPropSrc_yId;
+ }
+ uint32_t GetPropSrc_wId() const
+ {
+ return mPropSrc_wId;
+ }
+ uint32_t GetPropSrc_hId() const
+ {
+ return mPropSrc_hId;
+ }
+ uint32_t GetPropZposId() const
+ {
+ return mPropZposId;
+ }
+ uint32_t GetPropFenceInId() const
+ {
+ return mPropFenceInId;
+ }
+ uint32_t GetPropCrtcId() const
+ {
+ return mPropCrtcId;
+ }
+ uint32_t GetPossibleCrtcs() const
+ {
+ return mPossibleCrtcs;
+ }
+ uint32_t GetType() const
+ {
+ return mType;
+ }
+ void BindToPipe(uint32_t pipe)
+ {
+ mPipe = pipe;
+ }
+ void UnBindPipe()
+ {
+ mPipe = 0;
+ }
+ bool IsIdle() const
+ {
+ return (mPipe == 0);
+ }
+ uint32_t GetCrtcId()
+ {
+ return mCrtcId;
+ }
+ uint32_t GetPipe()
+ {
+ return mPipe;
+ }
+ DrmPlaneType GetWinType()
+ {
+ return mWinType;
+ }
+ std::string GetName()
+ {
+ return mName;
+ }
+private:
+ uint32_t mId = 0;
+ uint32_t mPossibleCrtcs = 0;
+ uint32_t mCrtcId = 0;
+ uint32_t mPropFbId = 0;
+ uint32_t mPropFenceInId = 0;
+ uint32_t mPropCrtcId = 0;
+ DrmPlaneType mWinType = DrmPlaneType::DRM_PLANE_TYPE_Unknown;
+ std::string mName;
+
+ uint32_t mPropCrtc_xId = 0;
+ uint32_t mPropCrtc_yId = 0;
+ uint32_t mPropCrtc_wId = 0;
+ uint32_t mPropCrtc_hId = 0;
+
+ uint32_t mPropSrc_xId = 0;
+ uint32_t mPropSrc_yId = 0;
+ uint32_t mPropSrc_wId = 0;
+ uint32_t mPropSrc_hId = 0;
+
+ uint32_t mPropZposId = 0;
+
+ uint32_t mPipe = 0;
+ uint32_t mType = 0;
+ std::vector mFormats;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // DRM_PLANE_H
diff --git a/hardware/display/src/display_device/drm_vsync_worker.cpp b/hardware/display/src/display_device/drm_vsync_worker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53ddd63aa399e82d047fe3c5981c3f2da607ec3e
--- /dev/null
+++ b/hardware/display/src/display_device/drm_vsync_worker.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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_vsync_worker.h"
+#include
+#include "display_common.h"
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+DrmVsyncWorker::DrmVsyncWorker() {}
+
+int32_t DrmVsyncWorker::Init(int fd)
+{
+ DISPLAY_CHK_RETURN((fd < 0), DISPLAY_FAILURE, DISPLAY_LOGE("the fd is invalid"));
+ mDrmFd = fd;
+ DISPLAY_DEBUGLOG("the drm fd is %{public}d", fd);
+ mThread = std::make_unique([this]() { WorkThread(); });
+ DISPLAY_CHK_RETURN((mThread == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create thread"));
+ mRunning = true;
+ return DISPLAY_SUCCESS;
+}
+
+DrmVsyncWorker &DrmVsyncWorker::GetInstance()
+{
+ static DrmVsyncWorker instance;
+ static std::once_flag once;
+ std::call_once(once, [&]() {
+ int ret = instance.Init(DrmDevice::GetDrmFd());
+ if (ret != DISPLAY_SUCCESS) {
+ DISPLAY_LOGE("Vsync Worker Init failed");
+ }
+ });
+ return instance;
+}
+
+DrmVsyncWorker::~DrmVsyncWorker()
+{
+ DISPLAY_DEBUGLOG();
+ {
+ std::lock_guard lg(mMutex);
+ mRunning = false;
+ }
+ DISPLAY_DEBUGLOG();
+ mCondition.notify_one();
+ if (mThread != nullptr) {
+ mThread->join();
+ }
+ DISPLAY_DEBUGLOG();
+}
+
+bool DrmVsyncWorker::WaitSignalAndCheckRuning()
+{
+ std::unique_lock ul(mMutex);
+ mCondition.wait(ul, [this]() { return (mEnable || !mRunning); });
+ return mRunning;
+}
+
+
+uint64_t DrmVsyncWorker::WaitNextVBlank(unsigned int &sq)
+{
+ constexpr uint64_t SEC_TO_NSEC = 1000 * 1000 * 1000;
+ constexpr uint64_t USEC_TO_NSEC = 1000;
+ drmVBlank vblank = {
+ .request =
+ drmVBlankReq {
+ .type = DRM_VBLANK_RELATIVE,
+ .sequence = 1,
+ .signal = 0,
+ }
+ };
+ /* The drmWaitVBlank need set the crtc pipe when there are multi crtcs in the system. */
+ if (mCallBack->GetPipe() == 1)
+ vblank.request.type = drmVBlankSeqType((int)(vblank.request.type) | (int)DRM_VBLANK_SECONDARY);
+ int ret = drmWaitVBlank(mDrmFd, &vblank);
+ DISPLAY_CHK_RETURN((ret < 0), 0,
+ DISPLAY_LOGE("wait vblank failed ret : %{public}d errno %{public}d", ret, errno));
+ sq = vblank.reply.sequence;
+ return (uint64_t)(vblank.reply.tval_sec * SEC_TO_NSEC + vblank.reply.tval_usec * USEC_TO_NSEC);
+}
+
+
+void DrmVsyncWorker::EnableVsync(bool enable)
+{
+ DISPLAY_DEBUGLOG();
+ {
+ std::lock_guard lg(mMutex);
+ mEnable = enable;
+ }
+ mCondition.notify_one();
+}
+
+void DrmVsyncWorker::WorkThread()
+{
+ DISPLAY_DEBUGLOG();
+ unsigned int seq = 0;
+ while (WaitSignalAndCheckRuning()) {
+ // wait the vblank
+ uint64_t time = WaitNextVBlank(seq);
+ if (mCallBack != nullptr) {
+ mCallBack->Vsync(seq, time);
+ } else {
+ DISPLAY_LOGE("the callbac is nullptr");
+ }
+ }
+}
+
+void DrmVsyncWorker::ReqesterVBlankCb(std::shared_ptr &cb)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN_NOT_VALUE((cb == nullptr), DISPLAY_LOGE("the VBlankCallback is nullptr "));
+ mCallBack = cb;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
\ No newline at end of file
diff --git a/hardware/display/src/display_device/drm_vsync_worker.h b/hardware/display/src/display_device/drm_vsync_worker.h
new file mode 100644
index 0000000000000000000000000000000000000000..c578e91c49e9fc8722115ef711cfd097fe1a3737
--- /dev/null
+++ b/hardware/display/src/display_device/drm_vsync_worker.h
@@ -0,0 +1,54 @@
+/*
+ * 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 DRM_VSYNC_WORKER_H
+#define DRM_VSYNC_WORKER_H
+#include
+#include
+#include
+#include
+#include "display_device.h"
+#include "hdi_device_common.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class DrmVsyncWorker {
+public:
+ DrmVsyncWorker();
+ virtual ~DrmVsyncWorker();
+ int32_t Init(int fd);
+ static DrmVsyncWorker &GetInstance();
+
+ void EnableVsync(bool enable);
+ void WorkThread();
+ uint64_t WaitNextVBlank(unsigned int &sq);
+ bool WaitSignalAndCheckRuning();
+ void ReqesterVBlankCb(std::shared_ptr &cb);
+
+private:
+ int mDrmFd = 0;
+ std::unique_ptr mThread;
+ bool mEnable = false;
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ std::shared_ptr mCallBack;
+ bool mRunning = false;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // DRM_VSYNC_WORKER_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_composer.cpp b/hardware/display/src/display_device/hdi_composer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..04eefdbcf0fefbbd48ede43d5cd37c50150e6d5f
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_composer.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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_composer.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+HdiComposer::HdiComposer(std::unique_ptr pre, std::unique_ptr post)
+{
+ mPreComp = std::move(pre);
+ mPostComp = std::move(post);
+}
+
+int32_t HdiComposer::Prepare(std::vector &layers, HdiLayer &clientLayer)
+{
+ int ret = mPreComp->SetLayers(layers, clientLayer);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("pre composition prepare failed"));
+ ret = mPostComp->SetLayers(layers, clientLayer);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("post composition prepare failed"));
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiComposer::Commit(bool modeSet)
+{
+ int ret = mPreComp->Apply(modeSet);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("pre composition apply failed"));
+ ret = mPostComp->Apply(modeSet);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("post composition apply failed"));
+ return DISPLAY_SUCCESS;
+}
+} // OHOS
+} // HDI
+} // DISPLAY
diff --git a/hardware/display/src/display_device/hdi_composer.h b/hardware/display/src/display_device/hdi_composer.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3b69de50dd58f1af8317533bf1ce9ab4fb23e38
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_composer.h
@@ -0,0 +1,69 @@
+/*
+ * 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 HDI_COMPOSER_H
+#define HDI_COMPOSER_H
+#include
+#include
+#include "hdi_layer.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class HdiComposition {
+public:
+ HdiComposition() {}
+ virtual int32_t Init()
+ {
+ return DISPLAY_SUCCESS;
+ };
+ virtual int32_t SetLayers(std::vector &layers, HdiLayer &clientLayer)
+ {
+ return DISPLAY_SUCCESS;
+ }
+ virtual int32_t Apply(bool modeSet)
+ {
+ return DISPLAY_SUCCESS;
+ }
+ virtual ~HdiComposition() {}
+
+protected:
+ std::vector mCompLayers;
+};
+
+class HdiComposer {
+public:
+ HdiComposer(std::unique_ptr pre, std::unique_ptr post);
+ virtual ~HdiComposer() {};
+ int32_t Prepare(std::vector &layers, HdiLayer &clientLayer);
+ int32_t Commit(bool modeSet);
+ HdiComposition *GetPreCompostion()
+ {
+ return mPreComp.get();
+ }
+ HdiComposition *GetPostCompostion()
+ {
+ return mPostComp.get();
+ }
+
+private:
+ std::unique_ptr mPreComp;
+ std::unique_ptr mPostComp;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_COMPOSER_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_device_common.h b/hardware/display/src/display_device/hdi_device_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5ceaf092a29ef909e045ffa8916668e69910c67
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_device_common.h
@@ -0,0 +1,39 @@
+/*
+ * 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 HDI_DEVICE_COMMON_H
+#define HDI_DEVICE_COMMON_H
+#include
+#include
+#include "display_type.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const int32_t INVALID_MODE_ID = -1;
+const uint32_t DRM_INVALID_ID = 0xFFFFFFFF;
+template using IdMapPtr = std::unordered_map>;
+class DrmEncoder;
+class DrmCrtc;
+class DrmPlane;
+class DrmDevice;
+class DrmConnector;
+class VsyncCallBack;
+class DrmVsyncWorker;
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_DEVICE_COMMON_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_device_interface.cpp b/hardware/display/src/display_device/hdi_device_interface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f79074b9f9516b224afa8b109cdb87a2c37a3be
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_device_interface.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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_device_interface.h"
+#include
+#include "display_common.h"
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+std::vector> HdiDeviceInterface::DiscoveryDevice()
+{
+ DISPLAY_DEBUGLOG();
+ int ret;
+ std::vector> devices;
+ std::shared_ptr drmDevice = DrmDevice::Create();
+ if (!drmDevice) {
+ DISPLAY_LOGE("can not create drm device");
+ }
+ ret = drmDevice->Init();
+ if (ret == DISPLAY_SUCCESS) {
+ DISPLAY_DEBUGLOG("drm device init success");
+ devices.push_back(std::move(drmDevice));
+ } else {
+ DISPLAY_LOGE("drm device init failed");
+ }
+ return devices;
+}
+}
+}
+}
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_device_interface.h b/hardware/display/src/display_device/hdi_device_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0bb3cccd4137bf53a02ff7c48d03b77a5ba3eb4
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_device_interface.h
@@ -0,0 +1,39 @@
+/*
+ * 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 HDI_DEVICE_INTERFACE_H
+#define HDI_DEVICE_INTERFACE_H
+#include
+#include
+#include
+#include "hdi_display.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class HdiDeviceInterface {
+public:
+ static std::vector> DiscoveryDevice();
+ virtual std::unordered_map> DiscoveryDisplay() = 0;
+ virtual bool HandleHotplug(uint32_t dispId, bool plugIn) = 0;
+ virtual int32_t Init() = 0;
+ virtual void DeInit() = 0;
+ virtual ~HdiDeviceInterface() {};
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_DEVICE_INTERFACE_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_display.cpp b/hardware/display/src/display_device/hdi_display.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cf229c0062b5c979319f374b189e0df7dd673b47
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_display.cpp
@@ -0,0 +1,233 @@
+/*
+ * 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
+#include "display_common.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+uint32_t HdiDisplay::mIdleId = 0;
+std::unordered_set HdiDisplay::mIdSets;
+
+uint32_t HdiDisplay::GetIdleId()
+{
+ const uint32_t oldIdleId = mIdleId;
+ uint32_t id = INVALIDE_DISPLAY_ID;
+ // ensure the mIdleId not INVALIDE_DISPLAY_ID
+ mIdleId = mIdleId % INVALIDE_DISPLAY_ID;
+ do {
+ auto iter = mIdSets.find(mIdleId);
+ if (iter == mIdSets.end()) {
+ id = mIdleId;
+ break;
+ }
+ mIdleId = (mIdleId + 1) % INVALIDE_DISPLAY_ID;
+ } while (oldIdleId != mIdleId);
+ mIdSets.emplace(id);
+ mIdleId++;
+ return id;
+}
+
+
+int32_t HdiDisplay::Init()
+{
+ DISPLAY_DEBUGLOG();
+ uint32_t id = GetIdleId();
+ DISPLAY_CHK_RETURN((id == INVALIDE_DISPLAY_ID), DISPLAY_FAILURE, DISPLAY_LOGE("have no id to used"));
+ mId = id;
+ auto layer = CreateHdiLayer(LAYER_TYPE_GRAPHIC);
+ DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer for client"));
+ mClientLayer = std::move(layer);
+ DISPLAY_DEBUGLOG("the id is %{public}d", id);
+ return DISPLAY_SUCCESS;
+}
+
+
+HdiDisplay::~HdiDisplay()
+{
+ mIdSets.erase(mId);
+}
+
+int32_t HdiDisplay::SetLayerZorder(uint32_t layerId, uint32_t zorder)
+{
+ DISPLAY_DEBUGLOG("layerId : %{public}d", layerId);
+ auto iter = mLayersMap.find(layerId);
+ DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not find the layer %{public}d", layerId));
+ auto layer = mLayersMap[layerId].get();
+ if (layer->GetZorder() == zorder) {
+ DISPLAY_DEBUGLOG("zorder no change layerId %{public}d, zorder %{public}d", layerId, zorder);
+ return DISPLAY_SUCCESS;
+ }
+ // reset to sort
+ auto zRange = mLayers.equal_range(layer);
+ DISPLAY_DEBUGLOG("zorder range : zRange.first %{public}p zRange.second %{public}p", *zRange.first, *zRange.second);
+ for (auto c = zRange.first; c != zRange.second; c++) {
+ if (*c == layer) {
+ mLayers.erase(c);
+ break;
+ }
+ }
+ layer->SetLayerZorder(zorder);
+ mLayers.emplace(layer);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::CreateLayer(const LayerInfo *layerInfo, uint32_t *layerId)
+{
+ DISPLAY_DEBUGLOG();
+ int ret;
+ DISPLAY_CHK_RETURN((layerInfo == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("LayerInfo is null"));
+ DISPLAY_CHK_RETURN((layerId == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("layerId is null"));
+ auto layer = CreateHdiLayer(layerInfo->type);
+ DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer"));
+ ret = layer->Init();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Layer Init failed"));
+ *layerId = layer->GetId();
+ mLayers.insert(layer.get());
+ mLayersMap.emplace(layer->GetId(), std::move(layer));
+ DISPLAY_DEBUGLOG("mLayers size %{public}zu", mLayers.size());
+ DISPLAY_DEBUGLOG("mLayerMap size %{public}zu", mLayersMap.size());
+ return DISPLAY_SUCCESS;
+}
+
+std::unique_ptr HdiDisplay::CreateHdiLayer(LayerType type)
+{
+ DISPLAY_DEBUGLOG();
+ return std::make_unique(type);
+}
+
+
+int32_t HdiDisplay::CloseLayer(uint32_t layerId)
+{
+ DISPLAY_DEBUGLOG("layerId %{public}d", layerId);
+ auto iter = mLayersMap.find(layerId);
+ DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not find the layer id %{public}d", layerId));
+ mLayers.erase(iter->second.get());
+ mLayersMap.erase(layerId);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type)
+{
+ DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
+ *num = mChangeLayers.size();
+ if ((layers == nullptr) && (type == nullptr)) {
+ return DISPLAY_SUCCESS;
+ }
+ DISPLAY_DEBUGLOG("set the layers and type");
+ for (uint32_t i = 0; i < mChangeLayers.size(); i++) {
+ HdiLayer *layer = mChangeLayers[i];
+ if (layers != nullptr) {
+ *(layers + i) = layer->GetId();
+ }
+ if (type != nullptr) {
+ *(type + i) = layer->GetCompositionType();
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences)
+{
+ DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
+ *num = mLayers.size();
+ if ((layers == nullptr) && (fences == nullptr)) {
+ return DISPLAY_SUCCESS;
+ }
+ DISPLAY_DEBUGLOG("set the layer fences");
+ int i = 0;
+ for (auto layer : mLayers) {
+ if (layers != nullptr) {
+ *(layers + i) = layer->GetId();
+ }
+ if (fences != nullptr) {
+ *(fences + i) = dup(layer->GetReleaseFenceFd());
+ }
+ DISPLAY_DEBUGLOG("layer id %{public}d fencefd %{public}d", layer->GetId(), layer->GetReleaseFenceFd());
+ i++;
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
+{
+ DISPLAY_DEBUGLOG();
+ mChangeLayers.clear();
+ std::vector layers;
+ uint32_t topZpos = 3;
+ for (auto c : mLayers) {
+ layers.push_back(c);
+ }
+ DISPLAY_DEBUGLOG(" mLayers size %{public}zu layers size %{public}zu", mLayers.size(), layers.size());
+
+ /* Set the target layer to the top.
+ * It would not by cover by other layer.
+ */
+ mClientLayer->SetLayerZorder(topZpos);
+
+ mComposer->Prepare(layers, *mClientLayer);
+ // get the change layers
+ for (auto &layer : layers) {
+ if (layer->GetDeviceSelect() != layer->GetCompositionType()) {
+ DISPLAY_DEBUGLOG("layer change");
+ layer->SetLayerCompositionType(layer->GetDeviceSelect());
+ }
+ mChangeLayers.push_back(layer);
+ }
+ *needFlushFb = true;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::Commit(int32_t *fence)
+{
+ DISPLAY_DEBUGLOG();
+ mComposer->Commit(false);
+ *fence = dup(mClientLayer->GetReleaseFenceFd());
+ DISPLAY_DEBUGLOG("the release fence is %{public}d", *fence);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence)
+{
+ mClientLayer->SetLayerBuffer(buffer, fence);
+ return DISPLAY_SUCCESS;
+}
+
+HdiLayer *HdiDisplay::GetHdiLayer(uint32_t id)
+{
+ DISPLAY_DEBUGLOG("id : %{public}d", id);
+ auto iter = mLayersMap.find(id);
+ DISPLAY_CHK_RETURN((iter == mLayersMap.end()), nullptr, DISPLAY_LOGE("can not find the layer %{public}d", id));
+ return iter->second.get();
+}
+
+VsyncCallBack::VsyncCallBack(VBlankCallback cb, void *data, uint32_t displayId) : mVBlankCb(cb),
+ mData(data), mPipe(displayId)
+{
+ DISPLAY_DEBUGLOG("VsyncCallBack %{public}p", cb);
+}
+
+void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
+{
+ DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
+ mVBlankCb(sequence, ns, mData);
+}
+}
+}
+}
diff --git a/hardware/display/src/display_device/hdi_display.h b/hardware/display/src/display_device/hdi_display.h
new file mode 100644
index 0000000000000000000000000000000000000000..277b55cfbb345ae6db02555dabe5bdee21ba8803
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_display.h
@@ -0,0 +1,133 @@
+/*
+ * 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 HDI_DISPLAY_H
+#define HDI_DISPLAY_H
+#include
+#include
+#include
+#include
+#include "display_device.h"
+#include "hdi_composer.h"
+#include "hdi_layer.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const uint32_t INVALIDE_DISPLAY_ID = 0xffffffff;
+const 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:
+ uint32_t GetId() const
+ {
+ return mId;
+ }
+ virtual int32_t Init();
+ virtual void DeInit() {}
+ HdiDisplay() {}
+ virtual ~HdiDisplay();
+ virtual int32_t GetDisplayCapability(DisplayCapability *info)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t GetDisplayMode(uint32_t *modeId)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t SetDisplayMode(uint32_t modeId)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t GetDisplayPowerStatus(DispPowerStatus *status)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t SetDisplayPowerStatus(DispPowerStatus status)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t GetDisplayBacklight(uint32_t *value)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t SetDisplayBacklight(uint32_t value)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t CreateLayer(const LayerInfo *layerInfo, uint32_t *layerId);
+ virtual int32_t CloseLayer(uint32_t layerId);
+ virtual int32_t PrepareDisplayLayers(bool *needFlushFb);
+ virtual int32_t Commit(int32_t *fence);
+ virtual int32_t GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type);
+ virtual int32_t SetLayerZorder(uint32_t layerId, uint32_t zorder);
+ virtual bool IsConnected()
+ {
+ return false;
+ }
+ virtual int32_t RegDisplayVBlankCallback(VBlankCallback cb, void *data)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t SetDisplayVsyncEnabled(bool enabled)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ virtual int32_t GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences);
+ virtual int32_t SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence);
+ virtual int32_t WaitForVBlank(uint64_t *ns)
+ {
+ return DISPLAY_NOT_SUPPORT;
+ }
+ HdiLayer *GetHdiLayer(uint32_t id);
+
+protected:
+ virtual std::unique_ptr CreateHdiLayer(LayerType type);
+ std::unique_ptr mComposer;
+
+ static uint32_t GetIdleId();
+ static uint32_t mIdleId;
+ static std::unordered_set mIdSets;
+ uint32_t mId = INVALIDE_DISPLAY_ID;
+ std::unordered_map> mLayersMap;
+ std::multiset mLayers;
+ std::unique_ptr mClientLayer;
+ std::vector mChangeLayers;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_DISPLAY_H
diff --git a/hardware/display/src/display_device/hdi_drm_composition.cpp b/hardware/display/src/display_device/hdi_drm_composition.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..cfeb1fc5979df28b248dbdd5676cfe44bb7af896
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_drm_composition.cpp
@@ -0,0 +1,298 @@
+/*
+ * 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_drm_composition.h"
+#include
+#include "hdi_drm_layer.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+HdiDrmComposition::HdiDrmComposition(const std::shared_ptr &connector,
+ const std::shared_ptr &crtc,
+ const std::shared_ptr &drmDevice)
+ : mDrmDevice(drmDevice), mConnector(connector), mCrtc(crtc)
+{
+ DISPLAY_DEBUGLOG();
+}
+
+int32_t HdiDrmComposition::Init()
+{
+ DISPLAY_DEBUGLOG();
+ mPrimPlanes.clear();
+ mOverlayPlanes.clear();
+ mPlanes.clear();
+ DISPLAY_CHK_RETURN((mCrtc == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("crtc is null"));
+ DISPLAY_CHK_RETURN((mConnector == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("connector is null"));
+ DISPLAY_CHK_RETURN((mDrmDevice == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("drmDevice is null"));
+ mPrimPlanes = mDrmDevice->GetDrmPlane(mCrtc->GetPipe(), DRM_PLANE_TYPE_PRIMARY);
+ mOverlayPlanes = mDrmDevice->GetDrmPlane(mCrtc->GetPipe(), DRM_PLANE_TYPE_OVERLAY);
+ mPlanes.insert(mPlanes.end(), mPrimPlanes.begin(), mPrimPlanes.end());
+ mPlanes.insert(mPlanes.end(), mOverlayPlanes.begin(), mOverlayPlanes.end());
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::SetLayers(std::vector &layers, HdiLayer &clientLayer)
+{
+ // now we do not surpport present direct
+ DISPLAY_DEBUGLOG();
+ mCompLayers.clear();
+ mCompLayers.push_back(&clientLayer);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::SetCrtcProperty(DrmPlane &drmPlane,
+ drmModeAtomicReqPtr pset,
+ int32_t bufferW,
+ int32_t bufferH)
+{
+ int ret;
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtc_xId(), 0);
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropCrtc_xId %{public}d, crop.x %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropCrtc_xId(), 0);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtc_yId(), 0);
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropCrtc_yId %{public}d, crop.y %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropCrtc_yId(), 0);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtc_wId(), bufferW);
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropCrtc_wId %{public}d, crop.w %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropCrtc_wId(), bufferW);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtc_hId(), bufferH);
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropCrtc_hId %{public}d, crop.h %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropCrtc_xId(), bufferH);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::SetSrcProperty(DrmPlane &drmPlane,
+ drmModeAtomicReqPtr pset,
+ int32_t bufferW,
+ int32_t bufferH)
+{
+ int ret;
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropSrc_xId(), 0<<16); // 16:shift left 16 bits
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropSrc_xId %{public}d, displayRect.x %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropSrc_xId(), 0);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropSrc_yId(), 0<<16); // 16:shift left 16 bits
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropSrc_yId %{public}d, displayRect.y %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropSrc_yId(), 0);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropSrc_wId(),
+ bufferW<<16); // 16:shift left 16 bits
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropCrtc_wId %{public}d, displayRect.w %{public}d",
+ drmPlane.GetId(), drmPlane.GetPropSrc_wId(), bufferW);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropSrc_hId(),
+ bufferH<<16); // 16:shift left 16 bits
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropSrc_hId %{public}d, displayRect.h %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropSrc_hId(), bufferH);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the fb planeid fialed errno : %{public}d", errno));
+
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::ApplyPlane(HdiDrmLayer &layer,
+ HdiLayer &hlayer,
+ DrmPlane &drmPlane,
+ drmModeAtomicReqPtr pset)
+{
+ int ret;
+ int fenceFd = layer.GetAcquireFenceFd();
+ int propId = drmPlane.GetPropFenceInId();
+ HdiLayerBuffer *layerBuffer = hlayer.GetCurrentBuffer();
+ int32_t bufferW = layerBuffer->GetWight();
+ int32_t bufferH = layerBuffer->GetHeight();
+
+ DISPLAY_DEBUGLOG();
+ if (propId != 0) {
+ DISPLAY_LOGI("set the fence in prop");
+ if (fenceFd >= 0) {
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), propId, fenceFd);
+ DISPLAY_DEBUGLOG("set the IfenceProp plane id %{public}d, propId %{public}d, fenceFd %{public}d",
+ drmPlane.GetId(), propId, fenceFd);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set IN_FENCE_FD failed"));
+ }
+ }
+
+ ret = SetCrtcProperty(drmPlane, pset, bufferW, bufferH);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set Crtc fialed errno : %{public}d", errno));
+
+ ret = SetSrcProperty(drmPlane, pset, bufferW, bufferH);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set Src fialed errno : %{public}d", errno));
+
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropZposId(), layer.GetZorder());
+ DISPLAY_LOGI("set the fb planeid %{public}d, GetPropZposId %{public}d, zpos %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropZposId(), layer.GetZorder());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the zpos fialed errno : %{public}d", errno));
+
+ // set fb id
+ DrmGemBuffer *gemBuffer = layer.GetGemBuffer();
+ DISPLAY_CHK_RETURN((gemBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("current gemBuffer is nullptr"));
+ DISPLAY_CHK_RETURN((!gemBuffer->IsValid()), DISPLAY_FAILURE, DISPLAY_LOGE("the DrmGemBuffer is invalid"));
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropFbId(), gemBuffer->GetFbId());
+ DISPLAY_DEBUGLOG("set the fb planeid %{public}d, propId %{public}d, fbId %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropFbId(), gemBuffer->GetFbId());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set fb id fialed errno : %{public}d", errno));
+
+ // set crtc id
+ ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), drmPlane.GetPropCrtcId(), mCrtc->GetId());
+ DISPLAY_DEBUGLOG("set the crtc planeId %{public}d, propId %{public}d, crtcId %{public}d", drmPlane.GetId(),
+ drmPlane.GetPropCrtcId(), mCrtc->GetId());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set crtc id fialed errno : %{public}d", errno));
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::UpdateMode(std::unique_ptr &modeBlock, drmModeAtomicReq &pset)
+{
+ // set the mode
+ DISPLAY_LOGI();
+ if (mCrtc->NeedModeSet()) {
+ modeBlock = mConnector->GetModeBlockFromId(mCrtc->GetActiveModeId());
+ if ((modeBlock != nullptr) && (modeBlock->GetBlockId() != DRM_INVALID_ID)) {
+ // set to active
+ DISPLAY_DEBUGLOG("set crtc to active");
+ int ret = drmModeAtomicAddProperty(&pset, mCrtc->GetId(), mCrtc->GetActivePropId(), 1);
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not add the active prop errno %{public}d", errno));
+
+ // set the mode id
+ DISPLAY_DEBUGLOG("set the mode");
+ ret = drmModeAtomicAddProperty(&pset, mCrtc->GetId(), mCrtc->GetModePropId(), modeBlock->GetBlockId());
+ DISPLAY_LOGI("set the mode planeId %{public}d, propId %{public}d, GetBlockId: %{public}d", mCrtc->GetId(),
+ mCrtc->GetModePropId(), modeBlock->GetBlockId());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not add the mode prop errno %{public}d", errno));
+ ret = drmModeAtomicAddProperty(&pset, mConnector->GetId(), mConnector->GetPropCrtcId(), mCrtc->GetId());
+ DISPLAY_LOGI("set the connector id: %{public}d, propId %{public}d, crtcId %{public}d", mConnector->GetId(),
+ mConnector->GetPropCrtcId(), mCrtc->GetId());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not add the crtc id prop %{public}d", errno));
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::RemoveUnusePlane(drmModeAtomicReqPtr pset)
+{
+ int ret = 0;
+ /* Remove useless planes from the drm */
+ for (uint32_t j = 0; j < mPlanes.size(); j++) {
+ auto &drmPlane = mPlanes[j];
+ if ((static_cast(drmPlane->GetWinType()) & mCrtc->GetPlaneMask()) && drmPlane->GetPipe() == 0) {
+ DISPLAY_LOGI("no used plane %{public}s id %{public}d", drmPlane->GetName().c_str(), drmPlane->GetId());
+ ret = drmModeAtomicAddProperty(pset, drmPlane->GetId(), drmPlane->GetPropFbId(), 0);
+ ret = drmModeAtomicAddProperty(pset, drmPlane->GetId(), drmPlane->GetPropFbId(), 0);
+ drmPlane->UnBindPipe();
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::FindPlaneAndApply(drmModeAtomicReqPtr pset)
+{
+ int32_t ret = 0;
+ for (uint32_t i = 0; i < mCompLayers.size(); i++) {
+ HdiDrmLayer *layer = static_cast(mCompLayers[i]);
+ HdiLayer *hlayer = mCompLayers[i];
+ for (uint32_t j = 0; j < mPlanes.size(); j++) {
+ auto &drmPlane = mPlanes[j];
+ if (drmPlane->GetPipe() != 0 && drmPlane->GetPipe() != (1 << mCrtc->GetPipe())) {
+ DISPLAY_LOGI("plane %{public}d used pipe %{public}d crtc pipe %{public}d", drmPlane->GetId(),
+ drmPlane->GetPipe(), mCrtc->GetPipe());
+ continue;
+ }
+ /* Check whether the plane belond to the crtc */
+ if (!(static_cast(drmPlane->GetWinType()) & mCrtc->GetPlaneMask())) {
+ continue;
+ }
+ DISPLAY_LOGI("use plane %{public}d WinType %{public}x crtc %{public}d PlaneMask %{public}x",
+ drmPlane->GetId(), drmPlane->GetWinType(), mCrtc->GetId(), mCrtc->GetPlaneMask());
+
+ if (drmPlane->GetCrtcId() == mCrtc->GetId() || drmPlane->GetCrtcId() == 0) {
+ ret = ApplyPlane(*layer, *hlayer, *drmPlane, pset);
+ if (ret != DISPLAY_SUCCESS) {
+ DISPLAY_LOGE("apply plane failed");
+ break;
+ }
+ /* mark the plane is used by crtc */
+ drmPlane->BindToPipe(1 << mCrtc->GetPipe());
+ break;
+ }
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiDrmComposition::Apply(bool modeSet)
+{
+ uint64_t crtcOutFence = -1;
+ int ret = 0;
+ std::unique_ptr modeBlock;
+ int drmFd = mDrmDevice->GetDrmFd();
+
+ DISPLAY_LOGI("mPlane size: %{public}zd mCompLayers size: %{public}zd", mPlanes.size(), mCompLayers.size());
+ DISPLAY_CHK_RETURN((mPlanes.size() < mCompLayers.size()), DISPLAY_FAILURE, DISPLAY_LOGE("plane not enough"));
+ drmModeAtomicReqPtr pset = drmModeAtomicAlloc();
+ DISPLAY_CHK_RETURN((pset == nullptr), DISPLAY_NULL_PTR,
+ DISPLAY_LOGE("drm atomic alloc failed errno %{public}d", errno));
+ AtomicReqPtr atomicReqPtr = AtomicReqPtr(pset);
+
+ // set the outFence property
+ ret = drmModeAtomicAddProperty(atomicReqPtr.Get(), mCrtc->GetId(), mCrtc->GetOutFencePropId(),
+ (uint64_t)&crtcOutFence);
+
+ DISPLAY_DEBUGLOG("Apply Set OutFence crtc id: %{public}d, fencePropId %{public}d", mCrtc->GetId(),
+ mCrtc->GetOutFencePropId());
+ DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("set the outfence property of crtc failed "));
+
+ // set the plane info.
+ DISPLAY_LOGI("mCompLayers size %{public}zd", mCompLayers.size());
+ DISPLAY_LOGI("crtc id %{public}d connect id %{public}d encoder id %{public}d", mCrtc->GetId(),
+ mConnector->GetId(), mConnector->GetEncoderId());
+
+ /* Bind the plane not used by other crtcs to the crtc. */
+ FindPlaneAndApply(atomicReqPtr.Get());
+ /* Remove useless planes from the drm */
+ RemoveUnusePlane(atomicReqPtr.Get());
+
+ ret = UpdateMode(modeBlock, *(atomicReqPtr.Get()));
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("update mode failed"));
+ uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
+
+ ret = drmModeAtomicCommit(drmFd, atomicReqPtr.Get(), flags, nullptr);
+ DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE,
+ DISPLAY_LOGE("drmModeAtomicCommit failed %{public}d errno %{public}d", ret, errno));
+ // set the release fence
+ for (auto layer : mCompLayers) {
+ layer->SetReleaseFence(static_cast(crtcOutFence));
+ }
+
+ return DISPLAY_SUCCESS;
+}
+} // OHOS
+} // HDI
+} // DISPLAY
diff --git a/hardware/display/src/display_device/hdi_drm_composition.h b/hardware/display/src/display_device/hdi_drm_composition.h
new file mode 100755
index 0000000000000000000000000000000000000000..042ff3c49fb38009123a625bbb0a715b0d9cc776
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_drm_composition.h
@@ -0,0 +1,75 @@
+/*
+ * 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 HDI_DRM_COMPOSITION_H
+#define HDI_DRM_COMPOSITION_H
+#include
+#include
+#include
+#include
+#include "drm_device.h"
+#include "hdi_composer.h"
+#include "hdi_device_common.h"
+#include "hdi_drm_layer.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class AtomicReqPtr {
+public:
+ explicit AtomicReqPtr(drmModeAtomicReqPtr ptr) : mPtr(ptr) {}
+ virtual ~AtomicReqPtr()
+ {
+ if (mPtr != nullptr)
+ drmModeAtomicFree(mPtr);
+ }
+ drmModeAtomicReqPtr Get() const
+ {
+ return mPtr;
+ }
+
+private:
+ drmModeAtomicReqPtr mPtr;
+};
+
+class HdiDrmComposition : public HdiComposition {
+public:
+ HdiDrmComposition(const std::shared_ptr &connector,
+ const std::shared_ptr &crtc,
+ const std::shared_ptr &drmDevice);
+ ~HdiDrmComposition() override {}
+ int32_t Init() override;
+ int32_t SetLayers(std::vector &layers, HdiLayer &clientLayer) override;
+ int32_t Apply(bool modeSet) override;
+ int32_t UpdateMode(std::unique_ptr &modeBlock, drmModeAtomicReq &pset);
+
+private:
+ int32_t ApplyPlane(HdiDrmLayer &layer, HdiLayer &hlayer, DrmPlane &drmPlane, drmModeAtomicReqPtr pset);
+ int32_t SetSrcProperty(DrmPlane &drmPlane, drmModeAtomicReqPtr pset, int32_t bufferW, int32_t bufferH);
+ int32_t SetCrtcProperty(DrmPlane &drmPlane, drmModeAtomicReqPtr pset, int32_t bufferW, int32_t bufferH);
+ int32_t RemoveUnusePlane(drmModeAtomicReqPtr pset);
+ int32_t FindPlaneAndApply(drmModeAtomicReqPtr pset);
+ std::shared_ptr mDrmDevice;
+ std::shared_ptr mConnector;
+ std::shared_ptr mCrtc;
+ std::vector> mPrimPlanes;
+ std::vector> mOverlayPlanes;
+ std::vector> mPlanes;
+};
+} // OHOS
+} // HDI
+} // DISPLAY
+
+#endif // HDI_DRM_COMPOSITION_H
diff --git a/hardware/display/src/display_device/hdi_drm_layer.cpp b/hardware/display/src/display_device/hdi_drm_layer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5cb701fead6d885993de81477d0e5d7c56781b65
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_drm_layer.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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_drm_layer.h"
+#include
+#include
+#include "drm_device.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+DrmGemBuffer::DrmGemBuffer(int drmFd, HdiLayerBuffer &hdl) : mDrmFd(drmFd)
+{
+ DISPLAY_DEBUGLOG();
+ Init(mDrmFd, hdl);
+}
+
+void DrmGemBuffer::Init(int drmFd, HdiLayerBuffer &hdl)
+{
+ int ret;
+ const int MAX_COUNT = 4;
+ uint32_t pitches[MAX_COUNT] = {0};
+ uint32_t gemHandles[MAX_COUNT] = {0};
+ uint32_t offsets[MAX_COUNT] = {0};
+ DISPLAY_DEBUGLOG("hdl %{public}" PRIx64 "", hdl.GetPhysicalAddr());
+ DISPLAY_CHK_RETURN_NOT_VALUE((drmFd < 0), DISPLAY_LOGE("can not init drmfd %{public}d", drmFd));
+ mDrmFormat = DrmDevice::ConvertToDrmFormat(static_cast(hdl.GetFormat()));
+ ret = drmPrimeFDToHandle(drmFd, hdl.GetFb(), &mGemHandle);
+ DISPLAY_CHK_RETURN_NOT_VALUE((ret != 0), DISPLAY_LOGE("can not get handle errno %{public}d", errno));
+
+ pitches[0] = hdl.GetStride();
+ gemHandles[0] = mGemHandle;
+ offsets[0] = 0;
+ ret = drmModeAddFB2(drmFd, hdl.GetWight(), hdl.GetHeight(), mDrmFormat, gemHandles, pitches, offsets, &mFdId, 0);
+ DISPLAY_DEBUGLOG("mGemHandle %{public}d mFdId %{public}d", mGemHandle, mFdId);
+ DISPLAY_DEBUGLOG("w: %{public}d h: %{public}d mDrmFormat : %{public}d gemHandles: %{public}d pitches: %{public}d "
+ "offsets: %{public}d",
+ hdl.GetWight(), hdl.GetHeight(), mDrmFormat, gemHandles[0], pitches[0], offsets[0]);
+ DISPLAY_CHK_RETURN_NOT_VALUE((ret != 0), DISPLAY_LOGE("can not add fb errno %{public}d", errno));
+}
+
+DrmGemBuffer::~DrmGemBuffer()
+{
+ DISPLAY_DEBUGLOG();
+ if (mFdId) {
+ if (drmModeRmFB(mDrmFd, mFdId)) {
+ DISPLAY_LOGE("can not free fdid %{public}d errno %{public}d", mFdId, errno);
+ }
+ }
+
+ if (mGemHandle) {
+ struct drm_gem_close gemClose = { 0 };
+ gemClose.handle = mGemHandle;
+ if (drmIoctl(mDrmFd, DRM_IOCTL_GEM_CLOSE, &gemClose)) {
+ DISPLAY_LOGE("can not free gem handle %{public}d errno : %{public}d", mGemHandle, errno);
+ }
+ }
+}
+
+bool DrmGemBuffer::IsValid()
+{
+ DISPLAY_DEBUGLOG();
+ return (mGemHandle != INVALID_DRM_ID) && (mFdId != INVALID_DRM_ID);
+}
+
+DrmGemBuffer *HdiDrmLayer::GetGemBuffer()
+{
+ DISPLAY_DEBUGLOG();
+ std::unique_ptr ptr = std::make_unique(DrmDevice::GetDrmFd(), *GetCurrentBuffer());
+ mLastBuffer = std::move(mCurrentBuffer);
+ mCurrentBuffer = std::move(ptr);
+ return mCurrentBuffer.get();
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/hdi_drm_layer.h b/hardware/display/src/display_device/hdi_drm_layer.h
new file mode 100644
index 0000000000000000000000000000000000000000..43ad767b4ef42a6f8921cb1f71c3e9cbe8c74630
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_drm_layer.h
@@ -0,0 +1,63 @@
+/*
+ * 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 HDI_DRM_LAYER_H
+#define HDI_DRM_LAYER_H
+#include
+#include
+#include "buffer_handle.h"
+#include "display_common.h"
+#include "drm_fourcc.h"
+#include "hdi_layer.h"
+#include "hdi_device_common.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const int INVALID_DRM_ID = 0;
+class DrmGemBuffer {
+public:
+ DrmGemBuffer(int drmFd, HdiLayerBuffer &hdl);
+ virtual ~DrmGemBuffer();
+ uint32_t GetFbId() const
+ {
+ return mFdId;
+ }
+ bool IsValid();
+
+private:
+ void Init(int drmFd, HdiLayerBuffer &hdl);
+ uint32_t mGemHandle = 0;
+ uint32_t mFdId = 0;
+ int mDrmFd = -1; // the fd can not close. the other module will close it.
+ uint32_t mDrmFormat = DRM_FORMAT_INVALID;
+};
+
+class HdiDrmLayer : public HdiLayer {
+public:
+ explicit HdiDrmLayer(LayerType type) : HdiLayer(type) {}
+ ~HdiDrmLayer() override {}
+ // Return value optimization
+ DrmGemBuffer *GetGemBuffer();
+
+private:
+ std::unique_ptr mCurrentBuffer;
+ std::unique_ptr mLastBuffer;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_DRM_LAYER_H
diff --git a/hardware/display/src/display_device/hdi_gfx_composition.cpp b/hardware/display/src/display_device/hdi_gfx_composition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b53fef257bb8745b8c7a173ac1bf9bc58bd8e0f
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_gfx_composition.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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
+#include
+#include
+#include "display_gfx.h"
+#include "hdi_gfx_composition.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+int32_t HdiGfxComposition::Init(void)
+{
+ DISPLAY_DEBUGLOG();
+ int32_t ret = GfxModuleInit();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS) || (mGfxFuncs == nullptr), DISPLAY_FAILURE,
+ DISPLAY_LOGE("GfxModuleInit failed"));
+ ret = mGfxFuncs->InitGfx();
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("gfx init failed"));
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiGfxComposition::GfxModuleInit(void)
+{
+ DISPLAY_DEBUGLOG();
+ mGfxModule = dlopen("libdisplay_gfx.z.so", RTLD_NOW | RTLD_NOLOAD);
+ if (mGfxModule != nullptr) {
+ DISPLAY_LOGI("Module '%{public}s' already loaded", "libdisplay_gfx.z.so");
+ } else {
+ DISPLAY_LOGI("Loading module '%{public}s'", "libdisplay_gfx.z.so");
+ mGfxModule = dlopen("libdisplay_gfx.z.so", RTLD_NOW);
+ if (mGfxModule == nullptr) {
+ DISPLAY_LOGE("Failed to load module: %{public}s", dlerror());
+ return DISPLAY_FAILURE;
+ }
+ }
+
+ using InitFunc = int32_t (*)(GfxFuncs **funcs);
+ InitFunc func = reinterpret_cast(dlsym(mGfxModule, "GfxInitialize"));
+ if (func == nullptr) {
+ DISPLAY_LOGE("Failed to lookup %{public}s function: %s", "GfxInitialize", dlerror());
+ dlclose(mGfxModule);
+ return DISPLAY_FAILURE;
+ }
+ return func(&mGfxFuncs);
+}
+
+int32_t HdiGfxComposition::GfxModuleDeinit(void)
+{
+ DISPLAY_DEBUGLOG();
+ int32_t ret = DISPLAY_SUCCESS;
+ if (mGfxModule == nullptr) {
+ using DeinitFunc = int32_t (*)(GfxFuncs *funcs);
+ DeinitFunc func = reinterpret_cast(dlsym(mGfxModule, "GfxUninitialize"));
+ if (func == nullptr) {
+ DISPLAY_LOGE("Failed to lookup %{public}s function: %s", "GfxUninitialize", dlerror());
+ } else {
+ ret = func(mGfxFuncs);
+ }
+ dlclose(mGfxModule);
+ }
+ return ret;
+}
+
+bool HdiGfxComposition::CanHandle(HdiLayer &hdiLayer)
+{
+ DISPLAY_DEBUGLOG();
+ (void)hdiLayer;
+ return true;
+}
+
+int32_t HdiGfxComposition::SetLayers(std::vector &layers, HdiLayer &clientLayer)
+{
+ DISPLAY_DEBUGLOG("layers size %{public}zd", layers.size());
+ mClientLayer = &clientLayer;
+ mCompLayers.clear();
+ for (auto &layer : layers) {
+ if (CanHandle(*layer)) {
+ if ((layer->GetCompositionType() != COMPOSITION_VIDEO) &&
+ (layer->GetCompositionType() != COMPOSITION_CURSOR)) {
+ layer->SetDeviceSelect(COMPOSITION_DEVICE);
+ } else {
+ layer->SetDeviceSelect(layer->GetCompositionType());
+ }
+ mCompLayers.push_back(layer);
+ }
+ }
+ DISPLAY_DEBUGLOG("composer layers size %{public}zd", mCompLayers.size());
+ return DISPLAY_SUCCESS;
+}
+
+void HdiGfxComposition::InitGfxSurface(ISurface &iSurface, HdiLayerBuffer &buffer)
+{
+ iSurface.width = buffer.GetWight();
+ iSurface.height = buffer.GetHeight();
+ iSurface.phyAddr = buffer.GetFb(); // buffer.GetPhysicalAddr();
+ iSurface.enColorFmt = (PixelFormat)buffer.GetFormat();
+ iSurface.stride = buffer.GetStride();
+ iSurface.bAlphaExt1555 = true;
+ iSurface.bAlphaMax255 = true;
+ iSurface.alpha0 = 0XFF;
+ iSurface.alpha1 = 0XFF;
+ DISPLAY_DEBUGLOG("iSurface fd %{public}d w:%{public}d h:%{public}d addr:0x%{public}" \
+ PRIx64 " fmt:%{public}d stride:%{public}d",
+ buffer.GetFb(), iSurface.width, iSurface.height,
+ buffer.GetPhysicalAddr(), iSurface.enColorFmt, iSurface.stride);
+}
+
+// now not handle the alpha of layer
+int32_t HdiGfxComposition::BlitLayer(HdiLayer &src, HdiLayer &dst)
+{
+ ISurface srcSurface = { 0 };
+ ISurface dstSurface = { 0 };
+ GfxOpt opt = { 0 };
+ DISPLAY_DEBUGLOG();
+ HdiLayerBuffer *srcBuffer = src.GetCurrentBuffer();
+ DISPLAY_CHK_RETURN((srcBuffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the srcbuffer is null"));
+ DISPLAY_DEBUGLOG("init the src iSurface");
+ InitGfxSurface(srcSurface, *srcBuffer);
+
+ HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
+ DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
+ DISPLAY_DEBUGLOG("init the dst iSurface");
+ InitGfxSurface(dstSurface, *dstBuffer);
+
+ opt.blendType = src.GetLayerBlenType();
+ DISPLAY_DEBUGLOG("blendType %{public}d", opt.blendType);
+ opt.enPixelAlpha = true;
+ opt.enableScale = true;
+
+ if (src.GetAlpha().enGlobalAlpha) { // is alpha is 0xff we not set it
+ opt.enGlobalAlpha = true;
+ srcSurface.alpha0 = src.GetAlpha().gAlpha;
+ DISPLAY_DEBUGLOG("src alpha %{public}x", src.GetAlpha().gAlpha);
+ }
+ opt.rotateType = src.GetTransFormType();
+ DISPLAY_DEBUGLOG(" the roate type is %{public}d", opt.rotateType);
+ IRect crop = src.GetLayerCrop();
+ IRect displayRect = src.GetLayerDisplayRect();
+ DISPLAY_DEBUGLOG("crop x: %{public}d y : %{public}d w : %{public}d h: %{public}d", crop.x, crop.y, crop.w, crop.h);
+ DISPLAY_DEBUGLOG("displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d",
+ displayRect.x, displayRect.y, displayRect.w, displayRect.h);
+ DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Blit: mGfxFuncs is null"));
+ return mGfxFuncs->Blit(&srcSurface, &crop, &dstSurface, &displayRect, &opt);
+}
+
+int32_t HdiGfxComposition::ClearRect(HdiLayer &src, HdiLayer &dst)
+{
+ ISurface dstSurface = { 0 };
+ GfxOpt opt = { 0 };
+ DISPLAY_DEBUGLOG();
+ HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
+ DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
+ InitGfxSurface(dstSurface, *dstBuffer);
+ IRect rect = src.GetLayerDisplayRect();
+ DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Rect: mGfxFuncs is null"));
+ return mGfxFuncs->FillRect(&dstSurface, &rect, 0, &opt);
+}
+
+int32_t HdiGfxComposition::Apply(bool modeSet)
+{
+ int32_t ret;
+ DISPLAY_DEBUGLOG("composer layers size %{public}zd", mCompLayers.size());
+ for (uint32_t i = 0; i < mCompLayers.size(); i++) {
+ HdiLayer *layer = mCompLayers[i];
+ CompositionType compType = layer->GetCompositionType();
+ switch (compType) {
+ case COMPOSITION_VIDEO:
+ ret = ClearRect(*layer, *mClientLayer);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
+ DISPLAY_LOGE("clear layer %{public}d failed", i));
+ break;
+ case COMPOSITION_DEVICE:
+ ret = BlitLayer(*layer, *mClientLayer);
+ DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
+ DISPLAY_LOGE("blit layer %{public}d failed ", i));
+ break;
+ default:
+ DISPLAY_LOGE("the gfx composition can not surpport the type %{public}d", compType);
+ break;
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/hdi_gfx_composition.h b/hardware/display/src/display_device/hdi_gfx_composition.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9654461d39a806aa9952be86d8a4ac327c90d60
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_gfx_composition.h
@@ -0,0 +1,48 @@
+/*
+ * 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 HDI_GFX_COMPOSITION_H
+#define HDI_GFX_COMPOSITION_H
+#include "display_gfx.h"
+#include "hdi_composer.h"
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class HdiGfxComposition : public HdiComposition {
+public:
+ int32_t Init(void) override;
+ int32_t SetLayers(std::vector &layers, HdiLayer &clientLayer) override;
+ int32_t Apply(bool modeSet) override;
+ ~HdiGfxComposition() override
+ {
+ (void)GfxModuleDeinit();
+ }
+
+private:
+ bool CanHandle(HdiLayer &hdiLayer);
+ void InitGfxSurface(ISurface &iSurface, HdiLayerBuffer &buffer);
+ int32_t BlitLayer(HdiLayer &src, HdiLayer &dst);
+ int32_t ClearRect(HdiLayer &src, HdiLayer &dst);
+ int32_t GfxModuleInit(void);
+ int32_t GfxModuleDeinit(void);
+ void *mGfxModule = nullptr;
+ GfxFuncs *mGfxFuncs = nullptr;
+ HdiLayer *mClientLayer;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_GFX_COMPOSITION_H
diff --git a/hardware/display/src/display_device/hdi_layer.cpp b/hardware/display/src/display_device/hdi_layer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20808a91be0de4c6061b362b46dea65cd104b6ad
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_layer.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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_layer.h"
+#include
+#include
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+uint32_t HdiLayer::mIdleId = 0;
+std::unordered_set HdiLayer::mIdSets;
+
+HdiLayerBuffer::HdiLayerBuffer(const BufferHandle &hdl)
+ : mPhyAddr(hdl.phyAddr), mHeight(hdl.height), mWidth(hdl.width), mStride(hdl.stride), mFormat(hdl.format)
+{
+ DISPLAY_DEBUGLOG();
+ mFd = dup(hdl.fd);
+ mHandle = hdl;
+ if (mFd < 0) {
+ DISPLAY_LOGE("the fd : %{public}d dup failed errno %{public}d", hdl.fd, errno);
+ }
+}
+
+HdiLayerBuffer::~HdiLayerBuffer()
+{
+ DISPLAY_DEBUGLOG();
+ if (mFd >= 0) {
+ close(mFd);
+ }
+}
+
+HdiLayerBuffer &HdiLayerBuffer::operator = (const BufferHandle &right)
+{
+ DISPLAY_DEBUGLOG();
+ if (mFd >= 0) {
+ close(mFd);
+ }
+ mFd = dup(right.fd);
+ mPhyAddr = right.phyAddr;
+ mWidth = right.width;
+ mHeight = right.height;
+ mStride = right.stride;
+ mFormat = right.format;
+ return *this;
+}
+
+uint32_t HdiLayer::GetIdleId()
+{
+ const uint32_t oldIdleId = mIdleId;
+ uint32_t id = INVALIDE_LAYER_ID;
+ // ensure the mIdleId not INVALIDE_LAYER_ID
+ mIdleId = mIdleId % INVALIDE_LAYER_ID;
+ do {
+ auto iter = mIdSets.find(mIdleId);
+ if (iter == mIdSets.end()) {
+ id = mIdleId;
+ break;
+ }
+ mIdleId = (mIdleId + 1) % INVALIDE_LAYER_ID;
+ } while (oldIdleId != mIdleId);
+ mIdSets.emplace(id);
+ mIdleId++;
+ DISPLAY_DEBUGLOG("id %{public}d mIdleId %{public}d", id, mIdleId);
+ return id;
+}
+
+int32_t HdiLayer::Init()
+{
+ DISPLAY_DEBUGLOG();
+ uint32_t id = GetIdleId();
+ DISPLAY_CHK_RETURN((id == INVALIDE_LAYER_ID), DISPLAY_FAILURE, DISPLAY_LOGE("have no id to used"));
+ mId = id;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerSize(IRect *rect)
+{
+ DISPLAY_CHK_RETURN((rect == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in rect is nullptr"));
+ DISPLAY_DEBUGLOG(" displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d", rect->x, rect->y,
+ rect->w, rect->h);
+ mDisplayRect = *rect;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerCrop(IRect *rect)
+{
+ DISPLAY_CHK_RETURN((rect == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in rect is nullptr"));
+ DISPLAY_DEBUGLOG("id : %{public}d crop x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId,
+ rect->x, rect->y, rect->w, rect->h);
+ mCrop = *rect;
+ return DISPLAY_SUCCESS;
+}
+
+void HdiLayer::SetLayerZorder(uint32_t zorder)
+{
+ DISPLAY_DEBUGLOG("id : %{public}d zorder : %{public}d ", mId, zorder);
+ mZorder = zorder;
+}
+
+int32_t HdiLayer::SetLayerPreMulti(bool preMul)
+{
+ DISPLAY_DEBUGLOG();
+ mPreMul = preMul;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerAlpha(LayerAlpha *alpha)
+{
+ DISPLAY_CHK_RETURN((alpha == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in alpha is nullptr"));
+ DISPLAY_DEBUGLOG("enable alpha %{public}d galpha 0x%{public}x", alpha->enGlobalAlpha, alpha->gAlpha);
+ mAlpha = *alpha;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetTransformMode(TransformType type)
+{
+ DISPLAY_DEBUGLOG("TransformType %{public}d", type);
+ mTransformType = type;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerDirtyRegion(IRect *region)
+{
+ DISPLAY_CHK_RETURN((region == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the in rect is null"));
+ DISPLAY_DEBUGLOG("id : %{public}d DirtyRegion x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId,
+ region->x, region->y, region->w, region->h);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerVisibleRegion(uint32_t num, IRect *rect)
+{
+ DISPLAY_DEBUGLOG("id : %{public}d DirtyRegion x: %{public}d y : %{public}d w : %{public}d h : %{public}d", mId, rect->x,
+ rect->y, rect->w, rect->h);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerBuffer(const BufferHandle *buffer, int32_t fence)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((buffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("buffer is nullptr"));
+ std::unique_ptr layerbuffer = std::make_unique(*buffer);
+ mHdiBuffer = std::move(layerbuffer);
+ mAcquireFence = fence;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerCompositionType(CompositionType type)
+{
+ DISPLAY_DEBUGLOG("CompositionType type %{public}d", type);
+ mCompositionType = type;
+ return DISPLAY_SUCCESS;
+}
+
+int32_t HdiLayer::SetLayerBlendType(BlendType type)
+{
+ DISPLAY_DEBUGLOG("BlendType type %{public}d", type);
+ mBlendType = type;
+ return DISPLAY_SUCCESS;
+}
+
+void HdiLayer::SetPixel(const BufferHandle &handle, int x, int y, uint32_t color)
+{
+ const int32_t pixelBytes = 4;
+ DISPLAY_CHK_RETURN_NOT_VALUE((handle.format <= 0),
+ DISPLAY_LOGE("CheckPixel do not support format %{public}d", handle.format));
+ DISPLAY_CHK_RETURN_NOT_VALUE((handle.virAddr == nullptr), DISPLAY_LOGE("CheckPixel viraddr is null must map it"));
+ DISPLAY_CHK_RETURN_NOT_VALUE((x < 0 || x >= handle.width),
+ DISPLAY_LOGE("CheckPixel invalid parameter x:%{public}d width:%{public}d", x, handle.width));
+ DISPLAY_CHK_RETURN_NOT_VALUE((y < 0 || y >= handle.height),
+ DISPLAY_LOGE("CheckPixel invalid parameter y:%{public}d height:%{public}d", y, handle.height));
+ int32_t position = y * handle.width + x;
+ if ((position * pixelBytes) > handle.size) {
+ DISPLAY_LOGE("the pixel postion outside\n");
+ }
+ uint32_t *pixel = reinterpret_cast(handle.virAddr) + position;
+ *pixel = color;
+}
+
+void HdiLayer::ClearColor(uint32_t color)
+{
+ DISPLAY_DEBUGLOG();
+ BufferHandle &handle = mHdiBuffer->mHandle;
+ for (int32_t x = 0; x < handle.width; x++) {
+ for (int32_t y = 0; y < handle.height; y++) {
+ SetPixel(handle, x, y, color);
+ }
+ }
+}
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
diff --git a/hardware/display/src/display_device/hdi_layer.h b/hardware/display/src/display_device/hdi_layer.h
new file mode 100644
index 0000000000000000000000000000000000000000..88803ce8e6086713bd9a33162bcdab8481f9f2ae
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_layer.h
@@ -0,0 +1,191 @@
+/*
+ * 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 HDI_LAYER_H
+#define HDI_LAYER_H
+#include
+#include
+#include "buffer_handle.h"
+#include "display_common.h"
+#include "hdi_device_common.h"
+#include "hdi_shared_fd.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+const uint32_t INVALIDE_LAYER_ID = 0xffffffff;
+struct HdiLayerBuffer {
+public:
+ explicit HdiLayerBuffer(const BufferHandle &hdl);
+ virtual ~HdiLayerBuffer();
+ HdiLayerBuffer &operator = (const BufferHandle &right);
+ uint64_t GetPhysicalAddr() const
+ {
+ return mPhyAddr;
+ }
+ int32_t GetHeight() const
+ {
+ return mHeight;
+ }
+ int32_t GetWight() const
+ {
+ return mWidth;
+ }
+ int32_t GetStride() const
+ {
+ return mStride;
+ }
+ int32_t GetFormat() const
+ {
+ return mFormat;
+ }
+ int GetFb() const
+ {
+ return mFd;
+ }
+ BufferHandle mHandle;
+
+private:
+ uint64_t mPhyAddr = 0;
+ int32_t mHeight = 0;
+ int32_t mWidth = 0;
+ int32_t mStride = 0;
+ int32_t mFormat = 0;
+ int mFd = -1;
+};
+
+class HdiLayer {
+public:
+ explicit HdiLayer(LayerType type) : mType(type) {}
+ int32_t Init();
+ uint32_t GetId() const
+ {
+ return mId;
+ }
+ uint32_t GetZorder() const
+ {
+ return mZorder;
+ }
+ const IRect &GetLayerDisplayRect() const
+ {
+ return mDisplayRect;
+ }
+ const IRect &GetLayerCrop() const
+ {
+ return mCrop;
+ }
+ bool GetLayerPreMulti() const
+ {
+ return mPreMul;
+ }
+ const LayerAlpha &GetAlpha() const
+ {
+ return mAlpha;
+ }
+ LayerType GetType() const
+ {
+ return mType;
+ }
+ TransformType GetTransFormType() const
+ {
+ return mTransformType;
+ }
+ BlendType GetLayerBlenType() const
+ {
+ return mBlendType;
+ }
+ CompositionType GetCompositionType() const
+ {
+ return mCompositionType;
+ }
+ void SetDeviceSelect(CompositionType type)
+ {
+ DISPLAY_DEBUGLOG("%{public}d", type);
+ mDeviceSelect = type;
+ }
+ CompositionType GetDeviceSelect() const
+ {
+ return mDeviceSelect;
+ }
+
+ int GetAcquireFenceFd()
+ {
+ return mAcquireFence.GetFd();
+ }
+ int GetReleaseFenceFd()
+ {
+ return mReleaseFence.GetFd();
+ }
+ void SetReleaseFence(int fd)
+ {
+ mReleaseFence = fd;
+ };
+ void ClearColor(uint32_t color);
+
+ void SetPixel(const BufferHandle &handle, int x, int y, uint32_t color);
+
+ virtual int32_t SetLayerSize(IRect *rect);
+ virtual int32_t SetLayerCrop(IRect *rect);
+ virtual void SetLayerZorder(uint32_t zorder);
+ virtual int32_t SetLayerPreMulti(bool preMul);
+ virtual int32_t SetLayerAlpha(LayerAlpha *alpha);
+ virtual int32_t SetTransformMode(TransformType type);
+ virtual int32_t SetLayerDirtyRegion(IRect *region);
+ virtual int32_t SetLayerVisibleRegion(uint32_t num, IRect *rect);
+ virtual int32_t SetLayerBuffer(const BufferHandle *buffer, int32_t fence);
+ virtual int32_t SetLayerCompositionType(CompositionType type);
+ virtual int32_t SetLayerBlendType(BlendType type);
+ virtual HdiLayerBuffer *GetCurrentBuffer()
+ {
+ return mHdiBuffer.get();
+ }
+ virtual ~HdiLayer() {}
+
+private:
+ static uint32_t GetIdleId();
+ static uint32_t mIdleId;
+ static std::unordered_set mIdSets;
+
+ uint32_t mId = 0;
+ HdiFd mAcquireFence;
+ HdiFd mReleaseFence;
+ LayerType mType;
+
+ IRect mDisplayRect;
+ IRect mCrop;
+ uint32_t mZorder = -1;
+ bool mPreMul = false;
+ LayerAlpha mAlpha;
+ TransformType mTransformType = ROTATE_BUTT;
+ CompositionType mCompositionType = COMPOSITION_CLIENT;
+ CompositionType mDeviceSelect = COMPOSITION_CLIENT;
+ BlendType mBlendType;
+ std::unique_ptr mHdiBuffer;
+};
+
+struct SortLayersByZ {
+ bool operator () (const HdiLayer *lhs, const HdiLayer *rhs) const
+ {
+ if (lhs == nullptr || rhs == nullptr) {
+ return (lhs == nullptr) && (rhs == nullptr);
+ }
+ return lhs->GetZorder() < rhs->GetZorder();
+ }
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_LAYER_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_netlink_monitor.cpp b/hardware/display/src/display_device/hdi_netlink_monitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..003275d3928543ba6ec6d2158e86fdea091b2bda
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_netlink_monitor.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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_netlink_monitor.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "display_common.h"
+#include "display_device.h"
+#include "display_layer.h"
+#include "hdi_session.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+HdiNetLinkMonitor::HdiNetLinkMonitor()
+{
+ DISPLAY_DEBUGLOG();
+}
+
+int HdiNetLinkMonitor::Init()
+{
+ DISPLAY_DEBUGLOG();
+ mThread = std::make_unique(std::bind(&HdiNetLinkMonitor::MonitorThread, this));
+ mThread->detach();
+ mRunning = true;
+ return DISPLAY_SUCCESS;
+}
+
+HdiNetLinkMonitor::~HdiNetLinkMonitor()
+{
+ DISPLAY_DEBUGLOG();
+ if (mScoketFd >= 0) {
+ close(mScoketFd);
+ }
+}
+
+static int ThreadInit()
+{
+ int ret;
+ int fd = -1;
+ const int32_t bufferSize = 1024;
+ struct sockaddr_nl snl;
+
+ bzero(&snl, sizeof(struct sockaddr_nl));
+ snl.nl_family = AF_NETLINK;
+ snl.nl_pid = getpid();
+ snl.nl_groups = 1;
+ fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+ DISPLAY_CHK_RETURN(fd < 0, DISPLAY_FAILURE, DISPLAY_LOGE("socket fail"));
+ ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
+ if (ret == -1) {
+ DISPLAY_LOGE("setsockopt fail");
+ close(fd);
+ return DISPLAY_FAILURE;
+ }
+ ret = bind(fd, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
+ if (ret < 0) {
+ DISPLAY_LOGE("bind fail");
+ close(fd);
+ return DISPLAY_FAILURE;
+ }
+ return fd;
+}
+
+static void ParseUeventMessage(const char *buf, uint32_t len)
+{
+ uint32_t num;
+
+ for (num = 0; num < len;) {
+ const char *event = buf + num;
+ if (strcmp(event, "STATE=HDMI=0") == 0) {
+ HdiSession::GetInstance().HandleHotplug(false);
+ break;
+ } else if (strcmp(event, "STATE=HDMI=1") == 0) {
+ HdiSession::GetInstance().HandleHotplug(true);
+ break;
+ }
+ num += strlen(event) + 1;
+ }
+}
+
+void HdiNetLinkMonitor::MonitorThread()
+{
+ constexpr int BUFFER_SIZE = 2048; /* buffer for the variables */
+ int len;
+ int fd = -1;
+
+ fd = ThreadInit();
+ DISPLAY_CHK_RETURN_NOT_VALUE(fd < 0, DISPLAY_LOGE("socket fail"));
+ mScoketFd = fd;
+ while (mRunning) {
+ char buf[BUFFER_SIZE] = { 0 };
+ len = read(fd, &buf, sizeof(buf));
+ if (len < 0) {
+ DISPLAY_LOGE("read uevent message fail");
+ break;
+ }
+ ParseUeventMessage(buf, len);
+ }
+}
+} // DISPLAY
+} // HDI
+} // OHOS
diff --git a/hardware/display/src/display_device/hdi_netlink_monitor.h b/hardware/display/src/display_device/hdi_netlink_monitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..12b83182b9c9f90b31e7a41b8ef5faec6042928c
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_netlink_monitor.h
@@ -0,0 +1,39 @@
+/*
+ * 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 HDI_NETLINK_NONITOR_H
+#define HDI_NETLINK_NONITOR_H
+#include
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class HdiNetLinkMonitor {
+public:
+ HdiNetLinkMonitor();
+ int Init();
+ virtual ~HdiNetLinkMonitor();
+
+private:
+ void MonitorThread();
+ volatile bool mRunning = false;
+ int mScoketFd = -1;
+ std::unique_ptr mThread;
+};
+} // namespace OHOS
+} // namespace HDI
+} // namespace DISPLAY
+
+#endif // HDI_NETLINK_NONITOR_H
\ No newline at end of file
diff --git a/hardware/display/src/display_device/hdi_session.cpp b/hardware/display/src/display_device/hdi_session.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..352d27c7f31ddf3b3b7ac32352826df4e638448f
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_session.cpp
@@ -0,0 +1,415 @@
+/*
+ * 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
+#include
+#include
+#include "display_common.h"
+#include "display_device.h"
+#include "display_layer.h"
+#include "hdi_netlink_monitor.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+HdiSession &HdiSession::GetInstance()
+{
+ static HdiSession instance;
+ static std::once_flag once;
+ std::call_once(once, [&]() { instance.Init(); });
+ return instance;
+}
+
+void HdiSession::Init()
+{
+ DISPLAY_DEBUGLOG();
+ mHdiDevices = HdiDeviceInterface::DiscoveryDevice();
+ DISPLAY_DEBUGLOG("devices size %{public}zd", mHdiDevices.size());
+ mHdiDisplays.clear();
+ for (auto device : mHdiDevices) {
+ auto displays = device->DiscoveryDisplay();
+ /* Register the connectors instead of display device.
+ * There are several connectors in one display device
+ * in rockchip platform.
+ */
+ for (auto display : displays) {
+ mHdiDisplays[display.first] = display.second;
+ }
+ }
+ std::shared_ptr mNetLinkMonitor = std::make_shared();
+ mNetLinkMonitor->Init();
+}
+
+void HdiSession::HandleHotplug(bool plugIn)
+{
+ for (auto device : mHdiDevices) {
+ for (auto displayMap : mHdiDisplays) {
+ auto display = displayMap.second;
+ auto isSuccess = device->HandleHotplug(display->GetId(), plugIn);
+ if (isSuccess == true) {
+ DoHotPlugCallback(display->GetId(), plugIn);
+ }
+ }
+ }
+}
+
+int32_t HdiSession::RegHotPlugCallback(HotPlugCallback callback, void *data)
+{
+ DISPLAY_CHK_RETURN((callback == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the callback is nullptr"));
+ mHotPlugCallBacks.emplace(callback, data);
+ for (auto displayMap : mHdiDisplays) {
+ auto display = displayMap.second;
+ if (display->IsConnected()) {
+ DoHotPlugCallback(display->GetId(), true);
+ }
+ }
+ return DISPLAY_SUCCESS;
+}
+
+void HdiSession::DoHotPlugCallback(uint32_t devId, bool connect)
+{
+ DISPLAY_DEBUGLOG();
+ for (const auto &callback : mHotPlugCallBacks) {
+ callback.first(devId, connect, callback.second);
+ }
+}
+} // OHOS
+} // HDI
+} // DISPLAY
+
+using namespace OHOS::HDI::DISPLAY;
+static int32_t RegHotPlugCallback(HotPlugCallback callback, void *data)
+{
+ DISPLAY_DEBUGLOG();
+ HdiSession::GetInstance().RegHotPlugCallback(callback, data);
+ return DISPLAY_SUCCESS;
+}
+
+static int32_t GetDisplayCapability(uint32_t devId, DisplayCapability *info)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN(info == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("info is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCapability, info);
+}
+
+static int32_t GetDisplaySupportedModes(uint32_t devId, uint32_t *num, DisplayModeInfo *modes)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN(num == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplaySupportedModes, num, modes);
+}
+
+static int32_t GetDisplayMode(uint32_t devId, uint32_t *mode)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((mode == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("mode is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayMode, mode);
+}
+
+static int32_t SetDisplayMode(uint32_t devId, uint32_t mode)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayMode, mode);
+}
+
+static int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus *status)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((status == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("status is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayPowerStatus, status);
+}
+
+static int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayPowerStatus, status);
+}
+
+static int32_t GetDisplayBacklight(uint32_t devId, uint32_t *value)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayBacklight, value);
+}
+
+static int32_t SetDisplayBacklight(uint32_t devId, uint32_t value)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayBacklight, value);
+}
+
+static int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t *value)
+{
+ DISPLAY_DEBUGLOG();
+ (void)id;
+ DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
+ return DISPLAY_NOT_SUPPORT;
+}
+
+static int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value)
+{
+ DISPLAY_DEBUGLOG();
+ (void)id;
+ return DISPLAY_NOT_SUPPORT;
+}
+
+static int32_t PrepareDisplayLayers(uint32_t devId, bool *needFlushFb)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((needFlushFb == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("needFlushFb is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::PrepareDisplayLayers, needFlushFb);
+}
+
+static int32_t GetDisplayCompChange(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *type)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCompChange, num, layers, type);
+}
+
+static int32_t SetDisplayClientCrop(uint32_t devId, IRect *rect)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ return DISPLAY_NOT_SUPPORT;
+}
+
+static int32_t SetDisplayClientDestRect(uint32_t devId, IRect *rect)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ return DISPLAY_NOT_SUPPORT;
+}
+
+static int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle *buffer, int32_t fence)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayClientBuffer, buffer, fence);
+}
+
+static int32_t SetDisplayClientDamage(uint32_t devId, uint32_t num, IRect *rect)
+{
+ DISPLAY_DEBUGLOG();
+ (void)num;
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ return DISPLAY_NOT_SUPPORT;
+}
+
+static int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayVsyncEnabled, enabled);
+}
+
+static int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback callback, void *data)
+{
+ DISPLAY_DEBUGLOG();
+ 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)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayReleaseFence, num, layers,
+ fences);
+}
+
+static int32_t Commit(uint32_t devId, int32_t *fence)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((fence == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("fence is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::Commit, fence);
+}
+
+static int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format, uint32_t *devId)
+{
+ DISPLAY_DEBUGLOG();
+ return DISPLAY_NOT_SUPPORT;
+}
+static int32_t DestroyVirtualDisplay(uint32_t devId)
+{
+ DISPLAY_DEBUGLOG();
+ return DISPLAY_NOT_SUPPORT;
+}
+static int32_t SetVirtualDisplayBuffer(uint32_t devId, BufferHandle *buffer, int32_t releaseFence)
+{
+ DISPLAY_DEBUGLOG();
+ return DISPLAY_NOT_SUPPORT;
+}
+
+
+// Layer function
+static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((layerId == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("layerId is nullptr"));
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CreateLayer, layerInfo, layerId);
+}
+
+static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CloseLayer, layerId);
+}
+
+static int32_t SetLayerSize(uint32_t devId, uint32_t layerId, IRect *rect)
+{
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerSize, rect);
+}
+
+static int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, IRect *rect)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCrop, rect);
+}
+
+static int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetLayerZorder, layerId, zorder);
+}
+
+static int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerPreMulti, preMul);
+}
+
+static int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, LayerAlpha *alpha)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((alpha == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("alpha is nullptr"));
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerAlpha, alpha);
+}
+
+static int32_t SetTransformMode(uint32_t devId, uint32_t layerId, TransformType type)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTransformMode, type);
+}
+
+static int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, IRect *region)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((region == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("region is nullptr"));
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerDirtyRegion, region);
+}
+
+static int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, uint32_t num, IRect *rect)
+{
+ DISPLAY_DEBUGLOG();
+ DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerVisibleRegion, num, rect);
+}
+
+static int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle *buffer, int32_t fence)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBuffer, buffer, fence);
+}
+
+static int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCompositionType, type);
+}
+
+static int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type)
+{
+ DISPLAY_DEBUGLOG();
+ return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBlendType, type);
+}
+
+
+extern "C" {
+int32_t DeviceInitialize(DeviceFuncs **funcs)
+{
+ DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
+ DeviceFuncs *dFuncs = (DeviceFuncs *)calloc(1, sizeof(DeviceFuncs));
+ DISPLAY_CHK_RETURN((dFuncs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not calloc"));
+
+ dFuncs->RegHotPlugCallback = RegHotPlugCallback;
+ dFuncs->GetDisplayCapability = GetDisplayCapability;
+ dFuncs->GetDisplaySupportedModes = GetDisplaySupportedModes;
+ dFuncs->GetDisplayMode = GetDisplayMode;
+ dFuncs->SetDisplayMode = SetDisplayMode;
+ dFuncs->GetDisplayPowerStatus = GetDisplayPowerStatus;
+ dFuncs->SetDisplayPowerStatus = SetDisplayPowerStatus;
+ dFuncs->PrepareDisplayLayers = PrepareDisplayLayers;
+ dFuncs->GetDisplayBacklight = GetDisplayBacklight;
+ dFuncs->SetDisplayBacklight = SetDisplayBacklight;
+ dFuncs->GetDisplayProperty = GetDisplayProperty;
+ dFuncs->GetDisplayCompChange = GetDisplayCompChange;
+ dFuncs->SetDisplayClientCrop = SetDisplayClientCrop;
+ dFuncs->SetDisplayClientDestRect = SetDisplayClientDestRect;
+ dFuncs->SetDisplayClientBuffer = SetDisplayClientBuffer;
+ dFuncs->SetDisplayClientDamage = SetDisplayClientDamage;
+ dFuncs->SetDisplayVsyncEnabled = SetDisplayVsyncEnabled;
+ dFuncs->RegDisplayVBlankCallback = RegDisplayVBlankCallback;
+ dFuncs->GetDisplayReleaseFence = GetDisplayReleaseFence;
+ dFuncs->CreateVirtualDisplay = CreateVirtualDisplay;
+ dFuncs->DestroyVirtualDisplay = DestroyVirtualDisplay;
+ dFuncs->SetVirtualDisplayBuffer = SetVirtualDisplayBuffer;
+ dFuncs->SetDisplayProperty = SetDisplayProperty;
+ dFuncs->Commit = Commit;
+ *funcs = dFuncs;
+ DISPLAY_DEBUGLOG("%{public}s: device initialize success", __func__);
+ HdiSession::GetInstance();
+ return DISPLAY_SUCCESS;
+}
+
+int32_t DeviceUninitialize(DeviceFuncs *funcs)
+{
+ DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
+ free(funcs);
+ return DISPLAY_SUCCESS;
+}
+
+
+int32_t LayerInitialize(LayerFuncs **funcs)
+{
+ DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the in funcs is nullptr"));
+ LayerFuncs *lFuncs = (LayerFuncs *)calloc(1, sizeof(LayerFuncs));
+ DISPLAY_CHK_RETURN((lFuncs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not calloc errno: %{public}d", errno));
+ lFuncs->SetLayerAlpha = SetLayerAlpha;
+ lFuncs->CreateLayer = CreateLayer;
+ lFuncs->CloseLayer = CloseLayer;
+ lFuncs->SetLayerSize = SetLayerSize;
+ lFuncs->SetLayerCrop = SetLayerCrop;
+ lFuncs->SetLayerZorder = SetLayerZorder;
+ lFuncs->SetLayerPreMulti = SetLayerPreMulti;
+ lFuncs->SetTransformMode = SetTransformMode;
+ lFuncs->SetLayerDirtyRegion = SetLayerDirtyRegion;
+ lFuncs->SetLayerVisibleRegion = SetLayerVisibleRegion;
+ lFuncs->SetLayerBuffer = SetLayerBuffer;
+ lFuncs->SetLayerCompositionType = SetLayerCompositionType;
+ lFuncs->SetLayerBlendType = SetLayerBlendType;
+
+ *funcs = lFuncs;
+ DISPLAY_DEBUGLOG("%{public}s: layer initialize success", __func__);
+ return DISPLAY_SUCCESS;
+}
+
+int32_t LayerUninitialize(LayerFuncs *funcs)
+{
+ DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the funcs is nullptr"));
+ free(funcs);
+ DISPLAY_DEBUGLOG("%{public}s: layer uninitialize success", __func__);
+ return DISPLAY_SUCCESS;
+}
+}
diff --git a/hardware/display/src/display_device/hdi_session.h b/hardware/display/src/display_device/hdi_session.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb040db883243d5796ca99f07d084c51ab56cdd2
--- /dev/null
+++ b/hardware/display/src/display_device/hdi_session.h
@@ -0,0 +1,73 @@
+/*
+ * 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 HDI_SESSION_H
+#define HDI_SESSION_H
+#include
+#include
+#include
+#include "display_device.h"
+#include "hdi_device_interface.h"
+#include "hdi_display.h"
+
+namespace OHOS {
+namespace HDI {
+namespace DISPLAY {
+class HdiSession {
+public:
+ void Init();
+ static HdiSession &GetInstance();
+
+ template
+ int32_t CallDisplayFunction(uint32_t devId, int32_t (HdiDisplay::*member)(Args...), Args... args)
+ {
+ DISPLAY_DEBUGLOG("device Id : %{public}d", devId);
+ DISPLAY_CHK_RETURN((devId == INVALIDE_DISPLAY_ID), DISPLAY_FAILURE, DISPLAY_LOGE("invalide device id"));
+ auto iter = mHdiDisplays.find(devId);
+ DISPLAY_CHK_RETURN((iter == mHdiDisplays.end()), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not find display %{public}d", devId));
+ auto display = iter->second.get();
+ return (display->*member)(std::forward(args)...);
+ }
+
+ template
+ int32_t CallLayerFunction(uint32_t devId, uint32_t layerId, int32_t (HdiLayer::*member)(Args...), Args... args)
+ {
+ DISPLAY_DEBUGLOG("device Id : %{public}d", devId);
+ DISPLAY_CHK_RETURN((devId == INVALIDE_DISPLAY_ID), DISPLAY_FAILURE, DISPLAY_LOGE("invalide device id"));
+ auto iter = mHdiDisplays.find(devId);
+ DISPLAY_CHK_RETURN((iter == mHdiDisplays.end()), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not find display %{public}d", devId));
+ auto display = iter->second.get();
+ auto layer = display->GetHdiLayer(layerId);
+ DISPLAY_CHK_RETURN((layer == nullptr), DISPLAY_FAILURE,
+ DISPLAY_LOGE("can not find the layer %{public}d", layerId));
+ return (layer->*member)(std::forward(args)...);
+ }
+
+ int32_t RegHotPlugCallback(HotPlugCallback callback, void *data);
+ void DoHotPlugCallback(uint32_t devId, bool connect);
+ void HandleHotplug(bool plugIn);
+
+private:
+ std::unordered_map> mHdiDisplays;
+ std::vector