|
|
657d8e |
From e4b2234d9918e9d3357ac3c7ca3898599725d3da Mon Sep 17 00:00:00 2001
|
|
|
657d8e |
From: Pekka Paalanen <pekka.paalanen@collabora.com>
|
|
|
657d8e |
Date: Mon, 6 May 2019 15:08:29 +0300
|
|
|
657d8e |
Subject: [PATCH 05/12] cogl: Allow glBlitFramebuffer between
|
|
|
657d8e |
onscreen/offscreen
|
|
|
657d8e |
|
|
|
657d8e |
Depends on "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit"
|
|
|
657d8e |
|
|
|
657d8e |
Allow blitting between onscreen and offscreen framebuffers by doing the y-flip
|
|
|
657d8e |
as necessary. This was not possible with ANGLE, but now with ANGLE gone,
|
|
|
657d8e |
glBlitFramebuffer supports flipping the copied image.
|
|
|
657d8e |
|
|
|
657d8e |
This will be useful in follow-up work to copy from onscreen primary GPU
|
|
|
657d8e |
framebuffer to an offscreen secondary GPU framebuffer.
|
|
|
657d8e |
|
|
|
657d8e |
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
|
|
|
657d8e |
|
|
|
657d8e |
(cherry picked from commit 45289b3d65e308117f1bc8fe6a4c88c1baaacca7)
|
|
|
657d8e |
---
|
|
|
657d8e |
cogl/cogl/cogl-framebuffer-private.h | 14 +++----
|
|
|
657d8e |
cogl/cogl/cogl-framebuffer.c | 46 ++++++++++++++++++-----
|
|
|
657d8e |
cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 5 +--
|
|
|
657d8e |
3 files changed, 43 insertions(+), 22 deletions(-)
|
|
|
657d8e |
|
|
|
657d8e |
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
|
|
|
657d8e |
index b06fbaee1..f68153d8b 100644
|
|
|
657d8e |
--- a/cogl/cogl/cogl-framebuffer-private.h
|
|
|
657d8e |
+++ b/cogl/cogl/cogl-framebuffer-private.h
|
|
|
657d8e |
@@ -381,7 +381,11 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
|
|
|
657d8e |
* This blits a region of the color buffer of the source buffer
|
|
|
657d8e |
* to the destination buffer. This function should only be
|
|
|
657d8e |
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
|
|
|
657d8e |
- * advertised. The two buffers must both be offscreen.
|
|
|
657d8e |
+ * advertised.
|
|
|
657d8e |
+ *
|
|
|
657d8e |
+ * The source and destination rectangles are defined in offscreen
|
|
|
657d8e |
+ * framebuffer orientation. When copying between an offscreen and
|
|
|
657d8e |
+ * onscreen framebuffers, the image is y-flipped accordingly.
|
|
|
657d8e |
*
|
|
|
657d8e |
* The two buffers must have the same value types (e.g. floating-point,
|
|
|
657d8e |
* unsigned int, signed int, or fixed-point), but color formats do not
|
|
|
657d8e |
@@ -396,14 +400,6 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
|
|
|
657d8e |
* scale the results it may make more sense to draw a primitive
|
|
|
657d8e |
* instead.
|
|
|
657d8e |
*
|
|
|
657d8e |
- * We can only really support blitting between two offscreen buffers
|
|
|
657d8e |
- * for this function on GLES2.0. This is because we effectively render
|
|
|
657d8e |
- * upside down to offscreen buffers to maintain Cogl's representation
|
|
|
657d8e |
- * of the texture coordinate system where 0,0 is the top left of the
|
|
|
657d8e |
- * texture. If we were to blit from an offscreen to an onscreen buffer
|
|
|
657d8e |
- * then we would need to mirror the blit along the x-axis but the GLES
|
|
|
657d8e |
- * extension does not support this.
|
|
|
657d8e |
- *
|
|
|
657d8e |
* The GL function is documented to be affected by the scissor. This
|
|
|
657d8e |
* function therefore ensure that an empty clip stack is flushed
|
|
|
657d8e |
* before performing the blit which means the scissor is effectively
|
|
|
657d8e |
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
|
|
|
657d8e |
index 0bc225945..90976a611 100644
|
|
|
657d8e |
--- a/cogl/cogl/cogl-framebuffer.c
|
|
|
657d8e |
+++ b/cogl/cogl/cogl-framebuffer.c
|
|
|
657d8e |
@@ -1460,15 +1460,12 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
|
|
657d8e |
int height)
|
|
|
657d8e |
{
|
|
|
657d8e |
CoglContext *ctx = src->context;
|
|
|
657d8e |
+ int src_x1, src_y1, src_x2, src_y2;
|
|
|
657d8e |
+ int dst_x1, dst_y1, dst_x2, dst_y2;
|
|
|
657d8e |
|
|
|
657d8e |
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
|
|
|
657d8e |
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
|
|
657d8e |
|
|
|
657d8e |
- /* We can only support blitting between offscreen buffers because
|
|
|
657d8e |
- otherwise we would need to mirror the image and GLES2.0 doesn't
|
|
|
657d8e |
- support this */
|
|
|
657d8e |
- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
|
|
|
657d8e |
- _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
|
|
|
657d8e |
/* The buffers must use the same premult convention */
|
|
|
657d8e |
_COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
|
|
|
657d8e |
(dest->internal_format & COGL_PREMULT_BIT));
|
|
|
657d8e |
@@ -1492,10 +1489,41 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
|
|
657d8e |
* as changed */
|
|
|
657d8e |
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
|
|
657d8e |
|
|
|
657d8e |
- ctx->glBlitFramebuffer (src_x, src_y,
|
|
|
657d8e |
- src_x + width, src_y + height,
|
|
|
657d8e |
- dst_x, dst_y,
|
|
|
657d8e |
- dst_x + width, dst_y + height,
|
|
|
657d8e |
+ /* Offscreens we do the normal way, onscreens need an y-flip. Even if
|
|
|
657d8e |
+ * we consider offscreens to be rendered upside-down, the offscreen
|
|
|
657d8e |
+ * orientation is in this function's API. */
|
|
|
657d8e |
+ if (cogl_is_offscreen (src))
|
|
|
657d8e |
+ {
|
|
|
657d8e |
+ src_x1 = src_x;
|
|
|
657d8e |
+ src_y1 = src_y;
|
|
|
657d8e |
+ src_x2 = src_x + width;
|
|
|
657d8e |
+ src_y2 = src_y + height;
|
|
|
657d8e |
+ }
|
|
|
657d8e |
+ else
|
|
|
657d8e |
+ {
|
|
|
657d8e |
+ src_x1 = src_x;
|
|
|
657d8e |
+ src_y1 = cogl_framebuffer_get_height (src) - src_y;
|
|
|
657d8e |
+ src_x2 = src_x + width;
|
|
|
657d8e |
+ src_y2 = src_y1 - height;
|
|
|
657d8e |
+ }
|
|
|
657d8e |
+
|
|
|
657d8e |
+ if (cogl_is_offscreen (dest))
|
|
|
657d8e |
+ {
|
|
|
657d8e |
+ dst_x1 = dst_x;
|
|
|
657d8e |
+ dst_y1 = dst_y;
|
|
|
657d8e |
+ dst_x2 = dst_x + width;
|
|
|
657d8e |
+ dst_y2 = dst_y + height;
|
|
|
657d8e |
+ }
|
|
|
657d8e |
+ else
|
|
|
657d8e |
+ {
|
|
|
657d8e |
+ dst_x1 = dst_x;
|
|
|
657d8e |
+ dst_y1 = cogl_framebuffer_get_height (dest) - dst_y;
|
|
|
657d8e |
+ dst_x2 = dst_x + width;
|
|
|
657d8e |
+ dst_y2 = dst_y1 - height;
|
|
|
657d8e |
+ }
|
|
|
657d8e |
+
|
|
|
657d8e |
+ ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2,
|
|
|
657d8e |
+ dst_x1, dst_y1, dst_x2, dst_y2,
|
|
|
657d8e |
GL_COLOR_BUFFER_BIT,
|
|
|
657d8e |
GL_NEAREST);
|
|
|
657d8e |
}
|
|
|
657d8e |
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
|
|
|
657d8e |
index 5402a7075..83e1d263a 100644
|
|
|
657d8e |
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
|
|
|
657d8e |
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
|
|
|
657d8e |
@@ -400,12 +400,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
|
|
657d8e |
else
|
|
|
657d8e |
{
|
|
|
657d8e |
/* NB: Currently we only take advantage of binding separate
|
|
|
657d8e |
- * read/write buffers for offscreen framebuffer blit
|
|
|
657d8e |
- * purposes. */
|
|
|
657d8e |
+ * read/write buffers for framebuffer blit purposes. */
|
|
|
657d8e |
_COGL_RETURN_IF_FAIL (_cogl_has_private_feature
|
|
|
657d8e |
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
|
|
657d8e |
- _COGL_RETURN_IF_FAIL (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
|
|
|
657d8e |
- _COGL_RETURN_IF_FAIL (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
|
|
|
657d8e |
|
|
|
657d8e |
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
|
|
|
657d8e |
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
|
|
|
657d8e |
--
|
|
|
657d8e |
2.21.0
|
|
|
657d8e |
|