gdk_surface_create_gl_context
gdk_surface_create_vulkan_context
-<SUBSECTION>
-gdk_surface_begin_draw_frame
-gdk_surface_end_draw_frame
-
<SUBSECTION>
gdk_surface_invalidate_rect
gdk_surface_invalidate_region
GdkDrawContext
gdk_draw_context_get_display
gdk_draw_context_get_surface
+gdk_draw_context_begin_frame
+gdk_draw_context_end_frame
gdk_draw_context_get_frame_region
<SUBSECTION Standard>
surface = gdk_draw_context_get_surface (draw_context);
if (surface->current_paint.surface == NULL)
{
- g_warning (G_STRLOC": no preceding call to gdk_surface_begin_draw_frame(), see documentation");
+ g_warning (G_STRLOC": no preceding call to gdk_draw_context_end_frame(), see documentation");
return;
}
* @context: a #GdkCairoContext that is currently drawing
*
* Retrieves a Cairo context to be used to draw on the #GdkSurface
- * of @context. A call to gdk_surface_begin_draw_frame() with this
+ * of @context. A call to gdk_draw_context_begin_frame() with this
* @context must have been done or this function will return %NULL.
*
* The returned context is guaranteed to be valid until
- * gdk_surface_end_draw_frame() is called.
+ * gdk_draw_context_end_frame() is called.
*
* Returns: (transfer full) (nullable): a Cairo context to be used
* to draw the contents of the #GdkSurface. %NULL is returned
return priv->is_drawing;
}
-/*< private >
- * gdk_draw_context_begin_frame:
- * @context: a #GdkDrawContext
- * @region: (inout): The clip region that needs to be repainted
- *
- * Sets up @context and @drawing for a new drawing.
- *
- * The @context is free to update @region to the size that actually needs to
- * be repainted. Contexts that do not support partial blits for example may
- * want to invalidate the whole surface instead.
- *
- * The function does not clear the background. Clearing the backgroud is the
- * job of the renderer. The contents of the backbuffer are undefined after this
- * function call.
- */
-void
-gdk_draw_context_begin_frame (GdkDrawContext *context,
- cairo_region_t *region)
-{
- GdkDrawContextPrivate *priv;
-
- g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
- g_return_if_fail (region != NULL);
-
- priv = gdk_draw_context_get_instance_private (context);
- priv->is_drawing = TRUE;
-
- GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, region);
-}
-
-/*< private >
- * gdk_draw_context_end_frame:
- * @context: a #GdkDrawContext
- * @painted: The area that has been redrawn this frame
- * @damage: The area that we know is actually different from the last frame
- *
- * Copies the back buffer to the front buffer.
- *
- * This function may call `glFlush()` implicitly before returning; it
- * is not recommended to call `glFlush()` explicitly before calling
- * this function.
- */
-void
-gdk_draw_context_end_frame (GdkDrawContext *context,
- cairo_region_t *painted,
- cairo_region_t *damage)
-{
- GdkDrawContextPrivate *priv;
-
- g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
-
- GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage);
-
- priv = gdk_draw_context_get_instance_private (context);
- priv->is_drawing = FALSE;
-}
-
/*< private >
* gdk_draw_context_surface_resized:
* @context: a #GdkDrawContext
return priv->surface;
}
+/**
+ * gdk_draw_context_begin_frame:
+ * @context: the context used to draw the frame
+ * @region: minimum region that should be drawn
+ *
+ * Indicates that you are beginning the process of redrawing @region
+ * on the @context's surface.
+ *
+ * Calling this function begins a drawing operation using @context on the
+ * surface that @context was created from. The actual requirements and
+ * guarantees for the drawing operation vary for different implementations
+ * of drawing, so a #GdkCairoContext and a #GdkGLContext need to be treated
+ * differently.
+ *
+ * A call to this function is a requirement for drawing and must be followed
+ * by a call to gdk_draw_context_end_frame(), which will complete the
+ * drawing operation and ensure the contents become visible on screen.
+ *
+ * Note that the @region passed to this function is the minimum region that
+ * needs to be drawn and depending on implementation, windowing system and
+ * hardware in use, it might be necessary to draw a larger region. Drawing
+ * implementation must use gdk_draw_context_get_frame_region() to query the
+ * region that must be drawn.
+ *
+ * When using GTK+, the widget system automatically places calls to
+ * gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
+ * use of #GskRenderers, so application code does not need to call these
+ * functions explicitly.
+ */
+void
+gdk_draw_context_begin_frame (GdkDrawContext *context,
+ const cairo_region_t *region)
+{
+ GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
+
+ g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
+ g_return_if_fail (region != NULL);
+
+ if (GDK_SURFACE_DESTROYED (priv->surface))
+ return;
+
+ if (priv->surface->paint_context != NULL)
+ {
+ if (priv->surface->paint_context == context)
+ {
+ g_critical ("The surface %p is already drawing. You must finish the "
+ "previous drawing operation with gdk_draw_context_end_frame() first.",
+ priv->surface);
+ }
+ else
+ {
+ g_critical ("The surface %p is already being drawn by %s %p. "
+ "You cannot draw s surface wih multiple contexts at the same time.",
+ priv->surface,
+ G_OBJECT_TYPE_NAME (priv->surface->paint_context), priv->surface->paint_context);
+ }
+ return;
+ }
+
+ context->frame_region = cairo_region_copy (region);
+ priv->is_drawing = TRUE;
+ priv->surface->paint_context = g_object_ref (context);
+
+ GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, context->frame_region);
+}
+
+/**
+ * gdk_draw_context_end_frame:
+ * @context: a #GdkDrawContext
+ *
+ * Ends a drawing operation started with gdk_draw_context_begin_frame()
+ * and makes the drawing available on screen. See that function for more
+ * details about drawing.
+ *
+ * When using a #GdkGLContext, this function may call `glFlush()`
+ * implicitly before returning; it is not recommended to call `glFlush()`
+ * explicitly before calling this function.
+ */
+void
+gdk_draw_context_end_frame (GdkDrawContext *context)
+{
+ GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
+
+ g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
+
+ if (GDK_SURFACE_DESTROYED (priv->surface))
+ return;
+
+ if (priv->surface->paint_context == NULL)
+ {
+ g_critical ("The surface %p has no drawing context. You must call "
+ "gdk_draw_context_begin_frame() before calling "
+ "gdk_draw_context_end_frame().", priv->surface);
+ return;
+ }
+ else if (priv->surface->paint_context != context)
+ {
+ g_critical ("The surface %p is not drawn by this context but by %s %p.",
+ priv->surface,
+ G_OBJECT_TYPE_NAME (priv->surface->paint_context), priv->surface->paint_context);
+ return;
+ }
+
+ GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context,
+ context->frame_region,
+ priv->surface->active_update_area);
+
+
+ priv->is_drawing = FALSE;
+ g_clear_pointer (&context->frame_region, cairo_region_destroy);
+ g_clear_object (&priv->surface->paint_context);
+}
+
/**
* gdk_draw_context_get_frame_region:
* @context: a #GdkDrawContext
GType gdk_draw_context_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
-GdkDisplay * gdk_draw_context_get_display (GdkDrawContext *context);
+GdkDisplay * gdk_draw_context_get_display (GdkDrawContext *context);
GDK_AVAILABLE_IN_ALL
-GdkSurface * gdk_draw_context_get_surface (GdkDrawContext *context);
+GdkSurface * gdk_draw_context_get_surface (GdkDrawContext *context);
GDK_AVAILABLE_IN_ALL
-const cairo_region_t * gdk_draw_context_get_frame_region (GdkDrawContext *context);
+void gdk_draw_context_begin_frame (GdkDrawContext *context,
+ const cairo_region_t *region);
+GDK_AVAILABLE_IN_ALL
+void gdk_draw_context_end_frame (GdkDrawContext *context);
+GDK_AVAILABLE_IN_ALL
+const cairo_region_t * gdk_draw_context_get_frame_region (GdkDrawContext *context);
G_END_DECLS
};
gboolean gdk_draw_context_is_drawing (GdkDrawContext *context);
-void gdk_draw_context_begin_frame (GdkDrawContext *context,
- cairo_region_t *region);
-void gdk_draw_context_end_frame (GdkDrawContext *context,
- cairo_region_t *painted,
- cairo_region_t *damage);
void gdk_draw_context_surface_resized (GdkDrawContext *context);
shared = gdk_gl_context_get_shared_context (context);
if (shared)
{
- gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (shared), region);
+ GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->begin_frame (GDK_DRAW_CONTEXT (shared), region);
return;
}
shared = gdk_gl_context_get_shared_context (context);
if (shared)
{
- gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (shared), painted, damage);
+ GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->end_frame (GDK_DRAW_CONTEXT (shared), painted, damage);
return;
}
NULL);
}
-/**
- * gdk_surface_begin_draw_frame:
- * @surface: a #GdkSurface
- * @context: (allow-none): the context used to draw the frame
- * @region: a Cairo region
- *
- * Indicates that you are beginning the process of redrawing @region
- * on @surface.
- *
- * If @surface is a top level #GdkSurface, backed by a native surface
- * implementation, a backing store (offscreen buffer) large enough to
- * contain @region will be created. The backing store will be initialized
- * with the background color or background surface for @surface. Then, all
- * drawing operations performed on @surface will be diverted to the
- * backing store. When you call gdk_surface_end_frame(), the contents of
- * the backing store will be copied to @surface, making it visible
- * on screen. Only the part of @surface contained in @region will be
- * modified; that is, drawing operations are clipped to @region.
- *
- * The net result of all this is to remove flicker, because the user
- * sees the finished product appear all at once when you call
- * gdk_surface_end_draw_frame(). If you draw to @surface directly without
- * calling gdk_surface_begin_draw_frame(), the user may see flicker
- * as individual drawing operations are performed in sequence.
- *
- * When using GTK+, the widget system automatically places calls to
- * gdk_surface_begin_draw_frame() and gdk_surface_end_draw_frame() around
- * emissions of the `GtkWidget::draw` signal. That is, if you’re
- * drawing the contents of the widget yourself, you can assume that the
- * widget has a cleared background, is already set as the clip region,
- * and already has a backing store. Therefore in most cases, application
- * code in GTK does not need to call gdk_surface_begin_draw_frame()
- * explicitly.
- */
-void
-gdk_surface_begin_draw_frame (GdkSurface *surface,
- GdkDrawContext *draw_context,
- const cairo_region_t *region)
-{
- g_return_if_fail (GDK_IS_SURFACE (surface));
- g_return_if_fail (gdk_surface_has_native (surface));
- g_return_if_fail (gdk_surface_is_toplevel (surface));
- g_return_if_fail (GDK_IS_DRAW_CONTEXT (draw_context));
- g_return_if_fail (gdk_draw_context_get_surface (draw_context) == surface);
- g_return_if_fail (region != NULL);
-
- if (GDK_SURFACE_DESTROYED (surface))
- return;
-
- if (surface->paint_context != NULL)
- {
- g_critical ("The surface %p already has a drawing context. You cannot "
- "call gdk_surface_begin_draw_frame() without calling "
- "gdk_surface_end_draw_frame() first.", surface);
- return;
- }
-
- draw_context->frame_region = cairo_region_copy (region);
-
- gdk_draw_context_begin_frame (draw_context, draw_context->frame_region);
-
- surface->paint_context = g_object_ref (draw_context);
-}
-
-/**
- * gdk_surface_end_draw_frame:
- * @surface: a #GdkSurface
- *
- * Indicates that the drawing of the contents of @surface started with
- * gdk_surface_begin_frame() has been completed.
- *
- * It is an error to call this function without a matching
- * gdk_surface_begin_frame() first.
- */
-void
-gdk_surface_end_draw_frame (GdkSurface *surface)
-{
- GdkDrawContext *paint_context;
-
- g_return_if_fail (GDK_IS_SURFACE (surface));
-
- if (GDK_SURFACE_DESTROYED (surface))
- return;
-
- if (surface->paint_context == NULL)
- {
- g_critical ("The surface %p has no drawing context. You must call "
- "gdk_surface_begin_draw_frame() before calling "
- "gdk_surface_end_draw_frame().", surface);
- return;
- }
-
- paint_context = g_steal_pointer (&surface->paint_context);
- gdk_draw_context_end_frame (paint_context,
- paint_context->frame_region,
- surface->active_update_area);
-
- g_clear_pointer (&paint_context->frame_region, cairo_region_destroy);
- g_object_unref (paint_context);
-}
-
/*< private >
* gdk_surface_get_current_paint_region:
* @surface: a #GdkSurface
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
-GDK_AVAILABLE_IN_ALL
-void gdk_surface_begin_draw_frame (GdkSurface *surface,
- GdkDrawContext *context,
- const cairo_region_t *region);
-GDK_AVAILABLE_IN_ALL
-void gdk_surface_end_draw_frame (GdkSurface *surface);
-
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_title (GdkSurface *surface,
const gchar *title);
*
* Gets the index of the image that is currently being drawn.
*
- * This function can only be used between gdk_surface_begin_draw_frame() and
- * gdk_surface_end_draw_frame() calls for the toplevel surface that the
- * @context is associated with.
+ * This function can only be used between gdk_cairo_context_begin_frame() and
+ * gdk_draw_context_end_frame() calls.
*
* Returns: the index of the images that is being drawn
*/
* Gets the Vulkan semaphore that protects access to the image that is
* currently being drawn.
*
- * This function can only be used between gdk_surface_begin_draw_frame() and
- * gdk_surface_end_draw_frame() calls for the toplevel surface that the
- * @context is associated with.
+ * This function can only be used between gdk_cairo_context_begin_frame() and
+ * gdk_draw_context_end_frame() calls.
*
* Returns: (transfer none): the VkSemaphore
*/
gdk_surface_get_height (surface) * self->scale_factor
};
- gdk_surface_begin_draw_frame (surface,
- GDK_DRAW_CONTEXT (self->gl_context),
+ gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->gl_context),
update_area);
damage = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->gl_context));
gdk_gl_context_make_current (self->gl_context);
gsk_gl_renderer_clear_tree (self);
- gdk_surface_end_draw_frame (surface);
+ gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->gl_context));
g_clear_pointer (&self->render_region, cairo_region_destroy);
}
gdk_surface_get_width (surface),
gdk_surface_get_height (surface)
});
- gdk_surface_begin_draw_frame (surface, NULL, whole);
+ gdk_draw_context_begin_frame (NULL, whole);
cairo_region_destroy (whole);
nodes = g_array_new (FALSE, FALSE, sizeof(guint32));
g_array_unref (nodes);
g_ptr_array_unref (node_textures);
- gdk_surface_end_draw_frame (surface);
+ gdk_draw_context_end_frame (NULL);
}
static void
const cairo_region_t *region)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
- GdkSurface *surface = gsk_renderer_get_surface (renderer);
cairo_t *cr;
- gdk_surface_begin_draw_frame (surface,
- GDK_DRAW_CONTEXT (self->cairo_context),
+ gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->cairo_context),
region);
cr = gdk_cairo_context_cairo_create (self->cairo_context);
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (renderer, GEOMETRY))
{
+ GdkSurface *surface = gsk_renderer_get_surface (renderer);
+
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr,
cairo_destroy (cr);
- gdk_surface_end_draw_frame (surface);
+ gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->cairo_context));
}
static void
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GskVulkanRender *render;
- GdkSurface *surface;
const cairo_region_t *clip;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
#endif
- surface = gsk_renderer_get_surface (renderer);
-
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
gsk_profiler_counter_set (profiler, self->profile_counters.fallback_pixels, 0);
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
- gdk_surface_begin_draw_frame (surface,
- GDK_DRAW_CONTEXT (self->vulkan),
- region);
+ gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->vulkan), region);
render = self->render;
clip = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->vulkan));
gsk_profiler_push_samples (profiler);
#endif
- gdk_surface_end_draw_frame (surface);
+ gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->vulkan));
}
static void