Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec271b47fb | |||
| 80bee35ab7 | |||
| 4be4e53bdd | |||
| d10c55c748 | |||
| 60d9d79bcc | |||
| d0fbe1db5a | |||
| 44aca0cecf | |||
| f8afc60c9b | |||
| 2f26bd9842 | |||
| 449fc749e6 | |||
| 56ea1754bf | |||
| cd18bb9fd1 | |||
| 9f3927e7a7 | |||
| df18749d6d |
+1
-1
@@ -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 +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
|
||||
|
||||
|
||||
@@ -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*)
|
||||
|
||||
@@ -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
|
||||
=========================================
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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 (®ion, 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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: */
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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 ();
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+349
-664
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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 == >K_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 == >K_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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
@@ -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
@@ -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')
|
||||
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user