Blame SOURCES/shaped-texture-get-image-via-offscreen.patch

776610
From 7bbe68b149d387ce65aaf35542a67bcc93a80d70 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Wed, 19 Dec 2018 10:08:05 +0100
776610
Subject: [PATCH 01/10] cogl/texture-2d-gl: Try to determine format for
776610
 external textures
776610
776610
Don't just set the internal format to the dummy format "any", as that causes
776610
code intended to be unreachable code to be reached. It's not possible to
776610
actually know the internal format of an external texture, however, so it might
776610
not actually correspond to the real format.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 7 ++++++-
776610
 1 file changed, 6 insertions(+), 1 deletion(-)
776610
776610
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
index d1eff4507..53be13216 100644
776610
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
@@ -470,7 +470,12 @@ allocate_custom_egl_image_external (CoglTexture2D *tex_2d,
776610
 {
776610
   CoglTexture *tex = COGL_TEXTURE (tex_2d);
776610
   CoglContext *ctx = tex->context;
776610
-  CoglPixelFormat internal_format = loader->src.egl_image_external.format;
776610
+  CoglPixelFormat external_format;
776610
+  CoglPixelFormat internal_format;
776610
+
776610
+  external_format = loader->src.egl_image_external.format;
776610
+  internal_format = _cogl_texture_determine_internal_format (tex,
776610
+                                                             external_format);
776610
 
776610
   _cogl_gl_util_clear_gl_errors (ctx);
776610
 
776610
-- 
776610
2.19.2
776610
776610
776610
From 320add39ea8e1d035f139167561ddb5ae7757d36 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Wed, 19 Dec 2018 10:12:49 +0100
776610
Subject: [PATCH 02/10] cogl/texture-2d-gl: Bind correct target when getting
776610
 data
776610
776610
While for normal textures, GL_TEXTURE_2D should be used, when it's an external
776610
texture, binding it using GL_TEXTURE_2D results in an error.
776610
776610
Reading the specification for GL_TEXTURE_EXTERNAL_OES it is unclear whether
776610
getting pixel data from a texture is possible, and tests show it doesn't result
776610
in any data, but in case it would eventually start working, at least bind the
776610
correct target for now.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 4 ++--
776610
 1 file changed, 2 insertions(+), 2 deletions(-)
776610
776610
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
index 53be13216..2cf6fed51 100644
776610
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
@@ -859,12 +859,12 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d,
776610
                                                     width,
776610
                                                     bpp);
776610
 
776610
-  _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
776610
+  _cogl_bind_gl_texture_transient (tex_2d->gl_target,
776610
                                    tex_2d->gl_texture,
776610
                                    tex_2d->is_foreign);
776610
 
776610
   ctx->texture_driver->gl_get_tex_image (ctx,
776610
-                                         GL_TEXTURE_2D,
776610
+                                         tex_2d->gl_target,
776610
                                          gl_format,
776610
                                          gl_type,
776610
                                          data);
776610
-- 
776610
2.19.2
776610
776610
776610
From f890ffe0f8970b640085d4cf767dc64bed1479a4 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Wed, 19 Dec 2018 11:46:45 +0100
776610
Subject: [PATCH 03/10] cogl/texture: Add API to check whether _get_data() will
776610
 work
776610
776610
Currently, GL_TEXTURE_EXTERNAL_OES textures doesn't support getting pixel data.
776610
Make it possible for texture users to know this.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 cogl/cogl/cogl-atlas-texture.c                   |  3 ++-
776610
 cogl/cogl/cogl-driver.h                          |  3 +++
776610
 cogl/cogl/cogl-sub-texture.c                     | 11 ++++++++++-
776610
 cogl/cogl/cogl-texture-2d-sliced.c               |  3 ++-
776610
 cogl/cogl/cogl-texture-2d.c                      | 12 +++++++++++-
776610
 cogl/cogl/cogl-texture-3d.c                      |  3 ++-
776610
 cogl/cogl/cogl-texture-private.h                 |  2 ++
776610
 cogl/cogl/cogl-texture-rectangle.c               |  3 ++-
776610
 cogl/cogl/cogl-texture.c                         |  9 +++++++++
776610
 cogl/cogl/cogl-texture.h                         |  6 ++++++
776610
 cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h |  3 +++
776610
 cogl/cogl/driver/gl/cogl-texture-2d-gl.c         |  9 +++++++++
776610
 cogl/cogl/driver/gl/gl/cogl-driver-gl.c          |  1 +
776610
 cogl/cogl/driver/gl/gles/cogl-driver-gles.c      |  1 +
776610
 cogl/cogl/driver/nop/cogl-driver-nop.c           |  1 +
776610
 cogl/cogl/winsys/cogl-texture-pixmap-x11.c       |  3 ++-
776610
 16 files changed, 66 insertions(+), 7 deletions(-)
776610
776610
diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c
776610
index 97bb84a6a..1a1f99b11 100644
776610
--- a/cogl/cogl/cogl-atlas-texture.c
776610
+++ b/cogl/cogl/cogl-atlas-texture.c
776610
@@ -1043,5 +1043,6 @@ cogl_atlas_texture_vtable =
776610
     _cogl_atlas_texture_get_gl_format,
776610
     _cogl_atlas_texture_get_type,
776610
     NULL, /* is_foreign */
776610
-    NULL /* set_auto_mipmap */
776610
+    NULL, /* set_auto_mipmap */
776610
+    NULL  /* is_get_data_supported */
776610
   };
776610
diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h
776610
index 85aa0d870..33a7598a9 100644
776610
--- a/cogl/cogl/cogl-driver.h
776610
+++ b/cogl/cogl/cogl-driver.h
776610
@@ -210,6 +210,9 @@ struct _CoglDriverVtable
776610
                            int rowstride,
776610
                            uint8_t *data);
776610
 
