cogl: Allow glBlitFramebuffer between onscreen/offscreen
Depends on "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit" Allow blitting between onscreen and offscreen framebuffers by doing the y-flip as necessary. This was not possible with ANGLE, but now with ANGLE gone, glBlitFramebuffer supports flipping the copied image. This will be useful in follow-up work to copy from onscreen primary GPU framebuffer to an offscreen secondary GPU framebuffer. https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
This commit is contained in:
parent
6df34eb4b7
commit
45289b3d65
@ -378,7 +378,11 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
|
||||
* This blits a region of the color buffer of the source buffer
|
||||
* to the destination buffer. This function should only be
|
||||
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
|
||||
* advertised. The two buffers must both be offscreen.
|
||||
* advertised.
|
||||
*
|
||||
* The source and destination rectangles are defined in offscreen
|
||||
* framebuffer orientation. When copying between an offscreen and
|
||||
* onscreen framebuffers, the image is y-flipped accordingly.
|
||||
*
|
||||
* The two buffers must have the same value types (e.g. floating-point,
|
||||
* unsigned int, signed int, or fixed-point), but color formats do not
|
||||
@ -393,14 +397,6 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
|
||||
* scale the results it may make more sense to draw a primitive
|
||||
* instead.
|
||||
*
|
||||
* We can only really support blitting between two offscreen buffers
|
||||
* for this function on GLES2.0. This is because we effectively render
|
||||
* upside down to offscreen buffers to maintain Cogl's representation
|
||||
* of the texture coordinate system where 0,0 is the top left of the
|
||||
* texture. If we were to blit from an offscreen to an onscreen buffer
|
||||
* then we would need to mirror the blit along the x-axis but the GLES
|
||||
* extension does not support this.
|
||||
*
|
||||
* The GL function is documented to be affected by the scissor. This
|
||||
* function therefore ensure that an empty clip stack is flushed
|
||||
* before performing the blit which means the scissor is effectively
|
||||
|
@ -1352,15 +1352,12 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
||||
int height)
|
||||
{
|
||||
CoglContext *ctx = src->context;
|
||||
int src_x1, src_y1, src_x2, src_y2;
|
||||
int dst_x1, dst_y1, dst_x2, dst_y2;
|
||||
|
||||
g_return_if_fail (_cogl_has_private_feature
|
||||
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
||||
|
||||
/* We can only support blitting between offscreen buffers because
|
||||
otherwise we would need to mirror the image and GLES2.0 doesn't
|
||||
support this */
|
||||
g_return_if_fail (cogl_is_offscreen (src));
|
||||
g_return_if_fail (cogl_is_offscreen (dest));
|
||||
/* The buffers must use the same premult convention */
|
||||
g_return_if_fail ((src->internal_format & COGL_PREMULT_BIT) ==
|
||||
(dest->internal_format & COGL_PREMULT_BIT));
|
||||
@ -1384,10 +1381,41 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
||||
* as changed */
|
||||
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
|
||||
ctx->glBlitFramebuffer (src_x, src_y,
|
||||
src_x + width, src_y + height,
|
||||
dst_x, dst_y,
|
||||
dst_x + width, dst_y + height,
|
||||
/* Offscreens we do the normal way, onscreens need an y-flip. Even if
|
||||
* we consider offscreens to be rendered upside-down, the offscreen
|
||||
* orientation is in this function's API. */
|
||||
if (cogl_is_offscreen (src))
|
||||
{
|
||||
src_x1 = src_x;
|
||||
src_y1 = src_y;
|
||||
src_x2 = src_x + width;
|
||||
src_y2 = src_y + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_x1 = src_x;
|
||||
src_y1 = cogl_framebuffer_get_height (src) - src_y;
|
||||
src_x2 = src_x + width;
|
||||
src_y2 = src_y1 - height;
|
||||
}
|
||||
|
||||
if (cogl_is_offscreen (dest))
|
||||
{
|
||||
dst_x1 = dst_x;
|
||||
dst_y1 = dst_y;
|
||||
dst_x2 = dst_x + width;
|
||||
dst_y2 = dst_y + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_x1 = dst_x;
|
||||
dst_y1 = cogl_framebuffer_get_height (dest) - dst_y;
|
||||
dst_x2 = dst_x + width;
|
||||
dst_y2 = dst_y1 - height;
|
||||
}
|
||||
|
||||
ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2,
|
||||
dst_x1, dst_y1, dst_x2, dst_y2,
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST);
|
||||
}
|
||||
|
@ -385,12 +385,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
||||
else
|
||||
{
|
||||
/* NB: Currently we only take advantage of binding separate
|
||||
* read/write buffers for offscreen framebuffer blit
|
||||
* purposes. */
|
||||
* read/write buffers for framebuffer blit purposes. */
|
||||
g_return_if_fail (_cogl_has_private_feature
|
||||
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
||||
g_return_if_fail (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
|
||||
g_return_if_fail (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
|
||||
|
||||
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
|
||||
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
|
||||
|
Loading…
Reference in New Issue
Block a user