cogl: Expose cogl_blit_framebuffer

The function will be used in copying from a primary GPU framebuffer to a
secondary GPU framebuffer using the primary GPU specifically when the
secondary GPU is not render-capable.

To allow falling back in case glBlitFramebuffer cannot be used, add boolean
return value, and GError argument for debugging purposes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
This commit is contained in:
Pekka Paalanen 2018-12-03 14:34:41 +02:00 committed by Jonas Ådahl
parent 55c084e6e1
commit 6061abbf90
4 changed files with 98 additions and 74 deletions

View File

@ -207,11 +207,12 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data,
int width, int width,
int height) int height)
{ {
_cogl_blit_framebuffer (data->src_fb, cogl_blit_framebuffer (data->src_fb,
data->dest_fb, data->dest_fb,
src_x, src_y, src_x, src_y,
dst_x, dst_y, dst_x, dst_y,
width, height); width, height,
NULL);
} }
static void static void

View File

@ -364,61 +364,6 @@ void
_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer); CoglFramebuffer *read_buffer);
/*
* _cogl_blit_framebuffer:
* @src: The source #CoglFramebuffer
* @dest: The destination #CoglFramebuffer
* @src_x: Source x position
* @src_y: Source y position
* @dst_x: Destination x position
* @dst_y: Destination y position
* @width: Width of region to copy
* @height: Height of region to copy
*
* 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_BLIT_FRAMEBUFFER feature is
* 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
* need to match. This limitation comes from OpenGL ES 3.0 definition
* of glBlitFramebuffer.
*
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
* it doesn't support having different sizes for the source and
* destination rectangle. This doesn't seem
* like a particularly useful feature. If the application wanted to
* scale the results it may make more sense to draw a primitive
* instead.
*
* 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
* ignored.
*
* The function also doesn't support specifying the buffers to copy
* and instead only the color buffer is copied. When copying the depth
* or stencil buffers the extension on GLES2.0 only supports copying
* the full buffer which would be awkward to document with this
* API. If we wanted to support that feature it may be better to have
* a separate function to copy the entire buffer for a given mask.
*/
void
_cogl_blit_framebuffer (CoglFramebuffer *src,
CoglFramebuffer *dest,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height);
void void
_cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer); _cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);

View File

@ -1341,26 +1341,38 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
return ret; return ret;
} }
void gboolean
_cogl_blit_framebuffer (CoglFramebuffer *src, cogl_blit_framebuffer (CoglFramebuffer *src,
CoglFramebuffer *dest, CoglFramebuffer *dest,
int src_x, int src_x,
int src_y, int src_y,
int dst_x, int dst_x,
int dst_y, int dst_y,
int width, int width,
int height) int height,
GError **error)
{ {
CoglContext *ctx = src->context; CoglContext *ctx = src->context;
int src_x1, src_y1, src_x2, src_y2; int src_x1, src_y1, src_x2, src_y2;
int dst_x1, dst_y1, dst_x2, dst_y2; int dst_x1, dst_y1, dst_x2, dst_y2;
g_return_if_fail (_cogl_has_private_feature if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
(ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)); {
g_set_error_literal (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"Cogl BLIT_FRAMEBUFFER is not supported by the system.");
return FALSE;
}
/* 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) == if ((src->internal_format & COGL_PREMULT_BIT) !=
(dest->internal_format & COGL_PREMULT_BIT)); (dest->internal_format & COGL_PREMULT_BIT))
{
g_set_error_literal (error, COGL_SYSTEM_ERROR,
COGL_SYSTEM_ERROR_UNSUPPORTED,
"cogl_blit_framebuffer premult mismatch.");
return FALSE;
}
/* Make sure the current framebuffers are bound. We explicitly avoid /* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */ flushing the clip state so we can bind our own empty state */
@ -1418,6 +1430,8 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
dst_x1, dst_y1, dst_x2, dst_y2, dst_x1, dst_y1, dst_x2, dst_y2,
GL_COLOR_BUFFER_BIT, GL_COLOR_BUFFER_BIT,
GL_NEAREST); GL_NEAREST);
return TRUE;
} }
void void

View File

@ -3,7 +3,8 @@
* *
* A Low Level GPU Graphics and Utilities API * A Low Level GPU Graphics and Utilities API
* *
* Copyright (C) 2011 Intel Corporation. * Copyright (C) 2007,2008,2009,2011 Intel Corporation.
* Copyright (C) 2019 DisplayLink (UK) Ltd.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -1797,6 +1798,69 @@ typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/
gboolean gboolean
cogl_is_framebuffer (void *object); cogl_is_framebuffer (void *object);
/**
* cogl_blit_framebuffer:
* @src: The source #CoglFramebuffer
* @dest: The destination #CoglFramebuffer
* @src_x: Source x position
* @src_y: Source y position
* @dst_x: Destination x position
* @dst_y: Destination y position
* @width: Width of region to copy
* @height: Height of region to copy
* @error: optional error object
*
* @return FALSE for an immediately detected error, TRUE otherwise.
*
* 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_BLIT_FRAMEBUFFER feature is
* 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
* need to match. This limitation comes from OpenGL ES 3.0 definition
* of glBlitFramebuffer.
*
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
* it doesn't support having different sizes for the source and
* destination rectangle. This doesn't seem
* like a particularly useful feature. If the application wanted to
* scale the results it may make more sense to draw a primitive
* instead.
*
* 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
* ignored.
*
* The function also doesn't support specifying the buffers to copy
* and instead only the color buffer is copied. When copying the depth
* or stencil buffers the extension on GLES2.0 only supports copying
* the full buffer which would be awkward to document with this
* API. If we wanted to support that feature it may be better to have
* a separate function to copy the entire buffer for a given mask.
*
* The @c error argument is optional, it can be NULL. If it is not NULL
* and this function returns FALSE, an error object with a code from
* COGL_SYSTEM_ERROR will be created.
*/
gboolean
cogl_blit_framebuffer (CoglFramebuffer *src,
CoglFramebuffer *dest,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height,
GError **error);
G_END_DECLS G_END_DECLS
#endif /* __COGL_FRAMEBUFFER_H */ #endif /* __COGL_FRAMEBUFFER_H */