Compare commits

..

14 Commits

Author SHA1 Message Date
Matthias Clasen ec271b47fb wip 2024-08-07 19:18:35 -04:00
Matthias Clasen 80bee35ab7 download op: wip 2024-08-07 18:13:34 -04:00
Matthias Clasen 4be4e53bdd memory convert: debug spew 2024-08-07 18:13:34 -04:00
Matthias Clasen d10c55c748 node processor: spew 2024-08-07 18:13:34 -04:00
Matthias Clasen 60d9d79bcc renderer: debug spew 2024-08-07 18:13:33 -04:00
Matthias Clasen d0fbe1db5a download op: debug spew 2024-08-07 18:13:33 -04:00
Matthias Clasen 44aca0cecf Add a test for render_texture 2024-08-07 18:13:33 -04:00
Matthias Clasen f8afc60c9b Some more color tests 2024-08-07 18:11:35 -04:00
Matthias Clasen 2f26bd9842 colorstate: Change the rendering color state api
Pass an extra boolean that tells whether the target image is GL_SRGB,
in which case, the rendering color state must be srgb-linear.

Update all callers to pass FALSE, except for the one call in
the node processor, where we want to take GL_LINEAR into account.
2024-08-07 18:11:35 -04:00
Matthias Clasen 449fc749e6 Add a compare test for handling of pq colors
The node file here has a pq color that is far out of range for
sRGB, and will produce widely different result if we don't clamp
things properly.
2024-08-07 13:34:45 -04:00
Matthias Clasen 56ea1754bf gsk: Pass color state to download op
This lets us create a texture in the desired color state.
2024-08-07 13:34:45 -04:00
Matthias Clasen cd18bb9fd1 renderer: Make hdr textures if necessary
Take the preferred color state of the content into account
when deciding what color state to use for the texture we
generate.
2024-08-07 13:34:45 -04:00
Matthias Clasen 9f3927e7a7 gsk: Adapt to new rendering colorstate api
Since we now handle the GL_SRGB case when the  node processor calls
get_rendering_color_state, we can just pass SRGB as input here.
2024-08-07 13:34:45 -04:00
Matthias Clasen df18749d6d colorstate: Change the rendering color state api
Pass an extra boolean that tells whether the target image is GL_SRGB,
in which case, the rendering color state must be srgb-linear.

