mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
Merge branch 'gles-texture-colors' into 'master'
Fix uploads of textures in GLES (and make texture uploads better) See merge request GNOME/gtk!2616
This commit is contained in:
commit
c9f6a9f7c5
@ -300,7 +300,6 @@ gdk_cairo_rectangle
|
|||||||
gdk_cairo_region
|
gdk_cairo_region
|
||||||
gdk_cairo_region_create_from_surface
|
gdk_cairo_region_create_from_surface
|
||||||
gdk_cairo_draw_from_gl
|
gdk_cairo_draw_from_gl
|
||||||
gdk_cairo_surface_upload_to_gl
|
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
@ -61,13 +61,6 @@ void gdk_cairo_draw_from_gl (cairo_t *cr,
|
|||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
void gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface,
|
|
||||||
int target,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
GdkGLContext *context);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_CAIRO_H__ */
|
#endif /* __GDK_CAIRO_H__ */
|
||||||
|
48
gdk/gdkgl.c
48
gdk/gdkgl.c
@ -438,51 +438,3 @@ out:
|
|||||||
if (clip_region)
|
if (clip_region)
|
||||||
cairo_region_destroy (clip_region);
|
cairo_region_destroy (clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gdk_cairo_surface_upload_to_gl:
|
|
||||||
* @surface: a Cairo surface
|
|
||||||
* @target: a GL texture target
|
|
||||||
* @width: the width of the texture @target
|
|
||||||
* @height: the height of the texture @target
|
|
||||||
* @context: (nullable): a #GdkGLContext, or %NULL to use the currently
|
|
||||||
* bound context
|
|
||||||
*
|
|
||||||
* Uploads the contents of a Cairo @surface to a GL texture @target.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface,
|
|
||||||
int target,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
GdkGLContext *context)
|
|
||||||
{
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
cairo_surface_t *tmp;
|
|
||||||
double device_x_offset, device_y_offset;
|
|
||||||
|
|
||||||
g_return_if_fail (surface != NULL);
|
|
||||||
g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context));
|
|
||||||
|
|
||||||
if (context == NULL)
|
|
||||||
context = gdk_gl_context_get_current ();
|
|
||||||
|
|
||||||
cairo_surface_flush (surface);
|
|
||||||
|
|
||||||
cairo_surface_get_device_offset (surface, &device_x_offset, &device_y_offset);
|
|
||||||
|
|
||||||
rect.x = (int) device_x_offset;
|
|
||||||
rect.y = (int) device_y_offset;
|
|
||||||
rect.width = width;
|
|
||||||
rect.height = height;
|
|
||||||
tmp = cairo_surface_map_to_image (surface, &rect);
|
|
||||||
|
|
||||||
gdk_gl_context_upload_texture (context,
|
|
||||||
cairo_image_surface_get_data (tmp),
|
|
||||||
rect.width,
|
|
||||||
rect.height,
|
|
||||||
cairo_image_surface_get_stride (tmp),
|
|
||||||
target);
|
|
||||||
|
|
||||||
cairo_surface_unmap_image (surface, tmp);
|
|
||||||
}
|
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
|
|
||||||
#include "gdkglcontextprivate.h"
|
#include "gdkglcontextprivate.h"
|
||||||
#include "gdkdisplayprivate.h"
|
#include "gdkdisplayprivate.h"
|
||||||
|
#include "gdkmemorytextureprivate.h"
|
||||||
#include "gdkinternals.h"
|
#include "gdkinternals.h"
|
||||||
|
|
||||||
#include "gdkintl.h"
|
#include "gdkintl.h"
|
||||||
@ -227,49 +228,90 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride,
|
int stride,
|
||||||
|
GdkMemoryFormat data_format,
|
||||||
guint texture_target)
|
guint texture_target)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
|
guchar *copy = NULL;
|
||||||
|
guint gl_format;
|
||||||
|
guint gl_type;
|
||||||
|
guint bpp;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||||
|
|
||||||
|
if (priv->use_es)
|
||||||
|
{
|
||||||
|
/* GLES only supports rgba, so convert if necessary */
|
||||||
|
if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||||
|
{
|
||||||
|
copy = g_malloc (width * height * 4);
|
||||||
|
gdk_memory_convert (copy, width * 4,
|
||||||
|
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||||
|
data, stride, data_format,
|
||||||
|
width, height);
|
||||||
|
stride = width * 4;
|
||||||
|
data = copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpp = 4;
|
||||||
|
gl_format = GL_RGBA;
|
||||||
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
|
||||||
|
{
|
||||||
|
gl_format = GL_BGRA;
|
||||||
|
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
bpp = 4;
|
||||||
|
}
|
||||||
|
else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
|
||||||
|
{
|
||||||
|
gl_format = GL_RGB;
|
||||||
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
bpp = 3;
|
||||||
|
}
|
||||||
|
else /* Fall-back, convert to cairo-surface-format */
|
||||||
|
{
|
||||||
|
copy = g_malloc (width * height * 4);
|
||||||
|
gdk_memory_convert (copy, width * 4,
|
||||||
|
GDK_MEMORY_DEFAULT,
|
||||||
|
data, stride, data_format,
|
||||||
|
width, height);
|
||||||
|
stride = width * 4;
|
||||||
|
bpp = 4;
|
||||||
|
data = copy;
|
||||||
|
gl_format = GL_BGRA;
|
||||||
|
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
||||||
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
|
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
|
||||||
*/
|
*/
|
||||||
if (!priv->use_es ||
|
if (stride == width * bpp)
|
||||||
(priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
|
|
||||||
{
|
{
|
||||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);
|
}
|
||||||
|
else if ((!priv->use_es ||
|
||||||
|
(priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage))))
|
||||||
|
{
|
||||||
|
glPixelStorei (GL_UNPACK_ALIGNMENT, bpp);
|
||||||
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||||
|
|
||||||
if (priv->use_es)
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
|
||||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
||||||
data);
|
|
||||||
else
|
|
||||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
|
||||||
data);
|
|
||||||
|
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, NULL);
|
||||||
if (priv->use_es)
|
for (i = 0; i < height; i++)
|
||||||
{
|
glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
|
||||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < height; i++)
|
|
||||||
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, data + (i * stride));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
|
||||||
|
|
||||||
for (i = 0; i < height; i++)
|
|
||||||
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data + (i * stride));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "gdkglcontext.h"
|
#include "gdkglcontext.h"
|
||||||
#include "gdkdrawcontextprivate.h"
|
#include "gdkdrawcontextprivate.h"
|
||||||
|
#include "gdkmemorytexture.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ void gdk_gl_context_upload_texture (GdkGLContext
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride,
|
int stride,
|
||||||
|
GdkMemoryFormat data_format,
|
||||||
guint texture_target);
|
guint texture_target);
|
||||||
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
|
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
|
||||||
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
|
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
|
||||||
|
@ -38,13 +38,14 @@ struct _GdkMemoryTextureClass
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GdkMemoryTexture, gdk_memory_texture, GDK_TYPE_TEXTURE)
|
G_DEFINE_TYPE (GdkMemoryTexture, gdk_memory_texture, GDK_TYPE_TEXTURE)
|
||||||
|
|
||||||
static gsize
|
gsize
|
||||||
gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||||
|
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||||
case GDK_MEMORY_B8G8R8A8:
|
case GDK_MEMORY_B8G8R8A8:
|
||||||
case GDK_MEMORY_A8R8G8B8:
|
case GDK_MEMORY_A8R8G8B8:
|
||||||
case GDK_MEMORY_R8G8B8A8:
|
case GDK_MEMORY_R8G8B8A8:
|
||||||
@ -199,6 +200,9 @@ convert_swizzle ## A ## R ## G ## B (guchar *dest_data, \
|
|||||||
}
|
}
|
||||||
|
|
||||||
SWIZZLE(3,2,1,0)
|
SWIZZLE(3,2,1,0)
|
||||||
|
SWIZZLE(2,1,0,3)
|
||||||
|
SWIZZLE(3,0,1,2)
|
||||||
|
SWIZZLE(1,2,3,0)
|
||||||
|
|
||||||
#define SWIZZLE_OPAQUE(A,R,G,B) \
|
#define SWIZZLE_OPAQUE(A,R,G,B) \
|
||||||
static void \
|
static void \
|
||||||
@ -267,6 +271,10 @@ SWIZZLE_PREMULTIPLY (3,2,1,0, 3,0,1,2)
|
|||||||
SWIZZLE_PREMULTIPLY (0,1,2,3, 3,0,1,2)
|
SWIZZLE_PREMULTIPLY (0,1,2,3, 3,0,1,2)
|
||||||
SWIZZLE_PREMULTIPLY (3,2,1,0, 0,3,2,1)
|
SWIZZLE_PREMULTIPLY (3,2,1,0, 0,3,2,1)
|
||||||
SWIZZLE_PREMULTIPLY (0,1,2,3, 0,3,2,1)
|
SWIZZLE_PREMULTIPLY (0,1,2,3, 0,3,2,1)
|
||||||
|
SWIZZLE_PREMULTIPLY (3,0,1,2, 3,2,1,0)
|
||||||
|
SWIZZLE_PREMULTIPLY (3,0,1,2, 0,1,2,3)
|
||||||
|
SWIZZLE_PREMULTIPLY (3,0,1,2, 3,0,1,2)
|
||||||
|
SWIZZLE_PREMULTIPLY (3,0,1,2, 0,3,2,1)
|
||||||
|
|
||||||
typedef void (* ConversionFunc) (guchar *dest_data,
|
typedef void (* ConversionFunc) (guchar *dest_data,
|
||||||
gsize dest_stride,
|
gsize dest_stride,
|
||||||
@ -275,16 +283,17 @@ typedef void (* ConversionFunc) (guchar *dest_data,
|
|||||||
gsize width,
|
gsize width,
|
||||||
gsize height);
|
gsize height);
|
||||||
|
|
||||||
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][2] =
|
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
|
||||||
{
|
{
|
||||||
{ convert_memcpy, convert_swizzle3210 },
|
{ convert_memcpy, convert_swizzle3210, convert_swizzle2103 },
|
||||||
{ convert_swizzle3210, convert_memcpy },
|
{ convert_swizzle3210, convert_memcpy, convert_swizzle3012 },
|
||||||
{ convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210 },
|
{ convert_swizzle2103, convert_swizzle1230, convert_memcpy },
|
||||||
{ convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123 },
|
{ convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210, convert_swizzle_premultiply_3012_3210, },
|
||||||
{ convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012 },
|
{ convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123, convert_swizzle_premultiply_3012_0123 },
|
||||||
{ convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321 },
|
{ convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012, convert_swizzle_premultiply_3012_3012 },
|
||||||
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123 },
|
{ convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321, convert_swizzle_premultiply_3012_0321 },
|
||||||
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321 }
|
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012 },
|
||||||
|
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -297,7 +306,7 @@ gdk_memory_convert (guchar *dest_data,
|
|||||||
gsize width,
|
gsize width,
|
||||||
gsize height)
|
gsize height)
|
||||||
{
|
{
|
||||||
g_assert (dest_format < 2);
|
g_assert (dest_format < 3);
|
||||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||||
|
|
||||||
converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
|
converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
|
||||||
|
@ -34,6 +34,8 @@ G_BEGIN_DECLS
|
|||||||
* The color values are premultiplied with the alpha value.
|
* The color values are premultiplied with the alpha value.
|
||||||
* @GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: 4 bytes; for alpha, red, green, blue.
|
* @GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: 4 bytes; for alpha, red, green, blue.
|
||||||
* The color values are premultiplied with the alpha value.
|
* The color values are premultiplied with the alpha value.
|
||||||
|
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
|
||||||
|
* The color values are premultiplied with the alpha value.
|
||||||
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
|
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
|
||||||
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
|
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
|
||||||
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
|
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
|
||||||
@ -58,6 +60,7 @@ G_BEGIN_DECLS
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
|
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
|
||||||
GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
|
GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
|
||||||
|
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||||
GDK_MEMORY_B8G8R8A8,
|
GDK_MEMORY_B8G8R8A8,
|
||||||
GDK_MEMORY_A8R8G8B8,
|
GDK_MEMORY_A8R8G8B8,
|
||||||
GDK_MEMORY_R8G8B8A8,
|
GDK_MEMORY_R8G8B8A8,
|
||||||
|
@ -31,6 +31,8 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
#define GDK_MEMORY_CAIRO_FORMAT_ARGB32 GDK_MEMORY_DEFAULT
|
#define GDK_MEMORY_CAIRO_FORMAT_ARGB32 GDK_MEMORY_DEFAULT
|
||||||
|
|
||||||
|
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format);
|
||||||
|
|
||||||
GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
|
GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
|
||||||
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
|
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
|
||||||
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
|
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
|
||||||
|
@ -130,28 +130,6 @@ gdk_texture_real_download (GdkTexture *self,
|
|||||||
GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download);
|
GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
|
||||||
gdk_texture_real_download_surface (GdkTexture *texture)
|
|
||||||
{
|
|
||||||
cairo_surface_t *surface;
|
|
||||||
cairo_status_t surface_status;
|
|
||||||
|
|
||||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
|
||||||
texture->width, texture->height);
|
|
||||||
|
|
||||||
surface_status = cairo_surface_status (surface);
|
|
||||||
if (surface_status != CAIRO_STATUS_SUCCESS)
|
|
||||||
g_warning ("%s: surface error: %s", __FUNCTION__,
|
|
||||||
cairo_status_to_string (surface_status));
|
|
||||||
|
|
||||||
gdk_texture_download (texture,
|
|
||||||
cairo_image_surface_get_data (surface),
|
|
||||||
cairo_image_surface_get_stride (surface));
|
|
||||||
cairo_surface_mark_dirty (surface);
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_texture_set_property (GObject *gobject,
|
gdk_texture_set_property (GObject *gobject,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -216,7 +194,6 @@ gdk_texture_class_init (GdkTextureClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
klass->download = gdk_texture_real_download;
|
klass->download = gdk_texture_real_download;
|
||||||
klass->download_surface = gdk_texture_real_download_surface;
|
|
||||||
|
|
||||||
gobject_class->set_property = gdk_texture_set_property;
|
gobject_class->set_property = gdk_texture_set_property;
|
||||||
gobject_class->get_property = gdk_texture_get_property;
|
gobject_class->get_property = gdk_texture_get_property;
|
||||||
@ -438,7 +415,23 @@ gdk_texture_get_height (GdkTexture *texture)
|
|||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
gdk_texture_download_surface (GdkTexture *texture)
|
gdk_texture_download_surface (GdkTexture *texture)
|
||||||
{
|
{
|
||||||
return GDK_TEXTURE_GET_CLASS (texture)->download_surface (texture);
|
cairo_surface_t *surface;
|
||||||
|
cairo_status_t surface_status;
|
||||||
|
|
||||||
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
|
texture->width, texture->height);
|
||||||
|
|
||||||
|
surface_status = cairo_surface_status (surface);
|
||||||
|
if (surface_status != CAIRO_STATUS_SUCCESS)
|
||||||
|
g_warning ("%s: surface error: %s", __FUNCTION__,
|
||||||
|
cairo_status_to_string (surface_status));
|
||||||
|
|
||||||
|
gdk_texture_download (texture,
|
||||||
|
cairo_image_surface_get_data (surface),
|
||||||
|
cairo_image_surface_get_stride (surface));
|
||||||
|
cairo_surface_mark_dirty (surface);
|
||||||
|
|
||||||
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -28,7 +28,6 @@ struct _GdkTextureClass {
|
|||||||
const GdkRectangle *area,
|
const GdkRectangle *area,
|
||||||
guchar *data,
|
guchar *data,
|
||||||
gsize stride);
|
gsize stride);
|
||||||
cairo_surface_t * (* download_surface) (GdkTexture *texture);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gpointer gdk_texture_new (const GdkTextureClass *klass,
|
gpointer gdk_texture_new (const GdkTextureClass *klass,
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "gdk/gdkglcontextprivate.h"
|
#include "gdk/gdkglcontextprivate.h"
|
||||||
#include "gdk/gdktextureprivate.h"
|
#include "gdk/gdktextureprivate.h"
|
||||||
#include "gdk/gdkgltextureprivate.h"
|
#include "gdk/gdkgltextureprivate.h"
|
||||||
|
#include "gdkmemorytextureprivate.h"
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
@ -58,6 +59,54 @@ struct _GskGLDriver
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
upload_gdk_texture (GdkTexture *source_texture,
|
||||||
|
int target,
|
||||||
|
int x_offset,
|
||||||
|
int y_offset,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface = NULL;
|
||||||
|
GdkMemoryFormat data_format;
|
||||||
|
const guchar *data;
|
||||||
|
gsize data_stride;
|
||||||
|
gsize bpp;
|
||||||
|
|
||||||
|
g_return_if_fail (source_texture != NULL);
|
||||||
|
g_return_if_fail (x_offset + width <= gdk_texture_get_width (source_texture));
|
||||||
|
g_return_if_fail (y_offset + height <= gdk_texture_get_height (source_texture));
|
||||||
|
|
||||||
|
/* Note: GdkGLTextures are already handled before we reach this and reused as-is */
|
||||||
|
|
||||||
|
if (GDK_IS_MEMORY_TEXTURE (source_texture))
|
||||||
|
{
|
||||||
|
GdkMemoryTexture *memory_texture = GDK_MEMORY_TEXTURE (source_texture);
|
||||||
|
data = gdk_memory_texture_get_data (memory_texture);
|
||||||
|
data_format = gdk_memory_texture_get_format (memory_texture);
|
||||||
|
data_stride = gdk_memory_texture_get_stride (memory_texture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fall back to downloading to a surface */
|
||||||
|
surface = gdk_texture_download_surface (source_texture);
|
||||||
|
cairo_surface_flush (surface);
|
||||||
|
data = cairo_image_surface_get_data (surface);
|
||||||
|
data_format = GDK_MEMORY_DEFAULT;
|
||||||
|
data_stride = cairo_image_surface_get_stride (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
bpp = gdk_memory_format_bytes_per_pixel (data_format);
|
||||||
|
|
||||||
|
gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
|
||||||
|
data + x_offset * bpp + y_offset * data_stride,
|
||||||
|
width, height, data_stride,
|
||||||
|
data_format, target);
|
||||||
|
|
||||||
|
if (surface)
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
}
|
||||||
|
|
||||||
static Texture *
|
static Texture *
|
||||||
texture_new (void)
|
texture_new (void)
|
||||||
{
|
{
|
||||||
@ -408,32 +457,15 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
|
|||||||
|
|
||||||
slices = g_new0 (TextureSlice, cols * rows);
|
slices = g_new0 (TextureSlice, cols * rows);
|
||||||
|
|
||||||
/* TODO: (Perf):
|
|
||||||
* We still create a surface here, which should obviously be unnecessary
|
|
||||||
* and we should eventually remove it and upload the data directly.
|
|
||||||
*/
|
|
||||||
for (col = 0; col < cols; col ++)
|
for (col = 0; col < cols; col ++)
|
||||||
{
|
{
|
||||||
const int slice_width = MIN (max_texture_size, texture->width - x);
|
const int slice_width = MIN (max_texture_size, texture->width - x);
|
||||||
const int stride = slice_width * 4;
|
|
||||||
|
|
||||||
for (row = 0; row < rows; row ++)
|
for (row = 0; row < rows; row ++)
|
||||||
{
|
{
|
||||||
const int slice_height = MIN (max_texture_size, texture->height - y);
|
const int slice_height = MIN (max_texture_size, texture->height - y);
|
||||||
const int slice_index = (col * rows) + row;
|
const int slice_index = (col * rows) + row;
|
||||||
guchar *data;
|
|
||||||
guint texture_id;
|
guint texture_id;
|
||||||
cairo_surface_t *surface;
|
|
||||||
|
|
||||||
data = g_malloc (sizeof (guchar) * stride * slice_height);
|
|
||||||
|
|
||||||
gdk_texture_download_area (texture,
|
|
||||||
&(GdkRectangle){x, y, slice_width, slice_height},
|
|
||||||
data, stride);
|
|
||||||
surface = cairo_image_surface_create_for_data (data,
|
|
||||||
CAIRO_FORMAT_ARGB32,
|
|
||||||
slice_width, slice_height,
|
|
||||||
stride);
|
|
||||||
|
|
||||||
glGenTextures (1, &texture_id);
|
glGenTextures (1, &texture_id);
|
||||||
|
|
||||||
@ -442,7 +474,7 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
|
|||||||
#endif
|
#endif
|
||||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||||
gsk_gl_driver_set_texture_parameters (self, GL_NEAREST, GL_NEAREST);
|
gsk_gl_driver_set_texture_parameters (self, GL_NEAREST, GL_NEAREST);
|
||||||
gdk_cairo_surface_upload_to_gl (surface, GL_TEXTURE_2D, slice_width, slice_height, NULL);
|
upload_gdk_texture (texture, GL_TEXTURE_2D, x, y, slice_width, slice_height);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
|
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
|
||||||
@ -451,9 +483,6 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
|
|||||||
slices[slice_index].rect = (GdkRectangle){x, y, slice_width, slice_height};
|
slices[slice_index].rect = (GdkRectangle){x, y, slice_width, slice_height};
|
||||||
slices[slice_index].texture_id = texture_id;
|
slices[slice_index].texture_id = texture_id;
|
||||||
|
|
||||||
g_free (data);
|
|
||||||
cairo_surface_destroy (surface);
|
|
||||||
|
|
||||||
y += slice_height;
|
y += slice_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +515,8 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
|||||||
int mag_filter)
|
int mag_filter)
|
||||||
{
|
{
|
||||||
Texture *t;
|
Texture *t;
|
||||||
cairo_surface_t *surface;
|
GdkTexture *downloaded_texture = NULL;
|
||||||
|
GdkTexture *source_texture;
|
||||||
|
|
||||||
if (GDK_IS_GL_TEXTURE (texture))
|
if (GDK_IS_GL_TEXTURE (texture))
|
||||||
{
|
{
|
||||||
@ -494,14 +524,20 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
|||||||
|
|
||||||
if (texture_context != self->gl_context)
|
if (texture_context != self->gl_context)
|
||||||
{
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
/* In this case, we have to temporarily make the texture's context the current one,
|
/* In this case, we have to temporarily make the texture's context the current one,
|
||||||
* download its data into our context and then create a texture from it. */
|
* download its data into our context and then create a texture from it. */
|
||||||
if (texture_context)
|
if (texture_context)
|
||||||
gdk_gl_context_make_current (texture_context);
|
gdk_gl_context_make_current (texture_context);
|
||||||
|
|
||||||
surface = gdk_texture_download_surface (texture);
|
surface = gdk_texture_download_surface (texture);
|
||||||
|
downloaded_texture = gdk_texture_new_for_surface (surface);
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->gl_context);
|
gdk_gl_context_make_current (self->gl_context);
|
||||||
|
|
||||||
|
source_texture = downloaded_texture;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -519,7 +555,7 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
|||||||
return t->texture_id;
|
return t->texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface = gdk_texture_download_surface (texture);
|
source_texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = create_texture (self, gdk_texture_get_width (texture), gdk_texture_get_height (texture));
|
t = create_texture (self, gdk_texture_get_width (texture), gdk_texture_get_height (texture));
|
||||||
@ -528,15 +564,16 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
|||||||
t->user = texture;
|
t->user = texture;
|
||||||
|
|
||||||
gsk_gl_driver_bind_source_texture (self, t->texture_id);
|
gsk_gl_driver_bind_source_texture (self, t->texture_id);
|
||||||
gsk_gl_driver_init_texture_with_surface (self,
|
gsk_gl_driver_init_texture (self,
|
||||||
t->texture_id,
|
t->texture_id,
|
||||||
surface,
|
source_texture,
|
||||||
min_filter,
|
min_filter,
|
||||||
mag_filter);
|
mag_filter);
|
||||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, t->texture_id,
|
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, t->texture_id,
|
||||||
"GdkTexture<%p> %d", texture, t->texture_id);
|
"GdkTexture<%p> %d", texture, t->texture_id);
|
||||||
|
|
||||||
cairo_surface_destroy (surface);
|
if (downloaded_texture)
|
||||||
|
g_object_unref (downloaded_texture);
|
||||||
|
|
||||||
return t->texture_id;
|
return t->texture_id;
|
||||||
}
|
}
|
||||||
@ -769,11 +806,11 @@ filter_uses_mipmaps (int filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_gl_driver_init_texture_with_surface (GskGLDriver *self,
|
gsk_gl_driver_init_texture (GskGLDriver *self,
|
||||||
int texture_id,
|
int texture_id,
|
||||||
cairo_surface_t *surface,
|
GdkTexture *texture,
|
||||||
int min_filter,
|
int min_filter,
|
||||||
int mag_filter)
|
int mag_filter)
|
||||||
{
|
{
|
||||||
Texture *t;
|
Texture *t;
|
||||||
|
|
||||||
@ -794,7 +831,7 @@ gsk_gl_driver_init_texture_with_surface (GskGLDriver *self,
|
|||||||
|
|
||||||
gsk_gl_driver_set_texture_parameters (self, min_filter, mag_filter);
|
gsk_gl_driver_set_texture_parameters (self, min_filter, mag_filter);
|
||||||
|
|
||||||
gdk_cairo_surface_upload_to_gl (surface, GL_TEXTURE_2D, t->width, t->height, NULL);
|
upload_gdk_texture (texture, GL_TEXTURE_2D, 0, 0, t->width, t->height);
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
|
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
|
||||||
|
@ -63,9 +63,9 @@ void gsk_gl_driver_init_texture_empty (GskGLDriver *driver
|
|||||||
int texture_id,
|
int texture_id,
|
||||||
int min_filter,
|
int min_filter,
|
||||||
int max_filter);
|
int max_filter);
|
||||||
void gsk_gl_driver_init_texture_with_surface (GskGLDriver *driver,
|
void gsk_gl_driver_init_texture (GskGLDriver *driver,
|
||||||
int texture_id,
|
int texture_id,
|
||||||
cairo_surface_t *surface,
|
GdkTexture *texture,
|
||||||
int min_filter,
|
int min_filter,
|
||||||
int mag_filter);
|
int mag_filter);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "gskgltextureatlasprivate.h"
|
#include "gskgltextureatlasprivate.h"
|
||||||
|
|
||||||
#include "gdk/gdkglcontextprivate.h"
|
#include "gdk/gdkglcontextprivate.h"
|
||||||
|
#include "gdk/gdkmemorytextureprivate.h"
|
||||||
|
|
||||||
#include <graphene.h>
|
#include <graphene.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
@ -186,6 +187,10 @@ upload_glyph (GlyphCacheKey *key,
|
|||||||
GskGLCachedGlyph *value)
|
GskGLCachedGlyph *value)
|
||||||
{
|
{
|
||||||
GskImageRegion r;
|
GskImageRegion r;
|
||||||
|
guchar *pixel_data;
|
||||||
|
guchar *free_data = NULL;
|
||||||
|
guint gl_format;
|
||||||
|
guint gl_type;
|
||||||
|
|
||||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||||
"Uploading glyph %d",
|
"Uploading glyph %d",
|
||||||
@ -197,15 +202,27 @@ upload_glyph (GlyphCacheKey *key,
|
|||||||
glBindTexture (GL_TEXTURE_2D, value->texture_id);
|
glBindTexture (GL_TEXTURE_2D, value->texture_id);
|
||||||
|
|
||||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
|
{
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
pixel_data = free_data = g_malloc (r.width * r.height * 4);
|
||||||
r.data);
|
gdk_memory_convert (pixel_data, r.width * 4,
|
||||||
|
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||||
|
r.data, r.width * 4,
|
||||||
|
GDK_MEMORY_DEFAULT, r.width, r.height);
|
||||||
|
gl_format = GL_RGBA;
|
||||||
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
|
{
|
||||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
pixel_data = r.data;
|
||||||
r.data);
|
gl_format = GL_BGRA;
|
||||||
|
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
|
||||||
|
gl_format, gl_type, pixel_data);
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||||
g_free (r.data);
|
g_free (r.data);
|
||||||
|
g_free (free_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "gskgliconcacheprivate.h"
|
#include "gskgliconcacheprivate.h"
|
||||||
#include "gskgltextureatlasprivate.h"
|
#include "gskgltextureatlasprivate.h"
|
||||||
#include "gdk/gdktextureprivate.h"
|
#include "gdk/gdktextureprivate.h"
|
||||||
|
#include "gdk/gdkmemorytextureprivate.h"
|
||||||
#include "gdk/gdkglcontextprivate.h"
|
#include "gdk/gdkglcontextprivate.h"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
@ -134,7 +135,10 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
|||||||
int packed_y = 0;
|
int packed_y = 0;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
unsigned char *surface_data;
|
unsigned char *surface_data;
|
||||||
|
unsigned char *pixel_data;
|
||||||
|
guchar *free_data = NULL;
|
||||||
guint gl_format;
|
guint gl_format;
|
||||||
|
guint gl_type;
|
||||||
|
|
||||||
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
||||||
|
|
||||||
@ -158,36 +162,47 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
|||||||
"Uploading texture");
|
"Uploading texture");
|
||||||
|
|
||||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||||
gl_format = GL_RGBA;
|
{
|
||||||
|
pixel_data = free_data = g_malloc (width * height * 4);
|
||||||
|
gdk_memory_convert (pixel_data, width * 4,
|
||||||
|
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||||
|
surface_data, cairo_image_surface_get_stride (surface),
|
||||||
|
GDK_MEMORY_DEFAULT, width, height);
|
||||||
|
gl_format = GL_RGBA;
|
||||||
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gl_format = GL_BGRA;
|
{
|
||||||
|
pixel_data = surface_data;
|
||||||
|
gl_format = GL_BGRA;
|
||||||
|
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
|
}
|
||||||
|
|
||||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||||
|
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + 1, packed_y + 1,
|
packed_x + 1, packed_y + 1,
|
||||||
width, height,
|
width, height,
|
||||||
gl_format,
|
gl_format, gl_type,
|
||||||
GL_UNSIGNED_BYTE,
|
pixel_data);
|
||||||
surface_data);
|
|
||||||
/* Padding top */
|
/* Padding top */
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + 1, packed_y,
|
packed_x + 1, packed_y,
|
||||||
width, 1,
|
width, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding left */
|
/* Padding left */
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x, packed_y + 1,
|
packed_x, packed_y + 1,
|
||||||
1, height,
|
1, height,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding top left */
|
/* Padding top left */
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x, packed_y,
|
packed_x, packed_y,
|
||||||
1, 1,
|
1, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
|
|
||||||
/* Padding right */
|
/* Padding right */
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||||
@ -195,14 +210,14 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
|||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + width + 1, packed_y + 1,
|
packed_x + width + 1, packed_y + 1,
|
||||||
1, height,
|
1, height,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding top right */
|
/* Padding top right */
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + width + 1, packed_y,
|
packed_x + width + 1, packed_y,
|
||||||
1, 1,
|
1, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding bottom */
|
/* Padding bottom */
|
||||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||||
@ -210,22 +225,22 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
|||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + 1, packed_y + 1 + height,
|
packed_x + 1, packed_y + 1 + height,
|
||||||
width, 1,
|
width, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding bottom left */
|
/* Padding bottom left */
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x, packed_y + 1 + height,
|
packed_x, packed_y + 1 + height,
|
||||||
1, 1,
|
1, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Padding bottom right */
|
/* Padding bottom right */
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
|
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||||
packed_x + 1 + width, packed_y + 1 + height,
|
packed_x + 1 + width, packed_y + 1 + height,
|
||||||
1, 1,
|
1, 1,
|
||||||
gl_format, GL_UNSIGNED_BYTE,
|
gl_format, gl_type,
|
||||||
surface_data);
|
pixel_data);
|
||||||
/* Reset this */
|
/* Reset this */
|
||||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||||
@ -236,6 +251,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
|||||||
*out_icon_data = icon_data;
|
*out_icon_data = icon_data;
|
||||||
|
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
g_free (free_data);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
@ -564,6 +564,7 @@ render_fallback_node (GskGLRenderer *self,
|
|||||||
GskRenderNode *node,
|
GskRenderNode *node,
|
||||||
RenderOpBuilder *builder)
|
RenderOpBuilder *builder)
|
||||||
{
|
{
|
||||||
|
GdkTexture *texture;
|
||||||
const float scale = ops_get_scale (builder);
|
const float scale = ops_get_scale (builder);
|
||||||
const int surface_width = ceilf (node->bounds.size.width * scale);
|
const int surface_width = ceilf (node->bounds.size.width * scale);
|
||||||
const int surface_height = ceilf (node->bounds.size.height * scale);
|
const int surface_height = ceilf (node->bounds.size.height * scale);
|
||||||
@ -645,15 +646,18 @@ render_fallback_node (GskGLRenderer *self,
|
|||||||
#endif
|
#endif
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
|
||||||
/* Upload the Cairo surface to a GL texture */
|
/* Upload the Cairo surface to a GL texture */
|
||||||
texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
texture_id = gsk_gl_driver_create_texture (self->gl_driver,
|
||||||
surface_width,
|
surface_width,
|
||||||
surface_height);
|
surface_height);
|
||||||
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
|
||||||
gsk_gl_driver_init_texture_with_surface (self->gl_driver,
|
|
||||||
texture_id,
|
texture = gdk_texture_new_for_surface (surface);
|
||||||
surface,
|
gsk_gl_driver_init_texture (self->gl_driver,
|
||||||
GL_NEAREST, GL_NEAREST);
|
texture_id,
|
||||||
|
texture,
|
||||||
|
GL_NEAREST, GL_NEAREST);
|
||||||
|
|
||||||
if (gdk_gl_context_has_debug (self->gl_context))
|
if (gdk_gl_context_has_debug (self->gl_context))
|
||||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||||
@ -661,6 +665,7 @@ render_fallback_node (GskGLRenderer *self,
|
|||||||
g_type_name_from_instance ((GTypeInstance *) node),
|
g_type_name_from_instance ((GTypeInstance *) node),
|
||||||
texture_id);
|
texture_id);
|
||||||
|
|
||||||
|
g_object_unref (texture);
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
cairo_surface_destroy (rendered_surface);
|
cairo_surface_destroy (rendered_surface);
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ typedef struct _TestData {
|
|||||||
static MemoryData tests[GDK_MEMORY_N_FORMATS] = {
|
static MemoryData tests[GDK_MEMORY_N_FORMATS] = {
|
||||||
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(00,FF,00,FF), RGBA(00,00,FF,FF), RGBA(00,00,00,00), RGBA(66,22,44,AA) } },
|
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(00,FF,00,FF), RGBA(00,00,FF,FF), RGBA(00,00,00,00), RGBA(66,22,44,AA) } },
|
||||||
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(FF,00,FF,00), RGBA(FF,FF,00,00), RGBA(00,00,00,00), RGBA(AA,44,22,66) } },
|
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(FF,00,FF,00), RGBA(FF,FF,00,00), RGBA(00,00,00,00), RGBA(AA,44,22,66) } },
|
||||||
|
{ 4, FALSE, { RGBA(00,00,FF,FF), RGBA(00,FF,00,FF), RGBA(FF,00,00,FF), RGBA(00,00,00,00), RGBA(44,22,66,AA) } },
|
||||||
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(00,FF,00,FF), RGBA(00,00,FF,FF), RGBA(00,00,00,00), RGBA(99,33,66,AA) } },
|
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(00,FF,00,FF), RGBA(00,00,FF,FF), RGBA(00,00,00,00), RGBA(99,33,66,AA) } },
|
||||||
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(FF,00,FF,00), RGBA(FF,FF,00,00), RGBA(00,00,00,00), RGBA(AA,66,33,99) } },
|
{ 4, FALSE, { RGBA(FF,00,00,FF), RGBA(FF,00,FF,00), RGBA(FF,FF,00,00), RGBA(00,00,00,00), RGBA(AA,66,33,99) } },
|
||||||
{ 4, FALSE, { RGBA(00,00,FF,FF), RGBA(00,FF,00,FF), RGBA(FF,00,00,FF), RGBA(00,00,00,00), RGBA(66,33,99,AA) } },
|
{ 4, FALSE, { RGBA(00,00,FF,FF), RGBA(00,FF,00,FF), RGBA(FF,00,00,FF), RGBA(00,00,00,00), RGBA(66,33,99,AA) } },
|
||||||
|
Loading…
Reference in New Issue
Block a user