gdk: Split out GL texture

Put GdkGLTexture into its own file and rename the API to
gdk_gl_texture_foo() instead of gdk_texture_foo_for_gl().

Apart from naming, no actual code changes.
This commit is contained in:
Benjamin Otte 2018-03-05 14:38:38 +01:00
parent b49c6cdcb1
commit 160e6ad6f6
11 changed files with 305 additions and 232 deletions

View File

@ -51,6 +51,7 @@
#include <gdk/gdkframeclock.h>
#include <gdk/gdkframetimings.h>
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexture.h>
#include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkmonitor.h>

223
gdk/gdkgltexture.c Normal file
View File

@ -0,0 +1,223 @@
/* gdkgltexture.c
*
* Copyright 2016 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkgltextureprivate.h"
#include "gdkcairo.h"
#include "gdktextureprivate.h"
#include <epoxy/gl.h>
struct _GdkGLTexture {
GdkTexture parent_instance;
GdkGLContext *context;
guint id;
cairo_surface_t *saved;
GDestroyNotify destroy;
gpointer data;
};
struct _GdkGLTextureClass {
GdkTextureClass parent_class;
};
G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE)
static void
gdk_gl_texture_dispose (GObject *object)
{
GdkGLTexture *self = GDK_GL_TEXTURE (object);
if (self->destroy)
{
self->destroy (self->data);
self->destroy = NULL;
self->data = NULL;
}
g_clear_object (&self->context);
self->id = 0;
if (self->saved)
{
cairo_surface_destroy (self->saved);
self->saved = NULL;
}
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
}
static void
gdk_gl_texture_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
texture->width, texture->height,
stride);
cr = cairo_create (surface);
if (self->saved)
{
cairo_set_source_surface (cr, self->saved, 0, 0);
cairo_paint (cr);
}
else
{
GdkWindow *window;
window = gdk_gl_context_get_window (self->context);
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
texture->width, texture->height);
}
cairo_destroy (cr);
cairo_surface_finish (surface);
cairo_surface_destroy (surface);
}
static void
gdk_gl_texture_class_init (GdkGLTextureClass *klass)
{
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
texture_class->download = gdk_gl_texture_download;
gobject_class->dispose = gdk_gl_texture_dispose;
}
static void
gdk_gl_texture_init (GdkGLTexture *self)
{
}
GdkGLContext *
gdk_gl_texture_get_context (GdkGLTexture *self)
{
return self->context;
}
guint
gdk_gl_texture_get_id (GdkGLTexture *self)
{
return self->id;
}
/**
* gdk_gl_texture_release:
* @texture: a #GdkTexture wrapping a GL texture
*
* Releases the GL resources held by a #GdkTexture that
* was created with gdk_texture_new_for_gl().
*
* The texture contents are still available via the
* gdk_texture_download() function, after this function
* has been called.
*/
void
gdk_gl_texture_release (GdkTexture *texture)
{
GdkGLTexture *self;
GdkWindow *window;
cairo_t *cr;
g_return_if_fail (GDK_IS_GL_TEXTURE (texture));
self = GDK_GL_TEXTURE (texture);
g_return_if_fail (self->saved == NULL);
self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
cr = cairo_create (self->saved);
window = gdk_gl_context_get_window (self->context);
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
texture->width, texture->height);
cairo_destroy (cr);
if (self->destroy)
{
self->destroy (self->data);
self->destroy = NULL;
self->data = NULL;
}
g_clear_object (&self->context);
self->id = 0;
}
/**
* gdk_gl_texture_new:
* @context: a #GdkGLContext
* @id: the ID of a texture that was created with @context
* @width: the nominal width of the texture
* @height: the nominal height of the texture
* @destroy: a destroy notify that will be called when the GL resources
* are released
* @data: data that gets passed to @destroy
*
* Creates a new texture for an existing GL texture.
*
* Note that the GL texture must not be modified until @destroy is called,
* which will happen when the GdkTexture object is finalized, or due to
* an explicit call of gdk_texture_release_gl().
*
* Return value: A newly-created #GdkTexture
**/
GdkTexture *
gdk_gl_texture_new (GdkGLContext *context,
guint id,
int width,
int height,
GDestroyNotify destroy,
gpointer data)
{
GdkGLTexture *self;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
g_return_val_if_fail (id != 0, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", width,
"height", height,
NULL);
self->context = g_object_ref (context);
self->id = id;
self->destroy = destroy;
self->data = data;
return GDK_TEXTURE (self);
}

46
gdk/gdkgltexture.h Normal file
View File

