gdk: Add GdkCairoContext
authorBenjamin Otte <otte@redhat.com>
Wed, 11 Apr 2018 22:16:43 +0000 (00:16 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 24 Apr 2018 21:16:12 +0000 (23:16 +0200)
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.

docs/reference/gdk/gdk4-sections.txt
gdk/gdk.h
gdk/gdkcairocontext.c [new file with mode: 0644]
gdk/gdkcairocontext.h [new file with mode: 0644]
gdk/gdkcairocontextprivate.h [new file with mode: 0644]
gdk/gdkdrawingcontext.c
gdk/gdksurface.c
gdk/gdksurface.h
gdk/gdktypes.h
gdk/meson.build
gsk/gskcairorenderer.c

index a6bcd8b82a186c12358376f9958607aae869024f..2cc4563ce86a27ef1b5671f4476b18012bd6cdd3 100644 (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
index 921e93690d34aaf0ec7d7d169f21d51693fc3336..8311ef23bd0d638355e3dcf4748cb42322d5095e 100644 (file)
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -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>
diff --git a/gdk/gdkcairocontext.c b/gdk/gdkcairocontext.c
new file mode 100644 (file)
index 0000000..281ef50
--- /dev/null
@@ -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)
+{
+}
+
diff --git a/gdk/gdkcairocontext.h b/gdk/gdkcairocontext.h
new file mode 100644 (file)
index 0000000..0d2948a
--- /dev/null
@@ -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__ */
diff --git a/gdk/gdkcairocontextprivate.h b/gdk/gdkcairocontextprivate.h
new file mode 100644 (file)
index 0000000..66cc322
--- /dev/null
@@ -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__ */
index 57740eeb340ad2d2d3c3995a90b43419702880b5..70569ba9cfae5107067ce1914d020ca7bab2ee8d 100644 (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)
index ed769e215e037af29912bd865c2f9b0861333de0..a818fb2d7de928f56f13f9b40d852cf4c1399b2a 100644 (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;
index e333608a99b1b14de9188aa85f96cd80243d6822..3775f20d5db8cd90156376686dc081af9bcf1e0a 100644 (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
index d4e3623309a168c4f7ba550da8671f34c924db04..f2081c1536d9d0ef7c69e8fe0e05cc2a83547740 100644 (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;
 
index d801d7592a2c327288376d0fced5c9242f4f7e74..0f22b2fe39153aa0e67ad4958e1f70a3dc5ba6cb 100644 (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',
index 5cf3d7822da65478c8af0abd2861b69359ef6463..f5871e49a89f959d194a680faf768f8bc068760d 100644 (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);