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
|
* This blits a region of the color buffer of the source buffer
|
||||||
* to the destination buffer. This function should only be
|
* to the destination buffer. This function should only be
|
||||||
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
|
* 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,
|
* 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
|
* 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
|
* scale the results it may make more sense to draw a primitive
|
||||||
* instead.
|
* 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
|
* The GL function is documented to be affected by the scissor. This
|
||||||
* function therefore ensure that an empty clip stack is flushed
|
* function therefore ensure that an empty clip stack is flushed
|
||||||
* before performing the blit which means the scissor is effectively
|
* before performing the blit which means the scissor is effectively
|
||||||
|
@ -1352,15 +1352,12 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
|||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
CoglContext *ctx = src->context;
|
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
|
g_return_if_fail (_cogl_has_private_feature
|
||||||
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
(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 */
|
/* The buffers must use the same premult convention */
|
||||||
g_return_if_fail ((src->internal_format & COGL_PREMULT_BIT) ==
|
g_return_if_fail ((src->internal_format & COGL_PREMULT_BIT) ==
|
||||||
(dest->internal_format & COGL_PREMULT_BIT));
|
(dest->internal_format & COGL_PREMULT_BIT));
|
||||||
@ -1384,10 +1381,41 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
|
|||||||
* as changed */
|
* as changed */
|
||||||
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||||
|
|
||||||
ctx->glBlitFramebuffer (src_x, src_y,
|
/* Offscreens we do the normal way, onscreens need an y-flip. Even if
|
||||||
src_x + width, src_y + height,
|
* we consider offscreens to be rendered upside-down, the offscreen
|
||||||
dst_x, dst_y,
|
* orientation is in this function's API. */
|
||||||
dst_x + width, dst_y + height,
|
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_COLOR_BUFFER_BIT,
|
||||||
GL_NEAREST);
|
GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
@ -385,12 +385,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* NB: Currently we only take advantage of binding separate
|
/* NB: Currently we only take advantage of binding separate
|
||||||
* read/write buffers for offscreen framebuffer blit
|
* read/write buffers for framebuffer blit purposes. */
|
||||||
* purposes. */
|
|
||||||
g_return_if_fail (_cogl_has_private_feature
|
g_return_if_fail (_cogl_has_private_feature
|
||||||
(ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
|
(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 (draw_buffer, GL_DRAW_FRAMEBUFFER);
|
||||||
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
|
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
|
||||||
|
Loading…
Reference in New Issue
Block a user