BsMacOSVideoModeInfo.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2017 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "MacOS/BsMacOSVideoModeInfo.h"
  4. #include <IOKit/graphics/IOGraphicsLib.h>
  5. namespace bs::ct
  6. {
  7. MacOSVideoModeInfo::MacOSVideoModeInfo()
  8. {
  9. VideoModeInfo info;
  10. CGDisplayCount numDisplays;
  11. CGGetOnlineDisplayList(0, nullptr, &numDisplays);
  12. auto displays = (CGDirectDisplayID*)bs_stack_alloc(sizeof(CGDirectDisplayID) * numDisplays);
  13. CGGetOnlineDisplayList(numDisplays, displays, &numDisplays);
  14. for(UINT32 i = 0; i < numDisplays; i++)
  15. {
  16. if(CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay)
  17. continue;
  18. CGDisplayModeRef modeRef = CGDisplayCopyDisplayMode(displays[i]);
  19. if(!modeRef)
  20. continue;
  21. VideoOutputInfo* output = bs_new<MacOSVideoOutputInfo>(displays[i], i);
  22. // Make sure the primary output is the first in the output list
  23. if(CGDisplayIsMain(displays[i]))
  24. mOutputs.insert(mOutputs.begin(), output);
  25. else
  26. mOutputs.push_back(output);
  27. }
  28. bs_stack_free(displays);
  29. }
  30. MacOSVideoOutputInfo::MacOSVideoOutputInfo(CGDirectDisplayID displayID, UINT32 outputIdx)
  31. :mDisplayID(displayID)
  32. {
  33. CGDisplayModeRef desktopModeRef = CGDisplayCopyDisplayMode(displayID);
  34. CVDisplayLinkRef linkRef = nullptr;
  35. CVDisplayLinkCreateWithCGDisplay(displayID, &linkRef);
  36. io_service_t service = CGDisplayIOServicePort(displayID);
  37. CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
  38. auto locNames = (CFDictionaryRef)CFDictionaryGetValue(deviceInfo, CFSTR(kDisplayProductName));
  39. CFIndex numNames = CFDictionaryGetCount(locNames);
  40. if(numNames > 0)
  41. {
  42. auto keys = (CFStringRef*)bs_stack_alloc(numNames * sizeof(CFTypeRef));
  43. CFDictionaryGetKeysAndValues(locNames, (const void**)keys, nullptr);
  44. CFStringRef value = (CFStringRef)CFDictionaryGetValue(locNames, keys[0]);
  45. mName = CFStringGetCStringPtr(value, kCFStringEncodingUTF8);
  46. bs_stack_free(keys);
  47. }
  48. CFRelease(deviceInfo);
  49. mDesktopVideoMode = new (bs_alloc<MacOSVideoMode>()) MacOSVideoMode(desktopModeRef, linkRef, outputIdx);
  50. CFArrayRef modes = CGDisplayCopyAllDisplayModes(displayID, nullptr);
  51. if(modes)
  52. {
  53. CFIndex count = CFArrayGetCount(modes);
  54. for(int i = 0; i < count; i++)
  55. {
  56. auto modeRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
  57. VideoMode* videoMode = new (bs_alloc<MacOSVideoMode>()) MacOSVideoMode(modeRef, linkRef, outputIdx);
  58. mVideoModes.push_back(videoMode);
  59. }
  60. CFRelease(modes);
  61. }
  62. }
  63. MacOSVideoMode::MacOSVideoMode(UINT32 width, UINT32 height, float refreshRate, UINT32 outputIdx)
  64. :VideoMode(width, height, refreshRate, outputIdx), mModeRef(nullptr)
  65. { }
  66. MacOSVideoMode::MacOSVideoMode(CGDisplayModeRef mode, CVDisplayLinkRef linkRef, UINT32 outputIdx)
  67. :VideoMode(0, 0, 0.0f, outputIdx), mModeRef(mode)
  68. {
  69. mWidth = (UINT32)CGDisplayModeGetPixelWidth(mModeRef);
  70. mHeight = (UINT32)CGDisplayModeGetPixelHeight(mModeRef);
  71. mRefreshRate = (float)CGDisplayModeGetRefreshRate(mModeRef);
  72. if(mRefreshRate == 0.0f && linkRef != nullptr)
  73. {
  74. CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(linkRef);
  75. if((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0)
  76. mRefreshRate = time.timeScale / (float)time.timeValue;
  77. }
  78. mIsCustom = false;
  79. }
  80. MacOSVideoMode::~MacOSVideoMode()
  81. {
  82. if(!mIsCustom && mModeRef)
  83. CGDisplayModeRelease(mModeRef);
  84. }
  85. }