Qt在ARM中,如何使用drmModeObjectSetProperty 设置 Plane 的 zpos 值

在 Qt 中直接使用 drmModeObjectSetProperty 设置 Plane 的 zpos 值需要结合 Linux DRM/KMS API 和 Qt 的底层窗口系统(如 eglfs 平台插件)。以下是详细步骤和代码示例:

1. 原理说明

  • DRM/KMS 基础

    • Plane:负责图层合成(如 Overlay、Primary、Cursor Plane)。

    • zpos 属性:控制 Plane 的层级顺序(值越大,显示越靠前)。

  • Qt 与 DRM:Qt 的 eglfs 平台插件默认使用 DRM/KMS 渲染,但未直接暴露 Plane 控制接口,需通过 libdrm 直接操作。

2. 准备工作

2.1 添加依赖

确保项目包含 libdrm 头文件和库:

# 安装 libdrm 开发包(Debian/Ubuntu)

sudo apt-get install libdrm-dev

在 .pro 文件中链接库:

qmake

LIBS += -ldrm

2.2 权限配置

确保应用程序有权访问 /dev/dri/card* 设备:

sudo usermod -aG video your_username # 将用户加入 video 组

3.  完整示例

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <xf86drm.h>
#include <xf86drmMode.h>

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);

    // 1. 打开 DRM 设备
    int drm_fd = openDrmDevice();
    if (drm_fd < 0) {
        qFatal("Failed to open DRM device");
    }

    // 2. 获取 Plane 资源
    drmModePlaneResPtr plane_res = drmModeGetPlaneResources(drm_fd);
    if (!plane_res) {
        close(drm_fd);
        qFatal("Failed to get plane resources");
    }

    // 3. 遍历所有 Plane,查找可设置 zpos 的 Plane
    for (uint32_t i = 0; i < plane_res->count_planes; i++) {
        drmModePlanePtr plane = drmModeGetPlane(drm_fd, plane_res->planes[i]);
        if (!plane) continue;

        // 4. 查找 zpos 属性 ID
        uint32_t zpos_prop_id = findZposPropertyId(drm_fd, plane);
        if (zpos_prop_id) {
            // 5. 设置 zpos 值(示例:设置为最大值)
            if (setPlaneZpos(drm_fd, plane->plane_id, zpos_prop_id, 255)) {
                qDebug() << "Successfully set zpos for plane" << plane->plane_id;
            } else {
                qWarning() << "Failed to set zpos for plane" << plane->plane_id;
            }
        }

        drmModeFreePlane(plane);
    }

    // 6. 清理资源
    drmModeFreePlaneResources(plane_res);
    close(drm_fd);

    // 启动 Qt 应用
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

5. 关键注意事项

  1. Qt 平台插件选择

    • 运行应用时指定 eglfs 平台:

      ./your_app -platform eglfs

    • 确保 Qt 编译时启用了 eglfs 支持。

  2. Plane 类型限制

    • 仅支持 DRM_PLANE_TYPE_OVERLAY 或 DRM_PLANE_TYPE_PRIMARY 类型的 Plane。

    • 通过 drmModeGetPlane 检查 plane->possible_crtcs 确认 Plane 是否可用。

  3. 属性兼容性

    • 不同硬件(如 i.MX6、Rockchip、Intel)的 DRM 驱动可能对 zpos 的支持不同,需查阅硬件文档。

    • 使用 drmModeGetProperty 检查属性是否可写(prop->flags & DRM_MODE_PROP_RANGE)。

  4. 时序控制

    • 在 Qt 窗口初始化完成后操作 Plane,避免与 Qt 内部 DRM 调用冲突。

    • 若动态调整 zpos,需通过信号/槽机制在合适的时机触发。

以下是使用Processing绘制泰森多面体的示例代码: ``` int numPoints = 200; //生成点的数量 float[] xPos = new float[numPoints]; //存储点的X坐标 float[] yPos = new float[numPoints]; //存储点的Y坐标 float[] zPos = new float[numPoints]; //存储点的Z坐标 int[][] triPoints; //存储三角形面的点索引 int numTris = 0; //三角形面的数量 float size = 200; //正方体的大小 void setup() { size(600, 600, P3D); smooth(); generatePoints(); generateTris(); } void draw() { background(255); translate(width/2, height/2, -500); rotateY(map(mouseX, 0, width, -PI, PI)); rotateX(map(mouseY, 0, height, -PI, PI)); fill(0, 150, 200); stroke(0); for (int i = 0; i < numTris; i++) { beginShape(TRIANGLE); vertex(xPos[triPoints[i][0]], yPos[triPoints[i][0]], zPos[triPoints[i][0]]); vertex(xPos[triPoints[i][1]], yPos[triPoints[i][1]], zPos[triPoints[i][1]]); vertex(xPos[triPoints[i][2]], yPos[triPoints[i][2]], zPos[triPoints[i][2]]); endShape(); } } //生成随机点 void generatePoints() { for (int i = 0; i < numPoints; i++) { xPos[i] = random(-size/2, size/2); yPos[i] = random(-size/2, size/2); zPos[i] = random(-size/2, size/2); } } //生成泰森多面体 void generateTris() { Delaunay d = new Delaunay(xPos, yPos, zPos); triPoints = d.getTriangles(); numTris = triPoints.length; } ``` 在这个示例中,我们使用了Delaunay库来生成泰森多面体的三角形面。首先,我们生成了一些随机点,并将它们传递给Delaunay对象。然后,我们使用getTriangles()方法获取所有的三角形面,并将它们存储在triPoints数组中。在draw()函数中,我们遍历所有的三角形面,并使用beginShape()和endShape()方法来绘制它们。最后,我们使用translate()和rotate()方法来控制视角。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千笺客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值