mirror of
https://github.com/openharmony/device_rockchip.git
synced 2026-06-30 21:27:58 -04:00
add display source
Signed-off-by: yanghongliang <yang_hongliang@hoperun.com>
This commit is contained in:
+1
-1
@@ -20,6 +20,6 @@ group("products_group") {
|
||||
}
|
||||
|
||||
deps += [
|
||||
"//device/rockchip/common:common_group",
|
||||
"//device/rockchip/hardware:hardware_group",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
print("common_group in")
|
||||
group("common_group") {
|
||||
group("hardware_group") {
|
||||
deps = [
|
||||
"//device/rockchip/hardware/wifi:ap6xxx",
|
||||
"//device/rockchip/hardware/isp:isp",
|
||||
Executable → Regular
+131
-43
@@ -12,62 +12,150 @@
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//build/ohos/ndk/ndk.gni")
|
||||
|
||||
ohos_prebuilt_shared_library("display_gralloc") {
|
||||
if (target_cpu == "arm") {
|
||||
source = "lib/libdisplay_gralloc.z.so"
|
||||
} else if (target_cpu == "arm64") {
|
||||
source = "lib64/libdisplay_gralloc.z.so"
|
||||
}
|
||||
subsystem_name = "hdf"
|
||||
part_name = "hdf"
|
||||
install_enable = true
|
||||
# output_name = "display_gralloc.z"
|
||||
group("display_group") {
|
||||
deps = [
|
||||
":display_device",
|
||||
":display_gralloc",
|
||||
":display_gfx",
|
||||
":higbm",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_prebuilt_shared_library("display_gfx") {
|
||||
if (target_cpu == "arm") {
|
||||
source = "lib/libdisplay_gfx.z.so"
|
||||
} else if (target_cpu == "arm64") {
|
||||
source = "lib64/libdisplay_gfx.z.so"
|
||||
}
|
||||
subsystem_name = "hdf"
|
||||
part_name = "hdf"
|
||||
install_enable = true
|
||||
# output_name = "display_gfx.z"
|
||||
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_prebuilt_shared_library("display_device_drm") {
|
||||
if (target_cpu == "arm") {
|
||||
source = "lib/libdisplay_device_drm.z.so"
|
||||
} else if (target_cpu == "arm64") {
|
||||
source = "lib64/libdisplay_device_drm.z.so"
|
||||
}
|
||||
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
|
||||
subsystem_name = "hdf"
|
||||
part_name = "hdf"
|
||||
install_enable = true
|
||||
# output_name = "display_device_drm.z"
|
||||
}
|
||||
|
||||
ohos_prebuilt_shared_library("display_device") {
|
||||
if (target_cpu == "arm") {
|
||||
source = "lib/libdisplay_device.z.so"
|
||||
} else if (target_cpu == "arm64") {
|
||||
source = "lib64/libdisplay_device.z.so"
|
||||
}
|
||||
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/rockchip/hardware/rga/include/",
|
||||
"//base/hiviewdfx/interfaces/innerkits/libhilog/include",
|
||||
]
|
||||
output_name = "display_gfx"
|
||||
cflags = [ "-Wno-macro-redefined" ]
|
||||
deps = [
|
||||
":display_gralloc",
|
||||
"//utils/native/base:utils",
|
||||
"//device/rockchip/hardware/rga:librga",
|
||||
]
|
||||
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
|
||||
install_enable = true
|
||||
subsystem_name = "hdf"
|
||||
part_name = "hdf"
|
||||
install_enable = true
|
||||
# output_name = "display_device_drm.z"
|
||||
}
|
||||
|
||||
ohos_prebuilt_shared_library("display_layer") {
|
||||
if (target_cpu == "arm") {
|
||||
source = "lib/libdisplay_layer.z.so"
|
||||
}
|
||||
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_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
|
||||
subsystem_name = "hdf"
|
||||
part_name = "hdf"
|
||||
install_enable = true
|
||||
# output_name = "display_device_drm.z"
|
||||
}
|
||||
|
||||
group("display_layer") {
|
||||
deps = [
|
||||
":display_device",
|
||||
":display_gralloc",
|
||||
":display_gfx",
|
||||
":higbm",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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 <string.h>
|
||||
#include <stdint.h>
|
||||
#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_LOGD
|
||||
#define DISPLAY_LOGD(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 */
|
||||
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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 <cinttypes>
|
||||
#include <securec.h>
|
||||
#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_LOGD("encoder_id %{public}d", mEncoderId);
|
||||
DISPLAY_LOGD("the connect state is %{public}d", mConnectState);
|
||||
|
||||
for (int i = 0; i < c.count_encoders; i++) {
|
||||
mPossibleEncoders.push_back(c.encoders[i]);
|
||||
DISPLAY_LOGD("add possible encoder id %{public}d", c.encoders[i]);
|
||||
}
|
||||
|
||||
ConvertToHdiType(c.connector_type, mType);
|
||||
ConvertTypeToName(mType, mName);
|
||||
InitModes(c);
|
||||
DISPLAY_LOGD("name %{public}s", mName.c_str());
|
||||
}
|
||||
|
||||
void DrmConnector::InitModes(drmModeConnector c)
|
||||
{
|
||||
DISPLAY_LOGD("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_LOGD("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_LOGD("set it to prefernce id %{public}d", i);
|
||||
mPreferenceId = i;
|
||||
}
|
||||
mModes.emplace(i, DrmMode { *mode, i });
|
||||
}
|
||||
DISPLAY_LOGD("mode count %{public}zd", mModes.size());
|
||||
}
|
||||
|
||||
int32_t DrmConnector::Init(DrmDevice &drmDevice)
|
||||
{
|
||||
int32_t ret;
|
||||
DrmProperty prop;
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD("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_LOGD("encoder_id %{public}d", mEncoderId);
|
||||
DISPLAY_LOGD("mPropCrtcId %{public}d", mPropCrtcId);
|
||||
// find the brightness
|
||||
ret = drmDevice.GetConnectorProperty(*this, PROP_BRIGHTNESS, prop);
|
||||
if (ret == DISPLAY_SUCCESS) {
|
||||
mPropBrightnessId = prop.propId;
|
||||
mBrightnessLevel = static_cast<uint32_t>(prop.value);
|
||||
DISPLAY_LOGD("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;
|
||||
}
|
||||
|
||||
int32_t DrmConnector::SetBrightness(uint32_t level)
|
||||
{
|
||||
DISPLAY_LOGD("set %{public}d", level);
|
||||
if (mPropBrightnessId == DRM_INVALID_ID) {
|
||||
DISPLAY_LOGE("the prop id of brightness is invalid");
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
int ret = drmModeConnectorSetProperty(mDrmFdPtr->GetFd(), mId, mPropBrightnessId, level);
|
||||
DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("can not set dpms"));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void DrmConnector::ConvertTypeToName(uint32_t type, std::string &name)
|
||||
{
|
||||
DISPLAY_LOGD("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<DrmEncoder> &encoders, uint32_t encoderId, IdMapPtr<DrmCrtc> &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_LOGD("connector : %{public}d encoder : %{public}d", mId, encoder->GetId());
|
||||
ret = encoder->PickIdleCrtcId(crtcs, crtcId);
|
||||
DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS,
|
||||
DISPLAY_LOGD("connector : %{public}d pick encoder : %{public}d", mId, encoder->GetId()));
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
|
||||
int32_t DrmConnector::PickIdleCrtcId(IdMapPtr<DrmEncoder> &encoders, IdMapPtr<DrmCrtc> &crtcs, uint32_t &crtcId)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_LOGD("encoder_id %{public}d", mEncoderId);
|
||||
int ret = TryPickEncoder(encoders, mEncoderId, crtcs, crtcId);
|
||||
DISPLAY_CHK_RETURN((ret == DISPLAY_SUCCESS), DISPLAY_SUCCESS,
|
||||
DISPLAY_LOGD("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_LOGD("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;
|
||||
}
|
||||
|
||||
int32_t DrmConnector::GetDisplaySuppportedModes(int *num, DisplayModeInfo *modes)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
|
||||
*num = static_cast<int32_t>(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_LOGD("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_LOGD();
|
||||
auto iter = mModes.find(id);
|
||||
if (iter == mModes.end()) {
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
mode = mModes[id];
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
std::unique_ptr<DrmModeBlock> DrmConnector::GetModeBlockFromId(int32_t id)
|
||||
{
|
||||
DISPLAY_LOGD("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<DrmModeBlock>(mModes[id]);
|
||||
}
|
||||
|
||||
DrmModeBlock::DrmModeBlock(DrmMode &mode)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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<void *>(&modeInfo), sizeof(modeInfo), &mBlockId);
|
||||
DISPLAY_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_LOGE("create property blob failed"));
|
||||
DISPLAY_LOGD("mBlockId %{public}d", mBlockId);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
DrmModeBlock::~DrmModeBlock()
|
||||
{
|
||||
DISPLAY_LOGD("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
|
||||
@@ -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 DRM_CONNECTOR_H
|
||||
#define DRM_CONNECTOR_H
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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<DrmEncoder> &encoders, IdMapPtr<DrmCrtc> &crtcs, uint32_t &crtcId);
|
||||
int32_t GetDisplaySuppportedModes(int *num, DisplayModeInfo *modes);
|
||||
int32_t GetPreferenceId() const
|
||||
{
|
||||
return mPreferenceId;
|
||||
}
|
||||
uint32_t GetPropCrtcId() const
|
||||
{
|
||||
return mPropCrtcId;
|
||||
}
|
||||
int32_t TryPickEncoder(IdMapPtr<DrmEncoder> &encoders, uint32_t encoderId, IdMapPtr<DrmCrtc> &crtcs,
|
||||
uint32_t &crtcId);
|
||||
// update modes will reset the preference mode id and active mode id
|
||||
int32_t UpdateModes();
|
||||
std::unique_ptr<DrmModeBlock> 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();
|
||||
|
||||
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 mEncoderId;
|
||||
std::vector<uint32_t> 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<int32_t, DrmMode> mModes;
|
||||
int32_t mPreferenceId = INVALID_MODE_ID;
|
||||
|
||||
FdPtr mDrmFdPtr;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
#endif // DRM_CONNECTOR_H
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 {
|
||||
DrmCrtc::DrmCrtc(drmModeCrtcPtr c, uint32_t pipe) : mId(c->crtc_id), mPipe(pipe) {}
|
||||
|
||||
int32_t DrmCrtc::Init(DrmDevice &drmDevice)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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;
|
||||
|
||||
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_LOGD();
|
||||
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_LOGD("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
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <memory>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // DRM_CRTC_H
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#include <drm_fourcc.h>
|
||||
#include "display_common.h"
|
||||
#include "drm_display.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
FdPtr DrmDevice::mDrmFd = nullptr;
|
||||
std::shared_ptr<DrmDevice> DrmDevice::mInstance;
|
||||
|
||||
std::shared_ptr<HdiDeviceInterface> DrmDevice::Create()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
if (mDrmFd == nullptr) {
|
||||
const std::string name("rockchip");
|
||||
int drmFd = 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_LOGD("the drm fd is %{public}d", drmFd);
|
||||
mDrmFd = std::make_shared<HdiFd>(drmFd);
|
||||
}
|
||||
if (mInstance == nullptr) {
|
||||
mInstance = std::make_shared<DrmDevice>();
|
||||
}
|
||||
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_LOGD("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(const 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];
|
||||
}
|
||||
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> drmCrtc = std::make_shared<DrmCrtc>(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> drmEncoder = std::make_shared<DrmEncoder>(*encoder);
|
||||
mEncoders.emplace(encoder->encoder_id, std::move(drmEncoder));
|
||||
drmModeFreeEncoder(encoder);
|
||||
}
|
||||
DISPLAY_LOGD("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> drmConnector = std::make_shared<DrmConnector>(*connector, mDrmFd);
|
||||
ret = drmConnector->Init(*this);
|
||||
drmModeFreeConnector(connector);
|
||||
if (ret != DISPLAY_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
int connectorId = drmConnector->GetId();
|
||||
mConnectors.emplace(connectorId, std::move(drmConnector));
|
||||
}
|
||||
DISPLAY_LOGD("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_LOGD("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> drmPlane = std::make_shared<DrmPlane>(*p);
|
||||
DISPLAY_LOGD();
|
||||
ret = drmPlane->Init(*this);
|
||||
DISPLAY_LOGD();
|
||||
drmModeFreePlane(p);
|
||||
if (ret != DISPLAY_SUCCESS) {
|
||||
DISPLAY_LOGE("drm plane %{public}d init failed", i);
|
||||
continue;
|
||||
}
|
||||
mPlanes.emplace_back(std::move(drmPlane));
|
||||
}
|
||||
DISPLAY_LOGD("find plane count %{public}zd", mPlanes.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<DrmEncoder> DrmDevice::GetDrmEncoderFromId(uint32_t id)
|
||||
{
|
||||
/*int32_t ret = DISPLAY_FAILURE;
|
||||
auto iter = mEncoders.find(id);
|
||||
if (iter == mEncoders.end()) {
|
||||
ret = DISPLAY_SUCCESS;
|
||||
}*/
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<DrmConnector> DrmDevice::GetDrmConnectorFromId(uint32_t id)
|
||||
{
|
||||
/*int32_t ret = DISPLAY_FAILURE;
|
||||
auto iter = mConnectors.find(id);
|
||||
if (iter == mConnectors.end()) {
|
||||
ret = DISPLAY_SUCCESS;
|
||||
}*/
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<DrmCrtc> DrmDevice::GetDrmCrtcFromId(uint32_t id)
|
||||
{
|
||||
/*int32_t ret = DISPLAY_FAILURE;
|
||||
auto iter = mCrtcs.find(id);
|
||||
if (iter == mCrtcs.end()) {
|
||||
ret = DISPLAY_SUCCESS;
|
||||
}*/
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<DrmPlane>> DrmDevice::GetDrmPlane(uint32_t pipe, uint32_t type)
|
||||
{
|
||||
std::vector<std::shared_ptr<DrmPlane>> planes;
|
||||
for (const auto &plane : mPlanes) {
|
||||
if (plane->IsIdle() && ((1 << pipe) & plane->GetPossibleCrtcs()) && (type == plane->GetType())) {
|
||||
plane->BindToPipe(pipe);
|
||||
planes.push_back(plane);
|
||||
}
|
||||
}
|
||||
DISPLAY_LOGD("the planes count %{public}zd", planes.size());
|
||||
return planes;
|
||||
}
|
||||
|
||||
|
||||
std::unordered_map<uint32_t, std::shared_ptr<HdiDisplay>> DrmDevice::DiscoveryDisplay()
|
||||
{
|
||||
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_LOGD();
|
||||
// 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_LOGD();
|
||||
|
||||
auto crtcIter = mCrtcs.find(crtcId);
|
||||
if (crtcIter == mCrtcs.end()) {
|
||||
DISPLAY_LOGE("can not find crtc for the id %{public}d", connector->GetId());
|
||||
continue;
|
||||
}
|
||||
DISPLAY_LOGD();
|
||||
auto crtc = crtcIter->second;
|
||||
DISPLAY_LOGD("crtc %{public}p", crtc.get());
|
||||
// create the display
|
||||
std::shared_ptr<HdiDisplay> display = std::make_shared<DrmDisplay>(connector, crtc, mInstance);
|
||||
DISPLAY_LOGD();
|
||||
display->Init();
|
||||
mDisplays.emplace(display->GetId(), std::move(display));
|
||||
}
|
||||
DISPLAY_LOGD("find display size %{public}zd", mDisplays.size());
|
||||
return mDisplays;
|
||||
}
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 <unordered_map>
|
||||
#include <memory>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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 {
|
||||
struct DrmProperty {
|
||||
uint32_t propId;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
class DrmDevice : public HdiDeviceInterface, std::enable_shared_from_this<DrmDevice> {
|
||||
public:
|
||||
static std::shared_ptr<HdiDeviceInterface> Create();
|
||||
static uint32_t ConvertToDrmFormat(PixelFormat fmtIn);
|
||||
static int GetDrmFd();
|
||||
DrmDevice();
|
||||
virtual ~DrmDevice() {}
|
||||
|
||||
std::vector<std::shared_ptr<DrmPlane>> 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<DrmEncoder> GetDrmEncoderFromId(uint32_t id);
|
||||
std::shared_ptr<DrmConnector> GetDrmConnectorFromId(uint32_t id);
|
||||
std::shared_ptr<DrmCrtc> GetDrmCrtcFromId(uint32_t id);
|
||||
void CreateCrtc(drmModeCrtcPtr c);
|
||||
virtual std::unordered_map<uint32_t, std::shared_ptr<HdiDisplay>> DiscoveryDisplay();
|
||||
virtual int32_t Init();
|
||||
virtual void DeInit();
|
||||
|
||||
private:
|
||||
static FdPtr mDrmFd;
|
||||
static std::shared_ptr<DrmDevice> mInstance;
|
||||
void FindAllCrtc(const drmModeResPtr &drmRes);
|
||||
void FindAllEncoder(const drmModeResPtr &drmRes);
|
||||
void FindAllConnector(const drmModeResPtr &drmRes);
|
||||
void FindAllPlane();
|
||||
int InitNetLink();
|
||||
IdMapPtr<HdiDisplay> mDisplays;
|
||||
IdMapPtr<DrmCrtc> mCrtcs;
|
||||
IdMapPtr<DrmEncoder> mEncoders;
|
||||
IdMapPtr<DrmConnector> mConnectors;
|
||||
std::vector<std::shared_ptr<DrmPlane>> mPlanes;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // DRM_DEVICE_H
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <errno.h>
|
||||
#include <memory>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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<DrmConnector> connector, std::shared_ptr<DrmCrtc> crtc,
|
||||
std::shared_ptr<DrmDevice> 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<HdiGfxComposition>();
|
||||
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<HdiDrmComposition>(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<HdiComposer>(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::GetDisplaySuppportedModes(int *num, DisplayModeInfo *modes)
|
||||
{
|
||||
mConnector->GetDisplaySuppportedModes(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)
|
||||
{
|
||||
DISPLAY_LOGD("the status %{public}d ", status);
|
||||
uint32_t drmPowerState = 0;
|
||||
int ret = ConvertToDrmPowerState(status, drmPowerState);
|
||||
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_PARAM_ERR,
|
||||
DISPLAY_LOGE("unknown power status %{public}d", status));
|
||||
mConnector->SetDpmsState(drmPowerState);
|
||||
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_LOGD("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<HdiLayer> DrmDisplay::CreateHdiLayer(LayerType type)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return std::make_unique<HdiDrmLayer>(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<uint64_t>(vbl.reply.tval_sec * nPerS + vbl.reply.tval_usec * nPerUS);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
bool DrmDisplay::IsConnected()
|
||||
{
|
||||
DISPLAY_LOGD("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<HdiLayer *> layers;
|
||||
HdiDrmComposition *drmComp = static_cast<HdiDrmComposition *>(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) {
|
||||
int32_t num = 0;
|
||||
ret = GetDisplaySuppportedModes(&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_LOGD("the VBlankCallback %{public}p ", cb);
|
||||
(void)data;
|
||||
std::shared_ptr<VsyncCallBack> vsyncCb = std::make_shared<VsyncCallBack>(cb, nullptr);
|
||||
DrmVsyncWorker::GetInstance().ReqesterVBlankCb(vsyncCb);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t DrmDisplay::SetDisplayVsyncEnabled(bool enabled)
|
||||
{
|
||||
DISPLAY_LOGD("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
|
||||
@@ -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 <unordered_map>
|
||||
#include <memory>
|
||||
#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<DrmConnector> connector, std::shared_ptr<DrmCrtc> crtc,
|
||||
std::shared_ptr<DrmDevice> drmDevice);
|
||||
|
||||
virtual ~DrmDisplay();
|
||||
|
||||
int32_t Init() override;
|
||||
int32_t GetDisplayCapability(DisplayCapability *info) override;
|
||||
int32_t GetDisplaySuppportedModes(int *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();
|
||||
virtual int32_t RegDisplayVBlankCallback(VBlankCallback cb, void *data) override;
|
||||
virtual int32_t WaitForVBlank(uint64_t *ns) override;
|
||||
virtual bool IsConnected() override;
|
||||
virtual int32_t SetDisplayVsyncEnabled(bool enabled) override;
|
||||
HdiDrmComposition *GetDrmComposition();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<HdiLayer> 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<DrmDevice> mDrmDevice;
|
||||
std::shared_ptr<DrmConnector> mConnector;
|
||||
std::shared_ptr<DrmCrtc> mCrtc;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_DISPLAY_H
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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<DrmCrtc> &crtcs, uint32_t &crtcId)
|
||||
{
|
||||
// find the crtc id;
|
||||
DISPLAY_LOGD("crtcs szie %{public}zu", crtcs.size());
|
||||
std::shared_ptr<DrmCrtc> crtc;
|
||||
auto crtcIter = crtcs.find(mCrtcId);
|
||||
if (crtcIter == crtcs.end()) {
|
||||
DISPLAY_LOGW("can not find crtc for id %{public}d", mCrtcId);
|
||||
crtcIter = crtcs.begin();
|
||||
}
|
||||
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_LOGD("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
|
||||
@@ -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 <string>
|
||||
#include <memory>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <display_type.h>
|
||||
#include <drm_crtc.h>
|
||||
|
||||
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<DrmCrtc> &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
|
||||
@@ -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_plane.h"
|
||||
#include "drm_device.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
DrmPlane::DrmPlane(drmModePlane &p)
|
||||
: mId(p.plane_id), mPossibleCrtcs(p.possible_crtcs), mFormats(p.formats, p.formats + p.count_formats)
|
||||
{}
|
||||
|
||||
DrmPlane::~DrmPlane()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
}
|
||||
|
||||
int32_t DrmPlane::Init(DrmDevice &drmDevice)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
int32_t ret;
|
||||
DrmProperty prop;
|
||||
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_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<uint32_t>(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
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 <cinttypes>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
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";
|
||||
class DrmDevice;
|
||||
|
||||
class DrmPlane {
|
||||
public:
|
||||
explicit DrmPlane(drmModePlane &p);
|
||||
virtual ~DrmPlane();
|
||||
int32_t Init(DrmDevice &drmDevice);
|
||||
uint32_t GetId() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
uint32_t GetPropFbId() const
|
||||
{
|
||||
return mPropFbId;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mId = 0;
|
||||
uint32_t mPossibleCrtcs = 0;
|
||||
uint32_t mPropFbId = 0;
|
||||
uint32_t mPropFenceInId = 0;
|
||||
uint32_t mPropCrtcId = 0;
|
||||
uint32_t mPipe = 0;
|
||||
uint32_t mType = 0;
|
||||
std::vector<uint32_t> mFormats;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // DRM_PLANE_H
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 <chrono>
|
||||
#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_LOGD("the drm fd is %{public}d", fd);
|
||||
mThread = std::make_unique<std::thread>([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_LOGD();
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(mMutex);
|
||||
mRunning = false;
|
||||
}
|
||||
DISPLAY_LOGD();
|
||||
mCondition.notify_one();
|
||||
if (mThread != nullptr) {
|
||||
mThread->join();
|
||||
}
|
||||
DISPLAY_LOGD();
|
||||
}
|
||||
|
||||
bool DrmVsyncWorker::WaitSignalAndCheckRuning()
|
||||
{
|
||||
std::unique_lock<std::mutex> 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,
|
||||
}
|
||||
};
|
||||
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_LOGD();
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(mMutex);
|
||||
mEnable = enable;
|
||||
}
|
||||
mCondition.notify_one();
|
||||
}
|
||||
|
||||
void DrmVsyncWorker::WorkThread()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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<VsyncCallBack> &cb)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((cb == nullptr), DISPLAY_LOGE("the VBlankCallback is nullptr "));
|
||||
mCallBack = cb;
|
||||
}
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
@@ -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 <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#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<VsyncCallBack> &cb);
|
||||
|
||||
private:
|
||||
int mDrmFd = 0;
|
||||
std::unique_ptr<std::thread> mThread;
|
||||
bool mEnable = false;
|
||||
std::mutex mMutex;
|
||||
std::condition_variable mCondition;
|
||||
std::shared_ptr<VsyncCallBack> mCallBack;
|
||||
bool mRunning = false;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // DRM_VSYNC_WORKER_H
|
||||
@@ -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<HdiComposition> pre, std::unique_ptr<HdiComposition> post)
|
||||
{
|
||||
mPreComp = std::move(pre);
|
||||
mPostComp = std::move(post);
|
||||
}
|
||||
|
||||
int32_t HdiComposer::Prepare(std::vector<HdiLayer *> &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
|
||||
@@ -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 <vector>
|
||||
#include <memory>
|
||||
#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<HdiLayer *> &layers, HdiLayer &clientLayer)
|
||||
{
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
virtual int32_t Apply(bool modeSet)
|
||||
{
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
virtual ~HdiComposition() {}
|
||||
|
||||
protected:
|
||||
std::vector<HdiLayer *> mCompLayers;
|
||||
};
|
||||
|
||||
class HdiComposer {
|
||||
public:
|
||||
HdiComposer(std::unique_ptr<HdiComposition> pre, std::unique_ptr<HdiComposition> post);
|
||||
virtual ~HdiComposer() {};
|
||||
int32_t Prepare(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer);
|
||||
int32_t Commit(bool modeSet);
|
||||
HdiComposition *GetPreCompostion()
|
||||
{
|
||||
return mPreComp.get();
|
||||
}
|
||||
HdiComposition *GetPostCompostion()
|
||||
{
|
||||
return mPostComp.get();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<HdiComposition> mPreComp;
|
||||
std::unique_ptr<HdiComposition> mPostComp;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_COMPOSER_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 <memory>
|
||||
#include <unordered_map>
|
||||
#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<typename T> using IdMapPtr = std::unordered_map<uint32_t, std::shared_ptr<T>>;
|
||||
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
|
||||
@@ -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 <vector>
|
||||
#include "display_common.h"
|
||||
#include "drm_device.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
std::vector<std::shared_ptr<HdiDeviceInterface>> HdiDeviceInterface::DiscoveryDevice()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
int ret;
|
||||
std::vector<std::shared_ptr<HdiDeviceInterface>> devices;
|
||||
std::shared_ptr<HdiDeviceInterface> drmDevice = DrmDevice::Create();
|
||||
if (!drmDevice) {
|
||||
DISPLAY_LOGE("can not create drm device");
|
||||
}
|
||||
ret = drmDevice->Init();
|
||||
if (ret == DISPLAY_SUCCESS) {
|
||||
DISPLAY_LOGD("drm device init success");
|
||||
devices.push_back(std::move(drmDevice));
|
||||
} else {
|
||||
DISPLAY_LOGE("drm device init failed");
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "hdi_display.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
class HdiDeviceInterface {
|
||||
public:
|
||||
static std::vector<std::shared_ptr<HdiDeviceInterface>> DiscoveryDevice();
|
||||
virtual std::unordered_map<uint32_t, std::shared_ptr<HdiDisplay>> DiscoveryDisplay() = 0;
|
||||
virtual int32_t Init() = 0;
|
||||
virtual void DeInit() = 0;
|
||||
virtual ~HdiDeviceInterface() {};
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_DEVICE_INTERFACE_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.
|
||||
*/
|
||||
|
||||
#include "hdi_display.h"
|
||||
#include <vector>
|
||||
#include "display_common.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
uint32_t HdiDisplay::mIdleId = 0;
|
||||
std::unordered_set<uint32_t> 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_LOGD();
|
||||
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_LOGD("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_LOGD("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_LOGD("zorder no change layerId %{public}d, zorder %{public}d", layerId, zorder);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
// reset to sort
|
||||
auto zRange = mLayers.equal_range(layer);
|
||||
DISPLAY_LOGD("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_LOGD();
|
||||
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_LOGD("mLayers size %{public}zu", mLayers.size());
|
||||
DISPLAY_LOGD("mLayerMap size %{public}zu", mLayersMap.size());
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
std::unique_ptr<HdiLayer> HdiDisplay::CreateHdiLayer(LayerType type)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return std::make_unique<HdiLayer>(type);
|
||||
}
|
||||
|
||||
|
||||
int32_t HdiDisplay::CloseLayer(uint32_t layerId)
|
||||
{
|
||||
DISPLAY_LOGD("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_LOGD("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_LOGD("set the layer fences");
|
||||
int i = 0;
|
||||
for (auto layer : mLayers) {
|
||||
if (layers != nullptr) {
|
||||
*(layers + i) = layer->GetId();
|
||||
}
|
||||
if (fences != nullptr) {
|
||||
*(fences + i) = layer->GetReleaseFenceFd();
|
||||
}
|
||||
DISPLAY_LOGD("layer id %{public}d fencefd %{public}d", layer->GetId(), layer->GetReleaseFenceFd());
|
||||
i++;
|
||||
}
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
mChangeLayers.clear();
|
||||
std::vector<HdiLayer *> layers;
|
||||
for (auto c : mLayers) {
|
||||
layers.push_back(c);
|
||||
}
|
||||
DISPLAY_LOGD(" mLayers size %{public}zu layers size %{public}zu", mLayers.size(), layers.size());
|
||||
|
||||
mComposer->Prepare(layers, *mClientLayer);
|
||||
// get the change layers
|
||||
for (auto &layer : layers) {
|
||||
if (layer->GetDeviceSelect() != layer->GetCompositionType()) {
|
||||
DISPLAY_LOGD("layer change");
|
||||
layer->SetLayerCompositionType(layer->GetDeviceSelect());
|
||||
}
|
||||
mChangeLayers.push_back(layer);
|
||||
}
|
||||
*needFlushFb = true;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiDisplay::Commit(int32_t *fence)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
mComposer->Commit(false);
|
||||
*fence = mClientLayer->GetReleaseFenceFd();
|
||||
DISPLAY_LOGD("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_LOGD("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) : mVBlankCb(cb), mData(data)
|
||||
{
|
||||
DISPLAY_LOGD("VsyncCallBack %{public}p", cb);
|
||||
}
|
||||
|
||||
void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
|
||||
mVBlankCb(sequence, ns, mData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef HDI_DISPLAY_H
|
||||
#define HDI_DISPLAY_H
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <memory.h>
|
||||
#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);
|
||||
virtual void Vsync(unsigned int sequence, uint64_t ns);
|
||||
virtual ~VsyncCallBack() {}
|
||||
|
||||
private:
|
||||
VBlankCallback mVBlankCb;
|
||||
void *mData;
|
||||
};
|
||||
|
||||
|
||||
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 GetDisplaySuppportedModes(int *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<HdiLayer> CreateHdiLayer(LayerType type);
|
||||
std::unique_ptr<HdiComposer> mComposer;
|
||||
|
||||
static uint32_t GetIdleId();
|
||||
static uint32_t mIdleId;
|
||||
static std::unordered_set<uint32_t> mIdSets;
|
||||
uint32_t mId = INVALIDE_DISPLAY_ID;
|
||||
std::unordered_map<uint32_t, std::unique_ptr<HdiLayer>> mLayersMap;
|
||||
std::multiset<HdiLayer *, SortLayersByZ> mLayers;
|
||||
std::unique_ptr<HdiLayer> mClientLayer;
|
||||
std::vector<HdiLayer *> mChangeLayers;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_DISPLAY_H
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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 <cerrno>
|
||||
#include "hdi_drm_layer.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
HdiDrmComposition::HdiDrmComposition(std::shared_ptr<DrmConnector> connector, std::shared_ptr<DrmCrtc> crtc,
|
||||
std::shared_ptr<DrmDevice> drmDevice)
|
||||
: mDrmDevice(drmDevice), mConnector(connector), mCrtc(crtc)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
}
|
||||
|
||||
int32_t HdiDrmComposition::Init()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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);
|
||||
DISPLAY_CHK_RETURN((mPrimPlanes.size() == 0), DISPLAY_FAILURE, DISPLAY_LOGE("has no primary plane"));
|
||||
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<HdiLayer *> &layers, HdiLayer &clientLayer)
|
||||
{
|
||||
// now we do not surpport present direct
|
||||
DISPLAY_LOGD();
|
||||
mCompLayers.clear();
|
||||
mCompLayers.push_back(&clientLayer);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiDrmComposition::ApplyPlane(HdiDrmLayer &layer, DrmPlane &drmPlane, drmModeAtomicReqPtr pset)
|
||||
{
|
||||
// set fence in
|
||||
int ret;
|
||||
int fenceFd = layer.GetAcquireFenceFd();
|
||||
int propId = drmPlane.GetPropFenceInId();
|
||||
DISPLAY_LOGD();
|
||||
if (propId != 0) {
|
||||
DISPLAY_LOGD("set the fence in prop");
|
||||
if (fenceFd >= 0) {
|
||||
ret = drmModeAtomicAddProperty(pset, drmPlane.GetId(), propId, fenceFd);
|
||||
DISPLAY_LOGD("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"));
|
||||
}
|
||||
}
|
||||
|
||||
// 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_LOGD("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_LOGD("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<DrmModeBlock> &modeBlock, drmModeAtomicReq &pset)
|
||||
{
|
||||
// set the mode
|
||||
DISPLAY_LOGD();
|
||||
if (mCrtc->NeedModeSet()) {
|
||||
modeBlock = mConnector->GetModeBlockFromId(mCrtc->GetActiveModeId());
|
||||
if ((modeBlock != nullptr) && (modeBlock->GetBlockId() != DRM_INVALID_ID)) {
|
||||
// set to active
|
||||
DISPLAY_LOGD("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_LOGD("set the mode");
|
||||
ret = drmModeAtomicAddProperty(&pset, mCrtc->GetId(), mCrtc->GetModePropId(), modeBlock->GetBlockId());
|
||||
DISPLAY_LOGD("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_LOGD("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::Apply(bool modeSet)
|
||||
{
|
||||
uint64_t crtcOutFence = -1;
|
||||
int ret;
|
||||
std::unique_ptr<DrmModeBlock> modeBlock;
|
||||
int drmFd = mDrmDevice->GetDrmFd();
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD("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_LOGD("mCompLayers size %{public}zd", mCompLayers.size());
|
||||
for (uint32_t i = 0; i < mCompLayers.size(); i++) {
|
||||
HdiDrmLayer *layer = static_cast<HdiDrmLayer *>(mCompLayers[i]);
|
||||
auto &drmPlane = mPlanes[i];
|
||||
ret = ApplyPlane(*layer, *drmPlane, atomicReqPtr.Get());
|
||||
if (ret != DISPLAY_SUCCESS) {
|
||||
DISPLAY_LOGE("apply plane failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
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<int>(crtcOutFence));
|
||||
}
|
||||
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
} // OHOS
|
||||
} // HDI
|
||||
} // DISPLAY
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 <vector>
|
||||
#include <memory>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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(std::shared_ptr<DrmConnector> connector, std::shared_ptr<DrmCrtc> crtc,
|
||||
std::shared_ptr<DrmDevice> drmDevice);
|
||||
virtual ~HdiDrmComposition() {}
|
||||
int32_t Init();
|
||||
int32_t SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer);
|
||||
int32_t Apply(bool modeSet);
|
||||
int32_t UpdateMode(std::unique_ptr<DrmModeBlock> &modeBlock, drmModeAtomicReq &pset);
|
||||
|
||||
private:
|
||||
int32_t ApplyPlane(HdiDrmLayer &layer, DrmPlane &drmPlane, drmModeAtomicReqPtr pset);
|
||||
std::shared_ptr<DrmDevice> mDrmDevice;
|
||||
std::shared_ptr<DrmConnector> mConnector;
|
||||
std::shared_ptr<DrmCrtc> mCrtc;
|
||||
std::vector<std::shared_ptr<DrmPlane>> mPrimPlanes;
|
||||
std::vector<std::shared_ptr<DrmPlane>> mOverlayPlanes;
|
||||
std::vector<std::shared_ptr<DrmPlane>> mPlanes;
|
||||
};
|
||||
} // OHOS
|
||||
} // HDI
|
||||
} // DISPLAY
|
||||
|
||||
#endif // HDI_DRM_COMPOSITION_H
|
||||
@@ -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 <cinttypes>
|
||||
#include <errno.h>
|
||||
#include "drm_device.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
DrmGemBuffer::DrmGemBuffer(int drmfd, HdiLayerBuffer &hdl) : mDrmFd(drmfd)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD("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<PixelFormat>(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_LOGD("mGemHandle %{public}d mFdId %{public}d", mGemHandle, mFdId);
|
||||
DISPLAY_LOGD("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_LOGD();
|
||||
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_LOGD();
|
||||
return (mGemHandle != INVALID_DRM_ID) && (mFdId != INVALID_DRM_ID);
|
||||
}
|
||||
|
||||
DrmGemBuffer *HdiDrmLayer::GetGemBuffer()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
std::unique_ptr<DrmGemBuffer> ptr = std::make_unique<DrmGemBuffer>(DrmDevice::GetDrmFd(), *GetCurrentBuffer());
|
||||
mLastBuffer = std::move(mCurrentBuffer);
|
||||
mCurrentBuffer = std::move(ptr);
|
||||
return mCurrentBuffer.get();
|
||||
}
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
@@ -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 <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#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) {}
|
||||
virtual ~HdiDrmLayer() {}
|
||||
// Return value optimization
|
||||
DrmGemBuffer *GetGemBuffer();
|
||||
|
||||
private:
|
||||
std::unique_ptr<DrmGemBuffer> mCurrentBuffer;
|
||||
std::unique_ptr<DrmGemBuffer> mLastBuffer;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_DRM_LAYER_H
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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_gfx_composition.h"
|
||||
#include <cinttypes>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include "display_gfx.h"
|
||||
|
||||
#define LIB_HDI_GFX_NAME "libdisplay_gfx.z.so"
|
||||
#define LIB_GFX_FUNC_INIT "GfxInitialize"
|
||||
#define LIB_GFX_FUNC_DEINIT "GfxUninitialize"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
int32_t HdiGfxComposition::Init(void)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
mGfxModule = dlopen(LIB_HDI_GFX_NAME, RTLD_NOW | RTLD_NOLOAD);
|
||||
if (mGfxModule != nullptr) {
|
||||
DISPLAY_LOGI("Module '%{public}s' already loaded", LIB_HDI_GFX_NAME);
|
||||
} else {
|
||||
DISPLAY_LOGI("Loading module '%{public}s'", LIB_HDI_GFX_NAME);
|
||||
mGfxModule = dlopen(LIB_HDI_GFX_NAME, 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<InitFunc>(dlsym(mGfxModule, LIB_GFX_FUNC_INIT));
|
||||
if (func == nullptr) {
|
||||
DISPLAY_LOGE("Failed to lookup %{public}s function: %s", LIB_GFX_FUNC_INIT, dlerror());
|
||||
dlclose(mGfxModule);
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
return func(&mGfxFuncs);
|
||||
}
|
||||
|
||||
int32_t HdiGfxComposition::GfxModuleDeinit(void)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
int32_t ret = DISPLAY_SUCCESS;
|
||||
if (mGfxModule == nullptr) {
|
||||
using DeinitFunc = int32_t (*)(GfxFuncs *funcs);
|
||||
DeinitFunc func = reinterpret_cast<DeinitFunc>(dlsym(mGfxModule, LIB_GFX_FUNC_DEINIT));
|
||||
if (func == nullptr) {
|
||||
DISPLAY_LOGE("Failed to lookup %{public}s function: %s", LIB_GFX_FUNC_DEINIT, dlerror());
|
||||
} else {
|
||||
ret = func(mGfxFuncs);
|
||||
}
|
||||
dlclose(mGfxModule);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool HdiGfxComposition::CanHandle(HdiLayer &hdiLayer)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
(void)hdiLayer;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t HdiGfxComposition::SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer)
|
||||
{
|
||||
DISPLAY_LOGD("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_LOGD("composer layers size %{public}zd", mCompLayers.size());
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
void HdiGfxComposition::InitGfxSurface(ISurface &surface, HdiLayerBuffer &buffer)
|
||||
{
|
||||
surface.width = buffer.GetWight();
|
||||
surface.height = buffer.GetHeight();
|
||||
surface.phyAddr = buffer.GetFb();//buffer.GetPhysicalAddr();
|
||||
// surface.fd = buffer.GetFb();
|
||||
surface.enColorFmt = (PixelFormat)buffer.GetFormat();
|
||||
surface.stride = buffer.GetStride();
|
||||
surface.bAlphaExt1555 = true;
|
||||
surface.bAlphaMax255 = true;
|
||||
surface.alpha0 = 0XFF;
|
||||
surface.alpha1 = 0XFF;
|
||||
DISPLAY_LOGD("surface fd %{public}d w:%{public}d h:%{public}d addr:0x%{public}" PRIx64 " fmt:%{public}d stride:%{public}d",
|
||||
buffer.GetFb(), surface.width, surface.height, buffer.GetPhysicalAddr(), surface.enColorFmt, surface.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_LOGD();
|
||||
HdiLayerBuffer *srcBuffer = src.GetCurrentBuffer();
|
||||
DISPLAY_CHK_RETURN((srcBuffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the srcbuffer is null"));
|
||||
DISPLAY_LOGD("init the src surface");
|
||||
InitGfxSurface(srcSurface, *srcBuffer);
|
||||
|
||||
HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
|
||||
DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
|
||||
DISPLAY_LOGD("init the dst surface");
|
||||
InitGfxSurface(dstSurface, *dstBuffer);
|
||||
|
||||
opt.blendType = src.GetLayerBlenType();
|
||||
DISPLAY_LOGD("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_LOGD("src alpha %{public}x", src.GetAlpha().gAlpha);
|
||||
}
|
||||
opt.rotateType = src.GetTransFormType();
|
||||
DISPLAY_LOGD(" the roate type is %{public}d", opt.rotateType);
|
||||
IRect crop = src.GetLayerCrop();
|
||||
IRect displayRect = src.GetLayerDisplayRect();
|
||||
DISPLAY_LOGD("crop x: %{public}d y : %{public}d w : %{public}d h: %{public}d", crop.x, crop.y, crop.w, crop.h);
|
||||
DISPLAY_LOGD("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_LOGD();
|
||||
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_LOGD("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
|
||||
@@ -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<HdiLayer *> &layers, HdiLayer &clientLayer) override;
|
||||
int32_t Apply(bool modeSet) override;
|
||||
virtual ~HdiGfxComposition()
|
||||
{
|
||||
(void)GfxModuleDeinit();
|
||||
}
|
||||
|
||||
private:
|
||||
bool CanHandle(HdiLayer &hdiLayer);
|
||||
void InitGfxSurface(ISurface &surface, 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
|
||||
@@ -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 <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
uint32_t HdiLayer::mIdleId = 0;
|
||||
std::unordered_set<uint32_t> HdiLayer::mIdSets;
|
||||
|
||||
HdiLayerBuffer::HdiLayerBuffer(const BufferHandle &hdl)
|
||||
: mPhyAddr(hdl.phyAddr), mHeight(hdl.height), mWidth(hdl.width), mStride(hdl.stride), mFormat(hdl.format)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
if (mFd >= 0) {
|
||||
close(mFd);
|
||||
}
|
||||
}
|
||||
|
||||
HdiLayerBuffer &HdiLayerBuffer::operator = (const BufferHandle &right)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
if (mFd >= 0) {
|
||||
close(mFd);
|
||||
}
|
||||
mFd = 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_LOGD("id %{public}d mIdleId %{public}d", id, mIdleId);
|
||||
return id;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::Init()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD(" 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_LOGD("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_LOGD("id : %{public}d zorder : %{public}d ", mId, zorder);
|
||||
mZorder = zorder;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetLayerPreMulti(bool preMul)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD("enable alpha %{public}d galpha 0x%{public}x", alpha->enGlobalAlpha, alpha->gAlpha);
|
||||
mAlpha = *alpha;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetTransformMode(TransformType type)
|
||||
{
|
||||
DISPLAY_LOGD("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_LOGD("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_LOGD("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_LOGD();
|
||||
DISPLAY_CHK_RETURN((buffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("buffer is nullptr"));
|
||||
std::unique_ptr<HdiLayerBuffer> layerbuffer = std::make_unique<HdiLayerBuffer>(*buffer);
|
||||
mHdiBuffer = std::move(layerbuffer);
|
||||
mAcquireFence = fence;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetLayerCompositionType(CompositionType type)
|
||||
{
|
||||
DISPLAY_LOGD("CompositionType type %{public}d", type);
|
||||
mCompositionType = type;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetLayerBlendType(BlendType type)
|
||||
{
|
||||
DISPLAY_LOGD("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<uint32_t *>(handle.virAddr) + position;
|
||||
*pixel = color;
|
||||
}
|
||||
|
||||
void HdiLayer::ClearColor(uint32_t color)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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
|
||||
@@ -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 <unordered_set>
|
||||
#include <memory>
|
||||
#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_LOGD("%{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<uint32_t> 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;
|
||||
CompositionType mCompositionType = COMPOSITION_CLIENT;
|
||||
CompositionType mDeviceSelect = COMPOSITION_CLIENT;
|
||||
BlendType mBlendType;
|
||||
std::unique_ptr<HdiLayerBuffer> 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
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#include "hdi_netlink_monitor.h"
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
HdiNetLinkMonitor::HdiNetLinkMonitor()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
}
|
||||
|
||||
int HdiNetLinkMonitor::Init()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
int fd;
|
||||
struct sockaddr_nl snl = { 0 };
|
||||
int ret;
|
||||
const int32_t bufferSize = 1024;
|
||||
DISPLAY_CHK_RETURN((mScoketFd < 0), DISPLAY_FAILURE, DISPLAY_LOGE("the socket has initial"));
|
||||
fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
|
||||
DISPLAY_CHK_RETURN((fd < 0), DISPLAY_FAILURE, DISPLAY_LOGE("scoket create failed"));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
|
||||
ret = bind(fd, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
|
||||
DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("bind failed errno : %{public}d", errno));
|
||||
|
||||
mThread = std::make_unique<std::thread>([this]() {
|
||||
mRunning = true;
|
||||
MonitorThread();
|
||||
});
|
||||
mScoketFd = fd;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
HdiNetLinkMonitor::~HdiNetLinkMonitor()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
if (mScoketFd >= 0) {
|
||||
close(mScoketFd);
|
||||
}
|
||||
}
|
||||
|
||||
Void HdiNetLinkMonitor::MonitorThread()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
constexpr int BUFFER_SIZE = UEVENT_BUFFER_SIZE * 2;
|
||||
while (mRunning) {
|
||||
char buf[BUFFER_SIZE] = { 0 };
|
||||
recv(mScoketFd, &buf, sizeof(buf), 0);
|
||||
}
|
||||
}
|
||||
} //DISPLAY
|
||||
} //HDI
|
||||
} //OHOS
|
||||
@@ -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 <thread>
|
||||
|
||||
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<std::thread> mThread;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_NETLINK_NONITOR_H
|
||||
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* 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_session.h>
|
||||
#include <errno.h>
|
||||
#include <mutex>
|
||||
#include "display_common.h"
|
||||
#include "display_device.h"
|
||||
#include "display_layer.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_LOGD();
|
||||
mHdiDevices = HdiDeviceInterface::DiscoveryDevice();
|
||||
DISPLAY_LOGD("devices size %{public}zd", mHdiDevices.size());
|
||||
mHdiDisplays.clear();
|
||||
for (auto device : mHdiDevices) {
|
||||
auto displays = device->DiscoveryDisplay();
|
||||
mHdiDisplays.insert(displays.begin(), displays.end());
|
||||
}
|
||||
}
|
||||
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
HdiSession::GetInstance().RegHotPlugCallback(callback, data);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t GetDisplayCapability(uint32_t devId, DisplayCapability *info)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN(info == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("info is nullptr"));
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCapability, info);
|
||||
}
|
||||
|
||||
static int32_t GetDisplaySuppportedModes(uint32_t devId, int *num, DisplayModeInfo *modes)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN(num == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplaySuppportedModes, num, modes);
|
||||
}
|
||||
|
||||
static int32_t GetDisplayMode(uint32_t devId, uint32_t *mode)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayMode, mode);
|
||||
}
|
||||
|
||||
static int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus *status)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayPowerStatus, status);
|
||||
}
|
||||
|
||||
static int32_t GetDisplayBacklight(uint32_t devId, uint32_t *value)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayBacklight, value);
|
||||
}
|
||||
|
||||
static int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t *value)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
(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_LOGD();
|
||||
(void)id;
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
static int32_t PrepareDisplayLayers(uint32_t devId, bool *needFlushFb)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayClientBuffer, buffer, fence);
|
||||
}
|
||||
|
||||
static int32_t SetDisplayClientDamage(uint32_t devId, uint32_t num, IRect *rect)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
(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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayVsyncEnabled, enabled);
|
||||
}
|
||||
|
||||
static int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback callback, void *data)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayReleaseFence, num, layers,
|
||||
fences);
|
||||
// return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
static int32_t Commit(uint32_t devId, int32_t *fence)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
static int32_t DestroyVirtualDisplay(uint32_t devId)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
static int32_t SetVirtualDisplayBuffer(uint32_t devId, BufferHandle *buffer, int32_t releaseFence)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
|
||||
// Layer function
|
||||
static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerSize, rect);
|
||||
}
|
||||
|
||||
static int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, IRect *rect)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetLayerZorder, layerId, zorder);
|
||||
}
|
||||
|
||||
static int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerPreMulti, preMul);
|
||||
}
|
||||
|
||||
static int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, LayerAlpha *alpha)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTransformMode, type);
|
||||
}
|
||||
|
||||
static int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, IRect *region)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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_LOGD();
|
||||
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_LOGD();
|
||||
return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBuffer, buffer, fence);
|
||||
}
|
||||
|
||||
static int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCompositionType, type);
|
||||
}
|
||||
|
||||
static int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
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->GetDisplaySuppportedModes = GetDisplaySuppportedModes;
|
||||
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_LOGD("%{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_LOGD("%{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_LOGD("%{public}s: layer uninitialize success", __func__);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#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<typename... Args>
|
||||
int32_t CallDisplayFunction(uint32_t devId, int32_t (HdiDisplay::*member)(Args...), Args... args)
|
||||
{
|
||||
DISPLAY_LOGD("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>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
int32_t CallLayerFunction(uint32_t devId, uint32_t layerId, int32_t (HdiLayer::*member)(Args...), Args... args)
|
||||
{
|
||||
DISPLAY_LOGD("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>(args)...);
|
||||
}
|
||||
|
||||
int32_t RegHotPlugCallback(HotPlugCallback callback, void *data);
|
||||
void DoHotPlugCallback(uint32_t devId, bool connect);
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, std::shared_ptr<HdiDisplay>> mHdiDisplays;
|
||||
std::vector<std::shared_ptr<HdiDeviceInterface>> mHdiDevices;
|
||||
std::unordered_map<HotPlugCallback, void *> mHotPlugCallBacks;
|
||||
};
|
||||
} // namespace OHOS
|
||||
} // namespace HDI
|
||||
} // namespace DISPLAY
|
||||
|
||||
#endif // HDI_SESSION_H
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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_SHARED_FD
|
||||
#define HDI_SHARED_FD
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#include "display_common.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace HDI {
|
||||
namespace DISPLAY {
|
||||
class HdiFd {
|
||||
public:
|
||||
HdiFd()
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
}
|
||||
explicit HdiFd(int fd) : mFd(fd)
|
||||
{
|
||||
DISPLAY_LOGD("mFd %{public}d", mFd);
|
||||
}
|
||||
int GetFd() const
|
||||
{
|
||||
return mFd;
|
||||
};
|
||||
|
||||
HdiFd &operator = (int fd)
|
||||
{
|
||||
if (mFd >= 0) {
|
||||
close(mFd);
|
||||
}
|
||||
mFd = fd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~HdiFd()
|
||||
{
|
||||
if (mFd >= 0) {
|
||||
close(mFd);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int mFd = -1;
|
||||
};
|
||||
|
||||
using FdPtr = std::shared_ptr<HdiFd>;
|
||||
} // OHOS
|
||||
} // HDIO
|
||||
} // DISPLAY
|
||||
|
||||
#endif // HDI_SHARED_FD
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "display_gfx.h"
|
||||
#include "im2d.h"
|
||||
#include "rga.h"
|
||||
#include "display_common.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "display_gralloc.h"
|
||||
|
||||
#define ALIGN_UP(x, a) ((((x) + ((a)-1)) / (a)) * (a))
|
||||
GrallocFuncs *grallocFucs = NULL;
|
||||
int32_t rkInitGfx()
|
||||
{
|
||||
DISPLAY_LOGE("%s\n", querystring(RGA_ALL));
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t rkDeinitGfx()
|
||||
{
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
RgaSURF_FORMAT colorSpaceModeChange(PixelFormat color, uint8_t *isYuv)
|
||||
{
|
||||
RgaSURF_FORMAT rkFormat;
|
||||
switch(color) {
|
||||
case PIXEL_FMT_RGB_565: /**< RGB565 format */
|
||||
rkFormat = RK_FORMAT_RGB_565;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_RGBA_4444: /**< RGBA4444 format */
|
||||
rkFormat = RK_FORMAT_RGBA_4444;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_RGBA_5551: /**< RGBA5551 format */
|
||||
rkFormat = RK_FORMAT_RGBA_5551;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_RGBX_8888: /**< RGBX8888 format */
|
||||
rkFormat = RK_FORMAT_RGBX_8888;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_RGBA_8888: /**< RGBA8888 format */
|
||||
rkFormat = RK_FORMAT_RGBA_8888;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_RGB_888: /**< RGB888 format */
|
||||
rkFormat = RK_FORMAT_RGB_888;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_BGR_565: /**< BGR565 format */
|
||||
rkFormat = RK_FORMAT_BGR_565;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_BGRA_4444: /**< BGRA4444 format */
|
||||
rkFormat = RK_FORMAT_BGRA_4444;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_BGRA_5551: /**< BGRA5551 format */
|
||||
rkFormat = RK_FORMAT_BGRA_5551;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_BGRX_8888: /**< BGRX8888 format */
|
||||
rkFormat = RK_FORMAT_BGRX_8888;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_BGRA_8888: /**< BGRA8888 format */
|
||||
rkFormat = RK_FORMAT_BGRA_8888;
|
||||
*isYuv = 0;
|
||||
break;
|
||||
case PIXEL_FMT_YCBCR_422_SP: /**< YCBCR422 semi-planar format */
|
||||
rkFormat = RK_FORMAT_YCbCr_420_SP;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCRCB_422_SP: /**< YCRCB422 semi-planar format */
|
||||
rkFormat = RK_FORMAT_YCrCb_422_SP;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCBCR_420_SP: /**< YCBCR420 semi-planar format */
|
||||
rkFormat = RK_FORMAT_YCbCr_420_SP;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCRCB_420_SP: /**< YCRCB420 semi-planar format */
|
||||
rkFormat = RK_FORMAT_YCrCb_420_SP;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCBCR_422_P: /**< YCBCR422 planar format */
|
||||
rkFormat = RK_FORMAT_YCbCr_422_P;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCRCB_422_P: /**< YCRCB422 planar format */
|
||||
rkFormat = RK_FORMAT_YCrCb_422_P;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCBCR_420_P: /**< YCBCR420 planar format */
|
||||
rkFormat = RK_FORMAT_YCbCr_420_P;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YCRCB_420_P: /**< YCRCB420 planar format */
|
||||
rkFormat = RK_FORMAT_YCrCb_420_P;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YUYV_422_PKG: /**< YUYV422 packed format */
|
||||
rkFormat = RK_FORMAT_YUYV_422;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_UYVY_422_PKG: /**< UYVY422 packed format */
|
||||
rkFormat = RK_FORMAT_UYVY_422;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_YVYU_422_PKG: /**< YVYU422 packed format */
|
||||
rkFormat = RK_FORMAT_YUYV_422;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
case PIXEL_FMT_VYUY_422_PKG: /**< VYUY422 packed format */
|
||||
rkFormat = RK_FORMAT_VYUY_422;
|
||||
*isYuv = 1;
|
||||
break;
|
||||
default:
|
||||
// PIXEL_FMT_CLUT8: /**< CLUT8 format */
|
||||
// PIXEL_FMT_CLUT1, /**< CLUT1 format */
|
||||
// PIXEL_FMT_CLUT4, /**< CLUT4 format */
|
||||
// PIXEL_FMT_RGBA_5658, /**< RGBA5658 format */
|
||||
// PIXEL_FMT_RGBX_4444, /**< RGBX4444 format */
|
||||
// PIXEL_FMT_RGB_444, /**< RGB444 format */
|
||||
// PIXEL_FMT_RGBX_5551, /**< RGBX5551 format */
|
||||
// PIXEL_FMT_RGB_555, /**< RGB555 format */
|
||||
// PIXEL_FMT_BGRX_4444, /**< BGRX4444 format */
|
||||
// PIXEL_FMT_BGRX_5551, /**< BGRX5551 format */
|
||||
// PIXEL_FMT_YUV_422_I, /**< YUV422 interleaved format */
|
||||
rkFormat = RK_FORMAT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return rkFormat;
|
||||
}
|
||||
|
||||
int32_t rkFillRect(ISurface *surface, IRect *rect, uint32_t color, GfxOpt *opt)
|
||||
{
|
||||
rga_buffer_t dst;
|
||||
im_rect imRect;
|
||||
IM_STATUS ret;
|
||||
uint8_t isYuv;
|
||||
|
||||
memset((void *)&imRect, 0, sizeof(imRect));
|
||||
imRect.x = rect->x;
|
||||
imRect.y = rect->y;
|
||||
imRect.width = rect->w;
|
||||
imRect.height = rect->h;
|
||||
|
||||
memset((void *)&dst, 0, sizeof(dst));
|
||||
dst.phy_addr = 0;//(void*)surface->phyAddr;
|
||||
dst.vir_addr = 0;//surface->virAddr;
|
||||
dst.fd = (int32_t)surface->phyAddr;
|
||||
if ((int)dst.phy_addr == 0 && dst.fd == 0 && dst.vir_addr == NULL) {
|
||||
DISPLAY_LOGE("source surface address error");
|
||||
return DISPLAY_PARAM_ERR;
|
||||
}
|
||||
DISPLAY_LOGE("gfx vir %{public}p phy 0x%{public}x fd %{public}d",dst.vir_addr, (int32_t)dst.phy_addr, dst.fd);
|
||||
dst.width = surface->width;
|
||||
dst.height = surface->height;
|
||||
dst.wstride = ALIGN_UP(surface->width, 16);
|
||||
dst.hstride = ALIGN_UP(surface->height, 16);
|
||||
dst.format = colorSpaceModeChange(surface->enColorFmt, &isYuv);
|
||||
dst.color_space_mode = IM_COLOR_SPACE_DEFAULT;
|
||||
dst.color = color;
|
||||
if (opt->enGlobalAlpha)
|
||||
dst.global_alpha = opt->globalAlpha;
|
||||
ret = imfill(dst, imRect, color);
|
||||
|
||||
if (ret != IM_STATUS_SUCCESS)
|
||||
return DISPLAY_FAILURE;
|
||||
else
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t blendTypeChange(BlendType blendType)
|
||||
{
|
||||
int32_t rkBlendType;
|
||||
switch(blendType) {
|
||||
case BLEND_SRC: /**< SRC blending */
|
||||
rkBlendType = IM_ALPHA_BLEND_SRC;
|
||||
break;
|
||||
case BLEND_DST: /**< SRC blending */
|
||||
rkBlendType = IM_ALPHA_BLEND_DST;
|
||||
break;
|
||||
case BLEND_SRCOVER: /**< SRC_OVER blending */
|
||||
rkBlendType = IM_ALPHA_BLEND_SRC_OVER;
|
||||
break;
|
||||
case BLEND_DSTOVER: /**< DST_OVER blending */
|
||||
rkBlendType = IM_ALPHA_BLEND_DST_OVER;
|
||||
break;
|
||||
default:
|
||||
/* Fix up later */
|
||||
// BLEND_NONE /**< No blending */
|
||||
// BLEND_CLEAR: /**< CLEAR blending */
|
||||
// BLEND_SRCIN: /**< SRC_IN blending */
|
||||
// BLEND_DSTIN: /**< DST_IN blending */
|
||||
// BLEND_SRCOUT: /**< SRC_OUT blending */
|
||||
// BLEND_DSTOUT: /**< DST_OUT blending */
|
||||
// BLEND_SRCATOP: /**< SRC_ATOP blending */
|
||||
// BLEND_DSTATOP: /**< DST_ATOP blending */
|
||||
// BLEND_ADD: /**< ADD blending */
|
||||
// BLEND_XOR: /**< XOR blending */
|
||||
// BLEND_DST: /**< DST blending */
|
||||
// BLEND_AKS: /**< AKS blending */
|
||||
// BLEND_AKD: /**< AKD blending */
|
||||
// BLEND_BUTT: /**< Null operation */
|
||||
rkBlendType = IM_STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
return rkBlendType;
|
||||
}
|
||||
|
||||
int32_t TransformTypeChange(TransformType type)
|
||||
{
|
||||
int32_t rkRotateType;
|
||||
switch(type) {
|
||||
case ROTATE_90: /**< Rotation by 90 degrees */
|
||||
rkRotateType = IM_HAL_TRANSFORM_ROT_90;
|
||||
break;
|
||||
case ROTATE_180: /**< Rotation by 180 degrees */
|
||||
rkRotateType = IM_HAL_TRANSFORM_ROT_180;
|
||||
break;
|
||||
case ROTATE_270: /**< Rotation by 270 degrees */
|
||||
rkRotateType = IM_HAL_TRANSFORM_ROT_270;
|
||||
break;
|
||||
default:
|
||||
rkRotateType = 0; /**< No rotation */
|
||||
break;
|
||||
}
|
||||
return rkRotateType;
|
||||
}
|
||||
|
||||
int32_t mirrorTypeChange(MirrorType type)
|
||||
{
|
||||
int32_t rkMirrorType;
|
||||
switch(type) {
|
||||
case MIRROR_LR: /**< Left and right mirrors */
|
||||
rkMirrorType = IM_HAL_TRANSFORM_FLIP_H;
|
||||
break;
|
||||
case MIRROR_TB: /**< Top and bottom mirrors */
|
||||
rkMirrorType = IM_HAL_TRANSFORM_FLIP_V;
|
||||
break;
|
||||
default:
|
||||
rkMirrorType = 0;
|
||||
break;
|
||||
}
|
||||
return rkMirrorType;
|
||||
}
|
||||
|
||||
int32_t doFlit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect *dstRect, GfxOpt *opt)
|
||||
{
|
||||
int32_t usage = 0;
|
||||
uint8_t isYuv = 0;
|
||||
rga_buffer_t dstRgaBuffer, srcRgaBuffer, bRgbBuffer;
|
||||
IM_STATUS ret = 0;
|
||||
im_rect srect;
|
||||
im_rect drect;
|
||||
im_rect prect;
|
||||
int32_t rkBlendType = 0;
|
||||
int32_t rkRotateType = 0;
|
||||
int32_t rkMirrorType = 0;
|
||||
|
||||
memset(&dstRgaBuffer, 0, sizeof(dstRgaBuffer));
|
||||
memset(&srcRgaBuffer, 0, sizeof(srcRgaBuffer));
|
||||
memset(&bRgbBuffer, 0, sizeof(bRgbBuffer));
|
||||
memset(&srect, 0, sizeof(srect));
|
||||
memset(&drect, 0, sizeof(drect));
|
||||
memset(&prect, 0, sizeof(prect));
|
||||
if (opt->enGlobalAlpha) {
|
||||
dstRgaBuffer.global_alpha = opt->globalAlpha;
|
||||
srcRgaBuffer.global_alpha = opt->globalAlpha;
|
||||
}
|
||||
dstRgaBuffer.width = dstSurface->width;
|
||||
dstRgaBuffer.height = dstSurface->height;
|
||||
dstRgaBuffer.wstride = ALIGN_UP(dstSurface->width, 16);
|
||||
dstRgaBuffer.hstride = ALIGN_UP(dstSurface->height, 16);
|
||||
dstRgaBuffer.format = colorSpaceModeChange(dstSurface->enColorFmt, &isYuv);
|
||||
dstRgaBuffer.phy_addr = 0;//(void *)dstSurface->phyAddr;
|
||||
dstRgaBuffer.vir_addr = 0;//dstSurface->virAddr;
|
||||
dstRgaBuffer.color_space_mode = IM_COLOR_SPACE_DEFAULT;
|
||||
dstRgaBuffer.fd = (int32_t)dstSurface->phyAddr;
|
||||
if (isYuv == 1) {
|
||||
DISPLAY_LOGE("rk gfx do not support dst buffer is yuv format");
|
||||
return DISPLAY_PARAM_ERR;
|
||||
}
|
||||
|
||||
srcRgaBuffer.width = srcSurface->width;
|
||||
srcRgaBuffer.height = srcSurface->height;
|
||||
srcRgaBuffer.wstride = ALIGN_UP(srcSurface->width, 16);
|
||||
srcRgaBuffer.hstride = ALIGN_UP(srcSurface->height, 16);
|
||||
srcRgaBuffer.phy_addr = 0;//(void *)srcSurface->phyAddr;
|
||||
srcRgaBuffer.vir_addr = 0;//srcSurface->virAddr;
|
||||
srcRgaBuffer.format = colorSpaceModeChange(srcSurface->enColorFmt, &isYuv);
|
||||
srcRgaBuffer.color_space_mode = IM_COLOR_SPACE_DEFAULT;
|
||||
srcRgaBuffer.fd = (int32_t)srcSurface->phyAddr;
|
||||
|
||||
if ((int)srcRgaBuffer.phy_addr == 0 && srcRgaBuffer.fd == 0 && srcRgaBuffer.vir_addr == NULL) {
|
||||
DISPLAY_LOGE("source surface address error");
|
||||
return DISPLAY_PARAM_ERR;
|
||||
}
|
||||
|
||||
DISPLAY_LOGE("gfx src fd %{public}d, w %{public}d, h %{publuc}d, sw %{public}d sh %{public}d vir %{public}p",(int32_t)srcSurface->phyAddr, srcSurface->width,
|
||||
srcSurface->height, ALIGN_UP(srcSurface->width, 16), ALIGN_UP(srcSurface->height, 16), srcRgaBuffer.vir_addr);
|
||||
DISPLAY_LOGE("gfx dst fd %{public}d, w %{public}d, h %{public}d, sw %{public}d sh %{public}d vir %{public}p",(int32_t)dstSurface->phyAddr, dstSurface->width,
|
||||
dstSurface->height, ALIGN_UP(dstSurface->width, 16), ALIGN_UP(dstSurface->height, 16), dstRgaBuffer.vir_addr);
|
||||
|
||||
srect.x = srcRect->x;
|
||||
srect.y = srcRect->y;
|
||||
srect.height = srcRect->h;
|
||||
srect.width = srcRect->w;
|
||||
drect.x = dstRect->x;
|
||||
drect.y = dstRect->y;
|
||||
drect.height = dstRect->h;
|
||||
drect.width = dstRect->w;
|
||||
|
||||
if (opt->blendType) {
|
||||
rkBlendType = blendTypeChange(opt->blendType);
|
||||
if (rkBlendType > 0) {
|
||||
usage |= rkBlendType;
|
||||
if (rkBlendType == IM_ALPHA_BLEND_DST_OVER || rkBlendType == IM_ALPHA_BLEND_SRC_OVER)
|
||||
usage |= IM_ALPHA_BLEND_PRE_MUL;
|
||||
} else if (rkBlendType == IM_STATUS_NOT_SUPPORTED) {
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
}
|
||||
if (opt->rotateType) {
|
||||
rkRotateType = TransformTypeChange(opt->rotateType);
|
||||
if (rkRotateType != 0)
|
||||
usage |= rkRotateType;
|
||||
}
|
||||
if (opt->mirrorType == MIRROR_LR || opt->mirrorType == MIRROR_TB) {
|
||||
rkMirrorType = mirrorTypeChange(opt->mirrorType);
|
||||
if (rkMirrorType != 0)
|
||||
usage |= rkMirrorType;
|
||||
}
|
||||
if (opt->enableScale) {
|
||||
DISPLAY_LOGE("gfx scale from (%{puhblic}d, %{public}d) to (%{public}d, %{public}d)", srcRgaBuffer.width, srcRgaBuffer.height, dstRgaBuffer.width,
|
||||
dstRgaBuffer.height);
|
||||
}
|
||||
usage |= IM_SYNC;
|
||||
if (isYuv == 1) {
|
||||
if (rkBlendType == IM_ALPHA_BLEND_SRC_OVER || rkBlendType == IM_ALPHA_BLEND_SRC) {
|
||||
usage = 0;
|
||||
if (opt->enableScale == 0) {
|
||||
memset(&srect, 0, sizeof(srect));
|
||||
srect.width = srcRgaBuffer.width;
|
||||
srect.height = srcRgaBuffer.height;
|
||||
|
||||
memset(&drect, 0, sizeof(drect));
|
||||
drect.x = dstRgaBuffer.width - srcRgaBuffer.width;
|
||||
drect.y = dstRgaBuffer.height - srcRgaBuffer.height;
|
||||
drect.width = srcRgaBuffer.width;
|
||||
drect.height = srcRgaBuffer.height;
|
||||
}
|
||||
usage = rkRotateType | rkMirrorType | IM_SYNC;
|
||||
ret = improcess(srcRgaBuffer, dstRgaBuffer, bRgbBuffer, srect, drect, prect, usage);
|
||||
if (ret != IM_STATUS_SUCCESS) {
|
||||
DISPLAY_LOGE("gfx improcess %{public}s", imStrError(ret));
|
||||
}
|
||||
} else if (rkBlendType == IM_ALPHA_BLEND_DST_OVER) {
|
||||
if (grallocFucs == NULL) {
|
||||
ret = GrallocInitialize(&grallocFucs);
|
||||
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Gralloc init failed"));
|
||||
}
|
||||
AllocInfo info = {
|
||||
.width = dstRgaBuffer.width,
|
||||
.height = dstRgaBuffer.height,
|
||||
.usage = HBM_USE_MEM_DMA | HBM_USE_CPU_READ | HBM_USE_CPU_WRITE,
|
||||
.format = PIXEL_FMT_RGBA_8888,//srcSurface->enColorFmt,
|
||||
};
|
||||
BufferHandle *buffer = NULL;
|
||||
|
||||
ret = grallocFucs->AllocMem(&info, &buffer);
|
||||
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not alloc memory"));
|
||||
|
||||
bRgbBuffer.width = dstRgaBuffer.width;
|
||||
bRgbBuffer.height = dstRgaBuffer.height;
|
||||
bRgbBuffer.wstride = dstRgaBuffer.wstride;
|
||||
bRgbBuffer.hstride = dstRgaBuffer.hstride;
|
||||
bRgbBuffer.format = RK_FORMAT_RGBA_8888;//srcRgaBuffer.format;
|
||||
bRgbBuffer.phy_addr = 0;//(void *) buffer->phyAddr;
|
||||
bRgbBuffer.vir_addr = 0;//buffer->virAddr;
|
||||
bRgbBuffer.color_space_mode = dstRgaBuffer.color_space_mode;
|
||||
bRgbBuffer.fd = (int32_t)buffer->phyAddr;
|
||||
memcpy(&prect, &drect, sizeof(drect));
|
||||
|
||||
ret = improcess(srcRgaBuffer, bRgbBuffer, dstRgaBuffer, srect, prect, drect, usage);
|
||||
if (ret != IM_STATUS_SUCCESS) {
|
||||
DISPLAY_LOGE("gfx improcess %{public}s", imStrError(ret));
|
||||
} else {
|
||||
ret = imcopy(bRgbBuffer, dstRgaBuffer);
|
||||
if (ret != IM_STATUS_SUCCESS) {
|
||||
DISPLAY_LOGE("gfx improcess %{public}s", imStrError(ret));
|
||||
}
|
||||
}
|
||||
grallocFucs->FreeMem(buffer);
|
||||
}
|
||||
} else {
|
||||
ret = improcess(srcRgaBuffer, dstRgaBuffer, bRgbBuffer, srect, drect, prect, usage);
|
||||
if (ret != IM_STATUS_SUCCESS) {
|
||||
DISPLAY_LOGE("gfx improcess %{public}s", imStrError(ret));
|
||||
}
|
||||
}
|
||||
if (ret != IM_STATUS_SUCCESS)
|
||||
return DISPLAY_FAILURE;
|
||||
else
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t rkBlit(ISurface *srcSurface, IRect *srcRect, ISurface *dstSurface, IRect *dstRect, GfxOpt *opt)
|
||||
{
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(srcSurface, DISPLAY_NULL_PTR);
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(srcRect, DISPLAY_NULL_PTR);
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(dstSurface, DISPLAY_NULL_PTR);
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(dstRect, DISPLAY_NULL_PTR);
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(opt, DISPLAY_NULL_PTR);
|
||||
|
||||
if (doFlit(srcSurface, srcRect, dstSurface, dstRect, opt) < 0)
|
||||
return DISPLAY_FAILURE;
|
||||
else
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t rkSync(int32_t timeOut)
|
||||
{
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t GfxInitialize(GfxFuncs **funcs)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((funcs == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("info is null"));
|
||||
GfxFuncs *gfxFuncs = (GfxFuncs *)malloc(sizeof(GfxFuncs));
|
||||
memset((void *)gfxFuncs, 0, sizeof(GfxFuncs));
|
||||
|
||||
gfxFuncs->InitGfx = rkInitGfx;
|
||||
gfxFuncs->DeinitGfx = rkDeinitGfx;
|
||||
gfxFuncs->FillRect = rkFillRect;
|
||||
gfxFuncs->Blit = rkBlit;
|
||||
gfxFuncs->Sync = rkSync;
|
||||
*funcs = gfxFuncs;
|
||||
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t GfxUninitialize(GfxFuncs *funcs)
|
||||
{
|
||||
CHECK_NULLPOINTER_RETURN_VALUE(funcs, DISPLAY_NULL_PTR);
|
||||
free(funcs);
|
||||
DISPLAY_LOGI("%s: gfx uninitialize success", __func__);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 "display_gralloc.h"
|
||||
#include <inttypes.h>
|
||||
#include <securec.h>
|
||||
#include "display_common.h"
|
||||
#include "display_gralloc_gbm.h"
|
||||
|
||||
int32_t AllocMem(const AllocInfo *info, BufferHandle **handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((info == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("info is null"));
|
||||
DISPLAY_CHK_RETURN((handle == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (info->usage & HBM_USE_MEM_DMA) {
|
||||
return GbmAllocMem(info, handle);
|
||||
}
|
||||
#endif
|
||||
DISPLAY_LOGE("the usage is not support 0x%{public}" PRIx64 "", info->usage);
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
void FreeMem(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((handle == NULL), DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (handle->usage & HBM_USE_MEM_DMA) {
|
||||
GbmFreeMem(handle);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void *Mmap(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((handle == NULL), NULL, DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (handle->usage & HBM_USE_MEM_DMA) {
|
||||
return GbmMmap(handle);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t Unmap(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((handle == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (handle->usage & HBM_USE_MEM_DMA) {
|
||||
return GbmUnmap(handle);
|
||||
}
|
||||
#endif
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
int32_t FlushCache(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((handle == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (handle->usage & HBM_USE_MEM_DMA) {
|
||||
return GbmFlushCache(handle);
|
||||
}
|
||||
#endif
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
int32_t InvalidateCache(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((handle == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("handle is null"));
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (handle->usage & HBM_USE_MEM_DMA) {
|
||||
return GbmInvalidateCache(handle);
|
||||
}
|
||||
#endif
|
||||
return DISPLAY_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
int32_t GrallocUninitialize(GrallocFuncs *funcs)
|
||||
{
|
||||
DISPLAY_CHK_RETURN(funcs == NULL, DISPLAY_PARAM_ERR, DISPLAY_LOGE("funcs is null"));
|
||||
DISPLAY_LOGD();
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
if (GbmGrallocUninitialize() != DISPLAY_SUCCESS) {
|
||||
DISPLAY_LOGE("gbm uninit failed");
|
||||
}
|
||||
#endif
|
||||
free(funcs);
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t GrallocInitialize(GrallocFuncs **funcs)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN((funcs == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("funcs is null"));
|
||||
GrallocFuncs *grallocFuncs = (GrallocFuncs *)malloc(sizeof(GrallocFuncs));
|
||||
DISPLAY_CHK_RETURN((grallocFuncs == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("memset_s failed"));
|
||||
errno_t eok = memset_s(grallocFuncs, sizeof(GrallocFuncs), 0, sizeof(GrallocFuncs));
|
||||
DISPLAY_CHK_RETURN((eok != EOK), DISPLAY_FAILURE, DISPLAY_LOGE("memset_s failed"));
|
||||
// initialize gbm gralloc
|
||||
#ifdef GRALLOC_GBM_SUPPORT
|
||||
int ret = GbmGrallocInitialize();
|
||||
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), ret, DISPLAY_LOGE("gbm initial"); free(grallocFuncs));
|
||||
#endif
|
||||
grallocFuncs->AllocMem = AllocMem;
|
||||
grallocFuncs->FreeMem = FreeMem;
|
||||
grallocFuncs->Mmap = Mmap;
|
||||
grallocFuncs->Unmap = Unmap;
|
||||
grallocFuncs->InvalidateCache = InvalidateCache;
|
||||
grallocFuncs->FlushCache = FlushCache;
|
||||
*funcs = grallocFuncs;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* 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 "display_gralloc_gbm.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
#include <xf86drm.h>
|
||||
#include <securec.h>
|
||||
#include "wayland_drm_auth_client.h"
|
||||
#include "drm_fourcc.h"
|
||||
#include "hisilicon_drm.h"
|
||||
#include "hi_gbm.h"
|
||||
#include "hdf_dlist.h"
|
||||
#include "display_gralloc_private.h"
|
||||
#include "display_common.h"
|
||||
|
||||
const char *g_drmFileNode = "/dev/dri/renderD128";
|
||||
static GrallocManager *g_grallocManager = NULL;
|
||||
static pthread_mutex_t g_lock;
|
||||
|
||||
typedef struct {
|
||||
uint32_t drmFormat;
|
||||
PixelFormat pixFormat;
|
||||
} PixelFormatConvertTbl;
|
||||
|
||||
typedef struct {
|
||||
uint32_t value;
|
||||
const char *str;
|
||||
} ValueStrMap;
|
||||
|
||||
static GrallocManager *GetGrallocManager()
|
||||
{
|
||||
if (g_grallocManager == NULL) {
|
||||
g_grallocManager = (GrallocManager *)malloc(sizeof(GrallocManager));
|
||||
errno_t eok = memset_s(g_grallocManager, sizeof(GrallocManager), 0, sizeof(GrallocManager));
|
||||
if (eok != EOK) {
|
||||
DISPLAY_LOGE("memset_s failed");
|
||||
}
|
||||
if (g_grallocManager == NULL) {
|
||||
DISPLAY_LOGE("gralloc manager malloc failed");
|
||||
}
|
||||
}
|
||||
return g_grallocManager;
|
||||
}
|
||||
|
||||
const char *GetPixelFmtStr(PixelFormat format)
|
||||
{
|
||||
static const ValueStrMap pixelStrMaps[] = {
|
||||
{PIXEL_FMT_CLUT8, "PIXEL_FMT_CLUT8"}, {PIXEL_FMT_CLUT1, "PIXEL_FMT_CLUT1"},
|
||||
{PIXEL_FMT_CLUT4, "PIXEL_FMT_CLUT4"}, {PIXEL_FMT_RGB_565, "PIXEL_FMT_RGB_565"},
|
||||
{PIXEL_FMT_RGBA_5658, "IXEL_FMT_RGBA_5658"}, {PIXEL_FMT_RGBX_4444, "PIXEL_FMT_RGBX_4444"},
|
||||
{PIXEL_FMT_RGBA_4444, "PIXEL_FMT_RGBA_4444"}, {PIXEL_FMT_RGB_444, "PIXEL_FMT_RGB_444"},
|
||||
{PIXEL_FMT_RGBX_5551, "PIXEL_FMT_RGBX_5551"}, {PIXEL_FMT_RGBA_5551, "PIXEL_FMT_RGBA_5551"},
|
||||
{PIXEL_FMT_RGB_555, "PIXEL_FMT_RGB_555"}, {PIXEL_FMT_RGBX_8888, "PIXEL_FMT_RGBX_8888"},
|
||||
{PIXEL_FMT_RGBA_8888, "PIXEL_FMT_RGBA_8888"}, {PIXEL_FMT_RGB_888, "PIXEL_FMT_RGB_888"},
|
||||
{PIXEL_FMT_BGR_565, "PIXEL_FMT_BGR_565"}, {PIXEL_FMT_BGRX_4444, "PIXEL_FMT_BGRX_4444"},
|
||||
{PIXEL_FMT_BGRA_4444, "PIXEL_FMT_BGRA_4444"}, {PIXEL_FMT_BGRX_5551, "PIXEL_FMT_BGRX_5551"},
|
||||
{PIXEL_FMT_BGRA_5551, "PIXEL_FMT_BGRA_5551"}, {PIXEL_FMT_BGRX_8888, "PIXEL_FMT_BGRX_8888"},
|
||||
{PIXEL_FMT_BGRA_8888, "PIXEL_FMT_BGRA_8888"}, {PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"},
|
||||
{PIXEL_FMT_YUV_422_I, "PIXEL_FMT_YUV_422_I"}, {PIXEL_FMT_YCBCR_422_SP, "PIXEL_FMT_YCBCR_422_SP"},
|
||||
{PIXEL_FMT_YCRCB_422_SP, "PIXEL_FMT_YCRCB_422_SP"}, {PIXEL_FMT_YCBCR_420_SP, "PIXEL_FMT_YCBCR_420_SP"},
|
||||
{PIXEL_FMT_YCRCB_420_SP, "PIXEL_FMT_YCRCB_420_SP"}, {PIXEL_FMT_YCBCR_422_P, "PIXEL_FMT_YCBCR_422_P"},
|
||||
{PIXEL_FMT_YCRCB_422_P, "PIXEL_FMT_YCRCB_422_P"}, {PIXEL_FMT_YCBCR_420_P, "PIXEL_FMT_YCBCR_420_P"},
|
||||
{PIXEL_FMT_YCRCB_420_P, "PIXEL_FMT_YCRCB_420_P"}, {PIXEL_FMT_YUYV_422_PKG, "PIXEL_FMT_YUYV_422_PKG"},
|
||||
{PIXEL_FMT_UYVY_422_PKG, "PIXEL_FMT_UYVY_422_PKG"}, {PIXEL_FMT_YVYU_422_PKG, "PIXEL_FMT_YVYU_422_PKG"},
|
||||
{PIXEL_FMT_VYUY_422_PKG, "PIXEL_FMT_VYUY_422_PKG"}, {PIXEL_FMT_BUTT, "PIXEL_FMT_BUTT"},
|
||||
};
|
||||
static const char *unknown = "unknown format";
|
||||
for (uint32_t i = 0; i < sizeof(pixelStrMaps) / sizeof(pixelStrMaps[0]); i++) {
|
||||
if (pixelStrMaps[i].value == format) {
|
||||
return pixelStrMaps[i].str;
|
||||
}
|
||||
}
|
||||
DISPLAY_LOGE("GetPixelFmtStr unknown format %{public}d", format);
|
||||
return unknown;
|
||||
}
|
||||
|
||||
const char *GetDrmFmtStr(uint32_t format)
|
||||
{
|
||||
static const ValueStrMap formatStrMaps[] = {
|
||||
{DRM_FORMAT_C8, "DRM_FORMAT_C8" }, {DRM_FORMAT_R8, "DRM_FORMAT_R8" },
|
||||
{DRM_FORMAT_R16, "DRM_FORMAT_R16"}, {DRM_FORMAT_RG88, "DRM_FORMAT_RG88"},
|
||||
{DRM_FORMAT_GR88, "DRM_FORMAT_GR88"}, {DRM_FORMAT_RG1616, "DRM_FORMAT_RG1616"},
|
||||
{DRM_FORMAT_GR1616, "DRM_FORMAT_GR1616"}, {DRM_FORMAT_RGB332, "DRM_FORMAT_RGB332"},
|
||||
{DRM_FORMAT_BGR233, "DRM_FORMAT_BGR233"}, {DRM_FORMAT_XRGB4444, "DRM_FORMAT_XRGB4444"},
|
||||
{DRM_FORMAT_XBGR4444, "DRM_FORMAT_XBGR4444"}, {DRM_FORMAT_RGBX4444, "DRM_FORMAT_RGBX4444"},
|
||||
{DRM_FORMAT_BGRX4444, "DRM_FORMAT_BGRX4444"}, {DRM_FORMAT_ARGB4444, "DRM_FORMAT_ARGB4444"},
|
||||
{DRM_FORMAT_ABGR4444, "DRM_FORMAT_ABGR4444"}, {DRM_FORMAT_RGBA4444, "DRM_FORMAT_RGBA4444"},
|
||||
{DRM_FORMAT_BGRA4444, "DRM_FORMAT_BGRA4444"}, {DRM_FORMAT_XRGB1555, "DRM_FORMAT_XRGB1555"},
|
||||
{DRM_FORMAT_XBGR1555, "DRM_FORMAT_XBGR1555"}, {DRM_FORMAT_RGBX5551, "DRM_FORMAT_RGBX5551"},
|
||||
{DRM_FORMAT_BGRX5551, "DRM_FORMAT_BGRX5551"}, {DRM_FORMAT_ARGB1555, "DRM_FORMAT_ARGB1555"},
|
||||
{DRM_FORMAT_ABGR1555, "DRM_FORMAT_ABGR1555"}, {DRM_FORMAT_RGBA5551, "DRM_FORMAT_RGBA5551"},
|
||||
{DRM_FORMAT_BGRA5551, "DRM_FORMAT_BGRA5551"}, {DRM_FORMAT_RGB565, "DRM_FORMAT_RGB565"},
|
||||
{DRM_FORMAT_BGR565, "DRM_FORMAT_BGR565"}, {DRM_FORMAT_RGB888, "DRM_FORMAT_RGB888"},
|
||||
{DRM_FORMAT_BGR888, "DRM_FORMAT_BGR888"}, {DRM_FORMAT_XRGB8888, "DRM_FORMAT_XRGB8888"},
|
||||
{DRM_FORMAT_XBGR8888, "DRM_FORMAT_XBGR8888"}, {DRM_FORMAT_RGBX8888, "DRM_FORMAT_RGBX8888"},
|
||||
{DRM_FORMAT_BGRX8888, "DRM_FORMAT_BGRX8888"}, {DRM_FORMAT_ARGB8888, "DRM_FORMAT_ARGB8888"},
|
||||
{DRM_FORMAT_ABGR8888, "DRM_FORMAT_ABGR8888"}, {DRM_FORMAT_RGBA8888, "DRM_FORMAT_RGBA8888"},
|
||||
{DRM_FORMAT_BGRA8888, "DRM_FORMAT_BGRA8888"}, {DRM_FORMAT_XRGB2101010, "DRM_FORMAT_XRGB2101010"},
|
||||
{DRM_FORMAT_BGRX1010102, "DRM_FORMAT_BGRX1010102"}, {DRM_FORMAT_ARGB2101010, "DRM_FORMAT_ARGB2101010"},
|
||||
{DRM_FORMAT_ABGR2101010, "DRM_FORMAT_ABGR2101010"}, {DRM_FORMAT_RGBA1010102, "DRM_FORMAT_RGBA1010102"},
|
||||
{DRM_FORMAT_YVYU, "DRM_FORMAT_YVYU"}, {DRM_FORMAT_UYVY, "DRM_FORMAT_UYVY"},
|
||||
{DRM_FORMAT_VYUY, "DRM_FORMAT_VYUY"}, {DRM_FORMAT_AYUV, "DRM_FORMAT_AYUV"},
|
||||
{DRM_FORMAT_NV12, "DRM_FORMAT_NV12"}, {DRM_FORMAT_NV21, "DRM_FORMAT_NV21"},
|
||||
{DRM_FORMAT_NV16, "DRM_FORMAT_NV16"}, {DRM_FORMAT_NV61, "DRM_FORMAT_NV61"},
|
||||
{DRM_FORMAT_NV24, "DRM_FORMAT_NV24"}, {DRM_FORMAT_NV42, "DRM_FORMAT_NV42"},
|
||||
{DRM_FORMAT_YUV410, "DRM_FORMAT_YUV410"}, {DRM_FORMAT_YVU410, "DRM_FORMAT_YVU410"},
|
||||
{DRM_FORMAT_YUV411, "DRM_FORMAT_YUV411"}, {DRM_FORMAT_YVU411, "DRM_FORMAT_YVU411"},
|
||||
{DRM_FORMAT_YUV420, "DRM_FORMAT_YUV420"}, {DRM_FORMAT_YVU420, "DRM_FORMAT_YVU420"},
|
||||
{DRM_FORMAT_YUV422, "DRM_FORMAT_YUV422"}, {DRM_FORMAT_YVU422, "DRM_FORMAT_YVU422"},
|
||||
{DRM_FORMAT_YUV444, "DRM_FORMAT_YUV444"}, {DRM_FORMAT_YVU444, "DRM_FORMAT_YVU444"},
|
||||
};
|
||||
|
||||
static const char *unknown = "unknown drm format";
|
||||
for (uint32_t i = 0; i < sizeof(formatStrMaps) / sizeof(formatStrMaps[0]); i++) {
|
||||
if (formatStrMaps[i].value == format) {
|
||||
return formatStrMaps[i].str;
|
||||
}
|
||||
}
|
||||
DISPLAY_LOGE("GetDrmFmtStr unknown format %{public}d", format);
|
||||
return unknown;
|
||||
}
|
||||
|
||||
static uint32_t ConvertFormatToDrm(PixelFormat fmtIn)
|
||||
{
|
||||
static const PixelFormatConvertTbl convertTable[] = {
|
||||
{DRM_FORMAT_RGBX8888, PIXEL_FMT_RGBX_8888}, {DRM_FORMAT_RGBA8888, PIXEL_FMT_RGBA_8888},
|
||||
{DRM_FORMAT_RGB888, PIXEL_FMT_RGB_888}, {DRM_FORMAT_RGB565, PIXEL_FMT_BGR_565},
|
||||
{DRM_FORMAT_BGRX4444, PIXEL_FMT_BGRX_4444}, {DRM_FORMAT_BGRA4444, PIXEL_FMT_BGRA_4444},
|
||||
{DRM_FORMAT_RGBA4444, PIXEL_FMT_RGBA_4444}, {DRM_FORMAT_RGBX4444, PIXEL_FMT_RGBX_4444},
|
||||
{DRM_FORMAT_BGRX5551, PIXEL_FMT_BGRX_5551}, {DRM_FORMAT_BGRA5551, PIXEL_FMT_BGRA_5551},
|
||||
{DRM_FORMAT_BGRX8888, PIXEL_FMT_BGRX_8888}, {DRM_FORMAT_BGRA8888, PIXEL_FMT_BGRA_8888},
|
||||
{DRM_FORMAT_NV12, PIXEL_FMT_YCBCR_420_SP}, {DRM_FORMAT_NV21, PIXEL_FMT_YCRCB_420_SP},
|
||||
{DRM_FORMAT_YUV420, PIXEL_FMT_YCBCR_420_P}, {DRM_FORMAT_YVU420, PIXEL_FMT_YCRCB_420_P},
|
||||
{DRM_FORMAT_NV16, PIXEL_FMT_YCBCR_422_SP}, {DRM_FORMAT_NV61, PIXEL_FMT_YCRCB_422_SP},
|
||||
{DRM_FORMAT_YUV422, PIXEL_FMT_YCBCR_422_P}, {DRM_FORMAT_YVU422, PIXEL_FMT_YCRCB_422_P},
|
||||
};
|
||||
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_LOGD("fmtIn %{public}d : %{public}s, outFmt %{public}d : %{public}s", fmtIn, GetPixelFmtStr(fmtIn), fmtOut,
|
||||
GetDrmFmtStr(fmtOut));
|
||||
return fmtOut;
|
||||
}
|
||||
|
||||
static uint64_t ConvertUsageToGbm(uint64_t inUsage)
|
||||
{
|
||||
uint64_t outUsage = GBM_BO_USE_TEXTURING;
|
||||
if (inUsage & HBM_USE_CPU_READ) {
|
||||
outUsage |= GBM_BO_USE_SW_READ_OFTEN;
|
||||
}
|
||||
if (inUsage & HBM_USE_CPU_WRITE) {
|
||||
outUsage |= GBM_BO_USE_SW_WRITE_OFTEN;
|
||||
}
|
||||
DISPLAY_LOGD("outUsage 0x%{public}" PRIx64 "", outUsage);
|
||||
return outUsage;
|
||||
}
|
||||
|
||||
static int32_t InitGbmDevice(const char *drmFile, GrallocManager *grallocManager)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
if (grallocManager->gbmDevice == NULL) {
|
||||
char path[PATH_MAX] = {0};
|
||||
if (realpath(drmFile, path) == NULL) {
|
||||
DISPLAY_LOGE(" drm File : %{public}s is not a realpath, errno: %{public}s", drmFile, strerror(errno));
|
||||
return DISPLAY_PARAM_ERR;
|
||||
}
|
||||
int drmFd = open(path, O_RDWR);
|
||||
if (drmFd < 0) {
|
||||
DISPLAY_LOGE("drm file:%{public}s open failed %{public}s", drmFile, strerror(errno));
|
||||
return DISPLAY_FD_ERR;
|
||||
}
|
||||
/*
|
||||
if (WaylandDrmAuth(drmFd) != AUTH_SCUCCESS) {
|
||||
DISPLAY_LOGE("drm authentication failed, may have no permission to allocate memory");
|
||||
}
|
||||
*/
|
||||
struct gbm_device *gbmDevice = hdi_gbm_create_device(drmFd);
|
||||
grallocManager->drmFd = drmFd;
|
||||
if (gbmDevice == NULL) {
|
||||
close(drmFd);
|
||||
grallocManager->drmFd = -1;
|
||||
DISPLAY_LOGE("gbm device create failed");
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
grallocManager->gbmDevice = gbmDevice;
|
||||
grallocManager->drmFd = drmFd;
|
||||
DListHeadInit(&grallocManager->gbmBoHead);
|
||||
}
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
static void DeInitGbmDevice(GrallocManager *grallocManager)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
hdi_gbm_device_destroy(grallocManager->gbmDevice);
|
||||
if (grallocManager->drmFd > 0) {
|
||||
close(grallocManager->drmFd);
|
||||
grallocManager->drmFd = -1;
|
||||
}
|
||||
grallocManager->gbmDevice = NULL;
|
||||
}
|
||||
|
||||
static int32_t DmaBufferSync(const BufferHandle *handle, bool start)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
struct dma_buf_sync syncPrm;
|
||||
errno_t eok = memset_s(&syncPrm, sizeof(syncPrm), 0, sizeof(syncPrm));
|
||||
DISPLAY_CHK_RETURN((eok != EOK), DISPLAY_PARAM_ERR, DISPLAY_LOGE("dma buffer sync memset_s failed"));
|
||||
|
||||
if (handle->usage & HBM_USE_CPU_WRITE) {
|
||||
syncPrm.flags |= DMA_BUF_SYNC_WRITE;
|
||||
}
|
||||
|
||||
if (handle->usage & HBM_USE_CPU_READ) {
|
||||
syncPrm.flags |= DMA_BUF_SYNC_READ;
|
||||
}
|
||||
|
||||
if (start) {
|
||||
syncPrm.flags |= DMA_BUF_SYNC_START;
|
||||
} else {
|
||||
syncPrm.flags |= DMA_BUF_SYNC_END;
|
||||
}
|
||||
int retry = 6;
|
||||
int ret;
|
||||
do {
|
||||
ret = ioctl(handle->fd, DMA_BUF_IOCTL_SYNC, &syncPrm);
|
||||
} while ((retry--) && (ret != -EAGAIN) && (ret != -EINTR));
|
||||
|
||||
if (ret < 0) {
|
||||
DISPLAY_LOGE("sync failed");
|
||||
return DISPLAY_SYS_BUSY;
|
||||
}
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
static void InitBufferHandle(struct gbm_bo *bo, int fd, const AllocInfo *info, PriBufferHandle *buffer)
|
||||
{
|
||||
BufferHandle *bufferHandle = &(buffer->hdl);
|
||||
bufferHandle->fd = fd;
|
||||
bufferHandle->reserveFds = 0;
|
||||
bufferHandle->reserveInts = 0;
|
||||
bufferHandle->stride = hdi_gbm_bo_get_stride(bo);
|
||||
bufferHandle->width = hdi_gbm_bo_get_width(bo);
|
||||
bufferHandle->height = hdi_gbm_bo_get_height(bo);
|
||||
bufferHandle->usage = info->usage;
|
||||
bufferHandle->format = info->format;
|
||||
bufferHandle->virAddr = NULL;
|
||||
bufferHandle->size = hdi_gbm_bo_get_stride(bo) * hdi_gbm_bo_get_height(bo);
|
||||
}
|
||||
|
||||
//static uint64_t GetPhysicalAddr(int fd, int primeFd)
|
||||
//{
|
||||
// struct DrmHisiliconPhyaddr args;
|
||||
// int ret;
|
||||
// DISPLAY_LOGD();
|
||||
// errno_t eok = memset_s(&args, sizeof(args), 0, sizeof(args));
|
||||
// DISPLAY_CHK_RETURN((eok != EOK), 0, DISPLAY_LOGE("memset_s failed"));
|
||||
// args.fd = primeFd;
|
||||
// ret = ioctl(fd, DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR, &args);
|
||||
// if (ret) {
|
||||
// DISPLAY_LOGE("DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR return failed");
|
||||
// }
|
||||
// DISPLAY_LOGD("DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR return %{public}d args.phyaddr %{public}llx", ret,
|
||||
// args.phyaddr);
|
||||
// return args.phyaddr;
|
||||
//}
|
||||
|
||||
int32_t GbmAllocMem(const AllocInfo *info, BufferHandle **buffer)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((info == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("info is null"));
|
||||
DISPLAY_CHK_RETURN((buffer == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("buffer is null"));
|
||||
PriBufferHandle *priBuffer = NULL;
|
||||
uint32_t drmFmt = ConvertFormatToDrm(info->format);
|
||||
DISPLAY_CHK_RETURN((drmFmt == INVALID_PIXEL_FMT), DISPLAY_NOT_SUPPORT,
|
||||
DISPLAY_LOGE("format %{public}d can not support", info->format));
|
||||
DISPLAY_LOGD("requeset width %{public}d, heigt %{public}d, format %{public}d", info->width, info->height, drmFmt);
|
||||
|
||||
GRALLOC_LOCK();
|
||||
GrallocManager *grallocManager = GetGrallocManager();
|
||||
DISPLAY_CHK_RETURN((grallocManager == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("gralloc manager failed");
|
||||
GRALLOC_UNLOCK());
|
||||
struct gbm_bo *bo =
|
||||
hdi_gbm_bo_create(grallocManager->gbmDevice, info->width, info->height, drmFmt, ConvertUsageToGbm(info->usage));
|
||||
DISPLAY_CHK_RETURN((bo == NULL), DISPLAY_NOMEM, DISPLAY_LOGE("gbm create bo failed"); GRALLOC_UNLOCK());
|
||||
|
||||
int fd = hdi_gbm_bo_get_fd(bo);
|
||||
DISPLAY_CHK_RETURN((fd < 0), DISPLAY_FD_ERR, DISPLAY_LOGE("gbm can not get fd"); hdi_gbm_bo_destroy(bo);
|
||||
GRALLOC_UNLOCK());
|
||||
|
||||
priBuffer = (PriBufferHandle *)malloc(sizeof(PriBufferHandle));
|
||||
DISPLAY_CHK_RETURN((priBuffer == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("bufferhandle malloc failed"); goto error);
|
||||
errno_t eok = memset_s(priBuffer, sizeof(PriBufferHandle), 0, sizeof(PriBufferHandle));
|
||||
DISPLAY_CHK_RETURN((eok != EOK), DISPLAY_PARAM_ERR, DISPLAY_LOGE("memset_s failed"); goto error);
|
||||
|
||||
InitBufferHandle(bo, fd, info, priBuffer);
|
||||
// priBuffer->hdl.phyAddr = GetPhysicalAddr(grallocManager->drmFd, fd);
|
||||
*buffer = &priBuffer->hdl;
|
||||
hdi_gbm_bo_destroy(bo);
|
||||
GRALLOC_UNLOCK();
|
||||
return DISPLAY_SUCCESS;
|
||||
error:
|
||||
close(fd);
|
||||
hdi_gbm_bo_destroy(bo);
|
||||
if (priBuffer != NULL) {
|
||||
free(priBuffer);
|
||||
}
|
||||
GRALLOC_UNLOCK();
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
|
||||
static void CloseBufferHandle(BufferHandle *handle)
|
||||
{
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((handle == NULL), DISPLAY_LOGE("buffer is null"));
|
||||
if (handle->fd >= 0) {
|
||||
close(handle->fd);
|
||||
handle->fd = -1;
|
||||
}
|
||||
const uint32_t reserveFds = handle->reserveFds;
|
||||
for (uint32_t i = 0; i < reserveFds; i++) {
|
||||
if (handle->reserve[i] >= 0) {
|
||||
close(handle->reserve[i]);
|
||||
handle->reserve[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GbmFreeMem(BufferHandle *buffer)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((buffer == NULL), DISPLAY_LOGE("buffer is null"));
|
||||
if ((buffer->virAddr != NULL) && (GbmUnmap(buffer) != DISPLAY_SUCCESS)) {
|
||||
DISPLAY_LOGE("freeMem unmap buffer failed");
|
||||
}
|
||||
CloseBufferHandle(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void *GbmMmap(BufferHandle *buffer)
|
||||
{
|
||||
void *virAddr = NULL;
|
||||
DISPLAY_LOGD();
|
||||
if (buffer == NULL) {
|
||||
DISPLAY_LOGE("gbmmap the buffer handle is NULL");
|
||||
return NULL;
|
||||
}
|
||||
if (buffer->virAddr != NULL) {
|
||||
DISPLAY_LOGD("the buffer has virtual addr");
|
||||
return buffer->virAddr;
|
||||
}
|
||||
virAddr = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer->fd, 0);
|
||||
if (virAddr == MAP_FAILED) {
|
||||
DISPLAY_LOGE("mmap failed errno %{public}s, fd : %{public}d", strerror(errno), buffer->fd);
|
||||
}
|
||||
buffer->virAddr = virAddr;
|
||||
return virAddr;
|
||||
}
|
||||
|
||||
int32_t GbmUnmap(BufferHandle *buffer)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
if (buffer == NULL) {
|
||||
DISPLAY_LOGE("gbmumap the buffer handle is null");
|
||||
return DISPLAY_NULL_PTR;
|
||||
}
|
||||
|
||||
if (buffer->virAddr == NULL) {
|
||||
DISPLAY_LOGE("virAddr is NULL , has not map the buffer");
|
||||
return DISPLAY_PARAM_ERR;
|
||||
}
|
||||
int ret = munmap(buffer->virAddr, buffer->size);
|
||||
if (ret != 0) {
|
||||
DISPLAY_LOGE("munmap failed err: %{public}s", strerror(errno));
|
||||
return DISPLAY_FAILURE;
|
||||
}
|
||||
buffer->virAddr = NULL;
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t GbmInvalidateCache(BufferHandle *buffer)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return DmaBufferSync(buffer, true);
|
||||
}
|
||||
|
||||
int32_t GbmFlushCache(BufferHandle *buffer)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
return DmaBufferSync(buffer, false);
|
||||
}
|
||||
|
||||
int32_t GbmGrallocUninitialize(void)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
GRALLOC_LOCK();
|
||||
GrallocManager *grallocManager = GetGrallocManager();
|
||||
DISPLAY_CHK_RETURN((grallocManager == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("gralloc manager failed");
|
||||
GRALLOC_UNLOCK());
|
||||
grallocManager->referCount--;
|
||||
if (grallocManager->referCount < 0) {
|
||||
DeInitGbmDevice(grallocManager);
|
||||
free(g_grallocManager);
|
||||
g_grallocManager = NULL;
|
||||
}
|
||||
GRALLOC_UNLOCK();
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t GbmGrallocInitialize(void)
|
||||
{
|
||||
DISPLAY_LOGD();
|
||||
GRALLOC_LOCK();
|
||||
GrallocManager *grallocManager = GetGrallocManager();
|
||||
DISPLAY_CHK_RETURN((grallocManager == NULL), DISPLAY_PARAM_ERR, DISPLAY_LOGE("gralloc manager failed");
|
||||
GRALLOC_UNLOCK());
|
||||
int ret = InitGbmDevice(g_drmFileNode, grallocManager);
|
||||
DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), ret, DISPLAY_LOGE("gralloc manager failed"); GRALLOC_UNLOCK());
|
||||
grallocManager->referCount++;
|
||||
GRALLOC_UNLOCK();
|
||||
return DISPLAY_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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_GBM_H
|
||||
#define DISPLAY_GRALLOC_GBM_H
|
||||
#include "display_type.h"
|
||||
#include "hdf_dlist.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
struct gbm_device *gbmDevice;
|
||||
int drmFd;
|
||||
struct DListHead gbmBoHead;
|
||||
int32_t referCount;
|
||||
} GrallocManager;
|
||||
|
||||
typedef struct {
|
||||
struct DListHead entry;
|
||||
struct gbm_bo *bo;
|
||||
int fd;
|
||||
} GbmBoList;
|
||||
|
||||
int32_t GbmAllocMem(const AllocInfo *info, BufferHandle **buffer);
|
||||
void GbmFreeMem(BufferHandle *buffer);
|
||||
void *GbmMmap(BufferHandle *buffer);
|
||||
int32_t GbmUnmap(BufferHandle *buffer);
|
||||
int32_t GbmInvalidateCache(BufferHandle *buffer);
|
||||
int32_t GbmFlushCache(BufferHandle *buffer);
|
||||
int32_t GbmGrallocUninitialize();
|
||||
int32_t GbmGrallocInitialize();
|
||||
|
||||
#ifdef GRALLOC_LOCK_DEBUG
|
||||
#define GRALLOC_LOCK(format, ...) \
|
||||
do { \
|
||||
HDF_LOGD("[%{public}s@%{public}s:%{public}d]" format "\n", __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
pthread_mutex_lock(&g_lock); \
|
||||
} while (0)
|
||||
|
||||
#define GRALLOC_UNLOCK(format, ...) \
|
||||
do { \
|
||||
HDF_LOGD("[%{public}s@%{public}s:%{public}d]" format "\n", __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
pthread_mutex_unlock(&g_lock); \
|
||||
} while (0)
|
||||
#else
|
||||
#define GRALLOC_LOCK(format, ...) \
|
||||
do { \
|
||||
pthread_mutex_lock(&g_lock); \
|
||||
} while (0)
|
||||
|
||||
#define GRALLOC_UNLOCK(format, ...) \
|
||||
do { \
|
||||
pthread_mutex_unlock(&g_lock); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DISPLAY_GRALLOC_GBM_H
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 "hi_gbm.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <securec.h>
|
||||
#include "display_common.h"
|
||||
#include "hi_gbm_internal.h"
|
||||
#ifdef ROCKCHIP_CMA
|
||||
#define ROCKCHIP_BO_CONTIG (1 << 0)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t numPlanes;
|
||||
uint32_t radio[MAX_PLANES];
|
||||
} PlaneLayoutInfo;
|
||||
|
||||
typedef struct {
|
||||
uint32_t format;
|
||||
uint32_t bitsPerPixel; // bits per pixel for first plane
|
||||
const PlaneLayoutInfo *planes;
|
||||
} FormatInfo;
|
||||
|
||||
static const PlaneLayoutInfo g_yuv420SPLayout = {
|
||||
.numPlanes = 2,
|
||||
.radio = { 4, 2 },
|
||||
};
|
||||
|
||||
static const PlaneLayoutInfo g_yuv420PLayout = {
|
||||
.numPlanes = 3,
|
||||
.radio = { 4, 1, 1 },
|
||||
};
|
||||
|
||||
static const PlaneLayoutInfo g_yuv422SPLayout = {
|
||||
.numPlanes = 2,
|
||||
.radio = { 4, 4 },
|
||||
};
|
||||
|
||||
static const PlaneLayoutInfo g_yuv422PLayout = {
|
||||
.numPlanes = 3,
|
||||
.radio = { 4, 2, 2 },
|
||||
};
|
||||
|
||||
static const FormatInfo *GetFormatInfo(uint32_t format)
|
||||
{
|
||||
static const FormatInfo fmtInfos[] = {
|
||||
{DRM_FORMAT_RGBX8888, 32, NULL}, {DRM_FORMAT_RGBA8888, 32, NULL},
|
||||
{DRM_FORMAT_BGRX8888, 32, NULL}, {DRM_FORMAT_BGRA8888, 32, NULL},
|
||||
{DRM_FORMAT_RGB888, 24, NULL}, {DRM_FORMAT_RGB565, 16, NULL},
|
||||
{DRM_FORMAT_BGRX4444, 16, NULL}, {DRM_FORMAT_BGRA4444, 16, NULL},
|
||||
{DRM_FORMAT_RGBA4444, 16, NULL}, {DRM_FORMAT_RGBX4444, 16, NULL},
|
||||
{DRM_FORMAT_BGRX5551, 16, NULL}, {DRM_FORMAT_BGRA5551, 16, NULL},
|
||||
{DRM_FORMAT_NV12, 8, &g_yuv420SPLayout}, {DRM_FORMAT_NV21, 8, &g_yuv420SPLayout},
|
||||
{DRM_FORMAT_NV16, 8, &g_yuv422SPLayout}, {DRM_FORMAT_NV61, 8, &g_yuv422SPLayout},
|
||||
{DRM_FORMAT_YUV420, 8, &g_yuv420PLayout}, {DRM_FORMAT_YVU420, 8, &g_yuv420PLayout},
|
||||
{DRM_FORMAT_YUV422, 8, &g_yuv422PLayout}, {DRM_FORMAT_YVU422, 8, &g_yuv422PLayout},
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(fmtInfos) / sizeof(FormatInfo); i++) {
|
||||
if (fmtInfos[i].format == format) {
|
||||
return &fmtInfos[i];
|
||||
}
|
||||
}
|
||||
DISPLAY_LOGE("the format can not support");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InitGbmBo(struct gbm_bo *bo, const struct drm_mode_create_dumb *dumb)
|
||||
{
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((dumb == NULL), DISPLAY_LOGE("dumb is null"));
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((bo == NULL), DISPLAY_LOGE("bo is null"));
|
||||
bo->stride = dumb->pitch;
|
||||
bo->size = dumb->size;
|
||||
bo->handle = dumb->handle;
|
||||
}
|
||||
|
||||
static uint32_t AdjustStrideFromFormat(uint32_t format, uint32_t height)
|
||||
{
|
||||
const FormatInfo *fmtInfo = GetFormatInfo(format);
|
||||
if ((fmtInfo != NULL) && (fmtInfo->planes != NULL)) {
|
||||
uint32_t sum = fmtInfo->planes->radio[0];
|
||||
for (uint32_t i = 1; (i < fmtInfo->planes->numPlanes) && (i < MAX_PLANES); i++) {
|
||||
sum += fmtInfo->planes->radio[i];
|
||||
}
|
||||
if (sum > 0) {
|
||||
height = DIV_ROUND_UP((height * sum), fmtInfo->planes->radio[0]);
|
||||
}
|
||||
DISPLAY_LOGD("height adjust to : %{public}d", height);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
struct gbm_bo *hdi_gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format,
|
||||
uint32_t usage)
|
||||
{
|
||||
DISPLAY_UNUSED(usage);
|
||||
int ret;
|
||||
struct gbm_bo *bo;
|
||||
struct drm_mode_create_dumb dumb = { 0 };
|
||||
const FormatInfo *fmtInfo = GetFormatInfo(format);
|
||||
DISPLAY_CHK_RETURN((fmtInfo == NULL), NULL, DISPLAY_LOGE("formt: 0x%{public}x can not get layout info", format));
|
||||
bo = (struct gbm_bo *)calloc(1, sizeof(struct gbm_bo));
|
||||
DISPLAY_CHK_RETURN((bo == NULL), NULL, DISPLAY_LOGE("gbm bo create fialed no memery"));
|
||||
(void)memset_s(bo, sizeof(struct gbm_bo), 0, sizeof(struct gbm_bo));
|
||||
bo->width = width;
|
||||
bo->height = height;
|
||||
bo->gbm = gbm;
|
||||
bo->format = format;
|
||||
// init create_dumb
|
||||
dumb.height = ALIGN_UP(height, HEIGHT_ALIGN);
|
||||
dumb.width = ALIGN_UP(AdjustStrideFromFormat(format, width), WIDTH_ALIGN);
|
||||
dumb.flags = 0;
|
||||
dumb.bpp = fmtInfo->bitsPerPixel;
|
||||
ret = drmIoctl(gbm->fd, DRM_IOCTL_MODE_CREATE_DUMB, &dumb);
|
||||
DISPLAY_LOGI("fmt 0x%{public}x create dumb width: %{public}d height: %{public}d bpp: %{public}u pitch %{public}d "
|
||||
"size %{public}llu",
|
||||
format, dumb.width, dumb.height, dumb.bpp, dumb.pitch, dumb.size);
|
||||
DISPLAY_CHK_RETURN((ret != 0), NULL, DISPLAY_LOGE("DRM_IOCTL_MODE_CREATE_DUMB failed errno %{public}d", errno));
|
||||
InitGbmBo(bo, &dumb);
|
||||
DISPLAY_LOGI(
|
||||
"fmt 0x%{public}x create dumb width: %{public}d height: %{public}d stride %{public}d size %{public}u", format,
|
||||
bo->width, bo->height, bo->stride, bo->size);
|
||||
return bo;
|
||||
}
|
||||
|
||||
struct gbm_device *hdi_gbm_create_device(int fd)
|
||||
{
|
||||
struct gbm_device *gbm;
|
||||
gbm = (struct gbm_device *)calloc(1, sizeof(struct gbm_device));
|
||||
DISPLAY_CHK_RETURN((gbm == NULL), NULL, DISPLAY_LOGE("memory calloc failed"));
|
||||
gbm->fd = fd;
|
||||
return gbm;
|
||||
}
|
||||
|
||||
void hdi_gbm_device_destroy(struct gbm_device *gbm)
|
||||
{
|
||||
free(gbm);
|
||||
}
|
||||
|
||||
uint32_t hdi_gbm_bo_get_stride(struct gbm_bo *bo)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
|
||||
return bo->stride;
|
||||
}
|
||||
|
||||
uint32_t hdi_gbm_bo_get_width(struct gbm_bo *bo)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
|
||||
return bo->width;
|
||||
}
|
||||
|
||||
uint32_t hdi_gbm_bo_get_height(struct gbm_bo *bo)
|
||||
{
|
||||
DISPLAY_CHK_RETURN((bo == NULL), 0, DISPLAY_LOGE("the bo is null"));
|
||||
return bo->height;
|
||||
}
|
||||
|
||||
void hdi_gbm_bo_destroy(struct gbm_bo *bo)
|
||||
{
|
||||
int ret;
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((bo == NULL), DISPLAY_LOGE("the bo is null"));
|
||||
struct drm_mode_destroy_dumb dumb = { 0 };
|
||||
dumb.handle = bo->handle;
|
||||
ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dumb);
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((ret), DISPLAY_LOGE("dumb buffer destroy failed errno %{public}d", errno));
|
||||
free(bo);
|
||||
}
|
||||
|
||||
int hdi_gbm_bo_get_fd(struct gbm_bo *bo)
|
||||
{
|
||||
int fd, ret;
|
||||
ret = drmPrimeHandleToFD(bo->gbm->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &fd);
|
||||
DISPLAY_CHK_RETURN((ret), -1,
|
||||
DISPLAY_LOGE("drmPrimeHandleToFD failed ret: %{public}d errno: %{public}d", ret, errno));
|
||||
return fd;
|
||||
}
|
||||
@@ -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 HI_GBM_H
|
||||
#define HI_GBM_H
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct gbm_device;
|
||||
struct gbm_bo;
|
||||
|
||||
enum gbm_bo_flags {
|
||||
/* *
|
||||
* Buffer is going to be presented to the screen using an API such as KMS
|
||||
*/
|
||||
GBM_BO_USE_SCANOUT = (1 << 0),
|
||||
/* *
|
||||
* Buffer is going to be used as cursor
|
||||
*/
|
||||
GBM_BO_USE_CURSOR = (1 << 1),
|
||||
/* *
|
||||
* Deprecated
|
||||
*/
|
||||
GBM_BO_USE_CURSOR_64X64 = GBM_BO_USE_CURSOR,
|
||||
/* *
|
||||
* Buffer is to be used for rendering - for example it is going to be used
|
||||
* as the storage for a color buffer
|
||||
*/
|
||||
GBM_BO_USE_RENDERING = (1 << 2),
|
||||
/* *
|
||||
* Deprecated
|
||||
*/
|
||||
GBM_BO_USE_WRITE = (1 << 3),
|
||||
/* *
|
||||
* Buffer is guaranteed to be laid out linearly in memory. That is, the
|
||||
* buffer is laid out as an array with 'height' blocks, each block with
|
||||
* length 'stride'. Each stride is in the same order as the rows of the
|
||||
* buffer. This is intended to be used with buffers that will be accessed
|
||||
* via dma-buf mmap().
|
||||
*/
|
||||
GBM_BO_USE_LINEAR = (1 << 4),
|
||||
/* *
|
||||
* The buffer will be used as a texture that will be sampled from.
|
||||
*/
|
||||
GBM_BO_USE_TEXTURING = (1 << 5),
|
||||
/* *
|
||||
* The buffer will be written to by a camera subsystem.
|
||||
*/
|
||||
GBM_BO_USE_CAMERA_WRITE = (1 << 6),
|
||||
/* *
|
||||
* The buffer will be read from by a camera subsystem.
|
||||
*/
|
||||
GBM_BO_USE_CAMERA_READ = (1 << 7),
|
||||
/* *
|
||||
* Buffer inaccessible to unprivileged users.
|
||||
*/
|
||||
GBM_BO_USE_PROTECTED = (1 << 8),
|
||||
/* *
|
||||
* These flags specify the frequency of software access. These flags do not
|
||||
* guarantee the buffer is linear, but do guarantee gbm_bo_map(..) will
|
||||
* present a linear view.
|
||||
*/
|
||||
GBM_BO_USE_SW_READ_OFTEN = (1 << 9),
|
||||
GBM_BO_USE_SW_READ_RARELY = (1 << 10),
|
||||
GBM_BO_USE_SW_WRITE_OFTEN = (1 << 11),
|
||||
GBM_BO_USE_SW_WRITE_RARELY = (1 << 12),
|
||||
/* *
|
||||
* The buffer will be written by a video decode accelerator.
|
||||
*/
|
||||
GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13),
|
||||
};
|
||||
|
||||
struct gbm_device *hdi_gbm_create_device(int fd);
|
||||
void hdi_gbm_device_destroy(struct gbm_device *gbm);
|
||||
struct gbm_bo *hdi_gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
|
||||
uint32_t hdi_gbm_bo_get_stride(struct gbm_bo *bo);
|
||||
uint32_t hdi_gbm_bo_get_width(struct gbm_bo *bo);
|
||||
uint32_t hdi_gbm_bo_get_height(struct gbm_bo *bo);
|
||||
void hdi_gbm_bo_destroy(struct gbm_bo *bo);
|
||||
int hdi_gbm_bo_get_fd(struct gbm_bo *bo);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif // HI_GBM_H
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 HI_GBM_INTERNEL_H
|
||||
#define HI_GBM_INTERNEL_H
|
||||
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
||||
#define ALIGN_UP(x, a) ((((x) + ((a)-1)) / (a)) * (a))
|
||||
#define HEIGHT_ALIGN 2U
|
||||
#define WIDTH_ALIGN 8U
|
||||
|
||||
#define MAX_PLANES 3
|
||||
|
||||
struct gbm_device {
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct gbm_bo {
|
||||
struct gbm_device *gbm;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
uint32_t handle;
|
||||
uint32_t stride;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
#endif // HI_GBM_INTERNEL_H
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 HISILICON_DRM_H
|
||||
#define HISILICON_DRM_H
|
||||
|
||||
#include "drm.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
#define DRM_HISILICON_GEM_FD_TO_PHYADDR 0x1
|
||||
|
||||
struct DrmHisiliconPhyaddr {
|
||||
/* * return the physical address */
|
||||
__u64 phyaddr;
|
||||
/* * dmabuf file descriptor */
|
||||
__s32 fd;
|
||||
};
|
||||
|
||||
#define DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR \
|
||||
DRM_IOWR(DRM_COMMAND_BASE + DRM_HISILICON_GEM_FD_TO_PHYADDR, struct DrmHisiliconPhyaddr)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HISILICON_DRM_H
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 "wayland_drm_auth_client.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "xf86drm.h"
|
||||
#include "wayland-client.h"
|
||||
#include "drm-auth-client-protocol.h"
|
||||
#include "display_common.h"
|
||||
|
||||
typedef struct {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
struct wl_drm_auth *drmAuth;
|
||||
enum wl_drm_auth_status authStatus;
|
||||
} WaylandDisplay;
|
||||
|
||||
const char *AUTH_INTERFACE_NAME = "wl_drm_auth";
|
||||
|
||||
static void AuthenticationStatus(void *data, struct wl_drm_auth *wlDrmAuth, uint32_t status)
|
||||
{
|
||||
(void)wlDrmAuth;
|
||||
DISPLAY_LOGD("AuthenticationStatus the status %{public}d", status);
|
||||
WaylandDisplay *display = data;
|
||||
display->authStatus = status;
|
||||
}
|
||||
|
||||
static const struct wl_drm_auth_listener g_drmAuthListener = { AuthenticationStatus };
|
||||
|
||||
static void RegistryHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
WaylandDisplay *display = data;
|
||||
DISPLAY_LOGD("interface global : %{public}s", interface);
|
||||
if (strcmp(interface, wl_drm_auth_interface.name) == 0) {
|
||||
display->drmAuth = wl_registry_bind(registry, id, &wl_drm_auth_interface, 1);
|
||||
wl_drm_auth_add_listener(display->drmAuth, &g_drmAuthListener, display);
|
||||
}
|
||||
}
|
||||
|
||||
static void RegistryHandleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name)
|
||||
{
|
||||
DISPLAY_LOGD("RegistryHandleGlobalRemove %{publuc}d name ", name);
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener g_registrListener = { RegistryHandleGlobal, RegistryHandleGlobalRemove };
|
||||
|
||||
void DeInitWaylandClient(WaylandDisplay *display)
|
||||
{
|
||||
DISPLAY_LOGD("DeInitWaylandClient");
|
||||
DISPLAY_CHK_RETURN_NOT_VALUE((display == NULL), DISPLAY_LOGD("display is NULL"));
|
||||
if (display->registry != NULL) {
|
||||
wl_registry_destroy(display->registry);
|
||||
}
|
||||
|
||||
if (display->display != NULL) {
|
||||
wl_display_flush(display->display);
|
||||
wl_display_disconnect(display->display);
|
||||
}
|
||||
free(display);
|
||||
}
|
||||
|
||||
WaylandDisplay *InitWaylandClient()
|
||||
{
|
||||
WaylandDisplay *dsp;
|
||||
int ret;
|
||||
dsp = calloc(1, sizeof(WaylandDisplay));
|
||||
DISPLAY_CHK_RETURN((dsp == NULL), NULL, DISPLAY_LOGE("can not alloc memory errno : %{public}d", errno));
|
||||
dsp->display = wl_display_connect(NULL);
|
||||
DISPLAY_CHK_RETURN((dsp->display == NULL), NULL, DISPLAY_LOGE("display connect failed, errno: %{public}d", errno);
|
||||
DeInitWaylandClient(dsp));
|
||||
dsp->registry = wl_display_get_registry(dsp->display);
|
||||
DISPLAY_CHK_RETURN((dsp->registry == NULL), NULL, DISPLAY_LOGE("can not get registry"); DeInitWaylandClient(dsp));
|
||||
ret = wl_registry_add_listener(dsp->registry, &g_registrListener, dsp);
|
||||
DISPLAY_CHK_RETURN((ret < 0), NULL, DISPLAY_LOGE("add listener failed"));
|
||||
wl_display_roundtrip(dsp->display); // for get registry
|
||||
wl_display_roundtrip(dsp->display); // for the listener will bind the service
|
||||
return dsp;
|
||||
}
|
||||
|
||||
int32_t WaylandDrmAuth(int drmFd)
|
||||
{
|
||||
WaylandDisplay *dsp;
|
||||
drm_magic_t magic;
|
||||
int ret;
|
||||
dsp = InitWaylandClient();
|
||||
DISPLAY_CHK_RETURN((dsp == NULL), AUTH_FAILED, DISPLAY_LOGE("init wayland client failed"));
|
||||
ret = drmGetMagic(drmFd, &magic);
|
||||
DISPLAY_CHK_RETURN((ret != 0), AUTH_FAILED, DISPLAY_LOGE("can not get magic"));
|
||||
DISPLAY_CHK_RETURN((dsp->drmAuth == NULL), AUTH_FAILED, DISPLAY_LOGE("drm auth service no find"));
|
||||
wl_drm_auth_authenticate(dsp->drmAuth, magic);
|
||||
wl_display_roundtrip(dsp->display); // wait for authenticate status return
|
||||
DISPLAY_LOGD("the status of authenticate is %{public}d", dsp->authStatus);
|
||||
if (dsp->authStatus == WL_DRM_AUTH_STATUS_SUCCESS) {
|
||||
ret = AUTH_SCUCCESS;
|
||||
}
|
||||
DeInitWaylandClient(dsp);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 WAYLAND_DRM_AUTH_CLIENT_H
|
||||
#define WAYLAND_DRM_AUTH_CLIENT_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
AUTH_SCUCCESS = 0, /* * authenticate sucess */
|
||||
AUTH_FAILED = 1 /* * authenticate failed */
|
||||
} AuthStatus;
|
||||
|
||||
/* *
|
||||
* @brief authenticate the drm fd
|
||||
*
|
||||
* it will connect to the wayland server, and will block to authenticate the drm fd, then disconnect the wayland
|
||||
*
|
||||
* @param display Indicates the pointer of wayland display
|
||||
*
|
||||
* @param drmFd Indicates the file descriptor of drm device
|
||||
*
|
||||
* @return Returns <b>AUTH_SCUCCESS</b> if the operation is successful else returns AUTH_FAILED
|
||||
* otherwise.
|
||||
* @since 1.0
|
||||
* @version 1.0
|
||||
*/
|
||||
int32_t WaylandDrmAuth(int drmFd);
|
||||
|
||||
#endif // WAYLAND_DRM_AUTH_CLIENT_H
|
||||
@@ -20,6 +20,14 @@ ohos_prebuilt_etc("init.rk3568.cfg") {
|
||||
install_enable = true
|
||||
}
|
||||
|
||||
ohos_prebuilt_executable("weston.cfg") {
|
||||
install_enable = true
|
||||
source = "weston.cfg"
|
||||
module_install_dir = "etc/init"
|
||||
install_images = [ "system" ]
|
||||
part_name = "rockchip_products"
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("init.rk3568.usb.cfg") {
|
||||
source = "init.rk3568.usb.cfg"
|
||||
install_images = [ "system" ]
|
||||
@@ -51,6 +59,7 @@ ohos_prebuilt_executable("display-hotplug.sh") {
|
||||
group("init_configs") {
|
||||
deps = [
|
||||
":display-hotplug.sh",
|
||||
":weston.cfg",
|
||||
":init.rk3568.cfg",
|
||||
":init.rk3568.usb.cfg",
|
||||
":init.cfg",
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"jobs" : [{
|
||||
"name" : "post-fs",
|
||||
"cmds" : [
|
||||
"start udevd_service",
|
||||
"sleep 1",
|
||||
"start mmi_uinput_service",
|
||||
"sleep 2",
|
||||
"export XDG_RUNTIME_DIR /data/weston",
|
||||
"export XKB_CONFIG_ROOT /etc/xkb",
|
||||
"export XKB_CONFIG_EXTRA_PATH /etc/xkb",
|
||||
"mkdir /data/weston",
|
||||
"chmod 777 /data/weston",
|
||||
"start weston",
|
||||
"trigger weston_start",
|
||||
"sleep 2",
|
||||
"exec /system/bin/udevadm trigger",
|
||||
"exec /system/bin/udevadm settle --timeout=30"
|
||||
]
|
||||
}
|
||||
],
|
||||
"services" : [{
|
||||
"name" : "weston",
|
||||
"path" : ["/system/bin/weston", "-c", "/system/etc/weston.ini", "-B", "drm-backend.so", "--tty=1"],
|
||||
"disabled" : 1
|
||||
}, {
|
||||
"name" : "hdi_weston",
|
||||
"path" : ["/system/bin/weston", "-c", "/system/etc/weston.ini", "-B", "hdi-backend.so"],
|
||||
"disabled" : 1
|
||||
}, {
|
||||
"name" : "mmi_uinput_service",
|
||||
"path" : ["/system/bin/uinput_inject"],
|
||||
"uid" : "root",
|
||||
"gid" : ["system", "shell", "uhid"]
|
||||
}, {
|
||||
"name" : "udevd_service",
|
||||
"path" : ["/system/bin/udevd"],
|
||||
"uid" : "root",
|
||||
"gid" : ["system"]
|
||||
}
|
||||
]
|
||||
}
|
||||
+31
-30
@@ -13,17 +13,11 @@
|
||||
import("//build/ohos.gni")
|
||||
import("//drivers/adapter/uhdf2/uhdf.gni")
|
||||
import("//drivers/peripheral/camera/hal/camera.gni")
|
||||
import("$hdf_framework_path/tools/hc-gen/hc_gen.gni")
|
||||
|
||||
action("build_camera_host_config") {
|
||||
script = "$hdf_framework_path/tools/hc-gen/build_hcs.py"
|
||||
hc_gen("build_camera_host_config") {
|
||||
sources = [ rebase_path(
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/hdi_impl/camera_host_config.hcs") ]
|
||||
outputs = [ "$target_gen_dir/config/hdi_impl/camera_host_config.hcb" ]
|
||||
args = [
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
sources[0],
|
||||
]
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("camera_host_config.hcb") {
|
||||
@@ -35,48 +29,55 @@ ohos_prebuilt_etc("camera_host_config.hcb") {
|
||||
part_name = "hdf"
|
||||
}
|
||||
|
||||
hc_gen_c("generate_source") {
|
||||
sources = [
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/config.hcs",
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/params.hcs",
|
||||
]
|
||||
}
|
||||
|
||||
action("copy_source") {
|
||||
script = "/usr/bin/env"
|
||||
outputs = [ "$target_out_dir/tmp.c" ] # no use, just for gn complains
|
||||
args = [
|
||||
"cp",
|
||||
"-f",
|
||||
]
|
||||
args += rebase_path(get_target_outputs(":generate_source"))
|
||||
args += [ rebase_path(
|
||||
"$camera_path/pipeline_core/pipeline_impl/src/strategy/config/") ]
|
||||
deps = [ ":generate_source" ]
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("config.c") {
|
||||
deps = [ ":copy_source" ]
|
||||
source =
|
||||
"$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c"
|
||||
exec_script(
|
||||
"//drivers/framework/tools/hc-gen/build_hcs.py",
|
||||
"/usr/bin/env",
|
||||
[
|
||||
"-o",
|
||||
"touch",
|
||||
rebase_path(
|
||||
"$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c"),
|
||||
"-t",
|
||||
rebase_path(
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/config.hcs"),
|
||||
],
|
||||
"")
|
||||
])
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("params.c") {
|
||||
deps = [ ":copy_source" ]
|
||||
source =
|
||||
"$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c"
|
||||
exec_script(
|
||||
"//drivers/framework/tools/hc-gen/build_hcs.py",
|
||||
"/usr/bin/env",
|
||||
[
|
||||
"-o",
|
||||
"touch",
|
||||
rebase_path(
|
||||
"$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c"),
|
||||
"-t",
|
||||
rebase_path(
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/params.hcs"),
|
||||
],
|
||||
"")
|
||||
])
|
||||
}
|
||||
|
||||
action("build_ipp_algo_config") {
|
||||
script = "$hdf_framework_path/tools/hc-gen/build_hcs.py"
|
||||
hc_gen("build_ipp_algo_config") {
|
||||
sources = [ rebase_path(
|
||||
"$camera_product_name_path/hdf_config/uhdf/camera/pipeline_core/ipp_algo_config.hcs") ]
|
||||
outputs = [ "$target_gen_dir/pipeline_core/ipp_algo_config.hcb" ]
|
||||
args = [
|
||||
"-o",
|
||||
rebase_path(outputs[0]),
|
||||
sources[0],
|
||||
]
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("ipp_algo_config.hcb") {
|
||||
|
||||
Reference in New Issue
Block a user