Compare commits

..

78 Commits

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

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

Update all callers to pass FALSE, except for the one call in
the node processor, where we want to take GL_LINEAR into account.
2024-08-07 13:34:45 -04:00
Matthias Clasen 50c19a6534 Merge branch 'hdr-content' into 'main'
gsk: Track whether nodes require wide gamut

See merge request GNOME/gtk!7575
2024-08-07 17:34:02 +00:00
Matthias Clasen 6edb526561 Merge branch 'plug-gtask-leaks' into 'main'
Plug GTask leaks

See merge request GNOME/gtk!7551
2024-08-07 16:26:52 +00:00
Matthias Clasen ee18156675 gsk: Add gsk_render_node_is_hdr
Add a function that tracks whether a render node's content is
in a wide gamut color state (in practice, that means non-sRGB).

This will be used in render_texture to determine the color
state to use when creating a texture.
2024-08-07 11:14:21 -04:00
Matthias Clasen e70a961ac1 Merge branch 'matthiasc/for-main' into 'main'
memoryformat: Add a debug helper

See merge request GNOME/gtk!7571
2024-08-07 14:51:05 +00:00
Matthias Clasen ffdc8c8f60 gsk: Drop some unused code
Nobody is using gsk_gpu_download_png_op, and we are going to
refactor the download op code.
2024-08-07 08:39:53 -04:00
Matthias Clasen fd78bd3eaf memoryformat: Add a debug helper
I need this often enough that I'll just put it here.
2024-08-07 08:22:05 -04:00
Matthias Clasen f2ccba0988 Merge branch 'wip/test-parser-data-additions' into 'main'
testsuite: add more files to test_data

See merge request GNOME/gtk!7569
2024-08-07 03:30:20 +00:00
Jeremy Bícha 8ee465c630 testsuite: add more files to test_data 2024-08-06 20:28:58 -04:00
Matthias Clasen 31b655c9eb Merge branch 'wip/dont-leak-egl-surface' into 'main'
gdk/surface: Don't leak the EGLSurface

See merge request GNOME/gtk!7568
2024-08-06 22:54:31 +00:00
Jonas Ådahl 7fd65cc3c1 gdk/surface: Don't leak the EGLSurface
Each time we create a new window, we create a new EGLSurface. Each time
we destroy a window, we failed to destroy the EGLSurface, due to passing
a GdkDisplay instead of a EGLDisplay to eglDestroySurface().

This effectively leaked not only the EGL surface metadata, but also the
associated DMA buffers. For applications where one opens and closes many
windows over the lifetime of the application, and where the application
runs for a long time; for example a terminal emulator server, this
causes a significant memory leak, as the memory will only ever be freed
once once the application process itself exits, if ever.

Fix this passing an actual EGLDisplay instead of an GdkDisplay, to
eglDestroySurface().
2024-08-06 23:42:11 +02:00
Jonas Ådahl 8089222fc3 gsk/gpu/downloadop: Include glib-unix.h
It's needed by g_close().
2024-08-06 23:41:46 +02:00
Benjamin Otte 0667bd39fb Merge branch 'wip/otte/for-main' into 'main'
gpu: Consult target colorstate for depth

See merge request GNOME/gtk!7567
2024-08-06 21:07:44 +00:00
Benjamin Otte a4854dfa9e memoryformat: Use "(p)" as premultiplied indicator in names
This matches what the gpu renderer does when printing
colorstates.

It also avoids it printing "S*RGBA8" for the format and instead prints
"SRGBA8(p)" now.
2024-08-06 22:15:17 +02:00
Benjamin Otte 6c54d0a7e2 gpu: Consult target colorstate for depth
When creating images for use with different colorstates, ensure that
they have the depth of that colorstate. Otherwise we might lose accuracy
due to quantization.

Fixes mipmaps in rec2100 being rendered as RGBA8.
2024-08-06 22:15:17 +02:00
Matthias Clasen 341860eb4d Merge branch 'small-fixes' into 'main'
colorstate: Drop xyz for now

See merge request GNOME/gtk!7565
2024-08-06 20:06:38 +00:00
Matthias Clasen 876445f080 inspector: Show color states of textures 2024-08-06 15:38:31 -04:00
Matthias Clasen 03ef6a7719 colorstate: Drop xyz for now
Converting to and from xyz turns out to be more difficult than
expected, depending on what whitepoint you choose, And different
specs choose different whitepoints, so we can't directly map
css xyz to cicp xyz anyway.
2024-08-06 15:38:31 -04:00
Benjamin Otte fde8c6df79 Merge branch 'wip/otte/for-main' into 'main'
rendrenodeparser: Use simpler function

See merge request GNOME/gtk!7564
2024-08-06 16:18:13 +00:00
Benjamin Otte 6c06e1855e roaring: Fix a compiler warning
This is a simple fix, I did not investigate if NULL is actually possible
here.

In function ‘bitset_container_empty’,
    inlined from ‘bitset_container_const_nonzero_cardinality’ at ../gtk/roaring/roaring.h:1942:13,
    inlined from ‘container_nonzero_cardinality’ at ../gtk/roaring/roaring.h:4055:20,
    inlined from ‘roaring_bitmap_lazy_xor’ at ../gtk/roaring/roaring.c:9727:17:
