aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pugl/detail/implementation.c10
-rw-r--r--pugl/detail/mac.m14
-rw-r--r--pugl/detail/mac_gl.m30
-rw-r--r--pugl/detail/win.c14
-rw-r--r--pugl/detail/win_gl.c18
-rw-r--r--pugl/detail/x11.h5
-rw-r--r--pugl/detail/x11_gl.c24
-rw-r--r--pugl/pugl.h10
-rw-r--r--pugl/pugl.hpp6
-rw-r--r--test/test_gl_hints.c86
-rw-r--r--test/test_stub_hints.c77
-rw-r--r--wscript24
12 files changed, 310 insertions, 8 deletions
diff --git a/pugl/detail/implementation.c b/pugl/detail/implementation.c
index 5534662..31ee643 100644
--- a/pugl/detail/implementation.c
+++ b/pugl/detail/implementation.c
@@ -262,6 +262,16 @@ puglSetViewHint(PuglView* view, PuglViewHint hint, int value)
return PUGL_BAD_PARAMETER;
}
+int
+puglGetViewHint(const PuglView* view, PuglViewHint hint)
+{
+ if (hint < PUGL_NUM_VIEW_HINTS) {
+ return view->hints[hint];
+ }
+
+ return PUGL_DONT_CARE;
+}
+
PuglStatus
puglSetParentWindow(PuglView* view, PuglNativeView parent)
{
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m
index 23671ae..0c50d20 100644
--- a/pugl/detail/mac.m
+++ b/pugl/detail/mac.m
@@ -866,6 +866,20 @@ puglRealize(PuglView* view)
const NSScreen* const screen = [NSScreen mainScreen];
const double scaleFactor = [screen backingScaleFactor];
+ // Getting depth from the display mode seems tedious, just set usual values
+ if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_RED_BITS] = 8;
+ }
+ if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_BLUE_BITS] = 8;
+ }
+ if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_GREEN_BITS] = 8;
+ }
+ if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_ALPHA_BITS] = 8;
+ }
+
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/mac_gl.m b/pugl/detail/mac_gl.m
index 4bf6fc1..4d4f324 100644
--- a/pugl/detail/mac_gl.m
+++ b/pugl/detail/mac_gl.m
@@ -48,12 +48,36 @@
? NSOpenGLProfileVersion4_1Core
: NSOpenGLProfileVersion3_2Core));
- NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
+ // Set attributes to default if they are unset
+ // (There is no GLX_DONT_CARE equivalent on MacOS)
+ if (puglview->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_DEPTH_BITS] = 0;
+ }
+ if (puglview->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_STENCIL_BITS] = 0;
+ }
+ if (puglview->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_SAMPLES] = 1;
+ }
+ if (puglview->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_DOUBLE_BUFFER] = 1;
+ }
+ if (puglview->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_SWAP_INTERVAL] = 1;
+ }
+
+ const unsigned colorSize = (unsigned)(puglview->hints[PUGL_RED_BITS] +
+ puglview->hints[PUGL_BLUE_BITS] +
+ puglview->hints[PUGL_GREEN_BITS] +
+ puglview->hints[PUGL_ALPHA_BITS]);
+
+ NSOpenGLPixelFormatAttribute pixelAttribs[17] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, profile,
- NSOpenGLPFAColorSize, 32,
- NSOpenGLPFADepthSize, 32,
+ NSOpenGLPFAColorSize, colorSize,
+ NSOpenGLPFADepthSize, (unsigned)puglview->hints[PUGL_DEPTH_BITS],
+ NSOpenGLPFAStencilSize, (unsigned)puglview->hints[PUGL_STENCIL_BITS],
NSOpenGLPFAMultisample, samples ? 1 : 0,
NSOpenGLPFASampleBuffers, samples ? 1 : 0,
NSOpenGLPFASamples, samples,
diff --git a/pugl/detail/win.c b/pugl/detail/win.c
index 4f7afee..38eca9d 100644
--- a/pugl/detail/win.c
+++ b/pugl/detail/win.c
@@ -166,6 +166,20 @@ puglRealize(PuglView* view)
{
PuglInternals* impl = view->impl;
+ // Getting depth from the display mode seems tedious, just set usual values
+ if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_RED_BITS] = 8;
+ }
+ if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_BLUE_BITS] = 8;
+ }
+ if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_GREEN_BITS] = 8;
+ }
+ if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_ALPHA_BITS] = 8;
+ }
+
// Get refresh rate for resize draw timer
DEVMODEA devMode = {0};
EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devMode);
diff --git a/pugl/detail/win_gl.c b/pugl/detail/win_gl.c
index 8cdad76..096c715 100644
--- a/pugl/detail/win_gl.c
+++ b/pugl/detail/win_gl.c
@@ -108,6 +108,24 @@ puglWinGlConfigure(PuglView* view)
{
PuglInternals* impl = view->impl;
+ // Set attributes to default if they are unset
+ // (There is no GLX_DONT_CARE equivalent on Windows)
+ if (view->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_DEPTH_BITS] = 0;
+ }
+ if (view->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_STENCIL_BITS] = 0;
+ }
+ if (view->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
+ view->hints[PUGL_SAMPLES] = 1;
+ }
+ if (view->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
+ view->hints[PUGL_DOUBLE_BUFFER] = 1;
+ }
+ if (view->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
+ view->hints[PUGL_SWAP_INTERVAL] = 1;
+ }
+
// clang-format off
const int pixelAttrs[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
diff --git a/pugl/detail/x11.h b/pugl/detail/x11.h
index cf647ed..4b0109d 100644
--- a/pugl/detail/x11.h
+++ b/pugl/detail/x11.h
@@ -83,5 +83,10 @@ puglX11StubConfigure(PuglView* view)
pat.screen = impl->screen;
impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n);
+ view->hints[PUGL_RED_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_GREEN_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_BLUE_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_ALPHA_BITS] = 0;
+
return PUGL_SUCCESS;
}
diff --git a/pugl/detail/x11_gl.c b/pugl/detail/x11_gl.c
index e4a0ea8..228a530 100644
--- a/pugl/detail/x11_gl.c
+++ b/pugl/detail/x11_gl.c
@@ -71,7 +71,7 @@ puglX11GlConfigure(PuglView* view)
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_SAMPLES, view->hints[PUGL_SAMPLES],
+ GLX_SAMPLES, puglX11GlHintValue(view->hints[PUGL_SAMPLES]),
GLX_RED_SIZE, puglX11GlHintValue(view->hints[PUGL_RED_BITS]),
GLX_GREEN_SIZE, puglX11GlHintValue(view->hints[PUGL_GREEN_BITS]),
GLX_BLUE_SIZE, puglX11GlHintValue(view->hints[PUGL_BLUE_BITS]),
@@ -91,6 +91,23 @@ puglX11GlConfigure(PuglView* view)
surface->fb_config = fbc[0];
impl->vi = glXGetVisualFromFBConfig(impl->display, fbc[0]);
+ view->hints[PUGL_RED_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_RED_SIZE);
+ view->hints[PUGL_GREEN_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_GREEN_SIZE);
+ view->hints[PUGL_BLUE_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_BLUE_SIZE);
+ view->hints[PUGL_ALPHA_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_ALPHA_SIZE);
+ view->hints[PUGL_DEPTH_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_DEPTH_SIZE);
+ view->hints[PUGL_STENCIL_BITS] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_STENCIL_SIZE);
+ view->hints[PUGL_SAMPLES] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_SAMPLES);
+ view->hints[PUGL_DOUBLE_BUFFER] = puglX11GlGetAttrib(
+ display, fbc[0], GLX_DOUBLEBUFFER);
+
char msg[128];
snprintf(
@@ -182,6 +199,11 @@ puglX11GlCreate(PuglView* view)
GLX_DOUBLEBUFFER,
&view->hints[PUGL_DOUBLE_BUFFER]);
+ glXQueryDrawable(display,
+ impl->win,
+ GLX_SWAP_INTERVAL_EXT,
+ (unsigned int*)&view->hints[PUGL_SWAP_INTERVAL]);
+
return PUGL_SUCCESS;
}
diff --git a/pugl/pugl.h b/pugl/pugl.h
index c32a17d..7e27425 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -939,6 +939,16 @@ PUGL_API PuglStatus
puglSetViewHint(PuglView* view, PuglViewHint hint, int value);
/**
+ Get the value for a view hint.
+
+ If the view has been realized, this can be used to get the actual value of a
+ hint which was initially set to PUGL_DONT_CARE, or has been adjusted from
+ the suggested value.
+*/
+PUGL_API int
+puglGetViewHint(const PuglView* view, PuglViewHint hint);
+
+/**
@}
@anchor frame
@name Frame
diff --git a/pugl/pugl.hpp b/pugl/pugl.hpp
index 3072560..4968da4 100644
--- a/pugl/pugl.hpp
+++ b/pugl/pugl.hpp
@@ -418,6 +418,12 @@ public:
puglSetViewHint(cobj(), static_cast<PuglViewHint>(hint), value));
}
+ /// @copydoc puglGetViewHint
+ int getHint(ViewHint hint)
+ {
+ return puglGetViewHint(cobj(), static_cast<PuglViewHint>(hint));
+ }
+
/**
@}
@name Frame
diff --git a/test/test_gl_hints.c b/test/test_gl_hints.c
new file mode 100644
index 0000000..9830e2e
--- /dev/null
+++ b/test/test_gl_hints.c
@@ -0,0 +1,86 @@
+/*
+ Copyright 2020 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ Tests that all hints are set to real values after a view is realized.
+*/
+
+#undef NDEBUG
+
+#include "test_utils.h"
+
+#include "pugl/pugl.h"
+#include "pugl/pugl_gl.h"
+
+#include <assert.h>
+
+static PuglStatus
+onEvent(PuglView* view, const PuglEvent* event)
+{
+ (void)view;
+ (void)event;
+
+ return PUGL_SUCCESS;
+}
+
+int
+main(void)
+{
+ PuglWorld* const world = puglNewWorld(PUGL_PROGRAM, 0);
+ PuglView* const view = puglNewView(world);
+
+ // Set up view
+ puglSetClassName(world, "Pugl Test");
+ puglSetBackend(view, puglGlBackend());
+ puglSetEventFunc(view, onEvent);
+ puglSetDefaultSize(view, 512, 512);
+
+ // Set all hints that support it to PUGL_DONT_CARE
+ assert(!puglSetViewHint(view, PUGL_RED_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_GREEN_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_BLUE_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_ALPHA_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_DEPTH_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_STENCIL_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_SAMPLES, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_DOUBLE_BUFFER, PUGL_DONT_CARE));
+
+ // Realize view and print all hints for debugging convenience
+ assert(!puglRealize(view));
+
+ // Check that no hints are set to PUGL_DONT_CARE
+ assert(puglGetViewHint(view, PUGL_USE_COMPAT_PROFILE) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_USE_DEBUG_CONTEXT) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_CONTEXT_VERSION_MINOR) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_RED_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_GREEN_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_BLUE_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_ALPHA_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_DEPTH_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_STENCIL_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_SAMPLES) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_DOUBLE_BUFFER) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_SWAP_INTERVAL) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_RESIZABLE) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_IGNORE_KEY_REPEAT) != PUGL_DONT_CARE);
+
+ // Tear down
+ puglFreeView(view);
+ puglFreeWorld(world);
+
+ return 0;
+}
diff --git a/test/test_stub_hints.c b/test/test_stub_hints.c
new file mode 100644
index 0000000..cd4db6a
--- /dev/null
+++ b/test/test_stub_hints.c
@@ -0,0 +1,77 @@
+/*
+ Copyright 2020 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ Tests that all hints are set to real values after a view is realized.
+*/
+
+#undef NDEBUG
+
+#include "test_utils.h"
+
+#include "pugl/pugl.h"
+#include "pugl/pugl_stub.h"
+
+#include <assert.h>
+
+static PuglStatus
+onEvent(PuglView* view, const PuglEvent* event)
+{
+ (void)view;
+ (void)event;
+
+ return PUGL_SUCCESS;
+}
+
+int
+main(void)
+{
+ PuglWorld* const world = puglNewWorld(PUGL_PROGRAM, 0);
+ PuglView* const view = puglNewView(world);
+
+ // Set up view
+ puglSetClassName(world, "Pugl Test");
+ puglSetBackend(view, puglStubBackend());
+ puglSetEventFunc(view, onEvent);
+ puglSetDefaultSize(view, 512, 512);
+
+ // Set all relevant hints that support it to PUGL_DONT_CARE
+ assert(!puglSetViewHint(view, PUGL_RED_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_GREEN_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_BLUE_BITS, PUGL_DONT_CARE));
+ assert(!puglSetViewHint(view, PUGL_ALPHA_BITS, PUGL_DONT_CARE));
+
+ // Realize view and print all hints for debugging convenience
+ assert(!puglRealize(view));
+
+ // Check that no relevant hints are set to PUGL_DONT_CARE
+ assert(puglGetViewHint(view, PUGL_USE_COMPAT_PROFILE) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_USE_DEBUG_CONTEXT) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_CONTEXT_VERSION_MINOR) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_RED_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_GREEN_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_BLUE_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_ALPHA_BITS) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_RESIZABLE) != PUGL_DONT_CARE);
+ assert(puglGetViewHint(view, PUGL_IGNORE_KEY_REPEAT) != PUGL_DONT_CARE);
+
+ // Tear down
+ puglFreeView(view);
+ puglFreeWorld(world);
+
+ return 0;
+}
diff --git a/wscript b/wscript
index 0855ef1..10be77c 100644
--- a/wscript
+++ b/wscript
@@ -255,7 +255,9 @@ def _build_pc_file(bld, name, desc, target, libname, deps={}, requires=[]):
LIBS=' '.join(link_flags))
-tests = ['redisplay', 'show_hide', 'update', 'timer']
+gl_tests = ['gl_hints']
+basic_tests = ['stub_hints', 'redisplay', 'show_hide', 'update', 'timer']
+tests = ['gl_hints', 'stub_hints', 'redisplay', 'show_hide', 'update', 'timer']
def build(bld):
@@ -430,18 +432,28 @@ def build(bld):
cflags=glad_cflags,
uselib=['DL', 'GL', 'M'])
+ for test in gl_tests:
+ bld(features = 'c cprogram',
+ source = 'test/test_%s.c' % test,
+ target = 'test/test_%s' % test,
+ install_path = '',
+ use = ['pugl_%s_static' % platform,
+ 'pugl_%s_gl_static' % platform],
+ uselib = deps[platform]['uselib'] + ['GL'])
+
if bld.env.HAVE_CAIRO:
build_example('pugl_cairo_demo', ['examples/pugl_cairo_demo.c'],
platform, 'cairo',
uselib=['M', 'CAIRO'])
- for test in tests:
+ for test in basic_tests:
bld(features = 'c cprogram',
source = 'test/test_%s.c' % test,
target = 'test/test_%s' % test,
install_path = '',
use = ['pugl_%s_static' % platform,
- 'pugl_%s_stub_static' % platform],
+ 'pugl_%s_stub_static' % platform,
+ 'pugl_%s_gl_static' % platform],
uselib = deps[platform]['uselib'] + ['CAIRO'])
# Make a hyper strict warning environment for checking API headers
@@ -488,9 +500,13 @@ def build(bld):
def test(tst):
if tst.options.gui_tests:
with tst.group('gui') as check:
- for test in tests:
+ for test in basic_tests:
check(['test/test_%s' % test])
+ if tst.env.HAVE_GL:
+ for test in gl_tests:
+ check(['test/test_%s' % test])
+
class LintContext(Build.BuildContext):
fun = cmd = 'lint'