776610
+  CoglBool
776610
+  (* texture_2d_is_get_data_supported) (CoglTexture2D *tex_2d);
776610
+
776610
   /* Prepares for drawing by flushing the journal, framebuffer state,
776610
    * pipeline state and attribute state.
776610
    */
776610
diff --git a/cogl/cogl/cogl-sub-texture.c b/cogl/cogl/cogl-sub-texture.c
776610
index 9d7abea90..c3b436140 100644
776610
--- a/cogl/cogl/cogl-sub-texture.c
776610
+++ b/cogl/cogl/cogl-sub-texture.c
776610
@@ -454,6 +454,14 @@ _cogl_sub_texture_get_type (CoglTexture *tex)
776610
   return _cogl_texture_get_type (sub_tex->full_texture);
776610
 }
776610
 
776610
+static CoglBool
776610
+_cogl_sub_texture_is_get_data_supported (CoglTexture *tex)
776610
+{
776610
+  CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
776610
+
776610
+  return cogl_texture_is_get_data_supported (sub_tex->full_texture);
776610
+}
776610
+
776610
 static const CoglTextureVtable
776610
 cogl_sub_texture_vtable =
776610
   {
776610
@@ -476,5 +484,6 @@ cogl_sub_texture_vtable =
776610
     _cogl_sub_texture_get_gl_format,
776610
     _cogl_sub_texture_get_type,
776610
     NULL, /* is_foreign */
776610
-    NULL /* set_auto_mipmap */
776610
+    NULL, /* set_auto_mipmap */
776610
+    _cogl_sub_texture_is_get_data_supported
776610
   };
776610
diff --git a/cogl/cogl/cogl-texture-2d-sliced.c b/cogl/cogl/cogl-texture-2d-sliced.c
776610
index 4f586cde7..458b29ce5 100644
776610
--- a/cogl/cogl/cogl-texture-2d-sliced.c
776610
+++ b/cogl/cogl/cogl-texture-2d-sliced.c
776610
@@ -1542,5 +1542,6 @@ cogl_texture_2d_sliced_vtable =
776610
     _cogl_texture_2d_sliced_get_gl_format,
776610
     _cogl_texture_2d_sliced_get_type,
776610
     _cogl_texture_2d_sliced_is_foreign,
776610
-    NULL /* set_auto_mipmap */
776610
+    NULL, /* set_auto_mipmap */
776610
+    NULL  /* is_get_data_supported */
776610
   };
776610
diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c
776610
index 663125890..0e4a73de0 100644
776610
--- a/cogl/cogl/cogl-texture-2d.c
776610
+++ b/cogl/cogl/cogl-texture-2d.c
776610
@@ -94,6 +94,15 @@ _cogl_texture_2d_set_auto_mipmap (CoglTexture *tex,
776610
   tex_2d->auto_mipmap = value;
776610
 }
776610
 
776610
+static CoglBool
776610
+_cogl_texture_2d_is_get_data_supported (CoglTexture *tex)
776610
+{
776610
+  CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
776610
+  CoglContext *ctx = tex->context;
776610
+
776610
+  return ctx->driver_vtable->texture_2d_is_get_data_supported (tex_2d);
776610
+}
776610
+
776610
 CoglTexture2D *
776610
 _cogl_texture_2d_create_base (CoglContext *ctx,
776610
                               int width,
776610
@@ -693,5 +702,6 @@ cogl_texture_2d_vtable =
776610
     _cogl_texture_2d_get_gl_format,
776610
     _cogl_texture_2d_get_type,
776610
     _cogl_texture_2d_is_foreign,
776610
-    _cogl_texture_2d_set_auto_mipmap
776610
+    _cogl_texture_2d_set_auto_mipmap,
776610
+    _cogl_texture_2d_is_get_data_supported
776610
   };
776610
diff --git a/cogl/cogl/cogl-texture-3d.c b/cogl/cogl/cogl-texture-3d.c
776610
index 5644119d7..00b3447ec 100644
776610
--- a/cogl/cogl/cogl-texture-3d.c
776610
+++ b/cogl/cogl/cogl-texture-3d.c
776610
@@ -755,5 +755,6 @@ cogl_texture_3d_vtable =
776610
     _cogl_texture_3d_get_gl_format,
776610
     _cogl_texture_3d_get_type,
776610
     NULL, /* is_foreign */
776610
-    _cogl_texture_3d_set_auto_mipmap
776610
+    _cogl_texture_3d_set_auto_mipmap,
776610
+    NULL  /* is_get_data_supported */
776610
   };
776610
diff --git a/cogl/cogl/cogl-texture-private.h b/cogl/cogl/cogl-texture-private.h
776610
index 742983e2d..44100f0b7 100644
776610
--- a/cogl/cogl/cogl-texture-private.h
776610
+++ b/cogl/cogl/cogl-texture-private.h
776610
@@ -149,6 +149,8 @@ struct _CoglTextureVtable
776610
   /* Only needs to be implemented if is_primitive == TRUE */
776610
   void (* set_auto_mipmap) (CoglTexture *texture,
776610
                             CoglBool value);
776610
+
776610
+  CoglBool (* is_get_data_supported) (CoglTexture *texture);
776610
 };
776610
 
776610
 typedef enum _CoglTextureSoureType {
776610
diff --git a/cogl/cogl/cogl-texture-rectangle.c b/cogl/cogl/cogl-texture-rectangle.c
776610
index cc2e642d3..0179324a4 100644
776610
--- a/cogl/cogl/cogl-texture-rectangle.c
776610
+++ b/cogl/cogl/cogl-texture-rectangle.c
776610
@@ -773,5 +773,6 @@ cogl_texture_rectangle_vtable =
776610
     _cogl_texture_rectangle_get_gl_format,
776610
     _cogl_texture_rectangle_get_type,
776610
     _cogl_texture_rectangle_is_foreign,
776610
-    _cogl_texture_rectangle_set_auto_mipmap
776610
+    _cogl_texture_rectangle_set_auto_mipmap,
776610
+    NULL  /* is_get_data_supported */
776610
   };