../gtk/roaring/roaring.h:1928:13: error: potential null pointer dereference [-Werror=null-dereference]
 1928 |   if (bitset->cardinality == BITSET_UNKNOWN_CARDINALITY) {
      |       ~~~~~~^~~~~~~~~~~~~
2024-08-06 17:53:41 +02:00
Benjamin Otte c60ae0b575 textview: Fix compiler warning
../gtk/gtktextview.c: In function ‘gtk_text_view_add_default_attributes’:
../gtk/gtktextview.c:10681:8: error: potential null pointer dereference [-Werror=null-dereference]
2024-08-06 17:50:57 +02:00
Benjamin Otte e58f9ea1b4 rendrenodeparser: Use simpler function
We don't need to peek tokens.
2024-08-06 17:50:43 +02:00
Matthias Clasen 3d55d733dc Merge branch 'fix-premul-for-colorize' into 'main'
Colors are always unpremultiplied

See merge request GNOME/gtk!7563
2024-08-06 11:33:38 +00:00
Matthias Clasen 582dba54b1 Try to fix win32 build of compare-render 2024-08-06 07:10:04 -04:00
Matthias Clasen 0775432ed9 Add a compare test for premultiplied colors
This test checks a that a specific combination of mask with alpha
inside opacity works as expected. We were treating the mask color
as premultiplied here, although it isn't.
2024-08-06 00:59:23 -04:00
Matthias Clasen d9e15ff6e9 Colors are always unpremultiplied
We can't use gsk_gpu_node_processor_color_states_self() for ops which
apply alt to colors that don't come from textures, since those are
always unpremultiplied.

This fixes the + and - in disabled spin buttons appearing completely
white.
2024-08-06 00:59:23 -04:00
Matthias Clasen c04edfc76e Merge branch 'matthiasc/for-main' into 'main'
rewrite color parsing in the node parser

See merge request GNOME/gtk!7560
2024-08-06 04:54:04 +00:00
Matthias Clasen 71d6392572 nodeparser: Rewrite the color parsing
Use gtk_css_parser_consume_function, for better error handling.
We are now getting the expected error for

  color(srgb 1 2 3 4 5 6)

Test included.
2024-08-06 00:23:07 -04:00
Matthias Clasen dbd16cd9da Rename GDK_COLOR_INIT_SRGB
Rename the macro to GDK_COLOR_SRGB, and make it usable as
a compound literal as well.

Update all users.
2024-08-06 00:06:41 -04:00
Matthias Clasen 950d266894 Merge branch 'wip/chergert/fix-6133-commit-funcs' into 'main'
textbuffer: Add GtkTextBufferCommitNotify

Closes #6133

See merge request GNOME/gtk!7524
2024-08-06 01:41:23 +00:00
Matthias Clasen 884974eeaa Merge branch 'matthiasc/for-main' into 'main'
gsk: Improve handling of fill and stroke nodes

See merge request GNOME/gtk!7559
2024-08-05 21:01:54 +00:00
Christian Hergert e836166664 textbuffer: Add GtkTextBufferCommitNotify
Add a new function callback called GtkTetBufferCommitNotify to be notified
of changes to a GtkTextBuffer without being involved in a signal chain.

This is necessary for some situations because signal handlers may modify
the parameters as they proceed down to default handler. As such, the signal
is unsuitable for applications heavily utilizing plug-ins such as Builder
due to non-deterministic signal connection ordering.

This technique has been used in Builder for the better part of a decade
and now would also vastly help in situations like libspelling where you
also want to know about changes to the buffer right before they are
committed to the b-tree.

Fixes: #6133
2024-08-05 13:28:59 -07:00
Matthias Clasen c1a99bf901 tests: Link compare-render statically
This is a temporary change, only needed until we make the new
snapshot and rendernode apis public.
2024-08-05 16:09:42 -04:00
Matthias Clasen f9c9a03404 gsk: Improve handling of fill and stroke nodes
Use GdkColor here. We still convert to sRGB as the last step, though.
2024-08-05 15:59:28 -04:00
Matthias Clasen 3a337824e6 Merge branch 'css-color-hookup-1' into 'main'
Add GdkColor, make non-srgb css colors work for color nodes

See merge request GNOME/gtk!7546
2024-08-05 16:11:39 +00:00
Matthias Clasen 7dab23e38a gl: Handle color nodes with color states
Since we don't have proper color management here, just convert
any color we meet to sRGB and hope for the best.
2024-08-05 11:11:15 -04:00
Matthias Clasen 78935ec83c Make node-format.md part of the docs
This makes useful information more easily available, and it also
serves to validate the markdown.
2024-08-05 11:11:15 -04:00
Matthias Clasen b8989b7ff6 Add a compare test for color states
This checks that the red values in all 4 default color states
come out identical to a plain old red png.
2024-08-05 11:11:15 -04:00
Matthias Clasen 96cd47d0a0 inspector: Show more color node details
Show the color state, and create textures with the full color
information.
2024-08-05 11:11:15 -04:00
Matthias Clasen d6a6cfe6c5 gtk: Fix gtk_snapshot_collect_repeat
This creates a new color node that is meant to be identical to
an existing one, so we need to use gsk_color_node_new2 to preserve
the color state information.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen 501356116d gtk: Preserve css background color spaces
When rendering css backgrounds, use the new gtk_css_color_get_color
and gtk_snapshot_append_color2 apis to preserve color spaces as
far as possible.
2024-08-05 11:11:15 -04:00
Matthias Clasen e11e5525db gtk: Add gtk_snapshot_append_color2
This is a private snapshot function that uses the new color
node constructor to create a color node with a given color state.
2024-08-05 11:11:15 -04:00
Matthias Clasen 16431da3f2 nodeparser: Add support for cicp color states
Allow defining cicp color states with an @-rule:

    @cicp "jpeg" {
      primaries: 1;
      transfer: 13;
      matrix: 6;
      range: full;
    }

And allow using them in color() like this:

    color("jpeg" 50% 0.5 1 / 75%)

Note that custom color states use a string, unlike default color
states which use an ident.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen 842949fcf3 nodeparser: Support color states
And allow using color states for colors with a syntax similar
to modern css color syntax.

color(srgb 50% 0.5 1 / 75%)

Both floating point numbers and percentages can be used.

Currently, this is only supported for color nodes.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen 3d3e935c91 offload: Use gsk_color_node_get_color2
We want the blackest black.
2024-08-05 11:11:15 -04:00
Matthias Clasen d5ae94ca5d testsuite: Update replay nodes
We can't currently recreate color nodes with public api, so cheat
and reuse the node we got.
2024-08-05 11:11:15 -04:00
Matthias Clasen 87e9c940a4 gsk: Use the private color node api
Use the color state returned by this function instead of assuming
the color of a color node is always sRGB.

Node colors are converted to the css on the cpu. That is necessary
since we don't know if they are in one of the default color states,
and our shaders can't deal with non-default color states.
2024-08-05 11:11:14 -04:00
Matthias Clasen 6a02fa4be8 gsk: Add private color node api
Add a constructor that takes a color state, a getter for it, and
also a getter for the color coordinates that avoids GdkRGBA.
2024-08-05 11:11:14 -04:00
Matthias Clasen 9f548efd32 gsk: Change color op apis
Make color-related ops take the ccs and a GdkColor, and make
decisions about color conversion on the cpu vs the gpu.

This makes the node processor code simpler, and lets use convert
the color directly into the op instance without extra copying.

We also pass opacity to the op, so it can be applied when we
write the color into the instance.

Lastly, rorder the offset to come right after the opacity argument.

Treat the color and rounded color ops the same way.

Update all callers.

With this, the prepare_color apis in gskgpunodeprocessor.c are
no longer used and have been dropped.
2024-08-05 11:11:14 -04:00
Matthias Clasen 9eebe8e547 gsk: Change the clear op api
A clear op is just a fancy memcpy. Make it the callers responsibility
to convert the color to the right color state before passing it
to the clear op.
2024-08-05 11:11:14 -04:00
Matthias Clasen f9612533c2 css: Add gtk_css_color_to_color
This api lets one obtain a color state and color values from
a GtkCssColor. We don't want to force everything though sRGB,
but we can't quite avoid conversion here, since we don't have
a 100% match between the css color spaces and color states.

css color cleanup
2024-08-05 11:11:14 -04:00
Matthias Clasen c9c0d444a2 cairo: Add gdk_cairo_set_source_color
This lets us set a GdkColor as a cairo source.
2024-08-05 11:11:14 -04:00
Matthias Clasen 13a8704f51 Add GdkColor
For now, this is all private api.

Parts of it will be opened up in 4.18.
2024-08-05 11:11:14 -04:00
Arjan Molenaar f20714262c Merge branch 'macos-fix-window-transparency' into 'main'
macos: fix window transparency

Closes #6838

See merge request GNOME/gtk!7544
2024-08-05 12:20:32 +00:00
Matthias Clasen 11ffeeb55c Merge branch 'wip/otte/for-alice' into 'main'
Fix warning on startup

See merge request GNOME/gtk!7547
2024-08-05 12:18:00 +00:00
Sergey Bugaev 85830c059e Plug GTask leaks
The error-prone pattern seems to be:

  GTask *task = g_task_new (...);

  if (condition)
    {
      g_task_return_... (task, ...);
      /* need g_object_unref (task) here! */
      return;
    }

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-08-05 14:38:23 +03:00
Matthias Clasen ffc89e40a0 colorstate: Add a color conversion function
Add a function for converting a single color from one
color state to another. This is a generalization of the
already existing function to convert a GdkRGBA to another
color state.
2024-08-04 14:21:15 -04:00
Matthias Clasen 1c92f2d963 Merge branch 'matthiasc/for-main' into 'main'
Disable blur-performance build

See merge request GNOME/gtk!7549
2024-08-04 02:52:53 +00:00
Matthias Clasen 12e0ec0b48 Add gtk_css_parser_has_percentage 2024-08-03 22:31:32 -04:00
Matthias Clasen 5574bf59f6 Disable blur-performance build
This is an old test that isn't very relevant anymore, and it has
some linking problems because it includes private headers that
have inlined functions.
2024-08-03 22:31:21 -04:00
Matthias Clasen 7ee27cc0ad Merge branch 'matthiasc/for-main' into 'main'
gpu: Rename function

See merge request GNOME/gtk!7548
2024-08-04 01:23:41 +00:00
Benjamin Otte 040974c8a2 iconhelper: Size no longer depends on scale
This is a leftover from GTK3 when iconhelper sizes depended on the
texture size.

Now we only need to queue a redraw with the new icon.

Fixes warnings about resizes during allocate caused by scale change
notification during allocation of GtkWindow.
2024-08-04 03:11:56 +02:00
Benjamin Otte 126d689086 gpu: Rename function
We want to reuse gsk_gpu_color_to_float() for use with GdkColor and this
function will be replaced. But until that's fully done, we need 2
different names.

So rename this one to something else
2024-08-03 20:59:40 -04:00
Benjamin Otte 8e676c7360 windowcontrols: No need to listen to scale factor changes
This is a GTK3 leftover where the icons were manually drawn and sized.
Now that they're managed by actual widgets that enforce a correct size
that is independent of scale factor, this is no longer necessary.

Fixes warnings about resizes during allocate caused by scale change
notification during allocation of GtkWindow.
2024-08-04 01:23:07 +02:00
Arjan Molenaar 84847e46fa macos: fix window transparency
Revert window decoration changes from
a6ce506714.
2024-08-02 17:30:48 +02:00
120 changed files with 2631 additions and 1826 deletions
+1 -1
View File
@@ -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>
+1
View File
@@ -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
View File
@@ -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
-4
View File
@@ -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
View File
@@ -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);
}
-36
View File
@@ -222,39 +222,3 @@ static const float srgb_to_rec2020[9] = {
0.069108, 0.919519, 0.011360,
0.016394, 0.088011, 0.895380,
};
static const float rgb_to_bt601[9] = {
0.299000, 0.587000, 0.114000,
-0.168736, -0.331264, 0.500000,
0.500000, -0.418688, -0.081312,
};
static const float bt601_to_rgb[9] = {
1.000000, 0.000000, 1.402000,
1.000000, -0.344136, -0.714136,
1.000000, 1.772000, 0.000000,
};
static const float rgb_to_bt709[9] = {
0.212600, 0.715200, 0.072200,
-0.114572, -0.385428, 0.500000,
0.500000, -0.454153, -0.045847,
};
static const float bt709_to_rgb[9] = {
1.000000, 0.000000, 1.574800,
1.000000, -0.187324, -0.468124,
1.000000, 1.855600, -0.000000,
};
static const float rgb_to_bt2020[9] = {
0.262700, 0.678000, 0.059300,
-0.139630, -0.360370, 0.500000,
0.500000, -0.459786, -0.040214,
};
static const float bt2020_to_rgb[9] = {
1.000000, -0.000000, 1.474600,
1.000000, -0.164553, -0.571353,
1.000000, 1.881400, -0.000000,
};
+135
View File
@@ -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);
}
+107
View File
@@ -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
View File
@@ -18,7 +18,6 @@
#include "config.h"
#define GDK_COLOR_STATE_IMPL
#include "gdkcolorstateprivate.h"
#include <math.h>
@@ -412,7 +411,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
},
};
/* }}} */
/* }}} */
/* {{{ Cicp implementation */
typedef struct _GdkCicpColorState GdkCicpColorState;
@@ -432,128 +431,25 @@ struct _GdkCicpColorState
float *from_srgb;
float *from_rec2020;
const float *from_yuv;
const float *to_yuv;
GdkCicp cicp;
};
/* {{{ Conversion functions */
#define TRANSFORM_FROM_CICP(name, matrix, oetf) \
static void \
name (GdkColorState *color_state, \
float (*values)[4], \
gsize n_values) \
{ \
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
\
for (gsize i = 0; i < n_values; i++) \
{ \
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
{ \
values[i][0] = CLAMP ((values[i][0] - 16.0/255.0) * 255.0 / 219.0, -10, 10); \
values[i][1] = CLAMP ((values[i][1] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
values[i][2] = CLAMP ((values[i][2] - 16.0/255.0) * 255.0 / 224.0, -10, 10); \
} \
if (self->from_yuv) \
{ \
float res[3]; \
values[i][1] -= 0.5; \
values[i][2] -= 0.5; \
res[0] = self->from_yuv[0] * values[i][0] + self->from_yuv[1] * values[i][1] + self->from_yuv[2] * values[i][2]; \
res[1] = self->from_yuv[3] * values[i][0] + self->from_yuv[4] * values[i][1] + self->from_yuv[5] * values[i][2]; \
res[2] = self->from_yuv[6] * values[i][0] + self->from_yuv[7] * values[i][1] + self->from_yuv[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (self->eotf != NONE) \
{ \
values[i][0] = self->eotf (values[i][0]); \
values[i][1] = self->eotf (values[i][1]); \
values[i][2] = self->eotf (values[i][2]); \
} \
if (self->matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (oetf != NONE) \
{ \
values[i][0] = oetf (values[i][0]); \
values[i][1] = oetf (values[i][1]); \
values[i][2] = oetf (values[i][2]); \
} \
} \
}
#define cicp ((GdkCicpColorState *)self)
#define TRANSFORM_TO_CICP(name, eotf, matrix) \
static void \
name (GdkColorState *color_state, \
float (*values)[4], \
gsize n_values) \
{ \
GdkCicpColorState *self = (GdkCicpColorState *) color_state; \
\
for (gsize i = 0; i < n_values; i++) \
{ \
if (eotf != NONE) \
{ \
values[i][0] = eotf (values[i][0]); \
values[i][1] = eotf (values[i][1]); \
values[i][2] = eotf (values[i][2]); \
} \
if (self->matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = self->matrix[0] * values[i][0] + self->matrix[1] * values[i][1] + self->matrix[2] * values[i][2]; \
res[1] = self->matrix[3] * values[i][0] + self->matrix[4] * values[i][1] + self->matrix[5] * values[i][2]; \
res[2] = self->matrix[6] * values[i][0] + self->matrix[7] * values[i][1] + self->matrix[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (self->oetf != NONE) \
{ \
values[i][0] = self->oetf (values[i][0]); \
values[i][1] = self->oetf (values[i][1]); \
values[i][2] = self->oetf (values[i][2]); \
} \
if (self->to_yuv) \
{ \
float res[3]; \
res[0] = self->to_yuv[0] * values[i][0] + self->to_yuv[1] * values[i][1] + self->to_yuv[2] * values[i][2]; \
res[1] = self->to_yuv[3] * values[i][0] + self->to_yuv[4] * values[i][1] + self->to_yuv[5] * values[i][2]; \
res[2] = self->to_yuv[6] * values[i][0] + self->to_yuv[7] * values[i][1] + self->to_yuv[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1] + 0.5; \
values[i][2] = res[2] + 0.5; \
} \
if (self->cicp.range == GDK_CICP_RANGE_NARROW) \
{ \
values[i][0] = values[i][0] * 219.0 / 255.0 + 16.0 / 255.0; \
values[i][1] = values[i][1] * 224.0 / 255.0 + 16.0 / 255.0; \
values[i][2] = values[i][2] * 224.0 / 255.0 + 16.0 / 255.0; \
} \
} \
}
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb, to_srgb, srgb_oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_srgb_linear, to_srgb, NONE)
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_pq, to_rec2020, pq_oetf)
TRANSFORM_FROM_CICP(gdk_cicp_to_rec2100_linear, to_rec2020, NONE)
TRANSFORM_TO_CICP(gdk_cicp_from_srgb, srgb_eotf, from_srgb)
TRANSFORM_TO_CICP(gdk_cicp_from_srgb_linear, NONE, from_srgb)
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_pq, pq_eotf, from_rec2020)
TRANSFORM_TO_CICP(gdk_cicp_from_rec2100_linear, NONE, from_rec2020)
#undef cicp
/* }}} */
/* }}} */
/* {{{ Vfuncs */
@@ -659,7 +555,7 @@ gdk_cicp_color_state_get_cicp (GdkColorState *color_state)
return &self->cicp;
}
/* }}} */
/* }}} */
static const
GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
@@ -672,46 +568,6 @@ GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
.get_cicp = gdk_cicp_color_state_get_cicp,
};
GdkCicpColorState gdk_color_state_bt601_narrow = {
.parent = {
.klass = &GDK_CICP_COLOR_STATE_CLASS,
.ref_count = 1,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "cicp-1/13/6/0",
.no_srgb = NULL,
.cicp = { 1, 13, 6, 0 },
.eotf = srgb_eotf,
.oetf = srgb_oetf,
.to_yuv = rgb_to_bt601,
.from_yuv = bt601_to_rgb,
.to_srgb = IDENTITY,
.to_rec2020 = (float *) srgb_to_rec2020,
.from_srgb = IDENTITY,
.from_rec2020 = (float *) rec2020_to_srgb,
};
GdkCicpColorState gdk_color_state_bt601_full = {
.parent = {
.klass = &GDK_CICP_COLOR_STATE_CLASS,
.ref_count = 1,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "cicp-1/13/6/1",
.no_srgb = NULL,
.cicp = { 1, 13, 6, 1 },
.eotf = srgb_eotf,
.oetf = srgb_oetf,
.to_yuv = rgb_to_bt601,
.from_yuv = bt601_to_rgb,
.to_srgb = IDENTITY,
.to_rec2020 = (float *) srgb_to_rec2020,
.from_srgb = IDENTITY,
.from_rec2020 = (float *) rec2020_to_srgb,
};
static inline float *
multiply (float res[9],
const float m1[9],
@@ -736,8 +592,14 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
GdkTransferFunc oetf;
gconstpointer to_xyz;
gconstpointer from_xyz;
gconstpointer to_yuv = NULL;
gconstpointer from_yuv = NULL;
if (cicp->range == GDK_CICP_RANGE_NARROW || cicp->matrix_coefficients != 0)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Narrow range or YUV not supported"));
return NULL;
}
if (cicp->color_primaries == 2 ||
cicp->transfer_function == 2 ||
@@ -751,16 +613,10 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
for (guint i = 0; i < GDK_COLOR_STATE_N_IDS; i++)
{
if (gdk_cicp_equal (cicp, &gdk_default_color_states[i].cicp))
if (gdk_cicp_equivalent (cicp, &gdk_default_color_states[i].cicp))
return (GdkColorState *) &gdk_default_color_states[i];
}
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_narrow.cicp))
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_narrow);
if (gdk_cicp_equal (cicp, &gdk_color_state_bt601_full.cicp))
return gdk_color_state_ref ((GdkColorState *) &gdk_color_state_bt601_full);
switch (cicp->transfer_function)
{
case 1:
@@ -813,7 +669,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
from_xyz = xyz_to_pal;
break;
case 6:
case 7:
to_xyz = ntsc_to_xyz;
from_xyz = xyz_to_ntsc;
break;
@@ -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
View File
@@ -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
View File
@@ -24,7 +24,6 @@
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkcolorstate.h"
#ifdef HAVE_DMABUF
#include <sys/mman.h>
@@ -134,6 +133,49 @@ download_memcpy_3_1 (guchar *dst_data,
}
}
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static void
download_nv12 (guchar *dst_data,
gsize dst_stride,
@@ -184,21 +226,14 @@ download_nv12 (guchar *dst_data,
{
for (x = 0; x < width; x += X_SUB)
{
int u_, v_;
int r, g, b;
gsize xs, ys;
u_ = uv_data[x / X_SUB * 2 + U];
v_ = uv_data[x / X_SUB * 2 + V];
get_uv_values (&itu601_narrow, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint8 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
rgb[0] = y_data[x + xs + y_stride * ys];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
@@ -206,6 +241,35 @@ download_nv12 (guchar *dst_data,
}
}
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static void
download_p010 (guchar *dst,
gsize dst_stride,
@@ -220,7 +284,7 @@ download_p010 (guchar *dst,
guint16 *dst_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
guint16 SIZE;
guint16 SIZE, MASK;
switch (dmabuf->fourcc)
{
@@ -240,6 +304,7 @@ download_p010 (guchar *dst,
g_assert_not_reached ();
return;
}
MASK = 0xFFFF << (16 - SIZE);
y_stride = dmabuf->planes[0].stride / 2;
y_data = (const guint16 *) (src_data[0] + dmabuf->planes[0].offset);
@@ -254,24 +319,22 @@ download_p010 (guchar *dst,
{
for (x = 0; x < width; x += X_SUB)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u_, v_;
guint16 u, v;
u_ = uv_data[x / X_SUB * 2 + U];
u_ = u_ | (u_ >> SIZE);
v_ = uv_data[x / X_SUB * 2 + V];
v_ = v_ | (v_ >> SIZE);
u = uv_data[x / X_SUB * 2 + U];
u = (u & MASK) | (u >> SIZE);
v = uv_data[x / X_SUB * 2 + V];
v = (v & MASK) | (v >> SIZE);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint16 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = y_ | (y_ >> SIZE);
rgb[0] = y_;
rgb[1] = u_;
rgb[2] = v_;
y_ = (y_ & MASK) | (y_ >> SIZE);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += Y_SUB * dst_stride;
@@ -345,21 +408,14 @@ download_yuv_3 (guchar *dst_data,
{
for (x = 0; x < width; x += X_SUB)
{
int u_, v_;
int r, g, b;
gsize xs, ys;
u_ = u_data[x / X_SUB];
v_ = v_data[x / X_SUB];
get_uv_values (&itu601_narrow, u_data[x / X_SUB], v_data[x / X_SUB], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint8 *rgb = &dst_data[3 * (x + xs) + dst_stride * ys];
rgb[0] = y_data[x + xs + y_stride * ys];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
@@ -409,23 +465,12 @@ download_yuyv (guchar *dst_data,
{
for (x = 0; x < width; x += 2)
{
guint8 *rgb;
int u_, v_;
int r, g, b;
u_ = src_data[2 * x + U];
v_ = src_data[2 * x + V];
rgb = &dst_data[3 * x];
rgb[0] = src_data[2 * x + Y1];
rgb[1] = u_;
rgb[2] = v_;
get_uv_values (&itu601_narrow, src_data[2 * x + U], src_data[2 * x + V], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + Y1], r, g, b);
if (x + 1 < width)
{
rgb = &dst_data[3 * (x + 1)];
rgb[0] = src_data[2 * x + Y2];
rgb[1] = u_;
rgb[2] = v_;
}
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + Y2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
@@ -2094,14 +2139,14 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
needs_unmap[i] = TRUE;
}
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
out:
for (i = 0; i < dmabuf->n_planes; i++)
+4 -76
View File
@@ -209,15 +209,12 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
int target)
{
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLint attribs[64];
int i;
EGLImage image;
gboolean is_yuv;
g_return_val_if_fail (width > 0, 0);
g_return_val_if_fail (height > 0, 0);
@@ -231,25 +228,6 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
return EGL_NO_IMAGE;
}
if (gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv) && is_yuv)
{
if (color_space_hint == 0 || range_hint == 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import yuv dmabuf into GL without color space hints");
return EGL_NO_IMAGE;
}
}
else
{
if (color_space_hint != 0 || range_hint != 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import non-yuv dmabuf into GL with color space hints");
return EGL_NO_IMAGE;
}
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
@@ -263,16 +241,10 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
attribs[i++] = height;
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[i++] = dmabuf->fourcc;
if (color_space_hint != 0)
{
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
attribs[i++] = color_space_hint;
}
if (range_hint != 0)
{
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
attribs[i++] = range_hint;
}
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
attribs[i++] = EGL_ITU_REC601_EXT;
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
attribs[i++] = EGL_YUV_NARROW_RANGE_EXT;
#define ADD_PLANE(plane) \
{ \
@@ -317,48 +289,4 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
return image;
}
void
gdk_dmabuf_get_egl_yuv_hints (const GdkDmabuf *dmabuf,
GdkColorState *color_state,
int *color_space_hint,
int *range_hint)
{
gboolean is_yuv;
const GdkCicp *cicp;
cicp = gdk_color_state_get_cicp (color_state);
if (cicp &&
gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv) && is_yuv)
{
if (cicp->range == GDK_CICP_RANGE_NARROW)
*range_hint = EGL_YUV_NARROW_RANGE_EXT;
else
*range_hint = EGL_YUV_FULL_RANGE_EXT;
switch (cicp->matrix_coefficients)
{
case 1:
*color_space_hint = EGL_ITU_REC709_EXT;
break;
case 5:
case 6:
*color_space_hint = EGL_ITU_REC601_EXT;
break;
case 9:
*color_space_hint = EGL_ITU_REC2020_EXT;
break;
default:
*color_space_hint = 0;
*range_hint = 0;
break;
}
}
else
{
*color_space_hint = 0;
*range_hint = 0;
}
}
#endif /* HAVE_DMABUF && HAVE_EGL */
-7
View File
@@ -13,13 +13,6 @@ EGLImage gdk_dmabuf_egl_create_image (GdkDisplay
int width,
int height,
const GdkDmabuf *dmabuf,
int color_state_hint,
int range_hint,
int target);
void gdk_dmabuf_get_egl_yuv_hints (const GdkDmabuf *dmabuf,
GdkColorState *color_state,
int *color_space_hint,
int *range_hint);
#endif /* HAVE_DMABUF && HAVE_EGL */
+5 -2
View File
@@ -208,9 +208,12 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
gboolean is_yuv;
if (gdk_dmabuf_fourcc_is_yuv (dmabuf.fourcc, &is_yuv) && is_yuv)
color_state = GDK_COLOR_STATE_YUV;
{
g_warning_once ("FIXME: Implement the proper colorstate for YUV dmabufs");
color_state = gdk_color_state_get_srgb ();
}
else
color_state = GDK_COLOR_STATE_SRGB;
color_state = gdk_color_state_get_srgb ();
}
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
+1 -16
View File
@@ -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)
-2
View File
@@ -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
View File
@@ -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)
+1
View File
@@ -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
View File
@@ -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;
}
+1 -4
View File
@@ -678,10 +678,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_union (region, priv->regions[priv->draw_index]);
if (priv->current_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_color_state = color_state;
*out_depth = priv->current_depth;
}
+28 -41
View File
@@ -149,39 +149,37 @@ gdk_load_jpeg (GBytes *input_bytes,
g_bytes_get_size (input_bytes));
jpeg_read_header (&info, TRUE);
if (info.jpeg_color_space == JCS_GRAYSCALE)
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_GRAYSCALE;
format = GDK_MEMORY_G8;
}
else if (info.jpeg_color_space == JCS_YCbCr)
{
color_state = GDK_COLOR_STATE_JPEG;
info.out_color_space = JCS_YCbCr;
format = GDK_MEMORY_R8G8B8;
}
else if (info.jpeg_color_space == JCS_CMYK)
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_CMYK;
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
else
{
color_state = GDK_COLOR_STATE_SRGB;
info.out_color_space = JCS_RGB;
format = GDK_MEMORY_R8G8B8;
}
jpeg_start_decompress (&info);
width = info.output_width;
height = info.output_height;
stride = gdk_memory_format_bytes_per_pixel (format) * width;
data = g_try_malloc_n (stride, height);
color_state = GDK_COLOR_STATE_SRGB;
switch ((int)info.out_color_space)
{
case JCS_GRAYSCALE:
stride = width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_G8;
break;
case JCS_RGB:
stride = 3 * width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_R8G8B8;
break;
case JCS_CMYK:
stride = 4 * width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
break;
default:
g_set_error (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
_("Unsupported JPEG colorspace (%d)"), info.out_color_space);
jpeg_destroy_decompress (&info);
return NULL;
}
if (!data)
{
@@ -217,6 +215,7 @@ gdk_load_jpeg (GBytes *input_bytes,
texture = gdk_memory_texture_builder_build (builder);
gdk_color_state_unref (color_state);
g_object_unref (builder);
g_bytes_unref (bytes);
@@ -240,7 +239,6 @@ gdk_save_jpeg (GdkTexture *texture)
gsize texstride;
guchar *row;
int width, height;
GdkColorState *color_state;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
@@ -270,24 +268,13 @@ gdk_save_jpeg (GdkTexture *texture)
jpeg_set_defaults (&info);
jpeg_set_quality (&info, 75, TRUE);
color_state = gdk_texture_get_color_state (texture);
if (gdk_color_state_equal (color_state, GDK_COLOR_STATE_JPEG))
{
info.in_color_space = JCS_YCbCr;
}
else
{
info.in_color_space = JCS_RGB;
color_state = GDK_COLOR_STATE_SRGB;
}
info.mem->max_memory_to_use = 300 * 1024 * 1024;
jpeg_mem_dest (&info, &data, &size);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8);
gdk_texture_downloader_set_color_state (&downloader, color_state);
gdk_texture_downloader_set_color_state (&downloader, GDK_COLOR_STATE_SRGB);
texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride);
gdk_texture_downloader_finish (&downloader);
texdata = g_bytes_get_data (texbytes, NULL);
+2 -9
View File
@@ -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];
}
+1
View File
@@ -7,6 +7,7 @@ gdk_public_sources = files([
'gdkcairocontext.c',
'gdkcicpparams.c',
'gdkclipboard.c',
'gdkcolor.c',
'gdkcolorstate.c',
'gdkcontentdeserializer.c',
'gdkcontentformats.c',
+3
View File
@@ -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 *
+3
View File
@@ -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 *
+3
View File
@@ -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 *
+9
View File
@@ -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 *
+1
View File
@@ -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;
}
+1
View File
@@ -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;
}
-9
View File
@@ -43,7 +43,6 @@
#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include <gdk/gdktextureprivate.h>
#include <gdk/gdkdmabufeglprivate.h>
#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkdmabuftextureprivate.h>
@@ -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
View File
@@ -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
View File
@@ -10,7 +10,6 @@
#include "gskglimageprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdmabufeglprivate.h"
#include "gdkglcontextprivate.h"
#include "gdkgltextureprivate.h"
@@ -93,7 +92,7 @@ gsk_gl_frame_upload_texture (GskGpuFrame *frame,
gdk_gl_texture_get_id (gl_texture),
FALSE,
gdk_gl_texture_has_mipmap (gl_texture) ? (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_MIPMAP) : 0);
/* This is a hack, but it works */
sync = gdk_gl_texture_get_sync (gl_texture);
if (sync)
@@ -106,56 +105,19 @@ gsk_gl_frame_upload_texture (GskGpuFrame *frame,
{
gboolean external;
GLuint tex_id;
int color_space_hint = 0;
int range_hint = 0;
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
gdk_dmabuf_get_egl_yuv_hints (gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
gdk_texture_get_color_state (texture),
&color_space_hint,
&range_hint);
#endif
tex_id = gdk_gl_context_import_dmabuf (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
color_space_hint,
range_hint,
&external);
if (tex_id)
{
GskGpuImageFlags flags = 0;
if (external)
flags |= GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT;
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
switch (color_space_hint)
{
case EGL_ITU_REC709_EXT:
flags |= GSK_GPU_IMAGE_BT709;
break;
case EGL_ITU_REC601_EXT:
flags |= GSK_GPU_IMAGE_BT601;
break;
case EGL_ITU_REC2020_EXT:
flags |= GSK_GPU_IMAGE_BT2020;
break;
default:
break;
}
if (range_hint == EGL_YUV_NARROW_RANGE_EXT)
flags |= GSK_GPU_IMAGE_NARROW_RANGE;
#endif
return gsk_gl_image_new_for_texture (GSK_GL_DEVICE (gsk_gpu_frame_get_device (frame)),
texture,
tex_id,
TRUE,
flags);
(external ? GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT : 0));
}
}
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -682,7 +682,7 @@ gsk_gpu_cache_lookup_tile (GskGpuCache *self,
gsk_gpu_cached_use (self, (GskGpuCached *) tile);
*out_color_state = gdk_color_state_ref (tile->color_state);
*out_color_state = tile->color_state;
return g_object_ref (tile->image);
}
+2 -3
View File
@@ -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);
}
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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);
}
+9 -5
View File
@@ -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);
}
+5 -3
View File
@@ -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
+10
View File
@@ -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;
}
+1 -6
View File
@@ -36,8 +36,7 @@ gsk_gpu_convert_cicp_op_print_instance (GskGpuShaderOp *shader,
g_string_append_printf (string, "cicp %u/%u/%u/%u",
instance->color_primaries,
instance->transfer_function,
instance->matrix_coefficients,
instance->range);
0, 1);
}
static const GskGpuShaderOpClass GSK_GPU_CONVERT_OP_CLASS = {
@@ -89,8 +88,6 @@ gsk_gpu_convert_from_cicp_op (GskGpuFrame *frame,
instance->opacity = opacity;
instance->color_primaries = cicp->color_primaries;
instance->transfer_function = cicp->transfer_function;
instance->matrix_coefficients = cicp->matrix_coefficients;
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
}
void
@@ -121,6 +118,4 @@ gsk_gpu_convert_to_cicp_op (GskGpuFrame *frame,
instance->opacity = opacity;
instance->color_primaries = cicp->color_primaries;
instance->transfer_function = cicp->transfer_function;
instance->matrix_coefficients = cicp->matrix_coefficients;
instance->range = cicp->range == GDK_CICP_RANGE_NARROW ? 0 : 1;
}
+102 -36
View File
@@ -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);
}
+2 -5
View File
@@ -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
View File
@@ -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) {
-59
View File
@@ -1,7 +1,6 @@
#include "config.h"
#include "gskgpuimageprivate.h"
#include "gdkcolorstateprivate.h"
typedef struct _GskGpuImagePrivate GskGpuImagePrivate;
@@ -163,61 +162,3 @@ gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
{
GSK_GPU_IMAGE_GET_CLASS (self)->get_projection_matrix (self, out_projection);
}
GdkColorState *
gsk_gpu_image_adjust_color_state (GskGpuImage *self,
GdkColorState *color_state)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
GdkColorState *adjusted;
GdkCicp cicp;
adjusted = gdk_color_state_ref (color_state);
if (priv->flags & GSK_GPU_IMAGE_SRGB)
{
GdkColorState *no_srgb;
no_srgb = gdk_color_state_get_no_srgb_tf (adjusted);
g_assert (no_srgb);
gdk_color_state_unref (adjusted);
adjusted = gdk_color_state_ref (no_srgb);
}
if (!gdk_color_state_get_cicp (adjusted))
return adjusted;
cicp = *gdk_color_state_get_cicp (adjusted);
if (priv->flags & GSK_GPU_IMAGE_NARROW_RANGE)
cicp.range = GDK_CICP_RANGE_FULL;
switch (priv->flags & GSK_GPU_IMAGE_YUV)
{
case GSK_GPU_IMAGE_BT709:
g_assert (cicp.matrix_coefficients == 1);
cicp.matrix_coefficients = 0;
break;
case GSK_GPU_IMAGE_BT601:
g_assert (cicp.matrix_coefficients == 5 ||
cicp.matrix_coefficients == 6);
cicp.matrix_coefficients = 0;
break;
case GSK_GPU_IMAGE_BT2020:
g_assert (cicp.matrix_coefficients == 9);
cicp.matrix_coefficients = 0;
break;
default:
break;
}
if (!gdk_cicp_equal (&cicp, gdk_color_state_get_cicp (adjusted)))
{
gdk_color_state_unref (adjusted);
adjusted = gdk_color_state_new_for_cicp (&cicp, NULL);
g_assert (adjusted);
}
return adjusted;
}
-3
View File
@@ -48,9 +48,6 @@ void gsk_gpu_image_set_flags (GskGpuI
void gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection);
GdkColorState * gsk_gpu_image_adjust_color_state (GskGpuImage *self,
GdkColorState *color_state);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuImage, g_object_unref)
+130 -87
View File
@@ -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))
{
+14 -9
View File
@@ -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);
+1 -1
View File
@@ -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;
}
+9 -5
View File
@@ -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);
}
+5 -3
View File
@@ -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
+13 -4
View File
@@ -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
-6
View File
@@ -29,14 +29,8 @@ typedef enum {
GSK_GPU_IMAGE_FILTERABLE = (1 << 6),
GSK_GPU_IMAGE_RENDERABLE = (1 << 7),
GSK_GPU_IMAGE_SRGB = (1 << 8),
GSK_GPU_IMAGE_NARROW_RANGE = (1 << 9),
GSK_GPU_IMAGE_BT601 = (1 << 10),
GSK_GPU_IMAGE_BT709 = (2 << 10),
GSK_GPU_IMAGE_BT2020 = (3 << 10),
} GskGpuImageFlags;
#define GSK_GPU_IMAGE_YUV (GSK_GPU_IMAGE_BT2020)
typedef enum {
GSK_GPU_SAMPLER_DEFAULT,
GSK_GPU_SAMPLER_TRANSPARENT,
-2
View File
@@ -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
View File
@@ -844,7 +844,6 @@ GskGpuImage *
gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
gsize width,
gsize height,
GdkColorState *color_state,
const GdkDmabuf *dmabuf,
gboolean premultiplied)
{
@@ -860,7 +859,6 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
GdkMemoryFormat format;
GskGpuImageFlags flags;
gboolean is_yuv;
const GdkCicp *cicp;
if (!gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_DMABUF))
{
@@ -970,36 +968,13 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
return NULL;
}
if (is_yuv)
flags |= GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
flags |= GSK_GPU_IMAGE_STRAIGHT_ALPHA;
if (!gsk_component_mapping_is_framebuffer_compatible (&vk_components))
flags |= GSK_GPU_IMAGE_NO_BLIT;
cicp = gdk_color_state_get_cicp (color_state);
switch (cicp->matrix_coefficients)
{
case 1:
flags |= GSK_GPU_IMAGE_BT709;
break;
case 5:
case 6:
flags |= GSK_GPU_IMAGE_BT601;
break;
case 9:
flags |= GSK_GPU_IMAGE_BT2020;
break;
default:
break;
}
if (cicp->range == GDK_CICP_RANGE_NARROW)
flags |= GSK_GPU_IMAGE_NARROW_RANGE;
gsk_gpu_image_setup (GSK_GPU_IMAGE (self), flags, format, width, height);
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
flags |
(gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0) |
(is_yuv ? (GSK_GPU_IMAGE_EXTERNAL | GSK_GPU_IMAGE_NO_BLIT) : 0) |
(gsk_component_mapping_is_framebuffer_compatible (&vk_components) ? 0 : GSK_GPU_IMAGE_NO_BLIT),
format,
width, height);
self->allocator = gsk_vulkan_device_get_external_allocator (device);
gsk_vulkan_allocator_ref (self->allocator);
@@ -1201,7 +1176,8 @@ gsk_vulkan_image_get_n_planes (GskVulkanImage *self,
}
GdkTexture *
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state)
{
GskGpuImage *image = GSK_GPU_IMAGE (self);
GdkDmabufTextureBuilder *builder;
@@ -1251,6 +1227,7 @@ gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gdk_dmabuf_texture_builder_set_display (builder, gsk_gpu_device_get_display (GSK_GPU_DEVICE (self->device)));
gdk_dmabuf_texture_builder_set_width (builder, gsk_gpu_image_get_width (image));
gdk_dmabuf_texture_builder_set_height (builder, gsk_gpu_image_get_height (image));
gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
gdk_dmabuf_texture_builder_set_fourcc (builder, fourcc);
gdk_dmabuf_texture_builder_set_modifier (builder, properties.drmFormatModifier);
gdk_dmabuf_texture_builder_set_premultiplied (builder, !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA));
+2 -2
View File
@@ -42,10 +42,10 @@ GskGpuImage * gsk_vulkan_image_new_dmabuf (GskVulk
GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
gsize width,
gsize height,
GdkColorState *color_state,
const GdkDmabuf *dmabuf,
gboolean premultiplied);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state);
#endif
guchar * gsk_vulkan_image_get_data (GskVulkanImage *self,
-97
View File
@@ -14,8 +14,6 @@ PASS(2) vec2 _tex_coord;
PASS_FLAT(3) float _opacity;
PASS_FLAT(4) uint _transfer_function;
PASS_FLAT(5) mat3 _mat;
PASS_FLAT(8) mat3 _yuv;
PASS_FLAT(11) uint _range;
#ifdef GSK_VERTEX_SHADER
@@ -24,8 +22,6 @@ IN(1) vec4 in_tex_rect;
IN(2) float in_opacity;
IN(3) uint in_color_primaries;
IN(4) uint in_transfer_function;
IN(5) uint in_matrix_coefficients;
IN(6) uint in_range;
const mat3 identity = mat3(
@@ -94,42 +90,6 @@ const mat3 xyz_to_p3 = mat3(
-0.4027108, 0.0236247, 0.9568845
);
const mat3 rgb_to_bt601 = mat3(
0.299000, -0.168736, 0.500000,
0.587000, -0.331264, -0.418688,
0.114000, 0.500000, -0.081312
);
const mat3 bt601_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
0.000000, -0.344136, 1.772000,
1.402000, -0.714136, 0.000000
);
const mat3 rgb_to_bt709 = mat3(
0.212600, -0.114572, 0.500000,
0.715200, -0.385428, -0.454153,
0.072200, 0.500000, -0.045847
);
const mat3 bt709_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
0.000000, -0.187324, 1.855600,
1.574800, -0.468124, -0.000000
);
const mat3 rgb_to_bt2020 = mat3(
0.262700, -0.139630, 0.500000,
0.678000, -0.360370, -0.459786,
0.059300, 0.500000, -0.040214
);
const mat3 bt2020_to_rgb = mat3(
1.000000, 1.000000, 1.000000,
-0.000000, -0.164553, 1.881400,
1.474600, -0.571353, -0.000000
);
mat3
cicp_to_xyz (uint cp)
{
@@ -161,34 +121,6 @@ cicp_from_xyz (uint cp)
}
mat3
yuv_to_rgb (uint mc)
{
switch (mc)
{
case 0u: return identity;
case 1u: return bt709_to_rgb;
case 5u:
case 6u: return bt601_to_rgb;
case 9u: return bt2020_to_rgb;
}
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
}
mat3
rgb_to_yuv (uint mc)
{
switch (mc)
{
case 0u: return identity;
case 1u: return rgb_to_bt709;
case 5u:
case 6u: return rgb_to_bt601;
case 9u: return rgb_to_bt2020;
}
return mat3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
}
void
run (out vec2 pos)
{
@@ -201,7 +133,6 @@ run (out vec2 pos)
_tex_coord = rect_get_coord (rect_from_gsk (in_tex_rect), pos);
_opacity = in_opacity;
_transfer_function = in_transfer_function;
_range = in_range;
if (HAS_VARIATION (VARIATION_REVERSE))
{
@@ -210,8 +141,6 @@ run (out vec2 pos)
_mat = cicp_from_xyz (in_color_primaries) * srgb_to_xyz;
else
_mat = cicp_from_xyz (in_color_primaries) * rec2020_to_xyz;
_yuv = rgb_to_yuv (in_matrix_coefficients);
}
else
{
@@ -220,8 +149,6 @@ run (out vec2 pos)
_mat = xyz_to_srgb * cicp_to_xyz (in_color_primaries);
else
_mat = xyz_to_rec2020 * cicp_to_xyz (in_color_primaries);
_yuv = yuv_to_rgb (in_matrix_coefficients);
}
}
@@ -402,18 +329,6 @@ convert_color_from_cicp (vec4 color,
if (from_premul)
color = color_unpremultiply (color);
if (_range == 0u)
{
color.r = (color.r - 16.0/255.0) * 255.0/219.0;
color.g = (color.g - 16.0/255.0) * 255.0/224.0;
color.b = (color.b - 16.0/255.0) * 255.0/224.0;
}
color.g -= 0.5;
color.b -= 0.5;
color.rgb = _yuv * color.rgb;
color.rgb = apply_cicp_eotf (color.rgb, _transfer_function);
color.rgb = _mat * color.rgb;
color.rgb = apply_oetf (color.rgb, to);
@@ -437,18 +352,6 @@ convert_color_to_cicp (vec4 color,
color.rgb = _mat * color.rgb;
color.rgb = apply_cicp_oetf (color.rgb, _transfer_function);
color.rgb = _yuv * color.rgb;
color.g += 0.5;
color.b += 0.5;
if (_range == 0u)
{
color.r = color.r * 219.0/255.0 + 16.0/255.0;
color.g = color.g * 224.0/255.0 + 16.0/255.0;
color.b = color.b * 224.0/255.0 + 16.0/255.0;
}
if (to_premul)
color = color_premultiply (color);
+10 -1
View File
@@ -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
View File
@@ -380,7 +380,7 @@ gsk_render_node_draw_ccs (GskRenderNode *node,
GdkColorState *ccs)
{
/* Check that the calling function did pass a correct color state */
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs));
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs, FALSE));
cairo_save (cr);
@@ -413,7 +413,7 @@ gsk_render_node_draw_with_color_state (GskRenderNode *node,
{
GdkColorState *ccs;
ccs = gdk_color_state_get_rendering_color_state (color_state);
ccs = gdk_color_state_get_rendering_color_state (color_state, FALSE);
if (gdk_color_state_equal (color_state, ccs))
{
@@ -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
View File
@@ -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
View File
@@ -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;
+8
View File
@@ -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
+10
View File
@@ -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`
+1
View File
@@ -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);
+1
View File
@@ -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;
}
+48
View File
@@ -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: */
+10
View File
@@ -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
+23
View File
@@ -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
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+4
View File
@@ -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
View File
@@ -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;
}
+58
View File
@@ -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
View File
@@ -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);
+2
View File
@@ -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;
}
-1
View File
@@ -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
View File
@@ -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:
+1 -1
View File
@@ -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 {
+9 -93
View File
@@ -24,8 +24,6 @@
#include "gtkgstpaintableprivate.h"
#include "gdk/gdkdmabuffourccprivate.h"
#if GST_GL_HAVE_WINDOW_X11 && (GST_GL_HAVE_PLATFORM_GLX || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_X11)
#define HAVE_GST_X11_SUPPORT
#include <gdk/x11/gdkx.h>
@@ -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;
-61
View File
@@ -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;
}
-1
View File
@@ -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'],
+7
View File
@@ -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',
+109 -4
View File
@@ -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 ();
}
-2
View File
@@ -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);
+1 -6
View File
@@ -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);
-34
View File
@@ -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

+23
View File
@@ -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

+8
View File
@@ -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

-439
View File
@@ -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