Update all callers to pass FALSE, except for the one call in
the node processor, where we want to take GL_LINEAR into account.
2024-08-07 13:34:45 -04:00
166 changed files with 2118 additions and 4563 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v52"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v49"
workflow:
rules:
+1 -4
View File
@@ -1,4 +1,4 @@
FROM fedora:40
FROM fedora:39
RUN dnf -y install \
adwaita-icon-theme \
@@ -99,11 +99,8 @@ RUN dnf -y install \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf -y update \
&& dnf clean all
RUN rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
+1
View File
@@ -11,6 +11,7 @@ multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${setup}" in
x11*)
-31
View File
@@ -1,37 +1,6 @@
Overview of Changes in 4.15.5, xx-xx-xxxx
=========================================
* GtkTextView:
- ADd GtkTextBufferCommitNotify
* CSS:
- Propagate color state information to GSK for many features:
colors, borders, shadows
* Gdk:
- Fix an fd leak in the Vulkan code
- Fix a leak of EGLSurfaces and DMA buffers
- Set the opaque region of surfaces automatically based on their content
* Gsk:
- Fix Emoji rendering in Vulkan
- Rework color handling to take color states into account
- Implement more powerful occlusion culling
* Macos:
- Fix window transparency
* Debugging:
- The inspector shows details about color states now
* Deprecations:
- gdk_draw_context_begin/end_frame
- gdk_surface_set_opaque_region
* Build:
- Require gstreamer 1.24
Overview of Changes in 4.15.4, 30-07-2024
=========================================
-7
View File
@@ -265,13 +265,6 @@ support in the file chooser.
This option controls whether GTK should use colord for color
calibration support in the cups print backend.
## `avif`
This option controls whether GTK will use libavif for loading
textures from AVIF image files. Note that the purpose of this option
is to facilitate development of GTK. The support for this image format
is not guaranteed and may go away at any time.
### `documentation`, `man-pages` and `screenshots`
The *gi-docgen* package is used to generate the reference documentation
+15 -61
View File
@@ -6,7 +6,7 @@ The format is a text format that follows the [CSS syntax rules](https://drafts.c
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
document: <@-rule>*<node>
document: <@-rule>*<node>*
@-rule: @cicp "name" { <property>* }
node: container [ "name" ] { <document> } | <node-type> [ "name" ] { <property>* } | "name"
property: <property-name>: <node> | <value> ;
@@ -49,16 +49,12 @@ The following properties can be set for custom color states:
| primaries | `<integer>` | 2 | always |
| transfer | `<integer>` | 2 | always |
| matrix | `<integer>` | 2 | always |
| range | `<range>` | full | non-default |
| range | `narrow | full` | full | non-default |
Note that the primaries, transfer and matrix properties always need
to be specified, since GTK does not allow creating color state objects
with these being set to 2 (== unspecified).
Range can have the following values:
range: narrow | full
# Colors
Colors can be specified with a variation of the modern CSS color syntax:
@@ -70,16 +66,6 @@ The traditional syntax for sRGB colors still works as well:
rgba(<number>, <number>, <number>, <number)
rgb(<number, <number>, <number>)
# Rectangles
Rectangles can be specified just as four integers for x, y, width and height:
rect: <number> <number> <number> <number>
Rounded rectangles use a CSS-like syntax:
rounded-rect: <rect> [ "/" <number>{1,4} [ "/" <number>{1,4} ] ]
# Nodes
### container
@@ -96,13 +82,6 @@ The **container** node is a special node that allows specifying a list of child
Creates a node like `gsk_blend_node_new()` with the given properties.
Possible values for the mode property are:
blend-mode: normal | multiply | screen | overlay | darken |
lighten | color-dodge | color-burn | hard-light |
soft-light | difference | exclusion | color |
hue | saturation | luminosity
### blur
| property | syntax | default | printed |
@@ -222,10 +201,6 @@ Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is the default color node, but created with the
bounds of the path.
Possible values for the fill-rule property are:
fill-rule: winding | even-odd
### glshader
| property | syntax | default | printed |
@@ -277,10 +252,6 @@ Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
Creates a node like `gsk_mask_node_new()` with the given properties.
Possible values for the mode property are:
mask-mode: alpha | inverted-alpha | luminance | inverted-luminance
### opacity
| property | syntax | default | printed |
@@ -319,11 +290,11 @@ Creates a node like `gsk_radial_gradient_node_new()` with the given properties.
### repeat
| property | syntax | default | printed |
| ------------ | ---------- | ---------------------- | ----------- |
| bounds | `<rect>` | *bounds of child node* | non-default |
| child | `<node>` | color { } | always |
| child-bounds | `<rect>` | *bounds of child node* | non-default |
| property | syntax | default | printed |
| ----------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | *bounds of child node* | non-default |
| child | `<node>` | color { } | always |
| child-bounds| `<rect>` | *bounds of child node* | non-default |
Creates a node like `gsk_repeat_node_new()` with the given properties.
@@ -390,14 +361,6 @@ Creates a node like `gsk_stroke_node_new()` with the given properties.
The default child node is the default color node, but created with the
stroke bounds of the path.
Possible values for the line-cap property are:
line-cap: butt | round | square
Possible values for the line-join property are:
line-join: miter | round | bevel
### text
| property | syntax | default | printed |
@@ -406,9 +369,9 @@ Possible values for the line-join property are:
| font | `<string>` `<url>`? | "Cantarell 15px" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| hint-style | `<hint-style>` | slight | non-default |
| hint-style | `<hint style>` | slight | non-default |
| antialias | `<antialias>` | gray | non-default |
| hint-metrics | `<hint-metrics>` | off | non-default |
| hint-metrics | `<hint metrics>` | off | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.
@@ -423,17 +386,9 @@ be specified as well, like this: 40 10 0 0 color.
If the given font does not exist or the given glyphs are invalid for the given
font, an error node will be returned.
Possible values for the hint-style property are:
hint-style: none | slight | full
Possible value for the antialias property are:
antialias: none | gray
Possible value for hint-metrics are:
hint-metrics: on | off
Possible values for hint-style are none, slight or full.
Possible value for antialias are none or gray.
Possible value for hint-metrics are on or off.
### texture
@@ -459,15 +414,14 @@ representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANS
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| texture | `<url>` | *see below* | always |
| filter | `filter` | linear | non-default |
| filter | `filter` | *see below* | non-default |
Creates a node like `gsk_texture_scale_node_new()` with the given properties.
The default texture is a 10x10 checkerboard, just like for texture.
Possible values for the filter property are:
filter: linear | nearest | trilinear
The possible filter values are `linear`, `nearest` and `trilinear`, with
`linear` being the default.
### transform
-2
View File
@@ -82,10 +82,8 @@ gdk_cairo_context_cairo_create (GdkCairoContext *self)
draw_context = GDK_DRAW_CONTEXT (self);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
if (!gdk_draw_context_is_in_frame (draw_context))
return NULL;
G_GNUC_END_IGNORE_DEPRECATIONS
cr = GDK_CAIRO_CONTEXT_GET_CLASS (self)->cairo_create (self);
-3
View File
@@ -208,10 +208,7 @@ gdk_cicp_params_class_init (GdkCicpParamsClass *klass)
* Supported values:
*
* - 0: RGB
* - 1: BT.709
* - 2: unspecified
* - 5,6: BT.601
* - 9: BT.2020
*
* Since: 4.16
*/
-36
View File
@@ -222,39 +222,3 @@ static const float srgb_to_rec2020[9] = {
0.069108, 0.919519, 0.011360,
0.016394, 0.088011, 0.895380,
};
static const float rgb_to_bt601[9] = {
0.299000, 0.587000, 0.114000,
-0.168736, -0.331264, 0.500000,
0.500000, -0.418688, -0.081312,
};
static const float bt601_to_rgb[9] = {
1.000000, 0.000000, 1.402000,
1.000000, -0.344136, -0.714136,
1.000000, 1.772000, 0.000000,
};
static const float rgb_to_bt709[9] = {
0.212600, 0.715200, 0.072200,
-0.114572, -0.385428, 0.500000,
0.500000, -0.454153, -0.045847,
};
static const float bt709_to_rgb[9] = {
1.000000, 0.000000, 1.574800,
1.000000, -0.187324, -0.468124,
1.000000, 1.855600, -0.000000,
};
static const float rgb_to_bt2020[9] = {
0.262700, 0.678000, 0.059300,
-0.139630, -0.360370, 0.500000,
0.500000, -0.459786, -0.040214,
};
static const float bt2020_to_rgb[9] = {
1.000000, -0.000000, 1.474600,
1.000000, -0.164553, -0.571353,
1.000000, 1.881400, -0.000000,
};
+22 -198
View File
@@ -18,7 +18,6 @@
#include "config.h"
#define GDK_COLOR_STATE_IMPL
#include "gdkcolorstateprivate.h"
#include <math.h>
@@ -412,7 +411,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
},
};
/* }}} */
/* }}} */
/* {{{ Cicp implementation */
typedef struct _GdkCicpColorState GdkCicpColorState;
@@ -432,128 +431,25 @@ struct _GdkCicpColorState
float *from_srgb;
float *from_rec2020;
const float *from_yuv;
const float *to_yuv;
GdkCicp cicp;
};
/* {{{ Conversion functions */
#define TRANSFORM_FROM_CICP(name, matrix, oetf) \
static void \
name (GdkColorState *color_state, \
float (*values)[4], \
gsize n_values) \
{ \
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
\
for (gsize i = 0; i < n_values; i++) \
{ \
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
{ \
values[i][0] = CLAMP ((values[i][0] - 16.0/255.0) * 255.0 / 219.0, -10, 10); \
values[i][1] = CLAMP ((values[i][1] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
values[i][2] = CLAMP ((values[i][2] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
} \
if (self->from_yuv) \
{ \
float res[3]; \
values[i][1] -= 0.5; \
values[i][2] -= 0.5; \
res[0] = self->from_yuv[0] * values[i][0] + self->from_yuv[1] * values[i][1] + self->from_yuv[2] * values[i][2]; \
res[1] = self->from_yuv[3] * values[i][0] + self->from_yuv[4] * values[i][1] + self->from_yuv[5] * values[i][2]; \
res[2] = self->from_yuv[6] * values[i][0] + self->from_yuv[7] * values[i][1] + self->from_yuv[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (self->eotf != NONE) \
{ \
values[i][0] = self->eotf (values[i][0]); \
values[i][1] = self->eotf (values[i][1]); \
values[i][2] = self->eotf (values[i][2]); \
} \
if (self->matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (oetf != NONE) \
{ \
values[i][0] = oetf (values[i][0]); \
values[i][1] = oetf (values[i][1]); \
values[i][2] = oetf (values[i][2]); \
} \
} \
}
#define cicp ((GdkCicpColorState *)self)
#define TRANSFORM_TO_CICP(name, eotf, matrix) \
static void \
name (GdkColorState *color_state, \
float (*values)[4], \
gsize n_values) \
{ \
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
\
for (gsize i = 0; i < n_values; i++) \
{ \
if (eotf != NONE) \
{ \
values[i][0] = eotf (values[i][0]); \
values[i][1] = eotf (values[i][1]); \
values[i][2] = eotf (values[i][2]); \
} \
if (self->matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (self->oetf != NONE) \
{ \
values[i][0] = self->oetf (values[i][0]); \
values[i][1] = self->oetf (values[i][1]); \
values[i][2] = self->oetf (values[i][2]); \
} \
if (self->to_yuv) \
{ \
float res[3]; \
res[0] = self->to_yuv[0] * values[i][0] + self->to_yuv[1] * values[i][1] + self->to_yuv[2] * values[i][2]; \
res[1] = self->to_yuv[3] * values[i][0] + self->to_yuv[4] * values[i][1] + self->to_yuv[5] * values[i][2]; \
res[2] = self->to_yuv[6] * values[i][0] + self->to_yuv[7] * values[i][1] + self->to_yuv[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1] + 0.5; \
values[i][2] = res[2] + 0.5; \
} \
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
{ \
values[i][0] = values[i][0] * 219.0 / 255.0 + 16.0 / 255.0; \
values[i][1] = values[i][1] * 224.0 / 255.0 + 16.0 / 255.0; \
values[i][2] = values[i][2] * 224.0 / 255.0 + 16.0 / 255.0; \
} \
} \
}
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb, to_srgb, srgb_oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb_linear, to_srgb, NONE)
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_pq, to_rec2020, pq_oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_linear, to_rec2020, NONE)
TRANSFORM_TO_CICP(gdk_cicp_from_srgb, srgb_eotf, from_srgb)
TRANSFORM_TO_CICP(gdk_cicp_from_srgb_linear, NONE, from_srgb)
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_pq, pq_eotf, from_rec2020)
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_linear, NONE, from_rec2020)
#undef cicp
/* }}} */
/* }}} */
/* {{{ Vfuncs */
@@ -659,7 +555,7 @@ gdk_cicp_color_state_get_cicp (GdkColorState *color_state)
return &self->cicp;
}
/* }}} */
/* }}} */
static const
GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
@@ -672,46 +568,6 @@ GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
.get_cicp = gdk_cicp_color_state_get_cicp,
};
GdkCicpColorState gdk_color_state_bt601_narrow = {
.parent = {
.klass = &GDK_CICP_COLOR_STATE_CLASS,
.ref_count = 1,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "cicp-1/13/6/0",
.no_srgb = NULL,
.cicp = { 1, 13, 6, 0 },
.eotf = srgb_eotf,
.oetf = srgb_oetf,
.to_yuv = rgb_to_bt601,
.from_yuv = bt601_to_rgb,
.to_srgb = IDENTITY,
.to_rec2020 = (float *) srgb_to_rec2020,
.from_srgb = IDENTITY,
.from_rec2020 = (float *) rec2020_to_srgb,
};
GdkCicpColorState gdk_color_state_bt601_full = {
.parent = {
.klass = &GDK_CICP_COLOR_STATE_CLASS,
.ref_count = 1,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "cicp-1/13/6/1",
.no_srgb = NULL,
.cicp = { 1, 13, 6, 1 },
.eotf = srgb_eotf,
.oetf = srgb_oetf,
.to_yuv = rgb_to_bt601,
.from_yuv = bt601_to_rgb,
.to_srgb = IDENTITY,
.to_rec2020 = (float *) srgb_to_rec2020,
.from_srgb = IDENTITY,
.from_rec2020 = (float *) rec2020_to_srgb,
};
static inline float *
multiply (float res[9],
const float m1[9],
@@ -736,8 +592,14 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
GdkTransferFunc oetf;
gconstpointer to_xyz;
gconstpointer from_xyz;
gconstpointer to_yuv = NULL;
gconstpointer from_yuv = NULL;
if (cicp->range == GDK_CICP_RANGE_NARROW || cicp->matrix_coefficients != 0)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Narrow range or YUV not supported"));
return NULL;
}
if (cicp->color_primaries == 2 ||
cicp->transfer_function == 2 ||
@@ -751,16 +613,10 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
for (guint i = 0; i < GDK_COLOR_STATE_N_IDS; i++)
{
if (gdk_cicp_equal (cicp, &gdk_default_color_states[i].cicp))
if (gdk_cicp_equivalent (cicp, &gdk_default_color_states[i].cicp))
return (GdkColorState *) &gdk_default_color_states[i];
}
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_narrow.cicp))
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_narrow);
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_full.cicp))
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_full);
switch (cicp->transfer_function)
{
case 1:
@@ -813,7 +669,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
from_xyz = xyz_to_pal;
break;
case 6:
case 7:
to_xyz = ntsc_to_xyz;
from_xyz = xyz_to_ntsc;
break;
@@ -833,34 +688,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
return NULL;
}
switch (cicp->matrix_coefficients)
{
case 0:
to_yuv = IDENTITY;
from_yuv = IDENTITY;
break;
case 1:
to_yuv = rgb_to_bt709;
from_yuv = bt709_to_rgb;
break;
case 5:
case 6:
to_yuv = rgb_to_bt601;
from_yuv = bt601_to_rgb;
break;
case 9:
to_yuv = rgb_to_bt2020;
from_yuv = bt2020_to_rgb;
break;
default:
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Matrix coefficients %u, %s not supported"),
cicp->matrix_coefficients,
cicp->range == GDK_CICP_RANGE_NARROW ? "narrow" : "full");
return NULL;
}
self = g_new0 (GdkCicpColorState, 1);
self->parent.klass = &GDK_CICP_COLOR_STATE_CLASS;
@@ -873,9 +700,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
memcpy (&self->cicp, cicp, sizeof (GdkCicp));
self->to_yuv = to_yuv;
self->from_yuv = from_yuv;
self->eotf = eotf;
self->oetf = oetf;
+8 -8
View File
@@ -78,8 +78,15 @@ GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp
GError **error);
static inline GdkColorState *
gdk_color_state_get_rendering_color_state (GdkColorState *self)
gdk_color_state_get_rendering_color_state (GdkColorState *self,
gboolean srgb)
{
if (srgb)
{
self = gdk_color_state_get_no_srgb_tf (self);
g_assert (self);
}
if (GDK_DEBUG_CHECK (HDR))
self = GDK_COLOR_STATE_REC2100_PQ;
@@ -211,10 +218,3 @@ gdk_color_state_from_rgba (GdkColorState *self,
out_color);
}
#ifndef GDK_COLOR_STATE_IMPL
extern GdkColorState gdk_color_state_bt601_narrow;
extern GdkColorState gdk_color_state_bt601_full;
#endif
#define GDK_COLOR_STATE_YUV ((GdkColorState *) &gdk_color_state_bt601_narrow)
#define GDK_COLOR_STATE_JPEG ((GdkColorState *) &gdk_color_state_bt601_full)
+1 -1
View File
@@ -1477,7 +1477,7 @@ gdk_display_create_gl_context (GdkDisplay *self,
if (!gdk_display_prepare_gl (self, error))
return NULL;
return gdk_gl_context_new (self, NULL, FALSE);
return gdk_gl_context_new (self, NULL);
}
/*< private >
+102 -57
View File
@@ -24,7 +24,6 @@
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkcolorstate.h"
#ifdef HAVE_DMABUF
#include <sys/mman.h>
@@ -72,7 +71,7 @@ download_memcpy (guchar *dst_data,
bpp = gdk_memory_format_bytes_per_pixel (dst_format);
src_stride = dmabuf->planes[0].stride;
src_data = src_datas[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + gdk_memory_format_min_buffer_size (dst_format, src_stride, width, height));
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + gdk_memory_format_min_buffer_size (dst_format, dst_stride, width, height));
if (dst_stride == src_stride)
memcpy (dst_data, src_data, (height - 1) * dst_stride + width * bpp);
@@ -134,6 +133,49 @@ download_memcpy_3_1 (guchar *dst_data,
}
}
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static void
download_nv12 (guchar *dst_data,
gsize dst_stride,
@@ -184,21 +226,14 @@ download_nv12 (guchar *dst_data,
{
for (x = 0; x < width; x += X_SUB)
{
int u_, v_;
int r, g, b;
gsize xs, ys;
u_ = uv_data[x / X_SUB * 2 + U];
v_ = uv_data[x / X_SUB * 2 + V];
get_uv_values (&itu601_narrow, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint8 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
rgb[0] = y_data[x + xs + y_stride * ys];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
@@ -206,6 +241,35 @@ download_nv12 (guchar *dst_data,
}
}
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static void
download_p010 (guchar *dst,
gsize dst_stride,
@@ -220,7 +284,7 @@ download_p010 (guchar *dst,
guint16 *dst_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
guint16 SIZE;
guint16 SIZE, MASK;
switch (dmabuf->fourcc)
{
@@ -240,6 +304,7 @@ download_p010 (guchar *dst,
g_assert_not_reached ();
return;
}
MASK = 0xFFFF << (16 - SIZE);
y_stride = dmabuf->planes[0].stride / 2;
y_data = (const guint16 *) (src_data[0] + dmabuf->planes[0].offset);
@@ -254,24 +319,22 @@ download_p010 (guchar *dst,
{
for (x = 0; x < width; x += X_SUB)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u_, v_;
guint16 u, v;
u_ = uv_data[x / X_SUB * 2 + U];
u_ = u_ | (u_ >> SIZE);
v_ = uv_data[x / X_SUB * 2 + V];
v_ = v_ | (v_ >> SIZE);
u = uv_data[x / X_SUB * 2 + U];
u = (u & MASK) | (u >> SIZE);
v = uv_data[x / X_SUB * 2 + V];
v = (v & MASK) | (v >> SIZE);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint16 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = y_ | (y_ >> SIZE);
rgb[0] = y_;
rgb[1] = u_;
rgb[2] = v_;
y_ = (y_ & MASK) | (y_ >> SIZE);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += Y_SUB * dst_stride;
@@ -345,21 +408,14 @@ download_yuv_3 (guchar *dst_data,
{
for (x = 0; x < width; x += X_SUB)
{
int u_, v_;
int r, g, b;
gsize xs, ys;
u_ = u_data[x / X_SUB];
v_ = v_data[x / X_SUB];
get_uv_values (&itu601_narrow, u_data[x / X_SUB], v_data[x / X_SUB], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint8 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
rgb[0] = y_data[x + xs + y_stride * ys];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
@@ -409,23 +465,12 @@ download_yuyv (guchar *dst_data,
{
for (x = 0; x < width; x += 2)
{
guint8 *rgb;
int u_, v_;
int r, g, b;
u_ = src_data[2 * x + U];
v_ = src_data[2 * x + V];
rgb = &dst_data[3 * x];
rgb[0] = src_data[2 * x + Y1];
rgb[1] = u_;
rgb[2] = v_;
get_uv_values (&itu601_narrow, src_data[2 * x + U], src_data[2 * x + V], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + Y1], r, g, b);
if (x + 1 < width)
{
rgb = &dst_data[3 * (x + 1)];
rgb[0] = src_data[2 * x + Y2];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + Y2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
@@ -2094,14 +2139,14 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
needs_unmap[i] = TRUE;
}
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
out:
for (i = 0; i < dmabuf->n_planes; i++)
+4 -76
View File
@@ -209,15 +209,12 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
int target)
{
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLint attribs[64];
int i;
EGLImage image;
gboolean is_yuv;
g_return_val_if_fail (width > 0, 0);
g_return_val_if_fail (height > 0, 0);
@@ -231,25 +228,6 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
return EGL_NO_IMAGE;
}
if (gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv) && is_yuv)
{
if (color_space_hint == 0 || range_hint == 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import yuv dmabuf into GL without color space hints");
return EGL_NO_IMAGE;
}
}
else
{
if (color_space_hint != 0 || range_hint != 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import non-yuv dmabuf into GL with color space hints");
return EGL_NO_IMAGE;
}
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
@@ -263,16 +241,10 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
attribs[i++] = height;
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[i++] = dmabuf->fourcc;
if (color_space_hint != 0)
{
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
attribs[i++] = color_space_hint;
}
if (range_hint != 0)
{
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
attribs[i++] = range_hint;
}
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
attribs[i++] = EGL_ITU_REC601_EXT;
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
attribs[i++] = EGL_YUV_NARROW_RANGE_EXT;
#define ADD_PLANE(plane) \
{ \
@@ -317,48 +289,4 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
return image;
}
void
gdk_dmabuf_get_egl_yuv_hints (const GdkDmabuf *dmabuf,
GdkColorState *color_state,
int *color_space_hint,
int *range_hint)
{
gboolean is_yuv;
const GdkCicp *cicp;
cicp = gdk_color_state_get_cicp (color_state);
if (cicp &&
gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv) && is_yuv)
{
if (cicp->range == GDK_CICP_RANGE_NARROW)
*range_hint = EGL_YUV_NARROW_RANGE_EXT;
else
*range_hint = EGL_YUV_FULL_RANGE_EXT;
switch (cicp->matrix_coefficients)
{
case 1:
*color_space_hint = EGL_ITU_REC709_EXT;
break;
case 5:
case 6:
*color_space_hint = EGL_ITU_REC601_EXT;
break;
case 9:
*color_space_hint = EGL_ITU_REC2020_EXT;
break;
default:
*color_space_hint = 0;
*range_hint = 0;
break;
}
}
else
{
*color_space_hint = 0;
*range_hint = 0;
}
}
#endif /* HAVE_DMABUF && HAVE_EGL */
-7
View File
@@ -13,13 +13,6 @@ EGLImage gdk_dmabuf_egl_create_image (GdkDisplay
int width,
int height,
const GdkDmabuf *dmabuf,
int color_state_hint,
int range_hint,
int target);
void gdk_dmabuf_get_egl_yuv_hints (const GdkDmabuf *dmabuf,
GdkColorState *color_state,
int *color_space_hint,
int *range_hint);
#endif /* HAVE_DMABUF && HAVE_EGL */
-4
View File
@@ -5,10 +5,6 @@
#include <drm_fourcc.h>
#endif
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
#ifndef fourcc_code
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
+5 -2
View File
@@ -208,9 +208,12 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
gboolean is_yuv;
if (gdk_dmabuf_fourcc_is_yuv (dmabuf.fourcc, &is_yuv) && is_yuv)
color_state = GDK_COLOR_STATE_YUV;
{
g_warning_once ("FIXME: Implement the proper colorstate for YUV dmabufs");
color_state = gdk_color_state_get_srgb ();
}
else
color_state = GDK_COLOR_STATE_SRGB;
color_state = gdk_color_state_get_srgb ();
}
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
+14 -44
View File
@@ -223,9 +223,6 @@ gdk_draw_context_init (GdkDrawContext *self)
*
* Returns: %TRUE if the context is between [method@Gdk.DrawContext.begin_frame]
* and [method@Gdk.DrawContext.end_frame] calls.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
gboolean
gdk_draw_context_is_in_frame (GdkDrawContext *context)
@@ -316,9 +313,6 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
* gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
* use of [GskRenderer](../gsk4/class.Renderer.html)s, so application code
* does not need to call these functions explicitly.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
void
gdk_draw_context_begin_frame (GdkDrawContext *context,
@@ -330,12 +324,11 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
g_return_if_fail (priv->surface != NULL);
g_return_if_fail (region != NULL);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region, NULL);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region);
}
/*
* @depth: best depth to render in
* @opaque: (nullable): opaque region of the rendering
*
* If the given depth is not `GDK_MEMORY_U8`, GDK will see about providing a
* rendering target that supports a higher bit depth than 8 bits per channel.
@@ -358,10 +351,9 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
* to choose.
*/
void
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
@@ -386,8 +378,6 @@ gdk_draw_context_begin_frame_full (GdkDrawContext *context,
return;
}
gdk_surface_set_opaque_rect (priv->surface, opaque);
if (gdk_display_get_debug_flags (priv->display) & GDK_DEBUG_HIGH_DEPTH)
depth = GDK_MEMORY_FLOAT32;
@@ -430,21 +420,6 @@ region_get_pixels (cairo_region_t *region)
}
#endif
void
gdk_draw_context_end_frame_full (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
g_clear_pointer (&priv->color_state, gdk_color_state_unref);
g_clear_pointer (&priv->frame_region, cairo_region_destroy);
g_clear_object (&priv->surface->paint_context);
priv->depth = GDK_N_DEPTHS;
}
/**
* gdk_draw_context_end_frame:
* @context: a `GdkDrawContext`
@@ -457,9 +432,6 @@ gdk_draw_context_end_frame_full (GdkDrawContext *context)
* When using a [class@Gdk.GLContext], this function may call `glFlush()`
* implicitly before returning; it is not recommended to call `glFlush()`
* explicitly before calling this function.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
void
gdk_draw_context_end_frame (GdkDrawContext *context)
@@ -487,7 +459,14 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
return;
}
gdk_draw_context_end_frame_full (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
g_clear_pointer (&priv->color_state, gdk_color_state_unref);
g_clear_pointer (&priv->frame_region, cairo_region_destroy);
g_clear_object (&priv->surface->paint_context);
priv->depth = GDK_N_DEPTHS;
}
/**
@@ -504,24 +483,15 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
* and [method@Gdk.DrawContext.end_frame], %NULL will be returned.
*
* Returns: (transfer none) (nullable): a Cairo region
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
const cairo_region_t *
_gdk_draw_context_get_frame_region (GdkDrawContext *context)
gdk_draw_context_get_frame_region (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
return priv->frame_region;
}
const cairo_region_t *
(gdk_draw_context_get_frame_region) (GdkDrawContext *context)
{
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
return _gdk_draw_context_get_frame_region (context);
return priv->frame_region;
}
/*<private>
+4 -4
View File
@@ -40,15 +40,15 @@ GdkDisplay * gdk_draw_context_get_display (GdkDrawContext
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_draw_context_get_surface (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
void gdk_draw_context_begin_frame (GdkDrawContext *context,
const cairo_region_t *region);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
void gdk_draw_context_end_frame (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
gboolean gdk_draw_context_is_in_frame (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
const cairo_region_t * gdk_draw_context_get_frame_region (GdkDrawContext *context);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawContext, g_object_unref)
+1 -7
View File
@@ -25,8 +25,6 @@
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include <graphene.h>
G_BEGIN_DECLS
#define GDK_DRAW_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAW_CONTEXT, GdkDrawContextClass))
@@ -59,14 +57,10 @@ void gdk_draw_context_surface_resized (GdkDrawContext
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque);
void gdk_draw_context_end_frame_full (GdkDrawContext *context);
const cairo_region_t *region);
void gdk_draw_context_empty_frame (GdkDrawContext *context);
#define gdk_draw_context_get_frame_region(...) _gdk_draw_context_get_frame_region(__VA_ARGS__)
const cairo_region_t * _gdk_draw_context_get_frame_region (GdkDrawContext *self);
GdkColorState * gdk_draw_context_get_color_state (GdkDrawContext *self);
GdkMemoryDepth gdk_draw_context_get_depth (GdkDrawContext *self);
+8 -42
View File
@@ -122,7 +122,6 @@ struct _GdkGLContextPrivate
GdkGLMemoryFlags memory_flags[GDK_MEMORY_N_FORMATS];
GdkGLFeatures features;
guint surface_attached : 1;
guint use_khr_debug : 1;
guint has_debug_output : 1;
guint extensions_checked : 1;
@@ -638,10 +637,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
else
*out_depth = GDK_MEMORY_U8;
if (*out_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_color_state = color_state;
#else
*out_color_state = gdk_color_state_get_srgb ();
*out_depth = GDK_MEMORY_U8;
@@ -830,28 +826,20 @@ gdk_gl_context_init (GdkGLContext *self)
/* Must have called gdk_display_prepare_gl() before */
GdkGLContext *
gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface,
gboolean surface_attached)
GdkSurface *surface)
{
GdkGLContextPrivate *priv;
GdkGLContext *shared, *result;
GdkGLContext *shared;
g_assert (surface == NULL || display == gdk_surface_get_display (surface));
g_assert (!surface_attached || surface != NULL);
/* assert gdk_display_prepare_gl() had been called */
shared = gdk_display_get_gl_context (display);
g_assert (shared);
result = g_object_new (G_OBJECT_TYPE (shared),
"display", display,
"surface", surface,
NULL);
priv = gdk_gl_context_get_instance_private (result);
priv->surface_attached = surface_attached;
return result;
return g_object_new (G_OBJECT_TYPE (shared),
"display", display,
"surface", surface,
NULL);
}
void
@@ -1834,22 +1822,12 @@ gdk_gl_context_check_is_current (GdkGLContext *context)
void
gdk_gl_context_make_current (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
MaskedContext *current, *masked_context;
gboolean surfaceless;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (priv->surface_attached)
{
surfaceless = FALSE;
}
else
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
G_GNUC_END_IGNORE_DEPRECATIONS
}
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
masked_context = mask_context (context, surfaceless);
current = g_private_get (&thread_current_context);
@@ -2198,8 +2176,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
int target)
{
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
@@ -2211,8 +2187,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
width,
height,
dmabuf,
color_space_hint,
range_hint,
target);
if (image == EGL_NO_IMAGE)
return 0;
@@ -2236,8 +2210,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
gboolean *external)
{
GdkDisplay *display = gdk_gl_context_get_display (self);
@@ -2254,8 +2226,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
color_space_hint,
range_hint,
GL_TEXTURE_2D);
if (texture_id == 0)
{
@@ -2285,8 +2255,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
color_space_hint,
range_hint,
GL_TEXTURE_EXTERNAL_OES);
if (texture_id == 0)
{
@@ -2319,8 +2287,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
color_space_hint,
range_hint,
target);
if (texture_id == 0)
+2 -5
View File
@@ -122,9 +122,8 @@ void gdk_gl_backend_use (GdkGLBackend
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface,
gboolean surface_attached);
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
@@ -185,8 +184,6 @@ guint gdk_gl_context_import_dmabuf (GdkGLContext
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
gboolean *external);
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
+14
View File
@@ -1879,6 +1879,12 @@ gdk_memory_convert (guchar *dest_data,
g_assert (dest_data + gdk_memory_format_min_buffer_size (dest_format, dest_stride, width, height) <= src_data ||
src_data + gdk_memory_format_min_buffer_size (src_format, src_stride, width, height) <= dest_data);
g_print ("memory convert %s %s -> %s %s\n",
gdk_memory_format_get_name (src_format),
gdk_color_state_get_name (src_cs),
gdk_memory_format_get_name (dest_format),
gdk_color_state_get_name (dest_cs));
if (src_format == dest_format && gdk_color_state_equal (dest_cs, src_cs))
{
gsize bytes_per_row = src_desc->bytes_per_pixel * width;
@@ -1952,6 +1958,7 @@ gdk_memory_convert (guchar *dest_data,
if (func != NULL)
{
g_print ("convert format\n");
for (y = 0; y < height; y++)
{
func (dest_data, src_data, width);
@@ -1974,10 +1981,13 @@ gdk_memory_convert (guchar *dest_data,
needs_premultiply = src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT;
}
g_print ("convert color %lu %lu\n", width, height);
for (y = 0; y < height; y++)
{
src_desc->to_float (tmp, src_data, width);
g_print ("after to_float: %f %f %f %f\n", tmp[0][0], tmp[0][1], tmp[0][2], tmp[0][3]);
if (needs_unpremultiply)
unpremultiply (tmp, width);
@@ -2159,6 +2169,10 @@ gdk_memory_convert_color_state (guchar *data,
if (gdk_color_state_equal (src_cs, dest_cs))
return;
g_print ("memory convert color state %s -> %s\n",
gdk_color_state_get_name (src_cs),
gdk_color_state_get_name (dest_cs));
if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB &&
dest_cs == GDK_COLOR_STATE_SRGB_LINEAR)
-10
View File
@@ -52,16 +52,6 @@ gdk_rectangle_transform_affine (const GdkRectangle *src,
dest->height = ceilf (MAX (y1, y2)) - dest->y;
}
static inline gboolean
gdk_rectangle_contains (const GdkRectangle *rect,
const GdkRectangle *contained)
{
return contained->x >= rect->x
&& contained->y >= rect->y
&& contained->x + contained->width <= rect->x + rect->width
&& contained->y + contained->height <= rect->y + rect->height;
}
G_END_DECLS
+11 -102
View File
@@ -40,13 +40,11 @@
#include <glib/gi18n-lib.h>
#include "gdkmarshalers.h"
#include "gdkpopupprivate.h"
#include "gdkrectangleprivate.h"
#include "gdkrectangle.h"
#include "gdktoplevelprivate.h"
#include "gdkvulkancontext.h"
#include "gdksubsurfaceprivate.h"
#include "gsk/gskrectprivate.h"
#include <math.h>
#ifdef HAVE_EGL
@@ -77,9 +75,6 @@ struct _GdkSurfacePrivate
GdkMemoryDepth egl_surface_depth;
#endif
cairo_region_t *opaque_region;
cairo_rectangle_int_t opaque_rect; /* This is different from the region */
gpointer widget;
GdkColorState *color_state;
@@ -515,12 +510,6 @@ gdk_surface_real_create_subsurface (GdkSurface *surface)
return NULL;
}
static void
gdk_surface_default_set_opaque_region (GdkSurface *surface,
cairo_region_t *region)
{
}
static void
gdk_surface_constructed (GObject *object)
{
@@ -544,7 +533,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
klass->beep = gdk_surface_real_beep;
klass->get_scale = gdk_surface_real_get_scale;
klass->create_subsurface = gdk_surface_real_create_subsurface;
klass->set_opaque_region = gdk_surface_default_set_opaque_region;
/**
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
@@ -783,7 +771,7 @@ gdk_surface_finalize (GObject *object)
g_clear_object (&surface->display);
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
g_clear_pointer (&surface->opaque_region, cairo_region_destroy);
if (surface->parent)
surface->parent->children = g_list_remove (surface->parent->children, surface);
@@ -1146,12 +1134,11 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
{
GdkDisplay *display = gdk_surface_get_display (self);
gdk_gl_context_clear_current_if_surface (self);
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
priv->egl_surface = NULL;
}
gdk_gl_context_clear_current_if_surface (self);
priv->egl_native_window = native_window;
}
@@ -1269,7 +1256,7 @@ gdk_surface_create_gl_context (GdkSurface *surface,
if (!gdk_display_prepare_gl (surface->display, error))
return NULL;
return gdk_gl_context_new (surface->display, surface, FALSE);
return gdk_gl_context_new (surface->display, surface);
}
/**
@@ -2646,35 +2633,6 @@ gdk_surface_get_scale (GdkSurface *surface)
return GDK_SURFACE_GET_CLASS (surface)->get_scale (surface);
}
static void
gdk_surface_update_opaque_region (GdkSurface *self)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
cairo_region_t *region;
if (priv->opaque_region == NULL)
{
if (priv->opaque_rect.width <= 0)
region = NULL;
else
region = cairo_region_create_rectangle (&priv->opaque_rect);
}
else
{
if (priv->opaque_rect.width <= 0)
region = cairo_region_reference (priv->opaque_region);
else
{
region = cairo_region_copy (priv->opaque_region);
cairo_region_union_rectangle (region, &priv->opaque_rect);
}
}
GDK_SURFACE_GET_CLASS (self)->set_opaque_region (self, region);
g_clear_pointer (&region, cairo_region_destroy);
}
/**
* gdk_surface_set_opaque_region:
* @surface: a top-level `GdkSurface`
@@ -2696,76 +2654,27 @@ gdk_surface_update_opaque_region (GdkSurface *self)
* is opaque, as we know where the opaque regions are. If your surface
* background is not opaque, please update this property in your
* [GtkWidgetClass.css_changed](../gtk4/vfunc.Widget.css_changed.html) handler.
*
* Deprecated: 4.16: GDK can figure out the opaque parts of a window itself
* by inspecting the contents that are drawn.
*/
void
gdk_surface_set_opaque_region (GdkSurface *surface,
cairo_region_t *region)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
GdkSurfaceClass *class;
g_return_if_fail (GDK_IS_SURFACE (surface));
g_return_if_fail (!GDK_SURFACE_DESTROYED (surface));
if (cairo_region_equal (priv->opaque_region, region))
if (cairo_region_equal (surface->opaque_region, region))
return;
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
g_clear_pointer (&surface->opaque_region, cairo_region_destroy);
if (region != NULL)
priv->opaque_region = cairo_region_reference (region);
surface->opaque_region = cairo_region_reference (region);
gdk_surface_update_opaque_region (surface);
}
/* Sets the opaque rect from the rendernode via end_frame() */
void
gdk_surface_set_opaque_rect (GdkSurface *self,
const graphene_rect_t *rect)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
cairo_rectangle_int_t opaque;
if (rect)
gsk_rect_to_cairo_shrink (rect, &opaque);
else
opaque = (cairo_rectangle_int_t) { 0, 0, 0, 0 };
if (gdk_rectangle_equal (&priv->opaque_rect, &opaque))
return;
priv->opaque_rect = opaque;
gdk_surface_update_opaque_region (self);
}
/*
* gdk_surface_is_opaque:
* @self: a surface
*
* Checks if the whole surface is known to be opaque.
* This allows using an RGBx buffer instead of RGBA.
*
* This function works for the currently rendered frame inside
* begin_frame() implementations.
*
* Returns: %TRUE if the whole surface is provably opaque
**/
gboolean
gdk_surface_is_opaque (GdkSurface *self)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
cairo_rectangle_int_t whole = { 0, 0, self->width, self->height };
if (gdk_rectangle_contains (&priv->opaque_rect, &whole))
return TRUE;
if (cairo_region_contains_rectangle (priv->opaque_region, &whole) == CAIRO_REGION_OVERLAP_IN)
return TRUE;
return FALSE;
class = GDK_SURFACE_GET_CLASS (surface);
if (class->set_opaque_region)
class->set_opaque_region (surface, region);
}
void
+1 -1
View File
@@ -125,7 +125,7 @@ void gdk_surface_request_layout (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_opaque_region (GdkSurface *surface,
cairo_region_t *region);
+10 -11
View File
@@ -96,6 +96,8 @@ struct _GdkSurface
GSList *draw_contexts;
GdkDrawContext *paint_context;
cairo_region_t *opaque_region;
GdkSeat *current_shortcuts_inhibited_seat;
GPtrArray *subsurfaces;
@@ -251,17 +253,14 @@ gdk_gravity_flip_vertically (GdkGravity anchor)
g_assert_not_reached ();
}
void _gdk_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy);
void gdk_surface_invalidate_rect (GdkSurface *surface,
const GdkRectangle *rect);
void gdk_surface_invalidate_region (GdkSurface *surface,
const cairo_region_t *region);
void _gdk_surface_clear_update_area (GdkSurface *surface);
void _gdk_surface_update_size (GdkSurface *surface);
void gdk_surface_set_opaque_rect (GdkSurface *self,
const graphene_rect_t *rect);
gboolean gdk_surface_is_opaque (GdkSurface *self);
void _gdk_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy);
void gdk_surface_invalidate_rect (GdkSurface *surface,
const GdkRectangle *rect);
void gdk_surface_invalidate_region (GdkSurface *surface,
const cairo_region_t *region);
void _gdk_surface_clear_update_area (GdkSurface *surface);
void _gdk_surface_update_size (GdkSurface *surface);
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
GError **error);
-2
View File
@@ -983,8 +983,6 @@ gdk_texture_download_surface (GdkTexture *texture,
* %CAIRO_FORMAT_ARGB32, so every downloaded pixel requires
* 4 bytes of memory.
*
* The downloaded data is converted to the sRGB color state.
*
* Downloading a texture into a Cairo image surface:
* ```c
* surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+3 -4
View File
@@ -678,10 +678,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_union (region, priv->regions[priv->draw_index]);
if (priv->current_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_color_state = color_state;
*out_depth = priv->current_depth;
}
@@ -1348,6 +1345,7 @@ gdk_vulkan_context_get_draw_index (GdkVulkanContext *context)
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), 0);
g_return_val_if_fail (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)), 0);
return priv->draw_index;
}
@@ -1371,6 +1369,7 @@ gdk_vulkan_context_set_draw_semaphore (GdkVulkanContext *context,
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
g_return_if_fail (GDK_IS_VULKAN_CONTEXT (context));
g_return_if_fail (!gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)));
g_return_if_fail (priv->draw_semaphore == VK_NULL_HANDLE);
priv->draw_semaphore = semaphore;
+1 -1
View File
@@ -65,7 +65,7 @@ gdk_vulkan_handle_result (VkResult res,
{
if (res != VK_SUCCESS)
{
g_warning ("%s(): %s (%d)", called_function, gdk_vulkan_strerror (res), res);
GDK_DEBUG (VULKAN, "%s(): %s (%d)", called_function, gdk_vulkan_strerror (res), res);
}
return res;
-865
View File
@@ -1,865 +0,0 @@
#include "config.h"
#include "gdkavifprivate.h"
#include "gdkmemorytexturebuilder.h"
#include "gdktexture.h"
#include "gdkdisplay.h"
#include "gdkcicpparamsprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkdmabuftexture.h"
#include "gdktexturedownloader.h"
#include <avif/avif.h>
#ifdef HAVE_DMABUF
#include "gdkdmabuftextureprivate.h"
#include "gdkdmabuftexturebuilder.h"
#include "gdkdmabuffourccprivate.h"
/* NOTE: We build this code outside of libgtk, in tests and the image tool, so this
* code has to be a bit careful to avoid depending on private api, which can also
* be dragged in indirectly, via inlines.
*/
#ifdef AVIF_DEBUG
#define DEBUG(fmt,...) g_log ("avif", G_LOG_LEVEL_DEBUG, fmt __VA_OPT__(,) __VA_ARGS__)
#else
#define DEBUG(fmt,...)
#endif
/* {{{ udmabuf support */
#include <inttypes.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/udmabuf.h>
#include <drm_fourcc.h>
#include <errno.h>
#include <gio/gio.h>
static int udmabuf_fd;
static gboolean
udmabuf_initialize (GError **error)
{
if (udmabuf_fd == 0)
{
udmabuf_fd = open ("/dev/udmabuf", O_RDWR);
if (udmabuf_fd == -1)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to open /dev/udmabuf: %s",
g_strerror (errno));
}
}
return udmabuf_fd != -1;
}
typedef struct
{
int mem_fd;
int dmabuf_fd;
size_t size;
gpointer data;
} UDmabuf;
static void
udmabuf_free (gpointer data)
{
UDmabuf *udmabuf = data;
munmap (udmabuf->data, udmabuf->size);
close (udmabuf->mem_fd);
close (udmabuf->dmabuf_fd);
g_free (udmabuf);
}
#define align(x,y) (((x) + (y) - 1) & ~((y) - 1))
static UDmabuf *
udmabuf_allocate (size_t size,
GError **error)
{
int mem_fd = -1;
int dmabuf_fd = -1;
uint64_t alignment;
int res;
gpointer data;
UDmabuf *udmabuf;
if (udmabuf_fd == -1)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"udmabuf not available");
goto fail;
}
alignment = sysconf (_SC_PAGE_SIZE);
size = align (size, alignment);
mem_fd = memfd_create ("gtk", MFD_ALLOW_SEALING);
if (mem_fd == -1)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to open /dev/udmabuf: %s",
g_strerror (errno));
goto fail;
}
res = ftruncate (mem_fd, size);
if (res == -1)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"ftruncate failed: %s",
g_strerror (errno));
goto fail;
}
if (fcntl (mem_fd, F_ADD_SEALS, F_SEAL_SHRINK) < 0)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"ftruncate failed: %s",
g_strerror (errno));
goto fail;
}
dmabuf_fd = ioctl (udmabuf_fd,
UDMABUF_CREATE,
&(struct udmabuf_create) {
.memfd = mem_fd,
.flags = UDMABUF_FLAGS_CLOEXEC,
.offset = 0,
.size = size
});
if (dmabuf_fd < 0)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"UDMABUF_CREATE ioctl failed: %s",
g_strerror (errno));
goto fail;
}
data = mmap (NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, 0);
if (!data)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"mmap failed: %s",
g_strerror (errno));
goto fail;
}
udmabuf = g_new0 (UDmabuf, 1);
udmabuf->mem_fd = mem_fd;
udmabuf->dmabuf_fd = dmabuf_fd;
udmabuf->size = size;
udmabuf->data = data;
return udmabuf;
fail:
if (mem_fd != -1)
close (mem_fd);
if (dmabuf_fd != -1)
close (dmabuf_fd);
return NULL;
}
/* }}} */
/* {{{ dmabuf texture support */
static GdkTexture *
gdk_avif_create_dmabuf_texture (avifDecoder *decoder,
GdkColorState *color_state,
GError **error)
{
guint fourcc = 0;
guint32 width, height, depth;
GdkDmabufTextureBuilder *builder;
UDmabuf *udmabuf;
gboolean combine_uv = FALSE;
guchar *data;
gsize size0, size1, size2;
GdkTexture *texture;
if (!udmabuf_initialize (error))
return NULL;
width = decoder->image->width;
height = decoder->image->height;
depth = decoder->image->depth;
if (decoder->image->alphaPlane)
{
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
"no yuv dmabuf with alpha");
return NULL;
}
switch (decoder->image->yuvFormat)
{
case AVIF_PIXEL_FORMAT_YUV444:
DEBUG ("load: format yuv444");
if (depth == 8)
fourcc = DRM_FORMAT_YUV444;
break;
case AVIF_PIXEL_FORMAT_YUV422:
DEBUG ("load: format yuv422");
if (depth == 8)
fourcc = DRM_FORMAT_YUV422;
break;
case AVIF_PIXEL_FORMAT_YUV420:
DEBUG ("load: format yuv420");
combine_uv = TRUE;
if (depth == 8)
fourcc = DRM_FORMAT_NV12;
else if (depth == 10)
fourcc = DRM_FORMAT_P010;
else if (depth == 12)
fourcc = DRM_FORMAT_P012;
else if (depth == 16)
fourcc = DRM_FORMAT_P016;
break;
case AVIF_PIXEL_FORMAT_YUV400:
case AVIF_PIXEL_FORMAT_NONE:
case AVIF_PIXEL_FORMAT_COUNT:
default:
break;
}
if (fourcc == 0)
{
const char *names[] = { "none", "yuv444", "yuv422", "yuv420", "yuv400" };
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
"unsupported pixel format %s, depth %u",
names[decoder->image->yuvFormat], decoder->image->depth);
return NULL;
}
DEBUG ("load: use fourcc %.4s", (char *)&fourcc);
builder = gdk_dmabuf_texture_builder_new ();
gdk_dmabuf_texture_builder_set_display (builder, gdk_display_get_default ());
gdk_dmabuf_texture_builder_set_width (builder, width);
gdk_dmabuf_texture_builder_set_height (builder, height);
gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
gdk_dmabuf_texture_builder_set_fourcc (builder, fourcc);
gdk_dmabuf_texture_builder_set_modifier (builder, DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_texture_builder_set_premultiplied (builder, FALSE);
if (combine_uv)
{
size0 = height * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y);
size1 = height / 2 * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y);
udmabuf = udmabuf_allocate (size0 + size1, NULL);
data = (guchar *) udmabuf->data;
if (depth == 8)
{
memcpy (data, avifImagePlane (decoder->image, AVIF_CHAN_Y), size0);
for (int i = 0; i < height / 2; i++)
{
guchar *usrc = avifImagePlane (decoder->image, AVIF_CHAN_U) + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U);
guchar *vsrc = avifImagePlane (decoder->image, AVIF_CHAN_V) + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V);
guchar *dest = data + size0 + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y);
for (int j = 0; j < width / 2; j++)
{
dest[2*j] = usrc[j];
dest[2*j+1] = vsrc[j];
}
}
}
else
{
for (int i = 0; i < height; i++)
{
guint16 *src = (guint16 *) (avifImagePlane (decoder->image, AVIF_CHAN_Y) + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
guint16 *dest = (guint16 *) (data + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
for (int j = 0; j < width; j++)
dest[j] = src[j] << (16 - depth);
}
for (int i = 0; i < height / 2; i++)
{
guint16 *usrc = (guint16 *)(avifImagePlane (decoder->image, AVIF_CHAN_U) + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U));
guint16 *vsrc = (guint16 *)(avifImagePlane (decoder->image, AVIF_CHAN_V) + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V));
guint16 *dest = (guint16 *)(data + size0 + i * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
for (int j = 0; j < width / 2; j++)
{
dest[2*j] = usrc[j] << (16 - depth);
dest[2*j+1] = vsrc[j] << (16 - depth);
}
}
}
gdk_dmabuf_texture_builder_set_n_planes (builder, 2);
gdk_dmabuf_texture_builder_set_fd (builder, 0, udmabuf->dmabuf_fd);
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
gdk_dmabuf_texture_builder_set_stride (builder, 0, avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
gdk_dmabuf_texture_builder_set_fd (builder, 1, udmabuf->dmabuf_fd);
gdk_dmabuf_texture_builder_set_offset (builder, 1, size0);
gdk_dmabuf_texture_builder_set_stride (builder, 1, avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
}
else
{
size0 = height * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y);
size1 = height * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U);
size2 = height * avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V);
udmabuf = udmabuf_allocate (size0 + size1 + size2, NULL);
data = (guchar *) udmabuf->data;
memcpy (data, avifImagePlane (decoder->image, AVIF_CHAN_Y), size0);
memcpy (data + size0, avifImagePlane (decoder->image, AVIF_CHAN_U), size1);
memcpy (data + size0 + size1, avifImagePlane (decoder->image, AVIF_CHAN_V), size2);
gdk_dmabuf_texture_builder_set_n_planes (builder, 3);
gdk_dmabuf_texture_builder_set_fd (builder, 0, udmabuf->dmabuf_fd);
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
gdk_dmabuf_texture_builder_set_stride (builder, 0, avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y));
gdk_dmabuf_texture_builder_set_fd (builder, 1, udmabuf->dmabuf_fd);
gdk_dmabuf_texture_builder_set_offset (builder, 1, size0);
gdk_dmabuf_texture_builder_set_stride (builder, 1, avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U));
gdk_dmabuf_texture_builder_set_fd (builder, 2, udmabuf->dmabuf_fd);
gdk_dmabuf_texture_builder_set_offset (builder, 2, size0 + size1);
gdk_dmabuf_texture_builder_set_stride (builder, 2, avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V));
}
texture = gdk_dmabuf_texture_builder_build (builder, udmabuf_free, udmabuf, error);
g_object_unref (builder);
return texture;
}
#endif /* HAVE_DMABUF */
/* }}} */
/* {{{ memory texture support */
static GdkTexture *
gdk_avif_create_memory_texture (avifDecoder *decoder,
GdkColorState *color_state,
GError **error)
{
guint32 width, height, depth, stride, bpp;
GdkTexture *texture;
GdkMemoryTextureBuilder *builder;
guchar *data;
GBytes *bytes;
GdkMemoryFormat format = GDK_MEMORY_N_FORMATS;
int X_SUB, Y_SUB;
width = decoder->image->width;
height = decoder->image->height;
depth = decoder->image->depth;
switch (decoder->image->yuvFormat)
{
case AVIF_PIXEL_FORMAT_YUV444:
X_SUB = 1; Y_SUB = 1;
if (depth == 8)
{
format = GDK_MEMORY_R8G8B8A8;
bpp = 4;
}
else
{
format = GDK_MEMORY_R16G16B16A16;
bpp = 8;
}
break;
case AVIF_PIXEL_FORMAT_YUV422:
X_SUB = 2; Y_SUB = 1;
if (depth == 8)
{
format = GDK_MEMORY_R8G8B8A8;
bpp = 8;
}
else
{
format = GDK_MEMORY_R16G16B16A16;
bpp = 8;
}
break;
case AVIF_PIXEL_FORMAT_YUV420:
X_SUB = 2; Y_SUB = 2;
break;
case AVIF_PIXEL_FORMAT_YUV400:
case AVIF_PIXEL_FORMAT_NONE:
case AVIF_PIXEL_FORMAT_COUNT:
if (depth == 8)
{
format = GDK_MEMORY_R8G8B8A8;
bpp = 4;
}
else
{
format = GDK_MEMORY_R16G16B16A16;
bpp = 8;
}
default:
break;
}
if (format == GDK_MEMORY_N_FORMATS)
{
const char *names[] = { "none", "yuv444", "yuv422", "yuv420", "yuv400" };
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
"unsupported pixel format for YUVA %s, depth %u",
names[decoder->image->yuvFormat], depth);
return NULL;
}
stride = width * bpp;
data = g_malloc (stride * height);
if (depth == 8)
{
guchar *y_data = avifImagePlane (decoder->image, AVIF_CHAN_Y);
guchar *u_data = avifImagePlane (decoder->image, AVIF_CHAN_U);
guchar *v_data = avifImagePlane (decoder->image, AVIF_CHAN_V);
guchar *a_data = avifImagePlane (decoder->image, AVIF_CHAN_A);
guchar *dst_data = data;
gsize y_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y);
gsize u_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U);
gsize v_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V);
gsize a_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_A);
gsize dst_stride = stride;
for (int y = 0; y < height; y += Y_SUB)
{
for (int x = 0; x < width; x += X_SUB)
{
guint y_, u_, v_, a_;
u_ = u_data[x / X_SUB];
v_ = v_data[x / X_SUB];
for (int ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (int xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guchar *dest = &dst_data[4 * (x + xs) + dst_stride * ys];
y_ = y_data[x + xs + y_stride * ys];
a_ = a_data ? a_data[x + xs + a_stride * ys] : 0xff;
dest[0] = y_;
dest[1] = u_;
dest[2] = v_;
dest[3] = a_;
}
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
u_data += u_stride;
v_data += v_stride;
if (a_data)
a_data += a_stride;
}
}
else
{
guint16 *y_data = (guint16 *) avifImagePlane (decoder->image, AVIF_CHAN_Y);
guint16 *u_data = (guint16 *) avifImagePlane (decoder->image, AVIF_CHAN_U);
guint16 *v_data = (guint16 *) avifImagePlane (decoder->image, AVIF_CHAN_V);
guint16 *a_data = (guint16 *) avifImagePlane (decoder->image, AVIF_CHAN_A);
guint16 *dst_data = (guint16 *) data;
gsize y_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_Y) / 2;
gsize u_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_U) / 2;
gsize v_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_V) / 2;
gsize a_stride = avifImagePlaneRowBytes (decoder->image, AVIF_CHAN_A) / 2;
gsize dst_stride = stride / 2;
for (int y = 0; y < height; y += Y_SUB)
{
for (int x = 0; x < width; x += X_SUB)
{
guint y_, u_, v_, a_;
u_ = u_data[x / X_SUB] << (16 - depth);
v_ = v_data[x / X_SUB] << (16 - depth);
for (int ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (int xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint16 *dest = &dst_data[4 * (x + xs) + dst_stride * ys];
y_ = y_data[x + xs + y_stride * ys] << (16 - depth);
a_ = (a_data ? a_data[x + xs + a_stride * ys] : 0xffff) << (16 - depth);
dest[0] = y_ | (y_ >> depth);
dest[1] = u_ | (u_ >> depth);
dest[2] = v_ | (v_ >> depth);
dest[3] = a_ | (a_ >> depth);
}
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
u_data += u_stride;
v_data += v_stride;
}
}
builder = gdk_memory_texture_builder_new ();
bytes = g_bytes_new_take (data, stride * height);
gdk_memory_texture_builder_set_width (builder, width);
gdk_memory_texture_builder_set_height (builder, height);
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_format (builder, format);
gdk_memory_texture_builder_set_color_state (builder, color_state);
texture = gdk_memory_texture_builder_build (builder);
g_bytes_unref (bytes);
g_object_unref (builder);
return texture;
}
/* }}} */
/* {{{ Public API */
GdkTexture *
gdk_load_avif (GBytes *bytes,
GError **error)
{
avifDecoder *decoder;
avifResult result;
GdkCicpParams *params;
GdkColorState *color_state = NULL;
GdkTexture *texture = NULL;
GError *local_error = NULL;
decoder = avifDecoderCreate ();
result = avifDecoderSetIOMemory (decoder,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
if (result != AVIF_RESULT_OK)
{
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
"avifDecoderSetIOFile failed: %u", result);
goto fail;
}
result = avifDecoderParse (decoder);
if (result != AVIF_RESULT_OK)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"avifDecoderParse failed: %u", result);
goto fail;
}
result = avifDecoderNextImage (decoder);
if (result != AVIF_RESULT_OK)
{
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
"avifDecoderNextImage failed: %u", result);
goto fail;
}
DEBUG ("load: depth %u", decoder->image->depth);
DEBUG ("load: cicp %u/%u/%u/%u",
decoder->image->colorPrimaries,
decoder->image->transferCharacteristics,
decoder->image->matrixCoefficients,
decoder->image->yuvRange);
params = gdk_cicp_params_new ();
gdk_cicp_params_set_color_primaries (params, decoder->image->colorPrimaries);
gdk_cicp_params_set_transfer_function (params, decoder->image->transferCharacteristics);
gdk_cicp_params_set_matrix_coefficients (params, decoder->image->matrixCoefficients);
gdk_cicp_params_set_range (params, decoder->image->yuvRange == AVIF_RANGE_LIMITED
? GDK_CICP_RANGE_NARROW
: GDK_CICP_RANGE_FULL);
color_state = gdk_cicp_params_build_color_state (params, error);
g_object_unref (params);
if (!color_state)
goto fail;
#ifdef HAVE_DMABUF
texture = gdk_avif_create_dmabuf_texture (decoder, color_state, &local_error);
if (!texture)
{
DEBUG ("load: creating dmabuf failed: %s", local_error->message);
g_clear_error (&local_error);
}
#endif
if (!texture)
texture = gdk_avif_create_memory_texture (decoder, color_state, error);
(gdk_color_state_unref) (color_state);
fail:
avifDecoderDestroy (decoder);
return texture;
}
static int
bytes_per_channel (GdkMemoryFormat format)
{
switch (format)
{
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_G8:
case GDK_MEMORY_A8:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
return 1;
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_G16:
case GDK_MEMORY_A16:
case GDK_MEMORY_A16_FLOAT:
return 2;
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT:
case GDK_MEMORY_A32_FLOAT:
return 4;
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();
}
}
GBytes *
gdk_save_avif (GdkTexture *texture)
{
uint32_t width, height, depth;
GdkColorState *color_state;
const GdkCicp *cicp;
avifEncoder *encoder;
avifImage *image = NULL;
avifRWData output = AVIF_DATA_EMPTY;
GdkTextureDownloader *downloader;
GBytes *bytes = NULL;
gsize stride;
GBytes *out_bytes = NULL;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
if (bytes_per_channel (gdk_texture_get_format (texture)) == 1)
depth = 8;
else
depth = 12;
color_state = gdk_texture_get_color_state (texture);
cicp = gdk_color_state_get_cicp (color_state);
DEBUG ("save: depth %u", depth);
DEBUG ("save: cicp %u/%u/%u/%u",
cicp->color_primaries,
cicp->transfer_function,
cicp->matrix_coefficients,
cicp->range);
downloader = gdk_texture_downloader_new (texture);
if (depth == 8)
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R8G8B8A8);
else
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R16G16B16A16);
gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (texture));
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
gdk_texture_downloader_free (downloader);
if (cicp->matrix_coefficients != 0)
{
/* some form of yuv */
image = avifImageCreate (width, height, depth, AVIF_PIXEL_FORMAT_YUV444);
image->colorPrimaries = cicp->color_primaries;
image->transferCharacteristics = cicp->transfer_function;
image->matrixCoefficients = cicp->matrix_coefficients;
image->yuvRange = cicp->range == GDK_CICP_RANGE_NARROW
? AVIF_RANGE_LIMITED
: AVIF_RANGE_FULL;
avifImageAllocatePlanes (image, AVIF_PLANES_YUV);
if (depth == 8)
{
for (gsize y = 0; y < height; y++)
{
const guchar *orig = (guchar *) g_bytes_get_data (bytes, NULL) + y * stride;
guchar *y_ = avifImagePlane (image, AVIF_CHAN_Y) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_Y);
guchar *u_ = avifImagePlane (image, AVIF_CHAN_U) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_U);
guchar *v_ = avifImagePlane (image, AVIF_CHAN_V) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_V);
for (gsize x = 0; x < width; x++)
{
y_[x] = orig[4*x + 0];
u_[x] = orig[4*x + 1];
v_[x] = orig[4*x + 2];
}
}
}
else
{
for (gsize y = 0; y < height; y++)
{
const guint16 *orig = (guint16 *) ((guchar *) g_bytes_get_data (bytes, NULL) + y * stride);
guint16 *y_ = (guint16 *) (avifImagePlane (image, AVIF_CHAN_Y) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_Y));
guint16 *u_ = (guint16 *) (avifImagePlane (image, AVIF_CHAN_U) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_U));
guint16 *v_ = (guint16 *) (avifImagePlane (image, AVIF_CHAN_V) + y * avifImagePlaneRowBytes (image, AVIF_CHAN_V));
for (gsize x = 0; x < width; x++)
{
y_[x] = orig[4*x + 0] >> (16 - depth);
u_[x] = orig[4*x + 1] >> (16 - depth);
v_[x] = orig[4*x + 2] >> (16 - depth);
}
}
}
}
else
{
avifRGBImage rgb;
image = avifImageCreate (width, height, depth, AVIF_PIXEL_FORMAT_YUV444);
image->colorPrimaries = cicp->color_primaries;
image->transferCharacteristics = cicp->transfer_function;
image->matrixCoefficients = cicp->matrix_coefficients;
image->yuvRange = cicp->range == GDK_CICP_RANGE_NARROW
? AVIF_RANGE_LIMITED
: AVIF_RANGE_FULL;
avifRGBImageSetDefaults (&rgb, image);
avifRGBImageAllocatePixels (&rgb);
if (depth == 8)
{
for (gsize y = 0; y < height; y++)
{
const guchar *orig = (guchar *) g_bytes_get_data (bytes, NULL) + y * stride;
guchar *pixels = rgb.pixels + y * rgb.rowBytes;
for (gsize x = 0; x < width; x++)
{
pixels[4*x + 0] = orig[4*x + 0];
pixels[4*x + 1] = orig[4*x + 1];
pixels[4*x + 2] = orig[4*x + 2];
pixels[4*x + 3] = orig[4*x + 3];
}
}
}
else
{
for (gsize y = 0; y < height; y++)
{
const guint16 *orig = (const guint16 *) ((guchar *) g_bytes_get_data (bytes, NULL) + y * stride);
guint16 *pixels = (guint16 *) (rgb.pixels + y * rgb.rowBytes);
for (gsize x = 0; x < width; x++)
{
pixels[4*x + 0] = orig[4*x + 0] >> (16 - depth);
pixels[4*x + 1] = orig[4*x + 1] >> (16 - depth);
pixels[4*x + 2] = orig[4*x + 2] >> (16 - depth);
pixels[4*x + 3] = orig[4*x + 3] >> (16 - depth);
}
}
}
avifImageRGBToYUV(image, &rgb);
avifRGBImageFreePixels (&rgb);
}
DEBUG ("save: cicp in image %u/%u/%u/%u",
image->colorPrimaries,
image->transferCharacteristics,
image->matrixCoefficients,
image->yuvRange);
encoder = avifEncoderCreate ();
if (avifEncoderWrite (encoder, image, &output) != AVIF_RESULT_OK)
goto fail;
out_bytes = g_bytes_new_take (output.data, output.size);
fail:
g_clear_pointer (&bytes, g_bytes_unref);
avifEncoderDestroy (encoder);
if (image)
avifImageDestroy (image);
return out_bytes;
}
gboolean
gdk_is_avif (GBytes *bytes)
{
avifROData input;
input.data = g_bytes_get_data (bytes, &input.size);
return avifPeekCompatibleFileType (&input);
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */
-28
View File
@@ -1,28 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2024 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gdk.h>
#include <gio/gio.h>
GdkTexture *gdk_load_avif (GBytes *bytes,
GError **error);
GBytes *gdk_save_avif (GdkTexture *texture);
gboolean gdk_is_avif (GBytes *bytes);
+28 -41
View File
@@ -149,39 +149,37 @@ gdk_load_jpeg (GBytes *input_bytes,
g_bytes_get_size (input_bytes));
jpeg_read_header (&info, TRUE);
if (info.jpeg_color_space == JCS_GRAYSCALE)
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_GRAYSCALE;
format = GDK_MEMORY_G8;
}
else if (info.jpeg_color_space == JCS_YCbCr)
{
color_state = GDK_COLOR_STATE_JPEG;
info.out_color_space = JCS_YCbCr;
format = GDK_MEMORY_R8G8B8;
}
else if (info.jpeg_color_space == JCS_CMYK)
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_CMYK;
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
else
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_RGB;
format = GDK_MEMORY_R8G8B8;
}
jpeg_start_decompress (&info);
width = info.output_width;
height = info.output_height;
stride = gdk_memory_format_bytes_per_pixel (format) * width;
data = g_try_malloc_n (stride, height);
color_state = GDK_COLOR_STATE_SRGB;
switch ((int)info.out_color_space)
{
case JCS_GRAYSCALE:
stride = width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_G8;
break;
case JCS_RGB:
stride = 3 * width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_R8G8B8;
break;
case JCS_CMYK:
stride = 4 * width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
break;
default:
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
_("Unsupported JPEG colorspace (%d)"), info.out_color_space);
jpeg_destroy_decompress (&info);
return NULL;
}
if (!data)
{
@@ -217,6 +215,7 @@ gdk_load_jpeg (GBytes *input_bytes,
texture = gdk_memory_texture_builder_build (builder);
gdk_color_state_unref (color_state);
g_object_unref (builder);
g_bytes_unref (bytes);
@@ -240,7 +239,6 @@ gdk_save_jpeg (GdkTexture *texture)
gsize texstride;
guchar *row;
int width, height;
GdkColorState *color_state;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
@@ -270,24 +268,13 @@ gdk_save_jpeg (GdkTexture *texture)
jpeg_set_defaults (&info);
jpeg_set_quality (&info, 75, TRUE);
color_state = gdk_texture_get_color_state (texture);
if (gdk_color_state_equal (color_state, GDK_COLOR_STATE_JPEG))
{
info.in_color_space = JCS_YCbCr;
}
else
{
info.in_color_space = JCS_RGB;
color_state = GDK_COLOR_STATE_SRGB;
}
info.mem->max_memory_to_use = 300 * 1024 * 1024;
jpeg_mem_dest (&info, &data, &size);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8);
gdk_texture_downloader_set_color_state (&downloader, color_state);
gdk_texture_downloader_set_color_state (&downloader, GDK_COLOR_STATE_SRGB);
texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride);
gdk_texture_downloader_finish (&downloader);
texdata = g_bytes_get_data (texbytes, NULL);
+21 -2
View File
@@ -107,13 +107,32 @@ _gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
cairo_clip (cr);
}
/* If we have some exposed transparent area in the damage region,
* we need to clear the existing content first to leave an transparent
* area for cairo. We use (surface_bounds or damage)-(opaque) to get
* the smallest set of rectangles we need to clear as it's expensive.
*/
if (!opaque)
{
cairo_region_t *transparent;
cairo_rectangle_int_t r = { 0, 0, width/scale, height/scale };
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
if (damage != NULL)
cairo_region_get_extents (damage, &r);
transparent = cairo_region_create_rectangle (&r);
if (surface->opaque_region)
cairo_region_subtract (transparent, surface->opaque_region);
if (!cairo_region_is_empty (transparent))
{
gdk_cairo_region (cr, transparent);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_fill (cr);
}
cairo_region_destroy (transparent);
cairo_restore (cr);
}
+1 -1
View File
@@ -242,7 +242,7 @@ gdk_macos_gl_context_allocate (GdkMacosGLContext *self)
return;
/* Alter to an opaque surface if necessary */
opaque = gdk_surface_is_opaque (surface);
opaque = _gdk_macos_surface_is_opaque (GDK_MACOS_SURFACE (surface));
if (opaque != self->last_opaque)
{
self->last_opaque = !!opaque;
+1
View File
@@ -86,6 +86,7 @@ CGDirectDisplayID _gdk_macos_surface_get_screen_id (GdkMacosSurface
const char *_gdk_macos_surface_get_title (GdkMacosSurface *self);
void _gdk_macos_surface_set_title (GdkMacosSurface *self,
const char *title);
gboolean _gdk_macos_surface_is_opaque (GdkMacosSurface *self);
NSView *_gdk_macos_surface_get_view (GdkMacosSurface *self);
gboolean _gdk_macos_surface_get_modal_hint (GdkMacosSurface *self);
void _gdk_macos_surface_set_modal_hint (GdkMacosSurface *self,
+23
View File
@@ -553,6 +553,29 @@ gdk_macos_surface_init (GdkMacosSurface *self)
self->monitors = g_ptr_array_new_with_free_func (g_object_unref);
}
gboolean
_gdk_macos_surface_is_opaque (GdkMacosSurface *self)
{
GdkSurface *surface = (GdkSurface *)self;
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), FALSE);
if (surface->opaque_region != NULL &&
cairo_region_num_rectangles (surface->opaque_region) == 1)
{
cairo_rectangle_int_t extents;
cairo_region_get_extents (surface->opaque_region, &extents);
return (extents.x == 0 &&
extents.y == 0 &&
extents.width == GDK_SURFACE (self)->width &&
extents.height == GDK_SURFACE (self)->height);
}
return FALSE;
}
const char *
_gdk_macos_surface_get_title (GdkMacosSurface *self)
{
-7
View File
@@ -74,12 +74,6 @@ gdk_public_sources = files([
'loaders/gdkjpeg.c',
])
if avif_dep.found()
gdk_public_sources += [
'loaders/gdkavif.c'
]
endif
gdk_public_headers = files([
'gdk.h',
'gdkapplaunchcontext.h',
@@ -243,7 +237,6 @@ gdk_deps = [
png_dep,
tiff_dep,
jpeg_dep,
avif_dep,
]
if profiler_enabled
+10 -36
View File
@@ -1,10 +1,9 @@
#include "config.h"
#include "gdkwaylandcolor-private.h"
#include "gdksurface-wayland-private.h"
#include <gdk/wayland/xx-color-management-v4-client-protocol.h>
typedef struct _ImageDescription ImageDescription;
static uint primaries_map[] = {
[XX_COLOR_MANAGER_V4_PRIMARIES_SRGB] = 1,
[XX_COLOR_MANAGER_V4_PRIMARIES_PAL_M] = 4,
@@ -427,12 +426,11 @@ struct _GdkWaylandColorSurface
GdkWaylandColor *color;
struct xx_color_management_surface_v4 *surface;
struct xx_color_management_feedback_surface_v4 *feedback;
ImageDescription *current_desc;
GdkColorStateChanged callback;
gpointer data;
};
struct _ImageDescription
typedef struct
{
GdkWaylandColorSurface *surface;
@@ -462,7 +460,7 @@ struct _ImageDescription
unsigned int has_target_luminance : 1;
unsigned int has_target_max_cll : 1;
unsigned int has_target_max_fall : 1;
};
} ImageDescription;
static GdkColorState *
gdk_color_state_from_image_description_bits (ImageDescription *desc)
@@ -482,21 +480,6 @@ gdk_color_state_from_image_description_bits (ImageDescription *desc)
return NULL;
}
static void
gdk_wayland_color_surface_clear_image_desc (GdkWaylandColorSurface *self)
{
ImageDescription *desc = self->current_desc;
if (desc == NULL)
return;
g_clear_pointer (&desc->image_desc, xx_image_description_v4_destroy);
g_clear_pointer (&desc->info, xx_image_description_info_v4_destroy);
g_free (desc);
self->current_desc = NULL;
}
static void
image_desc_info_done (void *data,
struct xx_image_description_info_v4 *info)
@@ -505,8 +488,6 @@ image_desc_info_done (void *data,
GdkWaylandColorSurface *self = desc->surface;
GdkColorState *cs;
g_assert (self->current_desc == desc);
cs = gdk_color_state_from_image_description_bits (desc);
if (cs)
{
@@ -517,7 +498,7 @@ image_desc_info_done (void *data,
else
{
cs = GDK_COLOR_STATE_SRGB;
g_clear_pointer (&desc->image_desc, xx_image_description_v4_destroy);
xx_image_description_v4_destroy (desc->image_desc);
}
if (self->callback)
@@ -525,7 +506,8 @@ image_desc_info_done (void *data,
gdk_color_state_unref (cs);
gdk_wayland_color_surface_clear_image_desc (self);
xx_image_description_info_v4_destroy (desc->info);
g_free (desc);
}
static void
@@ -681,11 +663,10 @@ image_desc_failed (void *data,
ImageDescription *desc = data;
GdkWaylandColorSurface *self = desc->surface;
g_assert (self->current_desc == desc);
self->callback (self, GDK_COLOR_STATE_SRGB, self->data);
gdk_wayland_color_surface_clear_image_desc (self);
xx_image_description_v4_destroy (desc->image_desc);
g_free (desc);
}
static void
@@ -697,14 +678,13 @@ image_desc_ready (void *data,
GdkWaylandColorSurface *self = desc->surface;
GdkColorState *cs;
g_assert (self->current_desc == desc);
cs = g_hash_table_lookup (self->color->id_to_cs, GUINT_TO_POINTER (identity));
if (cs)
{
self->callback (self, cs, self->data);
gdk_wayland_color_surface_clear_image_desc (self);
xx_image_description_v4_destroy (desc->image_desc);
g_free (desc);
return;
}
@@ -729,13 +709,9 @@ preferred_changed (void *data,
if (!self->callback)
return;
/* If there's still an ongoing query, cancel it. It's outdated. */
gdk_wayland_color_surface_clear_image_desc (self);
desc = g_new0 (ImageDescription, 1);
desc->surface = self;
self->current_desc = desc;
desc->image_desc = xx_color_management_feedback_surface_v4_get_preferred (self->feedback);
@@ -773,8 +749,6 @@ gdk_wayland_color_surface_new (GdkWaylandColor *color,
void
gdk_wayland_color_surface_free (GdkWaylandColorSurface *self)
{
gdk_wayland_color_surface_clear_image_desc (self);
xx_color_management_surface_v4_destroy (self->surface);
xx_color_management_feedback_surface_v4_destroy (self->feedback);
+16 -3
View File
@@ -120,6 +120,20 @@ maybe_wait_for_vblank (GdkDisplay *display,
}
}
static GLXDrawable
gdk_x11_gl_context_glx_get_drawable (GdkX11GLContextGLX *self)
{
GdkDrawContext *draw_context = GDK_DRAW_CONTEXT (self);
GdkSurface *surface;
if (gdk_draw_context_is_in_frame (draw_context))
surface = gdk_draw_context_get_surface (draw_context);
else
surface = GDK_X11_DISPLAY (gdk_draw_context_get_display (draw_context))->leader_gdk_surface;
return gdk_x11_surface_get_glx_drawable (surface);
}
static void
gdk_x11_gl_context_glx_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted)
@@ -304,11 +318,10 @@ gdk_x11_gl_context_glx_get_damage (GdkGLContext *context)
if (display_x11->has_glx_buffer_age)
{
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
GdkX11GLContextGLX *self = GDK_X11_GL_CONTEXT_GLX (context);
gdk_gl_context_make_current (context);
glXQueryDrawable (dpy,
gdk_x11_surface_get_glx_drawable (surface),
glXQueryDrawable (dpy, gdk_x11_gl_context_glx_get_drawable (self),
GLX_BACK_BUFFER_AGE_EXT, &buffer_age);
if (buffer_age > 0 && buffer_age <= GDK_GL_MAX_TRACKED_BUFFERS)
+2 -2
View File
@@ -934,7 +934,7 @@ gsk_broadway_renderer_render (GskRenderer *renderer,
self->node_lookup = g_hash_table_new (g_direct_hash, g_direct_equal);
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->draw_context), GDK_MEMORY_U8, update_area, NULL);
gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->draw_context), update_area);
/* These are owned by the draw context between begin and end, but
cache them here for easier access during the render */
@@ -946,7 +946,7 @@ gsk_broadway_renderer_render (GskRenderer *renderer,
self->nodes = NULL;
self->node_textures = NULL;
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->draw_context));
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->draw_context));
if (self->last_node_lookup)
g_hash_table_unref (self->last_node_lookup);
+4 -4
View File
@@ -133,7 +133,7 @@ void half_to_float4 (const guint16 h[4], float f[4]) __attribute__((ifunc ("reso
void float_to_half (const float *f, guint16 *h, int n) __attribute__((ifunc ("resolve_float_to_half")));
void half_to_float (const guint16 *h, float *f, int n) __attribute__((ifunc ("resolve_half_to_float")));
static void * __attribute__ ((no_sanitize_address)) G_GNUC_UNUSED
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half4 (void)
{
__builtin_cpu_init ();
@@ -143,7 +143,7 @@ resolve_float_to_half4 (void)
return float_to_half4_c;
}
static void * __attribute__ ((no_sanitize_address)) G_GNUC_UNUSED
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float4 (void)
{
__builtin_cpu_init ();
@@ -153,7 +153,7 @@ resolve_half_to_float4 (void)
return half_to_float4_c;
}
static void * __attribute__ ((no_sanitize_address)) G_GNUC_UNUSED
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half (void)
{
__builtin_cpu_init ();
@@ -163,7 +163,7 @@ resolve_float_to_half (void)
return float_to_half_c;
}
static void * __attribute__ ((no_sanitize_address)) G_GNUC_UNUSED
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float (void)
{
__builtin_cpu_init ();
-12
View File
@@ -43,7 +43,6 @@
#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include <gdk/gdktextureprivate.h>
#include <gdk/gdkdmabufeglprivate.h>
#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkdmabuftextureprivate.h>
@@ -218,9 +217,6 @@ gsk_gl_driver_dispose (GObject *object)
g_assert (GSK_IS_GL_DRIVER (self));
g_assert (self->in_frame == FALSE);
if (self->shared_command_queue)
gsk_gl_command_queue_make_current (self->shared_command_queue);
#define GSK_GL_NO_UNIFORMS
#define GSK_GL_SHADER_RESOURCE(name)
#define GSK_GL_SHADER_STRING(str)
@@ -815,8 +811,6 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
gboolean external;
GdkMemoryFormat format;
gboolean premultiply;
GdkColorState *color_state;
int color_space, range;
gdk_gl_context_make_current (context);
@@ -834,16 +828,10 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
format = gdk_texture_get_format (GDK_TEXTURE (texture));
premultiply = gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT;
color_state = gdk_texture_get_color_state (GDK_TEXTURE (texture));
gdk_dmabuf_get_egl_yuv_hints (dmabuf, color_state, &color_space, &range);
texture_id = gdk_gl_context_import_dmabuf (context,
width, height,
dmabuf,
color_space,
range,
&external);
if (texture_id == 0)
return 0;
+69 -17
View File
@@ -192,12 +192,12 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
g_assert (self->context == NULL);
g_assert (self->command_queue == NULL);
if (!gdk_display_prepare_gl (display, error))
goto failure;
if (surface == NULL)
context = gdk_display_create_gl_context (display, error);
else
context = gdk_surface_create_gl_context (surface, error);
context = gdk_gl_context_new (display, surface, surface != NULL);
if (!gdk_gl_context_realize (context, error))
if (!context || !gdk_gl_context_realize (context, error))
goto failure;
api = gdk_gl_context_get_api (context);
@@ -258,8 +258,6 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
g_clear_object (&self->driver);
g_clear_object (&self->command_queue);
g_clear_object (&self->context);
gdk_gl_context_clear_current ();
}
static cairo_region_t *
@@ -295,6 +293,65 @@ get_render_region (GdkSurface *surface,
return cairo_region_create_rectangle (&extents);
}
static gboolean
update_area_requires_clear (GdkSurface *surface,
const cairo_region_t *update_area)
{
cairo_rectangle_int_t rect;
guint n_rects;
g_assert (GDK_IS_SURFACE (surface));
/* No opaque region, assume we have to clear */
if (surface->opaque_region == NULL)
return TRUE;
/* If the update_area is the whole surface, then clear it
* because many drivers optimize for this by avoiding extra
* work to reload any contents.
*/
if (update_area == NULL)
return TRUE;
if (cairo_region_num_rectangles (update_area) == 1)
{
cairo_region_get_rectangle (update_area, 0, &rect);
if (rect.x == 0 &&
rect.y == 0 &&
rect.width == surface->width &&
rect.height == surface->height)
return TRUE;
}
/* If the entire surface is opaque, then we can skip clearing
* (with the exception of full surface clearing above).
*/
if (cairo_region_num_rectangles (surface->opaque_region) == 1)
{
cairo_region_get_rectangle (surface->opaque_region, 0, &rect);
if (rect.x == 0 &&
rect.y == 0 &&
rect.width == surface->width &&
rect.height == surface->height)
return FALSE;
}
/* If any update_area rectangle overlaps our transparent
* regions, then we need to clear the area.
*/
n_rects = cairo_region_num_rectangles (update_area);
for (guint i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (update_area, i, &rect);
if (cairo_region_contains_rectangle (surface->opaque_region, &rect) != CAIRO_REGION_OVERLAP_IN)
return TRUE;
}
return FALSE;
}
static void
gsk_gl_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
@@ -305,8 +362,7 @@ gsk_gl_renderer_render (GskRenderer *renderer,
graphene_rect_t viewport;
GskGLRenderJob *job;
GdkSurface *surface;
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
gboolean clear_framebuffer;
float scale;
g_assert (GSK_IS_GL_RENDERER (renderer));
@@ -326,27 +382,23 @@ gsk_gl_renderer_render (GskRenderer *renderer,
viewport.size.width = gdk_surface_get_width (surface) * scale;
viewport.size.height = gdk_surface_get_height (surface) * scale;
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->context),
gsk_render_node_get_preferred_depth (root),
update_area,
opaque);
update_area);
gdk_gl_context_make_current (self->context);
/* Must be called *AFTER* gdk_draw_context_begin_frame() */
render_region = get_render_region (surface, self->context);
clear_framebuffer = update_area_requires_clear (surface, render_region);
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, TRUE);
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, clear_framebuffer);
gsk_gl_render_job_render (job, root);
gsk_gl_driver_end_frame (self->driver);
gsk_gl_render_job_free (job);
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->context));
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));
gsk_gl_driver_after_frame (self->driver);
+4 -16
View File
@@ -2182,10 +2182,6 @@ gsk_gl_render_job_visit_unblurred_inset_shadow_node (GskGLRenderJob *job,
if (gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow)))
{
const GdkRGBA rgba;
gdk_color_to_float (gsk_inset_shadow_node_get_color2 (node), GDK_COLOR_STATE_SRGB, (float *) &rgba);
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
UNIFORM_INSET_SHADOW_OUTLINE_RECT, 0,
&transformed_outline);
@@ -2196,7 +2192,7 @@ gsk_gl_render_job_visit_unblurred_inset_shadow_node (GskGLRenderJob *job,
UNIFORM_INSET_SHADOW_OFFSET, 0,
gsk_inset_shadow_node_get_dx (node),
gsk_inset_shadow_node_get_dy (node));
rgba_to_half (&rgba, color);
rgba_to_half (gsk_inset_shadow_node_get_color (node), color);
gsk_gl_render_job_draw_rect_with_color (job, &node->bounds, color);
gsk_gl_render_job_end_draw (job);
}
@@ -2289,10 +2285,6 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
/* Actual inset shadow outline drawing */
if (gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow)))
{
const GdkRGBA rgba;
gdk_color_to_float (gsk_inset_shadow_node_get_color2 (node), GDK_COLOR_STATE_SRGB, (float *) &rgba);
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
UNIFORM_INSET_SHADOW_OUTLINE_RECT, 0,
&transformed_outline);
@@ -2303,7 +2295,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
UNIFORM_INSET_SHADOW_OFFSET, 0,
offset_x * scale_x,
offset_y * scale_y);
rgba_to_half (&rgba, color);
rgba_to_half (gsk_inset_shadow_node_get_color (node), color);
gsk_gl_render_job_draw_with_color (job,
0, 0, texture_width, texture_height,
color);
@@ -2386,7 +2378,6 @@ gsk_gl_render_job_visit_unblurred_outset_shadow_node (GskGLRenderJob *job,
float spread = gsk_outset_shadow_node_get_spread (node);
float dx = gsk_outset_shadow_node_get_dx (node);
float dy = gsk_outset_shadow_node_get_dy (node);
GdkRGBA rgba;
guint16 color[4];
const float edge_sizes[] = { // Top, right, bottom, left
spread - dy, spread + dx, spread + dy, spread - dx
@@ -2398,8 +2389,7 @@ gsk_gl_render_job_visit_unblurred_outset_shadow_node (GskGLRenderJob *job,
{ outline->corner[3].width + spread - dx, outline->corner[3].height + spread + dy },
};
gdk_color_to_float (gsk_outset_shadow_node_get_color2 (node), GDK_COLOR_STATE_SRGB, (float *) &rgba);
rgba_to_half (&rgba, color);
rgba_to_half (gsk_outset_shadow_node_get_color (node), color);
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
@@ -2483,13 +2473,11 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
int blurred_texture_id;
int cached_tid;
gboolean do_slicing;
GdkRGBA rgba;
guint16 color[4];
float half_width = outline->bounds.size.width / 2;
float half_height = outline->bounds.size.height / 2;
gdk_color_to_float (gsk_outset_shadow_node_get_color2 (node), GDK_COLOR_STATE_SRGB, (float *) &rgba);
rgba_to_half (&rgba, color);
rgba_to_half (gsk_outset_shadow_node_get_color (node), color);
/* scaled_outline is the minimal outline we need to draw the given drop shadow,
* enlarged by the spread and offset by the blur radius. */
+2 -40
View File
@@ -10,7 +10,6 @@
#include "gskglimageprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdmabufeglprivate.h"
#include "gdkglcontextprivate.h"
#include "gdkgltextureprivate.h"
@@ -93,7 +92,7 @@ gsk_gl_frame_upload_texture (GskGpuFrame *frame,
gdk_gl_texture_get_id (gl_texture),
FALSE,
gdk_gl_texture_has_mipmap (gl_texture) ? (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_MIPMAP) : 0);
/* This is a hack, but it works */
sync = gdk_gl_texture_get_sync (gl_texture);
if (sync)
@@ -106,56 +105,19 @@ gsk_gl_frame_upload_texture (GskGpuFrame *frame,
{
gboolean external;
GLuint tex_id;
int color_space_hint = 0;
int range_hint = 0;
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
gdk_dmabuf_get_egl_yuv_hints (gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
gdk_texture_get_color_state (texture),
&color_space_hint,
&range_hint);
#endif
tex_id = gdk_gl_context_import_dmabuf (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
color_space_hint,
range_hint,
&external);
if (tex_id)
{
GskGpuImageFlags flags = 0;
if (external)
flags |= GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT;
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
switch (color_space_hint)
{
case EGL_ITU_REC709_EXT:
flags |= GSK_GPU_IMAGE_BT709;
break;
case EGL_ITU_REC601_EXT:
flags |= GSK_GPU_IMAGE_BT601;
break;
case EGL_ITU_REC2020_EXT:
flags |= GSK_GPU_IMAGE_BT2020;
break;
default:
break;
}
if (range_hint == EGL_YUV_NARROW_RANGE_EXT)
flags |= GSK_GPU_IMAGE_NARROW_RANGE;
#endif
return gsk_gl_image_new_for_texture (GSK_GL_DEVICE (gsk_gpu_frame_get_device (frame)),
texture,
tex_id,
TRUE,
flags);
(external ? GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT : 0));
}
}
+13 -25
View File
@@ -56,22 +56,18 @@ static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = {
static void
gsk_gpu_blur_op_full (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GskGpuColorStates color_states,
guint32 variation,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const graphene_vec2_t *blur_direction,
const GdkColor *blur_color)
float blur_color[4])
{
GskGpuBlurInstance *instance;
GdkColorState *alt;
alt = gsk_gpu_color_states_find (ccs, blur_color);
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BLUR_OP_CLASS,
gsk_gpu_color_states_create (ccs, TRUE, alt, variation & VARIATION_COLORIZE ? FALSE : TRUE),
color_states,
variation,
clip,
(GskGpuImage *[1]) { image->image },
@@ -81,49 +77,41 @@ gsk_gpu_blur_op_full (GskGpuFrame *frame,
gsk_gpu_rect_to_float (image->coverage, offset, instance->rect);
gsk_gpu_rect_to_float (image->bounds, offset, instance->tex_rect);
graphene_vec2_to_float (blur_direction, instance->blur_direction);
gsk_gpu_color_to_float (blur_color, alt, opacity, instance->blur_color);
gsk_gpu_vec4_to_float (blur_color, instance->blur_color);
}
void
gsk_gpu_blur_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const graphene_vec2_t *blur_direction)
{
GdkColor blur_color;
gdk_color_init (&blur_color, ccs, (float[]) { 1, 1, 1, 1 });
gsk_gpu_blur_op_full (frame,
clip,
ccs,
opacity,
offset,
color_states,
0,
offset,
image,
blur_direction,
&blur_color);
gdk_color_finish (&blur_color);
(float[4]) { 1, 1, 1, 1 });
}
void
gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const graphene_vec2_t *blur_direction,
const GdkColor *shadow_color)
float shadow_color[4])
{
gsk_gpu_blur_op_full (frame,
clip,
ccs,
opacity,
offset,
color_states,
VARIATION_COLORIZE,
offset,
image,
blur_direction,
shadow_color);
+3 -5
View File
@@ -8,20 +8,18 @@ G_BEGIN_DECLS
void gsk_gpu_blur_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const graphene_vec2_t *blur_direction);
void gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const graphene_vec2_t *blur_direction,
const GdkColor *shadow_color);
float shadow_color[4]);
G_END_DECLS
+5 -15
View File
@@ -97,29 +97,19 @@ static const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS = {
void
gsk_gpu_border_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GskGpuColorStates color_states,
const GskRoundedRect *outline,
const graphene_point_t *offset,
const graphene_point_t *inside_offset,
const float widths[4],
const GdkColor colors[4])
const float colors[4][4])
{
GskGpuBorderInstance *instance;
guint i;
GdkColorState *alt;
if (GDK_IS_DEFAULT_COLOR_STATE (colors[0].color_state) &&
gdk_color_state_equal (colors[0].color_state, colors[1].color_state) &&
gdk_color_state_equal (colors[0].color_state, colors[2].color_state) &&
gdk_color_state_equal (colors[0].color_state, colors[3].color_state))
alt = colors[0].color_state;
else
alt = ccs;
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BORDER_OP_CLASS,
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
color_states,
0,
clip,
NULL,
@@ -131,7 +121,7 @@ gsk_gpu_border_op (GskGpuFrame *frame,
for (i = 0; i < 4; i++)
{
instance->border_widths[i] = widths[i];
gsk_gpu_color_to_float (&colors[i], alt, opacity, &instance->border_colors[4 * i]);
gsk_gpu_vec4_to_float (colors[i], &instance->border_colors[4 * i]);
}
instance->offset[0] = inside_offset->x;
instance->offset[1] = inside_offset->y;
+3 -5
View File
@@ -2,7 +2,6 @@
#include "gskgputypesprivate.h"
#include "gsktypes.h"
#include "gdkcolorprivate.h"
#include <graphene.h>
@@ -10,13 +9,12 @@ G_BEGIN_DECLS
void gsk_gpu_border_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GskGpuColorStates color_states,
const GskRoundedRect *outline,
const graphene_point_t *offset,
const graphene_point_t *inside_offset,
const float widths[4],
const GdkColor colors[4]);
const float colors[4][4]);
G_END_DECLS
+5 -9
View File
@@ -76,28 +76,24 @@ static const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS = {
void
gsk_gpu_box_shadow_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GskGpuColorStates color_states,
gboolean inset,
const graphene_rect_t *bounds,
const GskRoundedRect *outline,
const graphene_point_t *shadow_offset,
float spread,
float blur_radius,
const GdkColor *color)
const graphene_point_t *offset,
const float color[4])
{
GskGpuBoxshadowInstance *instance;
GdkColorState *alt;
/* Use border shader for no blurring */
g_return_if_fail (blur_radius > 0.0f);
alt = gsk_gpu_color_states_find (ccs, color);
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_BOX_SHADOW_OP_CLASS,
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
color_states,
inset ? VARIATION_INSET : 0,
clip,
NULL,
@@ -106,7 +102,7 @@ gsk_gpu_box_shadow_op (GskGpuFrame *frame,
gsk_gpu_rect_to_float (bounds, offset, instance->bounds);
gsk_rounded_rect_to_float (outline, offset, instance->outline);
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
gsk_gpu_vec4_to_float (color, instance->color);
instance->shadow_offset[0] = shadow_offset->x;
instance->shadow_offset[1] = shadow_offset->y;
instance->shadow_spread = spread;
+3 -5
View File
@@ -2,7 +2,6 @@
#include "gskgputypesprivate.h"
#include "gsktypes.h"
#include "gdkcolorprivate.h"
#include <graphene.h>
@@ -10,16 +9,15 @@ G_BEGIN_DECLS
void gsk_gpu_box_shadow_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
const graphene_point_t *offset,
GskGpuColorStates color_states,
gboolean inset,
const graphene_rect_t *bounds,
const GskRoundedRect *outline,
const graphene_point_t *shadow_offset,
float spread,
float blur_radius,
const GdkColor *color);
const graphene_point_t *offset,
const float color[4]);
G_END_DECLS
+1 -1
View File
@@ -682,7 +682,7 @@ gsk_gpu_cache_lookup_tile (GskGpuCache *self,
gsk_gpu_cached_use (self, (GskGpuCached *) tile);
*out_color_state = gdk_color_state_ref (tile->color_state);
*out_color_state = tile->color_state;
return g_object_ref (tile->image);
}
+4 -8
View File
@@ -52,20 +52,16 @@ static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
void
gsk_gpu_colorize_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color)
const float color[4])
{
GskGpuColorizeInstance *instance;
GdkColorState *alt;
alt = gsk_gpu_color_states_find (ccs, color);
gsk_gpu_shader_op_alloc (frame,
&GSK_GPU_COLORIZE_OP_CLASS,
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
color_states,
0,
clip,
(GskGpuImage *[1]) { image->image },
@@ -74,5 +70,5 @@ gsk_gpu_colorize_op (GskGpuFrame *frame,
gsk_gpu_rect_to_float (image->coverage ? image->coverage : image->bounds, offset, instance->rect);
gsk_gpu_rect_to_float (image->bounds, offset, instance->tex_rect);
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
gsk_gpu_vec4_to_float (color, instance->color);
}
+2 -3
View File
@@ -8,11 +8,10 @@ G_BEGIN_DECLS
void gsk_gpu_colorize_op (GskGpuFrame *frame,
GskGpuShaderClip clip,
GdkColorState *ccs,
float opacity,
GskGpuColorStates color_states,
const graphene_point_t *offset,
const GskGpuShaderImage *image,
const GdkColor *color);
const float color[4]);
G_END_DECLS
+1 -6
View File
@@ -36,8 +36,7 @@ gsk_gpu_convert_cicp_op_print_instance (GskGpuShaderOp *shader,
g_string_append_printf (string, "cicp %u/%u/%u/%u",
instance->color_primaries,
instance->transfer_function,
instance->matrix_coefficients,
instance->range);
0, 1);
}
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
@@ -89,8 +88,6 @@ gsk_gpu_convert_from_cicp_op (GskGpuFrame *frame,
instance->opacity = opacity;
instance->color_primaries = cicp->color_primaries;
instance->transfer_function = cicp->transfer_function;
instance->matrix_coefficients = cicp->matrix_coefficients;
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
}
void
@@ -121,6 +118,4 @@ gsk_gpu_convert_to_cicp_op (GskGpuFrame *frame,
instance->opacity = opacity;
instance->color_primaries = cicp->color_primaries;
instance->transfer_function = cicp->transfer_function;
instance->matrix_coefficients = cicp->matrix_coefficients;
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
}
+101 -7
View File
@@ -33,6 +33,8 @@ struct _GskGpuDownloadOp
GskGpuOp op;
GskGpuImage *image;
GdkColorState *image_cs;
GdkColorState *download_cs;
gboolean allow_dmabuf;
GdkGpuDownloadOpCreateFunc create_func;
GskGpuDownloadFunc func;
@@ -53,8 +55,60 @@ gsk_gpu_download_op_finish (GskGpuOp *op)
if (self->create_func)
self->create_func (self);
g_print ("downloaded texture: %s %.4s depth %s format %s color state %s\n",
GDK_IS_DMABUF_TEXTURE (self->texture)
? "dmabuf"
: (GDK_IS_GL_TEXTURE (self->texture)
? "gl"
: "memory"),
GDK_IS_DMABUF_TEXTURE (self->texture)
? (char *) &gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (self->texture))->fourcc
: "",
gdk_memory_depth_get_name (gdk_memory_format_get_depth (gdk_texture_get_format (self->texture), FALSE)),
gdk_memory_format_get_name (gdk_texture_get_format (self->texture)),
gdk_color_state_get_name (gdk_texture_get_color_state (self->texture)));
if (!gdk_color_state_equal (gdk_texture_get_color_state (self->texture), self->download_cs))
{
GdkTextureDownloader *downloader;
GdkMemoryTextureBuilder *builder;
GBytes *bytes;
gsize stride;
GdkTexture *texture;
g_print ("converting rendered %s texture after download: %s -> %s\n",
GDK_IS_DMABUF_TEXTURE (self->texture) ? "dmabuf" :
(GDK_IS_GL_TEXTURE (self->texture) ? "gl" : "memory"),
gdk_color_state_get_name (gdk_texture_get_color_state (self->texture)),
gdk_color_state_get_name (self->download_cs));
downloader = gdk_texture_downloader_new (self->texture);
gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (self->texture));
gdk_texture_downloader_set_color_state (downloader, self->download_cs);
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
gdk_texture_downloader_free (downloader);
builder = gdk_memory_texture_builder_new ();
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_width (builder, gdk_texture_get_width (self->texture));
gdk_memory_texture_builder_set_height (builder, gdk_texture_get_height (self->texture));
gdk_memory_texture_builder_set_format (builder, gdk_texture_get_format (self->texture));
gdk_memory_texture_builder_set_color_state (builder, self->download_cs);
texture = gdk_memory_texture_builder_build (builder);
g_object_unref (builder);
g_set_object (&self->texture, texture);
g_bytes_unref (bytes);
g_object_unref (texture);
}
self->func (self->user_data, self->texture);
gdk_color_state_unref (self->image_cs);
gdk_color_state_unref (self->download_cs);
g_object_unref (self->texture);
g_object_unref (self->image);
g_clear_object (&self->buffer);
@@ -70,6 +124,7 @@ gsk_gpu_download_op_print (GskGpuOp *op,
gsk_gpu_print_op (string, indent, "download");
gsk_gpu_print_image (string, self->image);
gsk_gpu_print_string (string, gdk_color_state_get_name (self->download_cs));
gsk_gpu_print_newline (string);
}
@@ -118,6 +173,7 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
guchar *data;
gsize width, height, stride;
GdkMemoryFormat format;
GdkMemoryTextureBuilder *builder;
data = gsk_gpu_buffer_map (self->buffer);
width = gsk_gpu_image_get_width (self->image);
@@ -125,11 +181,18 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
format = gsk_gpu_image_get_format (self->image);
stride = width * gdk_memory_format_bytes_per_pixel (format);
bytes = g_bytes_new (data, stride * height);
self->texture = gdk_memory_texture_new (width,
height,
format,
bytes,
stride);
builder = gdk_memory_texture_builder_new ();
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_width (builder, width);
gdk_memory_texture_builder_set_height (builder, height);
gdk_memory_texture_builder_set_format (builder, format);
gdk_memory_texture_builder_set_color_state (builder, self->image_cs);
self->texture = gdk_memory_texture_builder_build (builder);
g_object_unref (builder);
g_bytes_unref (bytes);
gsk_gpu_buffer_unmap (self->buffer, 0);
}
@@ -144,7 +207,17 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op,
#ifdef HAVE_DMABUF
if (self->allow_dmabuf)
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image));
{
GdkColorState *cs;
if (gsk_gpu_image_get_flags (self->image) & GSK_GPU_IMAGE_SRGB)
cs = GDK_COLOR_STATE_SRGB;
else
cs = self->image_cs;
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image), cs);
}
if (self->texture)
{
GskGpuDevice *device = gsk_gpu_frame_get_device (frame);
@@ -295,10 +368,16 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
GskGLTextureData *data;
GdkGLContext *context;
guint texture_id;
GdkColorState *cs;
context = GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame));
texture_id = gsk_gl_image_steal_texture (GSK_GL_IMAGE (self->image));
if (gsk_gpu_image_get_flags (self->image) & GSK_GPU_IMAGE_SRGB)
cs = GDK_COLOR_STATE_SRGB_LINEAR;
else
cs = self->image_cs;
#ifdef HAVE_DMABUF
if (self->allow_dmabuf)
{
@@ -317,12 +396,20 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
gdk_dmabuf_texture_builder_set_width (db, gsk_gpu_image_get_width (self->image));
gdk_dmabuf_texture_builder_set_height (db, gsk_gpu_image_get_height (self->image));
self->texture = gdk_dmabuf_texture_builder_build (db, release_dmabuf_texture, texture, NULL);
gdk_dmabuf_texture_builder_set_color_state (db, cs);
g_print ("dmabuf downloader color state: %s\n", gdk_color_state_get_name (gdk_dmabuf_texture_builder_get_color_state (db)));
self->texture = gdk_dmabuf_texture_builder_build (db,
release_dmabuf_texture,
texture,
NULL);
g_object_unref (db);
if (self->texture)
return op->next;
else
g_print ("failed to build dmabuf texture\n");
}
g_free (texture);
@@ -343,6 +430,7 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
gdk_gl_texture_builder_set_width (builder, gsk_gpu_image_get_width (self->image));
gdk_gl_texture_builder_set_height (builder, gsk_gpu_image_get_height (self->image));
gdk_gl_texture_builder_set_sync (builder, data->sync);
gdk_gl_texture_builder_set_color_state (builder, cs);
self->texture = gdk_gl_texture_builder_build (builder,
gsk_gl_texture_data_free,
@@ -367,6 +455,8 @@ static const GskGpuOpClass GSK_GPU_DOWNLOAD_OP_CLASS = {
void
gsk_gpu_download_op (GskGpuFrame *frame,
GskGpuImage *image,
GdkColorState *image_cs,
GdkColorState *download_cs,
gboolean allow_dmabuf,
GskGpuDownloadFunc func,
gpointer user_data)
@@ -377,6 +467,10 @@ gsk_gpu_download_op (GskGpuFrame *frame,
self->image = g_object_ref (image);
self->allow_dmabuf = allow_dmabuf;
self->image_cs = gdk_color_state_ref (image_cs);
self->download_cs = gdk_color_state_ref (download_cs);
self->func = func,
self->user_data = user_data;
}
+2
View File
@@ -9,6 +9,8 @@ typedef void (* GskGpuDownloadFunc) (gpointe
void gsk_gpu_download_op (GskGpuFrame *frame,
GskGpuImage *image,
GdkColorState *image_cs,
GdkColorState *download_cs,
gboolean allow_dmabuf,
GskGpuDownloadFunc func,
gpointer user_data);
+53 -15
View File
@@ -78,20 +78,19 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self)
}
static void
gsk_gpu_frame_default_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
gsk_gpu_frame_default_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
{
gdk_draw_context_begin_frame_full (context, depth, region, opaque);
gdk_draw_context_begin_frame_full (context, depth, region);
}
static void
gsk_gpu_frame_default_end (GskGpuFrame *self,
GdkDrawContext *context)
{
gdk_draw_context_end_frame_full (context);
gdk_draw_context_end_frame (context);
}
static void
@@ -203,10 +202,9 @@ void
gsk_gpu_frame_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
const cairo_region_t *region)
{
GSK_GPU_FRAME_GET_CLASS (self)->begin (self, context, depth, region, opaque);
GSK_GPU_FRAME_GET_CLASS (self)->begin (self, context, depth, region);
}
void
@@ -634,7 +632,7 @@ gsk_gpu_frame_record (GskGpuFrame *self,
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
cairo_region_t *clip,
const cairo_region_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport,
GdkTexture **texture)
@@ -645,10 +643,48 @@ gsk_gpu_frame_record (GskGpuFrame *self,
priv->timestamp = timestamp;
gsk_gpu_cache_set_time (gsk_gpu_device_get_cache (priv->device), timestamp);
gsk_gpu_node_processor_process (self, target, target_color_state, clip, node, viewport, pass_type);
if (clip)
{
int i;
for (i = 0; i < cairo_region_num_rectangles (clip); i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (clip, i, &rect);
gsk_gpu_node_processor_process (self, target, target_color_state, &rect, node, viewport, pass_type);
}
}
else
{
gsk_gpu_node_processor_process (self,
target,
target_color_state,
&(cairo_rectangle_int_t) {
0, 0,
gsk_gpu_image_get_width (target),
gsk_gpu_image_get_height (target)
},
node,
viewport,
pass_type);
}
if (texture)
gsk_gpu_download_op (self, target, TRUE, copy_texture, texture);
{
GdkColorState *image_cs;
GdkColorState *download_cs;
image_cs = gdk_color_state_get_rendering_color_state (target_color_state,
gsk_gpu_image_get_flags (target) & GSK_GPU_IMAGE_SRGB);
if (image_cs == GDK_COLOR_STATE_SRGB_LINEAR)
download_cs = GDK_COLOR_STATE_SRGB;
else
download_cs = image_cs;
gsk_gpu_download_op (self, target, target_color_state, download_cs, TRUE, copy_texture, texture);
}
}
static void
@@ -687,7 +723,7 @@ gsk_gpu_frame_render (GskGpuFrame *self,
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
cairo_region_t *clip,
const cairo_region_t *region,
GskRenderNode *node,
const graphene_rect_t *viewport,
GdkTexture **texture)
@@ -696,7 +732,7 @@ gsk_gpu_frame_render (GskGpuFrame *self,
gsk_gpu_frame_cleanup (self);
gsk_gpu_frame_record (self, timestamp, target, target_color_state, clip, node, viewport, texture);
gsk_gpu_frame_record (self, timestamp, target, target_color_state, region, node, viewport, texture);
gsk_gpu_frame_submit (self, pass_type);
}
@@ -755,6 +791,8 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self,
gsk_gpu_download_op (self,
image,
gdk_texture_get_color_state (texture),
color_state,
FALSE,
do_download,
g_memdup (&(Download) {
+3 -5
View File
@@ -30,8 +30,7 @@ struct _GskGpuFrameClass
void (* begin) (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque);
const cairo_region_t *region);
void (* end) (GskGpuFrame *self,
GdkDrawContext *context);
GskGpuImage * (* upload_texture) (GskGpuFrame *self,
@@ -67,8 +66,7 @@ gsize gsk_gpu_frame_get_texture_vertex_size (GskGpuF
void gsk_gpu_frame_begin (GskGpuFrame *self,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque);
const cairo_region_t *region);
void gsk_gpu_frame_end (GskGpuFrame *self,
GdkDrawContext *context);
@@ -104,7 +102,7 @@ void gsk_gpu_frame_render (GskGpuF
gint64 timestamp,
GskGpuImage *target,
GdkColorState *target_color_state,
cairo_region_t *clip,
const cairo_region_t *region,
GskRenderNode *node,
const graphene_rect_t *viewport,
GdkTexture **texture);
-59
View File
@@ -1,7 +1,6 @@
#include "config.h"
#include "gskgpuimageprivate.h"
#include "gdkcolorstateprivate.h"
typedef struct _GskGpuImagePrivate GskGpuImagePrivate;
@@ -163,61 +162,3 @@ gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
{
GSK_GPU_IMAGE_GET_CLASS (self)->get_projection_matrix (self, out_projection);
}
GdkColorState *
gsk_gpu_image_adjust_color_state (GskGpuImage *self,
GdkColorState *color_state)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
GdkColorState *adjusted;
GdkCicp cicp;
adjusted = gdk_color_state_ref (color_state);
if (priv->flags & GSK_GPU_IMAGE_SRGB)
{
GdkColorState *no_srgb;
no_srgb = gdk_color_state_get_no_srgb_tf (adjusted);
g_assert (no_srgb);
gdk_color_state_unref (adjusted);
adjusted = gdk_color_state_ref (no_srgb);
}
if (!gdk_color_state_get_cicp (adjusted))
return adjusted;
cicp = *gdk_color_state_get_cicp (adjusted);
if (priv->flags & GSK_GPU_IMAGE_NARROW_RANGE)
cicp.range = GDK_CICP_RANGE_FULL;
switch (priv->flags & GSK_GPU_IMAGE_YUV)
{
case GSK_GPU_IMAGE_BT709:
g_assert (cicp.matrix_coefficients == 1);
cicp.matrix_coefficients = 0;
break;
case GSK_GPU_IMAGE_BT601:
g_assert (cicp.matrix_coefficients == 5 ||
cicp.matrix_coefficients == 6);
cicp.matrix_coefficients = 0;
break;
case GSK_GPU_IMAGE_BT2020:
g_assert (cicp.matrix_coefficients == 9);
cicp.matrix_coefficients = 0;
break;
default:
break;
}
if (!gdk_cicp_equal (&cicp, gdk_color_state_get_cicp (adjusted)))
{
gdk_color_state_unref (adjusted);
adjusted = gdk_color_state_new_for_cicp (&cicp, NULL);
g_assert (adjusted);
}
return adjusted;
}
-3
View File
@@ -48,9 +48,6 @@ void gsk_gpu_image_set_flags (GskGpuI
void gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection);
GdkColorState * gsk_gpu_image_adjust_color_state (GskGpuImage *self,
GdkColorState *color_state);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuImage, g_object_unref)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -8,7 +8,7 @@ G_BEGIN_DECLS
void gsk_gpu_node_processor_process (GskGpuFrame *frame,
GskGpuImage *target,
GdkColorState *target_color_state,
cairo_region_t *clip,
const cairo_rectangle_int_t *clip,
GskRenderNode *node,
const graphene_rect_t *viewport,
GskRenderPassType pass_type);
+21 -33
View File
@@ -264,7 +264,6 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
guchar *data;
GdkTexture *texture;
GdkTextureDownloader downloader;
cairo_region_t *clip_region;
GskGpuFrame *frame;
max_size = gsk_gpu_device_get_max_image_size (priv->device);
@@ -300,22 +299,14 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
MIN (image_width, width - x),
MIN (image_height, height - y));
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
else
color_state = GDK_COLOR_STATE_SRGB;
color_state = GDK_COLOR_STATE_SRGB;
clip_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_gpu_image_get_width (image),
gsk_gpu_image_get_height (image)
});
frame = gsk_gpu_renderer_create_frame (self);
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
image,
color_state,
clip_region,
NULL,
root,
&GRAPHENE_RECT_INIT (rounded_viewport->origin.x + x,
rounded_viewport->origin.y + y,
@@ -358,7 +349,7 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
GdkTexture *texture;
graphene_rect_t rounded_viewport;
GdkColorState *color_state;
cairo_region_t *clip_region;
GdkMemoryDepth depth;
gsk_gpu_device_maybe_gc (priv->device);
@@ -368,33 +359,34 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
viewport->origin.y,
ceil (viewport->size.width),
ceil (viewport->size.height));
if (gsk_render_node_is_hdr (root))
color_state = GDK_COLOR_STATE_REC2100_PQ;
else
color_state = GDK_COLOR_STATE_SRGB;
depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (root),
gdk_color_state_get_depth (color_state));
image = gsk_gpu_device_create_download_image (priv->device,
gsk_render_node_get_preferred_depth (root),
depth,
rounded_viewport.size.width,
rounded_viewport.size.height);
if (image == NULL)
return gsk_gpu_renderer_fallback_render_texture (self, root, &rounded_viewport);
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
else
color_state = GDK_COLOR_STATE_SRGB;
g_print ("render_texture: image depth %s, target color state %s\n",
gdk_memory_depth_get_name (depth), gdk_color_state_get_name (color_state));
frame = gsk_gpu_renderer_create_frame (self);
clip_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_gpu_image_get_width (image),
gsk_gpu_image_get_height (image)
});
texture = NULL;
gsk_gpu_frame_render (frame,
g_get_monotonic_time (),
image,
color_state,
clip_region,
NULL,
root,
&rounded_viewport,
&texture);
@@ -420,8 +412,6 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
GskGpuFrame *frame;
GskGpuImage *backbuffer;
cairo_region_t *render_region;
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
double scale;
GdkMemoryDepth depth;
@@ -433,17 +423,13 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
gsk_gpu_device_maybe_gc (priv->device);
gsk_gpu_renderer_make_current (self);
depth = gsk_render_node_get_preferred_depth (root);
frame = gsk_gpu_renderer_get_frame (self);
scale = gsk_gpu_renderer_get_scale (self);
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gsk_gpu_frame_begin (frame, priv->context, depth, region, opaque);
gsk_gpu_frame_begin (frame, priv->context, depth, region);
gsk_gpu_renderer_make_current (self);
backbuffer = GSK_GPU_RENDERER_GET_CLASS (self)->get_backbuffer (self);
@@ -465,6 +451,8 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
gsk_gpu_frame_end (frame, priv->context);
gsk_gpu_device_queue_gc (priv->device);
g_clear_pointer (&render_region, cairo_region_destroy);
}
static double
-6
View File
@@ -29,14 +29,8 @@ typedef enum {
GSK_GPU_IMAGE_FILTERABLE = (1 << 6),
GSK_GPU_IMAGE_RENDERABLE = (1 << 7),
GSK_GPU_IMAGE_SRGB = (1 << 8),
GSK_GPU_IMAGE_NARROW_RANGE = (1 << 9),
GSK_GPU_IMAGE_BT601 = (1 << 10),
GSK_GPU_IMAGE_BT709 = (2 << 10),
GSK_GPU_IMAGE_BT2020 = (3 << 10),
} GskGpuImageFlags;
#define GSK_GPU_IMAGE_YUV (GSK_GPU_IMAGE_BT2020)
typedef enum {
GSK_GPU_SAMPLER_DEFAULT,
GSK_GPU_SAMPLER_TRANSPARENT,
+6 -5
View File
@@ -45,10 +45,13 @@ gsk_ngl_renderer_create_context (GskGpuRenderer *renderer,
{
GdkGLContext *context;
if (!gdk_display_prepare_gl (display, error))
return NULL;
if (surface)
context = gdk_surface_create_gl_context (surface, error);
else
context = gdk_display_create_gl_context (display, error);
context = gdk_gl_context_new (display, surface, surface != NULL);
if (context == NULL)
return NULL;
/* GLES 2 is not supported */
gdk_gl_context_set_required_version (context, 3, 0);
@@ -139,8 +142,6 @@ gsk_ngl_renderer_unrealize (GskRenderer *renderer)
gsk_ngl_renderer_free_backbuffer (self);
gdk_gl_context_clear_current ();
GSK_RENDERER_CLASS (gsk_ngl_renderer_parent_class)->unrealize (renderer);
}
+1 -1
View File
@@ -76,7 +76,7 @@ gsk_vulkan_handle_result (VkResult res,
{
if (res != VK_SUCCESS)
{
g_warning ("%s(): %s (%d)", called_function, gdk_vulkan_strerror (res), res);
GSK_DEBUG (VULKAN, "%s(): %s (%d)", called_function, gdk_vulkan_strerror (res), res);
}
return res;
}
+5 -8
View File
@@ -148,16 +148,15 @@ gsk_vulkan_frame_cleanup (GskGpuFrame *frame)
}
static void
gsk_vulkan_frame_begin (GskGpuFrame *frame,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
gsk_vulkan_frame_begin (GskGpuFrame *frame,
GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
{
GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
gdk_vulkan_context_set_draw_semaphore (GDK_VULKAN_CONTEXT (context), self->vk_acquire_semaphore);
GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->begin (frame, context, depth, region, opaque);
GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->begin (frame, context, depth, region);
}
static GskGpuImage *
@@ -188,7 +187,6 @@ gsk_vulkan_frame_upload_texture (GskGpuFrame *frame,
image = gsk_vulkan_image_new_for_dmabuf (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
gdk_texture_get_color_state (texture),
&dmabuf,
gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_PREMULTIPLIED);
@@ -211,7 +209,6 @@ gsk_vulkan_frame_upload_texture (GskGpuFrame *frame,
image = gsk_vulkan_image_new_for_dmabuf (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
gdk_texture_get_color_state (texture),
gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_PREMULTIPLIED);
if (image)
+10 -33
View File
@@ -844,7 +844,6 @@ GskGpuImage *
gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
gsize width,
gsize height,
GdkColorState *color_state,
const GdkDmabuf *dmabuf,
gboolean premultiplied)
{
@@ -860,7 +859,6 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
GdkMemoryFormat format;
GskGpuImageFlags flags;
gboolean is_yuv;
const GdkCicp *cicp;
if (!gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_DMABUF))
{
@@ -970,36 +968,13 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
return NULL;
}
if (is_yuv)
flags |= GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
flags |= GSK_GPU_IMAGE_STRAIGHT_ALPHA;
if (!gsk_component_mapping_is_framebuffer_compatible (&vk_components))
flags |= GSK_GPU_IMAGE_NO_BLIT;
cicp = gdk_color_state_get_cicp (color_state);
switch (cicp->matrix_coefficients)
{
case 1:
flags |= GSK_GPU_IMAGE_BT709;
break;
case 5:
case 6:
flags |= GSK_GPU_IMAGE_BT601;
break;
case 9:
flags |= GSK_GPU_IMAGE_BT2020;
break;
default:
break;
}
if (cicp->range == GDK_CICP_RANGE_NARROW)
flags |= GSK_GPU_IMAGE_NARROW_RANGE;
gsk_gpu_image_setup (GSK_GPU_IMAGE (self), flags, format, width, height);
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
flags |
(gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0) |
(is_yuv ? (GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT) : 0) |
(gsk_component_mapping_is_framebuffer_compatible (&vk_components) ? 0 : GSK_GPU_IMAGE_NO_BLIT),
format,
width, height);
self->allocator = gsk_vulkan_device_get_external_allocator (device);
gsk_vulkan_allocator_ref (self->allocator);
@@ -1201,7 +1176,8 @@ gsk_vulkan_image_get_n_planes (GskVulkanImage *self,
}
GdkTexture *
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state)
{
GskGpuImage *image = GSK_GPU_IMAGE (self);
GdkDmabufTextureBuilder *builder;
@@ -1251,6 +1227,7 @@ gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gdk_dmabuf_texture_builder_set_display (builder, gsk_gpu_device_get_display (GSK_GPU_DEVICE (self->device)));
gdk_dmabuf_texture_builder_set_width (builder, gsk_gpu_image_get_width (image));
gdk_dmabuf_texture_builder_set_height (builder, gsk_gpu_image_get_height (image));
gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
gdk_dmabuf_texture_builder_set_fourcc (builder, fourcc);
gdk_dmabuf_texture_builder_set_modifier (builder, properties.drmFormatModifier);
gdk_dmabuf_texture_builder_set_premultiplied (builder, !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA));
+2 -2
View File
@@ -42,10 +42,10 @@ GskGpuImage * gsk_vulkan_image_new_dmabuf (GskVulk
GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
gsize width,
gsize height,
GdkColorState *color_state,
const GdkDmabuf *dmabuf,
gboolean premultiplied);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state);
#endif
guchar * gsk_vulkan_image_get_data (GskVulkanImage *self,
-97
View File
@@ -14,8 +14,6 @@ PASS(2) vec2 _tex_coord;
PASS_FLAT(3) float _opacity;
PASS_FLAT(4) uint _transfer_function;
PASS_FLAT(5) mat3 _mat;
PASS_FLAT(8) mat3 _yuv;
PASS_FLAT(11) uint _range;
#ifdef GSK_VERTEX_SHADER
@@ -24,8 +22,6 @@ IN(1) vec4 in_tex_rect;
IN(2) float in_opacity;
IN(3) uint in_color_primaries;
IN(4) uint in_transfer_function;
IN(5) uint in_matrix_coefficients;
IN(6) uint in_range;
const mat3 identity = mat3(
@@ -94,42 +90,6 @@ const mat3 xyz_to_p3 = mat3(
-0.4027108, 0.0236247, 0.9568845
);
const mat3 rgb_to_bt601 = mat3(
0.299000, -0.168736, 0.500000,
0.587000, -0.331264, -0.418688,
0.114000, 0.500000, -0.081312
);
const mat3 bt601_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
0.000000, -0.344136, 1.772000,
1.402000, -0.714136, 0.000000
);
const mat3 rgb_to_bt709 = mat3(
0.212600, -0.114572, 0.500000,
0.715200, -0.385428, -0.454153,
0.072200, 0.500000, -0.045847
);
const mat3 bt709_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
0.000000, -0.187324, 1.855600,
1.574800, -0.468124, -0.000000
);
const mat3 rgb_to_bt2020 = mat3(
0.262700, -0.139630, 0.500000,
0.678000, -0.360370, -0.459786,
0.059300, 0.500000, -0.040214
);
const mat3 bt2020_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
-0.000000, -0.164553, 1.881400,
1.474600, -0.571353, -0.000000
);
mat3
cicp_to_xyz (uint cp)
{
@@ -161,34 +121,6 @@ cicp_from_xyz (uint cp)
}
mat3
yuv_to_rgb (uint mc)
{
switch (mc)
{
case 0u: return identity;
case 1u: return bt709_to_rgb;
case 5u:
case 6u: return bt601_to_rgb;
case 9u: return bt2020_to_rgb;
}
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
}
mat3
rgb_to_yuv (uint mc)
{
switch (mc)
{
case 0u: return identity;
case 1u: return rgb_to_bt709;
case 5u:
case 6u: return rgb_to_bt601;
case 9u: return rgb_to_bt2020;
}
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
}
void
run (out vec2 pos)
{
@@ -201,7 +133,6 @@ run (out vec2 pos)
_tex_coord = rect_get_coord (rect_from_gsk (in_tex_rect), pos);
_opacity = in_opacity;
_transfer_function = in_transfer_function;
_range = in_range;
if (HAS_VARIATION (VARIATION_REVERSE))
{
@@ -210,8 +141,6 @@ run (out vec2 pos)
_mat = cicp_from_xyz (in_color_primaries) * srgb_to_xyz;
else
_mat = cicp_from_xyz (in_color_primaries) * rec2020_to_xyz;
_yuv = rgb_to_yuv (in_matrix_coefficients);
}
else
{
@@ -220,8 +149,6 @@ run (out vec2 pos)
_mat = xyz_to_srgb * cicp_to_xyz (in_color_primaries);
else
_mat = xyz_to_rec2020 * cicp_to_xyz (in_color_primaries);
_yuv = yuv_to_rgb (in_matrix_coefficients);
}
}
@@ -402,18 +329,6 @@ convert_color_from_cicp (vec4 color,
if (from_premul)
color = color_unpremultiply (color);
if (_range == 0u)
{
color.r = (color.r - 16.0/255.0) * 255.0/219.0;
color.g = (color.g - 16.0/255.0) * 255.0/224.0;
color.b = (color.b - 16.0/255.0) * 255.0/224.0;
}
color.g -= 0.5;
color.b -= 0.5;
color.rgb = _yuv * color.rgb;
color.rgb = apply_cicp_eotf (color.rgb, _transfer_function);
color.rgb = _mat * color.rgb;
color.rgb = apply_oetf (color.rgb, to);
@@ -437,18 +352,6 @@ convert_color_to_cicp (vec4 color,
color.rgb = _mat * color.rgb;
color.rgb = apply_cicp_oetf (color.rgb, _transfer_function);
color.rgb = _yuv * color.rgb;
color.g += 0.5;
color.b += 0.5;
if (_range == 0u)
{
color.r = color.r * 219.0/255.0 + 16.0/255.0;
color.g = color.g * 224.0/255.0 + 16.0/255.0;
color.b = color.b * 224.0/255.0 + 16.0/255.0;
}
if (to_premul)
color = color_premultiply (color);
+2 -3
View File
@@ -23,7 +23,6 @@
#include "config.h"
#include "gskcairoblurprivate.h"
#include "gdkcairoprivate.h"
#include "gdkcairoprivate.h"
@@ -378,7 +377,7 @@ cairo_t *
gsk_cairo_blur_finish_drawing (cairo_t *cr,
GdkColorState *ccs,
float radius,
const GdkColor *color,
const GdkRGBA *color,
GskBlurFlags blur_flags)
{
cairo_t *original_cr;
@@ -398,7 +397,7 @@ gsk_cairo_blur_finish_drawing (cairo_t *cr,
gsk_cairo_blur_surface (surface, x_scale * radius, blur_flags);
gdk_cairo_set_source_color (original_cr, ccs, color);
gdk_cairo_set_source_rgba_ccs (original_cr, ccs, color);
if (blur_flags & GSK_BLUR_REPEAT)
mask_surface_repeat (original_cr, surface);
else
+2 -3
View File
@@ -25,7 +25,6 @@
#include <gdk/gdk.h>
#include <cairo.h>
#include "gdkcolorprivate.h"
G_BEGIN_DECLS
@@ -38,7 +37,7 @@ typedef enum {
void gsk_cairo_blur_surface (cairo_surface_t *surface,
double radius,
GskBlurFlags flags);
GskBlurFlags flags);
int gsk_cairo_blur_compute_pixels (double radius) G_GNUC_CONST;
cairo_t * gsk_cairo_blur_start_drawing (cairo_t *cr,
@@ -47,7 +46,7 @@ cairo_t * gsk_cairo_blur_start_drawing (cairo_t *cr,
cairo_t * gsk_cairo_blur_finish_drawing (cairo_t *cr,
GdkColorState *ccs,
float radius,
const GdkColor *color,
const GdkRGBA *color,
GskBlurFlags blur_flags);
G_END_DECLS
+3 -11
View File
@@ -159,18 +159,10 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
const cairo_region_t *region)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
graphene_rect_t opaque_tmp;
const graphene_rect_t *opaque;
cairo_t *cr;
if (gsk_render_node_get_opaque_rect (root, &opaque_tmp))
opaque = &opaque_tmp;
else
opaque = NULL;
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->cairo_context),
GDK_MEMORY_U8,
region,
opaque);
gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->cairo_context),
region);
cr = gdk_cairo_context_cairo_create (self->cairo_context);
g_return_if_fail (cr != NULL);
@@ -196,7 +188,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
cairo_destroy (cr);
gdk_draw_context_end_frame_full (GDK_DRAW_CONTEXT (self->cairo_context));
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->cairo_context));
}
static void
-1
View File
@@ -15,7 +15,6 @@ static const GdkDebugKey gsk_debug_keys[] = {
{ "staging", GSK_DEBUG_STAGING, "Use a staging image for texture upload (Vulkan only)" },
{ "offload-disable", GSK_DEBUG_OFFLOAD_DISABLE, "Disable graphics offload" },
{ "cairo", GSK_DEBUG_CAIRO, "Overlay error pattern over Cairo drawing (finds fallbacks)" },
{ "occlusion", GSK_DEBUG_OCCLUSION, "Overlay highlight over areas optimized via occlusion culling" },
};
static guint gsk_debug_flags;
-1
View File
@@ -18,7 +18,6 @@ typedef enum {
GSK_DEBUG_STAGING = 1 << 10,
GSK_DEBUG_OFFLOAD_DISABLE = 1 << 11,
GSK_DEBUG_CAIRO = 1 << 12,
GSK_DEBUG_OCCLUSION = 1 << 13,
} GskDebugFlags;
#define GSK_DEBUG_ANY ((1 << 13) - 1)
-12
View File
@@ -5,8 +5,6 @@
#include <graphene.h>
#include <math.h>
#define GSK_RECT_INIT_CAIRO(cairo_rect) GRAPHENE_RECT_INIT((cairo_rect)->x, (cairo_rect)->y, (cairo_rect)->width, (cairo_rect)->height)
static inline void
gsk_rect_init (graphene_rect_t *r,
float x,
@@ -187,16 +185,6 @@ gsk_rect_to_cairo_grow (const graphene_rect_t *graphene,
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
}
static inline void
gsk_rect_to_cairo_shrink (const graphene_rect_t *graphene,
cairo_rectangle_int_t *cairo)
{
cairo->x = ceilf (graphene->origin.x);
cairo->y = ceilf (graphene->origin.y);
cairo->width = floorf (graphene->origin.x + graphene->size.width) - cairo->x;
cairo->height = floorf (graphene->origin.y + graphene->size.height) - cairo->y;
}
static inline gboolean
gsk_rect_equal (const graphene_rect_t *r1,
const graphene_rect_t *r2)
+2 -2
View File
@@ -380,7 +380,7 @@ gsk_render_node_draw_ccs (GskRenderNode *node,
GdkColorState *ccs)
{
/* Check that the calling function did pass a correct color state */
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs));
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs, FALSE));
cairo_save (cr);
@@ -413,7 +413,7 @@ gsk_render_node_draw_with_color_state (GskRenderNode *node,
{
GdkColorState *ccs;
ccs = gdk_color_state_get_rendering_color_state (color_state);
ccs = gdk_color_state_get_rendering_color_state (color_state, FALSE);
if (gdk_color_state_equal (color_state, ccs))
{
+1 -1
View File
@@ -124,7 +124,7 @@ void gsk_render_node_get_bounds (GskRenderNode
GDK_AVAILABLE_IN_4_16
gboolean gsk_render_node_get_opaque_rect (GskRenderNode *self,
graphene_rect_t *out_opaque) G_GNUC_WARN_UNUSED_RESULT;
graphene_rect_t *out_opaque);
GDK_AVAILABLE_IN_ALL
void gsk_render_node_draw (GskRenderNode *node,
+95 -434
View File
@@ -61,11 +61,6 @@
*/
#define MAX_RECTS_IN_DIFF 30
/* This lock protects all on-demand created legacy rgba data of
* render nodes.
*/
G_LOCK_DEFINE_STATIC (rgba);
static gboolean
gsk_color_stops_are_opaque (const GskColorStop *stops,
gsize n_stops)
@@ -101,7 +96,7 @@ color_state_is_hdr (GdkColorState *color_state)
{
GdkColorState *rendering_cs;
rendering_cs = gdk_color_state_get_rendering_color_state (color_state);
rendering_cs = gdk_color_state_get_rendering_color_state (color_state, FALSE);
return rendering_cs != GDK_COLOR_STATE_SRGB &&
rendering_cs != GDK_COLOR_STATE_SRGB_LINEAR;
@@ -1455,28 +1450,13 @@ struct _GskBorderNode
bool uniform_color: 1;
GskRoundedRect outline;
float border_width[4];
GdkColor border_color[4];
GdkRGBA *border_rgba;
GdkRGBA border_color[4];
};
static void
gsk_border_node_finalize (GskRenderNode *node)
{
GskBorderNode *self = (GskBorderNode *) node;
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_BORDER_NODE));
for (int i = 0; i < 4; i++)
gdk_color_finish (&self->border_color[i]);
g_free (self->border_rgba);
parent_class->finalize (node);
}
static void
gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
GdkColorState *ccs,
const GdkColor *color,
const GdkRGBA *rgba,
double x0,
double y0,
double x1,
@@ -1486,19 +1466,18 @@ gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
double x3,
double y3)
{
float values[4];
gdk_color_to_float (color, ccs, values);
float color[4];
gdk_color_state_from_rgba (ccs, rgba, color);
cairo_mesh_pattern_begin_patch (pattern);
cairo_mesh_pattern_move_to (pattern, x0, y0);
cairo_mesh_pattern_line_to (pattern, x1, y1);
cairo_mesh_pattern_line_to (pattern, x2, y2);
cairo_mesh_pattern_line_to (pattern, x3, y3);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, values[0], values[1], values[2], values[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, values[0], values[1], values[2], values[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, values[0], values[1], values[2], values[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, values[0], values[1], values[2], values[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, color[0], color[1], color[2], color[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, color[0], color[1], color[2], color[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, color[0], color[1], color[2], color[3]);
cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, color[0], color[1], color[2], color[3]);
cairo_mesh_pattern_end_patch (pattern);
}
@@ -1521,11 +1500,11 @@ gsk_border_node_draw (GskRenderNode *node,
gsk_rounded_rect_path (&self->outline, cr);
gsk_rounded_rect_path (&inside, cr);
if (gdk_color_equal (&self->border_color[0], &self->border_color[1]) &&
gdk_color_equal (&self->border_color[0], &self->border_color[2]) &&
gdk_color_equal (&self->border_color[0], &self->border_color[3]))
if (gdk_rgba_equal (&self->border_color[0], &self->border_color[1]) &&
gdk_rgba_equal (&self->border_color[0], &self->border_color[2]) &&
gdk_rgba_equal (&self->border_color[0], &self->border_color[3]))
{
gdk_cairo_set_source_color (cr, ccs, &self->border_color[0]);
gdk_cairo_set_source_rgba_ccs (cr, ccs, &self->border_color[0]);
}
else
{
@@ -1633,7 +1612,7 @@ gsk_border_node_diff (GskRenderNode *node1,
uniform2 &&
self1->border_width[0] == self2->border_width[0] &&
gsk_rounded_rect_equal (&self1->outline, &self2->outline) &&
gdk_color_equal (&self1->border_color[0], &self2->border_color[0]))
gdk_rgba_equal (&self1->border_color[0], &self2->border_color[0]))
return;
/* Different uniformity -> diff impossible */
@@ -1647,10 +1626,10 @@ gsk_border_node_diff (GskRenderNode *node1,
self1->border_width[1] == self2->border_width[1] &&
self1->border_width[2] == self2->border_width[2] &&
self1->border_width[3] == self2->border_width[3] &&
gdk_color_equal (&self1->border_color[0], &self2->border_color[0]) &&
gdk_color_equal (&self1->border_color[1], &self2->border_color[1]) &&
gdk_color_equal (&self1->border_color[2], &self2->border_color[2]) &&
gdk_color_equal (&self1->border_color[3], &self2->border_color[3]) &&
gdk_rgba_equal (&self1->border_color[0], &self2->border_color[0]) &&
gdk_rgba_equal (&self1->border_color[1], &self2->border_color[1]) &&
gdk_rgba_equal (&self1->border_color[2], &self2->border_color[2]) &&
gdk_rgba_equal (&self1->border_color[3], &self2->border_color[3]) &&
gsk_rounded_rect_equal (&self1->outline, &self2->outline))
return;
@@ -1665,7 +1644,6 @@ gsk_border_node_class_init (gpointer g_class,
node_class->node_type = GSK_BORDER_NODE;
node_class->finalize = gsk_border_node_finalize;
node_class->draw = gsk_border_node_draw;
node_class->diff = gsk_border_node_diff;
}
@@ -1716,23 +1694,9 @@ gsk_border_node_get_widths (const GskRenderNode *node)
const GdkRGBA *
gsk_border_node_get_colors (const GskRenderNode *node)
{
GskBorderNode *self = (GskBorderNode *) node;
const GdkRGBA *colors;
const GskBorderNode *self = (const GskBorderNode *) node;
G_LOCK (rgba);
if (self->border_rgba == NULL)
{
self->border_rgba = g_new (GdkRGBA, 4);
for (int i = 0; i < 4; i++)
gdk_color_to_float (&self->border_color[i], GDK_COLOR_STATE_SRGB, (float *) &self->border_rgba[i]);
}
colors = self->border_rgba;
G_UNLOCK (rgba);
return colors;
return self->border_color;
}
/**
@@ -1754,37 +1718,6 @@ GskRenderNode *
gsk_border_node_new (const GskRoundedRect *outline,
const float border_width[4],
const GdkRGBA border_color[4])
{
GdkColor color[4];
for (int i = 0; i < 4; i++)
gdk_color_init_from_rgba (&color[i], &border_color[i]);
return gsk_border_node_new2 (outline, border_width, color);
for (int i = 0; i < 4; i++)
gdk_color_finish (&color[i]);
}
/*< private >
* gsk_border_node_new2:
* @outline: a `GskRoundedRect` describing the outline of the border
* @border_width: (array fixed-size=4): the stroke width of the border on
* the top, right, bottom and left side respectively.
* @border_color: (array fixed-size=4): the color used on the top, right,
* bottom and left side.
*
* Creates a `GskRenderNode` that will stroke a border rectangle inside the
* given @outline.
*
* The 4 sides of the border can have different widths and colors.
*
* Returns: (transfer full) (type GskBorderNode): A new `GskRenderNode`
*/
GskRenderNode *
gsk_border_node_new2 (const GskRoundedRect *outline,
const float border_width[4],
const GdkColor border_color[4])
{
GskBorderNode *self;
GskRenderNode *node;
@@ -1797,16 +1730,14 @@ gsk_border_node_new2 (const GskRoundedRect *outline,
node = (GskRenderNode *) self;
node->offscreen_for_opacity = FALSE;
node->preferred_depth = gdk_memory_depth_merge (
gdk_memory_depth_merge (gdk_color_get_depth (&border_color[0]),
gdk_color_get_depth (&border_color[1])),
gdk_memory_depth_merge (gdk_color_get_depth (&border_color[2]),
gdk_color_get_depth (&border_color[3])));
gdk_memory_depth_merge (my_color_get_depth (&border_color[0]),
my_color_get_depth (&border_color[1])),
gdk_memory_depth_merge (my_color_get_depth (&border_color[2]),
my_color_get_depth (&border_color[3])));
gsk_rounded_rect_init_copy (&self->outline, outline);
memcpy (self->border_width, border_width, sizeof (self->border_width));
memcpy (self->border_color, border_color, sizeof (self->border_color));
for (int i = 0; i < 4; i++)
gdk_color_init_copy (&self->border_color[i], &border_color[i]);
if (border_width[0] == border_width[1] &&
border_width[0] == border_width[2] &&
@@ -1815,9 +1746,9 @@ gsk_border_node_new2 (const GskRoundedRect *outline,
else
self->uniform_width = FALSE;
if (gdk_color_equal (&border_color[0], &border_color[1]) &&
gdk_color_equal (&border_color[0], &border_color[2]) &&
gdk_color_equal (&border_color[0], &border_color[3]))
if (gdk_rgba_equal (&border_color[0], &border_color[1]) &&
gdk_rgba_equal (&border_color[0], &border_color[2]) &&
gdk_rgba_equal (&border_color[0], &border_color[3]))
self->uniform_color = TRUE;
else
self->uniform_color = FALSE;
@@ -1827,23 +1758,7 @@ gsk_border_node_new2 (const GskRoundedRect *outline,
return node;
}
/*< private >
* gsk_border_node_get_colors2:
* @node: (type GskBorderNode): a `GskRenderNode` for a border
*
* Retrieves the colors of the border.
*
* Returns: (transfer none): an array of 4 `GdkColor` structs
* for the top, right, bottom and left color of the border
*/
const GdkColor *
gsk_border_node_get_colors2 (const GskRenderNode *node)
{
const GskBorderNode *self = (const GskBorderNode *) node;
return self->border_color;
}
/* Private */
bool
gsk_border_node_get_uniform (const GskRenderNode *self)
{
@@ -2323,23 +2238,13 @@ struct _GskInsetShadowNode
GskRenderNode render_node;
GskRoundedRect outline;
GdkColor color;
graphene_point_t offset;
GdkRGBA color;
float dx;
float dy;
float spread;
float blur_radius;
};
static void
gsk_inset_shadow_node_finalize (GskRenderNode *node)
{
GskInsetShadowNode *self = (GskInsetShadowNode *) node;
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_INSET_SHADOW_NODE));
gdk_color_finish (&self->color);
parent_class->finalize (node);
}
static gboolean
has_empty_clip (cairo_t *cr)
{
@@ -2356,7 +2261,7 @@ draw_shadow (cairo_t *cr,
const GskRoundedRect *box,
const GskRoundedRect *clip_box,
float radius,
const GdkColor *color,
const GdkRGBA *color,
GskBlurFlags blur_flags)
{
cairo_t *shadow_cr;
@@ -2364,7 +2269,7 @@ draw_shadow (cairo_t *cr,
if (has_empty_clip (cr))
return;
gdk_cairo_set_source_color (cr, ccs, color);
gdk_cairo_set_source_rgba_ccs (cr, ccs, color);
shadow_cr = gsk_cairo_blur_start_drawing (cr, radius, blur_flags);
cairo_set_fill_rule (shadow_cr, CAIRO_FILL_RULE_EVEN_ODD);
@@ -2414,7 +2319,7 @@ draw_shadow_corner (cairo_t *cr,
const GskRoundedRect *box,
const GskRoundedRect *clip_box,
float radius,
const GdkColor *color,
const GdkRGBA *color,
GskCorner corner,
cairo_rectangle_int_t *drawn_rect)
{
@@ -2538,7 +2443,7 @@ draw_shadow_corner (cairo_t *cr,
g_hash_table_insert (corner_mask_cache, g_memdup2 (&key, sizeof (key)), mask);
}
gdk_cairo_set_source_color (cr, ccs, color);
gdk_cairo_set_source_rgba_ccs (cr, ccs, color);
pattern = cairo_pattern_create_for_surface (mask);
cairo_matrix_init_identity (&matrix);
cairo_matrix_scale (&matrix, sx, sy);
@@ -2555,7 +2460,7 @@ draw_shadow_side (cairo_t *cr,
const GskRoundedRect *box,
const GskRoundedRect *clip_box,
float radius,
const GdkColor *color,
const GdkRGBA *color,
Side side,
cairo_rectangle_int_t *drawn_rect)
{
@@ -2632,7 +2537,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
double blur_radius;
/* We don't need to draw invisible shadows */
if (gdk_color_is_clear (&self->color))
if (gdk_rgba_is_clear (&self->color))
return;
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
@@ -2649,16 +2554,14 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
cairo_clip (cr);
gsk_rounded_rect_init_copy (&box, &self->outline);
gsk_rounded_rect_offset (&box, self->offset.x, self->offset.y);
gsk_rounded_rect_offset (&box, self->dx, self->dy);
gsk_rounded_rect_shrink (&box, self->spread, self->spread, self->spread, self->spread);
gsk_rounded_rect_init_copy (&clip_box, &self->outline);
gsk_rounded_rect_shrink (&clip_box, -clip_radius, -clip_radius, -clip_radius, -clip_radius);
if (!needs_blur (blur_radius))
{
draw_shadow (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE);
}
draw_shadow (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE);
else
{
cairo_region_t *remaining;
@@ -2730,8 +2633,9 @@ gsk_inset_shadow_node_diff (GskRenderNode *node1,
GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2;
if (gsk_rounded_rect_equal (&self1->outline, &self2->outline) &&
gdk_color_equal (&self1->color, &self2->color) &&
graphene_point_equal (&self1->offset, &self2->offset) &&
gdk_rgba_equal (&self1->color, &self2->color) &&
self1->dx == self2->dx &&
self1->dy == self2->dy &&
self1->spread == self2->spread &&
self1->blur_radius == self2->blur_radius)
return;
@@ -2747,7 +2651,6 @@ gsk_inset_shadow_node_class_init (gpointer g_class,
node_class->node_type = GSK_INSET_SHADOW_NODE;
node_class->finalize = gsk_inset_shadow_node_finalize;
node_class->draw = gsk_inset_shadow_node_draw;
node_class->diff = gsk_inset_shadow_node_diff;
}
@@ -2773,56 +2676,23 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
float dy,
float spread,
float blur_radius)
{
GdkColor color2;
GskRenderNode *node;
gdk_color_init_from_rgba (&color2, color);
node = gsk_inset_shadow_node_new2 (outline,
&color2,
&GRAPHENE_POINT_INIT (dx, dy),
spread, blur_radius);
gdk_color_finish (&color2);
return node;
}
/*< private >
* gsk_inset_shadow_node_new2:
* @outline: outline of the region containing the shadow
* @color: color of the shadow
* @offset: offset of shadow
* @spread: how far the shadow spreads towards the inside
* @blur_radius: how much blur to apply to the shadow
*
* Creates a `GskRenderNode` that will render an inset shadow
* into the box given by @outline.
*
* Returns: (transfer full) (type GskInsetShadowNode): A new `GskRenderNode`
*/
GskRenderNode *
gsk_inset_shadow_node_new2 (const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius)
{
GskInsetShadowNode *self;
GskRenderNode *node;
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (offset != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
node = (GskRenderNode *) self;
node->offscreen_for_opacity = FALSE;
node->preferred_depth = gdk_color_get_depth (color);
node->preferred_depth = my_color_get_depth (color);
gsk_rounded_rect_init_copy (&self->outline, outline);
gdk_color_init_copy (&self->color, color);
self->offset = *offset;
self->color = *color;
self->dx = dx;
self->dy = dy;
self->spread = spread;
self->blur_radius = blur_radius;
@@ -2853,9 +2723,6 @@ gsk_inset_shadow_node_get_outline (const GskRenderNode *node)
*
* Retrieves the color of the inset shadow.
*
* The value returned by this function will not be correct
* if the render node was created for a non-sRGB color.
*
* Returns: (transfer none): the color of the shadow
*/
const GdkRGBA *
@@ -2863,23 +2730,6 @@ gsk_inset_shadow_node_get_color (const GskRenderNode *node)
{
const GskInsetShadowNode *self = (const GskInsetShadowNode *) node;
/* NOTE: This is only correct for nodes with sRGB colors */
return (const GdkRGBA *) &self->color.values;
}
/*< private >
* gsk_inset_shadow_node_get_color2:
* @node: (type GskInsetShadowNode): a `GskRenderNode`
*
* Retrieves the color of the given @node.
*
* Returns: (transfer none): the color of the node
*/
const GdkColor *
gsk_inset_shadow_node_get_color2 (const GskRenderNode *node)
{
const GskInsetShadowNode *self = (const GskInsetShadowNode *) node;
return &self->color;
}
@@ -2896,7 +2746,7 @@ gsk_inset_shadow_node_get_dx (const GskRenderNode *node)
{
const GskInsetShadowNode *self = (const GskInsetShadowNode *) node;
return self->offset.x;
return self->dx;
}
/**
@@ -2912,23 +2762,7 @@ gsk_inset_shadow_node_get_dy (const GskRenderNode *node)
{
const GskInsetShadowNode *self = (const GskInsetShadowNode *) node;
return self->offset.y;
}
/**
* gsk_inset_shadow_node_get_offset:
* @node: (type GskInsetShadowNode): a `GskRenderNode` for an inset shadow
*
* Retrieves the offset of the inset shadow.
*
* Returns: an offset, in pixels
**/
const graphene_point_t *
gsk_inset_shadow_node_get_offset (const GskRenderNode *node)
{
const GskInsetShadowNode *self = (const GskInsetShadowNode *) node;
return &self->offset;
return self->dy;
}
/**
@@ -2976,23 +2810,13 @@ struct _GskOutsetShadowNode
GskRenderNode render_node;
GskRoundedRect outline;
GdkColor color;
graphene_point_t offset;
GdkRGBA color;
float dx;
float dy;
float spread;
float blur_radius;
};
static void
gsk_outset_shadow_node_finalize (GskRenderNode *node)
{
GskInsetShadowNode *self = (GskInsetShadowNode *) node;
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_OUTSET_SHADOW_NODE));
gdk_color_finish (&self->color);
parent_class->finalize (node);
}
static void
gsk_outset_shadow_get_extents (GskOutsetShadowNode *self,
float *top,
@@ -3003,10 +2827,10 @@ gsk_outset_shadow_get_extents (GskOutsetShadowNode *self,
float clip_radius;
clip_radius = gsk_cairo_blur_compute_pixels (ceil (self->blur_radius / 2.0));
*top = MAX (0, ceil (clip_radius + self->spread - self->offset.y));
*right = MAX (0, ceil (clip_radius + self->spread + self->offset.x));
*bottom = MAX (0, ceil (clip_radius + self->spread + self->offset.y));
*left = MAX (0, ceil (clip_radius + self->spread - self->offset.x));
*top = MAX (0, ceil (clip_radius + self->spread - self->dy));
*right = MAX (0, ceil (clip_radius + self->spread + self->dx));
*bottom = MAX (0, ceil (clip_radius + self->spread + self->dy));
*left = MAX (0, ceil (clip_radius + self->spread - self->dx));
}
static void
@@ -3022,7 +2846,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
double blur_radius;
/* We don't need to draw invisible shadows */
if (gdk_color_is_clear (&self->color))
if (gdk_rgba_is_clear (&self->color))
return;
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
@@ -3046,13 +2870,11 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
cairo_clip (cr);
gsk_rounded_rect_init_copy (&box, &self->outline);
gsk_rounded_rect_offset (&box, self->offset.x, self->offset.y);
gsk_rounded_rect_offset (&box, self->dx, self->dy);
gsk_rounded_rect_shrink (&box, -self->spread, -self->spread, -self->spread, -self->spread);
if (!needs_blur (blur_radius))
{
draw_shadow (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE);
}
draw_shadow (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE);
else
{
int i;
@@ -3126,8 +2948,9 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2;
if (gsk_rounded_rect_equal (&self1->outline, &self2->outline) &&
gdk_color_equal (&self1->color, &self2->color) &&
graphene_point_equal (&self1->offset, &self2->offset) &&
gdk_rgba_equal (&self1->color, &self2->color) &&
self1->dx == self2->dx &&
self1->dy == self2->dy &&
self1->spread == self2->spread &&
self1->blur_radius == self2->blur_radius)
return;
@@ -3143,7 +2966,6 @@ gsk_outset_shadow_node_class_init (gpointer g_class,
node_class->node_type = GSK_OUTSET_SHADOW_NODE;
node_class->finalize = gsk_outset_shadow_node_finalize;
node_class->draw = gsk_outset_shadow_node_draw;
node_class->diff = gsk_outset_shadow_node_diff;
}
@@ -3169,39 +2991,6 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
float dy,
float spread,
float blur_radius)
{
GdkColor color2;
GskRenderNode *node;
gdk_color_init_from_rgba (&color2, color);
node = gsk_outset_shadow_node_new2 (outline,
&color2,
&GRAPHENE_POINT_INIT (dx, dy),
spread, blur_radius);
gdk_color_finish (&color2);
return node;
}
/*< private >
* gsk_outset_shadow_node_new2:
* @outline: outline of the region surrounded by shadow
* @color: color of the shadow
* @offset: offset of shadow
* @spread: how far the shadow spreads towards the inside
* @blur_radius: how much blur to apply to the shadow
*
* Creates a `GskRenderNode` that will render an outset shadow
* around the box given by @outline.
*
* Returns: (transfer full) (type GskOutsetShadowNode): A new `GskRenderNode`
*/
GskRenderNode *
gsk_outset_shadow_node_new2 (const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius)
{
GskOutsetShadowNode *self;
GskRenderNode *node;
@@ -3214,11 +3003,12 @@ gsk_outset_shadow_node_new2 (const GskRoundedRect *outline,
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
node = (GskRenderNode *) self;
node->offscreen_for_opacity = FALSE;
node->preferred_depth = gdk_color_get_depth (color);
node->preferred_depth = my_color_get_depth (color);
gsk_rounded_rect_init_copy (&self->outline, outline);
gdk_color_init_copy (&self->color, color);
self->offset = *offset;
self->color = *color;
self->dx = dx;
self->dy = dy;
self->spread = spread;
self->blur_radius = blur_radius;
@@ -3255,9 +3045,6 @@ gsk_outset_shadow_node_get_outline (const GskRenderNode *node)
*
* Retrieves the color of the outset shadow.
*
* The value returned by this function will not be correct
* if the render node was created for a non-sRGB color.
*
* Returns: (transfer none): a color
*/
const GdkRGBA *
@@ -3265,23 +3052,6 @@ gsk_outset_shadow_node_get_color (const GskRenderNode *node)
{
const GskOutsetShadowNode *self = (const GskOutsetShadowNode *) node;
/* NOTE: This is only correct for nodes with sRGB colors */
return (const GdkRGBA *) &self->color.values;
}
/*< private >
* gsk_color_node_get_color2:
* @node: (type GskOutsetShadowNode): a `GskRenderNode`
*
* Retrieves the color of the given @node.
*
* Returns: (transfer none): the color of the node
*/
const GdkColor *
gsk_outset_shadow_node_get_color2 (const GskRenderNode *node)
{
const GskOutsetShadowNode *self = (const GskOutsetShadowNode *) node;
return &self->color;
}
@@ -3298,7 +3068,7 @@ gsk_outset_shadow_node_get_dx (const GskRenderNode *node)
{
const GskOutsetShadowNode *self = (const GskOutsetShadowNode *) node;
return self->offset.x;
return self->dx;
}
/**
@@ -3314,23 +3084,7 @@ gsk_outset_shadow_node_get_dy (const GskRenderNode *node)
{
const GskOutsetShadowNode *self = (const GskOutsetShadowNode *) node;
return self->offset.y;
}
/**
* gsk_outset_shadow_node_get_offset:
* @node: (type GskOutsetShadowNode): a `GskRenderNode` for an outset shadow
*
* Retrieves the offset of the outset shadow.
*
* Returns: an offset, in pixels
**/
const graphene_point_t *
gsk_outset_shadow_node_get_offset (const GskRenderNode *node)
{
const GskOutsetShadowNode *self = (const GskOutsetShadowNode *) node;
return &self->offset;
return self->dy;
}
/**
@@ -5589,9 +5343,7 @@ struct _GskShadowNode
GskRenderNode *child;
gsize n_shadows;
GskShadow2 *shadows;
GskShadow *rgba_shadows;
GskShadow *shadows;
};
static void
@@ -5601,13 +5353,8 @@ gsk_shadow_node_finalize (GskRenderNode *node)
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_SHADOW_NODE));
gsk_render_node_unref (self->child);
for (gsize i = 0; i < self->n_shadows; i++)
gdk_color_finish (&self->shadows[i].color);
g_free (self->shadows);
g_free (self->rgba_shadows);
parent_class->finalize (node);
}
@@ -5627,23 +5374,23 @@ gsk_shadow_node_draw (GskRenderNode *node,
for (i = 0; i < self->n_shadows; i++)
{
GskShadow2 *shadow = &self->shadows[i];
GskShadow *shadow = &self->shadows[i];
cairo_pattern_t *pattern;
/* We don't need to draw invisible shadows */
if (gdk_color_is_clear (&shadow->color))
if (gdk_rgba_is_clear (&shadow->color))
continue;
cairo_save (cr);
cr = gsk_cairo_blur_start_drawing (cr, 0.5 * shadow->radius, GSK_BLUR_X | GSK_BLUR_Y);
cairo_save (cr);
cairo_translate (cr, shadow->offset.x, shadow->offset.y);
cairo_translate (cr, shadow->dx, shadow->dy);
cairo_push_group (cr);
gsk_render_node_draw_ccs (self->child, cr, ccs);
pattern = cairo_pop_group (cr);
cairo_reset_clip (cr);
gdk_cairo_set_source_color (cr, ccs, &shadow->color);
gdk_cairo_set_source_rgba_ccs (cr, ccs, &shadow->color);
cairo_mask (cr, pattern);
cairo_pattern_destroy (pattern);
cairo_restore (cr);
@@ -5675,12 +5422,13 @@ gsk_shadow_node_diff (GskRenderNode *node1,
for (i = 0; i < self1->n_shadows; i++)
{
GskShadow2 *shadow1 = &self1->shadows[i];
GskShadow2 *shadow2 = &self2->shadows[i];
GskShadow *shadow1 = &self1->shadows[i];
GskShadow *shadow2 = &self2->shadows[i];
float clip_radius;
if (!gdk_color_equal (&shadow1->color, &shadow2->color) ||
!graphene_point_equal (&shadow1->offset, &shadow2->offset) ||
if (!gdk_rgba_equal (&shadow1->color, &shadow2->color) ||
shadow1->dx != shadow2->dx ||
shadow1->dy != shadow2->dy ||
shadow1->radius != shadow2->radius)
{
gsk_render_node_diff_impossible (node1, node2, data);
@@ -5688,10 +5436,10 @@ gsk_shadow_node_diff (GskRenderNode *node1,
}
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius / 2.0);
top = MAX (top, ceil (clip_radius - shadow1->offset.y));
right = MAX (right, ceil (clip_radius + shadow1->offset.x));
bottom = MAX (bottom, ceil (clip_radius + shadow1->offset.y));
left = MAX (left, ceil (clip_radius - shadow1->offset.x));
top = MAX (top, ceil (clip_radius - shadow1->dy));
right = MAX (right, ceil (clip_radius + shadow1->dx));
bottom = MAX (bottom, ceil (clip_radius + shadow1->dy));
left = MAX (left, ceil (clip_radius - shadow1->dx));
}
sub = cairo_region_create ();
@@ -5722,10 +5470,10 @@ gsk_shadow_node_get_bounds (GskShadowNode *self,
for (i = 0; i < self->n_shadows; i++)
{
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius / 2.0);
top = MAX (top, clip_radius - self->shadows[i].offset.y);
right = MAX (right, clip_radius + self->shadows[i].offset.x);
bottom = MAX (bottom, clip_radius + self->shadows[i].offset.y);
left = MAX (left, clip_radius - self->shadows[i].offset.x);
top = MAX (top, clip_radius - self->shadows[i].dy);
right = MAX (right, clip_radius + self->shadows[i].dx);
bottom = MAX (bottom, clip_radius + self->shadows[i].dy);
left = MAX (left, clip_radius - self->shadows[i].dx);
}
bounds->origin.x -= left;
@@ -5762,52 +5510,10 @@ GskRenderNode *
gsk_shadow_node_new (GskRenderNode *child,
const GskShadow *shadows,
gsize n_shadows)
{
GskShadow2 *shadows2;
GskRenderNode *node;
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
g_return_val_if_fail (shadows != NULL, NULL);
g_return_val_if_fail (n_shadows > 0, NULL);
shadows2 = g_new (GskShadow2, n_shadows);
for (gsize i = 0; i < n_shadows; i++)
{
gdk_color_init_from_rgba (&shadows2[i].color, &shadows[i].color);
graphene_point_init (&shadows2[i].offset, shadows[i].dx, shadows[i].dy);
shadows2[i].radius = shadows[i].radius;
}
node = gsk_shadow_node_new2 (child, shadows2, n_shadows);
for (gsize i = 0; i < n_shadows; i++)
gdk_color_finish (&shadows2[i].color);
g_free (shadows2);
return node;
}
/*< private >
* gsk_shadow_node_new2:
* @child: The node to draw
* @shadows: (array length=n_shadows): The shadows to apply
* @n_shadows: number of entries in the @shadows array
*
* Creates a `GskRenderNode` that will draw a @child with the given
* @shadows below it.
*
* Returns: (transfer full) (type GskShadowNode): A new `GskRenderNode`
*/
GskRenderNode *
gsk_shadow_node_new2 (GskRenderNode *child,
const GskShadow2 *shadows,
gsize n_shadows)
{
GskShadowNode *self;
GskRenderNode *node;
gsize i;
GdkMemoryDepth depth;
gboolean is_hdr;
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
g_return_val_if_fail (shadows != NULL, NULL);
@@ -5819,25 +5525,19 @@ gsk_shadow_node_new2 (GskRenderNode *child,
self->child = gsk_render_node_ref (child);
self->n_shadows = n_shadows;
self->shadows = g_new (GskShadow2, n_shadows);
depth = gsk_render_node_get_preferred_depth (child);
is_hdr = gsk_render_node_is_hdr (child);
for (i = 0; i < n_shadows; i++)
{
gdk_color_init_copy (&self->shadows[i].color, &shadows[i].color);
graphene_point_init_from_point (&self->shadows[i].offset, &shadows[i].offset);
self->shadows[i].radius = shadows[i].radius;
depth = gdk_memory_depth_merge (depth, gdk_color_get_depth (&shadows[i].color));
is_hdr = is_hdr || color_state_is_hdr (shadows[i].color.color_state);
}
node->preferred_depth = depth;
node->is_hdr = is_hdr;
self->shadows = g_malloc_n (n_shadows, sizeof (GskShadow));
memcpy (self->shadows, shadows, n_shadows * sizeof (GskShadow));
gsk_shadow_node_get_bounds (self, &node->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
for (i = 0; i < n_shadows; i++)
{
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
my_color_get_depth (&shadows->color));
}
return node;
}
@@ -5869,45 +5569,6 @@ gsk_shadow_node_get_child (const GskRenderNode *node)
const GskShadow *
gsk_shadow_node_get_shadow (const GskRenderNode *node,
gsize i)
{
GskShadowNode *self = (GskShadowNode *) node;
const GskShadow *shadow;
G_LOCK (rgba);
if (self->rgba_shadows == NULL)
{
self->rgba_shadows = g_new (GskShadow, self->n_shadows);
for (gsize j = 0; j < self->n_shadows; j++)
{
gdk_color_to_float (&self->shadows[j].color,
GDK_COLOR_STATE_SRGB,
(float *) &self->rgba_shadows[j].color);
self->rgba_shadows[j].dx = self->shadows[j].offset.x;
self->rgba_shadows[j].dy = self->shadows[j].offset.y;
self->rgba_shadows[j].radius = self->shadows[j].radius;
}
}
shadow = &self->rgba_shadows[i];
G_UNLOCK (rgba);
return shadow;
}
/*< private >
* gsk_shadow_node_get_shadow2:
* @node: (type GskShadowNode): a shadow `GskRenderNode`
* @i: the given index
*
* Retrieves the shadow data at the given index @i.
*
* Returns: (transfer none): the shadow data
*/
const GskShadow2 *
gsk_shadow_node_get_shadow2 (const GskRenderNode *node,
gsize i)
{
const GskShadowNode *self = (const GskShadowNode *) node;
+124 -167
View File
@@ -41,7 +41,6 @@
#include "gtk/css/gtkcssdataurlprivate.h"
#include "gtk/css/gtkcssparserprivate.h"
#include "gtk/css/gtkcssserializerprivate.h"
#include "gdk/loaders/gdkavifprivate.h"
#ifdef CAIRO_HAS_SCRIPT_SURFACE
#include <cairo-script.h>
@@ -217,19 +216,11 @@ parse_texture (GtkCssParser *parser,
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
{
GBytes *bytes;
char *mimetype;
bytes = gtk_css_data_url_parse (url, &mimetype, &error);
bytes = gtk_css_data_url_parse (url, NULL, &error);
if (bytes)
{
#ifdef HAVE_AVIF
if (strcmp (mimetype, "image/avif") == 0)
texture = gdk_load_avif (bytes, &error);
else
#endif
texture = gdk_texture_new_from_bytes (bytes, &error);
g_free (mimetype);
texture = gdk_texture_new_from_bytes (bytes, &error);
g_bytes_unref (bytes);
}
else
@@ -702,9 +693,33 @@ parse_float4 (GtkCssParser *parser,
return TRUE;
}
static gboolean parse_color2 (GtkCssParser *parser,
Context *context,
gpointer color);
static gboolean
parse_colors4 (GtkCssParser *parser,
Context *context,
gpointer out_colors)
{
GdkRGBA colors[4];
int i;
for (i = 0; i < 4 && !gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF); i ++)
{
if (!gdk_rgba_parser_parse (parser, &colors[i]))
return FALSE;
}
if (i == 0)
{
gtk_css_parser_error_syntax (parser, "Expected a color");
return FALSE;
}
for (; i < 4; i++)
{
colors[i] = colors[(i - 1) >> 1];
}
memcpy (out_colors, colors, sizeof (GdkRGBA) * 4);
return TRUE;
}
static gboolean
parse_shadows (GtkCssParser *parser,
@@ -715,11 +730,10 @@ parse_shadows (GtkCssParser *parser,
do
{
GskShadow2 shadow;
GdkColor color = GDK_COLOR_SRGB (0, 0, 0, 1);
GskShadow shadow = { GDK_RGBA("000000"), 0, 0, 0 };
double dx = 0, dy = 0, radius = 0;
if (!parse_color2 (parser, context, &color))
if (!gdk_rgba_parser_parse (parser, &shadow.color))
gtk_css_parser_error_value (parser, "Expected shadow color");
if (!gtk_css_parser_consume_number (parser, &dx))
@@ -734,13 +748,11 @@ parse_shadows (GtkCssParser *parser,
gtk_css_parser_error_value (parser, "Expected shadow blur radius");
}
gdk_color_init_copy (&shadow.color, &color);
graphene_point_init (&shadow.offset, dx, dy);
shadow.dx = dx;
shadow.dy = dy;
shadow.radius = radius;
g_array_append_val (shadows, shadow);
gdk_color_finish (&color);
}
while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
@@ -750,15 +762,7 @@ parse_shadows (GtkCssParser *parser,
static void
clear_shadows (gpointer inout_shadows)
{
GArray *shadows = inout_shadows;
for (gsize i = 0; i < shadows->len; i++)
{
GskShadow2 *shadow = &g_array_index (shadows, GskShadow2, i);
gdk_color_finish (&shadow->color);
}
g_array_set_size (shadows, 0);
g_array_set_size (inout_shadows, 0);
}
static const struct
@@ -1461,6 +1465,12 @@ create_default_path (void)
return gsk_path_builder_free_to_path (builder);
}
typedef struct
{
GdkColorState *color_state;
float values[4];
} Color;
static gboolean
parse_cicp_range (GtkCssParser *parser,
Context *context,
@@ -1596,6 +1606,35 @@ parse_color_state (GtkCssParser *parser,
return TRUE;
}
static gboolean
gtk_css_parser_consume_number_or_percentage (GtkCssParser *parser,
double min,
double max,
double *value)
{
if (gtk_css_parser_has_percentage (parser))
{
double number;
gtk_css_parser_consume_percentage (parser, &number);
*value = min + (number / 100.0) * (max - min);
return TRUE;
}
else if (gtk_css_parser_has_number (parser))
{
double number;
gtk_css_parser_consume_number (parser, &number);
*value = number;
return TRUE;
}
else
{
gtk_css_parser_error_syntax (parser, "Expected a number or percentage");
return FALSE;
}
}
typedef struct {
Context *context;
GdkColor *color;
@@ -1666,34 +1705,6 @@ parse_color2 (GtkCssParser *parser,
return FALSE;
}
static gboolean
parse_colors4 (GtkCssParser *parser,
Context *context,
gpointer out_colors)
{
GdkColor colors[4];
int i;
for (i = 0; i < 4 && !gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF); i ++)
{
if (!parse_color2 (parser, context, &colors[i]))
return FALSE;
}
if (i == 0)
{
gtk_css_parser_error_syntax (parser, "Expected a color");
return FALSE;
}
for (; i < 4; i++)
{
colors[i] = colors[(i - 1) >> 1];
}
memcpy (out_colors, colors, sizeof (GdkColor) * 4);
return TRUE;
}
static GskRenderNode *
parse_color_node (GtkCssParser *parser,
Context *context)
@@ -1867,25 +1878,20 @@ parse_inset_shadow_node (GtkCssParser *parser,
Context *context)
{
GskRoundedRect outline = GSK_ROUNDED_RECT_INIT (0, 0, 50, 50);
GdkColor color = GDK_COLOR_SRGB (0, 0, 0, 1);
GdkRGBA color = GDK_RGBA("000000");
double dx = 1, dy = 1, blur = 0, spread = 0;
const Declaration declarations[] = {
{ "outline", parse_rounded_rect, NULL, &outline },
{ "color", parse_color2, NULL, &color },
{ "color", parse_color, NULL, &color },
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_positive_double, NULL, &blur }
};
GskRenderNode *node;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
node = gsk_inset_shadow_node_new2 (&outline, &color, &GRAPHENE_POINT_INIT (dx, dy), spread, blur);
gdk_color_finish (&color);
return node;
return gsk_inset_shadow_node_new (&outline, &color, dx, dy, spread, blur);
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
@@ -2167,21 +2173,16 @@ parse_border_node (GtkCssParser *parser,
{
GskRoundedRect outline = GSK_ROUNDED_RECT_INIT (0, 0, 50, 50);
float widths[4] = { 1, 1, 1, 1 };
GdkColor colors[4] = {
GDK_COLOR_SRGB (0, 0, 0, 1),
GDK_COLOR_SRGB (0, 0, 0, 1),
GDK_COLOR_SRGB (0, 0, 0, 1),
GDK_COLOR_SRGB (0, 0, 0, 1),
};
GdkRGBA colors[4] = { GDK_RGBA("000"), GDK_RGBA("000"), GDK_RGBA("000"), GDK_RGBA("000") };
const Declaration declarations[] = {
{ "outline", parse_rounded_rect, NULL, &outline },
{ "widths", parse_float4, NULL, &widths },
{ "colors", parse_colors4, NULL, &colors },
{ "colors", parse_colors4, NULL, &colors }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
return gsk_border_node_new2 (&outline, widths, colors);
return gsk_border_node_new (&outline, widths, colors);
}
static GskRenderNode *
@@ -2281,25 +2282,20 @@ parse_outset_shadow_node (GtkCssParser *parser,
Context *context)
{
GskRoundedRect outline = GSK_ROUNDED_RECT_INIT (0, 0, 50, 50);
GdkColor color = GDK_COLOR_SRGB (0, 0, 0, 1);
GdkRGBA color = GDK_RGBA("000000");
double dx = 1, dy = 1, blur = 0, spread = 0;
const Declaration declarations[] = {
{ "outline", parse_rounded_rect, NULL, &outline },
{ "color", parse_color2, NULL, &color },
{ "color", parse_color, NULL, &color },
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_positive_double, NULL, &blur }
};
GskRenderNode *node;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
node = gsk_outset_shadow_node_new2 (&outline, &color, &GRAPHENE_POINT_INIT (dx, dy), spread, blur);
gdk_color_finish (&color);
return node;
return gsk_outset_shadow_node_new (&outline, &color, dx, dy, spread, blur);
}
static GskRenderNode *
@@ -2924,10 +2920,10 @@ parse_shadow_node (GtkCssParser *parser,
Context *context)
{
GskRenderNode *child = NULL;
GArray *shadows = g_array_new (FALSE, TRUE, sizeof (GskShadow2));
GArray *shadows = g_array_new (FALSE, TRUE, sizeof (GskShadow));
const Declaration declarations[] = {
{ "child", parse_node, clear_node, &child },
{ "shadows", parse_shadows, clear_shadows, shadows },
{ "shadows", parse_shadows, clear_shadows, shadows }
};
GskRenderNode *result;
@@ -2937,13 +2933,12 @@ parse_shadow_node (GtkCssParser *parser,
if (shadows->len == 0)
{
GskShadow2 default_shadow = { GDK_COLOR_SRGB (0, 0, 0, 1), GRAPHENE_POINT_INIT (1, 1), 0 };
GskShadow default_shadow = { GDK_RGBA("000000"), 1, 1, 0 };
g_array_append_val (shadows, default_shadow);
}
result = gsk_shadow_node_new2 (child, (GskShadow2 *)shadows->data, shadows->len);
result = gsk_shadow_node_new (child, (GskShadow *)shadows->data, shadows->len);
clear_shadows (shadows);
g_array_free (shadows, TRUE);
gsk_render_node_unref (child);
@@ -3316,28 +3311,15 @@ printer_init_duplicates_for_node (Printer *printer,
printer_init_check_color_state (printer, gsk_color_node_get_color2 (node)->color_state);
break;
case GSK_BORDER_NODE:
{
const GdkColor *colors = gsk_border_node_get_colors2 (node);
for (int i = 0; i < 4; i++)
printer_init_check_color_state (printer, colors[i].color_state);
}
break;
case GSK_INSET_SHADOW_NODE:
printer_init_check_color_state (printer, gsk_inset_shadow_node_get_color2 (node)->color_state);
break;
case GSK_OUTSET_SHADOW_NODE:
printer_init_check_color_state (printer, gsk_outset_shadow_node_get_color2 (node)->color_state);
break;
case GSK_CAIRO_NODE:
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
case GSK_CONIC_GRADIENT_NODE:
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
/* no children */
break;
@@ -3379,11 +3361,6 @@ printer_init_duplicates_for_node (Printer *printer,
case GSK_SHADOW_NODE:
printer_init_duplicates_for_node (printer, gsk_shadow_node_get_child (node));
for (int i = 0; i < gsk_shadow_node_get_n_shadows (node); i++)
{
const GskShadow2 * shadow = gsk_shadow_node_get_shadow2 (node, i);
printer_init_check_color_state (printer, shadow->color.color_state);
}
break;
case GSK_DEBUG_NODE:
@@ -3931,27 +3908,12 @@ base64_encode_with_linebreaks (const guchar *data,
return out;
}
#ifdef HAVE_AVIF
static gboolean
texture_should_use_avif (GdkTexture *texture)
{
GdkColorState *color_state;
const GdkCicp *cicp;
color_state = gdk_texture_get_color_state (texture);
cicp = gdk_color_state_get_cicp (color_state);
return cicp->matrix_coefficients != 0;
}
#endif
static void
append_texture_param (Printer *p,
const char *param_name,
GdkTexture *texture)
{
GBytes *bytes;
const char *mimetype;
char *b64;
const char *texture_name;
@@ -3980,38 +3942,26 @@ append_texture_param (Printer *p,
g_hash_table_insert (p->named_textures, texture, new_name);
}
#ifdef HAVE_AVIF
if (texture_should_use_avif (texture))
switch (gdk_texture_get_depth (texture))
{
bytes = gdk_save_avif (texture);
mimetype = "image/avif";
case GDK_MEMORY_U8:
case GDK_MEMORY_U8_SRGB:
case GDK_MEMORY_U16:
bytes = gdk_texture_save_to_png_bytes (texture);
g_string_append (p->str, "url(\"data:image/png;base64,\\\n");
break;
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
bytes = gdk_texture_save_to_tiff_bytes (texture);
g_string_append (p->str, "url(\"data:image/tiff;base64,\\\n");
break;
case GDK_MEMORY_NONE:
case GDK_N_DEPTHS:
default:
g_assert_not_reached ();
}
else
#endif
{
switch (gdk_texture_get_depth (texture))
{
case GDK_MEMORY_U8:
case GDK_MEMORY_U8_SRGB:
case GDK_MEMORY_U16:
bytes = gdk_texture_save_to_png_bytes (texture);
mimetype = "image/png";
break;
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
bytes = gdk_texture_save_to_tiff_bytes (texture);
mimetype = "image/tiff";
break;
case GDK_MEMORY_NONE:
case GDK_N_DEPTHS:
default:
g_assert_not_reached ();
}
}
g_string_append_printf (p->str, "url(\"data:%s;base64,\\\n", mimetype);
b64 = base64_encode_with_linebreaks (g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
@@ -4372,11 +4322,13 @@ render_node_print (Printer *p,
case GSK_OUTSET_SHADOW_NODE:
{
const GdkRGBA *color = gsk_outset_shadow_node_get_color (node);
start_node (p, "outset-shadow", node_name);
append_float_param (p, "blur", gsk_outset_shadow_node_get_blur_radius (node), 0.0f);
if (!gdk_color_equal (gsk_outset_shadow_node_get_color2 (node), &GDK_COLOR_SRGB (0, 0, 0, 1)))
append_color_param (p, "color", gsk_outset_shadow_node_get_color2 (node));
if (!gdk_rgba_equal (color, &GDK_RGBA("000")))
append_rgba_param (p, "color", color);
append_float_param (p, "dx", gsk_outset_shadow_node_get_dx (node), 1.0f);
append_float_param (p, "dy", gsk_outset_shadow_node_get_dy (node), 1.0f);
append_rounded_rect_param (p, "outline", gsk_outset_shadow_node_get_outline (node));
@@ -4474,18 +4426,18 @@ render_node_print (Printer *p,
case GSK_BORDER_NODE:
{
const GdkColor *colors = gsk_border_node_get_colors2 (node);
const GdkRGBA *colors = gsk_border_node_get_colors (node);
const float *widths = gsk_border_node_get_widths (node);
guint i, n;
start_node (p, "border", node_name);
if (!gdk_color_equal (&colors[3], &colors[1]))
if (!gdk_rgba_equal (&colors[3], &colors[1]))
n = 4;
else if (!gdk_color_equal (&colors[2], &colors[0]))
else if (!gdk_rgba_equal (&colors[2], &colors[0]))
n = 3;
else if (!gdk_color_equal (&colors[1], &colors[0]))
else if (!gdk_rgba_equal (&colors[1], &colors[0]))
n = 2;
else if (!gdk_color_equal (&colors[0], (&(GdkColor) { .color_state = GDK_COLOR_STATE_SRGB, .values = { 0, 0, 0, 1 } })))
else if (!gdk_rgba_equal (&colors[0], &GDK_RGBA("000000")))
n = 1;
else
n = 0;
@@ -4498,7 +4450,7 @@ render_node_print (Printer *p,
{
if (i > 0)
g_string_append_c (p->str, ' ');
print_color (p, &colors[i]);
gdk_rgba_print (&colors[i], p->str);
}
g_string_append (p->str, ";\n");
}
@@ -4544,21 +4496,25 @@ render_node_print (Printer *p,
g_string_append (p->str, "shadows: ");
for (i = 0; i < n_shadows; i ++)
{
const GskShadow2 *s = gsk_shadow_node_get_shadow2 (node, i);
const GskShadow *s = gsk_shadow_node_get_shadow (node, i);
char *color;
if (i > 0)
g_string_append (p->str, ", ");
print_color (p, &s->color);
color = gdk_rgba_to_string (&s->color);
g_string_append (p->str, color);
g_string_append_c (p->str, ' ');
string_append_double (p->str, s->offset.x);
string_append_double (p->str, s->dx);
g_string_append_c (p->str, ' ');
string_append_double (p->str, s->offset.y);
string_append_double (p->str, s->dy);
if (s->radius > 0)
{
g_string_append_c (p->str, ' ');
string_append_double (p->str, s->radius);
}
g_free (color);
}
g_string_append_c (p->str, ';');
@@ -4571,11 +4527,12 @@ render_node_print (Printer *p,
case GSK_INSET_SHADOW_NODE:
{
const GdkRGBA *color = gsk_inset_shadow_node_get_color (node);
start_node (p, "inset-shadow", node_name);
append_float_param (p, "blur", gsk_inset_shadow_node_get_blur_radius (node), 0.0f);
if (!gdk_color_equal (gsk_inset_shadow_node_get_color2 (node), &GDK_COLOR_SRGB (0, 0, 0, 1)))
append_color_param (p, "color", gsk_inset_shadow_node_get_color2 (node));
if (!gdk_rgba_equal (color, &GDK_RGBA("000")))
append_rgba_param (p, "color", color);
append_float_param (p, "dx", gsk_inset_shadow_node_get_dx (node), 1.0f);
append_float_param (p, "dy", gsk_inset_shadow_node_get_dy (node), 1.0f);
append_rounded_rect_param (p, "outline", gsk_inset_shadow_node_get_outline (node));
+3 -40
View File
@@ -123,47 +123,10 @@ _gsk_render_node_ref (GskRenderNode *node)
return node;
}
GskRenderNode * gsk_color_node_new2 (const GdkColor *color,
const graphene_rect_t *bounds);
const GdkColor * gsk_color_node_get_color2 (const GskRenderNode *node);
GskRenderNode * gsk_border_node_new2 (const GskRoundedRect *outline,
const float border_width[4],
const GdkColor border_color[4]);
const GdkColor * gsk_border_node_get_colors2 (const GskRenderNode *node);
GskRenderNode * gsk_inset_shadow_node_new2 (const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius);
const GdkColor * gsk_inset_shadow_node_get_color2 (const GskRenderNode *node);
const graphene_point_t *gsk_inset_shadow_node_get_offset (const GskRenderNode *node);
GskRenderNode * gsk_outset_shadow_node_new2 (const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius);
const GdkColor * gsk_outset_shadow_node_get_color2 (const GskRenderNode *node);
const graphene_point_t *gsk_outset_shadow_node_get_offset (const GskRenderNode *node);
typedef struct _GskShadow2 GskShadow2;
struct _GskShadow2
{
GdkColor color;
graphene_point_t offset;
float radius;
};
GskRenderNode * gsk_shadow_node_new2 (GskRenderNode *child,
const GskShadow2 *shadows,
gsize n_shadows);
const GskShadow2 *gsk_shadow_node_get_shadow2 (const GskRenderNode *node,
gsize i);
GskRenderNode * gsk_color_node_new2 (const GdkColor *color,
const graphene_rect_t *bounds);
const GdkColor* gsk_color_node_get_color2 (const GskRenderNode *node);
G_END_DECLS
-29
View File
@@ -1290,35 +1290,6 @@ gtk_css_parser_consume_percentage (GtkCssParser *self,
return FALSE;
}
gboolean
gtk_css_parser_consume_number_or_percentage (GtkCssParser *parser,
double min,
double max,
double *value)
{
double number = 0;
if (gtk_css_parser_has_percentage (parser))
{
if (gtk_css_parser_consume_percentage (parser, &number))
{
*value = min + (number / 100.0) * (max - min);
return TRUE;
}
}
else if (gtk_css_parser_has_number (parser))
{
if (gtk_css_parser_consume_number (parser, &number))
{
*value = number;
return TRUE;
}
}
gtk_css_parser_error_syntax (parser, "Expected a number or percentage");
return FALSE;
}
gsize
gtk_css_parser_consume_any (GtkCssParser *parser,
const GtkCssParseOption *options,
-5
View File
@@ -154,11 +154,6 @@ gboolean gtk_css_parser_consume_integer (GtkCssParser
int *number);
gboolean gtk_css_parser_consume_percentage (GtkCssParser *self,
double *number);
gboolean gtk_css_parser_consume_number_or_percentage
(GtkCssParser *parser,
double min,
double max,
double *value);
gboolean gtk_css_parser_consume_function (GtkCssParser *self,
guint min_args,
guint max_args,
+48 -64
View File
@@ -594,7 +594,7 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *value,
{
guint i;
double dx, dy, spread, radius;
GdkColor color;
const GdkRGBA *color;
g_return_if_fail (value->class == &GTK_CSS_VALUE_SHADOW);
@@ -605,14 +605,11 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *value,
if (shadow->inset)
continue;
gtk_css_color_to_color (gtk_css_color_value_get_color (shadow->color), &color);
color = gtk_css_color_value_get_rgba (shadow->color);
/* We don't need to draw invisible shadows */
if (gdk_color_is_clear (&color))
{
gdk_color_finish (&color);
continue;
}
if (gdk_rgba_is_clear (color))
continue;
dx = gtk_css_number_value_get (shadow->hoffset, 0);
dy = gtk_css_number_value_get (shadow->voffset, 0);
@@ -621,11 +618,7 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *value,
if (value->is_filter)
radius = 2 * radius;
gtk_snapshot_append_outset_shadow2 (snapshot, border_box,
&color,
&GRAPHENE_POINT_INIT (dx, dy),
spread, radius);
gdk_color_finish (&color);
gtk_snapshot_append_outset_shadow (snapshot, border_box, color, dx, dy, spread, radius);
}
}
@@ -636,7 +629,7 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *value,
{
guint i;
double dx, dy, spread, radius;
GdkColor color;
const GdkRGBA *color;
g_return_if_fail (value->class == &GTK_CSS_VALUE_SHADOW);
@@ -647,14 +640,11 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *value,
if (!shadow->inset)
continue;
gtk_css_color_to_color (gtk_css_color_value_get_color (shadow->color), &color);
color = gtk_css_color_value_get_rgba (shadow->color);
/* We don't need to draw invisible shadows */
if (gdk_color_is_clear (&color))
{
gdk_color_finish (&color);
continue;
}
if (gdk_rgba_is_clear (color))
continue;
dx = gtk_css_number_value_get (shadow->hoffset, 0);
dy = gtk_css_number_value_get (shadow->voffset, 0);
@@ -673,58 +663,55 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *value,
{
const float y = dy > 0 ? dy : 0;
gtk_snapshot_append_color2 (snapshot, &color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y + y,
dx,
padding_bounds->size.height - ABS (dy)
));
gtk_snapshot_append_color (snapshot, color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y + y,
dx,
padding_bounds->size.height - ABS (dy)
));
}
else if (dx < 0)
{
const float y = dy > 0 ? dy : 0;
gtk_snapshot_append_color2 (snapshot, &color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x + padding_bounds->size.width + dx,
padding_bounds->origin.y + y,
- dx,
padding_bounds->size.height - ABS (dy)
));
gtk_snapshot_append_color (snapshot, color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x + padding_bounds->size.width + dx,
padding_bounds->origin.y + y,
- dx,
padding_bounds->size.height - ABS (dy)
));
}
if (dy > 0)
{
gtk_snapshot_append_color2 (snapshot, &color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y,
padding_bounds->size.width,
dy
));
gtk_snapshot_append_color (snapshot, color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y,
padding_bounds->size.width,
dy
));
}
else if (dy < 0)
{
gtk_snapshot_append_color2 (snapshot, &color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y + padding_bounds->size.height + dy,
padding_bounds->size.width,
- dy
));
gtk_snapshot_append_color (snapshot, color,
&GRAPHENE_RECT_INIT (
padding_bounds->origin.x,
padding_bounds->origin.y + padding_bounds->size.height + dy,
padding_bounds->size.width,
- dy
));
}
}
else
{
gtk_snapshot_append_inset_shadow2 (snapshot,
padding_box,
&color,
&GRAPHENE_POINT_INIT (dx, dy),
spread, radius);
gtk_snapshot_append_inset_shadow (snapshot,
padding_box,
color,
dx, dy, spread, radius);
}
gdk_color_finish (&color);
}
}
@@ -757,31 +744,28 @@ gboolean
gtk_css_shadow_value_push_snapshot (const GtkCssValue *value,
GtkSnapshot *snapshot)
{
GskShadow2 *shadows;
GskShadow *shadows;
guint i;
if (gtk_css_shadow_value_is_clear (value))
return FALSE;
shadows = g_newa (GskShadow2, value->n_shadows);
shadows = g_newa (GskShadow, value->n_shadows);
for (i = 0; i < value->n_shadows; i++)
{
const ShadowValue *shadow = &value->shadows[i];
gtk_css_color_to_color (gtk_css_color_value_get_color (shadow->color), &shadows[i].color);
graphene_point_init (&shadows[i].offset,
gtk_css_number_value_get (shadow->hoffset, 0),
gtk_css_number_value_get (shadow->voffset, 0));
shadows[i].color = *gtk_css_color_value_get_rgba (shadow->color);
shadows[i].dx = gtk_css_number_value_get (shadow->hoffset, 0);
shadows[i].dy = gtk_css_number_value_get (shadow->voffset, 0);
shadows[i].radius = gtk_css_number_value_get (shadow->radius, 0);
if (value->is_filter)
shadows[i].radius *= 2;
}
gtk_snapshot_push_shadow2 (snapshot, shadows, value->n_shadows);
for (i = 0; i < value->n_shadows; i++)
gdk_color_finish (&shadows[i].color);
gtk_snapshot_push_shadow (snapshot, shadows, value->n_shadows);
return TRUE;
}
+182
View File
@@ -304,3 +304,185 @@ gtk_native_queue_relayout (GtkNative *self)
gdk_surface_request_layout (surface);
}
static void
corner_rect (const GtkCssValue *value,
cairo_rectangle_int_t *rect)
{
rect->width = _gtk_css_corner_value_get_x (value, 100);
rect->height = _gtk_css_corner_value_get_y (value, 100);
}
static void
subtract_decoration_corners_from_region (cairo_region_t *region,
cairo_rectangle_int_t *extents,
const GtkCssStyle *style)
{
cairo_rectangle_int_t rect;
corner_rect (style->border->border_top_left_radius, &rect);
rect.x = extents->x;
rect.y = extents->y;
cairo_region_subtract_rectangle (region, &rect);
corner_rect (style->border->border_top_right_radius, &rect);
rect.x = extents->x + extents->width - rect.width;
rect.y = extents->y;
cairo_region_subtract_rectangle (region, &rect);
corner_rect (style->border->border_bottom_left_radius, &rect);
rect.x = extents->x;
rect.y = extents->y + extents->height - rect.height;
cairo_region_subtract_rectangle (region, &rect);
corner_rect (style->border->border_bottom_right_radius, &rect);
rect.x = extents->x + extents->width - rect.width;
rect.y = extents->y + extents->height - rect.height;
cairo_region_subtract_rectangle (region, &rect);
}
static int
get_translucent_border_edge (GtkCssValue *border_color,
GtkCssValue *border_width)
{
if (!gdk_rgba_is_opaque (gtk_css_color_value_get_rgba (border_color)))
return round (gtk_css_number_value_get (border_width, 100));
return 0;
}
static void
get_translucent_border_width (GtkWidget *widget,
GtkBorder *border)
{
GtkCssNode *css_node = gtk_widget_get_css_node (widget);
GtkCssStyle *style = gtk_css_node_get_style (css_node);
border->top = get_translucent_border_edge (style->used->border_top_color,
style->border->border_top_width);
border->bottom = get_translucent_border_edge (style->used->border_bottom_color,
style->border->border_bottom_width);
border->left = get_translucent_border_edge (style->used->border_left_color,
style->border->border_left_width);
border->right = get_translucent_border_edge (style->used->border_right_color,
style->border->border_right_width);
}
static gboolean
get_opaque_rect (GtkWidget *widget,
cairo_rectangle_int_t *rect)
{
gboolean is_opaque;
if (gtk_widget_get_opacity (widget) < 1)
is_opaque = FALSE;
else
{
GtkCssNode *node;
GtkCssStyle *style;
const GdkRGBA *color;
node = gtk_widget_get_css_node (widget);
style = gtk_css_node_get_style (node);
color = gtk_css_color_value_get_rgba (style->used->background_color);
is_opaque = gdk_rgba_is_opaque (color);
}
if (is_opaque)
{
const graphene_rect_t *border_rect;
GtkCssBoxes css_boxes;
GtkBorder border;
gtk_css_boxes_init (&css_boxes, widget);
border_rect = gtk_css_boxes_get_border_rect (&css_boxes);
get_translucent_border_width (widget, &border);
rect->x = border_rect->origin.x + border.left;
rect->y = border_rect->origin.y + border.top;
rect->width = border_rect->size.width - border.left - border.right;
rect->height = border_rect->size.height - border.top - border.bottom;
}
return is_opaque;
}
static void
get_shadow_width (GtkWidget *widget,
GtkBorder *shadow_width,
int resize_handle_size)
{
GtkCssNode *css_node = gtk_widget_get_css_node (widget);
const GtkCssStyle *style = gtk_css_node_get_style (css_node);
gtk_css_shadow_value_get_extents (style->used->box_shadow, shadow_width);
shadow_width->left = MAX (shadow_width->left, resize_handle_size);
shadow_width->top = MAX (shadow_width->top, resize_handle_size);
shadow_width->bottom = MAX (shadow_width->bottom, resize_handle_size);
shadow_width->right = MAX (shadow_width->right, resize_handle_size);
}
void
gtk_native_update_opaque_region (GtkNative *native,
GtkWidget *contents,
gboolean subtract_decoration_corners,
gboolean subtract_shadow,
int resize_handle_size)
{
cairo_rectangle_int_t rect;
cairo_region_t *opaque_region = NULL;
GdkSurface *surface;
GtkBorder shadow;
g_return_if_fail (GTK_IS_NATIVE (native));
g_return_if_fail (!contents || GTK_IS_WIDGET (contents));
if (contents == NULL)
contents = GTK_WIDGET (native);
if (!_gtk_widget_get_realized (GTK_WIDGET (native)) ||
!_gtk_widget_get_realized (contents))
return;
if (subtract_shadow)
get_shadow_width (contents, &shadow, resize_handle_size);
else
shadow = (GtkBorder) {0, 0, 0, 0};
surface = gtk_native_get_surface (native);
if (get_opaque_rect (contents, &rect))
{
double native_x, native_y;
gtk_native_get_surface_transform (native, &native_x, &native_y);
rect.x += native_x;
rect.y += native_y;
if (contents != GTK_WIDGET (native))
{
graphene_point_t p;
if (!gtk_widget_compute_point (contents, GTK_WIDGET (native),
&GRAPHENE_POINT_INIT (0, 0), &p))
graphene_point_init (&p, 0, 0);
rect.x += p.x;
rect.y += p.y;
}
opaque_region = cairo_region_create_rectangle (&rect);
if (subtract_decoration_corners)
{
GtkCssStyle *style;
style = gtk_css_node_get_style (gtk_widget_get_css_node (contents));
subtract_decoration_corners_from_region (opaque_region, &rect, style);
}
}
gdk_surface_set_opaque_region (surface, opaque_region);
cairo_region_destroy (opaque_region);
}
+5
View File
@@ -28,6 +28,11 @@ struct _GtkNativeInterface
};
void gtk_native_queue_relayout (GtkNative *native);
void gtk_native_update_opaque_region (GtkNative *native,
GtkWidget *contents,
gboolean subtract_decoration_corners,
gboolean subtract_shadow,
int resize_handle_size);
G_END_DECLS
+5
View File
@@ -1029,6 +1029,8 @@ gtk_popover_realize (GtkWidget *widget)
priv->renderer = gsk_renderer_new_for_surface (priv->surface);
gtk_native_realize (GTK_NATIVE (popover));
gtk_native_update_opaque_region (GTK_NATIVE (popover), priv->contents_widget, TRUE, TRUE, 0);
}
static void
@@ -1465,6 +1467,9 @@ gtk_popover_update_shape (GtkPopover *popover)
gdk_surface_set_input_region (priv->surface, region);
cairo_region_destroy (region);
}
if (_gtk_widget_get_realized (GTK_WIDGET (popover)))
gtk_native_update_opaque_region (GTK_NATIVE (popover), priv->contents_widget, TRUE, TRUE, 0);
}
static int
+73 -94
View File
@@ -37,9 +37,6 @@
#include "gtksnapshotprivate.h"
#include "gdk/gdkhslaprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdkcolorprivate.h"
#include "gdk/gdkcairoprivate.h"
#include "gsk/gskroundedrectprivate.h"
#include "gsk/gskrectprivate.h"
@@ -338,30 +335,27 @@ static void
snapshot_frame_fill (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const float border_width[4],
const GdkColor colors[4],
const GdkRGBA colors[4],
guint hidden_side)
{
if (hidden_side)
{
GdkColor real_colors[4];
GdkRGBA real_colors[4];
guint i;
for (i = 0; i < 4; i++)
{
if (hidden_side & (1 << i))
gdk_color_init_from_rgba (&real_colors[i], &GDK_RGBA_TRANSPARENT);
real_colors[i] = (GdkRGBA) { 0, 0, 0, 0 };
else
gdk_color_init_copy (&real_colors[i], &colors[i]);
real_colors[i] = colors[i];
}
snapshot_frame_fill (snapshot, outline, border_width, real_colors, 0);
for (i = 0; i < 4; i++)
gdk_color_finish (&real_colors[i]);
return;
}
gtk_snapshot_append_border2 (snapshot, outline, border_width, colors);
gtk_snapshot_append_border (snapshot, outline, border_width, colors);
}
static void
@@ -415,7 +409,7 @@ static void
render_frame_stroke (cairo_t *cr,
const GskRoundedRect *border_box,
const double border_width[4],
const GdkColor colors[4],
GdkRGBA colors[4],
guint hidden_side,
GtkBorderStyle stroke_style)
{
@@ -423,9 +417,9 @@ render_frame_stroke (cairo_t *cr,
GskRoundedRect stroke_box;
guint i;
different_colors = !gdk_color_equal (&colors[0], &colors[1]) ||
!gdk_color_equal (&colors[0], &colors[2]) ||
!gdk_color_equal (&colors[0], &colors[3]);
different_colors = !gdk_rgba_equal (&colors[0], &colors[1]) ||
!gdk_rgba_equal (&colors[0], &colors[2]) ||
!gdk_rgba_equal (&colors[0], &colors[3]);
different_borders = border_width[0] != border_width[1] ||
border_width[0] != border_width[2] ||
border_width[0] != border_width[3] ;
@@ -442,15 +436,14 @@ render_frame_stroke (cairo_t *cr,
double length = 0;
/* FAST PATH:
* Mostly expected to trigger for focus rectangles
*/
for (i = 0; i < 4; i++)
* Mostly expected to trigger for focus rectangles */
for (i = 0; i < 4; i++)
{
length += _gtk_rounded_box_guess_length (&stroke_box, i);
}
gsk_rounded_rect_path (&stroke_box, cr);
gdk_cairo_set_source_color (cr, GDK_COLOR_STATE_SRGB, &colors[0]);
gdk_cairo_set_source_rgba (cr, &colors[0]);
set_stroke_style (cr, border_width[0], stroke_style, length);
cairo_stroke (cr);
}
@@ -487,7 +480,7 @@ render_frame_stroke (cairo_t *cr,
_gtk_rounded_box_path_side (&stroke_box, cr, i);
gdk_cairo_set_source_color (cr, GDK_COLOR_STATE_SRGB, &colors[i]);
gdk_cairo_set_source_rgba (cr, &colors[i]);
set_stroke_style (cr,
border_width[i],
stroke_style,
@@ -503,38 +496,36 @@ static void
snapshot_frame_stroke (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const float border_width[4],
const GdkColor colors[4],
GdkRGBA colors[4],
guint hidden_side,
GtkBorderStyle stroke_style)
{
double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] };
cairo_t *cr;
cr = gtk_snapshot_append_cairo (snapshot, &outline->bounds);
cr = gtk_snapshot_append_cairo (snapshot,
&outline->bounds);
render_frame_stroke (cr, outline, double_width, colors, hidden_side, stroke_style);
cairo_destroy (cr);
}
static void
color_shade (const GdkColor *color,
double factor,
GdkColor *color_return)
color_shade (const GdkRGBA *color,
double factor,
GdkRGBA *color_return)
{
GdkRGBA rgba;
GdkHSLA hsla;
gdk_color_to_float (color, GDK_COLOR_STATE_SRGB, (float *) &rgba);
_gdk_hsla_init_from_rgba (&hsla, &rgba);
_gdk_hsla_init_from_rgba (&hsla, color);
_gdk_hsla_shade (&hsla, &hsla, factor);
_gdk_rgba_init_from_hsla (&rgba, &hsla);
gdk_color_from_rgba (color_return, color->color_state, &rgba);
_gdk_rgba_init_from_hsla (color_return, &hsla);
}
static void
snapshot_border (GtkSnapshot *snapshot,
const GskRoundedRect *border_box,
const float border_width[4],
GdkColor colors[4],
GdkRGBA colors[4],
GtkBorderStyle border_style[4])
{
guint hidden_side = 0;
@@ -594,12 +585,12 @@ snapshot_border (GtkSnapshot *snapshot,
hidden_side |= (1 << j);
else
dont_draw |= (1 << j);
other_border[j] = border_width[j] / 3;
}
snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw);
other_box = *border_box;
gsk_rounded_rect_shrink (&other_box,
2 * other_border[GTK_CSS_TOP],
@@ -613,7 +604,7 @@ snapshot_border (GtkSnapshot *snapshot,
case GTK_BORDER_STYLE_RIDGE:
{
GskRoundedRect other_box;
GdkColor other_colors[4];
GdkRGBA other_colors[4];
guint dont_draw = hidden_side;
float other_border[4];
@@ -631,9 +622,9 @@ snapshot_border (GtkSnapshot *snapshot,
dont_draw |= (1 << j);
other_border[j] = border_width[j] / 2;
}
snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw);
other_box = *border_box;
gsk_rounded_rect_shrink (&other_box,
other_border[GTK_CSS_TOP],
@@ -648,7 +639,7 @@ snapshot_border (GtkSnapshot *snapshot,
break;
}
}
snapshot_frame_fill (snapshot, border_box, border_width, colors, hidden_side);
}
@@ -684,7 +675,7 @@ gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
else
{
GtkBorderStyle border_style[4];
GdkColor colors[4];
GdkRGBA colors[4];
graphene_simd4f_t alpha_test_vector;
/* Optimize the most common case of "This widget has no border" */
@@ -692,54 +683,46 @@ gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
gtk_css_boxes_get_padding_rect (boxes)))
return;
gtk_css_color_to_color (gtk_css_color_value_get_color (style->used->border_top_color), &colors[0]);
gtk_css_color_to_color (gtk_css_color_value_get_color (style->used->border_right_color), &colors[1]);
gtk_css_color_to_color (gtk_css_color_value_get_color (style->used->border_bottom_color), &colors[2]);
gtk_css_color_to_color (gtk_css_color_value_get_color (style->used->border_left_color), &colors[3]);
colors[0] = *gtk_css_color_value_get_rgba (style->used->border_top_color);
colors[1] = *gtk_css_color_value_get_rgba (style->used->border_right_color);
colors[2] = *gtk_css_color_value_get_rgba (style->used->border_bottom_color);
colors[3] = *gtk_css_color_value_get_rgba (style->used->border_left_color);
alpha_test_vector = graphene_simd4f_init (colors[0].alpha,
colors[1].alpha,
colors[2].alpha,
colors[3].alpha);
if (!graphene_simd4f_is_zero4 (alpha_test_vector))
alpha_test_vector = graphene_simd4f_init (colors[0].alpha, colors[1].alpha, colors[2].alpha, colors[3].alpha);
if (graphene_simd4f_is_zero4 (alpha_test_vector))
return;
border_style[0] = _gtk_css_border_style_value_get (style->border->border_top_style);
border_style[1] = _gtk_css_border_style_value_get (style->border->border_right_style);
border_style[2] = _gtk_css_border_style_value_get (style->border->border_bottom_style);
border_style[3] = _gtk_css_border_style_value_get (style->border->border_left_style);
border_width[0] = gtk_css_number_value_get (style->border->border_top_width, 100);
border_width[1] = gtk_css_number_value_get (style->border->border_right_width, 100);
border_width[2] = gtk_css_number_value_get (style->border->border_bottom_width, 100);
border_width[3] = gtk_css_number_value_get (style->border->border_left_width, 100);
gtk_snapshot_push_debug (snapshot, "CSS border");
if (border_style[0] <= GTK_BORDER_STYLE_SOLID &&
border_style[1] <= GTK_BORDER_STYLE_SOLID &&
border_style[2] <= GTK_BORDER_STYLE_SOLID &&
border_style[3] <= GTK_BORDER_STYLE_SOLID)
{
border_style[0] = _gtk_css_border_style_value_get (style->border->border_top_style);
border_style[1] = _gtk_css_border_style_value_get (style->border->border_right_style);
border_style[2] = _gtk_css_border_style_value_get (style->border->border_bottom_style);
border_style[3] = _gtk_css_border_style_value_get (style->border->border_left_style);
border_width[0] = gtk_css_number_value_get (style->border->border_top_width, 100);
border_width[1] = gtk_css_number_value_get (style->border->border_right_width, 100);
border_width[2] = gtk_css_number_value_get (style->border->border_bottom_width, 100);
border_width[3] = gtk_css_number_value_get (style->border->border_left_width, 100);
gtk_snapshot_push_debug (snapshot, "CSS border");
if (border_style[0] <= GTK_BORDER_STYLE_SOLID &&
border_style[1] <= GTK_BORDER_STYLE_SOLID &&
border_style[2] <= GTK_BORDER_STYLE_SOLID &&
border_style[3] <= GTK_BORDER_STYLE_SOLID)
{
/* The most common case of a solid border */
gtk_snapshot_append_border2 (snapshot,
gtk_css_boxes_get_border_box (boxes),
border_width,
colors);
}
else
{
snapshot_border (snapshot,
gtk_css_boxes_get_border_box (boxes),
border_width,
colors,
border_style);
}
gtk_snapshot_pop (snapshot);
/* The most common case of a solid border */
gtk_snapshot_append_border (snapshot,
gtk_css_boxes_get_border_box (boxes),
border_width,
colors);
}
gdk_color_finish (&colors[0]);
gdk_color_finish (&colors[1]);
gdk_color_finish (&colors[2]);
gdk_color_finish (&colors[3]);
else
{
snapshot_border (snapshot,
gtk_css_boxes_get_border_box (boxes),
border_width,
colors,
border_style);
}
gtk_snapshot_pop (snapshot);
}
}
@@ -750,20 +733,17 @@ gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
GtkCssStyle *style = boxes->style;
GtkBorderStyle border_style[4];
float border_width[4];
GdkColor colors[4];
GdkRGBA colors[4];
border_style[0] = _gtk_css_border_style_value_get (style->outline->outline_style);
if (border_style[0] != GTK_BORDER_STYLE_NONE)
{
GdkColor color;
const GdkRGBA *color;
gtk_css_color_to_color (gtk_css_color_value_get_color (style->used->outline_color), &color);
color = gtk_css_color_value_get_rgba (style->used->outline_color);
if (gdk_color_is_clear (&color))
{
gdk_color_finish (&color);
return;
}
if (gdk_rgba_is_clear (color))
return;
border_width[0] = gtk_css_number_value_get (style->outline->outline_width, 100);
@@ -772,7 +752,7 @@ gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
border_style[1] = border_style[2] = border_style[3] = border_style[0];
border_width[3] = border_width[2] = border_width[1] = border_width[0];
colors[0] = colors[1] = colors[2] = colors[3] = color;
colors[0] = colors[1] = colors[2] = colors[3] = *color;
gtk_snapshot_push_debug (snapshot, "CSS outline");
snapshot_border (snapshot,
@@ -781,6 +761,5 @@ gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
colors,
border_style);
gtk_snapshot_pop (snapshot);
gdk_color_finish (&color);
}
}
+37 -172
View File
@@ -119,8 +119,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
} stroke;
struct {
gsize n_shadows;
GskShadow2 *shadows;
GskShadow2 a_shadow; /* Used if n_shadows == 1 */
GskShadow *shadows;
GskShadow a_shadow; /* Used if n_shadows == 1 */
} shadow;
struct {
GskBlendMode blend_mode;
@@ -1348,11 +1348,11 @@ gtk_snapshot_collect_shadow (GtkSnapshot *snapshot,
if (node == NULL)
return NULL;
shadow_node = gsk_shadow_node_new2 (node,
state->data.shadow.shadows != NULL
? state->data.shadow.shadows
: &state->data.shadow.a_shadow,
state->data.shadow.n_shadows);
shadow_node = gsk_shadow_node_new (node,
state->data.shadow.shadows != NULL ?
state->data.shadow.shadows :
&state->data.shadow.a_shadow,
state->data.shadow.n_shadows);
gsk_render_node_unref (node);
@@ -1391,12 +1391,6 @@ gtk_snapshot_append_stroke (GtkSnapshot *snapshot,
static void
gtk_snapshot_clear_shadow (GtkSnapshotState *state)
{
if (state->data.shadow.shadows != 0)
for (gsize i = 0; i < state->data.shadow.n_shadows; i++)
gdk_color_finish (&state->data.shadow.shadows[i].color);
else
gdk_color_finish (&state->data.shadow.a_shadow.color);
g_free (state->data.shadow.shadows);
}
@@ -1414,41 +1408,6 @@ void
gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
const GskShadow *shadow,
gsize n_shadows)
{
GskShadow2 *shadow2;
g_return_if_fail (n_shadows > 0);
shadow2 = g_new (GskShadow2, n_shadows);
for (gsize i = 0; i < n_shadows; i++)
{
gdk_color_init_from_rgba (&shadow2[i].color, &shadow[i].color);
graphene_point_init (&shadow2[i].offset, shadow[i].dx,shadow[i].dy);
shadow2[i].radius = shadow[i].radius;
}
gtk_snapshot_push_shadow2 (snapshot, shadow2, n_shadows);
for (gsize i = 0; i < n_shadows; i++)
gdk_color_finish (&shadow2[i].color);
g_free (shadow2);
}
/*< private >
* gtk_snapshot_push_shadow2:
* @snapshot: a `GtkSnapshot`
* @shadow: (array length=n_shadows): the first shadow specification
* @n_shadows: number of shadow specifications
*
* Applies a shadow to an image.
*
* The image is recorded until the next call to [method@Gtk.Snapshot.pop].
*/
void
gtk_snapshot_push_shadow2 (GtkSnapshot *snapshot,
const GskShadow2 *shadow,
gsize n_shadows)
{
GtkSnapshotState *state;
GskTransform *transform;
@@ -1470,23 +1429,20 @@ gtk_snapshot_push_shadow2 (GtkSnapshot *snapshot,
if (n_shadows == 1)
{
state->data.shadow.shadows = NULL;
gdk_color_init_copy (&state->data.shadow.a_shadow.color, &shadow->color);
graphene_point_init (&state->data.shadow.a_shadow.offset,
shadow->offset.x * scale_x,
shadow->offset.y * scale_y);
state->data.shadow.a_shadow.radius = shadow->radius * scale_x;
memcpy (&state->data.shadow.a_shadow, shadow, sizeof (GskShadow));
state->data.shadow.a_shadow.dx *= scale_x;
state->data.shadow.a_shadow.dy *= scale_y;
state->data.shadow.a_shadow.radius *= scale_x;
}
else
{
state->data.shadow.shadows = g_malloc (sizeof (GskShadow2) * n_shadows);
memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow2) * n_shadows);
state->data.shadow.shadows = g_malloc (sizeof (GskShadow) * n_shadows);
memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow) * n_shadows);
for (i = 0; i < n_shadows; i++)
{
gdk_color_init_copy (&state->data.shadow.shadows[i].color, &shadow[i].color);
graphene_point_init (&state->data.shadow.shadows[i].offset,
shadow[i].offset.x * scale_x,
shadow[i].offset.y * scale_y);
state->data.shadow.shadows[i].radius = shadow[i].radius * scale_x;
state->data.shadow.shadows[i].dx *= scale_x;
state->data.shadow.shadows[i].dy *= scale_y;
state->data.shadow.shadows[i].radius *= scale_x;
}
}
@@ -2849,36 +2805,6 @@ gtk_snapshot_append_border (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const float border_width[4],
const GdkRGBA border_color[4])
{
GdkColor color[4];
for (int i = 0; i < 4; i++)
gdk_color_init_from_rgba (&color[i], &border_color[i]);
gtk_snapshot_append_border2 (snapshot, outline, border_width, color);
for (int i = 0; i < 4; i++)
gdk_color_finish (&color[i]);
}
/*< private >
* gtk_snapshot_append_border2:
* @snapshot: a `GtkSnapshot`
* @outline: the outline of the border
* @border_width: (array fixed-size=4): the stroke width of the border on
* the top, right, bottom and left side respectively.
* @border_color: (array fixed-size=4): the color used on the top, right,
* bottom and left side.
*
* Appends a stroked border rectangle inside the given @outline.
*
* The four sides of the border can have different widths and colors.
*/
void
gtk_snapshot_append_border2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const float border_width[4],
const GdkColor border_color[4])
{
GskRenderNode *node;
GskRoundedRect real_outline;
@@ -2892,14 +2818,14 @@ gtk_snapshot_append_border2 (GtkSnapshot *snapshot,
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &dx, &dy);
gsk_rounded_rect_scale_affine (&real_outline, outline, scale_x, scale_y, dx, dy);
node = gsk_border_node_new2 (&real_outline,
(float[4]) {
border_width[0] * scale_y,
border_width[1] * scale_x,
border_width[2] * scale_y,
border_width[3] * scale_x,
},
border_color);
node = gsk_border_node_new (&real_outline,
(float[4]) {
border_width[0] * scale_y,
border_width[1] * scale_x,
border_width[2] * scale_y,
border_width[3] * scale_x,
},
border_color);
gtk_snapshot_append_node_internal (snapshot, node);
}
@@ -2924,36 +2850,6 @@ gtk_snapshot_append_inset_shadow (GtkSnapshot *snapshot,
float dy,
float spread,
float blur_radius)
{
GdkColor color2;
gdk_color_init_from_rgba (&color2, color);
gtk_snapshot_append_inset_shadow2 (snapshot,
outline,
&color2,
&GRAPHENE_POINT_INIT (dx, dy),
spread, blur_radius);
gdk_color_finish (&color2);
}
/*< private >
* gtk_snapshot_append_inset_shadow2:
* @snapshot: a `GtkSnapshot`
* @outline: outline of the region surrounded by shadow
* @color: color of the shadow
* @offset: offset of shadow
* @spread: how far the shadow spreads towards the inside
* @blur_radius: how much blur to apply to the shadow
*
* Appends an inset shadow into the box given by @outline.
*/
void
gtk_snapshot_append_inset_shadow2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius)
{
GskRenderNode *node;
GskRoundedRect real_outline;
@@ -2962,17 +2858,16 @@ gtk_snapshot_append_inset_shadow2 (GtkSnapshot *snapshot,
g_return_if_fail (snapshot != NULL);
g_return_if_fail (outline != NULL);
g_return_if_fail (color != NULL);
g_return_if_fail (offset != NULL);
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &x, &y);
gsk_rounded_rect_scale_affine (&real_outline, outline, scale_x, scale_y, x, y);
node = gsk_inset_shadow_node_new2 (&real_outline,
color,
&GRAPHENE_POINT_INIT (scale_x * offset->x,
scale_y * offset->y),
spread,
blur_radius);
node = gsk_inset_shadow_node_new (&real_outline,
color,
scale_x * dx,
scale_y * dy,
spread,
blur_radius);
gtk_snapshot_append_node_internal (snapshot, node);
}
@@ -2997,36 +2892,6 @@ gtk_snapshot_append_outset_shadow (GtkSnapshot *snapshot,
float dy,
float spread,
float blur_radius)
{
GdkColor color2;
gdk_color_init_from_rgba (&color2, color);
gtk_snapshot_append_outset_shadow2 (snapshot,
outline,
&color2,
&GRAPHENE_POINT_INIT (dx, dy),
spread, blur_radius);
gdk_color_finish (&color2);
}
/*< private >
* gtk_snapshot_append_outset_shadow2:
* @snapshot: a `GtkSnapshot`
* @outline: outline of the region surrounded by shadow
* @color: color of the shadow
* @offset: offset of shadow
* @spread: how far the shadow spreads towards the outside
* @blur_radius: how much blur to apply to the shadow
*
* Appends an outset shadow node around the box given by @outline.
*/
void
gtk_snapshot_append_outset_shadow2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius)
{
GskRenderNode *node;
GskRoundedRect real_outline;
@@ -3035,17 +2900,17 @@ gtk_snapshot_append_outset_shadow2 (GtkSnapshot *snapshot,
g_return_if_fail (snapshot != NULL);
g_return_if_fail (outline != NULL);
g_return_if_fail (color != NULL);
g_return_if_fail (offset != NULL);
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &x, &y);
gsk_rounded_rect_scale_affine (&real_outline, outline, scale_x, scale_y, x, y);
node = gsk_outset_shadow_node_new2 (&real_outline,
color,
&GRAPHENE_POINT_INIT (scale_x * offset->x,
scale_y * offset->y),
spread,
blur_radius);
node = gsk_outset_shadow_node_new (&real_outline,
color,
scale_x * dx,
scale_y * dy,
spread,
blur_radius);
gtk_snapshot_append_node_internal (snapshot, node);
}
-22
View File
@@ -40,28 +40,6 @@ void gtk_snapshot_push_subsurface (GtkSnapshot
void gtk_snapshot_append_color2 (GtkSnapshot *snapshot,
const GdkColor *color,
const graphene_rect_t *bounds);
void gtk_snapshot_append_border2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const float border_width[4],
const GdkColor border_color[4]);
void gtk_snapshot_append_inset_shadow2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius);
void gtk_snapshot_append_outset_shadow2 (GtkSnapshot *snapshot,
const GskRoundedRect *outline,
const GdkColor *color,
const graphene_point_t *offset,
float spread,
float blur_radius);
void gtk_snapshot_push_shadow2 (GtkSnapshot *snapshot,
const GskShadow2 *shadow,
gsize n_shadows);
G_END_DECLS
-2
View File
@@ -28,8 +28,6 @@
G_BEGIN_DECLS
#define GTK_STYLE_PROVIDER_PRIORITY_INSPECTOR 1000
#define GTK_STYLE_PROVIDER_GET_INTERFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GTK_TYPE_STYLE_PROVIDER, GtkStyleProviderInterface))
typedef struct _GtkStyleProviderInterface GtkStyleProviderInterface;
+42
View File
@@ -470,6 +470,8 @@ static void gtk_window_activate_close (GtkWidget *widget,
const char *action_name,
GVariant *parameter);
static void gtk_window_css_changed (GtkWidget *widget,
GtkCssStyleChange *change);
static void _gtk_window_set_is_active (GtkWindow *window,
gboolean is_active);
static void gtk_window_present_toplevel (GtkWindow *window);
@@ -780,6 +782,7 @@ gtk_window_class_init (GtkWindowClass *klass)
widget_class->focus = gtk_window_focus;
widget_class->move_focus = gtk_window_move_focus;
widget_class->measure = gtk_window_measure;
widget_class->css_changed = gtk_window_css_changed;
klass->activate_default = gtk_window_real_activate_default;
klass->activate_focus = gtk_window_real_activate_focus;
@@ -4056,6 +4059,30 @@ out:
*shadow_width = (GtkBorder) {0, 0, 0, 0};
}
static void
update_opaque_region (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
gboolean subtract_decoration_corners;
gboolean subtract_shadow;
subtract_decoration_corners = (priv->client_decorated &&
priv->decorated &&
!priv->fullscreen &&
!priv->maximized);
subtract_shadow = (priv->client_decorated &&
priv->decorated &&
priv->use_client_shadow &&
!priv->maximized &&
!priv->fullscreen);
gtk_native_update_opaque_region (GTK_NATIVE (window),
NULL,
subtract_decoration_corners,
subtract_shadow,
RESIZE_HANDLE_SIZE);
}
static void
update_realized_window_properties (GtkWindow *window)
{
@@ -4065,6 +4092,8 @@ update_realized_window_properties (GtkWindow *window)
const graphene_rect_t *border_rect;
double native_x, native_y;
update_opaque_region (window);
if (!priv->client_decorated || !priv->use_client_shadow)
return;
@@ -5171,6 +5200,19 @@ gtk_window_set_focus (GtkWindow *window,
gtk_window_root_set_focus (GTK_ROOT (window), NULL);
}
static void
gtk_window_css_changed (GtkWidget *widget,
GtkCssStyleChange *change)
{
GtkWindow *window = GTK_WINDOW (widget);
GTK_WIDGET_CLASS (gtk_window_parent_class)->css_changed (widget, change);
if (!_gtk_widget_get_alloc_needed (widget) &&
(change == NULL || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_BACKGROUND_COLOR)))
update_opaque_region (window);
}
/*
* _gtk_window_unset_focus_and_default:
* @window: a `GtkWindow`
+6 -6
View File
@@ -26,15 +26,15 @@
#include "window.h"
#include "css-editor.h"
#include "gtkalertdialog.h"
#include "gtkcssprovider.h"
#include "gtkfiledialog.h"
#include "gtklabel.h"
#include "gtkstyleproviderprivate.h"
#include "gtktextiter.h"
#include "gtkstyleprovider.h"
#include "gtktextview.h"
#include "gtkalertdialog.h"
#include "gtkfiledialog.h"
#include "gtktogglebutton.h"
#include "gtklabel.h"
#include "gtktooltip.h"
#include "gtktextiter.h"
#include "gtk/css/gtkcss.h"
@@ -174,7 +174,7 @@ disable_toggled (GtkToggleButton *button,
else
gtk_style_context_add_provider_for_display (ce->priv->display,
GTK_STYLE_PROVIDER (ce->priv->provider),
GTK_STYLE_PROVIDER_PRIORITY_INSPECTOR);
GTK_STYLE_PROVIDER_PRIORITY_USER);
}
static void
+15 -29
View File
@@ -1033,7 +1033,7 @@ static void
populate_render_node_properties (GListStore *store,
GskRenderNode *node)
{
graphene_rect_t bounds, opaque;
graphene_rect_t bounds;
g_list_store_remove_all (store);
@@ -1042,25 +1042,11 @@ populate_render_node_properties (GListStore *store,
add_text_row (store, "Type", "%s", node_type_name (gsk_render_node_get_node_type (node)));
add_text_row (store, "Bounds",
"(%.2f, %.2f) to (%.2f, %.2f) - %.2f x %.2f",
bounds.origin.x,
bounds.origin.y,
bounds.origin.x + bounds.size.width,
bounds.origin.y + bounds.size.height,
"%.2f x %.2f + %.2f + %.2f",
bounds.size.width,
bounds.size.height);
if (gsk_render_node_get_opaque_rect (node, &opaque))
add_text_row (store, "Opaque",
"(%.2f, %.2f) to (%.2f, %.2f) - %.2f x %.2f",
opaque.origin.x,
opaque.origin.y,
opaque.origin.x + opaque.size.width,
opaque.origin.y + opaque.size.height,
opaque.size.width,
opaque.size.height);
else
add_text_row (store, "Opaque", "no");
bounds.size.height,
bounds.origin.x,
bounds.origin.y);
switch (gsk_render_node_get_node_type (node))
{
@@ -1237,7 +1223,7 @@ populate_render_node_properties (GListStore *store,
{
const char *name[4] = { "Top", "Right", "Bottom", "Left" };
const float *widths = gsk_border_node_get_widths (node);
const GdkColor *colors = gsk_border_node_get_colors2 (node);
const GdkRGBA *colors = gsk_border_node_get_colors (node);
int i;
for (i = 0; i < 4; i++)
@@ -1245,9 +1231,9 @@ populate_render_node_properties (GListStore *store,
GdkTexture *texture;
char *text, *tmp;
text = gdk_color_to_string (&colors[i]);
text = gdk_rgba_to_string (&colors[i]);
tmp = g_strdup_printf ("%.2f, %s", widths[i], text);
texture = get_color2_texture (&colors[i]);
texture = get_color_texture (&colors[i]);
list_store_add_object_property (store, name[i], tmp, texture);
g_object_unref (texture);
@@ -1369,13 +1355,13 @@ G_GNUC_END_IGNORE_DEPRECATIONS
case GSK_INSET_SHADOW_NODE:
{
const GdkColor *color = gsk_inset_shadow_node_get_color2 (node);
const GdkRGBA *color = gsk_inset_shadow_node_get_color (node);
float dx = gsk_inset_shadow_node_get_dx (node);
float dy = gsk_inset_shadow_node_get_dy (node);
float spread = gsk_inset_shadow_node_get_spread (node);
float radius = gsk_inset_shadow_node_get_blur_radius (node);
add_color2_row (store, "Color", color);
add_color_row (store, "Color", color);
add_text_row (store, "Offset", "%.2f %.2f", dx, dy);
@@ -1387,7 +1373,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
case GSK_OUTSET_SHADOW_NODE:
{
const GskRoundedRect *outline = gsk_outset_shadow_node_get_outline (node);
const GdkColor *color = gsk_outset_shadow_node_get_color2 (node);
const GdkRGBA *color = gsk_outset_shadow_node_get_color (node);
float dx = gsk_outset_shadow_node_get_dx (node);
float dy = gsk_outset_shadow_node_get_dy (node);
float spread = gsk_outset_shadow_node_get_spread (node);
@@ -1399,7 +1385,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
"%.2f x %.2f + %.2f + %.2f",
rect[2], rect[3], rect[0], rect[1]);
add_color2_row (store, "Color", color);
add_color_row (store, "Color", color);
add_text_row (store, "Offset", "%.2f %.2f", dx, dy);
@@ -1532,14 +1518,14 @@ G_GNUC_END_IGNORE_DEPRECATIONS
for (i = 0; i < gsk_shadow_node_get_n_shadows (node); i++)
{
char *label;
const GskShadow2 *shadow = gsk_shadow_node_get_shadow2 (node, i);
const GskShadow *shadow = gsk_shadow_node_get_shadow (node, i);
label = g_strdup_printf ("Color %d", i);
add_color2_row (store, label, &shadow->color);
add_color_row (store, label, &shadow->color);
g_free (label);
label = g_strdup_printf ("Offset %d", i);
add_text_row (store, label, "%.2f %.2f", shadow->offset.x, shadow->offset.y);
add_text_row (store, label, "%.2f %.2f", shadow->dx, shadow->dy);
g_free (label);
label = g_strdup_printf ("Radius %d", i);
+14 -25
View File
@@ -26,7 +26,6 @@ cloudproviders_req = '>= 0.3.1'
xkbcommon_req = '>= 0.2.0'
sysprof_req = '>= 3.38.0'
vulkan_req = '>= 1.3'
gstreamer_req = '>= 1.24.0'
fs = import('fs')
gnome = import('gnome')
@@ -411,30 +410,21 @@ if win32_enabled
pangowin32_dep = dependency('pangowin32')
endif
pangocairo_dep = dependency('pangocairo', version: pango_req)
pixbuf_dep = dependency('gdk-pixbuf-2.0', version: gdk_pixbuf_req,
default_options: ['png=enabled', 'jpeg=enabled', 'builtin_loaders=png,jpeg', 'man=false'])
png_dep = dependency('libpng', 'png')
tiff_dep = dependency('libtiff-4', 'tiff')
jpeg_dep = dependency('libjpeg', 'jpeg')
avif_dep = dependency('libavif', required: get_option('avif'))
pangocairo_dep = dependency('pangocairo', version: pango_req)
pixbuf_dep = dependency('gdk-pixbuf-2.0', version: gdk_pixbuf_req,
default_options: ['png=enabled', 'jpeg=enabled', 'builtin_loaders=png,jpeg', 'man=false'])
png_dep = dependency('libpng', 'png')
tiff_dep = dependency('libtiff-4', 'tiff')
jpeg_dep = dependency('libjpeg', 'jpeg')
cdata.set('HAVE_AVIF', avif_dep.found())
epoxy_dep = dependency('epoxy', version: epoxy_req)
xkbdep = dependency('xkbcommon', version: xkbcommon_req, required: wayland_enabled)
graphene_dep = dependency('graphene-gobject-1.0', version: graphene_req,
default_options: ['tests=false', 'gobject_types=true'])
iso_codes_dep = dependency('iso-codes', required: false)
gi_dep = dependency('gobject-introspection-1.0', version: introspection_req,
required: get_option('introspection').enabled() and
get_option('build-tests'))
gstplayer_dep = dependency('gstreamer-player-1.0', version: gstreamer_req,
required: get_option('media-gstreamer'))
gstgl_dep = dependency('gstreamer-gl-1.0', version: gstreamer_req,
required: get_option('media-gstreamer'))
gstallocators_dep = dependency('gstreamer-allocators-1.0', version: gstreamer_req,
required: get_option('media-gstreamer'))
epoxy_dep = dependency('epoxy', version: epoxy_req)
xkbdep = dependency('xkbcommon', version: xkbcommon_req, required: wayland_enabled)
graphene_dep = dependency('graphene-gobject-1.0', version: graphene_req,
default_options: ['tests=false', 'gobject_types=true'])
iso_codes_dep = dependency('iso-codes', required: false)
gi_dep = dependency('gobject-introspection-1.0', version: introspection_req,
required: get_option('introspection').enabled() and
get_option('build-tests'))
fontconfig_dep = [] # only used in x11 backend
@@ -958,7 +948,6 @@ summary('Cloud support', cloudproviders_dep.found(), section: 'Features')
summary('Sysprof support', libsysprof_capture_dep.found(), section: 'Features')
summary('Colord support', colord_dep.found(), section: 'Features')
summary('Tracker support', tracker3_dep.found(), section: 'Features')
summary('AVIF support', avif_dep.found(), section: 'Features')
summary('Compiler', cc.get_id(), section: 'Toolchain')
summary('Linker', cc.get_linker_id(), section: 'Toolchain')
-5
View File
@@ -52,11 +52,6 @@ option('print-cups',
# Optional features
option('avif',
type: 'feature',
value: 'disabled',
description: 'Enable support for AVIF images, for GTK development')
option('vulkan',
type: 'feature',
value: 'enabled',
+62 -124
View File
@@ -24,8 +24,6 @@
#include "gtkgstpaintableprivate.h"
#include "gdk/gdkdmabuffourccprivate.h"
#if GST_GL_HAVE_WINDOW_X11 && (GST_GL_HAVE_PLATFORM_GLX || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_X11)
#define HAVE_GST_X11_SUPPORT
#include <gdk/x11/gdkx.h>
@@ -54,8 +52,10 @@
#include <gst/gl/gstglfuncs.h>
#ifdef HAVE_GSTREAMER_DRM
#include <gdk/gdkdmabuffourccprivate.h>
#include <gst/allocators/gstdmabuf.h>
#endif
enum {
PROP_0,
@@ -72,11 +72,17 @@ GST_DEBUG_CATEGORY (gtk_debug_gst_sink);
#define NOGL_CAPS GST_VIDEO_CAPS_MAKE (FORMATS)
#ifdef HAVE_GSTREAMER_DRM
# define GST_VIDEO_DMA_DRM_CAPS_MAKE_STR GST_VIDEO_DMA_DRM_CAPS_MAKE "; "
#else
# define GST_VIDEO_DMA_DRM_CAPS_MAKE_STR
#endif
static GstStaticPadTemplate gtk_gst_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_DMA_DRM_CAPS_MAKE "; "
GST_STATIC_CAPS (GST_VIDEO_DMA_DRM_CAPS_MAKE_STR
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
"format = (string) RGBA, "
"width = " GST_VIDEO_SIZE_RANGE ", "
@@ -124,6 +130,7 @@ gtk_gst_sink_get_times (GstBaseSink *bsink,
}
}
#ifdef HAVE_GSTREAMER_DRM
static void
add_drm_formats_and_modifiers (GstCaps *caps,
GdkDmabufFormats *dmabuf_formats)
@@ -157,73 +164,11 @@ add_drm_formats_and_modifiers (GstCaps *caps,
gst_structure_take_value (gst_caps_get_structure (caps, 0), "drm-format",
&dmabuf_list);
}
#ifdef HAVE_GSTREAMER_DRM
static inline gboolean
dmabuf_fourcc_is_yuv (guint32 fourcc)
{
switch (fourcc)
{
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_AYUV:
case DRM_FORMAT_AVUY8888:
case DRM_FORMAT_XYUV8888:
case DRM_FORMAT_XVUY8888:
case DRM_FORMAT_VUY888:
case DRM_FORMAT_VUY101010:
case DRM_FORMAT_Y210:
case DRM_FORMAT_Y212:
case DRM_FORMAT_Y216:
case DRM_FORMAT_Y410:
case DRM_FORMAT_Y412:
case DRM_FORMAT_Y416:
case DRM_FORMAT_XVYU2101010:
case DRM_FORMAT_XVYU12_16161616:
case DRM_FORMAT_XVYU16161616:
case DRM_FORMAT_Y0L0:
case DRM_FORMAT_X0L0:
case DRM_FORMAT_Y0L2:
case DRM_FORMAT_X0L2:
case DRM_FORMAT_YUV420_8BIT:
case DRM_FORMAT_YUV420_10BIT:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV15:
case DRM_FORMAT_P210:
case DRM_FORMAT_P010:
case DRM_FORMAT_P012:
case DRM_FORMAT_P016:
case DRM_FORMAT_P030:
case DRM_FORMAT_Q410:
case DRM_FORMAT_Q401:
case DRM_FORMAT_YUV410:
case DRM_FORMAT_YVU410:
case DRM_FORMAT_YUV411:
case DRM_FORMAT_YVU411:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
case DRM_FORMAT_YUV422:
case DRM_FORMAT_YVU422:
case DRM_FORMAT_YUV444:
case DRM_FORMAT_YVU444:
return TRUE;
default:
return FALSE;
}
}
#endif
static GdkColorState *
gtk_gst_color_state_from_colorimetry (GtkGstSink *self,
const GstVideoColorimetry *colorimetry,
gconstpointer drm)
const GstVideoColorimetry *colorimetry)
{
GdkCicpParams *params;
GdkColorState *color_state;
@@ -241,40 +186,18 @@ gtk_gst_color_state_from_colorimetry (GtkGstSink *self,
else
gdk_cicp_params_set_transfer_function (params, gst_video_transfer_function_to_iso (colorimetry->transfer));
gdk_cicp_params_set_range (params, colorimetry->range == GST_VIDEO_COLOR_RANGE_16_235 ? GDK_CICP_RANGE_NARROW : GDK_CICP_RANGE_FULL);
#if 0
if (colorimetry->matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN)
{
gdk_cicp_params_set_matrix_coefficients (params, 0);
#ifdef HAVE_GSTREAMER_DRM
const GstVideoInfoDmaDrm *drm_info = drm;
if (drm_info)
{
if (dmabuf_fourcc_is_yuv (drm_info->drm_fourcc))
{
GST_DEBUG_OBJECT (self, "Assuming fourcc %.*s is yuv", 4, (char *)&drm_info->drm_fourcc);
gdk_cicp_params_set_matrix_coefficients (params, 6);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_NARROW);
}
}
#endif
}
gdk_cicp_params_set_matrix_coefficients (params, 6);
else
gdk_cicp_params_set_matrix_coefficients (params, gst_video_color_matrix_to_iso (colorimetry->matrix));
gdk_cicp_params_set_range (params, colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255 ? GDK_CICP_RANGE_FULL : GDK_CICP_RANGE_NARROW);
#else
gdk_cicp_params_set_matrix_coefficients (params, 0);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
#endif
color_state = gdk_cicp_params_build_color_state (params, &error);
GST_DEBUG_OBJECT (self, "cicp received: %u/%u/%u/%u",
gst_video_color_primaries_to_iso (colorimetry->primaries),
gst_video_transfer_function_to_iso (colorimetry->transfer),
gst_video_color_matrix_to_iso (colorimetry->matrix),
colorimetry->range == GST_VIDEO_COLOR_RANGE_0_255);
GST_DEBUG_OBJECT (self, "cicp used: %u/%u/%u/%u",
gdk_cicp_params_get_color_primaries (params),
gdk_cicp_params_get_transfer_function (params),
gdk_cicp_params_get_matrix_coefficients (params),
gdk_cicp_params_get_range (params));
g_object_unref (params);
if (color_state == NULL)
@@ -296,12 +219,16 @@ gtk_gst_sink_get_caps (GstBaseSink *bsink,
if (self->gst_context)
{
GdkDisplay *display = gdk_gl_context_get_display (self->gdk_context);
GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (display);
tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
tmp = gst_caps_make_writable (tmp);
add_drm_formats_and_modifiers (tmp, formats);
#ifdef HAVE_GSTREAMER_DRM
{
GdkDisplay *display = gdk_gl_context_get_display (self->gdk_context);
GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (display);
tmp = gst_caps_make_writable (tmp);
add_drm_formats_and_modifiers (tmp, formats);
}
#endif
}
else
{
@@ -334,33 +261,27 @@ gtk_gst_sink_set_caps (GstBaseSink *bsink,
GST_DEBUG_OBJECT (self, "set caps with %" GST_PTR_FORMAT, caps);
if (gst_video_is_dma_drm_caps (caps))
{
if (!gst_video_info_dma_drm_from_caps (&self->drm_info, caps))
return FALSE;
#ifdef HAVE_GSTREAMER_DRM
if (gst_video_is_dma_drm_caps (caps)) {
if (!gst_video_info_dma_drm_from_caps (&self->drm_info, caps))
return FALSE;
if (!gst_video_info_dma_drm_to_video_info (&self->drm_info, &self->v_info))
return FALSE;
if (!gst_video_info_dma_drm_to_video_info (&self->drm_info, &self->v_info))
return FALSE;
GST_INFO_OBJECT (self, "using DMABuf, passthrough possible");
}
else
{
gst_video_info_dma_drm_init (&self->drm_info);
GST_INFO_OBJECT (self, "using DMABuf, passthrough possible");
} else {
gst_video_info_dma_drm_init (&self->drm_info);
#endif
if (!gst_video_info_from_caps (&self->v_info, caps))
return FALSE;
}
if (!gst_video_info_from_caps (&self->v_info, caps))
return FALSE;
#ifdef HAVE_GSTREAMER_DRM
}
#endif
g_clear_pointer (&self->color_state, gdk_color_state_unref);
self->color_state = gtk_gst_color_state_from_colorimetry (self,
&self->v_info.colorimetry,
#ifdef HAVE_GSTREAMER_DRM
&self->drm_info
#else
NULL
#endif
);
self->color_state = gtk_gst_color_state_from_colorimetry (self, &self->v_info.colorimetry);
if (self->color_state == NULL)
return FALSE;
@@ -404,11 +325,13 @@ gtk_gst_sink_propose_allocation (GstBaseSink *bsink,
return FALSE;
}
#ifdef HAVE_GSTREAMER_DRM
if (gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_DMABUF))
{
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);
return TRUE;
}
#endif
if (!gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_GL_MEMORY))
return FALSE;
@@ -501,6 +424,7 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
viewport->size.width = GST_VIDEO_INFO_WIDTH (&self->v_info);
viewport->size.height = GST_VIDEO_INFO_HEIGHT (&self->v_info);
#ifdef HAVE_GSTREAMER_DRM
if (gst_is_dmabuf_memory (gst_buffer_peek_memory (buffer, 0)))
{
GdkDmabufTextureBuilder *builder = NULL;
@@ -559,8 +483,10 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self,
*pixel_aspect_ratio = ((double) GST_VIDEO_INFO_PAR_N (&self->v_info) /
(double) GST_VIDEO_INFO_PAR_D (&self->v_info));
}
else if (self->gdk_context &&
gst_video_frame_map (frame, &self->v_info, buffer, GST_MAP_READ | GST_MAP_GL))
else
#endif
if (self->gdk_context &&
gst_video_frame_map (frame, &self->v_info, buffer, GST_MAP_READ | GST_MAP_GL))
{
GstGLSyncMeta *sync_meta;
GdkGLTextureBuilder *builder;
@@ -779,8 +705,20 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
if (gl_api & (GST_GL_API_OPENGL3 | GST_GL_API_OPENGL))
{
#ifdef HAVE_GST_GL_DISPLAY_NEW_WITH_TYPE
self->gst_display = gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
#else
#if GST_GL_HAVE_PLATFORM_EGL
g_message ("If media fails to play, set the envvar `GST_DEBUG=1`, and if GstGL context creation fails");
g_message ("due to \"Couldn't create GL context: Cannot share context with non-EGL context\",");
g_message ("set in the environment `GST_GL_PLATFORM=wgl` and `GST_GL_WINDOW=win32`,");
g_message ("and restart the GTK application");
#endif
self->gst_display = gst_gl_display_new ();
#endif
}
#if GST_GL_HAVE_PLATFORM_EGL
else
{
+2
View File
@@ -47,7 +47,9 @@ struct _GtkGstSink
GstVideoSink parent;
GstVideoInfo v_info;
#ifdef HAVE_GSTREAMER_DRM
GstVideoInfoDmaDrm drm_info;
#endif
GtkGstPaintable * paintable;
GdkGLContext * gdk_context;

Some files were not shown because too many files have changed in this diff Show More