Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec271b47fb | |||
| 80bee35ab7 | |||
| 4be4e53bdd | |||
| d10c55c748 | |||
| 60d9d79bcc | |||
| d0fbe1db5a | |||
| 44aca0cecf | |||
| f8afc60c9b | |||
| 2f26bd9842 | |||
| 449fc749e6 | |||
| 56ea1754bf | |||
| cd18bb9fd1 | |||
| 9f3927e7a7 | |||
| df18749d6d | |||
| 50c19a6534 | |||
| 6edb526561 | |||
| ee18156675 | |||
| e70a961ac1 | |||
| ffdc8c8f60 | |||
| fd78bd3eaf | |||
| f2ccba0988 | |||
| 8ee465c630 | |||
| 31b655c9eb | |||
| 7fd65cc3c1 | |||
| 8089222fc3 | |||
| 0667bd39fb | |||
| a4854dfa9e | |||
| 6c54d0a7e2 | |||
| 341860eb4d | |||
| 876445f080 | |||
| 03ef6a7719 | |||
| fde8c6df79 | |||
| 6c06e1855e | |||
| c60ae0b575 | |||
| e58f9ea1b4 | |||
| 3d55d733dc | |||
| 582dba54b1 | |||
| 0775432ed9 | |||
| d9e15ff6e9 | |||
| c04edfc76e | |||
| 71d6392572 | |||
| dbd16cd9da | |||
| 950d266894 | |||
| 884974eeaa | |||
| e836166664 | |||
| c1a99bf901 | |||
| f9c9a03404 | |||
| 3a337824e6 | |||
| 7dab23e38a | |||
| 78935ec83c | |||
| b8989b7ff6 | |||
| 96cd47d0a0 | |||
| d6a6cfe6c5 | |||
| 501356116d | |||
| e11e5525db | |||
| 16431da3f2 | |||
| 842949fcf3 | |||
| 3d3e935c91 | |||
| d5ae94ca5d | |||
| 87e9c940a4 | |||
| 6a02fa4be8 | |||
| 9f548efd32 | |||
| 9eebe8e547 | |||
| f9612533c2 | |||
| c9c0d444a2 | |||
| 13a8704f51 | |||
| f20714262c | |||
| 11ffeeb55c | |||
| 85830c059e | |||
| ffc89e40a0 | |||
| 1c92f2d963 | |||
| 12e0ec0b48 | |||
| 5574bf59f6 | |||
| 7ee27cc0ad | |||
| 040974c8a2 | |||
| 126d689086 | |||
| 8e676c7360 | |||
| 84847e46fa |
@@ -3,7 +3,7 @@
|
||||
<gresource prefix="/org/gtk/gtk4/node-editor">
|
||||
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">help-window.ui</file>
|
||||
<file>node-format.md</file>
|
||||
<file alias='node-format.md'>../../docs/reference/gtk/node-format.md</file>
|
||||
<file alias='icons/apps/org.gtk.gtk4.NodeEditor.svg'>data/scalable/apps/org.gtk.gtk4.NodeEditor.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -85,6 +85,7 @@ content_files = [
|
||||
"x11.md",
|
||||
"tools.md",
|
||||
"visual_index.md",
|
||||
"node-format.md",
|
||||
]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
# The Node file format
|
||||
Title: The Node file format
|
||||
|
||||
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
|
||||
|
||||
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the parsing APIs.
|
||||
|
||||
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**: `<node>\*`
|
||||
**node**: container [ "name" ] { <document> } | `<node-type> [ "name" ] { <property>* }` | "name"
|
||||
**property**: `<property-name>: <node> | <value> ;`
|
||||
|
||||
document: <@-rule>*<node>*
|
||||
@-rule: @cicp "name" { <property>* }
|
||||
node: container [ "name" ] { <document> } | <node-type> [ "name" ] { <property>* } | "name"
|
||||
property: <property-name>: <node> | <value> ;
|
||||
|
||||
Each node has its own `<node-type>` and supports a custom set of properties, each with their own `<property-name>` and syntax. The following paragraphs document each of the nodes and their properties.
|
||||
|
||||
@@ -25,6 +27,45 @@ Nodes can be given a name by adding a string after the `<node-type>` in their de
|
||||
|
||||
Just like nodes, textures can be referenced by name. When defining a named texture, the name has to be placed in front of the URL.
|
||||
|
||||
# Color states
|
||||
|
||||
Color states are represented either by an ident (for builtin ones) or a string
|
||||
(for custom ones):
|
||||
|
||||
color-state: <ident> | <string>
|
||||
|
||||
Custom color states can be defined at the beginning of the document, with an @cicp rule.
|
||||
|
||||
The format for @cicp rules is
|
||||
|
||||
@cicp "name" {
|
||||
...
|
||||
}
|
||||
|
||||
The following properties can be set for custom color states:
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| --------- | ---------------- | -------- | ----------- |
|
||||
| primaries | `<integer>` | 2 | always |
|
||||
| transfer | `<integer>` | 2 | always |
|
||||
| matrix | `<integer>` | 2 | always |
|
||||
| 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).
|
||||
|
||||
# Colors
|
||||
|
||||
Colors can be specified with a variation of the modern CSS color syntax:
|
||||
|
||||
color(<color-state> <number> <number> <number> ["/" <number>])
|
||||
|
||||
The traditional syntax for sRGB colors still works as well:
|
||||
|
||||
rgba(<number>, <number>, <number>, <number)
|
||||
rgb(<number, <number>, <number>)
|
||||
|
||||
# Nodes
|
||||
|
||||
### container
|
||||
+15
-4
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkcolorstateprivate.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytexture.h"
|
||||
@@ -88,15 +89,25 @@ gdk_cairo_format_to_memory_format (cairo_format_t format)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_cairo_set_source_color (cairo_t *cr,
|
||||
GdkColorState *ccs,
|
||||
const GdkColor *color)
|
||||
{
|
||||
float c[4];
|
||||
gdk_color_to_float (color, ccs, c);
|
||||
cairo_set_source_rgba (cr, c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_cairo_set_source_rgba_ccs (cairo_t *cr,
|
||||
GdkColorState *ccs,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
float color[4];
|
||||
|
||||
gdk_color_state_from_rgba (ccs, rgba, color);
|
||||
cairo_set_source_rgba (cr, color[0], color[1], color[2], color[3]);
|
||||
GdkColor c;
|
||||
gdk_color_init_from_rgba (&c, rgba);
|
||||
gdk_cairo_set_source_color (cr, ccs, &c);
|
||||
gdk_color_finish (&c);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -168,7 +168,6 @@ gdk_cicp_params_class_init (GdkCicpParamsClass *klass)
|
||||
* - 5: PAL
|
||||
* - 6,7: BT.601 / NTSC
|
||||
* - 9: BT.2020
|
||||
* - 10: CIE XYZ
|
||||
* - 12: Display P3
|
||||
*
|
||||
* Since: 4.16
|
||||
@@ -209,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
|
||||
*/
|
||||
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkcolorprivate.h"
|
||||
#include "gdkcolorstateprivate.h"
|
||||
#include "gdkrgbaprivate.h"
|
||||
|
||||
/*< private >
|
||||
* GdkColor:
|
||||
* @color_state: the color state to interpret the values in
|
||||
* @values: the 3 coordinates that define the color, followed
|
||||
* by the alpha value
|
||||
*
|
||||
* A `GdkColor` represents a color.
|
||||
*
|
||||
* The color state defines the meaning and range of the values.
|
||||
* E.g., the srgb color state has r, g, b components representing
|
||||
* red, green and blue with a range of [0,1], while the oklch color
|
||||
* state has l, c, h components representing luminosity, chromaticity
|
||||
* and hue, with l ranging from 0 to 1 and c from 0 to about 0.4, while
|
||||
* h is interpreted as angle in degrees.
|
||||
*
|
||||
* value[3] is always the alpha value with a range of [0,1].
|
||||
*
|
||||
* The values are also available under the names red, green, blue
|
||||
* and alpha, or r, g, b and a.
|
||||
*/
|
||||
|
||||
/*< private >
|
||||
* gdk_color_init:
|
||||
* @self: the `GdkColor` struct to initialize
|
||||
* @color_state: the color state
|
||||
* @values: the values
|
||||
*
|
||||
* Initializes the `GdkColor` with the given color state
|
||||
* and values.
|
||||
*
|
||||
* Note that this takes a reference on @color_state that
|
||||
* must be freed by calling [function@Gdk.Color.finish]
|
||||
* when the `GdkColor` is no longer needed.
|
||||
*/
|
||||
void
|
||||
(gdk_color_init) (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const float values[4])
|
||||
{
|
||||
_gdk_color_init (self, color_state, values);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_init_copy:
|
||||
* @self: the `GdkColor` struct to initialize
|
||||
* @color: the `GdkColor` to copy
|
||||
*
|
||||
* Initializes the `GdkColor` by copying the contents
|
||||
* of another `GdkColor`.
|
||||
*
|
||||
* Note that this takes a reference on the color state
|
||||
* that must be freed by calling [function@Gdk.Color.finish]
|
||||
* when the `GdkColor` is no longer needed.
|
||||
*/
|
||||
void
|
||||
(gdk_color_init_copy) (GdkColor *self,
|
||||
const GdkColor *color)
|
||||
{
|
||||
_gdk_color_init_copy (self, color);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_init_from_rgba:
|
||||
* @self: the `GdkColor` struct to initialize
|
||||
* @rgba: the `GdkRGBA` to copy
|
||||
*
|
||||
* Initializes the `GdkColor` by copying the contents
|
||||
* of a `GdkRGBA`.
|
||||
*
|
||||
* Note that `GdkRGBA` colors are always in the sRGB
|
||||
* color state.
|
||||
*
|
||||
* Note that this takes a reference on the color state
|
||||
* that must be freed by calling [function@Gdk.Color.finish]
|
||||
* when the `GdkColor` is no longer needed.
|
||||
*/
|
||||
void
|
||||
(gdk_color_init_from_rgba) (GdkColor *self,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
_gdk_color_init_from_rgba (self, rgba);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* @self: a `GdkColor`
|
||||
*
|
||||
* Drop the reference on the color state of @self.
|
||||
*
|
||||
* After this, @self is empty and can be initialized again
|
||||
* with [function@Gdk.Color.init] and its variants.
|
||||
*/
|
||||
void
|
||||
(gdk_color_finish) (GdkColor *self)
|
||||
{
|
||||
_gdk_color_finish (self);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_equal:
|
||||
* @self: a `GdkColor`
|
||||
* @other: another `GdkColor`
|
||||
*
|
||||
* Compares two `GdkColor` structs for equality.
|
||||
*
|
||||
* Returns: `TRUE` if @self and @other are equal
|
||||
*/
|
||||
gboolean
|
||||
(gdk_color_equal) (const GdkColor *self,
|
||||
const GdkColor *other)
|
||||
{
|
||||
return _gdk_color_equal (self, other);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_is_clear:
|
||||
* @self: a `GdkColor`
|
||||
*
|
||||
* Returns whether @self is fully transparent.
|
||||
*
|
||||
* Returns: `TRUE` if @self is transparent
|
||||
*/
|
||||
gboolean
|
||||
(gdk_color_is_clear) (const GdkColor *self)
|
||||
{
|
||||
return _gdk_color_is_clear (self);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_is_opaque:
|
||||
* @self: a `GdkColor`
|
||||
*
|
||||
* Returns whether @self is fully opaque.
|
||||
*
|
||||
* Returns: `TRUE` if @self if opaque
|
||||
*/
|
||||
gboolean
|
||||
(gdk_color_is_opaque) (const GdkColor *self)
|
||||
{
|
||||
return _gdk_color_is_opaque (self);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_convert:
|
||||
* @self: the `GdkColor` to store the result in
|
||||
* @color_state: the target color start
|
||||
* @other: the `GdkColor` to convert
|
||||
*
|
||||
* Converts a given `GdkColor` to another color state.
|
||||
*
|
||||
* After the conversion, @self will represent the same
|
||||
* color as @other in @color_state, to the degree possible.
|
||||
*
|
||||
* Different color states have different gamuts of colors
|
||||
* they can represent, and converting a color to a color
|
||||
* state with a smaller gamut may yield an 'out of gamut'
|
||||
* result.
|
||||
*/
|
||||
void
|
||||
(gdk_color_convert) (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const GdkColor *other)
|
||||
{
|
||||
gdk_color_convert (self, color_state, other);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_to_float:
|
||||
* @self: a `GdkColor`
|
||||
* @target: the color state to convert to
|
||||
* @values: the location to store the result in
|
||||
*
|
||||
* Converts a given `GdkColor to another color state
|
||||
* and stores the result in a `float[4]`.
|
||||
*/
|
||||
void
|
||||
(gdk_color_to_float) (const GdkColor *self,
|
||||
GdkColorState *target,
|
||||
float values[4])
|
||||
{
|
||||
gdk_color_to_float (self, target, values);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_from_rgba:
|
||||
* @self: the `GdkColor` to store the result in
|
||||
* @color_state: the target color state
|
||||
* @rgba: the `GdkRGBA` to convert
|
||||
*
|
||||
* Converts a given `GdkRGBA` to the target @color_state.
|
||||
*/
|
||||
void
|
||||
gdk_color_from_rgba (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
GdkColor tmp = {
|
||||
.color_state = GDK_COLOR_STATE_SRGB,
|
||||
.r = rgba->red,
|
||||
.g = rgba->green,
|
||||
.b = rgba->blue,
|
||||
.a = rgba->alpha
|
||||
};
|
||||
|
||||
gdk_color_convert (self, color_state, &tmp);
|
||||
gdk_color_finish (&tmp);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_get_depth:
|
||||
* @self: a `GdkColor`
|
||||
*
|
||||
* Returns the preferred depth for the color state of @self.
|
||||
*
|
||||
* Returns: the preferred depth
|
||||
*/
|
||||
GdkMemoryDepth
|
||||
(gdk_color_get_depth) (const GdkColor *self)
|
||||
{
|
||||
return gdk_color_state_get_depth (self->color_state);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_print:
|
||||
* @self: the `GdkColor` to print
|
||||
* @string: the string to print to
|
||||
*
|
||||
* Appends a representation of @self to @string.
|
||||
*
|
||||
* The representation is inspired by CSS3 colors,
|
||||
* but not 100% identical, and looks like this:
|
||||
*
|
||||
* color(NAME R G B / A)
|
||||
*
|
||||
* where `NAME` identifies color state, and
|
||||
* `R`, `G`, `B` and `A` are the components of the color.
|
||||
*
|
||||
* The alpha may be omitted if it is 1.
|
||||
*/
|
||||
void
|
||||
gdk_color_print (const GdkColor *self,
|
||||
GString *string)
|
||||
{
|
||||
if (gdk_color_state_equal (self->color_state, GDK_COLOR_STATE_SRGB))
|
||||
{
|
||||
gdk_rgba_print ((const GdkRGBA *) self->values, string);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (string, "color(%s %g %g %g",
|
||||
gdk_color_state_get_name (self->color_state),
|
||||
self->r, self->g, self->b);
|
||||
if (self->a < 1)
|
||||
g_string_append_printf (string, " / %g", self->a);
|
||||
g_string_append_c (string, ')');
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_print:
|
||||
* @self: the `GdkColor` to print
|
||||
*
|
||||
* Create a string representation of @self.
|
||||
*
|
||||
* See [method@Gdk.Color.print] for details about
|
||||
* the format.
|
||||
|
||||
* Returns: (transfer full): a newly-allocated string
|
||||
*/
|
||||
char *
|
||||
gdk_color_to_string (const GdkColor *self)
|
||||
{
|
||||
GString *string = g_string_new ("");
|
||||
gdk_color_print (self, string);
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* 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 "gdkcolorstateprivate.h"
|
||||
|
||||
|
||||
#define gdk_color_init(...) _gdk_color_init (__VA_ARGS__)
|
||||
static inline void
|
||||
_gdk_color_init (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const float values[4])
|
||||
{
|
||||
self->color_state = gdk_color_state_ref (color_state);
|
||||
memcpy (self->values, values, sizeof (float) * 4);
|
||||
}
|
||||
|
||||
#define gdk_color_init_copy(self, color) _gdk_color_init_copy ((self), (color))
|
||||
static inline void
|
||||
_gdk_color_init_copy (GdkColor *self,
|
||||
const GdkColor *color)
|
||||
{
|
||||
_gdk_color_init (self, color->color_state, color->values);
|
||||
}
|
||||
|
||||
#define gdk_color_init_from_rgb(self, rgba) _gdk_color_init_from_rgba ((self), (rgba))
|
||||
static inline void
|
||||
_gdk_color_init_from_rgba (GdkColor *self,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
_gdk_color_init (self, GDK_COLOR_STATE_SRGB, (const float *) rgba);
|
||||
}
|
||||
|
||||
#define gdk_color_finish(self) _gdk_color_finish ((self))
|
||||
static inline void
|
||||
_gdk_color_finish (GdkColor *self)
|
||||
{
|
||||
gdk_color_state_unref (self->color_state);
|
||||
self->color_state = NULL;
|
||||
}
|
||||
|
||||
#define gdk_color_get_color_state(self) _gdk_color_get_color_state ((self))
|
||||
static inline GdkColorState *
|
||||
_gdk_color_get_color_state (const GdkColor *self)
|
||||
{
|
||||
return self->color_state;
|
||||
}
|
||||
|
||||
#define gdk_color_equal(self, other) _gdk_color_equal ((self), (other))
|
||||
static inline gboolean
|
||||
_gdk_color_equal (const GdkColor *self,
|
||||
const GdkColor *other)
|
||||
{
|
||||
return self->values[0] == other->values[0] &&
|
||||
self->values[1] == other->values[1] &&
|
||||
self->values[2] == other->values[2] &&
|
||||
self->values[3] == other->values[3] &&
|
||||
gdk_color_state_equal (self->color_state, other->color_state);
|
||||
}
|
||||
|
||||
#define gdk_color_is_clear(self) _gdk_color_is_clear ((self))
|
||||
static inline gboolean
|
||||
_gdk_color_is_clear (const GdkColor *self)
|
||||
{
|
||||
return self->alpha < (255.f / 65535.f);
|
||||
}
|
||||
|
||||
#define gdk_color_is_opaque(self) _gdk_color_is_opaque ((self))
|
||||
static inline gboolean
|
||||
_gdk_color_is_opaque (const GdkColor *self)
|
||||
{
|
||||
return self->alpha > (65280.f / 65535.f);
|
||||
}
|
||||
|
||||
#define gdk_color_convert(self, cs, other) _gdk_color_convert ((self), (cs), (other))
|
||||
static inline void
|
||||
_gdk_color_convert (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const GdkColor *other)
|
||||
{
|
||||
if (gdk_color_state_equal (color_state, other->color_state))
|
||||
{
|
||||
gdk_color_init_copy (self, other);
|
||||
return;
|
||||
}
|
||||
|
||||
self->color_state = gdk_color_state_ref (color_state);
|
||||
|
||||
gdk_color_state_convert_color (other->color_state,
|
||||
other->values,
|
||||
self->color_state,
|
||||
self->values);
|
||||
}
|
||||
|
||||
#define gdk_color_to_float(self, cs, values) _gdk_color_to_float ((self), (cs), (values))
|
||||
static inline void
|
||||
_gdk_color_to_float (const GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
float values[4])
|
||||
{
|
||||
if (gdk_color_state_equal (self->color_state, color_state))
|
||||
{
|
||||
memcpy (values, self->values, sizeof (float) * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_color_state_convert_color (self->color_state,
|
||||
self->values,
|
||||
color_state,
|
||||
values);
|
||||
}
|
||||
|
||||
#define gdk_color_get_depth(self) _gdk_color_get_depth ((self))
|
||||
static inline GdkMemoryDepth
|
||||
_gdk_color_get_depth (const GdkColor *self)
|
||||
{
|
||||
return gdk_color_state_get_depth (self->color_state);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright (C) 2021 Benjamin Otte
|
||||
*
|
||||
* 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/gdktypes.h>
|
||||
#include <gdk/gdkcolorstate.h>
|
||||
#include <gdk/gdkrgba.h>
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
|
||||
|
||||
typedef struct _GdkColor GdkColor;
|
||||
|
||||
/* The interpretation of the first 3 components depends on the color state.
|
||||
* values[3] is always alpha.
|
||||
*/
|
||||
struct _GdkColor
|
||||
{
|
||||
GdkColorState *color_state;
|
||||
union {
|
||||
float values[4];
|
||||
struct {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
struct {
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float alpha;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, r) == G_STRUCT_OFFSET (GdkColor, red));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, g) == G_STRUCT_OFFSET (GdkColor, green));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, b) == G_STRUCT_OFFSET (GdkColor, blue));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, a) == G_STRUCT_OFFSET (GdkColor, alpha));
|
||||
|
||||
/* The committee notes that since all known implementations but one "get it right"
|
||||
* this may well not be a defect at all.
|
||||
* https://open-std.org/JTC1/SC22/WG14/www/docs/n2396.htm#dr_496
|
||||
*/
|
||||
#ifndef _MSC_VER
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, r) == G_STRUCT_OFFSET (GdkColor, values[0]));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, g) == G_STRUCT_OFFSET (GdkColor, values[1]));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, b) == G_STRUCT_OFFSET (GdkColor, values[2]));
|
||||
G_STATIC_ASSERT (G_STRUCT_OFFSET (GdkColor, a) == G_STRUCT_OFFSET (GdkColor, values[3]));
|
||||
#endif
|
||||
|
||||
#define GDK_COLOR_SRGB(r,g,b,a) (GdkColor) { \
|
||||
.color_state = GDK_COLOR_STATE_SRGB, \
|
||||
.values = { (r), (g), (b), (a) } \
|
||||
}
|
||||
|
||||
void gdk_color_init (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const float values[4]);
|
||||
void gdk_color_init_copy (GdkColor *self,
|
||||
const GdkColor *color);
|
||||
void gdk_color_init_from_rgba (GdkColor *self,
|
||||
const GdkRGBA *rgba);
|
||||
void gdk_color_finish (GdkColor *self);
|
||||
|
||||
gboolean gdk_color_equal (const GdkColor *color1,
|
||||
const GdkColor *color2);
|
||||
gboolean gdk_color_is_clear (const GdkColor *self);
|
||||
gboolean gdk_color_is_opaque (const GdkColor *self);
|
||||
GdkMemoryDepth gdk_color_get_depth (const GdkColor *self);
|
||||
|
||||
void gdk_color_convert (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const GdkColor *other);
|
||||
|
||||
void gdk_color_to_float (const GdkColor *self,
|
||||
GdkColorState *target,
|
||||
float values[4]);
|
||||
|
||||
void gdk_color_from_rgba (GdkColor *self,
|
||||
GdkColorState *color_state,
|
||||
const GdkRGBA *rgba);
|
||||
|
||||
void gdk_color_print (const GdkColor *self,
|
||||
GString *string);
|
||||
|
||||
char * gdk_color_to_string (const GdkColor *self);
|
||||
|
||||
#include "gdkcolorimpl.h"
|
||||
|
||||
G_END_DECLS
|
||||
+22
-202
@@ -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;
|
||||
@@ -821,10 +676,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
to_xyz = rec2020_to_xyz;
|
||||
from_xyz = xyz_to_rec2020;
|
||||
break;
|
||||
case 10:
|
||||
to_xyz = identity;
|
||||
from_xyz = identity;
|
||||
break;
|
||||
case 12:
|
||||
to_xyz = p3_to_xyz;
|
||||
from_xyz = xyz_to_p3;
|
||||
@@ -837,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;
|
||||
@@ -877,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;
|
||||
|
||||
|
||||
+53
-28
@@ -74,9 +74,19 @@ extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
|
||||
const char * gdk_color_state_get_name (GdkColorState *color_state);
|
||||
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
|
||||
|
||||
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
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;
|
||||
|
||||
@@ -158,38 +168,53 @@ gdk_color_state_get_convert_from (GdkColorState *self,
|
||||
return self->klass->get_convert_from (self, source);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_color_state_from_rgba (GdkColorState *self,
|
||||
const GdkRGBA *rgba,
|
||||
float out_color[4])
|
||||
{
|
||||
GdkFloatColorConvert convert;
|
||||
|
||||
out_color[0] = rgba->red;
|
||||
out_color[1] = rgba->green;
|
||||
out_color[2] = rgba->blue;
|
||||
out_color[3] = rgba->alpha;
|
||||
|
||||
if (gdk_color_state_equal (GDK_COLOR_STATE_SRGB, self))
|
||||
return;
|
||||
|
||||
convert = gdk_color_state_get_convert_to (GDK_COLOR_STATE_SRGB, self);
|
||||
convert (GDK_COLOR_STATE_SRGB, (float(*)[4]) out_color, 1);
|
||||
}
|
||||
|
||||
static inline const GdkCicp *
|
||||
gdk_color_state_get_cicp (GdkColorState *self)
|
||||
{
|
||||
return self->klass->get_cicp (self);
|
||||
}
|
||||
|
||||
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
GError **error);
|
||||
static inline void
|
||||
gdk_color_state_convert_color (GdkColorState *src_cs,
|
||||
const float src[4],
|
||||
GdkColorState *dest_cs,
|
||||
float dest[4])
|
||||
{
|
||||
GdkFloatColorConvert convert = NULL;
|
||||
GdkFloatColorConvert convert2 = NULL;
|
||||
|
||||
#ifndef GDK_COLOR_STATE_IMPL
|
||||
extern GdkColorState gdk_color_state_bt601_narrow;
|
||||
extern GdkColorState gdk_color_state_bt601_full;
|
||||
#endif
|
||||
memcpy (dest, src, sizeof (float) * 4);
|
||||
|
||||
if (gdk_color_state_equal (src_cs, dest_cs))
|
||||
return;
|
||||
|
||||
convert = gdk_color_state_get_convert_to (src_cs, dest_cs);
|
||||
|
||||
if (!convert)
|
||||
convert2 = gdk_color_state_get_convert_from (dest_cs, src_cs);
|
||||
|
||||
if (!convert && !convert2)
|
||||
{
|
||||
GdkColorState *connection = GDK_COLOR_STATE_REC2100_LINEAR;
|
||||
convert = gdk_color_state_get_convert_to (src_cs, connection);
|
||||
convert2 = gdk_color_state_get_convert_from (dest_cs, connection);
|
||||
}
|
||||
|
||||
if (convert)
|
||||
convert (src_cs, (float(*)[4]) dest, 1);
|
||||
|
||||
if (convert2)
|
||||
convert2 (dest_cs, (float(*)[4]) dest, 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_color_state_from_rgba (GdkColorState *self,
|
||||
const GdkRGBA *rgba,
|
||||
float out_color[4])
|
||||
{
|
||||
gdk_color_state_convert_color (GDK_COLOR_STATE_SRGB,
|
||||
(const float *) rgba,
|
||||
self,
|
||||
out_color);
|
||||
}
|
||||
|
||||
#define GDK_COLOR_STATE_YUV ((GdkColorState *) &gdk_color_state_bt601_narrow)
|
||||
#define GDK_COLOR_STATE_JPEG ((GdkColorState *) &gdk_color_state_bt601_full)
|
||||
|
||||
+101
-56
@@ -24,7 +24,6 @@
|
||||
#include "gdkdmabuffourccprivate.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkcolorstate.h"
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <sys/mman.h>
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-16
@@ -637,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;
|
||||
@@ -2179,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)
|
||||
@@ -2192,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;
|
||||
@@ -2217,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);
|
||||
@@ -2235,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)
|
||||
{
|
||||
@@ -2266,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)
|
||||
{
|
||||
@@ -2300,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)
|
||||
|
||||
@@ -184,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,
|
||||
|
||||
+31
-9
@@ -358,7 +358,7 @@ struct _GdkMemoryFormatDescription
|
||||
|
||||
static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
|
||||
.name = "*BGRA8",
|
||||
.name = "BGRA8(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_B8G8R8A8,
|
||||
@@ -389,7 +389,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = b8g8r8a8_premultiplied_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
|
||||
.name = "*ARGB8",
|
||||
.name = "ARGB8(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_A8R8G8B8,
|
||||
@@ -420,7 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = a8r8g8b8_premultiplied_from_float,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
|
||||
.name = "*RGBA8",
|
||||
.name = "RGBA8(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_R8G8B8A8,
|
||||
@@ -450,7 +450,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = r8g8b8a8_premultiplied_from_float,
|
||||
},
|
||||
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = {
|
||||
.name = "*ABGR8",
|
||||
.name = "ABGR8(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_A8B8G8R8_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_A8B8G8R8,
|
||||
@@ -828,7 +828,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = r16g16b16_from_float,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
|
||||
.name = "*RGBA16",
|
||||
.name = "RGBA16(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_R16G16B16A16,
|
||||
@@ -927,7 +927,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = r16g16b16_float_from_float,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
|
||||
.name = "*RGBA16f",
|
||||
.name = "RGBA16f(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_R16G16B16A16_FLOAT,
|
||||
@@ -1024,7 +1024,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = r32g32b32_float_from_float,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
|
||||
.name = "*RGBA32f",
|
||||
.name = "RGBA32f(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_R32G32B32A32_FLOAT,
|
||||
@@ -1088,7 +1088,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = r32g32b32a32_float_from_float,
|
||||
},
|
||||
[GDK_MEMORY_G8A8_PREMULTIPLIED] = {
|
||||
.name = "*GA8",
|
||||
.name = "GA8(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_G8A8_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_G8A8,
|
||||
@@ -1181,7 +1181,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
.from_float = g8_from_float,
|
||||
},
|
||||
[GDK_MEMORY_G16A16_PREMULTIPLIED] = {
|
||||
.name = "*GA16",
|
||||
.name = "GA16(p)",
|
||||
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
.premultiplied = GDK_MEMORY_G16A16_PREMULTIPLIED,
|
||||
.straight = GDK_MEMORY_G16A16,
|
||||
@@ -1524,6 +1524,14 @@ gdk_memory_format_get_depth (GdkMemoryFormat format,
|
||||
return depth;
|
||||
}
|
||||
|
||||
const char *
|
||||
gdk_memory_depth_get_name (GdkMemoryDepth depth)
|
||||
{
|
||||
const char *names[] = { "none", "u8", "u8-srgb", "u16", "f16", "f32" };
|
||||
|
||||
return names[depth];
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_memory_depth_merge:
|
||||
* @depth1: the first depth
|
||||
@@ -1871,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;
|
||||
@@ -1944,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);
|
||||
@@ -1966,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);
|
||||
|
||||
@@ -2151,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)
|
||||
|
||||
@@ -66,6 +66,7 @@ GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth
|
||||
GdkMemoryDepth depth2) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
const char * gdk_memory_depth_get_name (GdkMemoryDepth depth);
|
||||
void gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
GLint *out_internal_format,
|
||||
|
||||
+3
-1
@@ -1132,8 +1132,10 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
|
||||
|
||||
if (priv->egl_surface != NULL)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (self);
|
||||
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+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);
|
||||
|
||||
@@ -785,20 +785,13 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
if (decorated)
|
||||
{
|
||||
style_mask &= ~NSWindowStyleMaskFullSizeContentView;
|
||||
[self setTitleVisibility:NSWindowTitleVisible];
|
||||
style_mask |= NSWindowStyleMaskTitled;
|
||||
}
|
||||
else
|
||||
{
|
||||
style_mask |= NSWindowStyleMaskFullSizeContentView;
|
||||
[self setTitleVisibility:NSWindowTitleHidden];
|
||||
style_mask &= ~NSWindowStyleMaskTitled;
|
||||
}
|
||||
|
||||
[self setTitlebarAppearsTransparent:!decorated];
|
||||
[[self standardWindowButton:NSWindowCloseButton] setHidden:!decorated];
|
||||
[[self standardWindowButton:NSWindowMiniaturizeButton] setHidden:!decorated];
|
||||
[[self standardWindowButton:NSWindowZoomButton] setHidden:!decorated];
|
||||
|
||||
[self setStyleMask:style_mask];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ gdk_public_sources = files([
|
||||
'gdkcairocontext.c',
|
||||
'gdkcicpparams.c',
|
||||
'gdkclipboard.c',
|
||||
'gdkcolor.c',
|
||||
'gdkcolorstate.c',
|
||||
'gdkcontentdeserializer.c',
|
||||
'gdkcontentformats.c',
|
||||
|
||||
@@ -236,6 +236,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
/* offer formats should be empty if we have no offer */
|
||||
@@ -246,6 +247,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,6 +255,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
|
||||
@@ -203,6 +203,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,6 +212,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,6 +220,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
|
||||
@@ -335,6 +335,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
/* offer formats should be empty if we have no offer */
|
||||
@@ -345,6 +346,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
|
||||
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,6 +354,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
|
||||
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
|
||||
close (pipe_fd[1]);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
|
||||
@@ -1016,6 +1016,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
g_clear_pointer (&drop_win32->dropfiles_list, g_free);
|
||||
|
||||
return;
|
||||
@@ -1025,6 +1026,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
drop_win32->dropfiles_list = NULL;
|
||||
g_object_set_data (G_OBJECT (stream), "gdk-dnd-stream-contenttype", (gpointer) "text/uri-list");
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
g_object_unref (task);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1035,6 +1037,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("GDK surface 0x%p is not registered as a drop target"), gdk_drop_get_surface (drop));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1042,6 +1045,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("Target context record 0x%p has no data object"), tctx);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1061,6 +1065,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1080,6 +1085,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("IDataObject_GetData (0x%x) failed, returning 0x%lx"), fmt.cfFormat, hr);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1092,6 +1098,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
if (data == NULL)
|
||||
{
|
||||
ReleaseStgMedium (&storage);
|
||||
g_object_unref (task);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1112,12 +1119,14 @@ gdk_win32_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
_("Failed to transmute DnD data W32 format 0x%x to %p (%s)"), pair->w32format, pair->contentformat, pair->contentformat);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (data, data_len, g_free);
|
||||
g_object_set_data (G_OBJECT (stream), "gdk-dnd-stream-contenttype", (gpointer) pair->contentformat);
|
||||
g_task_return_pointer (task, stream, g_object_unref);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
|
||||
@@ -797,6 +797,7 @@ gdk_x11_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@ gdk_x11_drop_read_async (GdkDrop *drop,
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No compatible transfer format found"));
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -812,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);
|
||||
|
||||
@@ -831,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;
|
||||
|
||||
+20
-9
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkcolorprivate.h>
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkprofilerprivate.h>
|
||||
#include <gdk/gdkrgbaprivate.h>
|
||||
@@ -1447,20 +1448,28 @@ blur_node (GskGLRenderJob *job,
|
||||
|
||||
#define ATLAS_SIZE 512
|
||||
|
||||
static void
|
||||
get_color_node_color_as_srgb (const GskRenderNode *node,
|
||||
GdkRGBA *rgba)
|
||||
{
|
||||
const GdkColor *color = gsk_color_node_get_color2 (node);
|
||||
gdk_color_to_float (color, GDK_COLOR_STATE_SRGB, (float *) rgba);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_color_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
const GdkRGBA *rgba;
|
||||
GdkRGBA rgba;
|
||||
guint16 color[4];
|
||||
GskGLProgram *program;
|
||||
GskGLCommandBatch *batch;
|
||||
|
||||
rgba = gsk_color_node_get_color (node);
|
||||
if (RGBA_IS_CLEAR (rgba))
|
||||
get_color_node_color_as_srgb (node, &rgba);
|
||||
if (RGBA_IS_CLEAR (&rgba))
|
||||
return;
|
||||
|
||||
rgba_to_half (rgba, color);
|
||||
rgba_to_half (&rgba, color);
|
||||
|
||||
/* Avoid switching away from the coloring program for
|
||||
* rendering a solid color.
|
||||
@@ -1965,12 +1974,14 @@ gsk_gl_render_job_visit_css_background (GskGLRenderJob *job,
|
||||
GskGLDrawVertex *vertices;
|
||||
guint16 color[4];
|
||||
guint16 color2[4];
|
||||
GdkRGBA rgba;
|
||||
|
||||
if (node_is_invisible (node2))
|
||||
return;
|
||||
|
||||
get_color_node_color_as_srgb (child, &rgba);
|
||||
rgba_to_half (&gsk_border_node_get_colors (node2)[0], color);
|
||||
rgba_to_half (gsk_color_node_get_color (child), color2);
|
||||
rgba_to_half (&rgba, color2);
|
||||
|
||||
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
|
||||
|
||||
@@ -3328,10 +3339,10 @@ gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
|
||||
{
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (mask);
|
||||
const GdkRGBA *rgba;
|
||||
GdkRGBA rgba;
|
||||
|
||||
rgba = gsk_color_node_get_color (color);
|
||||
if (RGBA_IS_CLEAR (rgba))
|
||||
get_color_node_color_as_srgb (color, &rgba);
|
||||
if (RGBA_IS_CLEAR (&rgba))
|
||||
return TRUE;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
@@ -3347,7 +3358,7 @@ gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
|
||||
use_mipmap = (scale_x * fabsf (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabsf (job->scale_y)) < 0.5;
|
||||
|
||||
rgba_to_half (rgba, cc);
|
||||
rgba_to_half (&rgba, cc);
|
||||
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
|
||||
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
|
||||
+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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ 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, instance->blur_color);
|
||||
gsk_gpu_vec4_to_float (blur_color, instance->blur_color);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -121,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], &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;
|
||||
|
||||
@@ -102,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, 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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -104,14 +104,13 @@ static const GskGpuOpClass GSK_GPU_CLEAR_OP_CLASS = {
|
||||
|
||||
void
|
||||
gsk_gpu_clear_op (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
const GdkRGBA *color)
|
||||
const float color[4])
|
||||
{
|
||||
GskGpuClearOp *self;
|
||||
|
||||
self = (GskGpuClearOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_CLEAR_OP_CLASS);
|
||||
|
||||
self->rect = *rect;
|
||||
gdk_color_state_from_rgba (ccs, color, self->color);
|
||||
memcpy (self->color, color, sizeof (float) * 4);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
#include "gskgpucolorstatesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_clear_op (GskGpuFrame *frame,
|
||||
GdkColorState *ccs,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
const GdkRGBA *color);
|
||||
const float color[4]);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -70,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, instance->color);
|
||||
gsk_gpu_vec4_to_float (color, instance->color);
|
||||
}
|
||||
|
||||
@@ -53,16 +53,20 @@ static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
const graphene_rect_t *rect,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const float color[4])
|
||||
const graphene_rect_t *rect,
|
||||
const GdkColor *color)
|
||||
{
|
||||
GskGpuColorInstance *instance;
|
||||
GdkColorState *alt;
|
||||
|
||||
alt = gsk_gpu_color_states_find (ccs, color);
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_COLOR_OP_CLASS,
|
||||
color_states,
|
||||
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
|
||||
0,
|
||||
clip,
|
||||
NULL,
|
||||
@@ -70,5 +74,5 @@ gsk_gpu_color_op (GskGpuFrame *frame,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
gsk_gpu_color_to_float (color, instance->color);
|
||||
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
@@ -8,10 +9,11 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
const graphene_rect_t *rect,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const float color[4]);
|
||||
const graphene_rect_t *rect,
|
||||
const GdkColor *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
|
||||
#include "gdk/gdkcolorprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
|
||||
#define COLOR_SPACE_OUTPUT_PREMULTIPLIED (1u << 2)
|
||||
@@ -73,3 +74,12 @@ gsk_gpu_color_states_is_alt_premultiplied (GskGpuColorStates self)
|
||||
return !!(self & COLOR_SPACE_ALT_PREMULTIPLIED);
|
||||
}
|
||||
|
||||
static inline GdkColorState *
|
||||
gsk_gpu_color_states_find (GdkColorState *ccs,
|
||||
const GdkColor *color)
|
||||
{
|
||||
if (GDK_IS_DEFAULT_COLOR_STATE (color->color_state))
|
||||
return color->color_state;
|
||||
else
|
||||
return ccs;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+102
-36
@@ -20,6 +20,7 @@
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <glib-unix.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#endif
|
||||
|
||||
@@ -32,6 +33,8 @@ struct _GskGpuDownloadOp
|
||||
GskGpuOp op;
|
||||
|
||||
GskGpuImage *image;
|
||||
GdkColorState *image_cs;
|
||||
GdkColorState *download_cs;
|
||||
gboolean allow_dmabuf;
|
||||
GdkGpuDownloadOpCreateFunc create_func;
|
||||
GskGpuDownloadFunc func;
|
||||
@@ -52,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);
|
||||
@@ -69,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);
|
||||
}
|
||||
|
||||
@@ -117,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);
|
||||
@@ -124,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);
|
||||
}
|
||||
@@ -143,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);
|
||||
@@ -294,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)
|
||||
{
|
||||
@@ -316,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);
|
||||
@@ -342,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,
|
||||
@@ -366,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)
|
||||
@@ -376,35 +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;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_download_save_png_cb (gpointer filename,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
gdk_texture_save_to_png (texture, filename);
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_download_png_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
const char *filename_format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
char *filename;
|
||||
|
||||
va_start (args, filename_format);
|
||||
filename = g_strdup_vprintf (filename_format, args);
|
||||
va_end (args);
|
||||
|
||||
gsk_gpu_download_op (frame,
|
||||
image,
|
||||
FALSE,
|
||||
gsk_gpu_download_save_png_cb,
|
||||
filename);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,11 @@ 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);
|
||||
|
||||
void gsk_gpu_download_png_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
const char *filename_format,
|
||||
...) G_GNUC_PRINTF(3, 4);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+16
-1
@@ -671,7 +671,20 @@ gsk_gpu_frame_record (GskGpuFrame *self,
|
||||
}
|
||||
|
||||
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
|
||||
@@ -778,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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+130
-87
@@ -43,6 +43,7 @@
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
#include "gdk/gdkcairoprivate.h"
|
||||
#include "gdk/gdkmemorytextureprivate.h"
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdksubsurfaceprivate.h"
|
||||
@@ -98,6 +99,7 @@
|
||||
* never uses it, other than to allow the vertex shaders to emit its vertices.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct _GskGpuNodeProcessor GskGpuNodeProcessor;
|
||||
|
||||
typedef enum {
|
||||
@@ -618,15 +620,18 @@ gsk_gpu_copy_image (GskGpuFrame *frame,
|
||||
GskGpuImage *copy;
|
||||
gsize width, height;
|
||||
GskGpuImageFlags flags;
|
||||
GdkMemoryDepth depth;
|
||||
|
||||
width = gsk_gpu_image_get_width (image);
|
||||
height = gsk_gpu_image_get_height (image);
|
||||
flags = gsk_gpu_image_get_flags (image);
|
||||
depth = gdk_memory_format_get_depth (gsk_gpu_image_get_format (image),
|
||||
flags & GSK_GPU_IMAGE_SRGB);
|
||||
depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (ccs));
|
||||
|
||||
copy = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
|
||||
prepare_mipmap,
|
||||
gdk_memory_format_get_depth (gsk_gpu_image_get_format (image),
|
||||
flags & GSK_GPU_IMAGE_SRGB),
|
||||
depth,
|
||||
width, height);
|
||||
|
||||
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_BLIT) &&
|
||||
@@ -1011,6 +1016,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
GskGpuNodeProcessor other;
|
||||
graphene_rect_t clip_bounds, child_rect;
|
||||
GskGpuImage *child_image, *mask_image;
|
||||
GdkColor white;
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
@@ -1030,13 +1036,16 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
gsk_render_node_get_preferred_depth (node)),
|
||||
&self->scale,
|
||||
&clip_bounds);
|
||||
|
||||
gdk_color_init (&white, self->ccs, ((float[]){ 1, 1, 1, 1 }));
|
||||
gsk_gpu_node_processor_sync_globals (&other, 0);
|
||||
gsk_gpu_rounded_color_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_self (&other),
|
||||
gsk_rounded_clip_node_get_clip (node),
|
||||
self->ccs,
|
||||
1,
|
||||
&other.offset,
|
||||
(float[4]) { 1, 1, 1, 1 });
|
||||
gsk_rounded_clip_node_get_clip (node),
|
||||
&white);
|
||||
gsk_gpu_node_processor_finish_draw (&other, mask_image);
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (self, 0);
|
||||
@@ -1061,6 +1070,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
|
||||
g_object_unref (child_image);
|
||||
g_object_unref (mask_image);
|
||||
gdk_color_finish (&white);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1080,15 +1090,15 @@ gsk_gpu_node_processor_add_rounded_clip_node (GskGpuNodeProcessor *self,
|
||||
if (gsk_render_node_get_node_type (child) == GSK_COLOR_NODE &&
|
||||
gsk_rect_contains_rect (&child->bounds, &original_clip->bounds))
|
||||
{
|
||||
const GdkRGBA *rgba = gsk_color_node_get_color (child);
|
||||
gsk_gpu_node_processor_sync_globals (self, 0);
|
||||
|
||||
gsk_gpu_rounded_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &original_clip->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
original_clip,
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&self->offset,
|
||||
GSK_RGBA_TO_VEC4_ALPHA (rgba, self->opacity));
|
||||
original_clip,
|
||||
gsk_color_node_get_color2 (child));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1470,16 +1480,15 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
{
|
||||
cairo_rectangle_int_t int_clipped;
|
||||
graphene_rect_t rect, clipped;
|
||||
const GdkRGBA *color;
|
||||
float clear_color[4];
|
||||
|
||||
color = gsk_color_node_get_color (node);
|
||||
graphene_rect_offset_r (&node->bounds,
|
||||
self->offset.x, self->offset.y,
|
||||
&rect);
|
||||
gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped);
|
||||
|
||||
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) &&
|
||||
gdk_rgba_is_opaque (color) &&
|
||||
gdk_color_is_opaque (gsk_color_node_get_color2 (node)) &&
|
||||
self->opacity >= 1.0 &&
|
||||
node->bounds.size.width * node->bounds.size.height > 100 * 100 && /* not worth the effort for small images */
|
||||
gsk_gpu_node_processor_rect_is_integer (self, &clipped, &int_clipped))
|
||||
@@ -1500,10 +1509,11 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
/* Yuck, rounded clip and modelview. I give up. */
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&node->bounds,
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&self->offset,
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
&node->bounds,
|
||||
gsk_color_node_get_color2 (node));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1523,10 +1533,11 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
{
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&clipped,
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
graphene_point_zero (),
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
&clipped,
|
||||
gsk_color_node_get_color2 (node));
|
||||
return;
|
||||
}
|
||||
cover = GRAPHENE_RECT_INIT (int_clipped.x / scale_x, int_clipped.y / scale_y,
|
||||
@@ -1534,53 +1545,64 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
if (clipped.origin.x != cover.origin.x)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, cover.origin.x - clipped.origin.x, clipped.size.height),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
graphene_point_zero (),
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, cover.origin.x - clipped.origin.x, clipped.size.height),
|
||||
gsk_color_node_get_color2 (node));
|
||||
if (clipped.origin.y != cover.origin.y)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, clipped.size.width, cover.origin.y - clipped.origin.y),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
graphene_point_zero (),
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, clipped.size.width, cover.origin.y - clipped.origin.y),
|
||||
gsk_color_node_get_color2 (node));
|
||||
if (clipped.origin.x + clipped.size.width != cover.origin.x + cover.size.width)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
graphene_point_zero (),
|
||||
&GRAPHENE_RECT_INIT (cover.origin.x + cover.size.width,
|
||||
clipped.origin.y,
|
||||
clipped.origin.x + clipped.size.width - cover.origin.x - cover.size.width,
|
||||
clipped.size.height),
|
||||
graphene_point_zero (),
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
gsk_color_node_get_color2 (node));
|
||||
if (clipped.origin.y + clipped.size.height != cover.origin.y + cover.size.height)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
graphene_point_zero (),
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x,
|
||||
cover.origin.y + cover.size.height,
|
||||
clipped.size.width,
|
||||
clipped.origin.y + clipped.size.height - cover.origin.y - cover.size.height),
|
||||
graphene_point_zero (),
|
||||
GSK_RGBA_TO_VEC4 (color));
|
||||
gsk_color_node_get_color2 (node));
|
||||
}
|
||||
}
|
||||
|
||||
gsk_gpu_clear_op (self->frame,
|
||||
self->ccs,
|
||||
&int_clipped,
|
||||
color);
|
||||
gdk_color_to_float (gsk_color_node_get_color2 (node), self->ccs, clear_color);
|
||||
g_print ("node processor: add color via clear %s -> %s %f %f %f %f\n",
|
||||
gdk_color_to_string (gsk_color_node_get_color2 (node)),
|
||||
gdk_color_state_get_name (self->ccs),
|
||||
clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
|
||||
gsk_gpu_clear_op (self->frame, &int_clipped, clear_color);
|
||||
return;
|
||||
}
|
||||
|
||||
g_print ("node processor: add color %s -> %s\n",
|
||||
gdk_color_to_string (gsk_color_node_get_color2 (node)),
|
||||
gdk_color_state_get_name (self->ccs));
|
||||
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&node->bounds,
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&self->offset,
|
||||
GSK_RGBA_TO_VEC4_ALPHA (color, self->opacity));
|
||||
&node->bounds,
|
||||
gsk_color_node_get_color2 (node));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1591,7 +1613,7 @@ gsk_gpu_node_processor_add_first_color_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
graphene_rect_t clip_bounds;
|
||||
float color[4];
|
||||
float clear_color[4];
|
||||
|
||||
if (!node->fully_opaque)
|
||||
return FALSE;
|
||||
@@ -1600,11 +1622,15 @@ gsk_gpu_node_processor_add_first_color_node (GskGpuNodeProcessor *self,
|
||||
if (!gsk_rect_contains_rect (&node->bounds, &clip_bounds))
|
||||
return FALSE;
|
||||
|
||||
gdk_color_state_from_rgba (self->ccs, gsk_color_node_get_color (node), color);
|
||||
gdk_color_to_float (gsk_color_node_get_color2 (node), self->ccs, clear_color);
|
||||
g_print ("node processor: add first color %s -> %s %f %f %f %f\n",
|
||||
gdk_color_to_string (gsk_color_node_get_color2 (node)),
|
||||
gdk_color_state_get_name (self->ccs),
|
||||
clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
|
||||
gsk_gpu_render_pass_begin_op (self->frame,
|
||||
target,
|
||||
clip,
|
||||
color,
|
||||
clear_color,
|
||||
pass_type);
|
||||
|
||||
return TRUE;
|
||||
@@ -1659,6 +1685,7 @@ gsk_gpu_lookup_texture (GskGpuFrame *frame,
|
||||
GdkColorState **out_image_cs)
|
||||
{
|
||||
GskGpuCache *cache;
|
||||
GdkColorState *image_cs;
|
||||
GskGpuImage *image;
|
||||
|
||||
cache = gsk_gpu_device_get_cache (gsk_gpu_frame_get_device (frame));
|
||||
@@ -1666,7 +1693,7 @@ gsk_gpu_lookup_texture (GskGpuFrame *frame,
|
||||
image = gsk_gpu_cache_lookup_texture_image (cache, texture, ccs);
|
||||
if (image)
|
||||
{
|
||||
*out_image_cs = gdk_color_state_ref (ccs);
|
||||
*out_image_cs = ccs;
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -1676,14 +1703,17 @@ gsk_gpu_lookup_texture (GskGpuFrame *frame,
|
||||
|
||||
/* Happens ie for oversized textures */
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
|
||||
image_cs = gdk_texture_get_color_state (texture);
|
||||
|
||||
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
|
||||
{
|
||||
*out_image_cs = NULL;
|
||||
return NULL;
|
||||
image_cs = gdk_color_state_get_no_srgb_tf (image_cs);
|
||||
g_assert (image_cs);
|
||||
}
|
||||
|
||||
*out_image_cs = gsk_gpu_image_adjust_color_state (image,
|
||||
gdk_texture_get_color_state (texture));
|
||||
|
||||
*out_image_cs = image_cs;
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -1717,6 +1747,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
GskGpuCache *cache;
|
||||
GskGpuDevice *device;
|
||||
GskGpuImage *tile;
|
||||
GdkColorState *tile_cs;
|
||||
GskGpuSampler sampler;
|
||||
gboolean need_mipmap;
|
||||
GdkMemoryTexture *memtex;
|
||||
@@ -1743,8 +1774,6 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
{
|
||||
for (x = 0; x < n_width; x++)
|
||||
{
|
||||
GdkColorState *tile_cs = NULL;
|
||||
|
||||
graphene_rect_t tile_rect = GRAPHENE_RECT_INIT (texture_bounds->origin.x + scaled_tile_width * x,
|
||||
texture_bounds->origin.y + scaled_tile_height * y,
|
||||
scaled_tile_width,
|
||||
@@ -1773,8 +1802,13 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
tile_cs = gsk_gpu_image_adjust_color_state (tile,
|
||||
gdk_texture_get_color_state (texture));
|
||||
tile_cs = gdk_texture_get_color_state (texture);
|
||||
if (gsk_gpu_image_get_flags (tile) & GSK_GPU_IMAGE_SRGB)
|
||||
{
|
||||
tile_cs = gdk_color_state_get_no_srgb_tf (tile_cs);
|
||||
g_assert (tile_cs);
|
||||
}
|
||||
|
||||
gsk_gpu_cache_cache_tile (cache, texture, y * n_width + x, tile, tile_cs);
|
||||
}
|
||||
|
||||
@@ -1782,8 +1816,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
(gsk_gpu_image_get_flags (tile) & (GSK_GPU_IMAGE_STRAIGHT_ALPHA | GSK_GPU_IMAGE_CAN_MIPMAP)) != GSK_GPU_IMAGE_CAN_MIPMAP)
|
||||
{
|
||||
tile = gsk_gpu_copy_image (self->frame, self->ccs, tile, tile_cs, TRUE);
|
||||
gdk_color_state_unref (tile_cs);
|
||||
tile_cs = gdk_color_state_ref (self->ccs);
|
||||
tile_cs = self->ccs;
|
||||
gsk_gpu_cache_cache_tile (cache, texture, y * n_width + x, tile, tile_cs);
|
||||
}
|
||||
if (need_mipmap && !(gsk_gpu_image_get_flags (tile) & GSK_GPU_IMAGE_MIPMAP))
|
||||
@@ -1796,7 +1829,6 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
&tile_rect,
|
||||
&tile_rect);
|
||||
|
||||
gdk_color_state_unref (tile_cs);
|
||||
g_object_unref (tile);
|
||||
}
|
||||
}
|
||||
@@ -1885,8 +1917,7 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
|
||||
!gdk_color_state_equal (image_cs, self->ccs))
|
||||
{
|
||||
image = gsk_gpu_copy_image (self->frame, self->ccs, image, image_cs, TRUE);
|
||||
gdk_color_state_unref (image_cs);
|
||||
image_cs = gdk_color_state_ref (self->ccs);
|
||||
image_cs = self->ccs;
|
||||
gsk_gpu_cache_cache_texture_image (gsk_gpu_device_get_cache (gsk_gpu_frame_get_device (self->frame)),
|
||||
texture,
|
||||
image,
|
||||
@@ -1913,7 +1944,6 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self,
|
||||
&node->bounds);
|
||||
}
|
||||
|
||||
gdk_color_state_unref (image_cs);
|
||||
g_object_unref (image);
|
||||
}
|
||||
|
||||
@@ -1960,7 +1990,6 @@ gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame,
|
||||
}
|
||||
|
||||
*out_bounds = node->bounds;
|
||||
gdk_color_state_unref (image_cs);
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -1999,7 +2028,6 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
/* now intersect with actual node bounds */
|
||||
if (!gsk_rect_intersection (&clip_bounds, &node->bounds, &clip_bounds))
|
||||
{
|
||||
gdk_color_state_unref (image_cs);
|
||||
g_object_unref (image);
|
||||
return;
|
||||
}
|
||||
@@ -2042,8 +2070,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
!gdk_color_state_equal (image_cs, self->ccs))
|
||||
{
|
||||
image = gsk_gpu_copy_image (self->frame, self->ccs, image, image_cs, need_mipmap);
|
||||
gdk_color_state_unref (image_cs);
|
||||
image_cs = gdk_color_state_ref (self->ccs);
|
||||
image_cs = self->ccs;
|
||||
gsk_gpu_cache_cache_texture_image (gsk_gpu_device_get_cache (gsk_gpu_frame_get_device (self->frame)),
|
||||
texture,
|
||||
image,
|
||||
@@ -2063,7 +2090,6 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
&node->bounds,
|
||||
});
|
||||
|
||||
gdk_color_state_unref (image_cs);
|
||||
g_object_unref (image);
|
||||
}
|
||||
|
||||
@@ -2510,14 +2536,13 @@ static void
|
||||
gsk_gpu_node_processor_add_gl_shader_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 };
|
||||
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
&node->bounds,
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&self->offset,
|
||||
GSK_RGBA_TO_VEC4_ALPHA (&pink, self->opacity));
|
||||
&node->bounds,
|
||||
&GDK_COLOR_SRGB (1, 105/255., 180/255., 1));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2696,10 +2721,14 @@ gsk_gpu_node_processor_add_mask_node (GskGpuNodeProcessor *self,
|
||||
if (gsk_render_node_get_node_type (source_child) == GSK_COLOR_NODE &&
|
||||
mask_mode == GSK_MASK_MODE_ALPHA)
|
||||
{
|
||||
const GdkRGBA *rgba = gsk_color_node_get_color (source_child);
|
||||
float color[4];
|
||||
|
||||
gdk_color_to_float (gsk_color_node_get_color2 (source_child), self->ccs, color);
|
||||
color[3] *= self->opacity;
|
||||
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
gsk_gpu_node_processor_color_states_explicit (self, self->ccs, FALSE),
|
||||
&self->offset,
|
||||
&(GskGpuShaderImage) {
|
||||
mask_image,
|
||||
@@ -2707,7 +2736,7 @@ gsk_gpu_node_processor_add_mask_node (GskGpuNodeProcessor *self,
|
||||
&node->bounds,
|
||||
&mask_rect,
|
||||
},
|
||||
GSK_RGBA_TO_VEC4_ALPHA (rgba, self->opacity));
|
||||
color);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3089,7 +3118,7 @@ typedef struct _FillData FillData;
|
||||
struct _FillData
|
||||
{
|
||||
GskPath *path;
|
||||
GdkRGBA color;
|
||||
GdkColor color;
|
||||
GskFillRule fill_rule;
|
||||
};
|
||||
|
||||
@@ -3098,6 +3127,7 @@ gsk_fill_data_free (gpointer data)
|
||||
{
|
||||
FillData *fill = data;
|
||||
|
||||
gdk_color_finish (&fill->color);
|
||||
gsk_path_unref (fill->path);
|
||||
g_free (fill);
|
||||
}
|
||||
@@ -3121,7 +3151,7 @@ gsk_gpu_node_processor_fill_path (gpointer data,
|
||||
break;
|
||||
}
|
||||
gsk_path_to_cairo (fill->path, cr);
|
||||
gdk_cairo_set_source_rgba (cr, &fill->color);
|
||||
gdk_cairo_set_source_color (cr, GDK_COLOR_STATE_SRGB, &fill->color);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
@@ -3132,6 +3162,7 @@ gsk_gpu_node_processor_add_fill_node (GskGpuNodeProcessor *self,
|
||||
graphene_rect_t clip_bounds, source_rect;
|
||||
GskGpuImage *mask_image, *source_image;
|
||||
GskRenderNode *child;
|
||||
GdkColor color;
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
@@ -3139,15 +3170,18 @@ gsk_gpu_node_processor_add_fill_node (GskGpuNodeProcessor *self,
|
||||
|
||||
child = gsk_fill_node_get_child (node);
|
||||
|
||||
if (GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE)
|
||||
gdk_color_init_copy (&color, gsk_color_node_get_color2 (child));
|
||||
else
|
||||
gdk_color_init (&color, GDK_COLOR_STATE_SRGB, (float[]) { 1, 1, 1, 1 });
|
||||
|
||||
mask_image = gsk_gpu_upload_cairo_op (self->frame,
|
||||
&self->scale,
|
||||
&clip_bounds,
|
||||
gsk_gpu_node_processor_fill_path,
|
||||
g_memdup (&(FillData) {
|
||||
.path = gsk_path_ref (gsk_fill_node_get_path (node)),
|
||||
.color = GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE
|
||||
? *gsk_color_node_get_color (child)
|
||||
: GDK_RGBA_WHITE,
|
||||
.color = color,
|
||||
.fill_rule = gsk_fill_node_get_fill_rule (node)
|
||||
}, sizeof (FillData)),
|
||||
(GDestroyNotify) gsk_fill_data_free);
|
||||
@@ -3196,7 +3230,7 @@ typedef struct _StrokeData StrokeData;
|
||||
struct _StrokeData
|
||||
{
|
||||
GskPath *path;
|
||||
GdkRGBA color;
|
||||
GdkColor color;
|
||||
GskStroke stroke;
|
||||
};
|
||||
|
||||
@@ -3205,6 +3239,7 @@ gsk_stroke_data_free (gpointer data)
|
||||
{
|
||||
StrokeData *stroke = data;
|
||||
|
||||
gdk_color_finish (&stroke->color);
|
||||
gsk_path_unref (stroke->path);
|
||||
gsk_stroke_clear (&stroke->stroke);
|
||||
g_free (stroke);
|
||||
@@ -3218,7 +3253,7 @@ gsk_gpu_node_processor_stroke_path (gpointer data,
|
||||
|
||||
gsk_stroke_to_cairo (&stroke->stroke, cr);
|
||||
gsk_path_to_cairo (stroke->path, cr);
|
||||
gdk_cairo_set_source_rgba (cr, &stroke->color);
|
||||
gdk_cairo_set_source_color (cr, GDK_COLOR_STATE_SRGB, &stroke->color);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
@@ -3229,6 +3264,7 @@ gsk_gpu_node_processor_add_stroke_node (GskGpuNodeProcessor *self,
|
||||
graphene_rect_t clip_bounds, source_rect;
|
||||
GskGpuImage *mask_image, *source_image;
|
||||
GskRenderNode *child;
|
||||
GdkColor color;
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
@@ -3236,15 +3272,18 @@ gsk_gpu_node_processor_add_stroke_node (GskGpuNodeProcessor *self,
|
||||
|
||||
child = gsk_stroke_node_get_child (node);
|
||||
|
||||
if (GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE)
|
||||
gdk_color_init_copy (&color, gsk_color_node_get_color2 (child));
|
||||
else
|
||||
gdk_color_init (&color, GDK_COLOR_STATE_SRGB, (float[]) { 1, 1, 1, 1 });
|
||||
|
||||
mask_image = gsk_gpu_upload_cairo_op (self->frame,
|
||||
&self->scale,
|
||||
&clip_bounds,
|
||||
gsk_gpu_node_processor_stroke_path,
|
||||
g_memdup (&(StrokeData) {
|
||||
.path = gsk_path_ref (gsk_stroke_node_get_path (node)),
|
||||
.color = GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE
|
||||
? *gsk_color_node_get_color (child)
|
||||
: GDK_RGBA_WHITE,
|
||||
.color = color,
|
||||
.stroke = GSK_STROKE_INIT_COPY (gsk_stroke_node_get_stroke (node))
|
||||
}, sizeof (StrokeData)),
|
||||
(GDestroyNotify) gsk_stroke_data_free);
|
||||
@@ -3322,10 +3361,8 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
{
|
||||
if (gdk_rectangle_intersect (&int_clipped, &self->scissor, &int_clipped))
|
||||
{
|
||||
gsk_gpu_clear_op (self->frame,
|
||||
GDK_COLOR_STATE_SRGB,
|
||||
&int_clipped,
|
||||
&GDK_RGBA_TRANSPARENT);
|
||||
float color[4] = { 0, 0, 0, 0 };
|
||||
gsk_gpu_clear_op (self->frame, &int_clipped, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3333,13 +3370,17 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
self->blend = GSK_GPU_BLEND_CLEAR;
|
||||
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
|
||||
gsk_gpu_node_processor_sync_globals (self, 0);
|
||||
GdkColor white;
|
||||
|
||||
gdk_color_init (&white, self->ccs, ((float[]) { 1, 1, 1, 1 }));
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_self (self),
|
||||
&node->bounds,
|
||||
self->ccs,
|
||||
1,
|
||||
&self->offset,
|
||||
(float[4]) { 1, 1, 1, 1 });
|
||||
&node->bounds,
|
||||
&white);
|
||||
gdk_color_finish (&white);
|
||||
|
||||
self->blend = GSK_GPU_BLEND_OVER;
|
||||
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
|
||||
@@ -3876,7 +3917,9 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
|
||||
clip,
|
||||
viewport);
|
||||
|
||||
ccs = gdk_color_state_get_rendering_color_state (target_color_state);
|
||||
ccs = gdk_color_state_get_rendering_color_state (target_color_state, gsk_gpu_image_get_flags (target) & GSK_GPU_IMAGE_SRGB);
|
||||
|
||||
g_print ("node processor: rendering color state %s\n", gdk_color_state_get_name (ccs));
|
||||
|
||||
if (gdk_color_state_equal (ccs, target_color_state))
|
||||
{
|
||||
|
||||
@@ -299,10 +299,7 @@ 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;
|
||||
|
||||
frame = gsk_gpu_renderer_create_frame (self);
|
||||
gsk_gpu_frame_render (frame,
|
||||
@@ -352,6 +349,7 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture;
|
||||
graphene_rect_t rounded_viewport;
|
||||
GdkColorState *color_state;
|
||||
GdkMemoryDepth depth;
|
||||
|
||||
gsk_gpu_device_maybe_gc (priv->device);
|
||||
|
||||
@@ -361,18 +359,25 @@ 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);
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ gsk_gpu_render_pass_begin_op (GskGpuFrame *frame,
|
||||
self->area = *area;
|
||||
self->clear = clear_color_or_null != NULL;
|
||||
if (clear_color_or_null)
|
||||
gsk_gpu_color_to_float (clear_color_or_null, self->clear_color);
|
||||
gsk_gpu_vec4_to_float (clear_color_or_null, self->clear_color);
|
||||
self->pass_type = pass_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,16 +52,20 @@ static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
const GskRoundedRect *outline,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const float color[4])
|
||||
const GskRoundedRect *outline,
|
||||
const GdkColor *color)
|
||||
{
|
||||
GskGpuRoundedcolorInstance *instance;
|
||||
GdkColorState *alt;
|
||||
|
||||
alt = gsk_gpu_color_states_find (ccs, color);
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_ROUNDED_COLOR_OP_CLASS,
|
||||
color_states,
|
||||
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
|
||||
0,
|
||||
clip,
|
||||
NULL,
|
||||
@@ -69,6 +73,6 @@ gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
&instance);
|
||||
|
||||
gsk_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_gpu_color_to_float (color, instance->color);
|
||||
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
#include "gsktypes.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
@@ -9,10 +10,11 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
const GskRoundedRect *outline,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const float color[4]);
|
||||
const GskRoundedRect *outline,
|
||||
const GdkColor *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
#include "gskgpucolorstatesprivate.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
@@ -84,15 +85,14 @@ GskGpuOp * gsk_gpu_shader_op_gl_command (GskGpuO
|
||||
#define GSK_VEC4_TRANSPARENT (float[4]) { 0.0f, 0.0f, 0.0f, 0.0f }
|
||||
|
||||
static inline void
|
||||
gsk_gpu_color_to_float (const float color[4],
|
||||
float values[4])
|
||||
gsk_gpu_vec4_to_float (const float color[4],
|
||||
float values[4])
|
||||
{
|
||||
values[0] = color[0];
|
||||
values[1] = color[1];
|
||||
values[2] = color[2];
|
||||
values[3] = color[3];
|
||||
}
|
||||
#include <graphene.h>
|
||||
|
||||
static inline void
|
||||
gsk_gpu_point_to_float (const graphene_point_t *point,
|
||||
@@ -103,5 +103,14 @@ gsk_gpu_point_to_float (const graphene_point_t *point,
|
||||
values[1] = point->y + offset->y;
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
static inline void
|
||||
gsk_gpu_color_to_float (const GdkColor *color,
|
||||
GdkColorState *target,
|
||||
float opacity,
|
||||
float values[4])
|
||||
{
|
||||
gdk_color_to_float (color, target, values);
|
||||
values[3] *= opacity;
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -187,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);
|
||||
|
||||
@@ -210,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);
|
||||
|
||||
|
||||
+10
-1
@@ -69,6 +69,15 @@ find_texture_transform (GskTransform *transform)
|
||||
return dihedral;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
color_is_black (const GdkColor *color)
|
||||
{
|
||||
return color->red < 255.f / 65535.f &&
|
||||
color->green < 255.f / 65535.f &&
|
||||
color->blue < 255.f / 65535.f &&
|
||||
color->alpha > 65280.f / 65535.f;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
find_texture_to_attach (GskOffload *self,
|
||||
const GskRenderNode *subsurface_node,
|
||||
@@ -116,7 +125,7 @@ find_texture_to_attach (GskOffload *self,
|
||||
gsk_transform_transform_bounds (transform, &child->bounds, &bounds);
|
||||
if (GSK_RENDER_NODE_TYPE (child) == GSK_COLOR_NODE &&
|
||||
gsk_rect_equal (&bounds, &subsurface_node->bounds) &&
|
||||
gdk_rgba_equal (gsk_color_node_get_color (child), &GDK_RGBA_BLACK))
|
||||
color_is_black (gsk_color_node_get_color2 (child)))
|
||||
{
|
||||
*has_background = TRUE;
|
||||
node = gsk_container_node_get_child (node, 1);
|
||||
|
||||
+8
-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))
|
||||
{
|
||||
@@ -827,6 +827,12 @@ gsk_render_node_get_preferred_depth (const GskRenderNode *node)
|
||||
return node->preferred_depth;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_render_node_is_hdr (const GskRenderNode *node)
|
||||
{
|
||||
return node->is_hdr;
|
||||
}
|
||||
|
||||
/* Whether we need an offscreen to handle opacity correctly for this node.
|
||||
* We don't if there is only one drawing node inside (could be child
|
||||
* node, or grandchild, or...).
|
||||
|
||||
+105
-10
@@ -42,6 +42,7 @@
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdktexturedownloaderprivate.h"
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
@@ -90,6 +91,17 @@ my_color_stops_get_depth (const GskColorStop *stops,
|
||||
return gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
color_state_is_hdr (GdkColorState *color_state)
|
||||
{
|
||||
GdkColorState *rendering_cs;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* apply a rectangle that bounds @rect in
|
||||
* pixel-aligned device coordinates.
|
||||
*
|
||||
@@ -172,10 +184,20 @@ region_union_region_affine (cairo_region_t *region,
|
||||
struct _GskColorNode
|
||||
{
|
||||
GskRenderNode render_node;
|
||||
|
||||
GdkRGBA color;
|
||||
GdkColor color;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_color_node_finalize (GskRenderNode *node)
|
||||
{
|
||||
GskColorNode *self = (GskColorNode *) node;
|
||||
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_COLOR_NODE));
|
||||
|
||||
gdk_color_finish (&self->color);
|
||||
|
||||
parent_class->finalize (node);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_color_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr,
|
||||
@@ -183,8 +205,7 @@ gsk_color_node_draw (GskRenderNode *node,
|
||||
{
|
||||
GskColorNode *self = (GskColorNode *) node;
|
||||
|
||||
gdk_cairo_set_source_rgba_ccs (cr, ccs, &self->color);
|
||||
|
||||
gdk_cairo_set_source_color (cr, ccs, &self->color);
|
||||
gdk_cairo_rect (cr, &node->bounds);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
@@ -198,7 +219,7 @@ gsk_color_node_diff (GskRenderNode *node1,
|
||||
GskColorNode *self2 = (GskColorNode *) node2;
|
||||
|
||||
if (gsk_rect_equal (&node1->bounds, &node2->bounds) &&
|
||||
gdk_rgba_equal (&self1->color, &self2->color))
|
||||
gdk_color_equal (&self1->color, &self2->color))
|
||||
return;
|
||||
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
@@ -212,6 +233,7 @@ gsk_color_node_class_init (gpointer g_class,
|
||||
|
||||
node_class->node_type = GSK_COLOR_NODE;
|
||||
|
||||
node_class->finalize = gsk_color_node_finalize;
|
||||
node_class->draw = gsk_color_node_draw;
|
||||
node_class->diff = gsk_color_node_diff;
|
||||
}
|
||||
@@ -222,6 +244,9 @@ gsk_color_node_class_init (gpointer g_class,
|
||||
*
|
||||
* Retrieves the color of the given @node.
|
||||
*
|
||||
* 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 node
|
||||
*/
|
||||
const GdkRGBA *
|
||||
@@ -231,6 +256,25 @@ gsk_color_node_get_color (const GskRenderNode *node)
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_COLOR_NODE), NULL);
|
||||
|
||||
/* NOTE: This is only correct for nodes with sRGB colors */
|
||||
return (const GdkRGBA *) &self->color.values;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_color_node_get_color2:
|
||||
* @node: (type GskColorNode): a `GskRenderNode`
|
||||
*
|
||||
* Retrieves the color of the given @node.
|
||||
*
|
||||
* Returns: (transfer none): the color of the node
|
||||
*/
|
||||
const GdkColor *
|
||||
gsk_color_node_get_color2 (const GskRenderNode *node)
|
||||
{
|
||||
GskColorNode *self = (GskColorNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_COLOR_NODE), NULL);
|
||||
|
||||
return &self->color;
|
||||
}
|
||||
|
||||
@@ -247,20 +291,46 @@ gsk_color_node_get_color (const GskRenderNode *node)
|
||||
GskRenderNode *
|
||||
gsk_color_node_new (const GdkRGBA *rgba,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
GdkColor color;
|
||||
GskRenderNode *node;
|
||||
|
||||
gdk_color_init_from_rgba (&color, rgba);
|
||||
node = gsk_color_node_new2 (&color, bounds);
|
||||
gdk_color_finish (&color);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_color_node_new2:
|
||||
* @color: a `GdkColor` specifying a color
|
||||
* @bounds: the rectangle to render the color into
|
||||
*
|
||||
* Creates a `GskRenderNode` that will render the color specified by @color
|
||||
* into the area given by @bounds.
|
||||
*
|
||||
* Returns: (transfer full) (type GskColorNode): A new `GskRenderNode`
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_color_node_new2 (const GdkColor *color,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
GskColorNode *self;
|
||||
GskRenderNode *node;
|
||||
|
||||
g_return_val_if_fail (rgba != NULL, NULL);
|
||||
g_return_val_if_fail (color != NULL, NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
|
||||
self = gsk_render_node_alloc (GSK_COLOR_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gdk_rgba_is_opaque (rgba);
|
||||
node->preferred_depth = my_color_get_depth (rgba);
|
||||
node->fully_opaque = gdk_color_is_opaque (color);
|
||||
node->preferred_depth = gdk_color_get_depth (color);
|
||||
node->is_hdr = color_state_is_hdr (color->color_state);
|
||||
|
||||
gdk_color_init_copy (&self->color, color);
|
||||
|
||||
self->color = *rgba;
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
gsk_rect_normalize (&node->bounds);
|
||||
|
||||
@@ -1920,6 +1990,7 @@ gsk_texture_node_new (GdkTexture *texture,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
node->fully_opaque = gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_OPAQUE;
|
||||
node->is_hdr = color_state_is_hdr (gdk_texture_get_color_state (texture));
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
@@ -2142,6 +2213,7 @@ gsk_texture_scale_node_new (GdkTexture *texture,
|
||||
node->fully_opaque = gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_OPAQUE &&
|
||||
bounds->size.width == floor (bounds->size.width) &&
|
||||
bounds->size.height == floor (bounds->size.height);
|
||||
node->is_hdr = color_state_is_hdr (gdk_texture_get_color_state (texture));
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
gsk_rect_init_from_rect (&node->bounds, bounds);
|
||||
@@ -3423,6 +3495,7 @@ gsk_container_node_new (GskRenderNode **children,
|
||||
{
|
||||
graphene_rect_t child_opaque;
|
||||
gboolean have_opaque;
|
||||
gboolean is_hdr;
|
||||
|
||||
self->children = g_malloc_n (n_children, sizeof (GskRenderNode *));
|
||||
|
||||
@@ -3431,6 +3504,7 @@ gsk_container_node_new (GskRenderNode **children,
|
||||
node->preferred_depth = children[0]->preferred_depth;
|
||||
gsk_rect_init_from_rect (&node->bounds, &(children[0]->bounds));
|
||||
have_opaque = gsk_render_node_get_opaque_rect (self->children[0], &self->opaque);
|
||||
is_hdr = gsk_render_node_is_hdr (self->children[0]);
|
||||
|
||||
for (guint i = 1; i < n_children; i++)
|
||||
{
|
||||
@@ -3449,10 +3523,13 @@ gsk_container_node_new (GskRenderNode **children,
|
||||
have_opaque = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
is_hdr |= gsk_render_node_is_hdr (self->children[i]);
|
||||
}
|
||||
|
||||
node->offscreen_for_opacity = node->offscreen_for_opacity || !self->disjoint;
|
||||
}
|
||||
node->is_hdr = is_hdr;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -3747,6 +3824,7 @@ gsk_transform_node_new (GskRenderNode *child,
|
||||
&node->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -3899,6 +3977,7 @@ gsk_opacity_node_new (GskRenderNode *child,
|
||||
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -4132,6 +4211,7 @@ gsk_color_matrix_node_new (GskRenderNode *child,
|
||||
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -4439,6 +4519,7 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
|
||||
}
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
node->fully_opaque = child->fully_opaque && gsk_rect_contains_rect (&child->bounds, &self->child_bounds);
|
||||
|
||||
return node;
|
||||
@@ -4606,6 +4687,7 @@ gsk_clip_node_new (GskRenderNode *child,
|
||||
gsk_rect_intersection (&self->clip, &child->bounds, &node->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -4789,6 +4871,7 @@ gsk_rounded_clip_node_new (GskRenderNode *child,
|
||||
gsk_rect_intersection (&self->clip.bounds, &child->bounds, &node->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -4959,6 +5042,7 @@ gsk_fill_node_new (GskRenderNode *child,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->path = gsk_path_ref (path);
|
||||
@@ -5169,6 +5253,7 @@ gsk_stroke_node_new (GskRenderNode *child,
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->path = gsk_path_ref (path);
|
||||
@@ -5446,6 +5531,7 @@ gsk_shadow_node_new (GskRenderNode *child,
|
||||
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,
|
||||
@@ -5669,6 +5755,8 @@ gsk_blend_node_new (GskRenderNode *bottom,
|
||||
|
||||
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (bottom),
|
||||
gsk_render_node_get_preferred_depth (top));
|
||||
node->is_hdr = gsk_render_node_is_hdr (bottom) ||
|
||||
gsk_render_node_is_hdr (top);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -5856,6 +5944,8 @@ gsk_cross_fade_node_new (GskRenderNode *start,
|
||||
|
||||
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (start),
|
||||
gsk_render_node_get_preferred_depth (end));
|
||||
node->is_hdr = gsk_render_node_is_hdr (start) ||
|
||||
gsk_render_node_is_hdr (end);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -6508,6 +6598,7 @@ gsk_blur_node_new (GskRenderNode *child,
|
||||
graphene_rect_inset (&self->render_node.bounds, - clip_radius, - clip_radius);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -6744,6 +6835,8 @@ gsk_mask_node_new (GskRenderNode *source,
|
||||
self->render_node.bounds = *graphene_rect_zero ();
|
||||
|
||||
self->render_node.preferred_depth = gsk_render_node_get_preferred_depth (source);
|
||||
self->render_node.is_hdr = gsk_render_node_is_hdr (source) ||
|
||||
gsk_render_node_is_hdr (mask);
|
||||
|
||||
return &self->render_node;
|
||||
}
|
||||
@@ -6922,6 +7015,7 @@ gsk_debug_node_new (GskRenderNode *child,
|
||||
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
self->render_node.is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -7344,6 +7438,7 @@ gsk_subsurface_node_new (GskRenderNode *child,
|
||||
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
+371
-8
@@ -33,6 +33,7 @@
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
#include "gdk/gdkcolorprivate.h"
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
@@ -65,6 +66,7 @@ struct _Context
|
||||
{
|
||||
GHashTable *named_nodes;
|
||||
GHashTable *named_textures;
|
||||
GHashTable *named_color_states;
|
||||
PangoFontMap *fontmap;
|
||||
};
|
||||
|
||||
@@ -89,6 +91,7 @@ context_finish (Context *context)
|
||||
{
|
||||
g_clear_pointer (&context->named_nodes, g_hash_table_unref);
|
||||
g_clear_pointer (&context->named_textures, g_hash_table_unref);
|
||||
g_clear_pointer (&context->named_color_states, g_hash_table_unref);
|
||||
g_clear_object (&context->fontmap);
|
||||
}
|
||||
|
||||
@@ -1462,20 +1465,265 @@ 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,
|
||||
gpointer out)
|
||||
{
|
||||
if (!parse_enum (parser, GDK_TYPE_CICP_RANGE, out))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_unsigned (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer out)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*((guint *)out) = (guint) token->number.number;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_value (parser, "Not an allowed value here");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_state_rule (GtkCssParser *parser,
|
||||
Context *context)
|
||||
{
|
||||
char *name = NULL;
|
||||
GdkColorState *cs = NULL;
|
||||
GdkCicp cicp = { 2, 2, 2, GDK_CICP_RANGE_FULL };
|
||||
const Declaration declarations[] = {
|
||||
{ "primaries", parse_unsigned, NULL, &cicp.color_primaries },
|
||||
{ "transfer", parse_unsigned, NULL, &cicp.transfer_function },
|
||||
{ "matrix", parse_unsigned, NULL, &cicp.matrix_coefficients },
|
||||
{ "range", parse_cicp_range, NULL, &cicp.range },
|
||||
};
|
||||
const char *default_names[] = { "srgb", "srgb-linear", "rec2100-pq", "rec2100-linear", NULL};
|
||||
GError *error = NULL;
|
||||
GtkCssLocation start;
|
||||
GtkCssLocation end;
|
||||
|
||||
/* We only return FALSE when we see the wrong @ keyword, since the caller
|
||||
* throws an error in this case.
|
||||
*/
|
||||
if (!gtk_css_parser_try_at_keyword (parser, "cicp"))
|
||||
return FALSE;
|
||||
|
||||
name = gtk_css_parser_consume_string (parser);
|
||||
if (name == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (g_strv_contains (default_names, name) ||
|
||||
(context->named_color_states &&
|
||||
g_hash_table_contains (context->named_color_states, name)))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "A color state named \"%s\" already exists", name);
|
||||
g_free (name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
start = *gtk_css_parser_get_block_location (parser);
|
||||
end = *gtk_css_parser_get_end_location (parser);
|
||||
|
||||
gtk_css_parser_end_block_prelude (parser);
|
||||
|
||||
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
|
||||
|
||||
cs = gdk_color_state_new_for_cicp (&cicp, &error);
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
&start, &end,
|
||||
"Not a valid cicp tuple: %s", error->message);
|
||||
g_error_free (error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (context->named_color_states == NULL)
|
||||
context->named_color_states = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, (GDestroyNotify) gdk_color_state_unref);
|
||||
g_hash_table_insert (context->named_color_states, name, cs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_state (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color_state)
|
||||
{
|
||||
GdkColorState *cs = NULL;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "srgb"))
|
||||
cs = gdk_color_state_get_srgb ();
|
||||
else if (gtk_css_parser_try_ident (parser, "srgb-linear"))
|
||||
cs = gdk_color_state_get_srgb_linear ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-pq"))
|
||||
cs = gdk_color_state_get_rec2100_pq ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-linear"))
|
||||
cs = gdk_color_state_get_rec2100_linear ();
|
||||
else if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
char *name = gtk_css_parser_consume_string (parser);
|
||||
|
||||
if (context->named_color_states)
|
||||
cs = g_hash_table_lookup (context->named_color_states, name);
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "No color state named \"%s\"", name);
|
||||
g_free (name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid color state");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*(GdkColorState **) color_state = gdk_color_state_ref (cs);
|
||||
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;
|
||||
} ColorArgData;
|
||||
|
||||
static guint
|
||||
parse_color_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
ColorArgData *d = data;
|
||||
GdkColorState *color_state;
|
||||
float values[4];
|
||||
|
||||
if (!parse_color_state (parser, d->context, &color_state))
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[i] = number;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[3] = number;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[3] = 1;
|
||||
}
|
||||
|
||||
gdk_color_init (d->color, color_state, values);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color2 (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "color"))
|
||||
{
|
||||
ColorArgData data = { context, color };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_color_arg, &data))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (gdk_rgba_parser_parse (parser, &rgba))
|
||||
{
|
||||
gdk_color_init_from_rgba ((GdkColor *) color, &rgba);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
parse_color_node (GtkCssParser *parser,
|
||||
Context *context)
|
||||
{
|
||||
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50);
|
||||
GdkRGBA color = GDK_RGBA("FF00CC");
|
||||
GdkColor color = GDK_COLOR_SRGB (1, 0, 0.8, 1);
|
||||
const Declaration declarations[] = {
|
||||
{ "bounds", parse_rect, NULL, &bounds },
|
||||
{ "color", parse_color, NULL, &color },
|
||||
{ "color", parse_color2, NULL, &color },
|
||||
};
|
||||
GskRenderNode *node;
|
||||
|
||||
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
|
||||
|
||||
return gsk_color_node_new (&color, &bounds);
|
||||
node = gsk_color_node_new2 (&color, &bounds);
|
||||
|
||||
gdk_color_finish (&color);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
@@ -2782,11 +3030,9 @@ parse_node (GtkCssParser *parser,
|
||||
{ "subsurface", parse_subsurface_node },
|
||||
};
|
||||
GskRenderNode **node_p = out_node;
|
||||
const GtkCssToken *token;
|
||||
guint i;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
GskRenderNode *node;
|
||||
char *node_name;
|
||||
@@ -2916,6 +3162,16 @@ gsk_render_node_deserialize_from_bytes (GBytes *bytes,
|
||||
&error_func_pair, NULL);
|
||||
context_init (&context);
|
||||
|
||||
while (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_AT_KEYWORD))
|
||||
{
|
||||
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
if (!parse_color_state_rule (parser, &context))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Unknown @ rule");
|
||||
}
|
||||
gtk_css_parser_end_block (parser);
|
||||
}
|
||||
|
||||
root = parse_container_node (parser, &context);
|
||||
|
||||
if (root && gsk_container_node_get_n_children (root) == 1)
|
||||
@@ -2943,6 +3199,8 @@ typedef struct
|
||||
gsize named_node_counter;
|
||||
GHashTable *named_textures;
|
||||
gsize named_texture_counter;
|
||||
GHashTable *named_color_states;
|
||||
gsize named_color_state_counter;
|
||||
GHashTable *fonts;
|
||||
} Printer;
|
||||
|
||||
@@ -2958,6 +3216,22 @@ printer_init_check_texture (Printer *printer,
|
||||
g_hash_table_insert (printer->named_textures, texture, g_strdup (""));
|
||||
}
|
||||
|
||||
static void
|
||||
printer_init_check_color_state (Printer *printer,
|
||||
GdkColorState *cs)
|
||||
{
|
||||
gpointer name;
|
||||
|
||||
if (GDK_IS_DEFAULT_COLOR_STATE (cs))
|
||||
return;
|
||||
|
||||
if (!g_hash_table_lookup_extended (printer->named_color_states, cs, NULL, &name))
|
||||
{
|
||||
name = g_strdup_printf ("cicp%zu", ++printer->named_color_state_counter);
|
||||
g_hash_table_insert (printer->named_color_states, cs, name);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
hb_face_t *face;
|
||||
hb_subset_input_t *input;
|
||||
@@ -3033,8 +3307,11 @@ printer_init_duplicates_for_node (Printer *printer,
|
||||
printer_init_collect_font_info (printer, node);
|
||||
break;
|
||||
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_COLOR_NODE:
|
||||
printer_init_check_color_state (printer, gsk_color_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:
|
||||
@@ -3159,6 +3436,8 @@ printer_init (Printer *self,
|
||||
self->named_node_counter = 0;
|
||||
self->named_textures = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
self->named_texture_counter = 0;
|
||||
self->named_color_states = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
self->named_color_state_counter = 0;
|
||||
self->fonts = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, font_info_free);
|
||||
|
||||
printer_init_duplicates_for_node (self, node);
|
||||
@@ -3171,6 +3450,7 @@ printer_clear (Printer *self)
|
||||
g_string_free (self->str, TRUE);
|
||||
g_hash_table_unref (self->named_nodes);
|
||||
g_hash_table_unref (self->named_textures);
|
||||
g_hash_table_unref (self->named_color_states);
|
||||
g_hash_table_unref (self->fonts);
|
||||
}
|
||||
|
||||
@@ -3330,6 +3610,15 @@ append_float_param (Printer *p,
|
||||
g_string_append (p->str, ";\n");
|
||||
}
|
||||
|
||||
static void
|
||||
append_unsigned_param (Printer *p,
|
||||
const char *param_name,
|
||||
guint value)
|
||||
{
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "%s: %u;\n", param_name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
append_rgba_param (Printer *p,
|
||||
const char *param_name,
|
||||
@@ -3342,6 +3631,55 @@ append_rgba_param (Printer *p,
|
||||
g_string_append_c (p->str, '\n');
|
||||
}
|
||||
|
||||
static void
|
||||
print_color (Printer *p,
|
||||
const GdkColor *color)
|
||||
{
|
||||
if (gdk_color_state_equal (color->color_state, GDK_COLOR_STATE_SRGB))
|
||||
{
|
||||
gdk_rgba_print ((const GdkRGBA *) color->values, p->str);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GDK_IS_DEFAULT_COLOR_STATE (color->color_state))
|
||||
{
|
||||
g_string_append_printf (p->str, "color(%s ",
|
||||
gdk_color_state_get_name (color->color_state));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *name = g_hash_table_lookup (p->named_color_states,
|
||||
color->color_state);
|
||||
g_assert (name != NULL);
|
||||
g_string_append_printf (p->str, "color(\"%s\" ", name);
|
||||
}
|
||||
|
||||
string_append_double (p->str, color->r);
|
||||
g_string_append_c (p->str, ' ');
|
||||
string_append_double (p->str, color->g);
|
||||
g_string_append_c (p->str, ' ');
|
||||
string_append_double (p->str, color->b);
|
||||
if (color->a < 1)
|
||||
{
|
||||
g_string_append (p->str, " / ");
|
||||
string_append_double (p->str, color->a);
|
||||
}
|
||||
g_string_append_c (p->str, ')');
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_color_param (Printer *p,
|
||||
const char *param_name,
|
||||
const GdkColor *color)
|
||||
{
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "%s: ", param_name);
|
||||
print_color (p, color);
|
||||
g_string_append_c (p->str, ';');
|
||||
g_string_append_c (p->str, '\n');
|
||||
}
|
||||
|
||||
static void
|
||||
append_rect_param (Printer *p,
|
||||
const char *param_name,
|
||||
@@ -3899,7 +4237,7 @@ render_node_print (Printer *p,
|
||||
{
|
||||
start_node (p, "color", node_name);
|
||||
append_rect_param (p, "bounds", &node->bounds);
|
||||
append_rgba_param (p, "color", gsk_color_node_get_color (node));
|
||||
append_color_param (p, "color", gsk_color_node_get_color2 (node));
|
||||
end_node (p);
|
||||
}
|
||||
break;
|
||||
@@ -4548,6 +4886,24 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_color_state (Printer *p,
|
||||
GdkColorState *color_state,
|
||||
const char *name)
|
||||
{
|
||||
const GdkCicp *cicp = gdk_color_state_get_cicp (color_state);
|
||||
|
||||
g_string_append_printf (p->str, "@cicp \"%s\" {\n", name);
|
||||
p->indentation_level ++;
|
||||
append_unsigned_param (p, "primaries", cicp->color_primaries);
|
||||
append_unsigned_param (p, "transfer", cicp->transfer_function);
|
||||
append_unsigned_param (p, "matrix", cicp->matrix_coefficients);
|
||||
if (cicp->range != GDK_CICP_RANGE_FULL)
|
||||
append_enum_param (p, "range", GDK_TYPE_CICP_RANGE, cicp->range);
|
||||
p->indentation_level --;
|
||||
g_string_append (p->str, "}\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_render_node_serialize:
|
||||
* @node: a `GskRenderNode`
|
||||
@@ -4569,9 +4925,16 @@ gsk_render_node_serialize (GskRenderNode *node)
|
||||
{
|
||||
Printer p;
|
||||
GBytes *res;
|
||||
GHashTableIter iter;
|
||||
GdkColorState *cs;
|
||||
const char *name;
|
||||
|
||||
printer_init (&p, node);
|
||||
|
||||
g_hash_table_iter_init (&iter, p.named_color_states);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&cs, (gpointer *)&name))
|
||||
serialize_color_state (&p, cs, name);
|
||||
|
||||
if (gsk_render_node_get_node_type (node) == GSK_CONTAINER_NODE)
|
||||
{
|
||||
guint i;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <cairo.h>
|
||||
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
#include "gdk/gdkcolorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -35,6 +36,7 @@ struct _GskRenderNode
|
||||
guint preferred_depth : GDK_MEMORY_DEPTH_BITS;
|
||||
guint offscreen_for_opacity : 1;
|
||||
guint fully_opaque : 1;
|
||||
guint is_hdr : 1;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -105,6 +107,7 @@ void gsk_transform_node_get_translate (const GskRenderNode
|
||||
float *dx,
|
||||
float *dy);
|
||||
GdkMemoryDepth gsk_render_node_get_preferred_depth (const GskRenderNode *node) G_GNUC_PURE;
|
||||
gboolean gsk_render_node_is_hdr (const GskRenderNode *node) G_GNUC_PURE;
|
||||
|
||||
gboolean gsk_container_node_is_disjoint (const GskRenderNode *node) G_GNUC_PURE;
|
||||
|
||||
@@ -120,5 +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);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -953,6 +953,16 @@ gtk_css_parser_has_integer (GtkCssParser *self)
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_parser_has_percentage (GtkCssParser *self)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (self);
|
||||
|
||||
return gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_parser_has_function:
|
||||
* @self: a `GtkCssParser`
|
||||
|
||||
@@ -132,6 +132,7 @@ gboolean gtk_css_parser_has_ident (GtkCssParser
|
||||
gboolean gtk_css_parser_has_url (GtkCssParser *self);
|
||||
gboolean gtk_css_parser_has_number (GtkCssParser *self);
|
||||
gboolean gtk_css_parser_has_integer (GtkCssParser *self);
|
||||
gboolean gtk_css_parser_has_percentage (GtkCssParser *self);
|
||||
gboolean gtk_css_parser_has_function (GtkCssParser *self,
|
||||
const char *name);
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ gtk_color_picker_win32_pick (GtkColorPicker *cp,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Cannot capture the mouse pointer");
|
||||
g_object_unref (picker->task);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "gtkcsscolorprivate.h"
|
||||
#include "gtkcolorutilsprivate.h"
|
||||
#include "gdkcolorstateprivate.h"
|
||||
|
||||
/* {{{ Initialization */
|
||||
|
||||
@@ -1163,5 +1164,52 @@ gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GdkColor conversion */
|
||||
|
||||
void
|
||||
gtk_css_color_to_color (const GtkCssColor *css,
|
||||
GdkColor *color)
|
||||
{
|
||||
switch (css->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
gdk_color_init (color, GDK_COLOR_STATE_SRGB, css->values);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
gdk_color_init (color, GDK_COLOR_STATE_SRGB_LINEAR, css->values);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_REC2100_PQ:
|
||||
gdk_color_init (color, GDK_COLOR_STATE_REC2100_PQ, css->values);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
{
|
||||
GtkCssColor tmp;
|
||||
gtk_css_color_convert (css, GTK_CSS_COLOR_SPACE_SRGB, &tmp);
|
||||
gdk_color_init (color, GDK_COLOR_STATE_SRGB, tmp.values);
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_REC2020:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
{
|
||||
GtkCssColor tmp;
|
||||
gtk_css_color_convert (css, GTK_CSS_COLOR_SPACE_REC2100_PQ, &tmp);
|
||||
gdk_color_init (color, GDK_COLOR_STATE_REC2100_PQ, tmp.values);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
#include "gtkcsstypesprivate.h"
|
||||
#include "gdk/gdkcolorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -115,4 +116,13 @@ void gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GString *string);
|
||||
|
||||
static inline gboolean
|
||||
gtk_css_color_is_clear (const GtkCssColor *color)
|
||||
{
|
||||
return color->values[3] < (float) 0x00ff / (float) 0xffff;
|
||||
}
|
||||
|
||||
void gtk_css_color_to_color (const GtkCssColor *css,
|
||||
GdkColor *color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1880,4 +1880,27 @@ typedef enum {
|
||||
GTK_FONT_RENDERING_MANUAL,
|
||||
} GtkFontRendering;
|
||||
|
||||
/**
|
||||
* GtkTextBufferNotifyFlags:
|
||||
* @GTK_TEXT_BUFFER_NOTIFY_BEFORE_INSERT: Be notified before text
|
||||
* is inserted into the underlying buffer.
|
||||
* @GTK_TEXT_BUFFER_NOTIFY_AFTER_INSERT: Be notified after text
|
||||
* has been inserted into the underlying buffer.
|
||||
* @GTK_TEXT_BUFFER_NOTIFY_BEFORE_DELETE: Be notified before text
|
||||
* is deleted from the underlying buffer.
|
||||
* @GTK_TEXT_BUFFER_NOTIFY_AFTER_DELETE: Be notified after text
|
||||
* has been deleted from the underlying buffer.
|
||||
*
|
||||
* Values for [callback@Gtk.TextBufferCommitNotify] to denote the
|
||||
* point of the notification.
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_TEXT_BUFFER_NOTIFY_BEFORE_INSERT = 1 << 0,
|
||||
GTK_TEXT_BUFFER_NOTIFY_AFTER_INSERT = 1 << 1,
|
||||
GTK_TEXT_BUFFER_NOTIFY_BEFORE_DELETE = 1 << 2,
|
||||
GTK_TEXT_BUFFER_NOTIFY_AFTER_DELETE = 1 << 3,
|
||||
} GtkTextBufferNotifyFlags;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -485,6 +485,7 @@ gtk_file_launcher_launch (GtkFileLauncher *self,
|
||||
g_task_return_new_error (task,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"No file to launch");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -576,6 +577,7 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
|
||||
g_task_return_new_error (task,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"No file to open");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -584,6 +586,7 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
|
||||
g_task_return_new_error (task,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"Operation not supported on non-native files");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -339,8 +339,7 @@ gtk_icon_helper_invalidate (GtkIconHelper *self)
|
||||
g_clear_object (&self->paintable);
|
||||
self->texture_is_symbolic = FALSE;
|
||||
|
||||
if (!GTK_IS_CSS_TRANSIENT_NODE (self->node))
|
||||
gtk_widget_queue_resize (self->owner);
|
||||
gtk_widget_queue_draw (self->owner);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+10
-10
@@ -36,6 +36,7 @@
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcsstypesprivate.h"
|
||||
#include "gtksnapshotprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -46,30 +47,29 @@
|
||||
static void
|
||||
gtk_theming_background_snapshot_color (GtkCssBoxes *boxes,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRGBA *bg_color,
|
||||
const GtkCssColor *bg_color,
|
||||
guint n_bg_values)
|
||||
{
|
||||
GtkCssStyle *style = boxes->style;
|
||||
const GskRoundedRect *box;
|
||||
GtkCssArea clip;
|
||||
GdkColor color;
|
||||
|
||||
clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (style->background->background_clip, n_bg_values - 1));
|
||||
box = gtk_css_boxes_get_box (boxes, clip);
|
||||
|
||||
gtk_css_color_to_color (bg_color, &color);
|
||||
if (gsk_rounded_rect_is_rectilinear (box))
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
bg_color,
|
||||
&box->bounds);
|
||||
gtk_snapshot_append_color2 (snapshot, &color, &box->bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_snapshot_push_rounded_clip (snapshot, box);
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
bg_color,
|
||||
&box->bounds);
|
||||
gtk_snapshot_append_color2 (snapshot, &color, &box->bounds);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
gdk_color_finish (&color);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,7 +248,7 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
{
|
||||
GtkCssStyle *style = boxes->style;
|
||||
GtkCssValue *background_image;
|
||||
const GdkRGBA *bg_color;
|
||||
const GtkCssColor *bg_color;
|
||||
const GtkCssValue *box_shadow;
|
||||
gboolean has_bg_color;
|
||||
gboolean has_bg_image;
|
||||
@@ -260,10 +260,10 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
return;
|
||||
|
||||
background_image = style->used->background_image;
|
||||
bg_color = gtk_css_color_value_get_rgba (style->used->background_color);
|
||||
bg_color = gtk_css_color_value_get_color (style->used->background_color);
|
||||
box_shadow = style->used->box_shadow;
|
||||
|
||||
has_bg_color = !gdk_rgba_is_clear (bg_color);
|
||||
has_bg_color = !gtk_css_color_is_clear (bg_color);
|
||||
has_bg_image = _gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (background_image, 0)) != NULL;
|
||||
has_shadow = !gtk_css_shadow_value_is_none (box_shadow);
|
||||
|
||||
|
||||
+25
-3
@@ -27,6 +27,7 @@
|
||||
#include "gsktransformprivate.h"
|
||||
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
#include "gsk/gskroundedrectprivate.h"
|
||||
@@ -705,8 +706,9 @@ gtk_snapshot_collect_repeat (GtkSnapshot *snapshot,
|
||||
graphene_rect_equal (child_bounds, &node->bounds))
|
||||
{
|
||||
/* Repeating a color node entirely is pretty easy by just increasing
|
||||
* the size of the color node. */
|
||||
GskRenderNode *color_node = gsk_color_node_new (gsk_color_node_get_color (node), bounds);
|
||||
* the size of the color node.
|
||||
*/
|
||||
GskRenderNode *color_node = gsk_color_node_new2 (gsk_color_node_get_color2 (node), bounds);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
@@ -2383,6 +2385,26 @@ void
|
||||
gtk_snapshot_append_color (GtkSnapshot *snapshot,
|
||||
const GdkRGBA *color,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
GdkColor color2;
|
||||
gdk_color_init_from_rgba (&color2, color);
|
||||
gtk_snapshot_append_color2 (snapshot, &color2, bounds);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_snapshot_append_color2:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @color: the color to draw
|
||||
* @bounds: the bounds for the new node
|
||||
*
|
||||
* Creates a new render node drawing the @color into the
|
||||
* given @bounds and appends it to the current render node
|
||||
* of @snapshot.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_append_color2 (GtkSnapshot *snapshot,
|
||||
const GdkColor *color,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
graphene_rect_t real_bounds;
|
||||
@@ -2395,7 +2417,7 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot,
|
||||
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &dx, &dy);
|
||||
gtk_graphene_rect_scale_affine (bounds, scale_x, scale_y, dx, dy, &real_bounds);
|
||||
|
||||
node = gsk_color_node_new (color, &real_bounds);
|
||||
node = gsk_color_node_new2 (color, &real_bounds);
|
||||
|
||||
gtk_snapshot_append_node_internal (snapshot, node);
|
||||
}
|
||||
|
||||
@@ -37,5 +37,9 @@ GskRenderNode * gtk_snapshot_pop_collect (GtkSnapshot
|
||||
void gtk_snapshot_push_subsurface (GtkSnapshot *snapshot,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
void gtk_snapshot_append_color2 (GtkSnapshot *snapshot,
|
||||
const GdkColor *color,
|
||||
const graphene_rect_t *bounds);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+201
-2
@@ -68,6 +68,9 @@ struct _GtkTextBufferPrivate
|
||||
|
||||
GtkTextHistory *history;
|
||||
|
||||
GArray *commit_funcs;
|
||||
guint last_commit_handler;
|
||||
|
||||
guint user_action_count;
|
||||
|
||||
/* Whether the buffer has been modified since last save */
|
||||
@@ -75,6 +78,7 @@ struct _GtkTextBufferPrivate
|
||||
guint has_selection : 1;
|
||||
guint can_undo : 1;
|
||||
guint can_redo : 1;
|
||||
guint in_commit_notify : 1;
|
||||
};
|
||||
|
||||
typedef struct _ClipboardRequest ClipboardRequest;
|
||||
@@ -87,6 +91,15 @@ struct _ClipboardRequest
|
||||
guint replace_selection : 1;
|
||||
};
|
||||
|
||||
typedef struct _CommitFunc
|
||||
{
|
||||
GtkTextBufferCommitNotify callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_data_destroy;
|
||||
GtkTextBufferNotifyFlags flags;
|
||||
guint handler_id;
|
||||
} CommitFunc;
|
||||
|
||||
enum {
|
||||
INSERT_TEXT,
|
||||
INSERT_PAINTABLE,
|
||||
@@ -151,6 +164,10 @@ static void gtk_text_buffer_real_mark_set (GtkTextBuffer *buffe
|
||||
GtkTextMark *mark);
|
||||
static void gtk_text_buffer_real_undo (GtkTextBuffer *buffer);
|
||||
static void gtk_text_buffer_real_redo (GtkTextBuffer *buffer);
|
||||
static void gtk_text_buffer_commit_notify (GtkTextBuffer *buffer,
|
||||
GtkTextBufferNotifyFlags flags,
|
||||
guint position,
|
||||
guint length);
|
||||
|
||||
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
|
||||
static void free_log_attr_cache (GtkTextLogAttrCache *cache);
|
||||
@@ -1081,6 +1098,8 @@ gtk_text_buffer_finalize (GObject *object)
|
||||
|
||||
remove_all_selection_clipboards (buffer);
|
||||
|
||||
g_clear_pointer (&buffer->priv->commit_funcs, g_array_unref);
|
||||
|
||||
g_clear_object (&buffer->priv->history);
|
||||
|
||||
if (priv->tag_table)
|
||||
@@ -1198,7 +1217,29 @@ gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
|
||||
text,
|
||||
len);
|
||||
|
||||
_gtk_text_btree_insert (iter, text, len);
|
||||
if (buffer->priv->commit_funcs == NULL)
|
||||
{
|
||||
_gtk_text_btree_insert (iter, text, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint position;
|
||||
guint n_chars;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (text);
|
||||
|
||||
position = gtk_text_iter_get_offset (iter);
|
||||
n_chars = g_utf8_strlen (text, len);
|
||||
|
||||
gtk_text_buffer_commit_notify (buffer,
|
||||
GTK_TEXT_BUFFER_NOTIFY_BEFORE_INSERT,
|
||||
position, n_chars);
|
||||
_gtk_text_btree_insert (iter, text, len);
|
||||
gtk_text_buffer_commit_notify (buffer,
|
||||
GTK_TEXT_BUFFER_NOTIFY_AFTER_INSERT,
|
||||
position, n_chars);
|
||||
}
|
||||
|
||||
g_signal_emit (buffer, signals[CHANGED], 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (buffer), text_buffer_props[PROP_CURSOR_POSITION]);
|
||||
@@ -1211,6 +1252,7 @@ gtk_text_buffer_emit_insert (GtkTextBuffer *buffer,
|
||||
int len)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (buffer->priv->in_commit_notify == FALSE);
|
||||
g_return_if_fail (iter != NULL);
|
||||
g_return_if_fail (text != NULL);
|
||||
|
||||
@@ -1955,7 +1997,36 @@ gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
_gtk_text_btree_delete (start, end);
|
||||
|
||||
|
||||
if (buffer->priv->commit_funcs == NULL)
|
||||
{
|
||||
_gtk_text_btree_delete (start, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint off1 = gtk_text_iter_get_offset (start);
|
||||
guint off2 = gtk_text_iter_get_offset (end);
|
||||
|
||||
if (off2 < off1)
|
||||
{
|
||||
guint tmp = off1;
|
||||
off1 = off2;
|
||||
off2 = tmp;
|
||||
}
|
||||
|
||||
buffer->priv->in_commit_notify = TRUE;
|
||||
|
||||
gtk_text_buffer_commit_notify (buffer,
|
||||
GTK_TEXT_BUFFER_NOTIFY_BEFORE_DELETE,
|
||||
off1, off2 - off1);
|
||||
_gtk_text_btree_delete (start, end);
|
||||
gtk_text_buffer_commit_notify (buffer,
|
||||
GTK_TEXT_BUFFER_NOTIFY_AFTER_DELETE,
|
||||
off1, 0);
|
||||
|
||||
buffer->priv->in_commit_notify = FALSE;
|
||||
}
|
||||
|
||||
/* may have deleted the selection... */
|
||||
update_selection_clipboards (buffer);
|
||||
@@ -1979,6 +2050,7 @@ gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (start != NULL);
|
||||
g_return_if_fail (end != NULL);
|
||||
g_return_if_fail (buffer->priv->in_commit_notify == FALSE);
|
||||
|
||||
if (gtk_text_iter_equal (start, end))
|
||||
return;
|
||||
@@ -5720,3 +5792,130 @@ gtk_text_buffer_add_run_attributes (GtkTextBuffer *buffer,
|
||||
|
||||
g_slist_free (tags);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_commit_func (gpointer data)
|
||||
{
|
||||
CommitFunc *func = data;
|
||||
|
||||
if (func->user_data_destroy)
|
||||
func->user_data_destroy (func->user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_add_commit_notify:
|
||||
* @buffer: a [type@Gtk.TextBuffer]
|
||||
* @flags: which notifications should be dispatched to @callback
|
||||
* @commit_notify: (scope async) (closure user_data) (destroy destroy): a
|
||||
* [callback@Gtk.TextBufferCommitNotify] to call for commit notifications
|
||||
* @user_data: closure data for @commit_notify
|
||||
* @destroy: a callback to free @user_data when @commit_notify is removed
|
||||
*
|
||||
* Adds a [callback@Gtk.TextBufferCommitNotify] to be called when a change
|
||||
* is to be made to the [type@Gtk.TextBuffer].
|
||||
*
|
||||
* Functions are explicitly forbidden from making changes to the
|
||||
* [type@Gtk.TextBuffer] from this callback. It is intended for tracking
|
||||
* changes to the buffer only.
|
||||
*
|
||||
* It may be advantageous to use [callback@Gtk.TextBufferCommitNotify] over
|
||||
* connecting to the [signal@Gtk.TextBuffer::insert-text] or
|
||||
* [signal@Gtk.TextBuffer::delete-range] signals to avoid ordering issues with
|
||||
* other signal handlers which may further modify the [type@Gtk.TextBuffer].
|
||||
*
|
||||
* Returns: a handler id which may be used to remove the commit notify
|
||||
* callback using [method@Gtk.TextBuffer.remove_commit_notify].
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
guint
|
||||
gtk_text_buffer_add_commit_notify (GtkTextBuffer *buffer,
|
||||
GtkTextBufferNotifyFlags flags,
|
||||
GtkTextBufferCommitNotify commit_notify,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
CommitFunc func;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
|
||||
g_return_val_if_fail (buffer->priv->in_commit_notify == FALSE, 0);
|
||||
|
||||
func.callback = commit_notify;
|
||||
func.user_data = user_data;
|
||||
func.user_data_destroy = destroy;
|
||||
func.handler_id = ++buffer->priv->last_commit_handler;
|
||||
func.flags = flags;
|
||||
|
||||
if (buffer->priv->commit_funcs == NULL)
|
||||
{
|
||||
buffer->priv->commit_funcs = g_array_new (FALSE, FALSE, sizeof (CommitFunc));
|
||||
g_array_set_clear_func (buffer->priv->commit_funcs, clear_commit_func);
|
||||
}
|
||||
|
||||
g_array_append_val (buffer->priv->commit_funcs, func);
|
||||
|
||||
return func.handler_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_remove_commit_notify:
|
||||
* @buffer: a `GtkTextBuffer`
|
||||
* @commit_notify_handler: the notify handler identifier returned from
|
||||
* [method@Gtk.TextBuffer.add_commit_notify].
|
||||
*
|
||||
* Removes the `GtkTextBufferCommitNotify` handler previously registered
|
||||
* with [method@Gtk.TextBuffer.add_commit_notify].
|
||||
*
|
||||
* This may result in the `user_data_destroy` being called that was passed when registering
|
||||
* the commit notify functions.
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
void
|
||||
gtk_text_buffer_remove_commit_notify (GtkTextBuffer *buffer,
|
||||
guint commit_notify_handler)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (commit_notify_handler > 0);
|
||||
g_return_if_fail (buffer->priv->in_commit_notify == FALSE);
|
||||
|
||||
if (buffer->priv->commit_funcs != NULL)
|
||||
{
|
||||
for (guint i = 0; i < buffer->priv->commit_funcs->len; i++)
|
||||
{
|
||||
const CommitFunc *func = &g_array_index (buffer->priv->commit_funcs, CommitFunc, i);
|
||||
|
||||
if (func->handler_id == commit_notify_handler)
|
||||
{
|
||||
g_array_remove_index (buffer->priv->commit_funcs, i);
|
||||
|
||||
if (buffer->priv->commit_funcs->len == 0)
|
||||
g_clear_pointer (&buffer->priv->commit_funcs, g_array_unref);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_warning ("No such GtkTextBufferCommitNotify matching %u",
|
||||
commit_notify_handler);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_commit_notify (GtkTextBuffer *buffer,
|
||||
GtkTextBufferNotifyFlags flags,
|
||||
guint position,
|
||||
guint length)
|
||||
{
|
||||
buffer->priv->in_commit_notify = TRUE;
|
||||
|
||||
for (guint i = 0; i < buffer->priv->commit_funcs->len; i++)
|
||||
{
|
||||
const CommitFunc *func = &g_array_index (buffer->priv->commit_funcs, CommitFunc, i);
|
||||
|
||||
if (func->flags & flags)
|
||||
func->callback (buffer, flags, position, length, func->user_data);
|
||||
}
|
||||
|
||||
buffer->priv->in_commit_notify = FALSE;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,55 @@ struct _GtkTextBuffer
|
||||
GtkTextBufferPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkTextBufferCommitNotify:
|
||||
* @buffer: the text buffer being notified
|
||||
* @flags: the type of commit notification
|
||||
* @position: the position of the text operation
|
||||
* @length: the length of the text operation in characters
|
||||
* @user_data: (closure): user data passed to the callback
|
||||
*
|
||||
* A notification callback used by [method@Gtk.TextBuffer.add_commit_notify].
|
||||
*
|
||||
* You may not modify the [class@Gtk.TextBuffer] from a
|
||||
* [callback@Gtk.TextBufferCommitNotify] callback and that is enforced
|
||||
* by the [class@Gtk.TextBuffer] API.
|
||||
*
|
||||
* [callback@Gtk.TextBufferCommitNotify] may be used to be notified about
|
||||
* changes to the underlying buffer right before-or-after the changes are
|
||||
* committed to the underlying B-Tree. This is useful if you want to observe
|
||||
* changes to the buffer without other signal handlers potentially modifying
|
||||
* state on the way to the default signal handler.
|
||||
*
|
||||
* When @flags is `GTK_TEXT_BUFFER_NOTIFY_BEFORE_INSERT`, `position` is set to
|
||||
* the offset in characters from the start of the buffer where the insertion
|
||||
* will occur. `length` is set to the number of characters to be inserted. You
|
||||
* may not yet retrieve the text until it has been inserted. You may access the
|
||||
* text from `GTK_TEXT_BUFFER_NOTIFY_AFTER_INSERT` using
|
||||
* [method@Gtk.TextBuffer.get_slice].
|
||||
*
|
||||
* When @flags is `GTK_TEXT_BUFFER_NOTIFY_AFTER_INSERT`, `position` is set to
|
||||
* offset in characters where the insertion occurred and `length` is set
|
||||
* to the number of characters inserted.
|
||||
*
|
||||
* When @flags is `GTK_TEXT_BUFFER_NOTIFY_BEFORE_DELETE`, `position` is set to
|
||||
* offset in characters where the deletion will occur and `length` is set
|
||||
* to the number of characters that will be removed. You may still retrieve
|
||||
* the text from this handler using `position` and `length`.
|
||||
*
|
||||
* When @flags is `GTK_TEXT_BUFFER_NOTIFY_AFTER_DELETE`, `length` is set to
|
||||
* zero to denote that the delete-range has already been committed to the
|
||||
* underlying B-Tree. You may no longer retrieve the text that has been
|
||||
* deleted from the [class@Gtk.TextBuffer].
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
typedef void (*GtkTextBufferCommitNotify) (GtkTextBuffer *buffer,
|
||||
GtkTextBufferNotifyFlags flags,
|
||||
guint position,
|
||||
guint length,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* GtkTextBufferClass:
|
||||
* @parent_class: The object class structure needs to be the first.
|
||||
@@ -459,6 +508,15 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_text_buffer_end_user_action (GtkTextBuffer *buffer);
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
guint gtk_text_buffer_add_commit_notify (GtkTextBuffer *buffer,
|
||||
GtkTextBufferNotifyFlags flags,
|
||||
GtkTextBufferCommitNotify commit_notify,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy);
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
void gtk_text_buffer_remove_commit_notify (GtkTextBuffer *buffer,
|
||||
guint commit_notify_handler);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkTextBuffer, g_object_unref)
|
||||
|
||||
|
||||
+1
-1
@@ -8221,7 +8221,7 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
|
||||
GtkTextAttributes*
|
||||
gtk_text_view_get_default_attributes (GtkTextView *text_view)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), gtk_text_attributes_new());
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
|
||||
@@ -292,6 +292,7 @@ gtk_uri_launcher_launch (GtkUriLauncher *self,
|
||||
g_task_return_new_error (task,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"No uri to launch");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -301,6 +302,7 @@ gtk_uri_launcher_launch (GtkUriLauncher *self,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"%s is not a valid uri: %s", self->uri, error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -382,7 +382,6 @@ window_notify_cb (GtkWindowControls *self,
|
||||
pspec->name == I_("maximized") ||
|
||||
pspec->name == I_("modal") ||
|
||||
pspec->name == I_("resizable") ||
|
||||
pspec->name == I_("scale-factor") ||
|
||||
pspec->name == I_("transient-for"))
|
||||
update_window_buttons (self);
|
||||
}
|
||||
|
||||
+51
-20
@@ -56,6 +56,7 @@
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include <gdk/gdkrgbaprivate.h>
|
||||
#include <gdk/gdkcolorstateprivate.h>
|
||||
#include "gtk/gtkdebug.h"
|
||||
#include "gtk/gtkbuiltiniconprivate.h"
|
||||
#include "gtk/gtkrendernodepaintableprivate.h"
|
||||
@@ -506,7 +507,7 @@ node_name (GskRenderNode *node)
|
||||
return g_strdup (gsk_debug_node_get_message (node));
|
||||
|
||||
case GSK_COLOR_NODE:
|
||||
return gdk_rgba_to_string (gsk_color_node_get_color (node));
|
||||
return gdk_color_to_string (gsk_color_node_get_color2 (node));
|
||||
|
||||
case GSK_TEXTURE_NODE:
|
||||
{
|
||||
@@ -793,38 +794,51 @@ recording_selected (GtkSingleSelection *selection,
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
get_color_texture (const GdkRGBA *color)
|
||||
get_color2_texture (const GdkColor *color)
|
||||
{
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
GdkTexture *texture;
|
||||
guchar pixel[4];
|
||||
gsize stride;
|
||||
guchar *data;
|
||||
GBytes *bytes;
|
||||
int width = 30;
|
||||
int height = 30;
|
||||
int i;
|
||||
|
||||
pixel[0] = round (color->red * 255);
|
||||
pixel[1] = round (color->green * 255);
|
||||
pixel[2] = round (color->blue * 255);
|
||||
pixel[3] = round (color->alpha * 255);
|
||||
stride = width * 4 * sizeof (float);
|
||||
data = g_malloc (stride * height);
|
||||
for (int i = 0; i < width * height; i++)
|
||||
memcpy (data + 4 * sizeof (float) * i, color->values, 4 * sizeof (float));
|
||||
|
||||
data = g_malloc (4 * width * height);
|
||||
for (i = 0; i < width * height; i++)
|
||||
{
|
||||
memcpy (data + 4 * i, pixel, 4);
|
||||
}
|
||||
bytes = g_bytes_new_take (data, stride * height);
|
||||
|
||||
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, 30);
|
||||
gdk_memory_texture_builder_set_height (builder, 30);
|
||||
gdk_memory_texture_builder_set_format (builder, GDK_MEMORY_R32G32B32A32_FLOAT);
|
||||
gdk_memory_texture_builder_set_color_state (builder, color->color_state);
|
||||
|
||||
texture = gdk_memory_texture_builder_build (builder);
|
||||
|
||||
bytes = g_bytes_new_take (data, 4 * width * height);
|
||||
texture = gdk_memory_texture_new (width,
|
||||
height,
|
||||
GDK_MEMORY_R8G8B8A8,
|
||||
bytes,
|
||||
width * 4);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
get_color_texture (const GdkRGBA *rgba)
|
||||
{
|
||||
GdkColor color;
|
||||
GdkTexture *texture;
|
||||
|
||||
gdk_color_init_from_rgba (&color, rgba);
|
||||
texture = get_color2_texture (&color);
|
||||
gdk_color_finish (&color);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
get_linear_gradient_texture (gsize n_stops, const GskColorStop *stops)
|
||||
{
|
||||
@@ -907,6 +921,21 @@ add_color_row (GListStore *store,
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
add_color2_row (GListStore *store,
|
||||
const char *name,
|
||||
const GdkColor *color)
|
||||
{
|
||||
char *text;
|
||||
GdkTexture *texture;
|
||||
|
||||
text = gdk_color_to_string (color);
|
||||
texture = get_color2_texture (color);
|
||||
list_store_add_object_property (store, name, text, texture);
|
||||
g_free (text);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
add_int_row (GListStore *store,
|
||||
const char *name,
|
||||
@@ -961,6 +990,8 @@ add_texture_rows (GListStore *store,
|
||||
add_text_row (store, "Type", "%s", G_OBJECT_TYPE_NAME (texture));
|
||||
add_text_row (store, "Size", "%u x %u", gdk_texture_get_width (texture), gdk_texture_get_height (texture));
|
||||
add_text_row (store, "Format", "%s", enum_to_nick (GDK_TYPE_MEMORY_FORMAT, gdk_texture_get_format (texture)));
|
||||
add_text_row (store, "Color State", "%s", gdk_color_state_get_name (gdk_texture_get_color_state (texture)));
|
||||
|
||||
if (GDK_IS_MEMORY_TEXTURE (texture))
|
||||
{
|
||||
GBytes *bytes;
|
||||
@@ -1067,7 +1098,7 @@ populate_render_node_properties (GListStore *store,
|
||||
break;
|
||||
|
||||
case GSK_COLOR_NODE:
|
||||
add_color_row (store, "Color", gsk_color_node_get_color (node));
|
||||
add_color2_row (store, "Color", gsk_color_node_get_color2 (node));
|
||||
break;
|
||||
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
|
||||
@@ -9724,7 +9724,7 @@ roaring_bitmap_t *roaring_bitmap_lazy_xor(const roaring_bitmap_t *x1,
|
||||
container_lazy_xor(c1, container_type_1, c2, container_type_2,
|
||||
&container_result_type);
|
||||
|
||||
if (container_nonzero_cardinality(c, container_result_type)) {
|
||||
if (c && container_nonzero_cardinality(c, container_result_type)) {
|
||||
ra_append(&answer->high_low_container, s1, c,
|
||||
container_result_type);
|
||||
} else {
|
||||
|
||||
@@ -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>
|
||||
@@ -170,8 +168,7 @@ add_drm_formats_and_modifiers (GstCaps *caps,
|
||||
|
||||
static GdkColorState *
|
||||
gtk_gst_color_state_from_colorimetry (GtkGstSink *self,
|
||||
const GstVideoColorimetry *colorimetry,
|
||||
gconstpointer drm)
|
||||
const GstVideoColorimetry *colorimetry)
|
||||
{
|
||||
GdkCicpParams *params;
|
||||
GdkColorState *color_state;
|
||||
@@ -189,92 +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)
|
||||
{
|
||||
switch (drm_info->drm_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:
|
||||
g_debug ("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);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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);
|
||||
g_debug ("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);
|
||||
|
||||
g_debug ("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)
|
||||
@@ -358,14 +281,7 @@ gtk_gst_sink_set_caps (GstBaseSink *bsink,
|
||||
#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;
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include <gsk/gskcairoblurprivate.h>
|
||||
|
||||
/* This is a hack to work around the fact that this code includes
|
||||
* private headers that inline access to non-exported variables.
|
||||
*/
|
||||
GdkColorState *gdk_default_color_states;
|
||||
|
||||
static void
|
||||
init_surface (cairo_t *cr)
|
||||
{
|
||||
int w = cairo_image_surface_get_width (cairo_get_target (cr));
|
||||
int h = cairo_image_surface_get_height (cairo_get_target (cr));
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_arc (cr, w/2, h/2, w/2, 0, 2*G_PI);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GTimer *timer;
|
||||
double msec;
|
||||
int i, j;
|
||||
int size;
|
||||
|
||||
gdk_default_color_states = gdk_color_state_get_srgb ();
|
||||
|
||||
timer = g_timer_new ();
|
||||
|
||||
size = 2000;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_A8, size, size);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
/* We do everything three times, first two as warmup */
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = 1; i < 16; i++)
|
||||
{
|
||||
init_surface (cr);
|
||||
g_timer_start (timer);
|
||||
gsk_cairo_blur_surface (surface, i, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
msec = g_timer_elapsed (timer, NULL) * 1000;
|
||||
if (j == 1)
|
||||
g_print ("Radius %2d: %.2f msec, %.2f kpixels/msec:\n", i, msec, size*size/(msec*1000));
|
||||
}
|
||||
}
|
||||
|
||||
g_timer_destroy (timer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -17,7 +17,6 @@ gtk_tests = [
|
||||
['animated-revealing', ['frame-stats.c', 'variable.c']],
|
||||
['motion-compression'],
|
||||
['scrolling-performance', ['frame-stats.c', 'variable.c']],
|
||||
['blur-performance', ['../gsk/gskcairoblur.c']],
|
||||
['simple'],
|
||||
['video-timer', ['variable.c']],
|
||||
['testaccel'],
|
||||
|
||||
@@ -128,6 +128,7 @@ test_data = [
|
||||
'at-valid-16.errors',
|
||||
'at-valid-16.ref.css',
|
||||
'at-valid-17.css',
|
||||
'at-valid-17.errors',
|
||||
'at-valid-18.css',
|
||||
'at-valid-18.ref.css',
|
||||
'background-blend-mode.css',
|
||||
@@ -147,6 +148,7 @@ test_data = [
|
||||
'background-repeat.css',
|
||||
'background-repeat.ref.css',
|
||||
'background-shorthand.css',
|
||||
'background-shorthand.errors',
|
||||
'background-shorthand.ref.css',
|
||||
'background-shorthand-single.css',
|
||||
'background-shorthand-single.ref.css',
|
||||
@@ -207,6 +209,7 @@ test_data = [
|
||||
'close-at-end-of-file.errors',
|
||||
'close-at-end-of-file.ref.css',
|
||||
'color.css',
|
||||
'color.errors',
|
||||
'color.ref.css',
|
||||
'colors-errors.css',
|
||||
'colors-errors.errors',
|
||||
@@ -229,6 +232,8 @@ test_data = [
|
||||
'css-21-malformed-statements.errors',
|
||||
'css-21-malformed-statements.ref.css',
|
||||
'currentcolor-everywhere.css',
|
||||
'currentcolor-everywhere.ref.css',
|
||||
'currentcolor-everywhere.errors',
|
||||
'dash-backslash-eof-is-identifier.ref.css',
|
||||
'dash-backslash-eof-is-identifier.css',
|
||||
'dash-backslash-eof-is-identifier.errors',
|
||||
@@ -286,6 +291,7 @@ test_data = [
|
||||
'declarations-valid-08.css',
|
||||
'declarations-valid-08.ref.css',
|
||||
'declarations-valid-09.css',
|
||||
'declarations-valid-09.errors',
|
||||
'declarations-valid-09.ref.css',
|
||||
'declarations-valid-10.css',
|
||||
'declarations-valid-10.ref.css',
|
||||
@@ -493,6 +499,7 @@ test_data = [
|
||||
'selector-original.css',
|
||||
'selector-original.ref.css',
|
||||
'shadow.css',
|
||||
'shadow.errors',
|
||||
'shadow.ref.css',
|
||||
'shadow-ordering.css',
|
||||
'shadow-ordering.ref.css',
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk.h>
|
||||
#include "gdkcolorstateprivate.h"
|
||||
#include "gdkcolorprivate.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "gdkcolordefs.h"
|
||||
@@ -48,9 +50,6 @@ static MatrixTest matrices[] = {
|
||||
{ "ntsc", ntsc_to_xyz, xyz_to_ntsc },
|
||||
{ "p3", p3_to_xyz, xyz_to_p3 },
|
||||
{ "srgb<>rec2020", rec2020_to_srgb, srgb_to_rec2020 },
|
||||
{ "bt601", bt601_to_rgb, rgb_to_bt601 },
|
||||
{ "bt709", bt709_to_rgb, rgb_to_bt709 },
|
||||
{ "bt2020", bt2020_to_rgb, rgb_to_bt2020 },
|
||||
};
|
||||
|
||||
#define IDX(i,j) 3*i+j
|
||||
@@ -137,9 +136,111 @@ test_rec2020_to_srgb (void)
|
||||
g_assert_cmpfloat_with_epsilon (norm (res), 0, 0.001);
|
||||
}
|
||||
|
||||
/* Verify that this color is different enough in srgb-linear and srgb
|
||||
* to be detected.
|
||||
*/
|
||||
static void
|
||||
test_color_mislabel (void)
|
||||
{
|
||||
GdkColor color;
|
||||
GdkColor color1;
|
||||
GdkColor color2;
|
||||
guint red1, red2;
|
||||
|
||||
gdk_color_init (&color, gdk_color_state_get_srgb_linear (), (float[]) { 0.604, 0, 0, 1 });
|
||||
gdk_color_convert (&color1, gdk_color_state_get_srgb (), &color);
|
||||
gdk_color_init (&color2, gdk_color_state_get_srgb (), (float[]) { 0.604, 0, 0, 1 });
|
||||
|
||||
g_assert_true (!gdk_color_equal (&color1, &color2));
|
||||
|
||||
red1 = round (color1.red * 255.0);
|
||||
red2 = round (color2.red * 255.0);
|
||||
|
||||
g_assert_true (red1 != red2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rendering_colorstate (void)
|
||||
{
|
||||
struct {
|
||||
GdkColorState *surface;
|
||||
gboolean srgb;
|
||||
GdkColorState *rendering;
|
||||
} tests[] = {
|
||||
{ GDK_COLOR_STATE_SRGB, 0, GDK_COLOR_STATE_SRGB },
|
||||
{ GDK_COLOR_STATE_SRGB, 1, GDK_COLOR_STATE_SRGB_LINEAR },
|
||||
{ GDK_COLOR_STATE_SRGB_LINEAR, 0, GDK_COLOR_STATE_SRGB_LINEAR },
|
||||
{ GDK_COLOR_STATE_SRGB_LINEAR, 1, GDK_COLOR_STATE_SRGB_LINEAR },
|
||||
{ GDK_COLOR_STATE_REC2100_PQ, 0, GDK_COLOR_STATE_REC2100_PQ },
|
||||
{ GDK_COLOR_STATE_REC2100_PQ, 1, GDK_COLOR_STATE_SRGB_LINEAR },
|
||||
{ GDK_COLOR_STATE_REC2100_LINEAR, 0, GDK_COLOR_STATE_REC2100_LINEAR },
|
||||
{ GDK_COLOR_STATE_REC2100_LINEAR, 1, GDK_COLOR_STATE_SRGB_LINEAR },
|
||||
};
|
||||
|
||||
if (GDK_DEBUG_CHECK (HDR) || GDK_DEBUG_CHECK (LINEAR))
|
||||
{
|
||||
g_test_skip ("Skip because GDK_DEBUG flags hdr or linear are set");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
GdkColorState *res = gdk_color_state_get_rendering_color_state (tests[i].surface, tests[i].srgb);
|
||||
|
||||
g_assert_true (gdk_color_state_equal (res, tests[i].rendering));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_color_conversion (void)
|
||||
{
|
||||
GdkColor color;
|
||||
GdkColor color2;
|
||||
GdkColor color3;
|
||||
|
||||
gdk_color_init (&color, GDK_COLOR_STATE_REC2100_PQ, (float[4]) { 0, 0.5, 1, 1 });
|
||||
gdk_color_convert (&color2, GDK_COLOR_STATE_REC2100_LINEAR, &color);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (0, color2.values[0], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (0.45, color2.values[1], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (49.26, color2.values[2], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (1, color2.values[3], 0.005);
|
||||
|
||||
gdk_color_convert (&color3, GDK_COLOR_STATE_REC2100_PQ, &color2);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[0], color.values[0], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[1], color.values[1], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[2], color.values[2], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[3], color.values[3], 0.005);
|
||||
|
||||
gdk_color_finish (&color);
|
||||
gdk_color_finish (&color2);
|
||||
gdk_color_finish (&color3);
|
||||
|
||||
gdk_color_init (&color, GDK_COLOR_STATE_SRGB, (float[4]) { 0, 0.5, 1, 1 });
|
||||
gdk_color_convert (&color2, GDK_COLOR_STATE_REC2100_LINEAR, &color);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (0.114, color2.values[0], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (0.208, color2.values[1], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (0.914, color2.values[2], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (1, color2.values[3], 0.005);
|
||||
|
||||
gdk_color_convert (&color3, GDK_COLOR_STATE_SRGB, &color2);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[0], color.values[0], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[1], color.values[1], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[2], color.values[2], 0.005);
|
||||
g_assert_cmpfloat_with_epsilon (color3.values[3], color.values[3], 0.005);
|
||||
|
||||
gdk_color_finish (&color);
|
||||
gdk_color_finish (&color2);
|
||||
gdk_color_finish (&color3);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_init ();
|
||||
(g_test_init) (&argc, &argv, NULL);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (transfers); i++)
|
||||
@@ -160,6 +261,10 @@ main (int argc, char *argv[])
|
||||
|
||||
g_test_add_func ("/colorstate/matrix/srgb_to_rec2020", test_srgb_to_rec2020);
|
||||
g_test_add_func ("/colorstate/matrix/rec2020_to_srgb", test_rec2020_to_srgb);
|
||||
g_test_add_func ("/colorstate/rendering", test_rendering_colorstate);
|
||||
g_test_add_func ("/color/mislabel", test_color_mislabel);
|
||||
g_test_add_func ("/color/conversion", test_color_conversion);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
||||
@@ -127,11 +127,9 @@ test_convert (gconstpointer testdata)
|
||||
gsize width, height;
|
||||
GdkMemoryFormat test_format;
|
||||
|
||||
#if 0
|
||||
if (g_test_rand_bit ())
|
||||
test_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
else
|
||||
#endif
|
||||
test_format = GDK_MEMORY_R32G32B32A32_FLOAT;
|
||||
|
||||
path = g_test_build_filename (G_TEST_DIST, "image-data", "image.png", NULL);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkdmabuffourccprivate.h>
|
||||
#include <gdk/gdkdmabuftextureprivate.h>
|
||||
#include <gdk/gdkdmabufeglprivate.h>
|
||||
|
||||
static cairo_surface_t *
|
||||
make_surface (int width,
|
||||
@@ -192,8 +191,6 @@ test_dmabuf_import (void)
|
||||
GdkGLTextureBuilder *builder;
|
||||
guchar *data;
|
||||
gboolean external;
|
||||
GdkColorState *color_state;
|
||||
int color_space, range;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
if (!gdk_display_prepare_gl (display, &error))
|
||||
@@ -232,9 +229,7 @@ test_dmabuf_import (void)
|
||||
g_assert_no_error (error);
|
||||
|
||||
dmabuf2 = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
color_state = gdk_texture_get_color_state (texture);
|
||||
gdk_dmabuf_get_egl_yuv_hints (dmabuf2, color_state, &color_space, &range);
|
||||
texture_id2 = gdk_gl_context_import_dmabuf (context2, 64, 64, dmabuf2, color_space, range, &external);
|
||||
texture_id2 = gdk_gl_context_import_dmabuf (context2, 64, 64, dmabuf2, &external);
|
||||
g_assert_cmpint (texture_id2, !=, 0);
|
||||
g_assert_false (external);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include "../reftests/reftest-compare.h"
|
||||
#include "dmabufize.h"
|
||||
|
||||
|
||||
static char *arg_output_dir = NULL;
|
||||
@@ -16,7 +15,6 @@ static gboolean mask = FALSE;
|
||||
static gboolean replay = FALSE;
|
||||
static gboolean clip = FALSE;
|
||||
static gboolean colorflip = FALSE;
|
||||
static gboolean dmabuf = FALSE;
|
||||
|
||||
extern void
|
||||
replay_node (GskRenderNode *node, GtkSnapshot *snapshot);
|
||||
@@ -174,7 +172,6 @@ static const GOptionEntry options[] = {
|
||||
{ "replay", 0, 0, G_OPTION_ARG_NONE, &replay, "Do replay test", NULL },
|
||||
{ "clip", 0, 0, G_OPTION_ARG_NONE, &clip, "Do clip test", NULL },
|
||||
{ "colorflip", 0, 0, G_OPTION_ARG_NONE, &colorflip, "Swap colors", NULL },
|
||||
{ "dmabuf", 0, 0, G_OPTION_ARG_NONE, &dmabuf, "Turn into dmabufs", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -731,37 +728,6 @@ skip_clip:
|
||||
gsk_render_node_unref (node2);
|
||||
}
|
||||
|
||||
if (dmabuf)
|
||||
{
|
||||
GskRenderNode *node2;
|
||||
graphene_rect_t node_bounds;
|
||||
|
||||
gsk_render_node_get_bounds (node, &node_bounds);
|
||||
|
||||
node2 = dmabufize_node (node);
|
||||
|
||||
save_node (node2, node_file, "-dmabuf.node");
|
||||
|
||||
rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL);
|
||||
save_image (rendered_texture, node_file, "-dmabuf.out.png");
|
||||
|
||||
reference_texture = gsk_renderer_render_texture (renderer, node, &node_bounds);
|
||||
save_image (reference_texture, node_file, "-dmabuf.ref.png");
|
||||
|
||||
diff_texture = reftest_compare_textures (rendered_texture, reference_texture);
|
||||
|
||||
if (diff_texture)
|
||||
{
|
||||
save_image (diff_texture, node_file, "-dmabuf.diff.png");
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
g_clear_object (&diff_texture);
|
||||
g_clear_object (&rendered_texture);
|
||||
g_clear_object (&reference_texture);
|
||||
gsk_render_node_unref (node2);
|
||||
}
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
gsk_renderer_unrealize (renderer);
|
||||
g_object_unref (renderer);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: color(rec2100-pq 1 0 0 / 0.2);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 222 B |
@@ -0,0 +1,23 @@
|
||||
@cicp "mycolors" {
|
||||
primaries: 1;
|
||||
transfer: 13;
|
||||
matrix: 0;
|
||||
range: full;
|
||||
}
|
||||
|
||||
color {
|
||||
bounds: 0 0 100 100;
|
||||
color: color(srgb 1 0 0);
|
||||
}
|
||||
color {
|
||||
bounds: 100 0 100 100;
|
||||
color: color(srgb-linear 1 0 0);
|
||||
}
|
||||
color {
|
||||
bounds: 0 100 100 100;
|
||||
color: color(rec2100-pq 0.792 0.231 0.0738);
|
||||
}
|
||||
color {
|
||||
bounds: 100 100 100 100;
|
||||
color: color("mycolors" 1 0 0);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 427 B |
@@ -0,0 +1,12 @@
|
||||
opacity {
|
||||
child: mask {
|
||||
source: color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgba(255,0,0,0.3);
|
||||
}
|
||||
mask: color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(255,255,255);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 174 B |
@@ -0,0 +1,8 @@
|
||||
repeat {
|
||||
bounds: 0 0 40 40;
|
||||
child-bounds: 0 0 10 10;
|
||||
child: color {
|
||||
bounds: 0 0 10 10;
|
||||
color: color(srgb-linear 0.604 0 0);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 149 B |
@@ -1,439 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "udmabuf.h"
|
||||
#include "dmabufize.h"
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
static GdkTexture *
|
||||
dmabufize_texture (GdkTexture *texture)
|
||||
{
|
||||
guint32 fourcc = 0;
|
||||
guint32 bpp;
|
||||
gboolean premultiplied;
|
||||
gsize width;
|
||||
gsize height;
|
||||
gsize size;
|
||||
UDmabuf *udmabuf;
|
||||
GdkTextureDownloader *downloader;
|
||||
GdkDmabufTextureBuilder *builder;
|
||||
GdkTexture *texture2;
|
||||
|
||||
if (strcmp (G_OBJECT_TYPE_NAME (texture), "GdkMemoryTexture") != 0)
|
||||
return g_object_ref (texture);
|
||||
|
||||
switch ((int) gdk_texture_get_format (texture))
|
||||
{
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
fourcc = DRM_FORMAT_ARGB8888;
|
||||
premultiplied = TRUE;
|
||||
bpp = 4;
|
||||
break;
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
fourcc = DRM_FORMAT_BGRA8888;
|
||||
premultiplied = TRUE;
|
||||
bpp = 4;
|
||||
break;
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
fourcc = DRM_FORMAT_ABGR8888;
|
||||
premultiplied = TRUE;
|
||||
bpp = 4;
|
||||
break;
|
||||
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
|
||||
fourcc = DRM_FORMAT_RGBA8888;
|
||||
premultiplied = TRUE;
|
||||
bpp = 4;
|
||||
break;
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
fourcc = DRM_FORMAT_ARGB8888;
|
||||
premultiplied = FALSE;
|
||||
bpp = 4;
|
||||
break;
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
fourcc = DRM_FORMAT_BGRA8888;
|
||||
premultiplied = FALSE;
|
||||
bpp = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fourcc == 0)
|
||||
return g_object_ref (texture);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
size = height * width * bpp;
|
||||
|
||||
udmabuf = udmabuf_allocate (size, NULL);
|
||||
|
||||
downloader = gdk_texture_downloader_new (texture);
|
||||
|
||||
gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (texture));
|
||||
gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (texture));
|
||||
|
||||
gdk_texture_downloader_download_into (downloader, (guchar *)udmabuf->data, width * bpp);
|
||||
|
||||
gdk_texture_downloader_free (downloader);
|
||||
|
||||
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_fourcc (builder, fourcc);
|
||||
gdk_dmabuf_texture_builder_set_modifier (builder, 0);
|
||||
gdk_dmabuf_texture_builder_set_premultiplied (builder, premultiplied);
|
||||
gdk_dmabuf_texture_builder_set_n_planes (builder, 1);
|
||||
gdk_dmabuf_texture_builder_set_fd (builder, 0, udmabuf->dmabuf_fd);
|
||||
gdk_dmabuf_texture_builder_set_stride (builder, 0, width * bpp);
|
||||
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
|
||||
gdk_dmabuf_texture_builder_set_color_state (builder, gdk_texture_get_color_state (texture));
|
||||
texture2 = gdk_dmabuf_texture_builder_build (builder, udmabuf_free, udmabuf, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
|
||||
return texture2;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_container_node (GskRenderNode *node)
|
||||
{
|
||||
guint n_nodes;
|
||||
GskRenderNode **nodes;
|
||||
|
||||
n_nodes = gsk_container_node_get_n_children (node);
|
||||
nodes = g_newa (GskRenderNode *, n_nodes);
|
||||
|
||||
for (int i = 0; i < n_nodes; i++)
|
||||
nodes[i] = dmabufize_node (gsk_container_node_get_child (node, i));
|
||||
|
||||
node = gsk_container_node_new (nodes, n_nodes);
|
||||
|
||||
for (int i = 0; i < n_nodes; i++)
|
||||
gsk_render_node_unref (nodes[i]);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_texture_node (GskRenderNode *node)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
|
||||
texture = dmabufize_texture (texture);
|
||||
|
||||
node = gsk_texture_node_new (texture, &bounds);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_texture_scale_node (GskRenderNode *node)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_scale_node_get_texture (node);
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
|
||||
texture = dmabufize_texture (texture);
|
||||
|
||||
node = gsk_texture_scale_node_new (texture, &bounds, gsk_texture_scale_node_get_filter (node));
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_transform_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_transform_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_transform_node_new (child, gsk_transform_node_get_transform (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_opacity_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_opacity_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_opacity_node_new (child, gsk_opacity_node_get_opacity (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_color_matrix_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_color_matrix_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_color_matrix_node_new (child, gsk_color_matrix_node_get_color_matrix (node),
|
||||
gsk_color_matrix_node_get_color_offset (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_repeat_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_repeat_node_get_child (node);
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_repeat_node_new (&bounds,
|
||||
child,
|
||||
gsk_repeat_node_get_child_bounds (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_clip_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_clip_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_clip_node_new (child, gsk_clip_node_get_clip (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_rounded_clip_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_rounded_clip_node_new (child, gsk_rounded_clip_node_get_clip (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_shadow_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_shadow_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_shadow_node_new (child,
|
||||
gsk_shadow_node_get_shadow (node, 0),
|
||||
gsk_shadow_node_get_n_shadows (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_blend_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *top = gsk_blend_node_get_top_child (node);
|
||||
GskRenderNode *bottom = gsk_blend_node_get_bottom_child (node);
|
||||
|
||||
top = dmabufize_node (top);
|
||||
bottom = dmabufize_node (bottom);
|
||||
node = gsk_blend_node_new (bottom, top, gsk_blend_node_get_blend_mode (node));
|
||||
gsk_render_node_unref (top);
|
||||
gsk_render_node_unref (bottom);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_cross_fade_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *start = gsk_cross_fade_node_get_start_child (node);
|
||||
GskRenderNode *end = gsk_cross_fade_node_get_end_child (node);
|
||||
|
||||
start = dmabufize_node (start);
|
||||
end = dmabufize_node (end);
|
||||
node = gsk_cross_fade_node_new (start, end, gsk_cross_fade_node_get_progress (node));
|
||||
gsk_render_node_unref (start);
|
||||
gsk_render_node_unref (end);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_blur_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_blur_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_blur_node_new (child, gsk_blur_node_get_radius (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_debug_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_debug_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_debug_node_new (child, (char *)gsk_debug_node_get_message (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_mask_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *source = gsk_mask_node_get_source (node);
|
||||
GskRenderNode *mask = gsk_mask_node_get_mask (node);
|
||||
|
||||
source = dmabufize_node (source);
|
||||
mask = dmabufize_node (mask);
|
||||
node = gsk_mask_node_new (source, mask, gsk_mask_node_get_mask_mode (node));
|
||||
gsk_render_node_unref (source);
|
||||
gsk_render_node_unref (mask);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_fill_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_fill_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_fill_node_new (child, gsk_fill_node_get_path (node), gsk_fill_node_get_fill_rule (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_stroke_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_stroke_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_stroke_node_new (child, gsk_stroke_node_get_path (node), gsk_stroke_node_get_stroke (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
dmabufize_subsurface_node (GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *child = gsk_subsurface_node_get_child (node);
|
||||
|
||||
child = dmabufize_node (child);
|
||||
node = gsk_subsurface_node_new (child, gsk_subsurface_node_get_subsurface (node));
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
dmabufize_node (GskRenderNode *node)
|
||||
{
|
||||
switch (gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_CONTAINER_NODE:
|
||||
return dmabufize_container_node (node);
|
||||
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_COLOR_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:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_GL_SHADER_NODE:
|
||||
return gsk_render_node_ref (node);
|
||||
|
||||
case GSK_TEXTURE_NODE:
|
||||
return dmabufize_texture_node (node);
|
||||
|
||||
case GSK_TEXTURE_SCALE_NODE:
|
||||
return dmabufize_texture_scale_node (node);
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
return dmabufize_transform_node (node);
|
||||
|
||||
case GSK_OPACITY_NODE:
|
||||
return dmabufize_opacity_node (node);
|
||||
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
return dmabufize_color_matrix_node (node);
|
||||
|
||||
case GSK_REPEAT_NODE:
|
||||
return dmabufize_repeat_node (node);
|
||||
|
||||
case GSK_CLIP_NODE:
|
||||
return dmabufize_clip_node (node);
|
||||
|
||||
case GSK_ROUNDED_CLIP_NODE:
|
||||
return dmabufize_rounded_clip_node (node);
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
return dmabufize_shadow_node (node);
|
||||
|
||||
case GSK_BLEND_NODE:
|
||||
return dmabufize_blend_node (node);
|
||||
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
return dmabufize_cross_fade_node (node);
|
||||
|
||||
case GSK_BLUR_NODE:
|
||||
return dmabufize_blur_node (node);
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
return dmabufize_debug_node (node);
|
||||
|
||||
case GSK_MASK_NODE:
|
||||
return dmabufize_mask_node (node);
|
||||
|
||||
case GSK_FILL_NODE:
|
||||
return dmabufize_fill_node (node);
|
||||
|
||||
case GSK_STROKE_NODE:
|
||||
return dmabufize_stroke_node (node);
|
||||
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
return dmabufize_subsurface_node (node);
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
GskRenderNode *
|
||||
dmabufize_node (GskRenderNode *node)
|
||||
{
|
||||
return gsk_render_node_ref (node);
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user