diff --git a/cogl/cogl/cogl-bitmap-conversion.c b/cogl/cogl/cogl-bitmap-conversion.c index 447db00b3..ab8251fc5 100644 --- a/cogl/cogl/cogl-bitmap-conversion.c +++ b/cogl/cogl/cogl-bitmap-conversion.c @@ -351,6 +351,14 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format) case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_FP_16161616: + case COGL_PIXEL_FORMAT_ABGR_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: + case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: + case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: return TRUE; } diff --git a/cogl/cogl/cogl-bitmap-packing.h b/cogl/cogl/cogl-bitmap-packing.h index 1b8e140ff..56d25e92d 100644 --- a/cogl/cogl/cogl-bitmap-packing.h +++ b/cogl/cogl/cogl-bitmap-packing.h @@ -40,13 +40,13 @@ #define UNPACK_2(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ 1) / 3) #define UNPACK_4(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 7) / 15) + 7) / 0xf) #define UNPACK_5(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 15) / 31) + 0xf) / 0x1f) #define UNPACK_6(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 31) / 63) + 0x1f) / 0x3f) #define UNPACK_10(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 511) / 1023) + 0x1ff) / 0x3ff) inline static void G_PASTE (_cogl_unpack_a_8_, component_size) (const uint8_t *src, @@ -207,8 +207,8 @@ G_PASTE (_cogl_unpack_rgb_565_, component_size) (const uint8_t *src, uint16_t v = *(const uint16_t *) src; dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_6 ((v >> 5) & 63); - dst[2] = UNPACK_5 (v & 31); + dst[1] = UNPACK_6 ((v >> 5) & 0x3f); + dst[2] = UNPACK_5 (v & 0x1f); dst[3] = UNPACK_BYTE (255); dst += 4; src += 2; @@ -225,9 +225,9 @@ G_PASTE (_cogl_unpack_rgba_4444_, component_size) (const uint8_t *src, uint16_t v = *(const uint16_t *) src; dst[0] = UNPACK_4 (v >> 12); - dst[1] = UNPACK_4 ((v >> 8) & 15); - dst[2] = UNPACK_4 ((v >> 4) & 15); - dst[3] = UNPACK_4 (v & 15); + dst[1] = UNPACK_4 ((v >> 8) & 0xf); + dst[2] = UNPACK_4 ((v >> 4) & 0xf); + dst[3] = UNPACK_4 (v & 0xf); dst += 4; src += 2; } @@ -243,8 +243,8 @@ G_PASTE (_cogl_unpack_rgba_5551_, component_size) (const uint8_t *src, uint16_t v = *(const uint16_t *) src; dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_5 ((v >> 6) & 31); - dst[2] = UNPACK_5 ((v >> 1) & 31); + dst[1] = UNPACK_5 ((v >> 6) & 0x1f); + dst[2] = UNPACK_5 ((v >> 1) & 0x1f); dst[3] = UNPACK_1 (v & 1); dst += 4; src += 2; @@ -261,8 +261,8 @@ G_PASTE (_cogl_unpack_rgba_1010102_, component_size) (const uint8_t *src, uint32_t v = *(const uint32_t *) src; dst[0] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 1023); - dst[2] = UNPACK_10 ((v >> 2) & 1023); + dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); + dst[2] = UNPACK_10 ((v >> 2) & 0x3ff); dst[3] = UNPACK_2 (v & 3); dst += 4; src += 2; @@ -279,8 +279,8 @@ G_PASTE (_cogl_unpack_bgra_1010102_, component_size) (const uint8_t *src, uint32_t v = *(const uint32_t *) src; dst[2] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 1023); - dst[0] = UNPACK_10 ((v >> 2) & 1023); + dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); + dst[0] = UNPACK_10 ((v >> 2) & 0x3ff); dst[3] = UNPACK_2 (v & 3); dst += 4; src += 2; @@ -297,9 +297,9 @@ G_PASTE (_cogl_unpack_argb_2101010_, component_size) (const uint8_t *src, uint32_t v = *(const uint32_t *) src; dst[3] = UNPACK_2 (v >> 30); - dst[0] = UNPACK_10 ((v >> 20) & 1023); - dst[1] = UNPACK_10 ((v >> 10) & 1023); - dst[2] = UNPACK_10 (v & 1023); + dst[0] = UNPACK_10 ((v >> 20) & 0x3ff); + dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); + dst[2] = UNPACK_10 (v & 0x3ff); dst += 4; src += 2; } @@ -315,14 +315,22 @@ G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (const uint8_t *src, uint32_t v = *(const uint32_t *) src; dst[3] = UNPACK_2 (v >> 30); - dst[2] = UNPACK_10 ((v >> 20) & 1023); - dst[1] = UNPACK_10 ((v >> 10) & 1023); - dst[0] = UNPACK_10 (v & 1023); + dst[2] = UNPACK_10 ((v >> 20) & 0x3ff); + dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); + dst[0] = UNPACK_10 (v & 0x3ff); dst += 4; src += 2; } } +inline static void +G_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (const uint8_t *src, + component_type *dst, + int width) +{ + g_warning ("Not implemented"); +} + #undef UNPACK_1 #undef UNPACK_2 #undef UNPACK_4 @@ -396,6 +404,16 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format, case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (src, dst, width); break; + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_FP_16161616: + case COGL_PIXEL_FORMAT_ABGR_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + 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_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (src, dst, width); + break; case COGL_PIXEL_FORMAT_DEPTH_16: case COGL_PIXEL_FORMAT_DEPTH_32: case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: @@ -414,10 +432,10 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format, #define PACK_1(b) PACK_SIZE (b, 1) #define PACK_2(b) PACK_SIZE (b, 3) -#define PACK_4(b) PACK_SIZE (b, 15) -#define PACK_5(b) PACK_SIZE (b, 31) -#define PACK_6(b) PACK_SIZE (b, 63) -#define PACK_10(b) PACK_SIZE (b, 1023) +#define PACK_4(b) PACK_SIZE (b, 0xf) +#define PACK_5(b) PACK_SIZE (b, 0x1f) +#define PACK_6(b) PACK_SIZE (b, 0x3f) +#define PACK_10(b) PACK_SIZE (b, 0x3ff) inline static void G_PASTE (_cogl_pack_a_8_, component_size) (const component_type *src, @@ -432,6 +450,16 @@ G_PASTE (_cogl_pack_a_8_, component_size) (const component_type *src, } } +inline static void + + +G_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (const component_type *src, + uint8_t *dst, + int width) +{ + g_warning ("Not implemented"); +} + inline static void G_PASTE (_cogl_pack_g_8_, component_size) (const component_type *src, uint8_t *dst, @@ -757,6 +785,16 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format, case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: G_PASTE (_cogl_pack_abgr_2101010_, component_size) (src, dst, width); break; + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_FP_16161616: + case COGL_PIXEL_FORMAT_ABGR_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + 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_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (src, dst, width); + break; case COGL_PIXEL_FORMAT_DEPTH_16: case COGL_PIXEL_FORMAT_DEPTH_32: case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 688c3b37d..067e28eed 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -30,6 +30,7 @@ #include "cogl-config.h" +#include "cogl-muffin.h" #include "cogl-object.h" #include "cogl-private.h" #include "cogl-profile.h" @@ -616,3 +617,10 @@ cogl_get_graphics_reset_status (CoglContext *context) return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; } } + +gboolean +cogl_context_format_supports_upload (CoglContext *ctx, + CoglPixelFormat format) +{ + return ctx->texture_driver->format_supports_upload (ctx, format); +} diff --git a/cogl/cogl/cogl-muffin.h b/cogl/cogl/cogl-muffin.h index f6c9560c0..566f39ba2 100644 --- a/cogl/cogl/cogl-muffin.h +++ b/cogl/cogl/cogl-muffin.h @@ -48,4 +48,8 @@ void cogl_renderer_set_custom_winsys (CoglRenderer *renderer, CoglCustomWinsysVtableGetter winsys_vtable_getter, void *user_data); +COGL_EXPORT +gboolean cogl_context_format_supports_upload (CoglContext *ctx, + CoglPixelFormat format); + #endif /* __COGL_MUFFIN_H___ */ diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c index bfe6e13ad..11df72bf0 100644 --- a/cogl/cogl/cogl-pixel-format.c +++ b/cogl/cogl/cogl-pixel-format.c @@ -245,6 +245,62 @@ static const CoglPixelFormatInfo format_info_table[] = { .aligned = 0, .bpp = { 4 }, }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616, + .format_str = "RGBA_FP_16161616", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616, + .format_str = "BGRA_FP_16161616", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616, + .format_str = "ARGB_FP_16161616", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616, + .format_str = "ABGR_FP_16161616", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE, + .format_str = "RGBA_FP_16161616_PRE", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE, + .format_str = "BGRA_FP_16161616_PRE", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE, + .format_str = "ARGB_FP_16161616_PRE", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE, + .format_str = "ABGR_FP_16161616_PRE", + .n_planes = 1, + .bpp = { 8 }, + .aligned = 1 + }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, .format_str = "DEPTH_16", diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h index e2f898c97..7ef03d3fd 100644 --- a/cogl/cogl/cogl-pixel-format.h +++ b/cogl/cogl/cogl-pixel-format.h @@ -103,7 +103,7 @@ G_BEGIN_DECLS * 7 = YUV: undefined bpp, undefined alignment * 9 = 2 bpp, aligned * 10 = depth, aligned (8, 16, 24, 32, 32f) - * 11 = undefined + * 11 = 8 bpp fp16 * 12 = 3 bpp, not aligned * 13 = 4 bpp, not aligned (e.g. 2101010) * 14-15 = undefined @@ -168,6 +168,14 @@ G_BEGIN_DECLS * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_RGBA_FP_16161616: RGBA half floating point, 64 bit + * @COGL_PIXEL_FORMAT_BGRA_FP_16161616: BGRA half floating point, 64 bit + * @COGL_PIXEL_FORMAT_ARGB_FP_16161616: ARGB half floating point, 64 bit + * @COGL_PIXEL_FORMAT_ABGR_FP_16161616: ABGR half floating point, 64 bit + * @COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: Premultiplied RGBA half floating point, 64 bit + * @COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: Premultiplied BGRA half floating point, 64 bit + * @COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: Premultiplied ARGB half floating point, 64 bit + * @COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: Premultiplied ABGR half floating point, 64 bit * * Pixel formats used by Cogl. For the formats with a byte per * component, the order of the components specify the order in @@ -216,6 +224,11 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT), COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_RGBA_FP_16161616 = (11 | COGL_A_BIT), + COGL_PIXEL_FORMAT_BGRA_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT), + COGL_PIXEL_FORMAT_ARGB_FP_16161616 = (11 | COGL_A_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_ABGR_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT), COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), @@ -228,6 +241,11 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT), COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), + COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT), diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h index 76829d454..66a81f19c 100644 --- a/cogl/cogl/cogl-private.h +++ b/cogl/cogl/cogl-private.h @@ -47,6 +47,8 @@ typedef enum COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT, diff --git a/cogl/cogl/cogl-texture-driver.h b/cogl/cogl/cogl-texture-driver.h index 240635f49..cde1d6e4a 100644 --- a/cogl/cogl/cogl-texture-driver.h +++ b/cogl/cogl/cogl-texture-driver.h @@ -128,6 +128,10 @@ struct _CoglTextureDriver int width, int height); + gboolean + (* format_supports_upload) (CoglContext *ctx, + CoglPixelFormat format); + /* * The driver may impose constraints on what formats can be used to store * texture data read from textures. For example GLES currently only supports diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index bb780cec5..311f98059 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -287,6 +287,31 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context, gltype = GL_UNSIGNED_SHORT_5_5_5_1; break; + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + glintformat = GL_RGBA; + glformat = GL_RGBA; + gltype = GL_HALF_FLOAT; + break; + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: + glintformat = GL_RGBA; + glformat = GL_BGRA; + gltype = GL_HALF_FLOAT; + break; + case COGL_PIXEL_FORMAT_ARGB_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: + glintformat = GL_RGBA; + glformat = GL_BGRA; + gltype = GL_HALF_FLOAT; + break; + case COGL_PIXEL_FORMAT_ABGR_FP_16161616: + case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: + glintformat = GL_RGBA; + glformat = GL_RGBA; + gltype = GL_HALF_FLOAT; + break; + case COGL_PIXEL_FORMAT_DEPTH_16: glintformat = GL_DEPTH_COMPONENT16; glformat = GL_DEPTH_COMPONENT; @@ -507,6 +532,14 @@ _cogl_driver_update_features (CoglContext *ctx, COGL_FEATURE_ID_TEXTURE_RG, TRUE); + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, TRUE); + + if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, + TRUE); + /* Cache features */ for (i = 0; i < G_N_ELEMENTS (private_features); i++) ctx->private_features[i] |= private_features[i]; diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c index 35c10c2d6..841dd7fd3 100644 --- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c @@ -396,6 +396,64 @@ _cogl_texture_driver_size_supported (CoglContext *ctx, return new_width != 0; } +static gboolean +_cogl_texture_driver_upload_supported (CoglContext *ctx, + CoglPixelFormat format) +{ + switch (format) + { + case COGL_PIXEL_FORMAT_A_8: + case COGL_PIXEL_FORMAT_G_8: + case COGL_PIXEL_FORMAT_RG_88: + case COGL_PIXEL_FORMAT_BGRA_8888: + case COGL_PIXEL_FORMAT_BGRA_8888_PRE: + case COGL_PIXEL_FORMAT_RGB_888: + case COGL_PIXEL_FORMAT_BGR_888: + 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_ABGR_2101010: + case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: + case COGL_PIXEL_FORMAT_ARGB_2101010: + case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: + case COGL_PIXEL_FORMAT_RGBA_8888: + case COGL_PIXEL_FORMAT_RGBA_8888_PRE: + 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_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: + return TRUE; + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_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: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + if (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) + return TRUE; + else + return FALSE; + case COGL_PIXEL_FORMAT_DEPTH_16: + case COGL_PIXEL_FORMAT_DEPTH_32: + case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: + case COGL_PIXEL_FORMAT_ANY: + case COGL_PIXEL_FORMAT_YUV: + return TRUE; + } + + g_assert_not_reached (); + return FALSE; +} + static CoglPixelFormat _cogl_texture_driver_find_best_gl_get_data_format (CoglContext *context, @@ -419,5 +477,6 @@ _cogl_texture_driver_gl = _cogl_texture_driver_prep_gl_for_pixels_download, _cogl_texture_driver_gl_get_tex_image, _cogl_texture_driver_size_supported, + _cogl_texture_driver_upload_supported, _cogl_texture_driver_find_best_gl_get_data_format }; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index ca98823e8..1c9bbfc57 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -55,6 +55,12 @@ #ifndef GL_RG8 #define GL_RG8 0x822B #endif +#ifndef GL_UNSIGNED_INT_2_10_10_10_REV_EXT +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif +#ifndef GL_HALF_FLOAT_OES +#define GL_HALF_FLOAT_OES 0x8D61 +#endif static gboolean _cogl_driver_pixel_format_from_gl_internal (CoglContext *context, @@ -137,21 +143,44 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context, required_format = COGL_PIXEL_FORMAT_RGB_888; break; - /* Just one 32-bit ordering supported */ - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - 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_1010102: case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (_cogl_has_private_feature + (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) + { + glintformat = GL_RGBA; + glformat = GL_RGBA; + gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT; + break; + } +#endif case COGL_PIXEL_FORMAT_BGRA_1010102: case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: case COGL_PIXEL_FORMAT_ABGR_2101010: case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: case COGL_PIXEL_FORMAT_ARGB_2101010: case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (_cogl_has_private_feature + (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) + { + glintformat = GL_RGBA; + glformat = GL_RGBA; + gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT; + required_format = COGL_PIXEL_FORMAT_RGBA_1010102; + required_format |= (format & COGL_PREMULT_BIT); + break; + } +#endif + + G_GNUC_FALLTHROUGH; + case COGL_PIXEL_FORMAT_RGBA_8888: + case COGL_PIXEL_FORMAT_RGBA_8888_PRE: + 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: glintformat = GL_RGBA; glformat = GL_RGBA; gltype = GL_UNSIGNED_BYTE; @@ -180,6 +209,26 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context, gltype = GL_UNSIGNED_SHORT_5_5_5_1; break; + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_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_warning ("Unhandled 16 bpc pixel format used"); + + G_GNUC_FALLTHROUGH; + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + if (!_cogl_has_private_feature + (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) + g_warning ("Missing 16 bpc half float extension"); + + glintformat = GL_RGBA; + glformat = GL_RGBA; + gltype = GL_HALF_FLOAT_OES; + break; + case COGL_PIXEL_FORMAT_DEPTH_16: glintformat = GL_DEPTH_COMPONENT; glformat = GL_DEPTH_COMPONENT; @@ -356,6 +405,14 @@ _cogl_driver_update_features (CoglContext *context, COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, TRUE); + if (_cogl_check_extension ("GL_EXT_texture_type_2_10_10_10_REV", gl_extensions)) + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, TRUE); + + if (_cogl_check_extension ("GL_OES_texture_half_float", gl_extensions)) + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, TRUE); + if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions)) COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, TRUE); diff --git a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c index f3cf3831e..08e68cd24 100644 --- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c @@ -439,6 +439,75 @@ _cogl_texture_driver_size_supported (CoglContext *ctx, return width <= max_size && height <= max_size; } +static gboolean +_cogl_texture_driver_upload_supported (CoglContext *ctx, + CoglPixelFormat format) +{ + switch (format) + { + case COGL_PIXEL_FORMAT_A_8: + case COGL_PIXEL_FORMAT_G_8: + case COGL_PIXEL_FORMAT_RG_88: + case COGL_PIXEL_FORMAT_BGRA_8888: + case COGL_PIXEL_FORMAT_BGRA_8888_PRE: + case COGL_PIXEL_FORMAT_RGB_888: + case COGL_PIXEL_FORMAT_BGR_888: + return TRUE; + 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_ABGR_2101010: + case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: + case COGL_PIXEL_FORMAT_ARGB_2101010: + case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) + return TRUE; + else + return FALSE; +#else + return FALSE; +#endif + case COGL_PIXEL_FORMAT_RGBA_8888: + case COGL_PIXEL_FORMAT_RGBA_8888_PRE: + 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_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: + return TRUE; + case COGL_PIXEL_FORMAT_BGRA_FP_16161616: + case COGL_PIXEL_FORMAT_ARGB_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: + return FALSE; + case COGL_PIXEL_FORMAT_RGBA_FP_16161616: + case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: + if (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) + return TRUE; + else + return FALSE; + case COGL_PIXEL_FORMAT_DEPTH_16: + case COGL_PIXEL_FORMAT_DEPTH_32: + case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: + case COGL_PIXEL_FORMAT_ANY: + case COGL_PIXEL_FORMAT_YUV: + return TRUE; + } + + g_assert_not_reached (); + return FALSE; +} + static CoglPixelFormat _cogl_texture_driver_find_best_gl_get_data_format (CoglContext *context, @@ -463,5 +532,6 @@ _cogl_texture_driver_gles = _cogl_texture_driver_prep_gl_for_pixels_download, _cogl_texture_driver_gl_get_tex_image, _cogl_texture_driver_size_supported, + _cogl_texture_driver_upload_supported, _cogl_texture_driver_find_best_gl_get_data_format }; diff --git a/debian/libmuffin0.symbols b/debian/libmuffin0.symbols index 999b34fad..5dd9c363c 100644 --- a/debian/libmuffin0.symbols +++ b/debian/libmuffin0.symbols @@ -1539,6 +1539,7 @@ libmuffin-cogl-0.so.0 libmuffin0 #MINVER# cogl_color_set_red_float@Base 5.3.0 cogl_color_to_hsl@Base 5.3.0 cogl_color_unpremultiply@Base 5.3.0 + cogl_context_format_supports_upload@Base 6.4.1 cogl_context_get_display@Base 5.3.0 cogl_context_get_gtype@Base 5.3.0 cogl_context_get_renderer@Base 5.3.0 diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c index 6236579e7..d38084fbf 100644 --- a/src/wayland/meta-wayland-buffer.c +++ b/src/wayland/meta-wayland-buffer.c @@ -57,6 +57,7 @@ #include "cogl/cogl-egl.h" #include "meta/util.h" #include "wayland/meta-wayland-dma-buf.h" +#include "wayland/meta-wayland-private.h" #ifndef DRM_FORMAT_MOD_INVALID #define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) @@ -181,15 +182,15 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer) return FALSE; } -static void -shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, - CoglPixelFormat *format_out, - CoglTextureComponents *components_out) +static gboolean +shm_format_to_cogl_pixel_format (enum wl_shm_format shm_format, + CoglPixelFormat *format_out, + CoglTextureComponents *components_out) { CoglPixelFormat format; CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA; - switch (wl_shm_buffer_get_format (shm_buffer)) + switch (shm_format) { #if G_BYTE_ORDER == G_BIG_ENDIAN case WL_SHM_FORMAT_ARGB8888: @@ -200,6 +201,10 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, components = COGL_TEXTURE_COMPONENTS_RGB; break; #elif G_BYTE_ORDER == G_LITTLE_ENDIAN + case WL_SHM_FORMAT_RGB565: + format = COGL_PIXEL_FORMAT_RGB_565; + components = COGL_TEXTURE_COMPONENTS_RGB; + break; case WL_SHM_FORMAT_ARGB8888: format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; break; @@ -207,16 +212,69 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, format = COGL_PIXEL_FORMAT_BGRA_8888; components = COGL_TEXTURE_COMPONENTS_RGB; break; + case WL_SHM_FORMAT_XRGB2101010: + components = COGL_TEXTURE_COMPONENTS_RGB; + G_GNUC_FALLTHROUGH; + case WL_SHM_FORMAT_ARGB2101010: + format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE; + break; + case WL_SHM_FORMAT_XBGR2101010: + components = COGL_TEXTURE_COMPONENTS_RGB; + G_GNUC_FALLTHROUGH; + case WL_SHM_FORMAT_ABGR2101010: + format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE; + break; + case WL_SHM_FORMAT_XRGB16161616F: + components = COGL_TEXTURE_COMPONENTS_RGB; + G_GNUC_FALLTHROUGH; + case WL_SHM_FORMAT_ARGB16161616F: + format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE; + break; + case WL_SHM_FORMAT_XBGR16161616F: + components = COGL_TEXTURE_COMPONENTS_RGB; + G_GNUC_FALLTHROUGH; + case WL_SHM_FORMAT_ABGR16161616F: + format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE; + break; #endif default: - g_warn_if_reached (); - format = COGL_PIXEL_FORMAT_ARGB_8888; + return FALSE; } if (format_out) *format_out = format; if (components_out) *components_out = components; + + return TRUE; +} + +static gboolean +shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, + CoglPixelFormat *format_out, + CoglTextureComponents *components_out) +{ + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + CoglPixelFormat cogl_format; + CoglTextureComponents cogl_components; + + if (!shm_format_to_cogl_pixel_format (wl_shm_buffer_get_format (shm_buffer), + &cogl_format, + &cogl_components)) + return FALSE; + + if (!cogl_context_format_supports_upload (cogl_context, cogl_format)) + return FALSE; + + if (format_out) + *format_out = cogl_format; + if (components_out) + *components_out = cogl_components; + + return TRUE; } static gboolean @@ -238,7 +296,12 @@ shm_buffer_attach (MetaWaylandBuffer *buffer, stride = wl_shm_buffer_get_stride (shm_buffer); width = wl_shm_buffer_get_width (shm_buffer); height = wl_shm_buffer_get_height (shm_buffer); - shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components); + if (!shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid shm pixel format"); + return FALSE; + } if (*texture && cogl_texture_get_width (*texture) == width && @@ -617,3 +680,44 @@ meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); } + +void +meta_wayland_init_shm (MetaWaylandCompositor *compositor) +{ + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + + static const enum wl_shm_format shm_formats[] = { + #if G_BYTE_ORDER == G_LITTLE_ENDIAN + WL_SHM_FORMAT_RGB565, + WL_SHM_FORMAT_ARGB2101010, + WL_SHM_FORMAT_XRGB2101010, + WL_SHM_FORMAT_ABGR2101010, + WL_SHM_FORMAT_XBGR2101010, + WL_SHM_FORMAT_ARGB16161616F, + WL_SHM_FORMAT_XRGB16161616F, + WL_SHM_FORMAT_ABGR16161616F, + WL_SHM_FORMAT_XBGR16161616F, + #endif + }; + int i; + + wl_display_init_shm (compositor->wayland_display); + + for (i = 0; i < G_N_ELEMENTS (shm_formats); i++) + { + CoglPixelFormat cogl_format; + + if (!shm_format_to_cogl_pixel_format (shm_formats[i], + &cogl_format, + NULL)) + continue; + + if (!cogl_context_format_supports_upload (cogl_context, cogl_format)) + continue; + + wl_display_add_shm_format (compositor->wayland_display, shm_formats[i]); + } +} diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h index 4a503b183..83607a976 100644 --- a/src/wayland/meta-wayland-buffer.h +++ b/src/wayland/meta-wayland-buffer.h @@ -89,4 +89,6 @@ void meta_wayland_buffer_process_damage (MetaWaylandBuff CoglTexture *texture, cairo_region_t *region); +void meta_wayland_init_shm (MetaWaylandCompositor *compositor); + #endif /* META_WAYLAND_BUFFER_H */ diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c index 206605d27..31ed68a3c 100644 --- a/src/wayland/meta-wayland-dma-buf.c +++ b/src/wayland/meta-wayland-dma-buf.c @@ -113,6 +113,9 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer, case DRM_FORMAT_ARGB8888: cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; break; + case DRM_FORMAT_XRGB2101010: + cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010; + break; case DRM_FORMAT_ABGR8888: cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE; break; @@ -122,6 +125,14 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer, case DRM_FORMAT_RGB565: cogl_format = COGL_PIXEL_FORMAT_RGB_565; break; + case DRM_FORMAT_XBGR16161616F: + case DRM_FORMAT_ABGR16161616F: + cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE; + break; + case DRM_FORMAT_XRGB16161616F: + case DRM_FORMAT_ARGB16161616F: + cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE; + break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -537,7 +548,12 @@ dma_buf_bind (struct wl_client *client, send_modifiers (resource, DRM_FORMAT_XRGB8888); send_modifiers (resource, DRM_FORMAT_XBGR8888); send_modifiers (resource, DRM_FORMAT_ARGB2101010); + send_modifiers (resource, DRM_FORMAT_XRGB2101010); send_modifiers (resource, DRM_FORMAT_RGB565); + send_modifiers (resource, DRM_FORMAT_ABGR16161616F); + send_modifiers (resource, DRM_FORMAT_XBGR16161616F); + send_modifiers (resource, DRM_FORMAT_XRGB16161616F); + send_modifiers (resource, DRM_FORMAT_ARGB16161616F); } /** diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index aeb39ec5d..a86fd3352 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -31,6 +31,7 @@ #include "clutter/clutter.h" #include "clutter/wayland/clutter-wayland-compositor.h" #include "core/main-private.h" +#include "wayland/meta-wayland-buffer.h" #include "wayland/meta-wayland-activation.h" #include "wayland/meta-wayland-data-device.h" #include "wayland/meta-wayland-dma-buf.h" @@ -422,7 +423,7 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *wayland_compositor) compositor, compositor_bind)) g_error ("Failed to register the global wl_compositor"); - wl_display_init_shm (compositor->wayland_display); + meta_wayland_init_shm (compositor); meta_wayland_outputs_init (compositor); meta_wayland_data_device_manager_init (compositor);