forked from AuroraMiddleware/gtk
gl: Refactor texture uploading
Don't pass texture + rect, but instead have gdk_memory_texture_new_subtexture() and use it to generate subtextures and pass them. This has the advantage of downloading the a too large texture only once instead of N times.
This commit is contained in:
parent
52e88ed4c8
commit
ddc4a40c33
@ -166,6 +166,39 @@ gdk_memory_texture_new (int width,
|
||||
return GDK_TEXTURE (self);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkTexture *texture, *result;
|
||||
gsize bpp, offset, size;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
|
||||
g_return_val_if_fail (x < 0 || x >= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y < 0 || y >= GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width <= 0 || x + width > GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height <= 0 || y + height > GDK_TEXTURE (source)->height, NULL);
|
||||
|
||||
texture = GDK_TEXTURE (source);
|
||||
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
|
||||
offset = y * source->stride + x * bpp;
|
||||
size = source->stride * (height - 1) + x * bpp;
|
||||
bytes = g_bytes_new_from_bytes (source->bytes, offset, size);
|
||||
|
||||
result = gdk_memory_texture_new (texture->width,
|
||||
texture->height,
|
||||
texture->format,
|
||||
bytes,
|
||||
source->stride);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GdkMemoryTexture *
|
||||
gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
GdkMemoryFormat format)
|
||||
|
@ -31,6 +31,11 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
GdkMemoryFormat format);
|
||||
GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *texture,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
|
||||
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
|
||||
|
@ -1422,10 +1422,6 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
int
|
||||
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture,
|
||||
guint x_offset,
|
||||
guint y_offset,
|
||||
guint width,
|
||||
guint height,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
{
|
||||
@ -1434,16 +1430,17 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkMemoryFormat data_format;
|
||||
const guchar *data;
|
||||
gsize data_stride;
|
||||
gsize bpp;
|
||||
int width, height;
|
||||
int texture_id;
|
||||
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
g_assert (!GDK_IS_GL_TEXTURE (texture));
|
||||
g_assert (x_offset + width <= gdk_texture_get_width (texture));
|
||||
g_assert (y_offset + height <= gdk_texture_get_height (texture));
|
||||
g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST);
|
||||
g_assert (mag_filter == GL_LINEAR || min_filter == GL_NEAREST);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
if (width > self->max_texture_size || height > self->max_texture_size)
|
||||
{
|
||||
g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
|
||||
@ -1476,14 +1473,12 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
self->n_uploads++;
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (data_format);
|
||||
|
||||
/* Switch to texture0 as 2D. We'll restore it later. */
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
gsk_gl_command_queue_do_upload_texture (self,
|
||||
data + x_offset * bpp + y_offset * data_stride,
|
||||
data,
|
||||
width, height, data_stride,
|
||||
data_format);
|
||||
|
||||
|
@ -281,10 +281,6 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
|
||||
const cairo_region_t *scissor);
|
||||
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture,
|
||||
guint x_offset,
|
||||
guint y_offset,
|
||||
guint width,
|
||||
guint height,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
|
@ -798,10 +798,6 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
height = gdk_texture_get_height (texture);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
GDK_TEXTURE (downloaded_texture),
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
|
||||
@ -1230,6 +1226,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
int tex_width;
|
||||
int tex_height;
|
||||
int x = 0, y = 0;
|
||||
GdkMemoryTexture *memtex;
|
||||
|
||||
g_assert (GSK_IS_GL_DRIVER (self));
|
||||
g_assert (GDK_IS_TEXTURE (texture));
|
||||
@ -1253,6 +1250,8 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
|
||||
n_slices = cols * rows;
|
||||
slices = g_new0 (GskGLTextureSlice, n_slices);
|
||||
memtex = gdk_memory_texture_from_texture (texture,
|
||||
gdk_texture_get_format (texture));
|
||||
|
||||
for (guint col = 0; col < cols; col ++)
|
||||
{
|
||||
@ -1262,13 +1261,16 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
{
|
||||
int slice_height = MIN (max_texture_size, texture->height - y);
|
||||
int slice_index = (col * rows) + row;
|
||||
GdkTexture *subtex;
|
||||
guint texture_id;
|
||||
|
||||
subtex = gdk_memory_texture_new_subtexture (memtex,
|
||||
x, y,
|
||||
slice_width, slice_height);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
texture,
|
||||
x, y,
|
||||
slice_width, slice_height,
|
||||
subtex,
|
||||
GL_NEAREST, GL_NEAREST);
|
||||
g_object_unref (subtex);
|
||||
|
||||
slices[slice_index].rect.x = x;
|
||||
slices[slice_index].rect.y = y;
|
||||
@ -1283,6 +1285,8 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
x += slice_width;
|
||||
}
|
||||
|
||||
g_object_unref (memtex);
|
||||
|
||||
/* Allocate one Texture for the entire thing. */
|
||||
t = gsk_gl_texture_new (0,
|
||||
tex_width, tex_height,
|
||||
|
Loading…
Reference in New Issue
Block a user