cogl: Determine glReadPixels format based on framebuffer format
Which gltype and glformat are allowed for a given gl framebuffer depends on the internal gl framebuffer format. Either the format we want to read into matches the gltype, glformat and doesn't need CPU packing from another format or we have to use a tmp buffer with a format that matches the GL requirements. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3441>
This commit is contained in:
parent
07bfb24312
commit
d90c2ab2a0
@ -62,11 +62,12 @@ struct _CoglDriverVtable
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype);
|
||||
|
||||
gboolean
|
||||
(* read_pixels_format_supported) (CoglContext *ctx,
|
||||
GLenum gl_intformat,
|
||||
GLenum gl_format,
|
||||
GLenum gl_type);
|
||||
CoglPixelFormat
|
||||
(* get_read_pixels_format) (CoglContext *context,
|
||||
CoglPixelFormat from,
|
||||
CoglPixelFormat to,
|
||||
GLenum *gl_format_out,
|
||||
GLenum *gl_type_out);
|
||||
|
||||
gboolean
|
||||
(* update_features) (CoglContext *context,
|
||||
|
@ -424,14 +424,13 @@ cogl_gl_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *driver,
|
||||
CoglPixelFormat format = cogl_bitmap_get_format (bitmap);
|
||||
CoglPixelFormat internal_format =
|
||||
cogl_framebuffer_get_internal_format (framebuffer);
|
||||
CoglPixelFormat required_format;
|
||||
GLenum gl_intformat;
|
||||
CoglPixelFormat read_format;
|
||||
GLenum gl_format;
|
||||
GLenum gl_type;
|
||||
GLenum gl_pack_enum = GL_FALSE;
|
||||
int bytes_per_pixel;
|
||||
gboolean is_read_pixels_format_supported;
|
||||
gboolean format_mismatch;
|
||||
gboolean stride_mismatch;
|
||||
gboolean pack_invert_set;
|
||||
int status = FALSE;
|
||||
|
||||
@ -448,12 +447,6 @@ cogl_gl_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *driver,
|
||||
if (!cogl_framebuffer_is_y_flipped (framebuffer))
|
||||
y = framebuffer_height - y - height;
|
||||
|
||||
required_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||
format,
|
||||
&gl_intformat,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
|
||||
(source & COGL_READ_PIXELS_NO_FLIP) == 0 &&
|
||||
!cogl_framebuffer_is_y_flipped (framebuffer))
|
||||
@ -469,39 +462,28 @@ cogl_gl_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *driver,
|
||||
else
|
||||
pack_invert_set = FALSE;
|
||||
|
||||
bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0);
|
||||
is_read_pixels_format_supported =
|
||||
ctx->driver_vtable->read_pixels_format_supported (ctx,
|
||||
gl_intformat,
|
||||
gl_format,
|
||||
gl_type);
|
||||
format_mismatch =
|
||||
(required_format & ~COGL_PREMULT_BIT) !=
|
||||
(format & ~COGL_PREMULT_BIT);
|
||||
read_format = ctx->driver_vtable->get_read_pixels_format (ctx,
|
||||
internal_format,
|
||||
format,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
if (!is_read_pixels_format_supported ||
|
||||
format_mismatch ||
|
||||
(!_cogl_has_private_feature (ctx,
|
||||
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_STRIDE) &&
|
||||
cogl_bitmap_get_rowstride (bitmap) != bytes_per_pixel * width))
|
||||
format_mismatch =
|
||||
(read_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT);
|
||||
|
||||
bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0);
|
||||
stride_mismatch =
|
||||
!_cogl_has_private_feature (ctx,
|
||||
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_STRIDE) &&
|
||||
(cogl_bitmap_get_rowstride (bitmap) != bytes_per_pixel * width);
|
||||
|
||||
if (format_mismatch || stride_mismatch)
|
||||
{
|
||||
CoglBitmap *tmp_bmp;
|
||||
CoglPixelFormat read_format;
|
||||
int bpp, rowstride;
|
||||
uint8_t *tmp_data;
|
||||
gboolean succeeded;
|
||||
|
||||
if (is_read_pixels_format_supported)
|
||||
{
|
||||
read_format = required_format;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (read_format))
|
||||
{
|
||||
read_format = ((read_format & ~COGL_PREMULT_BIT) |
|
||||
|
@ -329,13 +329,18 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
return required_format;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_driver_read_pixels_format_supported (CoglContext *context,
|
||||
GLenum glintformat,
|
||||
GLenum glformat,
|
||||
GLenum gltype)
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_get_read_pixels_format (CoglContext *context,
|
||||
CoglPixelFormat from,
|
||||
CoglPixelFormat to,
|
||||
GLenum *gl_format_out,
|
||||
GLenum *gl_type_out)
|
||||
{
|
||||
return TRUE;
|
||||
return _cogl_driver_pixel_format_to_gl (context,
|
||||
to,
|
||||
NULL,
|
||||
gl_format_out,
|
||||
gl_type_out);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -533,7 +538,7 @@ _cogl_driver_gl =
|
||||
_cogl_driver_gl_is_hardware_accelerated,
|
||||
_cogl_gl_get_graphics_reset_status,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_read_pixels_format_supported,
|
||||
_cogl_driver_get_read_pixels_format,
|
||||
_cogl_driver_update_features,
|
||||
_cogl_driver_gl_create_framebuffer_driver,
|
||||
_cogl_driver_gl_flush_framebuffer_state,
|
||||
|
@ -356,22 +356,109 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
return required_format;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_driver_read_pixels_format_supported (CoglContext *context,
|
||||
GLenum glintformat,
|
||||
GLenum glformat,
|
||||
GLenum gltype)
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_get_read_pixels_format (CoglContext *context,
|
||||
CoglPixelFormat from,
|
||||
CoglPixelFormat to,
|
||||
GLenum *gl_format_out,
|
||||
GLenum *gl_type_out)
|
||||
{
|
||||
if (glformat == GL_RGBA && gltype == GL_UNSIGNED_BYTE)
|
||||
return TRUE;
|
||||
CoglPixelFormat required_format = 0;
|
||||
GLenum required_gl_format = 0;
|
||||
GLenum required_gl_type = 0;
|
||||
CoglPixelFormat to_required_format;
|
||||
GLenum to_gl_format;
|
||||
GLenum to_gl_type;
|
||||
|
||||
if (glintformat == GL_RGB10_A2_EXT &&
|
||||
glformat == GL_RGBA &&
|
||||
gltype == GL_UNSIGNED_INT_2_10_10_10_REV &&
|
||||
cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RGBA1010102))
|
||||
return TRUE;
|
||||
switch (from)
|
||||
{
|
||||
/* fixed point normalized */
|
||||
case COGL_PIXEL_FORMAT_A_8:
|
||||
case COGL_PIXEL_FORMAT_R_8:
|
||||
case COGL_PIXEL_FORMAT_RG_88:
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
case COGL_PIXEL_FORMAT_BGR_888:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRX_8888:
|
||||
case COGL_PIXEL_FORMAT_RGBX_8888:
|
||||
case COGL_PIXEL_FORMAT_XRGB_8888:
|
||||
case COGL_PIXEL_FORMAT_XBGR_8888:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ABGR_8888:
|
||||
case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_RGBA_8888:
|
||||
case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_RGB_565:
|
||||
case COGL_PIXEL_FORMAT_RGBA_4444:
|
||||
case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
|
||||
case COGL_PIXEL_FORMAT_RGBA_5551:
|
||||
case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
|
||||
required_gl_format = GL_RGBA;
|
||||
required_gl_type = GL_UNSIGNED_BYTE;
|
||||
required_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||
break;
|
||||
|
||||
return FALSE;
|
||||
/* fixed point normalized, 10bpc special case */
|
||||
case COGL_PIXEL_FORMAT_ABGR_2101010:
|
||||
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
|
||||
case COGL_PIXEL_FORMAT_RGBA_1010102:
|
||||
case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_1010102:
|
||||
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
|
||||
case COGL_PIXEL_FORMAT_XBGR_2101010:
|
||||
case COGL_PIXEL_FORMAT_XRGB_2101010:
|
||||
case COGL_PIXEL_FORMAT_ARGB_2101010:
|
||||
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
|
||||
required_gl_format = GL_RGBA;
|
||||
required_gl_type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
required_format = COGL_PIXEL_FORMAT_ABGR_2101010;
|
||||
break;
|
||||
|
||||
/* floating point */
|
||||
case COGL_PIXEL_FORMAT_RGBX_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_RGBA_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRX_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_BGRA_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_XRGB_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_ARGB_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_XBGR_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_ABGR_FP_16161616:
|
||||
case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE:
|
||||
case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
case COGL_PIXEL_FORMAT_DEPTH_16:
|
||||
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
|
||||
case COGL_PIXEL_FORMAT_R_16:
|
||||
case COGL_PIXEL_FORMAT_RG_1616:
|
||||
case COGL_PIXEL_FORMAT_ANY:
|
||||
case COGL_PIXEL_FORMAT_YUV:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
g_assert (required_format != 0);
|
||||
|
||||
to_required_format = _cogl_driver_pixel_format_to_gl (context,
|
||||
to,
|
||||
NULL,
|
||||
&to_gl_format,
|
||||
&to_gl_type);
|
||||
|
||||
*gl_format_out = required_gl_format;
|
||||
*gl_type_out = required_gl_type;
|
||||
|
||||
if (to_required_format != to ||
|
||||
to_gl_format != required_gl_format ||
|
||||
to_gl_type != required_gl_type)
|
||||
return required_format;
|
||||
|
||||
return to_required_format;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -594,7 +681,7 @@ _cogl_driver_gles =
|
||||
_cogl_driver_gl_is_hardware_accelerated,
|
||||
_cogl_gl_get_graphics_reset_status,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_read_pixels_format_supported,
|
||||
_cogl_driver_get_read_pixels_format,
|
||||
_cogl_driver_update_features,
|
||||
_cogl_driver_gl_create_framebuffer_driver,
|
||||
_cogl_driver_gl_flush_framebuffer_state,
|
||||
|
@ -94,7 +94,7 @@ _cogl_driver_nop =
|
||||
_cogl_driver_nop_is_hardware_accelerated,
|
||||
NULL, /* get_graphics_reset_status */
|
||||
NULL, /* pixel_format_to_gl */
|
||||
NULL, /* read_pixels_format_supported */
|
||||
NULL, /* _cogl_driver_get_read_pixels_format */
|
||||
_cogl_driver_update_features,
|
||||
_cogl_driver_nop_create_framebuffer_driver,
|
||||
_cogl_driver_nop_flush_framebuffer_state,
|
||||
|
Loading…
Reference in New Issue
Block a user