aboutsummaryrefslogtreecommitdiffstats
path: root/pugl
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-10-03 19:38:55 +0200
committerDavid Robillard <d@drobilla.net>2020-10-04 12:52:37 +0200
commit0b876c3d4e87b65ea3b3f05ec3274b16600e47fc (patch)
tree09f4cb47953ac769c8b740900ea9b54ac8639a52 /pugl
parenta36408b7c641e0b9052315aed87ce8e591a6a717 (diff)
downloadpugl-0b876c3d4e87b65ea3b3f05ec3274b16600e47fc.tar.gz
pugl-0b876c3d4e87b65ea3b3f05ec3274b16600e47fc.tar.bz2
pugl-0b876c3d4e87b65ea3b3f05ec3274b16600e47fc.zip
Add refresh rate hint
Diffstat (limited to 'pugl')
-rw-r--r--pugl/detail/implementation.c1
-rw-r--r--pugl/detail/mac.m20
-rw-r--r--pugl/detail/win.c4
-rw-r--r--pugl/detail/win.h1
-rw-r--r--pugl/detail/x11.c13
-rw-r--r--pugl/pugl.h1
-rw-r--r--pugl/pugl.hpp4
7 files changed, 39 insertions, 5 deletions
diff --git a/pugl/detail/implementation.c b/pugl/detail/implementation.c
index 31ee643..6a5f932 100644
--- a/pugl/detail/implementation.c
+++ b/pugl/detail/implementation.c
@@ -117,6 +117,7 @@ puglSetDefaultHints(PuglHints hints)
hints[PUGL_SWAP_INTERVAL] = PUGL_DONT_CARE;
hints[PUGL_RESIZABLE] = PUGL_FALSE;
hints[PUGL_IGNORE_KEY_REPEAT] = PUGL_FALSE;
+ hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE;
}
PuglWorld*
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m
index 0c50d20..64590c6 100644
--- a/pugl/detail/mac.m
+++ b/pugl/detail/mac.m
@@ -880,6 +880,26 @@ puglRealize(PuglView* view)
view->hints[PUGL_ALPHA_BITS] = 8;
}
+ CGDirectDisplayID displayId = CGMainDisplayID();
+ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
+
+ // Try to get refresh rate from mode (usually fails)
+ view->hints[PUGL_REFRESH_RATE] = (int)CGDisplayModeGetRefreshRate(mode);
+
+ CGDisplayModeRelease(mode);
+ if (view->hints[PUGL_REFRESH_RATE] == 0) {
+ // Get refresh rate from a display link
+ // TODO: Keep and actually use the display link for something?
+ CVDisplayLinkRef link;
+ CVDisplayLinkCreateWithCGDisplay(displayId, &link);
+
+ const CVTime p = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
+ const double r = p.timeScale / (double)p.timeValue;
+ view->hints[PUGL_REFRESH_RATE] = (int)lrint(r);
+
+ CVDisplayLinkRelease(link);
+ }
+
if (view->frame.width == 0.0 && view->frame.height == 0.0) {
if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
return PUGL_BAD_CONFIGURATION;
diff --git a/pugl/detail/win.c b/pugl/detail/win.c
index 38eca9d..17346cb 100644
--- a/pugl/detail/win.c
+++ b/pugl/detail/win.c
@@ -183,7 +183,7 @@ puglRealize(PuglView* view)
// Get refresh rate for resize draw timer
DEVMODEA devMode = {0};
EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devMode);
- view->impl->refreshRate = devMode.dmDisplayFrequency;
+ view->hints[PUGL_REFRESH_RATE] = (int)devMode.dmDisplayFrequency;
// Register window class if necessary
if (!puglRegisterWindowClass(view->world->className)) {
@@ -592,7 +592,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
view->impl->resizing = true;
SetTimer(view->impl->hwnd,
PUGL_RESIZE_TIMER_ID,
- 1000 / view->impl->refreshRate,
+ 1000 / (UINT)view->hints[PUGL_REFRESH_RATE],
NULL);
break;
case WM_TIMER:
diff --git a/pugl/detail/win.h b/pugl/detail/win.h
index 1b9b0c4..547bd02 100644
--- a/pugl/detail/win.h
+++ b/pugl/detail/win.h
@@ -38,7 +38,6 @@ struct PuglInternalsImpl {
HCURSOR cursor;
HDC hdc;
PuglSurface* surface;
- DWORD refreshRate;
bool flashing;
bool resizing;
bool mouseTracked;
diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c
index 7b8daf2..f9a45e8 100644
--- a/pugl/detail/x11.c
+++ b/pugl/detail/x11.c
@@ -37,6 +37,10 @@
#include <X11/Xutil.h>
#include <X11/keysym.h>
+#ifdef HAVE_XRANDR
+# include <X11/extensions/Xrandr.h>
+#endif
+
#ifdef HAVE_XSYNC
# include <X11/extensions/sync.h>
# include <X11/extensions/syncconst.h>
@@ -325,6 +329,15 @@ puglRealize(PuglView* view)
return st;
}
+#ifdef HAVE_XRANDR
+ // Set refresh rate hint to the real refresh rate
+ XRRScreenConfiguration* conf = XRRGetScreenInfo(display, xParent);
+ short current_rate = XRRConfigCurrentRate(conf);
+
+ view->hints[PUGL_REFRESH_RATE] = current_rate;
+ XRRFreeScreenConfigInfo(conf);
+#endif
+
updateSizeHints(view);
XClassHint classHint = { world->className, world->className };
diff --git a/pugl/pugl.h b/pugl/pugl.h
index 7e27425..bbe1b5d 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -841,6 +841,7 @@ typedef enum {
PUGL_SWAP_INTERVAL, ///< Number of frames between buffer swaps
PUGL_RESIZABLE, ///< True if view should be resizable
PUGL_IGNORE_KEY_REPEAT, ///< True if key repeat events are ignored
+ PUGL_REFRESH_RATE, ///< Refresh rate in Hz
PUGL_NUM_VIEW_HINTS
} PuglViewHint;
diff --git a/pugl/pugl.hpp b/pugl/pugl.hpp
index 4968da4..f6172d1 100644
--- a/pugl/pugl.hpp
+++ b/pugl/pugl.hpp
@@ -358,10 +358,10 @@ enum class ViewHint {
swapInterval, ///< @copydoc PUGL_SWAP_INTERVAL
resizable, ///< @copydoc PUGL_RESIZABLE
ignoreKeyRepeat, ///< @copydoc PUGL_IGNORE_KEY_REPEAT
+ refreshRate, ///< @copydoc PUGL_REFRESH_RATE
};
-static_assert(ViewHint(PUGL_IGNORE_KEY_REPEAT) == ViewHint::ignoreKeyRepeat,
- "");
+static_assert(ViewHint(PUGL_REFRESH_RATE) == ViewHint::refreshRate, "");
using ViewHintValue = PuglViewHintValue; ///< @copydoc PuglViewHintValue