IOSurface.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/OwnPtr.h>
  7. #include <LibCore/IOSurface.h>
  8. #if !defined(AK_OS_MACOS)
  9. static_assert(false, "This file must only be used for macOS");
  10. #endif
  11. #define FixedPoint FixedPointMacOS
  12. #define Duration DurationMacOS
  13. #include <IOSurface/IOSurface.h>
  14. #undef FixedPoint
  15. #undef Duration
  16. namespace Core {
  17. template<typename T>
  18. class RefAutoRelease {
  19. AK_MAKE_NONCOPYABLE(RefAutoRelease);
  20. public:
  21. RefAutoRelease(T ref)
  22. : m_ref(ref)
  23. {
  24. }
  25. ~RefAutoRelease()
  26. {
  27. if (m_ref)
  28. CFRelease(m_ref);
  29. m_ref = nullptr;
  30. }
  31. T ref() const { return m_ref; }
  32. private:
  33. T m_ref { nullptr };
  34. };
  35. struct IOSurfaceHandle::IOSurfaceRefWrapper {
  36. IOSurfaceRef ref;
  37. };
  38. IOSurfaceHandle::IOSurfaceHandle(OwnPtr<IOSurfaceRefWrapper>&& ref_wrapper)
  39. : m_ref_wrapper(move(ref_wrapper))
  40. {
  41. }
  42. IOSurfaceHandle::IOSurfaceHandle(IOSurfaceHandle&& other) = default;
  43. IOSurfaceHandle& IOSurfaceHandle::operator=(IOSurfaceHandle&& other) = default;
  44. IOSurfaceHandle::~IOSurfaceHandle()
  45. {
  46. if (m_ref_wrapper)
  47. CFRelease(m_ref_wrapper->ref);
  48. }
  49. IOSurfaceHandle IOSurfaceHandle::create(int width, int height)
  50. {
  51. size_t bytes_per_element = 4;
  52. uint32_t pixel_format = 'BGRA';
  53. RefAutoRelease<CFNumberRef> width_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &width);
  54. RefAutoRelease<CFNumberRef> height_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &height);
  55. RefAutoRelease<CFNumberRef> bytes_per_element_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bytes_per_element);
  56. RefAutoRelease<CFNumberRef> pixel_format_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixel_format);
  57. CFMutableDictionaryRef props = CFDictionaryCreateMutable(kCFAllocatorDefault,
  58. 0,
  59. &kCFTypeDictionaryKeyCallBacks,
  60. &kCFTypeDictionaryValueCallBacks);
  61. CFDictionarySetValue(props, kIOSurfaceWidth, width_number.ref());
  62. CFDictionarySetValue(props, kIOSurfaceHeight, height_number.ref());
  63. CFDictionarySetValue(props, kIOSurfaceBytesPerElement, bytes_per_element_number.ref());
  64. CFDictionarySetValue(props, kIOSurfacePixelFormat, pixel_format_number.ref());
  65. auto* ref = IOSurfaceCreate(props);
  66. VERIFY(ref);
  67. return IOSurfaceHandle(make<IOSurfaceRefWrapper>(ref));
  68. }
  69. MachPort IOSurfaceHandle::create_mach_port() const
  70. {
  71. auto port = IOSurfaceCreateMachPort(m_ref_wrapper->ref);
  72. return MachPort::adopt_right(port, MachPort::PortRight::Send);
  73. }
  74. IOSurfaceHandle IOSurfaceHandle::from_mach_port(MachPort const& port)
  75. {
  76. // NOTE: This call does not destroy the port
  77. auto* ref = IOSurfaceLookupFromMachPort(port.port());
  78. VERIFY(ref);
  79. return IOSurfaceHandle(make<IOSurfaceRefWrapper>(ref));
  80. }
  81. size_t IOSurfaceHandle::width() const
  82. {
  83. return IOSurfaceGetWidth(m_ref_wrapper->ref);
  84. }
  85. size_t IOSurfaceHandle::height() const
  86. {
  87. return IOSurfaceGetHeight(m_ref_wrapper->ref);
  88. }
  89. size_t IOSurfaceHandle::bytes_per_element() const
  90. {
  91. return IOSurfaceGetBytesPerElement(m_ref_wrapper->ref);
  92. }
  93. size_t IOSurfaceHandle::bytes_per_row() const
  94. {
  95. return IOSurfaceGetBytesPerRow(m_ref_wrapper->ref);
  96. }
  97. void* IOSurfaceHandle::data() const
  98. {
  99. return IOSurfaceGetBaseAddress(m_ref_wrapper->ref);
  100. }
  101. void* IOSurfaceHandle::core_foundation_pointer() const
  102. {
  103. return m_ref_wrapper->ref;
  104. }
  105. }