gdk: Add GdkCairoContext

This does nothing but disallow passing NULL to gdk_surface_begin_paint()
and instead require this context.

The ultimate goal is to split out Cairo drawing into its own source file
so it doesn't clutter up the generic rendering path.
This commit is contained in:
Benjamin Otte 2018-04-12 00:16:43 +02:00
parent 2210b9a302
commit f396786051
11 changed files with 252 additions and 22 deletions

View File

@ -1201,6 +1201,14 @@ GDK_DRAWING_CONTEXT
GDK_IS_DRAWING_CONTEXT
</SECTION>
<SECTION>
<FILE>gdkcairocontext</FILE>
GdkCairoContext
<SUBSECTION Standard>
gdk_cairo_context_get_type
</SECTION>
<SECTION>
<FILE>gdkvulkancontext</FILE>
GdkVulkanContext

View File

@ -31,6 +31,7 @@
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkapplaunchcontext.h>
#include <gdk/gdkcairo.h>
#include <gdk/gdkcairocontext.h>
#include <gdk/gdkclipboard.h>
#include <gdk/gdkcontentdeserializer.h>
#include <gdk/gdkcontentformats.h>

102
gdk/gdkcairocontext.c Normal file
View File

@ -0,0 +1,102 @@
/* GDK - The GIMP Drawing Kit
*
* gdkcairocontext.c: Cairo wrappers
*
* Copyright © 2018 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkcairocontext.h"
#include "gdkcairocontextprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkinternals.h"
#include "gdkintl.h"
/**
* SECTION:gdkcairocontext
* @Title: GdkCairoContext
* @Short_description: Cairo draw context
*
* #GdkCairoContext is an object representing the platform-specific
* draw context.
*
* #GdkCairoContexts are created for a #GdkDisplay using
* gdk_surface_create_cairo_context(), and the context can then be used
* to draw on that #GdkSurface.
*/
/**
* GdkCairoContext:
*
* The GdkCairoContext struct contains only private fields and should not
* be accessed directly.
*/
typedef struct _GdkCairoContextPrivate GdkCairoContextPrivate;
struct _GdkCairoContextPrivate {
gpointer unused;
};
G_DEFINE_TYPE_WITH_CODE (GdkCairoContext, gdk_cairo_context, GDK_TYPE_DRAW_CONTEXT,
G_ADD_PRIVATE (GdkCairoContext))
void
gdk_surface_begin_paint_internal (GdkSurface *surface,
const cairo_region_t *region);
static void
gdk_cairo_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *region)
{
gdk_surface_begin_paint_internal (gdk_draw_context_get_surface (draw_context),
region);
}
void
gdk_surface_end_paint_internal (GdkSurface *surface);
static void
gdk_cairo_context_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted,
cairo_region_t *damage)
{
gdk_surface_end_paint_internal (gdk_draw_context_get_surface (draw_context));
}
static void
gdk_cairo_context_surface_resized (GdkDrawContext *draw_context)
{
}
static void
gdk_cairo_context_class_init (GdkCairoContextClass *klass)
{
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
draw_context_class->begin_frame = gdk_cairo_context_begin_frame;
draw_context_class->end_frame = gdk_cairo_context_end_frame;
draw_context_class->surface_resized = gdk_cairo_context_surface_resized;
}
static void
gdk_cairo_context_init (GdkCairoContext *self)
{
}

47
gdk/gdkcairocontext.h Normal file
View File

@ -0,0 +1,47 @@
/* GDK - The GIMP Drawing Kit
*
* gdkcairocontext.h: specific Cairo wrappers
*
* Copyright © 2018 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CAIRO_CONTEXT__
#define __GDK_CAIRO_CONTEXT__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <cairo/cairo.h>
G_BEGIN_DECLS
#define GDK_TYPE_CAIRO_CONTEXT (gdk_cairo_context_get_type ())
#define GDK_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContext))
#define GDK_IS_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CAIRO_CONTEXT))
#define GDK_CAIRO_ERROR (gdk_cairo_error_quark ())
GDK_AVAILABLE_IN_ALL
GType gdk_cairo_context_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GDK_CAIRO_CONTEXT__ */

View File

@ -0,0 +1,50 @@
/* GDK - The GIMP Drawing Kit
*
* gdkcairocontextprivate.h: specific Cairo wrappers
*
* Copyright © 2018 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_CAIRO_CONTEXT_PRIVATE__
#define __GDK_CAIRO_CONTEXT_PRIVATE__
#include "gdkcairocontext.h"
#include "gdkdrawcontextprivate.h"
#include <cairo/cairo.h>
G_BEGIN_DECLS
#define GDK_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContextClass))
#define GDK_IS_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CAIRO_CONTEXT))
#define GDK_CAIRO_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContextClass))
typedef struct _GdkCairoContextClass GdkCairoContextClass;
struct _GdkCairoContext
{
GdkDrawContext parent_instance;
};
struct _GdkCairoContextClass
{
GdkDrawContextClass parent_class;
};
G_END_DECLS
#endif /* __GDK__CAIRO_CONTEXT_PRIVATE__ */

View File

@ -232,7 +232,7 @@ gdk_drawing_context_get_cairo_context (GdkDrawingContext *context)
g_return_val_if_fail (GDK_IS_DRAWING_CONTEXT (context), NULL);
g_return_val_if_fail (GDK_IS_SURFACE (priv->surface), NULL);
if (priv->paint_context != NULL)
if (!GDK_IS_CAIRO_CONTEXT (priv->paint_context))
return NULL;
if (priv->cr == NULL)

View File

