GraphicsBitmap.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "GraphicsBitmap.h"
  2. #ifdef KERNEL
  3. #include <Kernel/Process.h>
  4. #include <Kernel/MemoryManager.h>
  5. #include <WindowServer/WSMessageLoop.h>
  6. #endif
  7. #ifdef USERLAND
  8. #include <sys/mman.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <stdio.h>
  13. #endif
  14. RetainPtr<GraphicsBitmap> GraphicsBitmap::create(const Size& size)
  15. {
  16. return adopt(*new GraphicsBitmap(size));
  17. }
  18. GraphicsBitmap::GraphicsBitmap(const Size& size)
  19. : m_size(size)
  20. , m_pitch(size.width() * sizeof(RGBA32))
  21. {
  22. #ifdef KERNEL
  23. Syscall::SC_mmap_params params;
  24. memset(&params, 0, sizeof(params));
  25. params.fd = 0;
  26. params.prot = PROT_READ | PROT_WRITE;
  27. params.flags = MAP_ANONYMOUS | MAP_PRIVATE;
  28. params.size = size.area() * sizeof(RGBA32);
  29. params.offset = 0;
  30. m_data = (RGBA32*)current->sys$mmap(&params);
  31. ASSERT(m_data && m_data != (void*)-1);
  32. m_mmaped = true;
  33. #endif
  34. }
  35. RetainPtr<GraphicsBitmap> GraphicsBitmap::create_wrapper(const Size& size, RGBA32* data)
  36. {
  37. return adopt(*new GraphicsBitmap(size, data));
  38. }
  39. RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(const String& path, const Size& size)
  40. {
  41. RGBA32* mapped_data = nullptr;
  42. #ifdef USERLAND
  43. int fd = open(path.characters(), O_RDONLY, 0644);
  44. if (fd < 0) {
  45. dbgprintf("open(%s) got fd=%d, failed: %s\n", path.characters(), fd, strerror(errno));
  46. perror("open");
  47. return nullptr;
  48. }
  49. mapped_data = (RGBA32*)mmap(nullptr, size.area() * 4, PROT_READ, MAP_SHARED, fd, 0);
  50. if (mapped_data == MAP_FAILED) {
  51. int rc = close(fd);
  52. ASSERT(rc == 0);
  53. return nullptr;
  54. }
  55. #else
  56. int error;
  57. auto descriptor = VFS::the().open(path, error, 0, 0, *VFS::the().root_inode());
  58. if (!descriptor) {
  59. kprintf("Failed to load GraphicsBitmap from file (%s)\n", path.characters());
  60. return nullptr;
  61. }
  62. auto* region = WSMessageLoop::the().server_process().allocate_file_backed_region(LinearAddress(), size.area() * 4, descriptor->inode(), ".rgb file", /*readable*/true, /*writable*/false);
  63. mapped_data = (RGBA32*)region->laddr().get();
  64. #endif
  65. #ifdef USERLAND
  66. int rc = close(fd);
  67. ASSERT(rc == 0);
  68. #endif
  69. auto bitmap = create_wrapper(size, mapped_data);
  70. #ifdef KERNEL
  71. bitmap->m_server_region = region;
  72. #else
  73. bitmap->m_mmaped = true;
  74. #endif
  75. return bitmap;
  76. }
  77. GraphicsBitmap::GraphicsBitmap(const Size& size, RGBA32* data)
  78. : m_size(size)
  79. , m_data(data)
  80. , m_pitch(size.width() * sizeof(RGBA32))
  81. {
  82. }
  83. RetainPtr<GraphicsBitmap> GraphicsBitmap::create_with_shared_buffer(int shared_buffer_id, const Size& size, RGBA32* data)
  84. {
  85. if (!data) {
  86. #ifdef KERNEL
  87. void* shared_buffer = current->sys$get_shared_buffer(shared_buffer_id);
  88. #else
  89. void* shared_buffer = get_shared_buffer(shared_buffer_id);
  90. #endif
  91. if (!shared_buffer || shared_buffer == (void*)-1)
  92. return nullptr;
  93. data = (RGBA32*)shared_buffer;
  94. }
  95. return adopt(*new GraphicsBitmap(shared_buffer_id, size, data));
  96. }
  97. GraphicsBitmap::GraphicsBitmap(int shared_buffer_id, const Size& size, RGBA32* data)
  98. : m_size(size)
  99. , m_data(data)
  100. , m_pitch(size.width() * sizeof(RGBA32))
  101. , m_shared_buffer_id(shared_buffer_id)
  102. {
  103. }
  104. GraphicsBitmap::~GraphicsBitmap()
  105. {
  106. if (m_mmaped) {
  107. #ifdef KERNEL
  108. int rc = current->sys$munmap(m_data, m_size.area() * 4);
  109. #else
  110. int rc = munmap(m_data, m_size.area() * 4);
  111. #endif
  112. ASSERT(rc == 0);
  113. }
  114. if (m_shared_buffer_id != -1) {
  115. int rc;
  116. #ifdef KERNEL
  117. rc = current->sys$release_shared_buffer(m_shared_buffer_id);
  118. #else
  119. rc = release_shared_buffer(m_shared_buffer_id);
  120. #endif
  121. ASSERT(rc == 0);
  122. }
  123. m_data = nullptr;
  124. }