diff --git a/gsk/gpu/gskglframe.c b/gsk/gpu/gskglframe.c index 70993f9535..2f69b00172 100644 --- a/gsk/gpu/gskglframe.c +++ b/gsk/gpu/gskglframe.c @@ -8,6 +8,9 @@ #include "gskglbufferprivate.h" #include "gskgldescriptorsprivate.h" #include "gskgldeviceprivate.h" +#include "gskglimageprivate.h" + +#include "gdkgltextureprivate.h" struct _GskGLFrame { @@ -50,6 +53,39 @@ gsk_gl_frame_cleanup (GskGpuFrame *frame) GSK_GPU_FRAME_CLASS (gsk_gl_frame_parent_class)->cleanup (frame); } +static GskGpuImage * +gsk_gl_frame_upload_texture (GskGpuFrame *frame, + gboolean with_mipmap, + GdkTexture *texture) +{ + if (GDK_IS_GL_TEXTURE (texture)) + { + GdkGLTexture *gl_texture = GDK_GL_TEXTURE (texture); + + if (gdk_gl_context_is_shared (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)), + gdk_gl_texture_get_context (gl_texture))) + { + GskGpuImage *image; + GLsync sync; + + image = gsk_gl_image_new_for_texture (GSK_GL_DEVICE (gsk_gpu_frame_get_device (frame)), + texture, + gdk_gl_texture_get_id (gl_texture), + FALSE, + gdk_gl_texture_has_mipmap (gl_texture) ? (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_MIPMAP) : 0); + + /* This is a hack, but it works */ + sync = gdk_gl_texture_get_sync (gl_texture); + if (sync) + glWaitSync (sync, 0, GL_TIMEOUT_IGNORED); + + return image; + } + } + + return GSK_GPU_FRAME_CLASS (gsk_gl_frame_parent_class)->upload_texture (frame, with_mipmap, texture); +} + static GskGpuDescriptors * gsk_gl_frame_create_descriptors (GskGpuFrame *frame) { @@ -133,6 +169,7 @@ gsk_gl_frame_class_init (GskGLFrameClass *klass) gpu_frame_class->is_busy = gsk_gl_frame_is_busy; gpu_frame_class->setup = gsk_gl_frame_setup; gpu_frame_class->cleanup = gsk_gl_frame_cleanup; + gpu_frame_class->upload_texture = gsk_gl_frame_upload_texture; gpu_frame_class->create_descriptors = gsk_gl_frame_create_descriptors; gpu_frame_class->create_vertex_buffer = gsk_gl_frame_create_vertex_buffer; gpu_frame_class->create_storage_buffer = gsk_gl_frame_create_storage_buffer; diff --git a/gsk/gpu/gskglimage.c b/gsk/gpu/gskglimage.c index 4967fef2a5..cc16119e1e 100644 --- a/gsk/gpu/gskglimage.c +++ b/gsk/gpu/gskglimage.c @@ -153,6 +153,44 @@ gsk_gl_image_new (GskGLDevice *device, return GSK_GPU_IMAGE (self); } +GskGpuImage * +gsk_gl_image_new_for_texture (GskGLDevice *device, + GdkTexture *owner, + GLuint tex_id, + gboolean take_ownership, + GskGpuImageFlags extra_flags) +{ + GdkMemoryFormat format; + GskGLImage *self; + GLint swizzle[4]; + + format = gdk_texture_get_format (owner); + + self = g_object_new (GSK_TYPE_GL_IMAGE, NULL); + + /* We only do this so these variables get initialized */ + gsk_gl_device_find_gl_format (device, + format, + &format, + &self->gl_internal_format, + &self->gl_format, + &self->gl_type, + swizzle); + + gsk_gpu_image_setup (GSK_GPU_IMAGE (self), + extra_flags | + (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0), + format, + gdk_texture_get_width (owner), + gdk_texture_get_height (owner)); + gsk_gpu_image_toggle_ref_texture (GSK_GPU_IMAGE (self), owner); + + self->texture_id = tex_id; + self->owns_texture = take_ownership; + + return GSK_GPU_IMAGE (self); +} + void gsk_gl_image_bind_texture (GskGLImage *self) { diff --git a/gsk/gpu/gskglimageprivate.h b/gsk/gpu/gskglimageprivate.h index de0371aa39..a38195daee 100644 --- a/gsk/gpu/gskglimageprivate.h +++ b/gsk/gpu/gskglimageprivate.h @@ -18,6 +18,12 @@ GskGpuImage * gsk_gl_image_new (GskGLDe GdkMemoryFormat format, gsize width, gsize height); +GskGpuImage * gsk_gl_image_new_for_texture (GskGLDevice *device, + GdkTexture *owner, + GLuint tex_id, + gboolean take_ownership, + GskGpuImageFlags extra_flags); + void gsk_gl_image_bind_texture (GskGLImage *self); void gsk_gl_image_bind_framebuffer (GskGLImage *self);