mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-06 02:40:07 +00:00
fa33af248e
Previously, we were always downloading into CAIRO_FORMAT_ARGB32. Now we check the texture depth and pick a suitable format. This improves rendering for high depth content, but it's slower. That's why we're not yet making sure the depth is suitable for the colorspace conversion. That would force all SRGB textures into float surfaces as we don't consider conversions suitable for U8 in our generic code.
149 lines
4.0 KiB
C
149 lines
4.0 KiB
C
#pragma once
|
|
|
|
#include "gdkcolorstateprivate.h"
|
|
|
|
#include "gdkmemoryformatprivate.h"
|
|
#include "gdkmemorytexture.h"
|
|
|
|
#include <cairo.h>
|
|
#include <graphene.h>
|
|
|
|
static inline cairo_format_t
|
|
gdk_cairo_format_for_depth (GdkMemoryDepth depth)
|
|
{
|
|
switch (depth)
|
|
{
|
|
case GDK_MEMORY_NONE:
|
|
case GDK_MEMORY_U8:
|
|
return CAIRO_FORMAT_ARGB32;
|
|
|
|
case GDK_MEMORY_U8_SRGB:
|
|
case GDK_MEMORY_U16:
|
|
case GDK_MEMORY_FLOAT16:
|
|
case GDK_MEMORY_FLOAT32:
|
|
return CAIRO_FORMAT_RGBA128F;
|
|
|
|
case GDK_N_DEPTHS:
|
|
default:
|
|
g_return_val_if_reached (CAIRO_FORMAT_ARGB32);
|
|
}
|
|
}
|
|
|
|
static inline GdkMemoryDepth
|
|
gdk_cairo_depth_for_format (cairo_format_t format)
|
|
{
|
|
switch (format)
|
|
{
|
|
case CAIRO_FORMAT_ARGB32:
|
|
case CAIRO_FORMAT_RGB24:
|
|
case CAIRO_FORMAT_RGB16_565:
|
|
case CAIRO_FORMAT_A1:
|
|
case CAIRO_FORMAT_A8:
|
|
return GDK_MEMORY_U8;
|
|
|
|
case CAIRO_FORMAT_RGB30:
|
|
return GDK_MEMORY_U16;
|
|
|
|
case CAIRO_FORMAT_RGB96F:
|
|
case CAIRO_FORMAT_RGBA128F:
|
|
return GDK_MEMORY_FLOAT32;
|
|
|
|
case CAIRO_FORMAT_INVALID:
|
|
default:
|
|
g_assert_not_reached ();
|
|
return GDK_MEMORY_NONE;
|
|
}
|
|
}
|
|
|
|
static GdkMemoryFormat
|
|
gdk_cairo_format_to_memory_format (cairo_format_t format)
|
|
{
|
|
switch (format)
|
|
{
|
|
case CAIRO_FORMAT_ARGB32:
|
|
return GDK_MEMORY_DEFAULT;
|
|
|
|
case CAIRO_FORMAT_RGB24:
|
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
return GDK_MEMORY_B8G8R8X8;
|
|
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
|
return GDK_MEMORY_X8R8G8B8;
|
|
#else
|
|
#error "Unknown byte order for Cairo format"
|
|
#endif
|
|
case CAIRO_FORMAT_A8:
|
|
return GDK_MEMORY_A8;
|
|
case CAIRO_FORMAT_RGB96F:
|
|
return GDK_MEMORY_R32G32B32_FLOAT;
|
|
case CAIRO_FORMAT_RGBA128F:
|
|
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
|
|
|
case CAIRO_FORMAT_RGB16_565:
|
|
case CAIRO_FORMAT_RGB30:
|
|
case CAIRO_FORMAT_INVALID:
|
|
case CAIRO_FORMAT_A1:
|
|
default:
|
|
g_assert_not_reached ();
|
|
return GDK_MEMORY_DEFAULT;
|
|
}
|
|
}
|
|
|
|
static inline void
|
|
gdk_cairo_set_source_rgba_ccs (cairo_t *cr,
|
|
GdkColorState *ccs,
|
|
const GdkRGBA *rgba)
|
|
{
|
|
float color[4];
|
|
|
|
gdk_color_state_from_rgba (ccs, rgba, color);
|
|
cairo_set_source_rgba (cr, color[0], color[1], color[2], color[3]);
|
|
}
|
|
|
|
static inline void
|
|
gdk_cairo_pattern_add_color_stop_rgba_ccs (cairo_pattern_t *pattern,
|
|
GdkColorState *ccs,
|
|
double offset,
|
|
const GdkRGBA *rgba)
|
|
{
|
|
float color[4];
|
|
|
|
gdk_color_state_from_rgba (ccs, rgba, color);
|
|
cairo_pattern_add_color_stop_rgba (pattern, offset, color[0], color[1], color[2], color[3]);
|
|
}
|
|
|
|
static inline void
|
|
gdk_cairo_rect (cairo_t *cr,
|
|
const graphene_rect_t *rect)
|
|
{
|
|
cairo_rectangle (cr,
|
|
rect->origin.x, rect->origin.y,
|
|
rect->size.width, rect->size.height);
|
|
}
|
|
|
|
static inline void
|
|
gdk_cairo_surface_convert_color_state (cairo_surface_t *surface,
|
|
GdkColorState *source,
|
|
GdkColorState *target)
|
|
{
|
|
cairo_surface_t *image_surface;
|
|
|
|
if (gdk_color_state_equal (source, target))
|
|
return;
|
|
|
|
image_surface = cairo_surface_map_to_image (surface, NULL);
|
|
|
|
gdk_memory_convert_color_state (cairo_image_surface_get_data (image_surface),
|
|
cairo_image_surface_get_stride (image_surface),
|
|
gdk_cairo_format_to_memory_format (cairo_image_surface_get_format (image_surface)),
|
|
source,
|
|
target,
|
|
cairo_image_surface_get_width (image_surface),
|
|
cairo_image_surface_get_height (image_surface));
|
|
|
|
cairo_surface_mark_dirty (image_surface);
|
|
cairo_surface_unmap_image (surface, image_surface);
|
|
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
|
|
cairo_surface_mark_dirty (surface);
|
|
}
|
|
|