DisplayManager.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // DisplayManager.cpp
  3. // konvergo
  4. //
  5. // Created by Lionel CHAZALLON on 28/09/2014.
  6. //
  7. //
  8. #include "QsLog.h"
  9. #include "DisplayManager.h"
  10. #include "math.h"
  11. ///////////////////////////////////////////////////////////////////////////////////////////////////
  12. DisplayManager::DisplayManager(QObject* parent) : QObject(parent) {}
  13. ///////////////////////////////////////////////////////////////////////////////////////////////////
  14. bool DisplayManager::initialize()
  15. {
  16. QLOG_INFO() << QString("DisplayManager found %1 Display(s).").arg(displays.size());
  17. // list video modes
  18. foreach(int displayid, displays.keys())
  19. {
  20. DMDisplayPtr display = displays[displayid];
  21. QLOG_INFO() << QString("Available modes for Display #%1 (%2)").arg(displayid).arg(display->name);
  22. for (int modeid = 0; modeid < display->videoModes.size(); modeid++)
  23. {
  24. DMVideoModePtr mode = display->videoModes[modeid];
  25. QLOG_INFO() << QString("Mode %1: %2").arg(modeid, 2).arg(mode->getPrettyName());
  26. }
  27. }
  28. // Log current display mode
  29. int mainDisplay = getMainDisplay();
  30. if (mainDisplay >= 0)
  31. {
  32. int currentMode = getCurrentDisplayMode(mainDisplay);
  33. if (currentMode >= 0)
  34. QLOG_INFO() << QString("DisplayManager : Current Display Mode on Display #%1 is %2")
  35. .arg(mainDisplay)
  36. .arg(displays[mainDisplay]->videoModes[currentMode]->getPrettyName());
  37. else
  38. QLOG_ERROR() << "DisplayManager : unable to retrieve current video mode";
  39. }
  40. else
  41. QLOG_ERROR() << "DisplayManager : unable to retrieve main display";
  42. return true;
  43. }
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////
  45. DMVideoModePtr DisplayManager::getCurrentVideoMode(int display)
  46. {
  47. int currentMode = getCurrentDisplayMode(display);
  48. DMVideoModePtr currentVideoMode;
  49. if (currentMode >= 0)
  50. currentVideoMode = displays[display]->videoModes[currentMode];
  51. return currentVideoMode;
  52. }
  53. ///////////////////////////////////////////////////////////////////////////////////////////////////
  54. bool DisplayManager::isValidDisplay(int display) { return displays.contains(display); }
  55. ///////////////////////////////////////////////////////////////////////////////////////////////////
  56. bool DisplayManager::isValidDisplayMode(int display, int mode)
  57. {
  58. if (isValidDisplay(display))
  59. if (mode >= 0 && mode < displays[display]->videoModes.size())
  60. return true;
  61. return false;
  62. }
  63. ///////////////////////////////////////////////////////////////////////////////////////////////////
  64. bool DisplayManager::isRateMultipleOf(float refresh, float multiple, bool exact)
  65. {
  66. if (((int)refresh == 0) || ((int)multiple == 0))
  67. return false;
  68. if (((int)multiple % (int)refresh) == 0)
  69. return true;
  70. int roundedRefresh = (int)round(refresh);
  71. int roundedMultiple = (int)round(multiple);
  72. if (((roundedMultiple % roundedRefresh) == 0) && (!exact))
  73. return true;
  74. return false;
  75. }
  76. ///////////////////////////////////////////////////////////////////////////////////////////////////
  77. int DisplayManager::findBestMatch(int display, DMMatchMediaInfo& matchInfo)
  78. {
  79. // Grab current videomode information
  80. DMVideoModePtr currentVideoMode = getCurrentVideoMode(display);
  81. if (!currentVideoMode)
  82. return -1;
  83. // now we try to find the exact match in current resolution
  84. // then fill a list
  85. DMVideoModeWeightMap weights;
  86. DMVideoModeMap::const_iterator modeit = displays[display]->videoModes.constBegin();
  87. while (modeit != displays[display]->videoModes.constEnd())
  88. {
  89. DMVideoModePtr candidate = modeit.value();
  90. weights[candidate->id] = DMVideoModeWeightPtr(new DMVideoModeWeight);
  91. weights[candidate->id]->mode = candidate;
  92. weights[candidate->id]->weight = 0;
  93. // Weight Resolution match
  94. if ((candidate->width == currentVideoMode->width) &&
  95. (candidate->height == currentVideoMode->height) &&
  96. (candidate->bitsPerPixel == currentVideoMode->bitsPerPixel))
  97. {
  98. weights[candidate->id]->weight += MATCH_WEIGHT_RES;
  99. }
  100. // weight refresh rate
  101. // exact Match
  102. if (candidate->refreshRate == matchInfo.refreshRate)
  103. weights[candidate->id]->weight += MATCH_WEIGHT_REFRESH_RATE_EXACT;
  104. // exact multiple refresh rate
  105. if (isRateMultipleOf(matchInfo.refreshRate, candidate->refreshRate, true))
  106. weights[candidate->id]->weight += MATCH_WEIGHT_REFRESH_RATE_MULTIPLE;
  107. // close refresh match (less than 1 hz diff to match all 23.xxx modes to 24p)
  108. if (fabs(candidate->refreshRate - matchInfo.refreshRate) <= 0.5)
  109. {
  110. weights[candidate->id]->weight += MATCH_WEIGHT_REFRESH_RATE_CLOSE;
  111. }
  112. // approx multiple refresh rate
  113. if (isRateMultipleOf(matchInfo.refreshRate, candidate->refreshRate, false))
  114. weights[candidate->id]->weight += MATCH_WEIGHT_REFRESH_RATE_MULTIPLE_CLOSE;
  115. // weight interlacing
  116. if (candidate->interlaced == matchInfo.interlaced)
  117. weights[candidate->id]->weight += MATCH_WEIGHT_INTERLACE;
  118. if (candidate->id == currentVideoMode->id)
  119. weights[candidate->id]->weight += MATCH_WEIGHT_CURRENT;
  120. modeit++;
  121. }
  122. // now grab the mode with the highest weight
  123. DMVideoModeWeightPtr chosen;
  124. float maxWeight = 0;
  125. DMVideoModeWeightMap::const_iterator weightit = weights.constBegin();
  126. while (weightit != weights.constEnd())
  127. {
  128. QLOG_DEBUG() << "Mode " << weightit.value()->mode->id << "("
  129. << weightit.value()->mode->getPrettyName() << ") has weight "
  130. << weightit.value()->weight;
  131. if (weightit.value()->weight > maxWeight)
  132. {
  133. chosen = weightit.value();
  134. maxWeight = chosen->weight;
  135. }
  136. weightit++;
  137. }
  138. if ((chosen) && (chosen->weight > MATCH_WEIGHT_RES))
  139. {
  140. QLOG_INFO() << "DisplayManager RefreshMatch : found a suitable mode : "
  141. << chosen->mode->getPrettyName();
  142. return chosen->mode->id;
  143. }
  144. QLOG_INFO() << "DisplayManager RefreshMatch : found no suitable videomode";
  145. return -1;
  146. }
  147. ///////////////////////////////////////////////////////////////////////////////////////////////////
  148. int DisplayManager::findBestMode(int display)
  149. {
  150. int best_mode = -1;
  151. foreach (auto mode, displays[display]->videoModes)
  152. {
  153. if (best_mode < 0)
  154. {
  155. best_mode = mode->id;
  156. }
  157. else
  158. {
  159. DMVideoModePtr best = displays[display]->videoModes[best_mode];
  160. DMVideoModePtr candidate = mode;
  161. // Highest priority: prefer non-interlaced modes.
  162. if (!best->interlaced && candidate->interlaced)
  163. continue;
  164. if (best->bitsPerPixel > candidate->bitsPerPixel)
  165. continue;
  166. if (best->width > candidate->width)
  167. continue;
  168. if (best->height > candidate->height)
  169. continue;
  170. if (best->refreshRate > candidate->refreshRate)
  171. continue;
  172. best_mode = candidate->id;
  173. }
  174. }
  175. return best_mode;
  176. }
  177. ///////////////////////////////////////////////////////////////////////////////////////////////////
  178. int DisplayManager::getDisplayFromPoint(const QPoint& pt)
  179. {
  180. return getDisplayFromPoint(pt.x(), pt.y());
  181. }