@ -1496,7 +1496,7 @@ gdk_surface_get_paint_gl_context (GdkSurface *surface,
* %NULL on error
**/
GdkGLContext *
gdk_surface_create_gl_context (GdkSurface *surface,
gdk_surface_create_gl_context (GdkSurface *surface,
GError **error)
{
GdkGLContext *paint_context;
@ -1509,9 +1509,17 @@ gdk_surface_create_gl_context (GdkSurface *surface,
return NULL;
return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->create_gl_context (surface->impl_surface,
FALSE,
paint_context,
error);
FALSE,
paint_context,
error);
}
GdkCairoContext *
gdk_surface_create_cairo_context (GdkSurface *surface)
{
return g_object_new (GDK_TYPE_CAIRO_CONTEXT,
"surface", surface,
NULL);
}
/**
@ -1558,7 +1566,10 @@ gdk_surface_create_vulkan_context (GdkSurface *surface,
NULL);
}
static void
void
gdk_surface_begin_paint_internal (GdkSurface *surface,
const cairo_region_t *region);
void
gdk_surface_begin_paint_internal (GdkSurface *surface,
const cairo_region_t *region)
{
@ -1609,7 +1620,9 @@ gdk_surface_begin_paint_internal (GdkSurface *surface,
gdk_surface_clear_backing_region (surface);
}
static void
void
gdk_surface_end_paint_internal (GdkSurface *surface);
void
gdk_surface_end_paint_internal (GdkSurface *surface)
{
GdkSurfaceImplClass *impl_class;
@ -1688,7 +1701,7 @@ gdk_surface_end_paint_internal (GdkSurface *surface)
* by GDK.
*/
GdkDrawingContext *
gdk_surface_begin_draw_frame (GdkSurface *surface,
gdk_surface_begin_draw_frame (GdkSurface *surface,
GdkDrawContext *draw_context,
const cairo_region_t *region)
{
@ -1698,12 +1711,9 @@ gdk_surface_begin_draw_frame (GdkSurface *surface,
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
g_return_val_if_fail (gdk_surface_has_native (surface), NULL);
g_return_val_if_fail (gdk_surface_is_toplevel (surface), NULL);
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL);
g_return_val_if_fail (gdk_draw_context_get_surface (draw_context) == surface, NULL);
g_return_val_if_fail (region != NULL, NULL);
if (draw_context != NULL)
{
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL);
g_return_val_if_fail (gdk_draw_context_get_surface (draw_context) == surface, NULL);
}
if (GDK_SURFACE_DESTROYED (surface))
return NULL;
@ -1718,10 +1728,7 @@ gdk_surface_begin_draw_frame (GdkSurface *surface,
real_region = cairo_region_copy (region);
if (draw_context)
gdk_draw_context_begin_frame (draw_context, real_region);
else
gdk_surface_begin_paint_internal (surface, real_region);
gdk_draw_context_begin_frame (draw_context, real_region);
context = g_object_new (GDK_TYPE_DRAWING_CONTEXT,
"surface", surface,
@ -1784,7 +1791,6 @@ gdk_surface_end_draw_frame (GdkSurface *surface,
}
else
{
gdk_surface_end_paint_internal (surface);
}
surface->drawing_context = NULL;

View File

@ -843,11 +843,13 @@ gboolean gdk_surface_show_window_menu (GdkSurface *surface,
GdkEvent *event);
GDK_AVAILABLE_IN_ALL
GdkGLContext * gdk_surface_create_gl_context (GdkSurface *surface,
GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkGLContext * gdk_surface_create_gl_context (GdkSurface *surface,
GError **error);
GDK_AVAILABLE_IN_ALL
GdkVulkanContext *
gdk_surface_create_vulkan_context(GdkSurface *surface,
gdk_surface_create_vulkan_context(GdkSurface *surface,
GError **error);
G_END_DECLS

View File

@ -136,6 +136,7 @@ typedef struct _GdkSnapshot GdkSnapshot;
typedef struct _GdkDrawingContext GdkDrawingContext;
typedef struct _GdkDrawContext GdkDrawContext;
typedef struct _GdkCairoContext GdkCairoContext;
typedef struct _GdkGLContext GdkGLContext;
typedef struct _GdkVulkanContext GdkVulkanContext;

View File

@ -2,6 +2,7 @@ gdk_public_sources = files([
'gdk.c',
'gdkapplaunchcontext.c',
'gdkcairo.c',
'gdkcairocontext.c',
'gdkclipboard.c',
'gdkcontentdeserializer.c',
'gdkcontentformats.c',
@ -51,6 +52,7 @@ gdk_public_headers = files([
'gdk.h',
'gdkapplaunchcontext.h',
'gdkcairo.h',
'gdkcairocontext.h',
'gdkclipboard.h',
'gdkcontentdeserializer.h',
'gdkcontentformats.h',

View File

@ -18,6 +18,8 @@ struct _GskCairoRenderer
{
GskRenderer parent_instance;
GdkCairoContext *cairo_context;
#ifdef G_ENABLE_DEBUG
ProfileTimers profile_timers;
#endif
@ -32,16 +34,22 @@ G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER)
static gboolean
gsk_cairo_renderer_realize (GskRenderer *renderer,
GdkSurface *surface,
GdkSurface *surface,
GError **error)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
self->cairo_context = gdk_surface_create_cairo_context (surface);
return TRUE;
}
static void
gsk_cairo_renderer_unrealize (GskRenderer *renderer)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
g_clear_object (&self->cairo_context);
}
static void
@ -99,11 +107,14 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *region)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
GdkSurface *surface = gsk_renderer_get_surface (renderer);
GdkDrawingContext *context;
cairo_t *cr;
context = gdk_surface_begin_draw_frame (surface, NULL, region);
context = gdk_surface_begin_draw_frame (surface,
GDK_DRAW_CONTEXT (self->cairo_context),
region);
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);