776610
diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c
776610
index e2d37e225..eef2abdbe 100644
776610
--- a/cogl/cogl/cogl-texture.c
776610
+++ b/cogl/cogl/cogl-texture.c
776610
@@ -205,6 +205,15 @@ _cogl_texture_is_foreign (CoglTexture *texture)
776610
     return FALSE;
776610
 }
776610
 
776610
+CoglBool
776610
+cogl_texture_is_get_data_supported (CoglTexture *texture)
776610
+{
776610
+  if (texture->vtable->is_get_data_supported)
776610
+    return texture->vtable->is_get_data_supported (texture);
776610
+  else
776610
+    return TRUE;
776610
+}
776610
+
776610
 unsigned int
776610
 cogl_texture_get_width (CoglTexture *texture)
776610
 {
776610
diff --git a/cogl/cogl/cogl-texture.h b/cogl/cogl/cogl-texture.h
776610
index ef7d14281..67647aa9c 100644
776610
--- a/cogl/cogl/cogl-texture.h
776610
+++ b/cogl/cogl/cogl-texture.h
776610
@@ -511,6 +511,12 @@ CoglBool
776610
 cogl_texture_allocate (CoglTexture *texture,
776610
                        CoglError **error);
776610
 
776610
+/**
776610
+ * cogl_texture_is_get_data_supported: (skip)
776610
+ */
776610
+CoglBool
776610
+cogl_texture_is_get_data_supported (CoglTexture *texture);
776610
+
776610
 COGL_END_DECLS
776610
 
776610
 #endif /* __COGL_TEXTURE_H__ */
776610
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h
776610
index e5c658534..1379e9a93 100644
776610
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h
776610
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h
776610
@@ -116,4 +116,7 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d,
776610
                               int rowstride,
776610
                               uint8_t *data);
776610
 
776610
+CoglBool
776610
+_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d);
776610
+
776610
 #endif /* _COGL_TEXTURE_2D_GL_PRIVATE_H_ */
776610
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
index 2cf6fed51..f04e3ebca 100644
776610
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
776610
@@ -869,3 +869,12 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d,
776610
                                          gl_type,
776610
                                          data);
776610
 }
776610
+
776610
+CoglBool
776610
+_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d)
776610
+{
776610
+  if (tex_2d->gl_target == GL_TEXTURE_EXTERNAL_OES)
776610
+    return FALSE;
776610
+  else
776610
+    return TRUE;
776610
+}
776610
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
776610
index 178262ac0..9247e4e78 100644
776610
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
776610
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
776610
@@ -714,6 +714,7 @@ _cogl_driver_gl =
776610
     _cogl_texture_2d_gl_generate_mipmap,
776610
     _cogl_texture_2d_gl_copy_from_bitmap,
776610
     _cogl_texture_2d_gl_get_data,
776610
+    _cogl_texture_2d_gl_is_get_data_supported,
776610
     _cogl_gl_flush_attributes_state,
776610
     _cogl_clip_stack_gl_flush,
776610
     _cogl_buffer_gl_create,
776610
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
776610
index 521f6ef3d..14f9b282c 100644
776610
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
776610
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
776610
@@ -493,6 +493,7 @@ _cogl_driver_gles =
776610
     _cogl_texture_2d_gl_generate_mipmap,
776610
     _cogl_texture_2d_gl_copy_from_bitmap,
776610
     NULL, /* texture_2d_get_data */
776610
+    NULL, /* texture_2d_is_get_data_supported */
776610
     _cogl_gl_flush_attributes_state,
776610
     _cogl_clip_stack_gl_flush,
776610
     _cogl_buffer_gl_create,
776610
diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c
776610
index 6e04e7164..8424c64ef 100644
776610
--- a/cogl/cogl/driver/nop/cogl-driver-nop.c
776610
+++ b/cogl/cogl/driver/nop/cogl-driver-nop.c
776610
@@ -82,6 +82,7 @@ _cogl_driver_nop =
776610
     _cogl_texture_2d_nop_generate_mipmap,
776610
     _cogl_texture_2d_nop_copy_from_bitmap,
776610
     NULL, /* texture_2d_get_data */
776610
+    NULL, /* texture_2d_is_get_data_supported */
776610
     _cogl_nop_flush_attributes_state,
776610
     _cogl_clip_stack_nop_flush,
776610
   };
776610
diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
776610
index d03040c24..3bb057f4a 100644
776610
--- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
776610
+++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
776610
@@ -1180,5 +1180,6 @@ cogl_texture_pixmap_x11_vtable =
776610
     _cogl_texture_pixmap_x11_get_gl_format,
776610
     _cogl_texture_pixmap_x11_get_type,
776610
     NULL, /* is_foreign */
776610
-    NULL /* set_auto_mipmap */
776610
+    NULL, /* set_auto_mipmap */
776610
+    NULL  /* is_get_data_supported */
776610
   };
776610
-- 
776610
2.19.2
776610
776610
776610
From 363816fab233b965ff8b9e3a55bdb80b9cee4515 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Wed, 19 Dec 2018 11:55:43 +0100
776610
Subject: [PATCH 04/10] compositor: Make meta_actor_painting_untransformed take
776610
 a framebuffer
776610
776610
Stop using the cogl draw framebuffer implicitly.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/clutter-utils.c         | 9 +++++----
776610
 src/compositor/clutter-utils.h         | 9 +++++----
776610
 src/compositor/meta-background-actor.c | 7 ++++++-
776610
 src/compositor/meta-shaped-texture.c   | 7 +++++--
776610
 src/compositor/meta-window-group.c     | 6 +++++-
