# define kCGLOGLPVersion_Legacy 0x1000
#endif
+#define YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(index, attribute, value) \
+ error = CGLDescribePixelFormat(pixel_format, (index), (attribute), (value)); \
+ if (error) { \
+ YAGL_LOG_WARN("CGLDescribePixelFormat failed to get " #attribute); \
+ YAGL_LOG_FUNC_EXIT(NULL); \
+ return false; \
+ }
+
static const CGLPixelFormatAttribute prefered_pixel_format_legacy_attrs[] =
{
kCGLPFAAccelerated,
struct yagl_egl_driver base;
CGLPixelFormatObj pixel_format_legacy;
+ CGLPixelFormatObj pixel_format_legacy_ms;
CGLPixelFormatObj pixel_format_3_2_core;
+ CGLPixelFormatObj pixel_format_3_2_core_ms;
};
struct yagl_egl_cgl_context
"glVertexAttribDivisor"
};
-static CGLError yagl_egl_cgl_choose_pixel_format(const CGLPixelFormatAttribute prefered_attrs[],
- const CGLPixelFormatAttribute fallback_attrs[],
- CGLPixelFormatObj *pix,
- int *n)
-{
- CGLError error;
-
- YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_choose_pixel_format, NULL);
-
- error = CGLChoosePixelFormat(prefered_attrs, pix, n);
-
- if (error) {
- YAGL_LOG_WARN("CGLChoosePixelFormat: error occurs (%s)",
- CGLErrorString(error));
- return CGLChoosePixelFormat(fallback_attrs, pix, n);
- } else if (*pix == NULL || *n == 0) {
- YAGL_LOG_WARN("CGLChoosePixelFormat: no suitable prefered format found");
- return CGLChoosePixelFormat(fallback_attrs, pix, n);
- } else {
- return error;
- }
-
-}
-
static bool yagl_egl_cgl_get_gl_version(struct yagl_egl_cgl *egl_cgl,
const char *gl_version,
yagl_gl_version *version)
YAGL_LOG_FUNC_EXIT(NULL);
}
-static struct yagl_egl_native_config
- *yagl_egl_cgl_config_enum(struct yagl_egl_driver *driver,
- EGLNativeDisplayType dpy,
- int *num_configs)
+static bool yagl_egl_cgl_config_fill(CGLPixelFormatObj pixel_format,
+ struct yagl_egl_native_config *cfg,
+ int screen_idx, int cfg_idx)
{
- struct yagl_egl_cgl *egl_cgl = (struct yagl_egl_cgl*)driver;
- struct yagl_egl_native_config *cfg = NULL;
+ int buffer_size = 0;
+ int alpha_size = 0;
+ int depth_size = 0;
+ int stencil_size = 0;
+ int samples_per_pixel = 0;
CGLError error;
- YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_config_enum, "%p", dpy);
+ YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_config_fill, NULL);
- YAGL_LOG_TRACE("got 1 config");
+ YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(screen_idx, kCGLPFAAlphaSize, &alpha_size);
+ YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(screen_idx, kCGLPFADepthSize, &depth_size);
+ YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(screen_idx, kCGLPFAStencilSize, &stencil_size);
+ YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(screen_idx, kCGLPFAColorSize, &buffer_size);
- cfg = g_malloc0(sizeof(*cfg));
+ YAGL_EGL_CGL_GET_CONFIG_ATTRIB_RET(screen_idx, kCGLPFASamples, &samples_per_pixel);
yagl_egl_native_config_init(cfg);
+ cfg->config_id = cfg_idx;
cfg->red_size = 8;
cfg->green_size = 8;
cfg->blue_size = 8;
- cfg->alpha_size = 8;
- cfg->buffer_size = 32;
+ cfg->alpha_size = alpha_size;
+ cfg->buffer_size = buffer_size;
+ cfg->stencil_size = stencil_size;
+ cfg->depth_size = depth_size;
+ cfg->samples_per_pixel = samples_per_pixel;
cfg->caveat = EGL_NONE;
- cfg->config_id = 1;
cfg->frame_buffer_level = 0;
- cfg->depth_size = 24;
cfg->max_pbuffer_width = 4096;
cfg->max_pbuffer_height = 4096;
cfg->max_pbuffer_size = 4096 * 4096;
cfg->min_swap_interval = 0;
cfg->native_visual_id = 0;
cfg->native_visual_type = EGL_NONE;
+ cfg->transparent_type = EGL_NONE;
+ cfg->trans_red_val = 0;
+ cfg->trans_green_val = 0;
+ cfg->trans_blue_val = 0;
+ cfg->driver_data = pixel_format;
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return true;
+}
+
+static struct yagl_egl_native_config
+ *yagl_egl_cgl_config_enum(struct yagl_egl_driver *driver,
+ EGLNativeDisplayType dpy,
+ int *num_configs)
+{
+ struct yagl_egl_cgl *egl_cgl = (struct yagl_egl_cgl*)driver;
+ struct yagl_egl_native_config *cfgs = NULL;
+ CGLPixelFormatObj pixel_format = NULL, pixel_format_ms = NULL;
+ int n = 0, n_ms = 0;
+ int screen_idx, cfg_idx;
+ CGLError error;
+
+ YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_config_enum, "%p", dpy);
+
+ *num_configs = 0;
if (egl_cgl->base.gl_version >= yagl_gl_3_2) {
- error = CGLDescribePixelFormat(egl_cgl->pixel_format_3_2_core,
- 0,
- kCGLPFASamples,
- &cfg->samples_per_pixel);
+ pixel_format = egl_cgl->pixel_format_3_2_core;
+ pixel_format_ms = egl_cgl->pixel_format_3_2_core_ms;
} else {
- error = CGLDescribePixelFormat(egl_cgl->pixel_format_legacy,
- 0,
- kCGLPFASamples,
- &cfg->samples_per_pixel);
+ pixel_format = egl_cgl->pixel_format_legacy;
+ pixel_format_ms = egl_cgl->pixel_format_legacy_ms;
}
+ error = CGLDescribePixelFormat(pixel_format,
+ 0,
+ kCGLPFAVirtualScreenCount,
+ &n);
if (error) {
- YAGL_LOG_WARN("CGLDescribePixelFormat(kCGLPFASamples) failed: %s",
- CGLErrorString(error));
- cfg->samples_per_pixel = 0;
+ YAGL_LOG_ERROR("CGLDescribePixelFormat failed: %s",
+ CGLErrorString(error));
+ return NULL;
}
- cfg->stencil_size = 8;
- cfg->transparent_type = EGL_NONE;
- cfg->trans_red_val = 0;
- cfg->trans_green_val = 0;
- cfg->trans_blue_val = 0;
- cfg->driver_data = NULL;
+ if (pixel_format_ms) {
+ error = CGLDescribePixelFormat(pixel_format_ms,
+ 0,
+ kCGLPFAVirtualScreenCount,
+ &n_ms);
+ if (error) {
+ YAGL_LOG_ERROR("CGLDescribePixelFormat failed: %s",
+ CGLErrorString(error));
+ return NULL;
+ }
+ }
+
+ YAGL_LOG_TRACE("got %d config", n + n_ms);
+
+ cfgs = g_new0(struct yagl_egl_native_config, n + n_ms);
+
+ for (screen_idx = 0, cfg_idx = 0; screen_idx < n; ++screen_idx) {
+ if (yagl_egl_cgl_config_fill(pixel_format,
+ &cfgs[cfg_idx],
+ screen_idx, cfg_idx)) {
+ ++cfg_idx;
+ }
+ }
+ if (pixel_format_ms) {
+ for (screen_idx = 0; screen_idx < n_ms; ++screen_idx) {
+ if (yagl_egl_cgl_config_fill(pixel_format_ms,
+ &cfgs[cfg_idx],
+ screen_idx, cfg_idx)) {
+ ++cfg_idx;
+ }
+ }
+ }
- *num_configs = 1;
+ if (cfg_idx < n + n_ms) {
+ cfgs = g_renew(struct yagl_egl_native_config,
+ cfgs,
+ cfg_idx);
+ }
+
+ *num_configs = cfg_idx;
YAGL_LOG_FUNC_EXIT(NULL);
- return cfg;
+ return cfgs;
}
static void yagl_egl_cgl_config_cleanup(struct yagl_egl_driver *driver,
}
if ((egl_cgl->base.gl_version > yagl_gl_2) && (version != 1)) {
- error = CGLCreateContext(egl_cgl->pixel_format_3_2_core,
- share_ctx,
- &ctx->base);
ctx->is_3_2_core = true;
} else {
- error = CGLCreateContext(egl_cgl->pixel_format_legacy,
- share_ctx,
- &ctx->base);
ctx->is_3_2_core = false;
}
+ error = CGLCreateContext((CGLPixelFormatObj)cfg->driver_data,
+ share_ctx,
+ &ctx->base);
if (error) {
YAGL_LOG_ERROR("CGLCreateContext failed: %s", CGLErrorString(error));
YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_destroy, NULL);
CGLDestroyPixelFormat(egl_cgl->pixel_format_legacy);
+ if (egl_cgl->pixel_format_legacy_ms) {
+ CGLDestroyPixelFormat(egl_cgl->pixel_format_legacy_ms);
+ }
if (egl_cgl->pixel_format_3_2_core) {
CGLDestroyPixelFormat(egl_cgl->pixel_format_3_2_core);
}
+ if (egl_cgl->pixel_format_3_2_core_ms) {
+ CGLDestroyPixelFormat(egl_cgl->pixel_format_3_2_core_ms);
+ }
yagl_egl_driver_cleanup(&egl_cgl->base);
goto fail;
}
- error = yagl_egl_cgl_choose_pixel_format(prefered_pixel_format_legacy_attrs,
- pixel_format_legacy_attrs,
- &egl_cgl->pixel_format_legacy,
- &n);
-
- if (error) {
- YAGL_LOG_ERROR("CGLChoosePixelFormat failed for legacy attrs: %s", CGLErrorString(error));
- goto fail;
+ error = CGLChoosePixelFormat(prefered_pixel_format_legacy_attrs,
+ &egl_cgl->pixel_format_legacy_ms,
+ &n);
+ if (error || !egl_cgl->pixel_format_legacy_ms || n == 0) {
+ YAGL_LOG_WARN("CGLChoosePixelFormat failed for legacy attrs with multisampling");
+ egl_cgl->pixel_format_legacy_ms = NULL;
}
- if (!egl_cgl->pixel_format_legacy) {
+ error = CGLChoosePixelFormat(pixel_format_legacy_attrs,
+ &egl_cgl->pixel_format_legacy,
+ &n);
+ if (error || !egl_cgl->pixel_format_legacy || n == 0) {
YAGL_LOG_ERROR("CGLChoosePixelFormat failed to find formats for legacy attrs");
goto fail;
}
if (egl_cgl->base.gl_version >= yagl_gl_3_2) {
- error = yagl_egl_cgl_choose_pixel_format(prefered_pixel_format_3_2_core_attrs,
- pixel_format_3_2_core_attrs,
- &egl_cgl->pixel_format_3_2_core,
- &n);
-
- if (error) {
- YAGL_LOG_ERROR("CGLChoosePixelFormat failed for 3_2_core attrs: %s", CGLErrorString(error));
- goto fail;
+ error = CGLChoosePixelFormat(prefered_pixel_format_3_2_core_attrs,
+ &egl_cgl->pixel_format_3_2_core_ms,
+ &n);
+ if (error || !egl_cgl->pixel_format_3_2_core_ms || n == 0) {
+ YAGL_LOG_ERROR("CGLChoosePixelFormat failed for 3_2_core attrs with multisampling");
+ egl_cgl->pixel_format_3_2_core_ms = NULL;
}
- if (!egl_cgl->pixel_format_3_2_core) {
+ error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+ &egl_cgl->pixel_format_3_2_core,
+ &n);
+ if (error || !egl_cgl->pixel_format_3_2_core || n == 0) {
YAGL_LOG_ERROR("CGLChoosePixelFormat failed to find formats for 3_2_core attrs");
goto fail;
}