modeset-atomic-plane.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. uint32_t property_fb_id;
  84. uint32_t property_crtc_x;
  85. uint32_t property_crtc_y;
  86. uint32_t property_crtc_w;
  87. uint32_t property_crtc_h;
  88. uint32_t property_src_x;
  89. uint32_t property_src_y;
  90. uint32_t property_src_w;
  91. uint32_t property_src_h;
  92. fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
  93. res = drmModeGetResources(fd);
  94. crtc_id = res->crtcs[0];
  95. conn_id = res->connectors[0];
  96. drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
  97. plane_res = drmModeGetPlaneResources(fd);
  98. plane_id = plane_res->planes[0];
  99. conn = drmModeGetConnector(fd, conn_id);
  100. buf.width = conn->modes[0].hdisplay;
  101. buf.height = conn->modes[0].vdisplay;
  102. modeset_create_fb(fd, &buf);
  103. drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
  104. props = drmModeObjectGetProperties(fd, conn_id, DRM_MODE_OBJECT_CONNECTOR);
  105. property_crtc_id = get_property_id(fd, props, "CRTC_ID");
  106. drmModeFreeObjectProperties(props);
  107. props = drmModeObjectGetProperties(fd, crtc_id, DRM_MODE_OBJECT_CRTC);
  108. property_active = get_property_id(fd, props, "ACTIVE");
  109. property_mode_id = get_property_id(fd, props, "MODE_ID");
  110. drmModeFreeObjectProperties(props);
  111. drmModeCreatePropertyBlob(fd, &conn->modes[0],
  112. sizeof(conn->modes[0]), &blob_id);
  113. req = drmModeAtomicAlloc();
  114. drmModeAtomicAddProperty(req, crtc_id, property_active, 1);
  115. drmModeAtomicAddProperty(req, crtc_id, property_mode_id, blob_id);
  116. drmModeAtomicAddProperty(req, conn_id, property_crtc_id, crtc_id);
  117. drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
  118. drmModeAtomicFree(req);
  119. printf("drmModeAtomicCommit SetCrtc\n");
  120. getchar();
  121. props = drmModeObjectGetProperties(fd, plane_id, DRM_MODE_OBJECT_PLANE);
  122. property_crtc_id = get_property_id(fd, props, "CRTC_ID");
  123. property_fb_id = get_property_id(fd, props, "FB_ID");
  124. property_crtc_x = get_property_id(fd, props, "CRTC_X");
  125. property_crtc_y = get_property_id(fd, props, "CRTC_Y");
  126. property_crtc_w = get_property_id(fd, props, "CRTC_W");
  127. property_crtc_h = get_property_id(fd, props, "CRTC_H");
  128. property_src_x = get_property_id(fd, props, "SRC_X");
  129. property_src_y = get_property_id(fd, props, "SRC_Y");
  130. property_src_w = get_property_id(fd, props, "SRC_W");
  131. property_src_h = get_property_id(fd, props, "SRC_H");
  132. drmModeFreeObjectProperties(props);
  133. req = drmModeAtomicAlloc();
  134. drmModeAtomicAddProperty(req, plane_id, property_crtc_id, crtc_id);
  135. drmModeAtomicAddProperty(req, plane_id, property_fb_id, buf.fb_id);
  136. drmModeAtomicAddProperty(req, plane_id, property_crtc_x, 50);
  137. drmModeAtomicAddProperty(req, plane_id, property_crtc_y, 50);
  138. drmModeAtomicAddProperty(req, plane_id, property_crtc_w, 320);
  139. drmModeAtomicAddProperty(req, plane_id, property_crtc_h, 320);
  140. drmModeAtomicAddProperty(req, plane_id, property_src_x, 0);
  141. drmModeAtomicAddProperty(req, plane_id, property_src_y, 0);
  142. drmModeAtomicAddProperty(req, plane_id, property_src_w, 320 << 16);
  143. drmModeAtomicAddProperty(req, plane_id, property_src_h, 320 << 16);
  144. //memset(buf.vaddr, 0x0f, buf.size);
  145. drmModeAtomicCommit(fd, req, 0, NULL);
  146. drmModeAtomicFree(req);
  147. printf("drmModeAtomicCommit SetPlane\n");
  148. getchar();
  149. modeset_destroy_fb(fd, &buf);
  150. drmModeFreeConnector(conn);
  151. drmModeFreePlaneResources(plane_res);
  152. drmModeFreeResources(res);
  153. close(fd);
  154. return 0;
  155. }