modeset-atomic-crtc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #define _GNU_SOURCE
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <stdbool.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/mman.h>
  10. #include <time.h>
  11. #include <unistd.h>
  12. #include <xf86drm.h>
  13. #include <xf86drmMode.h>
  14. struct buffer_object {
  15. uint32_t width;
  16. uint32_t height;
  17. uint32_t pitch;
  18. uint32_t handle;
  19. uint32_t size;
  20. uint8_t *vaddr;
  21. uint32_t fb_id;
  22. };
  23. struct buffer_object buf;
  24. static int modeset_create_fb(int fd, struct buffer_object *bo)
  25. {
  26. struct drm_mode_create_dumb create = {};
  27. struct drm_mode_map_dumb map = {};
  28. create.width = bo->width;
  29. create.height = bo->height;
  30. create.bpp = 32;
  31. drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
  32. bo->pitch = create.pitch;
  33. bo->size = create.size;
  34. bo->handle = create.handle;
  35. // {24, 32}
  36. drmModeAddFB(fd, bo->width, bo->height, 32, 32, bo->pitch,
  37. bo->handle, &bo->fb_id);
  38. map.handle = create.handle;
  39. drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
  40. bo->vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,
  41. MAP_SHARED, fd, map.offset);
  42. memset(bo->vaddr, 0xff, bo->size);
  43. return 0;
  44. }
  45. static void modeset_destroy_fb(int fd, struct buffer_object *bo)
  46. {
  47. struct drm_mode_destroy_dumb destroy = {};
  48. drmModeRmFB(fd, bo->fb_id);
  49. munmap(bo->vaddr, bo->size);
  50. destroy.handle = bo->handle;
  51. drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
  52. }
  53. static uint32_t get_property_id(int fd, drmModeObjectProperties *props,
  54. const char *name)
  55. {
  56. drmModePropertyPtr property;
  57. uint32_t i, id = 0;
  58. for (i = 0; i < props->count_props; i++) {
  59. property = drmModeGetProperty(fd, props->props[i]);
  60. if (!strcmp(property->name, name))
  61. id = property->prop_id;
  62. drmModeFreeProperty(property);
  63. if (id)
  64. break;
  65. }
  66. return id;
  67. }
  68. int main(int argc, char **argv)
  69. {
  70. int fd;
  71. drmModeConnector *conn;
  72. drmModeRes *res;
  73. drmModePlaneRes *plane_res;
  74. drmModeObjectProperties *props;
  75. drmModeAtomicReq *req;
  76. uint32_t conn_id;
  77. uint32_t crtc_id;
  78. uint32_t plane_id;
  79. uint32_t blob_id;
  80. uint32_t property_crtc_id;
  81. uint32_t property_mode_id;
  82. uint32_t property_active;
  83. fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
  84. res = drmModeGetResources(fd);
  85. crtc_id = res->crtcs[0];
  86. conn_id = res->connectors[0];
  87. drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
  88. plane_res = drmModeGetPlaneResources(fd);
  89. plane_id = plane_res->planes[0];
  90. conn = drmModeGetConnector(fd, conn_id);
  91. buf.width = conn->modes[0].hdisplay;
  92. buf.height = conn->modes[0].vdisplay;
  93. modeset_create_fb(fd, &buf);
  94. drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
  95. props = drmModeObjectGetProperties(fd, conn_id, DRM_MODE_OBJECT_CONNECTOR);
  96. property_crtc_id = get_property_id(fd, props, "CRTC_ID");
  97. drmModeFreeObjectProperties(props);
  98. props = drmModeObjectGetProperties(fd, crtc_id, DRM_MODE_OBJECT_CRTC);
  99. property_active = get_property_id(fd, props, "ACTIVE");
  100. property_mode_id = get_property_id(fd, props, "MODE_ID");
  101. drmModeFreeObjectProperties(props);
  102. drmModeCreatePropertyBlob(fd, &conn->modes[0],
  103. sizeof(conn->modes[0]), &blob_id);
  104. req = drmModeAtomicAlloc();
  105. drmModeAtomicAddProperty(req, crtc_id, property_active, 1);
  106. drmModeAtomicAddProperty(req, crtc_id, property_mode_id, blob_id);
  107. drmModeAtomicAddProperty(req, conn_id, property_crtc_id, crtc_id);
  108. drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
  109. drmModeAtomicFree(req);
  110. printf("drmModeAtomicCommit SetCrtc\n");
  111. getchar();
  112. drmModeSetPlane(fd, plane_id, crtc_id, buf.fb_id, 0,
  113. 50, 50, 320, 320,
  114. 0, 0, 320 << 16, 320 << 16);
  115. printf("drmModeSetPlane\n");
  116. getchar();
  117. modeset_destroy_fb(fd, &buf);
  118. drmModeFreeConnector(conn);
  119. drmModeFreePlaneResources(plane_res);
  120. drmModeFreeResources(res);
  121. close(fd);
  122. return 0;
  123. }