@ -0,0 +1,46 @@
/* gdktexture.h
*
* Copyright 2016 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_GL_TEXTURE_H__
#define __GDK_GL_TEXTURE_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
#include <gdk/gdkglcontext.h>
G_BEGIN_DECLS
GDK_AVAILABLE_IN_ALL
GdkTexture * gdk_gl_texture_new (GdkGLContext *context,
guint id,
int width,
int height,
GDestroyNotify destroy,
gpointer data);
GDK_AVAILABLE_IN_ALL
void gdk_gl_texture_release (GdkTexture *texture);
G_END_DECLS
#endif /* __GDK_GL_TEXTURE_H__ */

19
gdk/gdkgltextureprivate.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __GDK_GL_TEXTURE_PRIVATE_H__
#define __GDK_GL_TEXTURE_PRIVATE_H__
#include "gdkgltexture.h"
#include "gdktextureprivate.h"
G_BEGIN_DECLS
#define GDK_TYPE_GL_TEXTURE (gdk_gl_texture_get_type ())
G_DECLARE_FINAL_TYPE (GdkGLTexture, gdk_gl_texture, GDK, GL_TEXTURE, GdkTexture)
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
guint gdk_gl_texture_get_id (GdkGLTexture *self);
G_END_DECLS
#endif /* __GDK_GL_TEXTURE_PRIVATE_H__ */

View File

@ -36,10 +36,8 @@
#include "gdktextureprivate.h"
#include "gdkinternals.h"
#include "gdkcairo.h"
#include <epoxy/gl.h>
#include "gdkinternals.h"
/**
* SECTION:gdktexture
@ -429,159 +427,6 @@ gdk_pixbuf_texture_init (GdkPixbufTexture *self)
{
}
/* GdkGLTexture */
struct _GdkGLTexture {
GdkTexture parent_instance;
GdkGLContext *context;
guint id;
cairo_surface_t *saved;
GDestroyNotify destroy;
gpointer data;
};
struct _GdkGLTextureClass {
GdkTextureClass parent_class;
};
G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE)
static void
gdk_gl_texture_dispose (GObject *object)
{
GdkGLTexture *self = GDK_GL_TEXTURE (object);
if (self->destroy)
{
self->destroy (self->data);
self->destroy = NULL;
self->data = NULL;
}
g_clear_object (&self->context);
self->id = 0;
if (self->saved)
{
cairo_surface_destroy (self->saved);
self->saved = NULL;
}
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
}
static void
gdk_gl_texture_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
texture->width, texture->height,
stride);
cr = cairo_create (surface);
if (self->saved)
{
cairo_set_source_surface (cr, self->saved, 0, 0);
cairo_paint (cr);
}
else
{
GdkWindow *window;
window = gdk_gl_context_get_window (self->context);
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
texture->width, texture->height);
}
cairo_destroy (cr);
cairo_surface_finish (surface);
cairo_surface_destroy (surface);
}
static void
gdk_gl_texture_class_init (GdkGLTextureClass *klass)
{
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
texture_class->download = gdk_gl_texture_download;
gobject_class->dispose = gdk_gl_texture_dispose;
}
static void
gdk_gl_texture_init (GdkGLTexture *self)
{
}
GdkGLContext *
gdk_gl_texture_get_context (GdkGLTexture *self)
{
return self->context;
}
guint
gdk_gl_texture_get_id (GdkGLTexture *self)
{
return self->id;
}
/**
* gdk_texture_release_gl:
* @texture: a #GdkTexture wrapping a GL texture
*
* Releases the GL resources held by a #GdkTexture that
* was created with gdk_texture_new_for_gl().
*
* The texture contents are still available via the
* gdk_texture_download() function, after this function
* has been called.
*/
void
gdk_texture_release_gl (GdkTexture *texture)
{
GdkGLTexture *self;
GdkWindow *window;
cairo_t *cr;
g_return_if_fail (GDK_IS_GL_TEXTURE (texture));
self = GDK_GL_TEXTURE (texture);
g_return_if_fail (self->saved == NULL);
self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
cr = cairo_create (self->saved);
window = gdk_gl_context_get_window (self->context);
gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
texture->width, texture->height);
cairo_destroy (cr);
if (self->destroy)
{
self->destroy (self->data);
self->destroy = NULL;
self->data = NULL;
}
g_clear_object (&self->context);
self->id = 0;
}
/**
* gdk_texture_new_for_pixbuf:
* @pixbuf: a #GdkPixbuf
@ -676,52 +521,6 @@ gdk_texture_new_from_file (GFile *file,
return texture;
}
/**
* gdk_texture_new_for_gl:
* @context: a #GdkGLContext
* @id: the ID of a texture that was created with @context
* @width: the nominal width of the texture
* @height: the nominal height of the texture
* @destroy: a destroy notify that will be called when the GL resources
* are released
* @data: data that gets passed to @destroy
*
* Creates a new texture for an existing GL texture.
*
* Note that the GL texture must not be modified until @destroy is called,
* which will happen when the GdkTexture object is finalized, or due to
* an explicit call of gdk_texture_release_gl().
*
* Return value: A newly-created #GdkTexture
**/
GdkTexture *
gdk_texture_new_for_gl (GdkGLContext *context,
guint id,
int width,
int height,
GDestroyNotify destroy,
gpointer data)
{
GdkGLTexture *self;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
g_return_val_if_fail (id != 0, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", width,
"height", height,
NULL);
self->context = g_object_ref (context);
self->id = id;
self->destroy = destroy;
self->data = data;
return GDK_TEXTURE (self);
}
/**
* gdk_texture_get_width:
* @texture: a #GdkTexture

View File

@ -26,7 +26,6 @@
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkglcontext.h>
G_BEGIN_DECLS
@ -56,17 +55,6 @@ GDK_AVAILABLE_IN_ALL
GdkTexture * gdk_texture_new_from_file (GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GdkTexture * gdk_texture_new_for_gl (GdkGLContext *context,
guint id,
int width,
int height,
GDestroyNotify destroy,
gpointer data);
GDK_AVAILABLE_IN_ALL
void gdk_texture_release_gl (GdkTexture *texture);
GDK_AVAILABLE_IN_ALL
int gdk_texture_get_width (GdkTexture *texture);
GDK_AVAILABLE_IN_ALL

View File

@ -44,13 +44,6 @@ void gdk_texture_clear_render_data (GdkTexture
gpointer gdk_texture_get_render_data (GdkTexture *self,
gpointer key);
#define GDK_TYPE_GL_TEXTURE (gdk_gl_texture_get_type ())
G_DECLARE_FINAL_TYPE (GdkGLTexture, gdk_gl_texture, GDK, GL_TEXTURE, GdkTexture)
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
guint gdk_gl_texture_get_id (GdkGLTexture *self);
G_END_DECLS
#endif /* __GDK_TEXTURE_PRIVATE_H__ */

