modeset-single-buffer.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. #include <signal.h>
  15. struct buffer_object {
  16. uint32_t width;
  17. uint32_t height;
  18. uint32_t pitch;
  19. uint32_t handle;
  20. uint32_t size;
  21. uint8_t *vaddr;
  22. uint32_t fb_id;
  23. };
  24. struct buffer_object buf;
  25. static int modeset_create_fb(int fd, struct buffer_object *bo)
  26. {
  27. struct drm_mode_create_dumb create = {};
  28. struct drm_mode_map_dumb map = {};
  29. create.width = bo->width;
  30. create.height = bo->height;
  31. create.bpp = 32;
  32. drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
  33. bo->pitch = create.pitch;
  34. bo->size = create.size;
  35. bo->handle = create.handle;
  36. // {24, 32}
  37. drmModeAddFB(fd, bo->width, bo->height, 32, 32, bo->pitch,
  38. bo->handle, &bo->fb_id);
  39. map.handle = create.handle;
  40. drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
  41. bo->vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,
  42. MAP_SHARED, fd, map.offset);
  43. //memset(bo->vaddr, 0xff, bo->size);
  44. int i =0;
  45. for (i=0;i<bo->size;i+=4) {
  46. bo->vaddr[i] = 0x0F;
  47. bo->vaddr[i+1] = 0x00;
  48. bo->vaddr[i+2] = 0xF0;
  49. bo->vaddr[i+3] = 0x00;
  50. }
  51. return 0;
  52. }
  53. static void modeset_destroy_fb(int fd, struct buffer_object *bo)
  54. {
  55. struct drm_mode_destroy_dumb destroy = {};
  56. drmModeRmFB(fd, bo->fb_id);
  57. munmap(bo->vaddr, bo->size);
  58. destroy.handle = bo->handle;
  59. drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
  60. }
  61. static int terminate = 0;
  62. static void sigint_handler(int arg)
  63. {
  64. terminate = 1;
  65. }
  66. int main(int argc, char **argv)
  67. {
  68. int fd;
  69. drmModeConnector *conn;
  70. drmModeRes *res;
  71. uint32_t conn_id;
  72. uint32_t crtc_id;
  73. int ret = -1;
  74. int i =0;
  75. signal(SIGINT, sigint_handler);
  76. fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
  77. res = drmModeGetResources(fd);
  78. crtc_id = res->crtcs[0];
  79. conn_id = res->connectors[0];
  80. conn = drmModeGetConnector(fd, conn_id);
  81. buf.width = conn->modes[0].hdisplay;
  82. buf.height = conn->modes[0].vdisplay;
  83. modeset_create_fb(fd, &buf);
  84. ret = drmModeSetCrtc(fd, crtc_id, buf.fb_id,
  85. 0, 0, &conn_id, 1, &conn->modes[0]);
  86. if (ret) {
  87. fprintf(stderr, "cannot set CRTC for connector %u (%d): %m\n",
  88. crtc_id, errno);
  89. }
  90. getchar();
  91. uint32_t cnt = 10;
  92. uint8_t v1 = 0xFF;
  93. uint8_t v2 = 0x00;
  94. uint8_t v3 = 0x00;
  95. uint8_t v4 = 0x00;
  96. while (!terminate && cnt--) {
  97. for (i=0;i<buf.size;i+=4) {
  98. #if 0
  99. if (cnt % 2) {
  100. buf.vaddr[i] = 0x0F;
  101. buf.vaddr[i+1] = 0x00;
  102. buf.vaddr[i+2] = 0x00;
  103. buf.vaddr[i+3] = 0xFF;
  104. } else {
  105. buf.vaddr[i] = 0x00;
  106. buf.vaddr[i+1] = 0xF0;
  107. buf.vaddr[i+2] = 0xFF;
  108. buf.vaddr[i+3] = 0x00;
  109. }
  110. #else
  111. buf.vaddr[i] = v1 - cnt * 20;
  112. buf.vaddr[i+1] = v2 + cnt * 20;
  113. buf.vaddr[i+2] = v3;
  114. buf.vaddr[i+3] = v4;
  115. #endif
  116. }
  117. sleep(1);
  118. }
  119. modeset_destroy_fb(fd, &buf);
  120. drmModeFreeConnector(conn);
  121. drmModeFreeResources(res);
  122. close(fd);
  123. return 0;
  124. }