void cogl_begin_gl (void) { CoglPipeline *pipeline; _COGL_GET_CONTEXT (ctx, NO_RETVAL); if (ctx->in_begin_gl_block) { static CoglBool shown = FALSE; if (!shown) g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks"); shown = TRUE; return; } ctx->in_begin_gl_block = TRUE; /* Flush all batched primitives */ cogl_flush (); /* Flush framebuffer state, including clip state, modelview and * projection matrix state * * NB: _cogl_framebuffer_flush_state may disrupt various state (such * as the pipeline state) when flushing the clip stack, so should * always be done first when preparing to draw. */ _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), _cogl_get_read_framebuffer (), COGL_FRAMEBUFFER_STATE_ALL); /* Setup the state for the current pipeline */ /* We considered flushing a specific, minimal pipeline here to try and * simplify the GL state, but decided to avoid special cases and second * guessing what would be actually helpful. * * A user should instead call cogl_set_source_color4ub() before * cogl_begin_gl() to simplify the state flushed. * * XXX: note defining n_tex_coord_attribs using * cogl_pipeline_get_n_layers is a hack, but the problem is that * n_tex_coord_attribs is usually defined when drawing a primitive * which isn't happening here. * * Maybe it would be more useful if this code did flush the * opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then * restore all state for the material's backend back to default OpenGL * values. */ pipeline = cogl_get_source (); _cogl_pipeline_flush_gl_state (ctx, pipeline, cogl_get_draw_framebuffer (), FALSE, FALSE); /* Disable any cached vertex arrays */ _cogl_gl_disable_all_attributes (ctx); }
static void _capture_desktop(MetaSwitcher* self) { MetaSwitcherPrivate* priv = self->priv; MetaScreen* screen = meta_plugin_get_screen(priv->plugin); ClutterActor* stage = meta_get_stage_for_screen(screen); gfloat tx, ty, w, h; clutter_actor_get_position(priv->top, &tx, &ty); clutter_actor_get_size(priv->top, &w, &h); g_debug("%s: %f, %f, %f, %f", __func__, tx, ty, w, h); if (priv->snapshot) { cairo_surface_destroy(priv->snapshot); priv->snapshot = NULL; } priv->snapshot_offset = 20.0; w += priv->snapshot_offset*3; clutter_stage_ensure_redraw(CLUTTER_STAGE(stage)); guchar* data = g_malloc(w*h*4); cogl_framebuffer_read_pixels(cogl_get_draw_framebuffer(), tx-priv->snapshot_offset, ty, w, h, CLUTTER_CAIRO_FORMAT_ARGB32, data); /*guchar* data = clutter_stage_read_pixels(CLUTTER_STAGE(stage), */ /*tx-priv->snapshot_offset, ty, w, h);*/ priv->snapshot = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, w, h, w*4); g_free(data); }
static void _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path) { CoglFramebuffer *fb; _COGL_GET_CONTEXT (ctx, NO_RETVAL); if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_STENCIL_BUFFER)) { static gboolean seen_warning = FALSE; if (!seen_warning) { g_warning ("Paths can not be filled using materials with " "sliced textures unless there is a stencil " "buffer"); seen_warning = TRUE; } } fb = cogl_get_draw_framebuffer (); cogl_framebuffer_push_path_clip (fb, path); cogl_rectangle (path->data->path_nodes_min.x, path->data->path_nodes_min.y, path->data->path_nodes_max.x, path->data->path_nodes_max.y); cogl_framebuffer_pop_clip (fb); }
void _cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags) { gboolean needs_fallback = FALSE; CoglPipeline *pipeline = cogl_get_source (); _cogl_pipeline_foreach_layer_internal (pipeline, validate_layer_cb, &needs_fallback); if (needs_fallback) { _cogl_path_fill_nodes_with_clipped_rectangle (path); return; } _cogl_path_build_fill_attribute_buffer (path); _cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (), pipeline, COGL_VERTICES_MODE_TRIANGLES, 0, /* first_vertex */ path->data->fill_vbo_n_indices, path->data->fill_vbo_indices, path->data->fill_attributes, COGL_PATH_N_ATTRIBUTES, flags); }
void _st_paint_shadow_with_opacity (StShadow *shadow_spec, CoglPipeline *shadow_pipeline, ClutterActorBox *box, guint8 paint_opacity) { CoglFramebuffer *fb = cogl_get_draw_framebuffer (); ClutterActorBox shadow_box; CoglColor color; g_return_if_fail (shadow_spec != NULL); g_return_if_fail (shadow_pipeline != NULL); st_shadow_get_box (shadow_spec, box, &shadow_box); cogl_color_init_from_4ub (&color, shadow_spec->color.red * paint_opacity / 255, shadow_spec->color.green * paint_opacity / 255, shadow_spec->color.blue * paint_opacity / 255, shadow_spec->color.alpha * paint_opacity / 255); cogl_color_premultiply (&color); cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color); cogl_framebuffer_draw_rectangle (fb, shadow_pipeline, shadow_box.x1, shadow_box.y1, shadow_box.x2, shadow_box.y2); }
CoglClipState * _cogl_get_clip_state (void) { CoglFramebuffer *framebuffer; framebuffer = cogl_get_draw_framebuffer (); return _cogl_framebuffer_get_clip_state (framebuffer); }
static void meta_surface_actor_pick (ClutterActor *actor, const ClutterColor *color) { MetaSurfaceActor *self = META_SURFACE_ACTOR (actor); MetaSurfaceActorPrivate *priv = meta_surface_actor_get_instance_private (self); ClutterActorIter iter; ClutterActor *child; if (!clutter_actor_should_pick_paint (actor)) return; /* If there is no region then use the regular pick */ if (priv->input_region == NULL) CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->pick (actor, color); else { int n_rects; float *rectangles; int i; CoglPipeline *pipeline; CoglContext *ctx; CoglFramebuffer *fb; CoglColor cogl_color; n_rects = cairo_region_num_rectangles (priv->input_region); rectangles = g_alloca (sizeof (float) * 4 * n_rects); for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; int pos = i * 4; cairo_region_get_rectangle (priv->input_region, i, &rect); rectangles[pos + 0] = rect.x; rectangles[pos + 1] = rect.y; rectangles[pos + 2] = rect.x + rect.width; rectangles[pos + 3] = rect.y + rect.height; } ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); fb = cogl_get_draw_framebuffer (); cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_color (pipeline, &cogl_color); cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects); cogl_object_unref (pipeline); } clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_next (&iter, &child)) clutter_actor_paint (child); }
void cogl_perspective (float fov_y, float aspect, float z_near, float z_far) { cogl_framebuffer_perspective (cogl_get_draw_framebuffer (), fov_y, aspect, z_near, z_far); }
static void pre_paint_windows (MetaCompositor *compositor) { GList *l; MetaWindowActor *top_window; if (compositor->onscreen == NULL) { compositor->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ()); compositor->frame_closure = cogl_onscreen_add_frame_callback (compositor->onscreen, frame_callback, compositor, NULL); } if (compositor->windows == NULL) return; top_window = g_list_last (compositor->windows)->data; if (meta_window_actor_should_unredirect (top_window) && compositor->disable_unredirect_count == 0) set_unredirected_window (compositor, meta_window_actor_get_meta_window (top_window)); else set_unredirected_window (compositor, NULL); for (l = compositor->windows; l; l = l->next) meta_window_actor_pre_paint (l->data); if (compositor->frame_has_updated_xsurfaces) { /* We need to make sure that any X drawing that happens before * the XDamageSubtract() for each window above is visible to * subsequent GL rendering; the only standardized way to do this * is EXT_x11_sync_object, which isn't yet widely available. For * now, we count on details of Xorg and the open source drivers, * and hope for the best otherwise. * * Xorg and open source driver specifics: * * The X server makes sure to flush drawing to the kernel before * sending out damage events, but since we use * DamageReportBoundingBox there may be drawing between the last * damage event and the XDamageSubtract() that needs to be * flushed as well. * * Xorg always makes sure that drawing is flushed to the kernel * before writing events or responses to the client, so any * round trip request at this point is sufficient to flush the * GLX buffers. */ XSync (compositor->display->xdisplay, False); compositor->frame_has_updated_xsurfaces = FALSE; } }
/* TODO: Update to the protoype used in the Cogl master branch. * This is experimental API but not in sync with the cogl_path_fill() * api in Cogl master which takes explicit framebuffer and pipeline * arguments */ void cogl2_path_fill (CoglPath *path) { _COGL_RETURN_IF_FAIL (cogl_is_path (path)); _cogl_path_fill_nodes (path, cogl_get_draw_framebuffer (), cogl_get_source (), 0 /* flags */); }
/* XXX: This function should either be replaced with one returning * integers, or removed/deprecated and make the * _cogl_framebuffer_get_viewport* functions public. */ void cogl_get_viewport (float viewport[4]) { CoglFramebuffer *framebuffer; _COGL_GET_CONTEXT (ctx, NO_RETVAL); framebuffer = cogl_get_draw_framebuffer (); cogl_framebuffer_get_viewport4fv (framebuffer, viewport); }
void cogl_frustum (float left, float right, float bottom, float top, float z_near, float z_far) { cogl_framebuffer_frustum (cogl_get_draw_framebuffer (), left, right, bottom, top, z_near, z_far); }
void cogl_ortho (float left, float right, float bottom, float top, float near, float far) { cogl_framebuffer_orthographic (cogl_get_draw_framebuffer (), left, top, right, bottom, near, far); }
static void _cogl_rectangles_with_multitexture_coords ( CoglMultiTexturedRect *rects, int n_rects) { _cogl_framebuffer_draw_multitextured_rectangles (cogl_get_draw_framebuffer (), cogl_get_source (), rects, n_rects, FALSE); }
/* TODO: Update to the protoype used in the Cogl master branch. * This is experimental API but not in sync with the cogl_path_fill() * api in Cogl master which takes explicit framebuffer and pipeline * arguments */ void cogl2_path_stroke (CoglPath *path) { _COGL_RETURN_IF_FAIL (cogl_is_path (path)); if (path->data->path_nodes->len == 0) return; _cogl_path_stroke_nodes (path, cogl_get_draw_framebuffer (), cogl_get_source ()); }
void cogl_clip_stack_restore (void) { CoglFramebuffer *framebuffer; CoglClipState *clip_state; _COGL_GET_CONTEXT (ctx, NO_RETVAL); framebuffer = cogl_get_draw_framebuffer (); clip_state = _cogl_framebuffer_get_clip_state (framebuffer); _cogl_clip_stack_restore_real (clip_state); }
/* XXX: This should never have been made public API! */ void cogl_clip_ensure (void) { CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglClipState *clip_state; clip_state = _cogl_framebuffer_get_clip_state (framebuffer); /* Flushing the clip state doesn't cause the journal to be flushed. This function may be being called by an external application however so it makes sense to flush the journal here */ _cogl_framebuffer_flush_journal (framebuffer); _cogl_clip_state_flush (clip_state); }
static void _cogl_path_stroke_nodes (CoglPath *path) { CoglPathData *data = path->data; CoglPipeline *copy = NULL; CoglPipeline *source; unsigned int path_start; int path_num = 0; CoglPathNode *node; _COGL_GET_CONTEXT (ctx, NO_RETVAL); source = cogl_get_source (); if (cogl_pipeline_get_n_layers (source) != 0) { copy = cogl_pipeline_copy (source); _cogl_pipeline_prune_to_n_layers (copy, 0); source = copy; } _cogl_path_build_stroke_attribute_buffer (path); cogl_push_source (source); for (path_start = 0; path_start < data->path_nodes->len; path_start += node->path_size) { node = &g_array_index (data->path_nodes, CoglPathNode, path_start); cogl_framebuffer_vdraw_attributes (cogl_get_draw_framebuffer (), source, COGL_VERTICES_MODE_LINE_STRIP, 0, node->path_size, data->stroke_attributes[path_num], NULL); path_num++; } cogl_pop_source (); if (copy) cogl_object_unref (copy); }
void cogl_set_viewport (int x, int y, int width, int height) { CoglFramebuffer *framebuffer; _COGL_GET_CONTEXT (ctx, NO_RETVAL); framebuffer = cogl_get_draw_framebuffer (); cogl_framebuffer_set_viewport (framebuffer, x, y, width, height); }
void cogl_clip_push_window_rectangle (int x_offset, int y_offset, int width, int height) { CoglFramebuffer *framebuffer; CoglClipState *clip_state; _COGL_GET_CONTEXT (ctx, NO_RETVAL); framebuffer = cogl_get_draw_framebuffer (); clip_state = _cogl_framebuffer_get_clip_state (framebuffer); clip_state->stacks->data = _cogl_clip_stack_push_window_rectangle (clip_state->stacks->data, x_offset, y_offset, width, height); }
/** * mash_data_render: * @self: A #MashData instance * * Renders the data contained in the model to the Clutter * scene. The current Cogl source material will be used to affect the * appearance of the model. This function is not usually called * directly but instead the #MashData instance is added to a * #MashModel and this function will be automatically called by * the paint method of the model. */ void mash_data_render (MashData *self, CoglPipeline* pl){ MashDataPrivate *priv; g_return_if_fail (MASH_IS_DATA (self)); priv = self->priv; if (priv->loaded_data.prim != NULL){ CoglFramebuffer *fb = /*(CoglFramebuffer*)*/ cogl_get_draw_framebuffer(); cogl_primitive_draw(priv->loaded_data.prim, fb, pl); } else if(priv->loaded_data.vertices_vbo != NULL && priv->loaded_data.indices != NULL){ cogl_vertex_buffer_draw_elements (priv->loaded_data.vertices_vbo, COGL_VERTICES_MODE_TRIANGLES, priv->loaded_data.indices, priv->loaded_data.min_index, priv->loaded_data.max_index, 0, priv->loaded_data.n_triangles * 3); } }
static void meta_overlay_paint (MetaOverlay *overlay) { if (!overlay->enabled) return; g_assert (meta_is_wayland_compositor ()); cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), overlay->pipeline, overlay->current_rect.x, overlay->current_rect.y, overlay->current_rect.x + overlay->current_rect.width, overlay->current_rect.y + overlay->current_rect.height); overlay->previous_rect = overlay->current_rect; overlay->previous_is_valid = TRUE; }
void cogl_clip_push_rectangle (float x_1, float y_1, float x_2, float y_2) { CoglFramebuffer *framebuffer; CoglClipState *clip_state; CoglMatrix modelview_matrix; _COGL_GET_CONTEXT (ctx, NO_RETVAL); framebuffer = cogl_get_draw_framebuffer (); clip_state = _cogl_framebuffer_get_clip_state (framebuffer); cogl_get_modelview_matrix (&modelview_matrix); clip_state->stacks->data = _cogl_clip_stack_push_rectangle (clip_state->stacks->data, x_1, y_1, x_2, y_2, &modelview_matrix); }
static void shell_anamorphosis_effect_paint_target (ClutterOffscreenEffect *effect) { ShellAnamorphosisEffect *self = SHELL_ANAMORPHOSIS_EFFECT (effect); ShellAnamorphosisEffectPrivate *priv = shell_anamorphosis_effect_get_instance_private (self); CoglFramebuffer *fb = cogl_get_draw_framebuffer (); ClutterActor *actor; guint8 paint_opacity; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); paint_opacity = clutter_actor_get_paint_opacity (actor); cogl_pipeline_set_color4ub (priv->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (fb, priv->pipeline, 0, 0, priv->tex_width, priv->tex_height); }
static void clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect) { ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); ClutterActor *actor; guint8 paint_opacity; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); paint_opacity = clutter_actor_get_paint_opacity (actor); cogl_pipeline_set_color4ub (self->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (framebuffer, self->pipeline, 0, 0, self->tex_width, self->tex_height); }
void cogl_get_bitmasks (int *red, int *green, int *blue, int *alpha) { CoglFramebuffer *framebuffer; framebuffer = cogl_get_draw_framebuffer (); if (red) *red = cogl_framebuffer_get_red_bits (framebuffer); if (green) *green = cogl_framebuffer_get_green_bits (framebuffer); if (blue) *blue = cogl_framebuffer_get_blue_bits (framebuffer); if (alpha) *alpha = cogl_framebuffer_get_alpha_bits (framebuffer); }
static void shell_glsl_quad_paint (ClutterActor *actor) { ShellGLSLQuad *self = SHELL_GLSL_QUAD (actor); ShellGLSLQuadPrivate *priv; guint8 paint_opacity; ClutterActorBox box; priv = shell_glsl_quad_get_instance_private (self); paint_opacity = clutter_actor_get_paint_opacity (actor); clutter_actor_get_allocation_box (actor, &box); cogl_pipeline_set_color4ub (priv->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), priv->pipeline, box.x1, box.y1, box.x2, box.y2); }
static void do_grab_screenshot (_screenshot_data *screenshot_data, int x, int y, int width, int height) { CoglBitmap *bitmap; ClutterBackend *backend; CoglContext *context; int stride; guchar *data; backend = clutter_get_default_backend (); context = clutter_backend_get_cogl_context (backend); screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); data = cairo_image_surface_get_data (screenshot_data->image); stride = cairo_image_surface_get_stride (screenshot_data->image); bitmap = cogl_bitmap_new_for_data (context, width, height, CLUTTER_CAIRO_FORMAT_ARGB32, stride, data); cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (), x, y, COGL_READ_PIXELS_COLOR_BUFFER, bitmap); cairo_surface_mark_dirty (screenshot_data->image); cogl_object_unref (bitmap); }
static void clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) { ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); ClutterDeformEffectPrivate *priv = self->priv; CoglHandle material; CoglPipeline *pipeline; CoglDepthState depth_state; CoglFramebuffer *fb = cogl_get_draw_framebuffer (); if (priv->is_dirty) { ClutterRect rect; gboolean mapped_buffer; CoglVertexP3T2C4 *verts; ClutterActor *actor; gfloat width, height; guint opacity; gint i, j; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); opacity = clutter_actor_get_paint_opacity (actor); /* if we don't have a target size, fall back to the actor's * allocation, though wrong it might be */ if (clutter_offscreen_effect_get_target_rect (effect, &rect)) { width = clutter_rect_get_width (&rect); height = clutter_rect_get_height (&rect); } else clutter_actor_get_size (actor, &width, &height); /* XXX ideally, the sub-classes should tell us what they * changed in the texture vertices; we then would be able to * avoid resubmitting the same data, if it did not change. for * the time being, we resubmit everything */ verts = cogl_buffer_map (COGL_BUFFER (priv->buffer), COGL_BUFFER_ACCESS_WRITE, COGL_BUFFER_MAP_HINT_DISCARD); /* If the map failed then we'll resort to allocating a temporary buffer */ if (verts == NULL) { mapped_buffer = FALSE; verts = g_malloc (sizeof (*verts) * priv->n_vertices); } else mapped_buffer = TRUE; for (i = 0; i < priv->y_tiles + 1; i++) { for (j = 0; j < priv->x_tiles + 1; j++) { CoglVertexP3T2C4 *vertex_out; CoglTextureVertex vertex; /* CoglTextureVertex isn't an ideal structure to use for this because it contains a CoglColor. The internal layout of CoglColor is mean to be private so Clutter can not pass a pointer to it as a vertex attribute. Also it contains padding so we end up storing more data in the vertex buffer than we need to. Instead we let the application modify a dummy vertex and then copy the details back out to a more well-defined struct */ vertex.tx = (float) j / priv->x_tiles; vertex.ty = (float) i / priv->y_tiles; vertex.x = width * vertex.tx; vertex.y = height * vertex.ty; vertex.z = 0.0f; cogl_color_init_from_4ub (&vertex.color, 255, 255, 255, opacity); clutter_deform_effect_deform_vertex (self, width, height, &vertex); vertex_out = verts + i * (priv->x_tiles + 1) + j; vertex_out->x = vertex.x; vertex_out->y = vertex.y; vertex_out->z = vertex.z; vertex_out->s = vertex.tx; vertex_out->t = vertex.ty; vertex_out->r = cogl_color_get_red_byte (&vertex.color); vertex_out->g = cogl_color_get_green_byte (&vertex.color); vertex_out->b = cogl_color_get_blue_byte (&vertex.color); vertex_out->a = cogl_color_get_alpha_byte (&vertex.color); } } if (mapped_buffer) cogl_buffer_unmap (COGL_BUFFER (priv->buffer)); else { cogl_buffer_set_data (COGL_BUFFER (priv->buffer), 0, /* offset */ verts, sizeof (*verts) * priv->n_vertices); g_free (verts); } priv->is_dirty = FALSE; } material = clutter_offscreen_effect_get_target (effect); pipeline = COGL_PIPELINE (material); /* enable depth testing */ cogl_depth_state_init (&depth_state); cogl_depth_state_set_test_enabled (&depth_state, TRUE); cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); /* enable backface culling if we have a back material */ if (priv->back_pipeline != NULL) cogl_pipeline_set_cull_face_mode (pipeline, COGL_PIPELINE_CULL_FACE_MODE_BACK); /* draw the front */ if (material != NULL) cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive); /* draw the back */ if (priv->back_pipeline != NULL) { CoglPipeline *back_pipeline; /* We probably shouldn't be modifying the user's material so instead we make a temporary copy */ back_pipeline = cogl_pipeline_copy (priv->back_pipeline); cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL); cogl_pipeline_set_cull_face_mode (back_pipeline, COGL_PIPELINE_CULL_FACE_MODE_FRONT); cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive); cogl_object_unref (back_pipeline); } if (G_UNLIKELY (priv->lines_primitive != NULL)) { CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0); cogl_framebuffer_draw_primitive (fb, lines_pipeline, priv->lines_primitive); cogl_object_unref (lines_pipeline); } }
/* XXX: it's expected that we'll deprecated this with * cogl_framebuffer_clear at some point. */ void cogl_clear (const CoglColor *color, unsigned long buffers) { cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color); }