static CoglDisplay * clutter_backend_wayland_get_display (ClutterBackend *backend, CoglRenderer *renderer, CoglSwapChain *swap_chain, GError **error) { CoglOnscreenTemplate *onscreen_template = NULL; CoglDisplay *display; onscreen_template = cogl_onscreen_template_new (swap_chain); /* XXX: I have some doubts that this is a good design. * Conceptually should we be able to check an onscreen_template * without more details about the CoglDisplay configuration? */ if (!cogl_renderer_check_onscreen_template (renderer, onscreen_template, error)) goto error; display = cogl_display_new (renderer, onscreen_template); return display; error: if (onscreen_template) cogl_object_unref (onscreen_template); return NULL; }
static CoglDisplay * clutter_backend_cex100_get_display (ClutterBackend *backend, CoglRenderer *renderer, CoglSwapChain *swap_chain, GError **error) { CoglOnscreenTemplate *onscreen_template = NULL; CoglDisplay *display; swap_chain = cogl_swap_chain_new (); #if defined(COGL_HAS_GDL_SUPPORT) cogl_swap_chain_set_length (swap_chain, gdl_n_buffers); #endif onscreen_template = cogl_onscreen_template_new (swap_chain); /* XXX: I have some doubts that this is a good design. * Conceptually should we be able to check an onscreen_template * without more details about the CoglDisplay configuration? */ if (!cogl_renderer_check_onscreen_template (renderer, onscreen_template, error)) goto error; display = cogl_display_new (renderer, onscreen_template); #if defined(COGL_HAS_GDL_SUPPORT) cogl_gdl_display_set_plane (cogl_display, gdl_plane); #endif return display; }
static gboolean clutter_backend_win32_create_context (ClutterBackend *backend, GError **error) { CoglSwapChain *swap_chain; CoglOnscreenTemplate *onscreen_template; if (backend->cogl_context) return TRUE; backend->cogl_renderer = cogl_renderer_new (); if (!cogl_renderer_connect (backend->cogl_renderer, error)) goto error; swap_chain = cogl_swap_chain_new (); onscreen_template = cogl_onscreen_template_new (swap_chain); cogl_object_unref (swap_chain); if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer, onscreen_template, error)) goto error; backend->cogl_display = cogl_display_new (backend->cogl_renderer, onscreen_template); cogl_object_unref (backend->cogl_renderer); cogl_object_unref (onscreen_template); if (!cogl_display_setup (backend->cogl_display, error)) goto error; backend->cogl_context = cogl_context_new (backend->cogl_display, error); if (!backend->cogl_context) goto error; return TRUE; error: if (backend->cogl_display) { cogl_object_unref (backend->cogl_display); backend->cogl_display = NULL; } if (onscreen_template) cogl_object_unref (onscreen_template); if (swap_chain) cogl_object_unref (swap_chain); if (backend->cogl_renderer) { cogl_object_unref (backend->cogl_renderer); backend->cogl_renderer = NULL; } return FALSE; }
static CoglDisplay * clutter_backend_x11_get_display (ClutterBackend *backend, CoglRenderer *renderer, CoglSwapChain *swap_chain, GError **error) { CoglOnscreenTemplate *onscreen_template; CoglDisplay *display = NULL; gboolean res = FALSE; CLUTTER_NOTE (BACKEND, "Creating CoglDisplay, alpha=%s, stereo=%s", clutter_enable_argb ? "enabled" : "disabled", clutter_enable_stereo ? "enabled" : "disabled"); onscreen_template = cogl_onscreen_template_new (swap_chain); /* It's possible that the current renderer doesn't support transparency * or doesn't support stereo, so we try the different combinations. */ if (clutter_enable_argb && clutter_enable_stereo) res = check_onscreen_template (renderer, swap_chain, onscreen_template, TRUE, TRUE, error); /* Prioritize stereo over alpha */ if (!res && clutter_enable_stereo) res = check_onscreen_template (renderer, swap_chain, onscreen_template, FALSE, TRUE, error); if (!res && clutter_enable_argb) res = check_onscreen_template (renderer, swap_chain, onscreen_template, TRUE, FALSE, error); if (!res) res = check_onscreen_template (renderer, swap_chain, onscreen_template, FALSE, FALSE, error); if (res) display = cogl_display_new (renderer, onscreen_template); cogl_object_unref (onscreen_template); return display; }
void cogl_display_set_onscreen_template (CoglDisplay *display, CoglOnscreenTemplate *onscreen_template) { _COGL_RETURN_IF_FAIL (display->setup == FALSE); if (onscreen_template) cogl_object_ref (onscreen_template); if (display->onscreen_template) cogl_object_unref (display->onscreen_template); display->onscreen_template = onscreen_template; /* NB: we want to maintain the invariable that there is always an * onscreen template associated with a CoglDisplay... */ if (!onscreen_template) display->onscreen_template = cogl_onscreen_template_new (NULL); }
int main (int argc, char **argv) { CoglOnscreenTemplate *onscreen_template; CoglDisplay *display; CoglContext *ctx; CoglOnscreen *onscreen; CoglFramebuffer *fb; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0x80}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; CoglPrimitive *triangle; CoglTexture *tex; CoglOffscreen *offscreen; CoglFramebuffer *offscreen_fb; CoglPipeline *pipeline; onscreen_template = cogl_onscreen_template_new (NULL); cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4); display = cogl_display_new (NULL, onscreen_template); if (!cogl_display_setup (display, &error)) { fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n", error->message); return 1; } ctx = cogl_context_new (display, &error); if (!ctx) { fprintf (stderr, "Failed to create context: %s\n", error->message); return 1; } onscreen = cogl_onscreen_new (ctx, 640, 480); fb = COGL_FRAMEBUFFER (onscreen); cogl_framebuffer_set_samples_per_pixel (fb, 4); if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for onscreen rendering: %s\n", error->message); cogl_error_free (error); cogl_framebuffer_set_samples_per_pixel (fb, 0); error = NULL; if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message); return 1; } } cogl_onscreen_show (onscreen); tex = cogl_texture_new_with_size (ctx, 320, 480, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_to_texture (tex); offscreen_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4); if (!cogl_framebuffer_allocate (offscreen_fb, &error)) { cogl_error_free (error); error = NULL; fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for offscreen rendering"); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0); } triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); pipeline = cogl_pipeline_new (ctx); for (;;) { CoglPollFD *poll_fds; int n_poll_fds; int64_t timeout; CoglPipeline *texture_pipeline; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_framebuffer_push_matrix (fb); cogl_framebuffer_scale (fb, 0.5, 1, 1); cogl_framebuffer_translate (fb, -1, 0, 0); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_pop_matrix (fb); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_resolve_samples (offscreen_fb); texture_pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex); cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1); cogl_object_unref (texture_pipeline); cogl_onscreen_swap_buffers (onscreen); cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout); g_poll ((GPollFD *) poll_fds, n_poll_fds, 0); cogl_poll_dispatch (ctx, poll_fds, n_poll_fds); } return 0; }
static CoglDisplay * clutter_backend_gdk_get_display (ClutterBackend *backend, CoglRenderer *renderer, CoglSwapChain *swap_chain, GError **error) { ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend); CoglOnscreenTemplate *onscreen_template; GError *internal_error = NULL; CoglDisplay *display; gboolean has_rgba_visual; gboolean res; has_rgba_visual = gdk_screen_get_rgba_visual (backend_gdk->screen) == NULL; CLUTTER_NOTE (BACKEND, "Alpha on Cogl swap chain: %s", has_rgba_visual ? "enabled" : "disabled"); cogl_swap_chain_set_has_alpha (swap_chain, has_rgba_visual); onscreen_template = cogl_onscreen_template_new (swap_chain); res = cogl_renderer_check_onscreen_template (renderer, onscreen_template, &internal_error); if (!res && has_rgba_visual) { CLUTTER_NOTE (BACKEND, "Creation of a context with a ARGB visual failed: %s", internal_error != NULL ? internal_error->message : "Unknown reason"); g_clear_error (&internal_error); /* It's possible that the current renderer doesn't support transparency * in a swap_chain so lets see if we can fallback to not having any * transparency... * * XXX: It might be nice to have a CoglRenderer feature we could * explicitly check for ahead of time. */ cogl_swap_chain_set_has_alpha (swap_chain, FALSE); res = cogl_renderer_check_onscreen_template (renderer, onscreen_template, &internal_error); } if (!res) { g_set_error_literal (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, internal_error->message); g_error_free (internal_error); cogl_object_unref (onscreen_template); return NULL; } display = cogl_display_new (renderer, onscreen_template); cogl_object_unref (onscreen_template); return display; }
static gboolean clutter_backend_real_create_context (ClutterBackend *backend, GError **error) { ClutterBackendClass *klass; CoglSwapChain *swap_chain; GError *internal_error; if (backend->cogl_context != NULL) return TRUE; klass = CLUTTER_BACKEND_GET_CLASS (backend); swap_chain = NULL; internal_error = NULL; CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); if (klass->get_renderer != NULL) backend->cogl_renderer = klass->get_renderer (backend, &internal_error); else backend->cogl_renderer = cogl_renderer_new (); if (backend->cogl_renderer == NULL) goto error; #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR /* If the application is trying to act as a Wayland compositor then it needs to have an EGL-based renderer backend */ if (_wayland_compositor_display) cogl_renderer_add_constraint (backend->cogl_renderer, COGL_RENDERER_CONSTRAINT_USES_EGL); #endif CLUTTER_NOTE (BACKEND, "Connecting the renderer"); if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error)) goto error; CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); swap_chain = cogl_swap_chain_new (); CLUTTER_NOTE (BACKEND, "Creating Cogl display"); if (klass->get_display != NULL) { backend->cogl_display = klass->get_display (backend, backend->cogl_renderer, swap_chain, &internal_error); } else { CoglOnscreenTemplate *tmpl; gboolean res; tmpl = cogl_onscreen_template_new (swap_chain); /* XXX: I have some doubts that this is a good design. * * Conceptually should we be able to check an onscreen_template * without more details about the CoglDisplay configuration? */ res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, tmpl, &internal_error); if (!res) goto error; backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl); /* the display owns the template */ cogl_object_unref (tmpl); } if (backend->cogl_display == NULL) goto error; #ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR cogl_wayland_display_set_compositor_display (backend->cogl_display, _wayland_compositor_display); #endif CLUTTER_NOTE (BACKEND, "Setting up the display"); if (!cogl_display_setup (backend->cogl_display, &internal_error)) goto error; CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error); if (backend->cogl_context == NULL) goto error; backend->cogl_source = cogl_glib_source_new (backend->cogl_context, G_PRIORITY_DEFAULT); g_source_attach (backend->cogl_source, NULL); /* the display owns the renderer and the swap chain */ cogl_object_unref (backend->cogl_renderer); cogl_object_unref (swap_chain); return TRUE; error: if (backend->cogl_display != NULL) { cogl_object_unref (backend->cogl_display); backend->cogl_display = NULL; } if (backend->cogl_renderer != NULL) { cogl_object_unref (backend->cogl_renderer); backend->cogl_renderer = NULL; } if (swap_chain != NULL) cogl_object_unref (swap_chain); if (internal_error != NULL) g_propagate_error (error, internal_error); else g_set_error_literal (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, _("Unable to initialize the Clutter backend")); return FALSE; }