776610
 5 files changed, 26 insertions(+), 12 deletions(-)
776610
776610
diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c
776610
index fb74732ce..6591ee2d3 100644
776610
--- a/src/compositor/clutter-utils.c
776610
+++ b/src/compositor/clutter-utils.c
776610
@@ -143,7 +143,8 @@ meta_actor_is_untransformed (ClutterActor *actor,
776610
  * transform.
776610
  */
776610
 gboolean
776610
-meta_actor_painting_untransformed (int              paint_width,
776610
+meta_actor_painting_untransformed (CoglFramebuffer *fb,
776610
+                                   int              paint_width,
776610
                                    int              paint_height,
776610
                                    int             *x_origin,
776610
                                    int             *y_origin)
776610
@@ -153,8 +154,8 @@ meta_actor_painting_untransformed (int              paint_width,
776610
   float viewport[4];
776610
   int i;
776610
 
776610
-  cogl_get_modelview_matrix (&modelview);
776610
-  cogl_get_projection_matrix (&projection);
776610
+  cogl_framebuffer_get_modelview_matrix (fb, &modelview);
776610
+  cogl_framebuffer_get_projection_matrix (fb, &projection);
776610
 
776610
   cogl_matrix_multiply (&modelview_projection,
776610
                         &projection,
776610
@@ -173,7 +174,7 @@ meta_actor_painting_untransformed (int              paint_width,
776610
   vertices[3].y = paint_height;
776610
   vertices[3].z = 0;
776610
 
776610
-  cogl_get_viewport (viewport);
776610
+  cogl_framebuffer_get_viewport4fv (fb, viewport);
776610
 
776610
   for (i = 0; i < 4; i++)
776610
     {
776610
diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h
776610
index 36a5925cf..b96733e4a 100644
776610
--- a/src/compositor/clutter-utils.h
776610
+++ b/src/compositor/clutter-utils.h
776610
@@ -31,9 +31,10 @@ gboolean meta_actor_is_untransformed (ClutterActor *actor,
776610
                                       int          *x_origin,
776610
                                       int          *y_origin);
776610
 
776610
-gboolean meta_actor_painting_untransformed (int         paint_width,
776610
-                                            int         paint_height,
776610
-                                            int        *x_origin,
776610
-                                            int        *y_origin);
776610
+gboolean meta_actor_painting_untransformed (CoglFramebuffer *fb,
776610
+                                            int              paint_width,
776610
+                                            int              paint_height,
776610
+                                            int             *x_origin,
776610
+                                            int             *y_origin);
776610
 
776610
 #endif /* __META_CLUTTER_UTILS_H__ */
776610
diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c
776610
index 197a62c0f..c4c0f9561 100644
776610
--- a/src/compositor/meta-background-actor.c
776610
+++ b/src/compositor/meta-background-actor.c
776610
@@ -325,6 +325,7 @@ setup_pipeline (MetaBackgroundActor   *self,
776610
   PipelineFlags pipeline_flags = 0;
776610
   guint8 opacity;
776610
   float color_component;
776610
+  CoglFramebuffer *fb;
776610
   CoglPipelineFilter filter;
776610
 
776610
   opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
776610
@@ -417,8 +418,12 @@ setup_pipeline (MetaBackgroundActor   *self,
776610
                              color_component,
776610
                              opacity / 255.);
776610
 
776610
+  fb = cogl_get_draw_framebuffer ();
776610
   if (!priv->force_bilinear &&
776610
-      meta_actor_painting_untransformed (actor_pixel_rect->width, actor_pixel_rect->height, NULL, NULL))
776610
+      meta_actor_painting_untransformed (fb,
776610
+                                         actor_pixel_rect->width,
776610
+                                         actor_pixel_rect->height,
776610
+                                         NULL, NULL))
776610
     filter = COGL_PIPELINE_FILTER_NEAREST;
776610
   else
776610
     filter = COGL_PIPELINE_FILTER_LINEAR;
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 98346c6ae..133041ba9 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -422,17 +422,20 @@ meta_shaped_texture_paint (ClutterActor *actor)
776610
 
776610
   cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
776610
 
776610
+  fb = cogl_get_draw_framebuffer ();
776610
+
776610
   /* Use nearest-pixel interpolation if the texture is unscaled. This
776610
    * improves performance, especially with software rendering.
776610
    */
776610
 
776610
   filter = COGL_PIPELINE_FILTER_LINEAR;
776610
 
776610
-  if (meta_actor_painting_untransformed (tex_width, tex_height, NULL, NULL))
776610
+  if (meta_actor_painting_untransformed (fb,
776610
+                                         tex_width, tex_height,
776610
+                                         NULL, NULL))
776610
     filter = COGL_PIPELINE_FILTER_NEAREST;
776610
 
776610
   ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
776610
-  fb = cogl_get_draw_framebuffer ();
776610
 
776610
   opacity = clutter_actor_get_paint_opacity (actor);
776610
   clutter_actor_get_allocation_box (actor, &alloc);
776610
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
776610
index 665adee77..d41c00783 100644
776610
--- a/src/compositor/meta-window-group.c
776610
+++ b/src/compositor/meta-window-group.c
776610
@@ -81,7 +81,11 @@ meta_window_group_paint (ClutterActor *actor)
776610
    */
776610
   if (clutter_actor_is_in_clone_paint (actor))
776610
     {
776610
-      if (!meta_actor_painting_untransformed (screen_width,
776610
+      CoglFramebuffer *fb;
776610
+
776610
+      fb = cogl_get_draw_framebuffer ();
776610
+      if (!meta_actor_painting_untransformed (fb,
776610
+                                              screen_width,
776610
                                               screen_height,
776610
                                               &paint_x_origin,
776610
                                               &paint_y_origin) ||
776610
-- 
776610
2.19.2
776610
776610
776610
From ff3110a1a547e0a5523cc5ef33f52b1d706c072e Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Wed, 19 Dec 2018 12:52:58 +0100
776610
Subject: [PATCH 05/10] shaped-texture: Put actual texture painting in helper
776610
776610
This is so that it can be reused later by meta_shaped_texture_get_image() for
776610
drawing via an offscreen framebuffer.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/meta-shaped-texture.c | 89 ++++++++++++++++------------
776610
 1 file changed, 52 insertions(+), 37 deletions(-)
776610
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 133041ba9..68098a536 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -373,47 +373,18 @@ set_cogl_texture (MetaShapedTexture *stex,
776610
 }
776610
 
776610
 static void
776610
-meta_shaped_texture_paint (ClutterActor *actor)
776610
+do_paint (MetaShapedTexture *stex,
776610
+          CoglFramebuffer   *fb,
776610
+          CoglTexture       *paint_tex,
776610
+          cairo_region_t    *clip_region)
776610
 {
776610
-  MetaShapedTexture *stex = (MetaShapedTexture *) actor;
776610
   MetaShapedTexturePrivate *priv = stex->priv;
776610
   guint tex_width, tex_height;
776610
   guchar opacity;
776610
   CoglContext *ctx;
776610
-  CoglFramebuffer *fb;
776610
-  CoglTexture *paint_tex;
776610
   ClutterActorBox alloc;
776610
   CoglPipelineFilter filter;
776610
 
776610
-  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
776610
-    return;
776610
-
776610
-  if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
776610
-    clutter_actor_realize (CLUTTER_ACTOR (stex));
776610
-
776610
-  /* The GL EXT_texture_from_pixmap extension does allow for it to be
776610
-   * used together with SGIS_generate_mipmap, however this is very
776610
-   * rarely supported. Also, even when it is supported there
776610
-   * are distinct performance implications from:
776610
-   *
776610
-   *  - Updating mipmaps that we don't need
776610
-   *  - Having to reallocate pixmaps on the server into larger buffers
776610
-   *
776610
-   * So, we just unconditionally use our mipmap emulation code. If we
776610
-   * wanted to use SGIS_generate_mipmap, we'd have to  query COGL to
776610
-   * see if it was supported (no API currently), and then if and only
776610
-   * if that was the case, set the clutter texture quality to HIGH.
776610
-   * Setting the texture quality to high without SGIS_generate_mipmap
776610
-   * support for TFP textures will result in fallbacks to XGetImage.
776610
-   */
776610
-  if (priv->create_mipmaps)
776610
-    paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
776610
-  else
776610
-    paint_tex = COGL_TEXTURE (priv->texture);
776610
-
776610
-  if (paint_tex == NULL)
776610
-    return;
776610
-
776610
   tex_width = priv->tex_width;
776610
   tex_height = priv->tex_height;
776610
 
776610
@@ -422,8 +393,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
776610
 
776610
   cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
776610
 
776610
-  fb = cogl_get_draw_framebuffer ();
776610
-
776610
   /* Use nearest-pixel interpolation if the texture is unscaled. This
776610
    * improves performance, especially with software rendering.
776610
    */
776610
@@ -437,8 +406,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
776610
 
776610
   ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
776610
 
776610
-  opacity = clutter_actor_get_paint_opacity (actor);
776610
-  clutter_actor_get_allocation_box (actor, &alloc);
776610
+  opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (stex));
776610
+  clutter_actor_get_allocation_box (CLUTTER_ACTOR (stex), &alloc);
776610
 
776610
   cairo_region_t *blended_region;
776610
   gboolean use_opaque_region = (priv->opaque_region != NULL && opacity == 255);
776610
@@ -576,6 +545,52 @@ meta_shaped_texture_paint (ClutterActor *actor)
776610
     cairo_region_destroy (blended_region);
776610
 }
776610
 
776610
+static void
776610
+meta_shaped_texture_paint (ClutterActor *actor)
776610
+{
776610
+  MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
776610
+  MetaShapedTexturePrivate *priv = stex->priv;
776610
+  CoglTexture *paint_tex = NULL;
776610
+  CoglFramebuffer *fb;
776610
+
776610
+  if (!priv->texture)
776610
+    return;
776610
+
776610
+  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
776610
+    return;
776610
+
776610
+  if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
776610
+    clutter_actor_realize (CLUTTER_ACTOR (stex));
776610
+
776610
+  /* The GL EXT_texture_from_pixmap extension does allow for it to be
776610
+   * used together with SGIS_generate_mipmap, however this is very
776610
+   * rarely supported. Also, even when it is supported there
776610
+   * are distinct performance implications from:
776610
+   *
776610
+   *  - Updating mipmaps that we don't need
776610
+   *  - Having to reallocate pixmaps on the server into larger buffers
776610
+   *
776610
+   * So, we just unconditionally use our mipmap emulation code. If we
776610
+   * wanted to use SGIS_generate_mipmap, we'd have to  query COGL to
776610
+   * see if it was supported (no API currently), and then if and only
776610
+   * if that was the case, set the clutter texture quality to HIGH.
776610
+   * Setting the texture quality to high without SGIS_generate_mipmap
776610
+   * support for TFP textures will result in fallbacks to XGetImage.
776610
+   */
776610
+  if (priv->create_mipmaps)
776610
+    paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
776610
+
776610
+  if (!paint_tex)
776610
+    paint_tex = COGL_TEXTURE (priv->texture);
776610
+
776610
+  if (cogl_texture_get_width (paint_tex) == 0 ||
776610
+      cogl_texture_get_height (paint_tex) == 0)
776610
+    return;
776610
+
776610
+  fb = cogl_get_draw_framebuffer ();
776610
+  do_paint (META_SHAPED_TEXTURE (actor), fb, paint_tex, priv->clip_region);
776610
+}
776610
+
776610
 static void
776610
 meta_shaped_texture_get_preferred_width (ClutterActor *self,
776610
                                          gfloat        for_height,
776610
-- 
776610
2.19.2
776610
776610
776610
From f594c31d3f9fad5cafced8dc3e8cacb459f87bb0 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Thu, 20 Dec 2018 16:58:03 +0100
776610
Subject: [PATCH 06/10] boxes: Add helper to scale rectangles by a double
776610
776610
And change the similar region scaling helper to use this one.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/core/boxes-private.h | 10 ++++++++++
776610
 src/core/boxes.c         | 22 ++++++++++++++++++++++
776610
 2 files changed, 32 insertions(+)
776610
776610
diff --git a/src/core/boxes-private.h b/src/core/boxes-private.h
776610
index bf019b4d6..793f39527 100644
776610
--- a/src/core/boxes-private.h
776610
+++ b/src/core/boxes-private.h
776610
@@ -38,6 +38,12 @@ typedef enum
776610
   FIXED_DIRECTION_Y    = 1 << 1,
776610
 } FixedDirections;
776610
 
776610
+typedef enum _MetaRoundingStrategy
776610
+{
776610
+  META_ROUNDING_STRATEGY_SHRINK,
776610
+  META_ROUNDING_STRATEGY_GROW,
776610
+} MetaRoundingStrategy;
776610
+
776610
 /* Output functions -- note that the output buffer had better be big enough:
776610
  *   rect_to_string:   RECT_LENGTH
776610
  *   region_to_string: (RECT_LENGTH+strlen(separator_string)) *
776610
@@ -218,6 +224,10 @@ GList* meta_rectangle_find_nonintersected_monitor_edges (
776610
 gboolean meta_rectangle_is_adjecent_to (MetaRectangle *rect,
776610
                                         MetaRectangle *other);
776610
 
776610
+void meta_rectangle_scale_double (MetaRectangle        *rect,
776610
+                                  double                scale,
776610
+                                  MetaRoundingStrategy  rounding_strategy);
776610
+
776610
 static inline ClutterRect
776610
 meta_rectangle_to_clutter_rect (MetaRectangle *rect)
776610
 {
776610
diff --git a/src/core/boxes.c b/src/core/boxes.c
776610
index 35e9ac3cd..0854ecf94 100644
776610
--- a/src/core/boxes.c
776610
+++ b/src/core/boxes.c
776610
@@ -2036,3 +2036,25 @@ meta_rectangle_is_adjecent_to (MetaRectangle *rect,
776610
   else
776610
     return FALSE;
776610
 }
776610
+
776610
+void
776610
+meta_rectangle_scale_double (MetaRectangle        *rect,
776610
+                             double                scale,
776610
+                             MetaRoundingStrategy  rounding_strategy)
776610
+{
776610
+  switch (rounding_strategy)
776610
+    {
776610
+    case META_ROUNDING_STRATEGY_SHRINK:
776610
+      rect->x = (int) ceil (rect->x * scale);
776610
+      rect->y = (int) ceil (rect->y * scale);
776610
+      rect->width = (int) floor (rect->width * scale);
776610
+      rect->height = (int) floor (rect->height * scale);
776610
+      break;
776610
+    case META_ROUNDING_STRATEGY_GROW:
776610
+      rect->x = (int) floor (rect->x * scale);
776610
+      rect->y = (int) floor (rect->y * scale);
776610
+      rect->width = (int) ceil (rect->width * scale);
776610
+      rect->height = (int) ceil (rect->height * scale);
776610
+      break;
776610
+    }
776610
+}
776610
-- 
776610
2.19.2
776610
776610
776610
From 7826c0fdc45a62c6ca563d2f1526b81975243dbb Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Thu, 20 Dec 2018 17:21:26 +0100
776610
Subject: [PATCH 07/10] shaped-texture: Stop using gdk rect helper
776610
776610
We have our own version, just use that.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/meta-shaped-texture.c | 4 +---
776610
 1 file changed, 1 insertion(+), 3 deletions(-)
776610
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 68098a536..6cde86390 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -940,9 +940,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
 
776610
   if (clip != NULL)
776610
     {
776610
-      /* GdkRectangle is just a typedef of cairo_rectangle_int_t,
776610
-       * so we can use the gdk_rectangle_* APIs on these. */
776610
-      if (!gdk_rectangle_intersect (&texture_rect, clip, clip))
776610
+      if (!meta_rectangle_intersect (&texture_rect, clip, clip))
776610
         return NULL;
776610
     }
776610
 
776610
-- 
776610
2.19.2
776610
776610
776610
From a8cecf4997d28e6672bc51afea9682504225c997 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Thu, 20 Dec 2018 17:22:37 +0100
776610
Subject: [PATCH 08/10] shaped-texture: Add priv pointer to _get_image()
776610
776610
The MetaShapedTexturePrivate is accessed more than once, so keep a
776610
pointer to it.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/meta-shaped-texture.c | 5 +++--
776610
 1 file changed, 3 insertions(+), 2 deletions(-)
776610
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 6cde86390..0fa5fa92f 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -924,13 +924,14 @@ cairo_surface_t *
776610
 meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
                                cairo_rectangle_int_t *clip)
776610
 {
776610
+  MetaShapedTexturePrivate *priv = stex->priv;
776610
   CoglTexture *texture, *mask_texture;
776610
   cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
776610
   cairo_surface_t *surface;
776610
 
776610
   g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
776610
 
776610
-  texture = COGL_TEXTURE (stex->priv->texture);
776610
+  texture = COGL_TEXTURE (priv->texture);
776610
 
776610
   if (texture == NULL)
776610
     return NULL;
776610
@@ -964,7 +965,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
   if (clip != NULL)
776610
     cogl_object_unref (texture);
776610
 
776610
-  mask_texture = stex->priv->mask_texture;
776610
+  mask_texture = priv->mask_texture;
776610
   if (mask_texture != NULL)
776610
     {
776610
       cairo_t *cr;
776610
-- 
776610
2.19.2
776610
776610
776610
From a2fb231955a41a9e87ffcdf845fa4dbca0d31dc4 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Thu, 20 Dec 2018 17:32:27 +0100
776610
Subject: [PATCH 09/10] shaped-texture: Don't change the callers clip rect
776610
776610
We intersected the callers clip rect. That is probably not a good idea,
776610
and easily avoided, so lets avoid it.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/meta-shaped-texture.c | 36 +++++++++++++++-------------
776610
 1 file changed, 20 insertions(+), 16 deletions(-)
776610
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 0fa5fa92f..823bd47f2 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -925,6 +925,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
                                cairo_rectangle_int_t *clip)
776610
 {
776610
   MetaShapedTexturePrivate *priv = stex->priv;
776610
+  cairo_rectangle_int_t *transformed_clip = NULL;
776610
   CoglTexture *texture, *mask_texture;
776610
   cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
776610
   cairo_surface_t *surface;
776610
@@ -936,21 +937,23 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
   if (texture == NULL)
776610
     return NULL;
776610
 
776610
-  texture_rect.width = cogl_texture_get_width (texture);
776610
-  texture_rect.height = cogl_texture_get_height (texture);
776610
 
776610
   if (clip != NULL)
776610
     {
776610
-      if (!meta_rectangle_intersect (&texture_rect, clip, clip))
776610
+      transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
776610
+      *transformed_clip = *clip;
776610
+
776610
+      if (!meta_rectangle_intersect (&texture_rect, transformed_clip,
776610
+                                     transformed_clip))
776610
         return NULL;
776610
     }
776610
 
776610
-  if (clip != NULL)
776610
+  if (transformed_clip)
776610
     texture = cogl_texture_new_from_sub_texture (texture,
776610
-                                                 clip->x,
776610
-                                                 clip->y,
776610
-                                                 clip->width,
776610
-                                                 clip->height);
776610
+                                                 transformed_clip->x,
776610
+                                                 transformed_clip->y,
776610
+                                                 transformed_clip->width,
776610
+                                                 transformed_clip->height);
776610
 
776610
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
776610
                                         cogl_texture_get_width (texture),
776610
@@ -962,7 +965,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
 
776610
   cairo_surface_mark_dirty (surface);
776610
 
776610
-  if (clip != NULL)
776610
+  if (transformed_clip)
776610
     cogl_object_unref (texture);
776610
 
776610
   mask_texture = priv->mask_texture;
776610
@@ -971,12 +974,13 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
       cairo_t *cr;
776610
       cairo_surface_t *mask_surface;
776610
 
776610
-      if (clip != NULL)
776610
-        mask_texture = cogl_texture_new_from_sub_texture (mask_texture,
776610
-                                                          clip->x,
776610
-                                                          clip->y,
776610
-                                                          clip->width,
776610
-                                                          clip->height);
776610
+      if (transformed_clip)
776610
+        mask_texture =
776610
+          cogl_texture_new_from_sub_texture (mask_texture,
776610
+                                             transformed_clip->x,
776610
+                                             transformed_clip->y,
776610
+                                             transformed_clip->width,
776610
+                                             transformed_clip->height);
776610
 
776610
       mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
776610
                                                  cogl_texture_get_width (mask_texture),
776610
@@ -996,7 +1000,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
 
776610
       cairo_surface_destroy (mask_surface);
776610
 
776610
-      if (clip != NULL)
776610
+      if (transformed_clip)
776610
         cogl_object_unref (mask_texture);
776610
     }
776610
 
776610
-- 
776610
2.19.2
776610
776610
776610
From 0adfd8966c2de7bfb3223911d194119f1ab46828 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Thu, 20 Dec 2018 17:34:18 +0100
776610
Subject: [PATCH 10/10] shaped-texture: Draw external textures via offscreen
776610
776610
EGLStream textures are imported as GL_TEXTURE_EXTERNAL_OES and reading
776610
pixels directly from them is not supported. To make it possible to get
776610
pixels, create an offscreen framebuffer and paint the actor to it, then
776610
read pixels from the framebuffer instead of the texture directly.
776610
776610
https://gitlab.gnome.org/GNOME/mutter/merge_requests/362
776610
---
776610
 src/compositor/meta-shaped-texture.c | 136 ++++++++++++++++++++++++++-
776610
 1 file changed, 134 insertions(+), 2 deletions(-)
776610
776610
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
776610
index 823bd47f2..d8c250fc9 100644
776610
--- a/src/compositor/meta-shaped-texture.c
776610
+++ b/src/compositor/meta-shaped-texture.c
776610
@@ -35,6 +35,7 @@
776610
 
776610
 #include "clutter-utils.h"
776610
 #include "meta-texture-tower.h"
776610
+#include "core/boxes-private.h"
776610
 
776610
 #include "meta-cullable.h"
776610
 
776610
@@ -906,6 +907,121 @@ meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
776610
   return priv->opaque_region;
776610
 }
776610
 
776610
+static gboolean
776610
+should_get_via_offscreen (MetaShapedTexture *stex)
776610
+{
776610
+  MetaShapedTexturePrivate *priv = stex->priv;
776610
+
776610
+  if (!cogl_texture_is_get_data_supported (priv->texture))
776610
+    return TRUE;
776610
+
776610
+  return FALSE;
776610
+}
776610
+
776610
+static cairo_surface_t *
776610
+get_image_via_offscreen (MetaShapedTexture     *stex,
776610
+                         cairo_rectangle_int_t *clip)
776610
+{
776610
+  MetaShapedTexturePrivate *priv = stex->priv;
776610
+  ClutterBackend *clutter_backend = clutter_get_default_backend ();
776610
+  CoglContext *cogl_context =
776610
+    clutter_backend_get_cogl_context (clutter_backend);
776610
+  CoglTexture *image_texture;
776610
+  GError *error = NULL;
776610
+  CoglOffscreen *offscreen;
776610
+  CoglFramebuffer *fb;
776610
+  CoglMatrix projection_matrix;
776610
+  unsigned int fb_width, fb_height;
776610
+  cairo_rectangle_int_t fallback_clip;
776610
+  CoglColor clear_color;
776610
+  cairo_surface_t *surface;
776610
+
776610
+  if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_TEXTURE_NPOT))
776610
+    {
776610
+      fb_width = priv->tex_width;
776610
+      fb_height = priv->tex_height;
776610
+    }
776610
+  else
776610
+    {
776610
+      fb_width = clutter_util_next_p2 (priv->tex_width);
776610
+      fb_height = clutter_util_next_p2 (priv->tex_height);
776610
+    }
776610
+
776610
+  if (!clip)
776610
+    {
776610
+      fallback_clip = (cairo_rectangle_int_t) {
776610
+        .width = priv->tex_width,
776610
+        .height = priv->tex_height,
776610
+      };
776610
+      clip = &fallback_clip;
776610
+    }
776610
+
776610
+  image_texture =
776610
+    COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
776610
+                                                 fb_width, fb_height));
776610
+  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture),
776610
+                                          FALSE);
776610
+  if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error))
776610
+    {
776610
+      g_error_free (error);
776610
+      cogl_object_unref (image_texture);
776610
+      return FALSE;
776610
+    }
776610
+
776610
+  if (fb_width != priv->tex_width || fb_height != priv->tex_height)
776610
+    {
776610
+      CoglSubTexture *sub_texture;
776610
+
776610
+      sub_texture = cogl_sub_texture_new (cogl_context,
776610
+                                          image_texture,
776610
+                                          0, 0,
776610
+                                          priv->tex_width, priv->tex_height);
776610
+      cogl_object_unref (image_texture);
776610
+      image_texture = COGL_TEXTURE (sub_texture);
776610
+    }
776610
+
776610
+  offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (image_texture));
776610
+  fb = COGL_FRAMEBUFFER (offscreen);
776610
+  cogl_object_unref (image_texture);
776610
+  if (!cogl_framebuffer_allocate (fb, &error))
776610
+    {
776610
+      g_error_free (error);
776610
+      cogl_object_unref (fb);
776610
+      return FALSE;
776610
+    }
776610
+
776610
+  cogl_framebuffer_push_matrix (fb);
776610
+  cogl_matrix_init_identity (&projection_matrix);
776610
+  cogl_matrix_scale (&projection_matrix,
776610
+                     1.0 / (priv->tex_width / 2.0),
776610
+                     -1.0 / (priv->tex_height / 2.0), 0);
776610
+  cogl_matrix_translate (&projection_matrix,
776610
+                         -(priv->tex_width / 2.0),
776610
+                         -(priv->tex_height / 2.0), 0);
776610
+
776610
+  cogl_framebuffer_set_projection_matrix (fb, &projection_matrix);
776610
+
776610
+  cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
776610
+  cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
776610
+
776610
+  do_paint (stex, fb, priv->texture, NULL);
776610
+
776610
+  cogl_framebuffer_pop_matrix (fb);
776610
+
776610
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
776610
+                                        clip->width, clip->height);
776610
+  cogl_framebuffer_read_pixels (fb,
776610
+                                clip->x, clip->y,
776610
+                                clip->width, clip->height,
776610
+                                CLUTTER_CAIRO_FORMAT_ARGB32,
776610
+                                cairo_image_surface_get_data (surface));
776610
+  cogl_object_unref (fb);
776610
+
776610
+  cairo_surface_mark_dirty (surface);
776610
+
776610
+  return surface;
776610
+}
776610
+
776610
 /**
776610
  * meta_shaped_texture_get_image:
776610
  * @stex: A #MetaShapedTexture
776610
@@ -927,7 +1043,6 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
   MetaShapedTexturePrivate *priv = stex->priv;
776610
   cairo_rectangle_int_t *transformed_clip = NULL;
776610
   CoglTexture *texture, *mask_texture;
776610
-  cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
776610
   cairo_surface_t *surface;
776610
 
776610
   g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
776610
@@ -937,17 +1052,34 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
776610
   if (texture == NULL)
776610
     return NULL;
776610
 
776610
+  if (priv->tex_width == 0 || priv->tex_height == 0)
776610
+    return NULL;
776610
 
776610
   if (clip != NULL)
776610
     {
776610
+      double tex_scale;
776610
+      cairo_rectangle_int_t tex_rect;
776610
+
776610
       transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
776610
       *transformed_clip = *clip;
776610
 
776610
-      if (!meta_rectangle_intersect (&texture_rect, transformed_clip,
776610
+      clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
776610
+      meta_rectangle_scale_double (transformed_clip, 1.0 / tex_scale,
776610
+                                   META_ROUNDING_STRATEGY_GROW);
776610
+
776610
+      tex_rect = (cairo_rectangle_int_t) {
776610
+        .width = priv->tex_width,
776610
+        .height = priv->tex_height,
776610
+      };
776610
+
776610
+      if (!meta_rectangle_intersect (&tex_rect, transformed_clip,
776610
                                      transformed_clip))
776610
         return NULL;
776610
     }
776610
 
776610
+  if (should_get_via_offscreen (stex))
776610
+    return get_image_via_offscreen (stex, transformed_clip);
776610
+
776610
   if (transformed_clip)
776610
     texture = cogl_texture_new_from_sub_texture (texture,
776610
                                                  transformed_clip->x,
776610
-- 
776610
2.19.2
776610