View File

@ -24,6 +24,7 @@ gdk_public_sources = files([
'gdkgl.c',
'gdkglcontext.c',
'gdkglobals.c',
'gdkgltexture.c',
'gdkkeys.c',
'gdkkeyuni.c',
'gdkmonitor.c',
@ -66,6 +67,7 @@ gdk_public_headers = files([
'gdkframeclock.h',
'gdkframetimings.h',
'gdkglcontext.h',
'gdkgltexture.h',
'gdkkeys.h',
'gdkkeysyms.h',
'gdkmonitor.h',

View File

@ -5,6 +5,7 @@
#include "gskdebugprivate.h"
#include "gskprofilerprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkgltextureprivate.h"
#include <gdk/gdk.h>
#include <epoxy/gl.h>

View File

@ -11,12 +11,13 @@
#include "gskrendernodeprivate.h"
#include "gskshaderbuilderprivate.h"
#include "gskglglyphcacheprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gskglrenderopsprivate.h"
#include "gskcairoblurprivate.h"
#include "gskprivate.h"
#include "gdk/gdkgltextureprivate.h"
#include <epoxy/gl.h>
#include <cairo-ft.h>
@ -2573,10 +2574,10 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
/* Render the actual scene */
gsk_gl_renderer_do_render (renderer, root, viewport, texture_id, 1);
texture = gdk_texture_new_for_gl (self->gl_context,
texture_id,
width, height,
NULL, NULL);
texture = gdk_gl_texture_new (self->gl_context,
texture_id,
width, height,
NULL, NULL);
gsk_gl_renderer_clear_tree (self);
return texture;

View File

@ -386,7 +386,7 @@ delete_one_texture (gpointer data)
Texture *texture = data;
if (texture->holder)
gdk_texture_release_gl (texture->holder);
gdk_gl_texture_release (texture->holder);
if (texture->id != 0)
{
@ -735,11 +735,11 @@ gtk_gl_area_snapshot (GtkWidget *widget,
priv->texture = NULL;
priv->textures = g_list_prepend (priv->textures, texture);
texture->holder = gdk_texture_new_for_gl (priv->context,
texture->id,
texture->width,
texture->height,
release_texture, texture);
texture->holder = gdk_gl_texture_new (priv->context,
texture->id,
texture->width,
texture->height,
release_texture, texture);
gtk_snapshot_append_texture (snapshot,
texture->holder,