diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index 4402998ebb..71df887b0b 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -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) diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h index a71648a950..57dafd567b 100644 --- a/gdk/gdkmemorytextureprivate.h +++ b/gdk/gdkmemorytextureprivate.h @@ -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); diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index 38f879c5c1..6842b032b8 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -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); diff --git a/gsk/gl/gskglcommandqueueprivate.h b/gsk/gl/gskglcommandqueueprivate.h index c4da7231c9..4147283e6d 100644 --- a/gsk/gl/gskglcommandqueueprivate.h +++ b/gsk/gl/gskglcommandqueueprivate.h @@ -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, diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 33fcf380b3..327dea93ff 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -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,