Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen
84c6a1a8cf Add a shader tool
This tool will do what is necessary to populate the Vulkan shader
cache with most of the shaders that GTK will need.
2024-04-30 18:38:25 -04:00
Matthias Clasen
57f3598b71 gsk: Export some shader api
We need a way to get at the shader op classes, so an external
tool can use them.
2024-04-30 18:38:25 -04:00
Matthias Clasen
422fc3dda4 gdk: Export some pipeline cache api
This will be used in a tool to precompile shaders.
2024-04-30 18:38:25 -04:00
925 changed files with 24150 additions and 55561 deletions

View File

@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v52"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v49"
workflow:
rules:
@@ -117,11 +117,10 @@ release-build:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- mkdir _install
- export PATH="$HOME/.local/bin:${CI_PROJECT_DIR}/_install/bin:$PATH"
- .gitlab-ci/install-meson-project.sh --prefix ${CI_PROJECT_DIR}/_install https://gitlab.gnome.org/jadahl/catch.git main
- export PATH="$HOME/.local/bin:$PATH"
- meson subprojects download
- meson subprojects update --reset
- mkdir _install
- meson setup
--prefix=${CI_PROJECT_DIR}/_install
${COMMON_MESON_FLAGS}
@@ -446,10 +445,9 @@ reference:
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dman-pages=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:documentation=true
-Dbuild-demos=true
-Dbuild-demos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false
@@ -461,7 +459,6 @@ reference:
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
- mv _build/docs/reference/gtk/*.html _reference/gtk4/
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/

View File

@@ -1,4 +1,4 @@
FROM fedora:40
FROM fedora:39
RUN dnf -y install \
adwaita-icon-theme \
@@ -99,11 +99,8 @@ RUN dnf -y install \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf -y update \
&& dnf clean all
RUN rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers

View File

@@ -1,91 +0,0 @@
#!/bin/bash
set -e
usage() {
cat <<-EOF
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
Check out and install a meson project
Options:
-Dkey=val Option to pass on to meson
--prefix Prefix to install to
--subdir Build subdirectory instead of whole project
--prepare Script to run before build
-h, --help Display this help
EOF
}
TEMP=$(getopt \
--name=$(basename $0) \
--options='D:h' \
--longoptions='prefix:' \
--longoptions='subdir:' \
--longoptions='prepare:' \
--longoptions='help' \
-- "$@")
eval set -- "$TEMP"
unset TEMP
MESON_OPTIONS=()
PREFIX=/usr
SUBDIR=.
PREPARE=:
while true; do
case "$1" in
-D)
MESON_OPTIONS+=( -D$2 )
shift 2
;;
--prefix)
PREFIX=$2
shift 2
;;
--subdir)
SUBDIR=$2
shift 2
;;
--prepare)
PREPARE=$2
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
break
;;
esac
done
if [[ $# -lt 2 ]]; then
usage
exit 1
fi
REPO_URL="$1"
COMMIT="$2"
CHECKOUT_DIR=$(mktemp --directory)
trap "rm -rf $CHECKOUT_DIR" EXIT
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
pushd "$CHECKOUT_DIR/$SUBDIR"
sh -c "$PREPARE"
meson setup --prefix "$PREFIX" _build "${MESON_OPTIONS[@]}"
meson compile -C _build
meson install -C _build
popd

View File

@@ -11,6 +11,7 @@ multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${setup}" in
x11*)

View File

@@ -100,16 +100,14 @@ development tools appropriate for your operating system, including:
- Meson
- Ninja
- Gettext (19.7 or newer)
- a [C99 compatible compiler][glib-toolchain-reqs]
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
Up-to-date instructions about developing GNOME applications and libraries
can be found on [the GNOME Developer Center](https://developer.gnome.org).
The GTK project uses GitLab for code hosting and for tracking issues. More
information about using GitLab can be found on [the GNOME handbook][handbook].
[glib-toolchain-reqs]: https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md
[handbook]: https://handbook.gnome.org/infrastructure/gitlab.html
information about using GitLab can be found [on the GNOME
wiki](https://wiki.gnome.org/GitLab).
### Dependencies
@@ -133,7 +131,7 @@ GTK will attempt to download and build some of these dependencies if it
cannot find them on your system.
Additionally, you may want to look at projects that create a development
environment for you, like [jhbuild](https://gitlab.gnome.org/GNOME/jhbuild)
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
and [gvsbuild](https://github.com/wingtk/gvsbuild).
### Getting started

238
NEWS
View File

@@ -1,242 +1,6 @@
Overview of Changes in 4.15.5, xx-xx-xxxx
Overview of Changes in 4.15.1, xx-xx-xxxx
=========================================
* GtkTextView:
- ADd GtkTextBufferCommitNotify
* CSS:
- Propagate color state information to GSK for many features:
colors, borders, shadows
* Gdk:
- Fix an fd leak in the Vulkan code
- Fix a leak of EGLSurfaces and DMA buffers
- Set the opaque region of surfaces automatically based on their content
* Gsk:
- Fix Emoji rendering in Vulkan
- Rework color handling to take color states into account
- Implement more powerful occlusion culling
* Macos:
- Fix window transparency
* Debugging:
- The inspector shows details about color states now
* Deprecations:
- gdk_draw_context_begin/end_frame
- gdk_surface_set_opaque_region
* Build:
- Require gstreamer 1.24
Overview of Changes in 4.15.4, 30-07-2024
=========================================
* GtkPopover:
- Fix size allocation with wrapping labels
* GtkColumnView:
- Check column visibility when measuring
* CSS:
- Fix fallout from recent changes
- Make implementation of currentcolor inheritance match browsers
* Gdk:
- Introduce GdkColorState for encoding color space information
Currently, we support srgb, srgb-linear, rec2100-pq and rec2100-linear
- Add color states to GdkTexture, as well as to the texture builder
and downloader objects, and convert as necessary
- Add GdkMemoryTextureBuilder
- Attach color states when loading or saving textures
- Add GdkCicpParams to create color state objects for cicp tuples
- Drop GDK_DEBUG=vulkan-validate
Use VK_INSTEANCE_LAYERS=VK_LAYER_KHRONOS_validation instead
* Gsk:
- Improve caching of glyphs and textures
- Remove the uber shader
- Numerous bug fixes
- Fix corner cases in offload handling
- Implement occlusion culling for opaque content
- Allow offloading (some) transformed textures
- Take colorstate into account when compositing
- Add GDK_DEBUG=linear to opt into linear compositing
- Implement tiling for large textures
- Stop using descriptors and go back to simpler texture
management that should work better with older GL
- Use correct shader clip mode for glyphs
- Improve shadow rendering
* Media:
- Attach color states to textures obtained from gstreamer
* Wayland:
- Allow offloading GL textures via dmabuf export
- Suppot the xx-color-management-v4 protocol
* Deprecations:
- GskGLShader and the render node
* Tools:
- Improve the rendernode tool extract command
- Add an image tool that is about manipulating textures
* Build:
- GTK now requires a C11 compiler
* Translation updates
Georgian
Hebrew
Hindi
Occitan
Slovenian
Overview of Changes in 4.15.3, 29-06-2024
=========================================
* Accessibility:
- Only emit notifications when cursor positions change in GtkText
- Fix handling of help text properties
* CSS:
- Fix some crashes introduced in recent currentcolor changes
* DND:
- Avoid a critical
* Documentation:
- Fix many oversights and missing docs
* maxOS:
- Add native keyboard shortcuts
Overview of Changes in 4.15.2, 28-06-2024
=========================================
* GtkFileChooserWidget:
- Plug some memory leaks
- Make Ctrl-Shift-N create a new folder
* GtkPopover:
- Handle resizing and position changes better
* CSS:
- Support color(), oklab(), etc (https://www.w3.org/TR/css-color-4/)
- Support color-mix() (https://www.w3.org/TR/css-color-5/)
- Support relative colors (https://www.w3.org/TR/css-color-5/)
- Support more colorspaces in color()
- Allow percentages for opacity
- Handle currentcolor more correctly
* Accessibility:
- Avoid markup when reading labels
* GSK:
- Subset fonts when serializing node trees
- Make ngl export render_texture results as dmabufs
* Wayland:
- Use xdg-dialog protocol for attached dialogs
* Windows:
- Build with UNICODE
* macOS:
- Implement fullscreen-on-monitor
* Documentation:
- Widget shortcuts and actions are now described in the docs
* Debugging:
- Add GTK_DEBUG=css for warning about deprecated css syntax
* Tools:
- rendernode-tool: Add an extract command for data urls
* Deprecations:
- CSS Color functions shade(), lighter(), darker(), alpha(), mix()
* Translation updates:
Czech
Hebrew
Serbian
Overview of Changes in 4.15.1, 21-05-2024
=========================================
* GtkGraphicsOffload:
- Don't crash without a child
* GtkSpinner:
- Don't animate when unmapped
* CSS:
- Support the :root selector
- Support variables and custom properties (https://www.w3.org/TR/css-variables-1/)
- Implement math functions (https://www.w3.org/TR/css-values-4/)
- Support modern syntax and calc in rgb() and hsl()
* Icontheme:
- Make symbolic svg loading more efficient
- Handle color-free symbolics more efficiently
* Accessibility:
- Make the gtk-demo sidebar search more accessible
- Stop emitting focus events
- Realize child contexts when necessary
* GDK:
- Support XDG_ACTIVATION_TOKEN
- dmabuf: Be more defensive when importing unknown formats to GL
- dmabuf: Use narrow range for YUV
- vulkan: Recreate swapchains when necessary or beneficial
* GSK:
- Improve logging for GDK_DEBUG=offload
- Improve logging for GSK_DEBUG=renderer
- gpu: Warn about inefficient texture import
- gpu: Handle tiny offscreens correctly
- vulkan: Add profiler marks in various places
- vulkan: Fix a problem with imported dmabufs showing up black
- cairo: Speed up mask nodes, since we use them for symbolic icons
* Wayland:
- Use wl_compositor version 6
* X11:
- Implement a missing method
* Build:
- Fix many ubsan warnings
* Debugging:
- Show more texture details in the recorder
- Use GTK_DEBUG=css to see CSS deprecations
* macOS:
- Fix problems with events handed back to the OS
- Respect GDK_DEBUG=default-settings
- Allow applictions to handle Dock > Quit
* Deprecations:
- Use of @name colors in CSS
* Translation updates:
Catalan
Georgian
Hungarian
Korean
Portuguese
Turkish
Overview of Changes in 4.15.0, 21-04-2024
=========================================

View File

@@ -39,21 +39,18 @@ Nightly documentation can be found at
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
Nightly flatpaks of our demos can be installed from the
[GNOME Nightly](https://nightly.gnome.org/) repository:
```sh
flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
flatpak install gnome-nightly org.gtk.Demo4
flatpak install gnome-nightly org.gtk.WidgetFactory4
flatpak install gnome-nightly org.gtk.IconBrowser4
```
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
- `flatpak install gnome-nightly org.gtk.Demo4`
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
Building and installing
-----------------------
In order to build GTK you will need:
- [a C11 compatible compiler](https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md)
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
- [Python 3](https://www.python.org/)
- [Meson](http://mesonbuild.com)
- [Ninja](https://ninja-build.org)

View File

@@ -170,7 +170,6 @@ update_paintable (GtkWidget *widget,
static GtkWidget *
create_cogs (void)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GtkWidget *picture;
static GskGLShader *cog_shader = NULL;
GdkPaintable *paintable;
@@ -183,7 +182,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
return picture;
G_GNUC_END_IGNORE_DEPRECATIONS
}
static gboolean

View File

@@ -363,9 +363,7 @@ insert_markup_idle (gpointer data)
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
{
guint id;
id = g_idle_add (insert_markup_idle, data);
g_source_set_name_by_id (id, "[gtk-demo] insert_markup_idle");
g_idle_add (insert_markup_idle, data);
return G_SOURCE_REMOVE;
}
@@ -400,9 +398,7 @@ parse_markup_idle (gpointer data)
do {
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
{
guint id;
id = g_idle_add (parse_markup_idle, data);
g_source_set_name_by_id (id, "[gtk-demo] parse_markup_idle");
g_idle_add (parse_markup_idle, data);
return G_SOURCE_REMOVE;
}

View File

@@ -20,8 +20,6 @@
#include "gtkshadertoy.h"
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *demo_window = NULL;
static void
@@ -362,5 +360,3 @@ do_gltransition (GtkWidget *do_widget)
return demo_window;
}
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -22,8 +22,6 @@
#include <gtk/gtk.h>
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GskShaderPaintable:
*
@@ -334,5 +332,3 @@ gsk_shader_paintable_update_time (GskShaderPaintable *self,
g_bytes_unref (args);
}
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -22,8 +22,6 @@
#include <gdk/gdk.h>
#include <gsk/gsk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
@@ -43,5 +41,3 @@ void gsk_shader_paintable_update_time (GskShaderPaintable *self
int time_idx,
gint64 frame_time);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -1,7 +1,5 @@
#include "gtkshaderbin.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef struct {
GskGLShader *shader;
GtkStateFlags state;
@@ -264,5 +262,3 @@ gtk_shader_bin_new (void)
return GTK_WIDGET (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -2,8 +2,6 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
@@ -20,5 +18,3 @@ void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -1,7 +1,5 @@
#include "gtkshaderstack.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _GtkShaderStack
{
GtkWidget parent_instance;
@@ -361,5 +359,3 @@ gtk_shader_stack_set_active (GtkShaderStack *self,
self->current = MIN (index, self->children->len);
update_child_visible (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -2,8 +2,6 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
@@ -20,5 +18,3 @@ void gtk_shader_stack_set_active (GtkShaderStack *self,
int index);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS

View File

@@ -40,7 +40,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale;
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
@@ -59,6 +59,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);

View File

@@ -936,7 +936,7 @@ search_results_update (GObject *filter_model,
char *text;
if (n_items > 0)
text = g_strdup_printf (ngettext ("%ld search result", "%ld search results", (long) n_items), (long) n_items);
text = g_strdup_printf (ngettext ("%ld search result", "%ld search results", n_items), n_items);
else
text = g_strdup (_("No search results"));

View File

@@ -299,7 +299,7 @@ node_editor_application_new (void)
app = g_object_new (NODE_EDITOR_APPLICATION_TYPE,
"application-id", "org.gtk.gtk4.NodeEditor",
"flags", G_APPLICATION_HANDLES_OPEN | G_APPLICATION_NON_UNIQUE,
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
g_application_add_main_option (G_APPLICATION (app), "version", 0, 0,G_OPTION_ARG_NONE, "Show program version", NULL);

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 alias='node-format.md'>../../docs/reference/gtk/node-format.md</file>
<file>node-format.md</file>
<file alias='icons/apps/org.gtk.gtk4.NodeEditor.svg'>data/scalable/apps/org.gtk.gtk4.NodeEditor.svg</file>
</gresource>
</gresources>

View File

@@ -1,15 +1,13 @@
Title: The Node file format
# 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: <@-rule>*<node>
@-rule: @cicp "name" { <property>* }
node: container [ "name" ] { <document> } | <node-type> [ "name" ] { <property>* } | "name"
property: <property-name>: <node> | <value> ;
**document**: `<node>\*`
**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.
@@ -27,59 +25,6 @@ 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 | `<range>` | full | non-default |
Note that the primaries, transfer and matrix properties always need
to be specified, since GTK does not allow creating color state objects
with these being set to 2 (== unspecified).
Range can have the following values:
range: narrow | full
# Colors
Colors can be specified with a variation of the modern CSS color syntax:
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>)
# Rectangles
Rectangles can be specified just as four integers for x, y, width and height:
rect: <number> <number> <number> <number>
Rounded rectangles use a CSS-like syntax:
rounded-rect: <rect> [ "/" <number>{1,4} [ "/" <number>{1,4} ] ]
# Nodes
### container
@@ -96,13 +41,6 @@ The **container** node is a special node that allows specifying a list of child
Creates a node like `gsk_blend_node_new()` with the given properties.
Possible values for the mode property are:
blend-mode: normal | multiply | screen | overlay | darken |
lighten | color-dodge | color-burn | hard-light |
soft-light | difference | exclusion | color |
hue | saturation | luminosity
### blur
| property | syntax | default | printed |
@@ -222,10 +160,6 @@ Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is the default color node, but created with the
bounds of the path.
Possible values for the fill-rule property are:
fill-rule: winding | even-odd
### glshader
| property | syntax | default | printed |
@@ -277,10 +211,6 @@ Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
Creates a node like `gsk_mask_node_new()` with the given properties.
Possible values for the mode property are:
mask-mode: alpha | inverted-alpha | luminance | inverted-luminance
### opacity
| property | syntax | default | printed |
@@ -319,11 +249,11 @@ Creates a node like `gsk_radial_gradient_node_new()` with the given properties.
### repeat
| property | syntax | default | printed |
| ------------ | ---------- | ---------------------- | ----------- |
| bounds | `<rect>` | *bounds of child node* | non-default |
| child | `<node>` | color { } | always |
| child-bounds | `<rect>` | *bounds of child node* | non-default |
| property | syntax | default | printed |
| ----------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | *bounds of child node* | non-default |
| child | `<node>` | color { } | always |
| child-bounds| `<rect>` | *bounds of child node* | non-default |
Creates a node like `gsk_repeat_node_new()` with the given properties.
@@ -390,14 +320,6 @@ Creates a node like `gsk_stroke_node_new()` with the given properties.
The default child node is the default color node, but created with the
stroke bounds of the path.
Possible values for the line-cap property are:
line-cap: butt | round | square
Possible values for the line-join property are:
line-join: miter | round | bevel
### text
| property | syntax | default | printed |
@@ -406,9 +328,8 @@ Possible values for the line-join property are:
| font | `<string>` `<url>`? | "Cantarell 15px" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| hint-style | `<hint-style>` | slight | non-default |
| hint-style | `<hint style>` | slight | non-default |
| antialias | `<antialias>` | gray | non-default |
| hint-metrics | `<hint-metrics>` | off | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.
@@ -423,17 +344,8 @@ be specified as well, like this: 40 10 0 0 color.
If the given font does not exist or the given glyphs are invalid for the given
font, an error node will be returned.
Possible values for the hint-style property are:
hint-style: none | slight | full
Possible value for the antialias property are:
antialias: none | gray
Possible value for hint-metrics are:
hint-metrics: on | off
Possible values for hint-style are none, slight or full.
Possible value for antialias are none or gray.
### texture
@@ -459,15 +371,14 @@ representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANS
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| texture | `<url>` | *see below* | always |
| filter | `filter` | linear | non-default |
| filter | `filter` | *see below* | non-default |
Creates a node like `gsk_texture_scale_node_new()` with the given properties.
The default texture is a 10x10 checkerboard, just like for texture.
Possible values for the filter property are:
filter: linear | nearest | trilinear
The possible filter values are `linear`, `nearest` and `trilinear`, with
`linear` being the default.
### transform

View File

@@ -111,11 +111,3 @@ content_images = [
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gdk/"
urlmap_file = "urlmap.js"
[[object]]
name = "DECLARE_INTERNAL_TYPE"
hidden = true
[[object]]
pattern = "KEY_*"
check_ignore = true

View File

@@ -29,18 +29,6 @@ if get_option('documentation')
install_dir: docs_dir,
)
test('doc-check-gdk',
gidocgen,
args: [
'check',
'--config', gdk4_toml,
'--add-include-path=@0@'.format(meson.current_build_dir() / '../../../gtk'),
gdk_gir[0],
],
depends: gdk_gir[0],
suite: ['docs'],
)
if x11_enabled
gdk4x11_toml = configure_file(
input: 'gdk4-x11.toml.in',
@@ -99,17 +87,5 @@ if get_option('documentation')
install: true,
install_dir: docs_dir,
)
test('doc-check-gdk-wayland',
gidocgen,
args: [
'check',
'--config', gdk4wayland_toml,
'--add-include-path=@0@'.format(meson.current_build_dir() / '../../../gtk'),
gdk_wayland_gir[0],
],
depends: gdk_wayland_gir[0],
suite: ['docs'],
)
endif
endif

View File

@@ -66,7 +66,3 @@ content_images = [
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gsk/"
urlmap_file = "urlmap.js"
[[object]]
name = "INCLUDE_WARNING"
hidden = true

View File

@@ -30,16 +30,4 @@ if get_option('documentation')
install: true,
install_dir: docs_dir,
)
test('doc-check-gsk',
gidocgen,
args: [
'check',
'--config', gsk4_toml,
'--add-include-path=@0@'.format(meson.current_build_dir() / '../../../gtk'),
gsk_gir[0],
],
depends: gsk_gir[0],
suite: ['docs'],
)
endif

View File

@@ -140,7 +140,7 @@ Other libraries are maintained separately.
file formats. It is available [here](ttps://download.gnome.org/sources/gdk-pixbuf/).
- [Pango](http://www.pango.org) is a library for internationalized
text handling. It is available [here](https://download.gnome.org/sources/pango/).
- [GObject Introspection](https://gitlab.gnome.org/GNOME/gobject-introspection)
- [GObject Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
is a framework for making introspection data available to language
bindings. It is available [here](https://download.gnome.org/sources/gobject-introspection/).
- The [GNU libiconv](https://www.gnu.org/software/libiconv/) library
@@ -265,13 +265,6 @@ support in the file chooser.
This option controls whether GTK should use colord for color
calibration support in the cups print backend.
## `avif`
This option controls whether GTK will use libavif for loading
textures from AVIF image files. Note that the purpose of this option
is to facilitate development of GTK. The support for this image format
is not guaranteed and may go away at any time.
### `documentation`, `man-pages` and `screenshots`
The *gi-docgen* package is used to generate the reference documentation

View File

@@ -15,16 +15,16 @@ spec.
The following units are supported for basic datatypes:
Length
: px, pt, em, ex, rem, pc, in, cm, mm
: px, pt, em, ex, rem, pc, in, cm, mm, calc()
Percentage
: %
: %, calc()
Angle
: deg, rad, grad, turn
: deg, grad, turn, calc()
Time
: s, ms
: s, ms, calc()
Length values with the em or ex units are resolved using the font
size value, unless they occur in setting the font-size itself, in
@@ -33,15 +33,11 @@ which case they are resolved using the inherited font size value.
The rem unit is resolved using the initial font size value, which is
not quite the same as the CSS definition of rem.
Length values using physical units (pt, pc, in, cm, mm) are translated
to px using the dpi value specified by the -gtk-dpi property, which is
different from the CSS definition, which uses a fixed dpi of 96.
The calc() notation adds considerable expressive power to all of these
datatypes. There are limits on what types can be combined in such an
expression (e.g. it does not make sense to add a number and a time).
For the full details, see the
[CSS Values and Units](https://www.w3.org/TR/css-values-4/) spec.
The calc() notation adds considerable expressive power. There are limits
on what types can be combined in such an expression (e.g. it does not make
sense to add a number and a time). For the full details, see the
[CSS3 Values and Units](https://www.w3.org/TR/css3-values/#calc-notation)
spec.
A common pattern among shorthand properties (called 'four sides') is one
where one to four values can be specified, to determine a value for each
@@ -60,80 +56,38 @@ follows:
1 value:
: all
## Custom Properties
GTK supports custom properties as defined in the
[CSS Custom Properties for Cascading Variables](https://www.w3.org/TR/css-variables-1)
spec.
Custom properties are defined as follows:
```css
--prop: red;
```
and used via the `var` keyword:
```css
color: var(--prop);
```
Custom properties can have a fallback for when the referred property is invalid:
```css
color: var(--prop, green);
```
## Colors
### CSS Colors
Colors can be expressed in numerous ways in CSS (see the
[Color Module](https://www.w3.org/TR/css-color-5/). GTK supports
many (but not all) of these.
You can use rgb(), rgba(), hsl() with both the legacy or the modern CSS
syntax, and calc() can be used as well in color expressions. hwb(), oklab(),
oklch(), color(), color-mix() and relative colors are supported as well.
### Non-CSS Colors
GTK extends the CSS syntax with several additional ways to specify colors.
These extensions are deprecated and should be replaced by the equivalent
standard CSS notions.
GTK extends the CSS syntax with several additional ways to specify colors.
The first is a reference to a color defined via a @define-color rule in CSS.
The syntax for @define-color rules is as follows:
```
@define-color name color
@define-color Name Color
```
To refer to the color defined by a @define-color rule, prefix the name with @.
The standard CSS mechanisms that should be used instead of @define-color are
custom properties, :root and var().
GTK also supports color expressions, which allow colors to be transformed to
new ones. Color expressions can be nested, providing a rich language to
define colors. Color expressions resemble functions, taking 1 or more colors
and in some cases a number as arguments.
`lighter(color)`
: produces a brighter variant of `color`.
`lighter(Color)`
: produces a brighter variant of Color
`darker(color)`
: produces a darker variant of `color`.
`darker(Color)`
: produces a darker variant of Color
`shade(color, number)`
: changes the lightness of `color`. The `number` ranges from 0 for black to 2 for white.
`shade(Color, Number)`
: changes the lightness of Color. The number ranges from 0 for black to 2 for white.
`alpha(color, number)`
: multiplies the alpha value of `color` by `number` (between 0 and 1).
`alpha(Color, Number)`
: replaces the alpha value of color with number (between 0 and 1)
`mix(color1, color2, number)`
: interpolates between the two colors.
`mix(Color1, Color2, Number)`
: interpolates between the two colors
## Images
@@ -141,7 +95,7 @@ GTK extends the CSS syntax for images and also uses it for specifying icons.
To load a themed icon, use
```
-gtk-icontheme(name)
-gtk-icontheme(Name)
```
The specified icon name is used to look up a themed icon, while taking into
@@ -170,14 +124,14 @@ and the
syntax makes this available. -gtk-recolor requires a url as first argument.
The remaining arguments specify the color palette to use. If the palette is
not explicitly specified, the current value of the -gtk-icon-palette property
is used.
is used.
GTK supports scaled rendering on hi-resolution displays. This works best if
images can specify normal and hi-resolution variants. From CSS, this can be
done with
```
-gtk-scaled(image1, image2)
-gtk-scaled(Image1, Image2)
```
## GTK CSS Properties

View File

@@ -99,15 +99,16 @@ reaches the requested phase. However, in practice most things
happen at higher levels:
- If you are doing an animation, you can use
[method@Gtk.Widget.add_tick_callback] which will cause a regular
gtk_widget_add_tick_callback() which will cause a regular
beating of the clock with a callback in the Update phase
until you stop the tick.
- If some state changes that causes the size of your widget to
change you call [method@Gtk.Widget.queue_resize] which will request
change you call gtk_widget_queue_resize() which will request
a Layout phase and mark your widget as needing relayout.
- If some state changes so you need to redraw your widget you
use [method@Gtk.Widget.queue_draw] to request a Paint phase for
your widget.
- If some state changes so you need to redraw some area of
your widget you use the normal gtk_widget_queue_draw()
set of functions. These will request a Paint phase and
mark the region as needing redraw.
There are also a lot of implicit triggers of these from the
CSS layer (which does animations, resizes and repaints as needed).

View File

@@ -245,6 +245,9 @@ to connect the "clicked" signal with [method@Gtk.Window.destroy], then the funct
would be called on `button` (which would not go well, since the function expects
a `GtkWindow` as argument).
More information about creating buttons can be found
[here](https://wiki.gnome.org/HowDoI/Buttons).
The rest of the code in `example-1.c` is identical to `example-0.c`. The next
section will elaborate further on how to add several [class@Gtk.Widget]s to your
GTK application.

View File

@@ -1,97 +0,0 @@
.. _gtk4-image-tool(1):
====================
gtk4-image-tool
====================
-----------------------
Image Utility
-----------------------
:Version: GTK
:Manual section: 1
:Manual group: GTK commands
SYNOPSIS
--------
| **gtk4-image-tool** <COMMAND> [OPTIONS...] <FILE>...
|
| **gtk4-image-tool** compare [OPTIONS...] <FILE1> <FILE2>
| **gtk4-image-tool** convert [OPTIONS...] <FILE1> <FILE2>
| **gtk4-image-tool** info [OPTIONS...] <FILE>
| **gtk4-image-tool** relabel [OPTIONS...] <FILE1> <FILE2>
| **gtk4-image-tool** show [OPTIONS...] <FILE>...
DESCRIPTION
-----------
``gtk4-image-tool`` can perform various operations on images.
COMMANDS
--------
Information
^^^^^^^^^^^
The ``info`` command shows general information about the image, such
as its format and color state.
Showing
^^^^^^^
The ``show`` command displays one or more images, side-by-side.
``--undecorated``
Removes window decorations. This is meant for rendering of exactly the image
without any titlebar.
Compare
^^^^^^^
The ``compare`` command compares two images. If any differences are found,
the exit code is 1. If the images are identical, it is 0.
``--output=FILE``
Save the differences as a png image in ``FILE``.
``--quiet``
Don't write results to stdout.
Conversion
^^^^^^^^^^
The ``convert`` command converts the image to a different format or color state.
``--format=FORMAT``
Convert to the given format. The supported formats can be listed
with ``--format=list``.
``--color-state=COLORSTATE``
Convert to the given color state. The supported color states can be
listed with ``--format=list``.
``--cicp=CICP``
Convert to a color state that is specified as a cicp tuple. The cicp tuple
must be specified as four numbers, separated by /, e.g. 1/13/6/0.
Relabeling
^^^^^^^^^^
The ``relabel`` command changes the color state of an image without conversion.
This can be useful to produce wrong color renderings for diagnostics.
``--color-state=COLORSTATE``
Relabel to the given color state. The supported color states can be
listed with ``--format=list``.
``--cicp=CICP``
Relabel to a color state that is specified as a cicp tuple. The cicp tuple
must be specified as four numbers, separated by /, e.g. 1/13/6/0.

View File

@@ -18,7 +18,6 @@ SYNOPSIS
|
| **gtk4-rendernode-tool** benchmark [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** compare [OPTIONS...] <FILE1> <FILE2>
| **gtk4-rendernode-tool** extract [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
@@ -100,15 +99,3 @@ exit code is 1. If the images are identical, it is 0.
``--quiet``
Don't write results to stdout.
Extract
^^^^^^^
The ``extract`` command saves all the data urls found in a node file to a given
directory. The file names for the extracted files are derived from the mimetype
of the url.
``--dir=DIRECTORY``
Save extracted files in ``DIRECTORY`` (defaults to the current directory).

View File

@@ -77,15 +77,12 @@ content_files = [
"section-tree-widget.md",
"migrating-2to4.md",
"migrating-3to4.md",
"migrating-4to5.md",
"broadway.md",
"osx.md",
"wayland.md",
"windows.md",
"x11.md",
"tools.md",
"visual_index.md",
"node-format.md",
]
content_images = [
"../images/favicon.svg",
@@ -252,12 +249,3 @@ content_images = [
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gtk/"
urlmap_file = "urlmap.js"
[[object]]
name = "StyleProvider"
[[object.signal]]
name = "gtk-private-changed"
hidden = true
[check]
skip_deprecated = true

View File

@@ -140,11 +140,6 @@ capture phase, and key bindings locally, during the target phase.
Under the hood, all shortcuts are represented as instances of `GtkShortcut`,
and they are managed by `GtkShortcutController`.
Note that GTK does not do anything to map the primary shortcut modifier
to <kbd>Command</kbd> on macOS. If you want to let your application to follow
macOS user experience conventions, you must create macOS-specific keyboard shortcuts.
The <kbd>Command</kbd> is named `Meta` (`GDK_META_MASK`) in GTK.
## Text input
When actual text input is needed (i.e. not just keyboard shortcuts),

View File

@@ -14,7 +14,6 @@ expand_content_md_files = [
'running.md',
'migrating-2to4.md',
'migrating-3to4.md',
'migrating-4to5.md',
'actions.md',
'input-handling.md',
'drawing-model.md',
@@ -26,8 +25,7 @@ expand_content_md_files = [
'section-tree-widget.md',
'section-list-widget.md',
'question_index.md',
'visual_index.md',
'tools.md',
'visual_index.md'
]
gtk_images = []
@@ -62,52 +60,39 @@ if get_option('documentation')
build_by_default: true,
install: true,
install_dir: docs_dir,
install_tag: 'doc',
)
test('doc-check-gtk',
gidocgen,
args: [
'check',
'--config', gtk4_toml,
'--add-include-path=@0@'.format(meson.current_build_dir() / '../../../gtk'),
gtk_gir[0],
],
depends: gtk_gir[0],
suite: ['docs'],
)
endif
rst2man = find_program('rst2man', 'rst2man.py', required: get_option('man-pages'))
rst2html5 = find_program('rst2html5', 'rst2html5.py', required: get_option('documentation'))
rst2man = find_program('rst2man', 'rst2man.py', required: false)
if get_option('man-pages') and not rst2man.found()
error('No rst2man found, but man pages were explicitly enabled')
endif
rst_files = [
[ 'gtk4-broadwayd', '1' ],
[ 'gtk4-builder-tool', '1' ],
[ 'gtk4-encode-symbolic-svg', '1', ],
[ 'gtk4-image-tool', '1' ],
[ 'gtk4-launch', '1', ],
[ 'gtk4-query-settings', '1', ],
[ 'gtk4-rendernode-tool', '1' ],
[ 'gtk4-update-icon-cache', '1', ],
[ 'gtk4-path-tool', '1', ],
]
if get_option('build-demos')
rst_files += [
[ 'gtk4-demo', '1', ],
[ 'gtk4-demo-application', '1', ],
[ 'gtk4-widget-factory', '1', ],
[ 'gtk4-icon-browser', '1', ],
[ 'gtk4-node-editor', '1', ],
if get_option('man-pages') and rst2man.found()
rst_files = [
[ 'gtk4-broadwayd', '1' ],
[ 'gtk4-builder-tool', '1' ],
[ 'gtk4-encode-symbolic-svg', '1', ],
[ 'gtk4-launch', '1', ],
[ 'gtk4-query-settings', '1', ],
[ 'gtk4-rendernode-tool', '1' ],
[ 'gtk4-update-icon-cache', '1', ],
[ 'gtk4-path-tool', '1', ],
]
endif
rst2x_flags = [
'--syntax-highlight=none',
]
if get_option('build-demos')
rst_files += [
[ 'gtk4-demo', '1', ],
[ 'gtk4-demo-application', '1', ],
[ 'gtk4-widget-factory', '1', ],
[ 'gtk4-icon-browser', '1', ],
[ 'gtk4-node-editor', '1', ],
]
endif
if get_option('man-pages')
rst2man_flags = [
'--syntax-highlight=none',
]
foreach rst: rst_files
man_name = rst[0]
@@ -118,34 +103,12 @@ if get_option('man-pages')
output: '@0@.@1@'.format(man_name, man_section),
command: [
rst2man,
rst2x_flags,
rst2man_flags,
'@INPUT@',
],
capture: true,
install: true,
install_dir: get_option('mandir') / 'man@0@'.format(man_section),
install_tag: 'doc',
)
endforeach
endif
if get_option('documentation')
foreach rst: rst_files
man_name = rst[0]
custom_target(
input: '@0@.rst'.format(man_name),
output: '@0@.html'.format(man_name),
command: [
rst2html5,
rst2x_flags,
'@INPUT@',
],
capture: true,
install: true,
install_dir: docs_dir / 'gtk4',
install_tag: 'doc',
)
endforeach
endif

View File

@@ -451,11 +451,11 @@ hint about how modifiers are expected to be used. It also promoted
the use of `<Primary>` instead of `<Control>` to specify accelerators that
adapt to platform conventions.
In GTK 4, the meaning of modifiers has been fixed, and applications are
In GTK 4, the meaning of modifiers has been fixed, and backends are
expected to map the platform conventions to the existing modifiers.
The expected use of modifiers in GTK 4 is:
`GDK_CONTROL_MASK` (`GDK_META_MASK` on macOS)
`GDK_CONTROL_MASK`
: Primary accelerators
`GDK_ALT_MASK`
@@ -464,7 +464,7 @@ The expected use of modifiers in GTK 4 is:
`GDK_SHIFT_MASK`
: Extending selections
`GDK_CONTROL_MASK` (`GDK_META_MASK` on macOS)
`GDK_CONTROL_MASK`
: Modifying selections
`GDK_CONTROL_MASK|GDK_ALT_MASK`
@@ -473,15 +473,9 @@ The expected use of modifiers in GTK 4 is:
Consequently, `GdkModifierIntent` and related APIs have been removed,
and `<Control>` is preferred over `<Primary>` in accelerators.
In GTK 3 on macOS, the `<Primary>` modifier mapped to the <kbd>Command</kbd> key.
In GTK 4, this is no longer the case: `<Primary>` is synonymous to `<Control>`.
If you want to make your application to feel native on macOS,
you need to add accelerators for macOS that use the `<Meta>` modifier.
A related change is that GTK 4 no longer supports the use of archaic
X11 'real' modifiers with the names Mod1,..., Mod5, and `GDK_MOD1_MASK`
has been renamed to `GDK_ALT_MASK` and `GDK_MOD2_MASK` has been renamed to
`GDK_META_MASK`.
has been renamed to `GDK_ALT_MASK`.
### Replace `GtkClipboard` with `GdkClipboard`

View File

@@ -58,7 +58,7 @@ use a GtkLabel.
If you have a need for custom drawing that fits into the current
(dark or light) theme, e.g. for rendering a graph, you can still
get the current style foreground color, using
[method@Gtk.Widget.get_color].
[method@Gtk.Widget.get_style_color].
## Local stylesheets are going away
@@ -73,103 +73,6 @@ GTK 5 will no longer provide this functionality. The recommendations
is to use a global stylesheet (i.e. gtk_style_context_add_provider_for_display())
and rely on style classes to make your CSS apply only where desired.
## Non-standard CSS extensions are going away
GTK's CSS machinery has a some non-standard extensions around colors:
named colors with \@define-color and color functions: lighter(), darker(),
shade(), alpha(), mix().
GTK now implements equivalent functionality from the CSS specs.
### \@define-color is going away
\@define-color should be replaced by custom properties in the :root scope.
Instead of
```
@define-color fg_color #2e3436
...
box {
color: @fg_color;
}
```
use
```
:root {
--fg-color: #2e3436;
}
...
box {
color: var(--fg-color);
}
```
For more information about custom CSS properties and variables, see the
[CSS Custom Properties for Cascading Variables](https://www.w3.org/TR/css-variables-1/)
spec.
### Color expressions are going away
The color functions can all be replaced by combinations of calc() and color-mix().
ligher(c) and darker(c) are just shade(c, 1.3) or shade(c, 0.7), respectively, and
thus can be handled the same way as shade in the examples below.
Replace
```
a {
color: mix(red, green, 0.8);
}
b {
color: alpha(green, 0.6);
}
c {
color: shade(red, 1.3);
}
d {
color: shade(red, 0.7);
}
```
with
```
a {
color: color-mix(in srgb, red, green 80%);
}
b {
color: rgb(from green, r g b / calc(alpha * 0.6));
}
c {
color: hsl(from red, h calc(s * 1.3) calc(l * 1.3));
}
d {
color: hsl(from red, h calc(s * 0.7) calc(l * 0.7));
}
```
Variations of these replacements are possible.
Note that GTK has historically computed mix() and shade() values in the SRGB and HSL
colorspaces, but using OKLAB instead might yield slightly better results.
For more information about color-mix(), see the
[CSS Color](https://drafts.csswg.org/css-color-5) spec.
## Chooser interfaces are going away
The GtkColorChooser, GtkFontChooser, GtkFileChooser and GtkAppChooser

View File

@@ -7,5 +7,5 @@ on top of the Quartz API.
Currently, the macOS port does not use any additional commandline options
or environment variables.
For up-to-date information on building, installation, and bundling, see the
[GTK website](https://www.gtk.org/docs/installations/macos).
For up-to-date information about the current status of this port, see the
[project page](https://wiki.gnome.org/Projects/GTK/OSX).

View File

@@ -64,6 +64,6 @@ GTK is divided into three parts:
[cairo]: https://www.cairographics.org/manual/
[opengl]: https://www.opengl.org/about/
[vulkan]: https://www.vulkan.org/
[pango]: https://docs.gtk.org/Pango/
[pango]: https://docs.gtk.org/pango/
[gdkpixbuf]: https://docs.gtk.org/gdk-pixbuf/
[graphene]: https://ebassi.github.io/graphene/

View File

@@ -5,12 +5,10 @@ Slug: gtk-running
GTK inspects a number of environment variables in addition to
standard variables like `LANG`, `PATH`, `HOME` or `DISPLAY`; mostly
to determine paths to look for certain files. The
[X11](https://docs.gtk.org/gtk4/x11.html#x11-specific-environment-variables),
[Wayland](https://docs.gtk.org/gtk4/wayland.html#wayland-specific-environment-variables),
[Windows](https://docs.gtk.org/gtk4/windows.html#windows-specific-environment-variables) and
[Broadway](https://docs.gtk.org/gtk4/broadway.html#broadway-specific-environment-variables)
GDK backends use some additional environment variables.
to determine paths to look for certain files. The [X11](#x11-envar),
[Wayland](#wayland-envar), [Windows](#win32-envar) and
[Broadway](#broadway-envar) GDK backends use some additional
environment variables.
Note that environment variables are generally used for debugging
purposes. They are not guaranteed to be API stable, and should not
@@ -292,8 +290,8 @@ are only available when GTK has been configured with `-Ddebug=true`.
`fallback`
: Information about fallback usage in renderers
`cache`
: Information about caching
`glyphcache`
: Information about glyph caching
`verbose`
: Print verbose output while rendering

View File

@@ -155,7 +155,6 @@ Each property name is part of the `GtkAccessibleProperty` enumeration.
| %GTK_ACCESSIBLE_PROPERTY_VALUE_MIN | “aria-valuemin” | double |
| %GTK_ACCESSIBLE_PROPERTY_VALUE_NOW | “aria-valuenow” | double |
| %GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT | “aria-valuetext” | translatable string |
| %GTK_ACCESSIBLE_PROPERTY_HELP_TEXT | N/A | translatable string |
#### List of accessible relations
@@ -217,10 +216,6 @@ are accessible as part of the development process. The GTK Inspector shows
the accessible attributes of each widget, and also provides an overlay that
can highlight accessibility issues.
If you support some non-standard keyboard interactions for a widget, you
**should** set an appropriate `GTK_ACCESSIBLE_PROPERTY_HELP_TEXT` to help
discoverability of the behavior.
It is possible to set accessible attributes in UI files as well:
```xml
<object class="GtkButton" id="button1">

View File

@@ -1,18 +0,0 @@
Title: Tools and Demos
GTK ships with a number of tools and demos that come with their own
documentation in the form of man pages.
- [gtk4-broadwayd](gtk4-broadwayd.html)
- [gtk4-builder-tool](gtk4-builder-tool.html)
- [gtk4-demo](gtk4-demo.html)
- [gtk4-demo-application](gtk4-demo-application.html)
- [gtk4-encode-symbolic-svg](gtk4-encode-symbolic-svg.html)
- [gtk4-icon-browser](gtk4-icon-browser.html)
- [gtk4-launch](gtk4-launch.html)
- [gtk4-node-editor](gtk4-node-editor.html)
- [gtk4-path-tool](gtk4-path-tool.html)
- [gtk4-query-settings](gtk4-query-settings.html)
- [gtk4-rendernode-tool](gtk4-rendernode-tool.html)
- [gtk4-update-icon-cache](gtk4-update-icon-cache.html)
- [gtk4-widget-factory](gtk4-widget-factory.html)

View File

@@ -43,7 +43,7 @@ X11 details, in particular the ICCCM and the Extended Window Manager
Hints specifications. [freedesktop.org](http://www.freedesktop.org/standards/)
has links to many relevant specifications.
The GDK manual covers [using Xlib in a GTK program](https://docs.gtk.org/gdk4/x11.html).
The GDK manual covers [using Xlib in a GTK program](#gdk-X-Window-System-Interaction).
### Server, client, window manager

View File

@@ -33,11 +33,9 @@ gdk_broadway_cairo_context_dispose (GObject *object)
}
static void
gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkBroadwayCairoContext *self = GDK_BROADWAY_CAIRO_CONTEXT (draw_context);
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
@@ -61,9 +59,6 @@ gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_fill (cr);
cairo_destroy (cr);
*out_color_state = GDK_COLOR_STATE_SRGB;
*out_depth = gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
}
static void

View File

@@ -33,11 +33,9 @@ gdk_broadway_draw_context_dispose (GObject *object)
}
static void
gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkBroadwayDrawContext *self = GDK_BROADWAY_DRAW_CONTEXT (draw_context);
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
@@ -54,9 +52,6 @@ gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context,
self->nodes = g_array_new (FALSE, FALSE, sizeof(guint32));
self->node_textures = g_ptr_array_new_with_free_func (g_object_unref);
*out_color_state = GDK_COLOR_STATE_SRGB;
*out_depth = gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
}
static void

View File

@@ -43,14 +43,6 @@
#include <fribidi.h>
/* GTK has a general architectural assumption that gsize is pointer-sized
* (equivalent to uintptr_t), making it non-portable to architectures like
* CHERI where that isn't true. If a future release relaxes that
* assumption, changes will be needed in numerous places.
* See also https://gitlab.gnome.org/GNOME/glib/-/issues/2842 for the
* equivalent in GLib, which would be a prerequisite. */
G_STATIC_ASSERT (sizeof (gsize) == sizeof (void *));
G_STATIC_ASSERT (G_ALIGNOF (gsize) == G_ALIGNOF (void *));
/**
* GDK_WINDOWING_X11:
@@ -128,8 +120,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
{ "offload", GDK_DEBUG_OFFLOAD, "Information about subsurfaces and graphics offload" },
{ "linear", GDK_DEBUG_LINEAR, "Enable linear rendering" },
{ "hdr", GDK_DEBUG_HDR, "Force HDR rendering" },
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
{ "force-offload", GDK_DEBUG_FORCE_OFFLOAD, "Force graphics offload for all textures" },
@@ -143,6 +133,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible" },
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)" },

View File

@@ -29,9 +29,7 @@
#include <gdk/gdkapplaunchcontext.h>
#include <gdk/gdkcairo.h>
#include <gdk/gdkcairocontext.h>
#include <gdk/gdkcicpparams.h>
#include <gdk/gdkclipboard.h>
#include <gdk/gdkcolorstate.h>
#include <gdk/gdkconfig.h>
#include <gdk/gdkcontentdeserializer.h>
#include <gdk/gdkcontentformats.h>
@@ -63,7 +61,6 @@
#include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkmemorytexture.h>
#include <gdk/gdkmemorytexturebuilder.h>
#include <gdk/gdkmonitor.h>
#include <gdk/gdkpaintable.h>
#include <gdk/gdkpango.h>

View File

@@ -41,10 +41,8 @@ G_BEGIN_DECLS
#ifdef GDK_ARRAY_NULL_TERMINATED
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof (_T_) - 1)
#else
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof (_T_))
#endif
/* make this readable */
@@ -179,23 +177,18 @@ G_GNUC_UNUSED static inline void
gdk_array(reserve) (GdkArray *self,
gsize n)
{
gsize new_capacity, size, capacity;
gsize new_size, size;
if (G_UNLIKELY (n > GDK_ARRAY_MAX_SIZE))
g_error ("requesting array size of %zu, but maximum size is %zu", n, GDK_ARRAY_MAX_SIZE);
capacity = gdk_array(get_capacity) (self);
if (n <= capacity)
return;
if (n <= gdk_array(get_capacity) (self))
return;
size = gdk_array(get_size) (self);
/* capacity * 2 can overflow, that's why we MAX() */
new_capacity = MAX (GDK_ARRAY_REAL_SIZE (n), capacity * 2);
new_size = ((gsize) 1) << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated)
{
self->start = g_new (_T_, new_capacity);
self->start = g_new (_T_, new_size);
memcpy (self->start, self->preallocated, sizeof (_T_) * GDK_ARRAY_REAL_SIZE (size));
}
else
@@ -203,15 +196,15 @@ gdk_array(reserve) (GdkArray *self,
#ifdef GDK_ARRAY_NULL_TERMINATED
if (self->start == NULL)
{
self->start = g_new (_T_, new_capacity);
self->start = g_new (_T_, new_size);
*self->start = *(_T_[1]) { 0 };
}
else
#endif
self->start = g_renew (_T_, self->start, new_capacity);
self->start = g_renew (_T_, self->start, new_size);
self->end = self->start + size;
self->end_allocation = self->start + new_capacity;
self->end_allocation = self->start + new_size;
#ifdef GDK_ARRAY_NULL_TERMINATED
self->end_allocation--;
#endif
@@ -319,7 +312,6 @@ gdk_array(get) (const GdkArray *self,
#undef gdk_array_paste
#undef gdk_array
#undef GDK_ARRAY_REAL_SIZE
#undef GDK_ARRAY_MAX_SIZE
#undef GDK_ARRAY_BY_VALUE
#undef GDK_ARRAY_ELEMENT_TYPE

View File

@@ -82,10 +82,8 @@ gdk_cairo_context_cairo_create (GdkCairoContext *self)
draw_context = GDK_DRAW_CONTEXT (self);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
if (!gdk_draw_context_is_in_frame (draw_context))
return NULL;
G_GNUC_END_IGNORE_DEPRECATIONS
cr = GDK_CAIRO_CONTEXT_GET_CLASS (self)->cairo_create (self);

View File

@@ -1,159 +0,0 @@
#pragma once
#include "gdkcolorstateprivate.h"
#include "gdkcolorprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytexture.h"
#include <cairo.h>
#include <graphene.h>
static inline cairo_format_t
gdk_cairo_format_for_depth (GdkMemoryDepth depth)
{
switch (depth)
{
case GDK_MEMORY_NONE:
case GDK_MEMORY_U8:
return CAIRO_FORMAT_ARGB32;
case GDK_MEMORY_U8_SRGB:
case GDK_MEMORY_U16:
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
return CAIRO_FORMAT_RGBA128F;
case GDK_N_DEPTHS:
default:
g_return_val_if_reached (CAIRO_FORMAT_ARGB32);
}
}
static inline GdkMemoryDepth
gdk_cairo_depth_for_format (cairo_format_t format)
{
switch (format)
{
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
case CAIRO_FORMAT_RGB16_565:
case CAIRO_FORMAT_A1:
case CAIRO_FORMAT_A8:
return GDK_MEMORY_U8;
case CAIRO_FORMAT_RGB30:
return GDK_MEMORY_U16;
case CAIRO_FORMAT_RGB96F:
case CAIRO_FORMAT_RGBA128F:
return GDK_MEMORY_FLOAT32;
case CAIRO_FORMAT_INVALID:
default:
g_assert_not_reached ();
return GDK_MEMORY_NONE;
}
}
static GdkMemoryFormat
gdk_cairo_format_to_memory_format (cairo_format_t format)
{
switch (format)
{
case CAIRO_FORMAT_ARGB32:
return GDK_MEMORY_DEFAULT;
case CAIRO_FORMAT_RGB24:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
return GDK_MEMORY_B8G8R8X8;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
return GDK_MEMORY_X8R8G8B8;
#else
#error "Unknown byte order for Cairo format"
#endif
case CAIRO_FORMAT_A8:
return GDK_MEMORY_A8;
case CAIRO_FORMAT_RGB96F:
return GDK_MEMORY_R32G32B32_FLOAT;
case CAIRO_FORMAT_RGBA128F:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case CAIRO_FORMAT_RGB16_565:
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_INVALID:
case CAIRO_FORMAT_A1:
default:
g_assert_not_reached ();
return GDK_MEMORY_DEFAULT;
}
}
static inline void
gdk_cairo_set_source_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)
{
GdkColor c;
gdk_color_init_from_rgba (&c, rgba);
gdk_cairo_set_source_color (cr, ccs, &c);
gdk_color_finish (&c);
}
static inline void
gdk_cairo_pattern_add_color_stop_rgba_ccs (cairo_pattern_t *pattern,
GdkColorState *ccs,
double offset,
const GdkRGBA *rgba)
{
float color[4];
gdk_color_state_from_rgba (ccs, rgba, color);
cairo_pattern_add_color_stop_rgba (pattern, offset, color[0], color[1], color[2], color[3]);
}
static inline void
gdk_cairo_rect (cairo_t *cr,
const graphene_rect_t *rect)
{
cairo_rectangle (cr,
rect->origin.x, rect->origin.y,
rect->size.width, rect->size.height);
}
static inline void
gdk_cairo_surface_convert_color_state (cairo_surface_t *surface,
GdkColorState *source,
GdkColorState *target)
{
cairo_surface_t *image_surface;
if (gdk_color_state_equal (source, target))
return;
image_surface = cairo_surface_map_to_image (surface, NULL);
gdk_memory_convert_color_state (cairo_image_surface_get_data (image_surface),
cairo_image_surface_get_stride (image_surface),
gdk_cairo_format_to_memory_format (cairo_image_surface_get_format (image_surface)),
source,
target,
cairo_image_surface_get_width (image_surface),
cairo_image_surface_get_height (image_surface));
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}

View File

@@ -1,484 +0,0 @@
/* gdkcicpparams.c
*
* Copyright 2024 Matthias Clasen
*
* 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 "gdkcicpparamsprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkenumtypes.h"
/**
* GdkCicpParams:
*
* The `GdkCicpParams` struct contains the parameters that define
* a colorstate according to the ITU-T H.273
* [specification](https://www.itu.int/rec/T-REC-H.273/en).
*
* See the documentation of individual properties for supported values.
*
* The 'unspecified' value (2) is not treated in any special way, and
* must be replaced by a different value before creating a color state.
*
* `GdkCicpParams` can be used as a builder object to construct a color
* state from Cicp data with [method@Gdk.CicpParams.build_color_state].
* The function will return an error if the given parameters are not
* supported.
*
* You can obtain a `GdkCicpParams` object from a color state with
* [method@Gdk.ColorState.create_cicp_params]. This can be used to
* create a variant of a color state, by changing just one of the cicp
* parameters, or just to obtain information about the color state.
*
* Since: 4.16
*/
/* {{{ GObject boilerplate */
struct _GdkCicpParams
{
GObject parent_instance;
GdkCicp cicp;
};
struct _GdkCicpParamsClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (GdkCicpParams, gdk_cicp_params, G_TYPE_OBJECT)
enum
{
PROP_COLOR_PRIMARIES = 1,
PROP_TRANSFER_FUNCTION,
PROP_MATRIX_COEFFICIENTS,
PROP_RANGE,
N_PROPERTIES,
};
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
static void
gdk_cicp_params_init (GdkCicpParams *self)
{
self->cicp.color_primaries = 2;
self->cicp.transfer_function = 2;
self->cicp.matrix_coefficients = 2;
self->cicp.range = GDK_CICP_RANGE_NARROW;
}
static void
gdk_cicp_params_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GdkCicpParams *self = GDK_CICP_PARAMS (object);
switch (property_id)
{
case PROP_COLOR_PRIMARIES:
g_value_set_uint (value, self->cicp.color_primaries);
break;
case PROP_TRANSFER_FUNCTION:
g_value_set_uint (value, self->cicp.transfer_function);
break;
case PROP_MATRIX_COEFFICIENTS:
g_value_set_uint (value, self->cicp.matrix_coefficients);
break;
case PROP_RANGE:
g_value_set_enum (value, self->cicp.range);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_cicp_params_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GdkCicpParams *self = GDK_CICP_PARAMS (object);
switch (property_id)
{
case PROP_COLOR_PRIMARIES:
gdk_cicp_params_set_color_primaries (self, g_value_get_uint (value));
break;
case PROP_TRANSFER_FUNCTION:
gdk_cicp_params_set_transfer_function (self, g_value_get_uint (value));
break;
case PROP_MATRIX_COEFFICIENTS:
gdk_cicp_params_set_matrix_coefficients (self, g_value_get_uint (value));
break;
case PROP_RANGE:
gdk_cicp_params_set_range (self, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_cicp_params_class_init (GdkCicpParamsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gdk_cicp_params_get_property;
object_class->set_property = gdk_cicp_params_set_property;
/**
* GdkCicpParams:color-primaries:
*
* The color primaries to use.
*
* Supported values:
*
* - 1: BT.709 / sRGB
* - 2: unspecified
* - 5: PAL
* - 6,7: BT.601 / NTSC
* - 9: BT.2020
* - 12: Display P3
*
* Since: 4.16
*/
properties[PROP_COLOR_PRIMARIES] =
g_param_spec_uint ("color-primaries", NULL, NULL,
0, 255, 2,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkCicpParams:transfer-function:
*
* The transfer function to use.
*
* Supported values:
*
* - 1,6,14,15: BT.709, BT.601, BT.2020
* - 2: unspecified
* - 4: gamma 2.2
* - 5: gamma 2.8
* - 8: linear
* - 13: sRGB
* - 16: BT.2100 PQ
* - 18: BT.2100 HLG
*
* Since: 4.16
*/
properties[PROP_TRANSFER_FUNCTION] =
g_param_spec_uint ("transfer-function", NULL, NULL,
0, 255, 2,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkCicpParams:matrix-coefficients:
*
* The matrix coefficients (for YUV to RGB conversion).
*
* Supported values:
*
* - 0: RGB
* - 1: BT.709
* - 2: unspecified
* - 5,6: BT.601
* - 9: BT.2020
*
* Since: 4.16
*/
properties[PROP_MATRIX_COEFFICIENTS] =
g_param_spec_uint ("matrix-coefficients", NULL, NULL,
0, 255, 2,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkCicpParams:range:
*
* Whether the data is using the full range of values.
*
* The range of the data.
*
* Since: 4.16
*/
properties[PROP_RANGE] =
g_param_spec_enum ("range", NULL, NULL,
GDK_TYPE_CICP_RANGE,
GDK_CICP_RANGE_NARROW,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
/* }}} */
/* {{{ Public API */
/**
* gdk_cicp_params_new:
*
* Creates a new `GdkCicpParams` object.
*
* The initial values of the properties are the values for "undefined"
* and need to be set before a color state object can be built.
*
* Returns: (transfer full): a new `GdkCicpParams`
*
* Since: 4.16
*/
GdkCicpParams *
gdk_cicp_params_new (void)
{
return g_object_new (GDK_TYPE_CICP_PARAMS, NULL);
}
/**
* gdk_cicp_params_get_color_primaries:
* @self: a `GdkCicpParams`
*
* Returns the value of the color-primaries property
* of @self.
*
* Returns: the color-primaries value
*
* Since: 4.16
*/
guint
gdk_cicp_params_get_color_primaries (GdkCicpParams *self)
{
g_return_val_if_fail (GDK_IS_CICP_PARAMS (self), 0);
return self->cicp.color_primaries;
}
/**
* gdk_cicp_params_set_color_primaries:
* @self: a `GdkCicpParams`
* @color_primaries: the new color primaries value
*
* Sets the color-primaries property of @self.
*
* Since: 4.16
*/
void
gdk_cicp_params_set_color_primaries (GdkCicpParams *self,
guint color_primaries)
{
g_return_if_fail (GDK_IS_CICP_PARAMS (self));
if (self->cicp.color_primaries == color_primaries)
return;
self->cicp.color_primaries = color_primaries;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR_PRIMARIES]);
}
/**
* gdk_cicp_params_get_transfer_function:
* @self: a `GdkCicpParams`
*
* Gets the transfer-function property of @self.
*
* Returns: the transfer-function value
*
* Since: 4.16
*/
guint
gdk_cicp_params_get_transfer_function (GdkCicpParams *self)
{
g_return_val_if_fail (GDK_IS_CICP_PARAMS (self), 0);
return self->cicp.transfer_function;
}
/**
* gdk_cicp_params_set_transfer_function:
* @self: a `GdkCicpParams`
* @transfer_function: the new transfer-function value
*
* Sets the transfer-function property of @self.
*
* Since: 4.16
*/
void
gdk_cicp_params_set_transfer_function (GdkCicpParams *self,
guint transfer_function)
{
g_return_if_fail (GDK_IS_CICP_PARAMS (self));
if (self->cicp.transfer_function == transfer_function)
return;
self->cicp.transfer_function = transfer_function;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRANSFER_FUNCTION]);
}
/**
* gdk_cicp_params_get_matrix_coefficients:
* @self: a `GdkCicpParams`
*
* Gets the matrix-coefficients property of @self.
*
* Returns: the matrix-coefficients value
*
* Since: 4.16
*/
guint
gdk_cicp_params_get_matrix_coefficients (GdkCicpParams *self)
{
g_return_val_if_fail (GDK_IS_CICP_PARAMS (self), 0);
return self->cicp.matrix_coefficients;
}
/**
* gdk_cicp_params_set_matrix_coefficients:
* @self a `GdkCicpParams`
* @matrix_coefficients: the new matrix-coefficients value
*
* Sets the matrix-coefficients property of @self.
*
* Since: 4.16
*/
void
gdk_cicp_params_set_matrix_coefficients (GdkCicpParams *self,
guint matrix_coefficients)
{
g_return_if_fail (GDK_IS_CICP_PARAMS (self));
if (self->cicp.matrix_coefficients == matrix_coefficients)
return;
self->cicp.matrix_coefficients = matrix_coefficients;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MATRIX_COEFFICIENTS]);
}
/**
* gdk_cicp_params_get_range:
* @self: a `GdkCicpParams`
*
* Gets the range property of @self.
*
* Returns: the range value
*
* Since: 4.16
*/
GdkCicpRange
gdk_cicp_params_get_range (GdkCicpParams *self)
{
g_return_val_if_fail (GDK_IS_CICP_PARAMS (self), GDK_CICP_RANGE_NARROW);
return self->cicp.range;
}
/**
* gdk_cicp_params_set_range:
* @self: a `GdkCipParams`
* @range: the range value
*
* Sets the range property of @self
*
* Since: 4.16
*/
void
gdk_cicp_params_set_range (GdkCicpParams *self,
GdkCicpRange range)
{
g_return_if_fail (GDK_IS_CICP_PARAMS (self));
if (self->cicp.range == range)
return;
self->cicp.range = range;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RANGE]);
}
/**
* gdk_cicp_params_build_color_state:
* @self: a `GdkCicpParams`
* @error: return location for errors
*
* Creates a new `GdkColorState` object for the cicp parameters in @self.
*
* Note that this may fail if the cicp parameters in @self are not
* supported by GTK. In that case, `NULL` is returned, and @error is set
* with an error message that can be presented to the user.
*
* Returns: (transfer full) (nullable): A newly allocated `GdkColorState`
*
* Since: 4.16
*/
GdkColorState *
gdk_cicp_params_build_color_state (GdkCicpParams *self,
GError **error)
{
return gdk_color_state_new_for_cicp (gdk_cicp_params_get_cicp (self), error);
}
/* }}} */
/* {{{ Private API */
/*< private >
* gdk_cicp_params_new_for_cicp:
* @cicp: a GdkCicp struct
*
* Create a `GdkCicpParams` from the values in @cicp.
*
* Returns: (transfer full): a new `GdkCicpParams` object
*/
GdkCicpParams *
gdk_cicp_params_new_for_cicp (const GdkCicp *cicp)
{
return g_object_new (GDK_TYPE_CICP_PARAMS,
"color-primaries", cicp->color_primaries,
"transfer-function", cicp->transfer_function,
"matrix-coefficients", cicp->matrix_coefficients,
"range", cicp->range,
NULL);
}
/*< private >
* gdk_cicp_params_get_cicp:
* @self: a `GdkCicpParams` object
*
* Gets the `GdkCicp` struct of @self.
*
* Returns: (transfer none): a `GdkCicp` struct containing
* the values of @self
*/
const GdkCicp *
gdk_cicp_params_get_cicp (GdkCicpParams *self)
{
return &self->cicp;
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@@ -1,90 +0,0 @@
/* gdkcicpparams.h
*
* Copyright 2024 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CICP_PARAMS (gdk_cicp_params_get_type ())
GDK_AVAILABLE_IN_4_16
GDK_DECLARE_INTERNAL_TYPE (GdkCicpParams, gdk_cicp_params, GDK, CICP_PARAMS, GObject)
GDK_AVAILABLE_IN_4_16
GdkCicpParams *gdk_cicp_params_new (void);
GDK_AVAILABLE_IN_4_16
guint gdk_cicp_params_get_color_primaries (GdkCicpParams *self);
GDK_AVAILABLE_IN_4_16
void gdk_cicp_params_set_color_primaries (GdkCicpParams *self,
guint color_primaries);
GDK_AVAILABLE_IN_4_16
guint gdk_cicp_params_get_transfer_function (GdkCicpParams *self);
GDK_AVAILABLE_IN_4_16
void gdk_cicp_params_set_transfer_function (GdkCicpParams *self,
guint transfer_function);
GDK_AVAILABLE_IN_4_16
guint gdk_cicp_params_get_matrix_coefficients (GdkCicpParams *self);
GDK_AVAILABLE_IN_4_16
void gdk_cicp_params_set_matrix_coefficients (GdkCicpParams *self,
guint matrix_coefficients);
/**
* GdkCicpRange:
* @GDK_CICP_RANGE_NARROW: The values use the range of 16-235 (for Y) and 16-240 for u and v.
* @GDK_CICO_RANGE_FULL: The values use the full range.
*
* The values of this enumeration describe whether image data uses
* the full range of 8-bit values.
*
* In digital broadcasting, it is common to reserve the lowest and
* highest values. Typically the allowed values for the narrow range
* are 16-235 for Y and 16-240 for u,v (when dealing with YUV data).
*
* Since: 4.16
*/
typedef enum
{
GDK_CICP_RANGE_NARROW,
GDK_CICP_RANGE_FULL,
} GdkCicpRange;
GDK_AVAILABLE_IN_4_16
GdkCicpRange gdk_cicp_params_get_range (GdkCicpParams *self);
GDK_AVAILABLE_IN_4_16
void gdk_cicp_params_set_range (GdkCicpParams *self,
GdkCicpRange range);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_cicp_params_build_color_state (GdkCicpParams *self,
GError **error);
G_END_DECLS

View File

@@ -1,84 +0,0 @@
#pragma once
#include "gdkcicpparams.h"
typedef struct _GdkCicp GdkCicp;
struct _GdkCicp
{
guint color_primaries;
guint transfer_function;
guint matrix_coefficients;
GdkCicpRange range;
};
/*< private >
* gdk_cicp_equal:
* @p1: a `GdkCicp`
* @p2: another `GdkCicp`
*
* Compare two cicp tuples for equality.
*
* Note that several cicp values are 'functionally equivalent'.
* If you are interested in that notion, use gdk_cicp_equivalent().
*
* Returns: whether @p1 and @p2 are equal
*/
static inline gboolean
gdk_cicp_equal (const GdkCicp *p1,
const GdkCicp *p2)
{
return p1->color_primaries == p2->color_primaries &&
p1->transfer_function == p2->transfer_function &&
p1->matrix_coefficients == p2->matrix_coefficients &&
p1->range == p2->range;
}
static inline void
gdk_cicp_normalize (const GdkCicp *orig,
GdkCicp *out)
{
memcpy (out, orig, sizeof (GdkCicp));
/* ntsc */
if (out->color_primaries == 6)
out->color_primaries = 5;
/* bt709 */
if (out->transfer_function == 6 ||
out->transfer_function == 14 ||
out->transfer_function == 15)
out->transfer_function = 1;
/* bt601 */
if (out->matrix_coefficients == 6)
out->matrix_coefficients = 5;
}
/*< private >
* gdk_cicp_equivalent:
* @p1: a `GdkCicp`
* @p2: another `GdkCicp`
*
* Determine whether two cicp tuples are functionally equivalent.
*
* Returns: whether @p1 and @p2 are functionally equivalent
*/
static inline gboolean
gdk_cicp_equivalent (const GdkCicp *p1,
const GdkCicp *p2)
{
GdkCicp n1, n2;
if (gdk_cicp_equal (p1, p2))
return TRUE;
gdk_cicp_normalize (p1, &n1);
gdk_cicp_normalize (p2, &n2);
return gdk_cicp_equal (&n1, &n2);
}
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *params);
GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp);

View File

@@ -515,13 +515,15 @@ gdk_clipboard_get_content (GdkClipboard *clipboard)
* @clipboard: a `GdkClipboard`
* @io_priority: the I/O priority of the request
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data:: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously instructs the @clipboard to store its contents remotely.
*
* If the clipboard is not local, this function does nothing but report success.
*
* The @callback must call [method@Gdk.Clipboard.store_finish].
*
* The purpose of this call is to preserve clipboard contents beyond the
* lifetime of an application, so this function is typically called on
* exit. Depending on the platform, the functionality may not be available
@@ -630,12 +632,15 @@ gdk_clipboard_read_internal (GdkClipboard *clipboard,
* @mime_types: (array zero-terminated=1): a %NULL-terminated array of mime types to choose from
* @io_priority: the I/O priority of the request
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously requests an input stream to read the @clipboard's
* contents from.
*
* When the operation is finished @callback will be called. You must then
* call [method@Gdk.Clipboard.read_finish] to get the result of the operation.
*
* The clipboard will choose the most suitable mime type from the given list
* to fulfill the request, preferring the ones listed first.
*/
@@ -823,12 +828,15 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
* @type: a `GType` to read
* @io_priority: the I/O priority of the request
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously request the @clipboard contents converted to the given
* @type.
*
* When the operation is finished @callback will be called. You must then call
* [method@Gdk.Clipboard.read_value_finish] to get the resulting `GValue`.
*
* For local clipboard contents that are available in the given `GType`,
* the value will be copied directly. Otherwise, GDK will try to use
* [func@content_deserialize_async] to convert the clipboard's data.
@@ -882,11 +890,14 @@ gdk_clipboard_read_value_finish (GdkClipboard *clipboard,
* gdk_clipboard_read_texture_async:
* @clipboard: a `GdkClipboard`
* @cancellable: (nullable): optional `GCancellable` object, %NULL to ignore.
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously request the @clipboard contents converted to a `GdkPixbuf`.
*
* When the operation is finished @callback will be called. You must then
* call [method@Gdk.Clipboard.read_texture_finish] to get the result.
*
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
* need more control over the operation.
@@ -944,11 +955,14 @@ gdk_clipboard_read_texture_finish (GdkClipboard *clipboard,
* gdk_clipboard_read_text_async:
* @clipboard: a `GdkClipboard`
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously request the @clipboard contents converted to a string.
*
* When the operation is finished @callback will be called. You must then
* call [method@Gdk.Clipboard.read_text_finish] to get the result.
*
* This is a simple wrapper around [method@Gdk.Clipboard.read_value_async].
* Use that function or [method@Gdk.Clipboard.read_async] directly if you
* need more control over the operation.

View File

@@ -1,301 +0,0 @@
/* 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);
}

View File

@@ -1,260 +0,0 @@
/* gdkcolordefs.h
*
* Copyright 2024 Matthias Clasen
*
* 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/>.
*/
/* Note that this header is shared between the color state implementation
* and tests, and must not include other headers.
*/
static inline float
srgb_oetf (float v)
{
if (v > 0.0031308f)
return 1.055f * powf (v, 1.f / 2.4f) - 0.055f;
else
return 12.92f * v;
}
static inline float
srgb_eotf (float v)
{
if (v >= 0.04045f)
return powf (((v + 0.055f) / (1.f + 0.055f)), 2.4f);
else
return v / 12.92f;
}
static inline float
gamma22_oetf (float v)
{
return powf (v, 1.f / 2.2f);
}
static inline float
gamma22_eotf (float v)
{
return powf (v, 2.2f);
}
static inline float
gamma28_oetf (float v)
{
return powf (v, 1.f / 2.8f);
}
static inline float
gamma28_eotf (float v)
{
return powf (v, 2.8f);
}
static inline float
pq_eotf (float v)
{
float ninv = (1 << 14) / 2610.0;
float minv = (1 << 5) / 2523.0;
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
float x = powf (MAX ((powf (v, minv) - c1), 0) / (c2 - (c3 * (powf (v, minv)))), ninv);
return x * 10000 / 203.0;
}
static inline float
pq_oetf (float v)
{
float x = v * 203.0 / 10000.0;
float n = 2610.0 / (1 << 14);
float m = 2523.0 / (1 << 5);
float c1 = 3424.0 / (1 << 12);
float c2 = 2413.0 / (1 << 7);
float c3 = 2392.0 / (1 << 7);
return powf (((c1 + (c2 * powf (x, n))) / (1 + (c3 * powf (x, n)))), m);
}
static inline float
bt709_eotf (float v)
{
const float a = 1.099;
const float d = 0.0812;
if (v < d)
return v / 4.5f;
else
return powf ((v + (a - 1)) / a, 1 / 0.45f);
}
static inline float
bt709_oetf (float v)
{
const float a = 1.099;
const float b = 0.018;
if (v < b)
return v * 4.5f;
else
return a * powf (v, 0.45f) - (a - 1);
}
static inline float
hlg_eotf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 0.5)
return (v * v) / 3;
else
return (expf ((v - c) / a) + b) / 12.0;
}
static inline float
hlg_oetf (float v)
{
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
if (v <= 1/12.0)
return sqrtf (3 * v);
else
return a * logf (12 * v - b) + c;
}
/* See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
* for how to derive the abc_to_xyz matrices from chromaticity coordinates.
*/
static const float identity[9] = {
1, 0, 0,
0, 1, 0,
0, 0, 1,
};
static const float srgb_to_xyz[9] = {
0.4124564, 0.3575761, 0.1804375,
0.2126729, 0.7151522, 0.0721750,
0.0193339, 0.1191920, 0.9503041,
};
static const float xyz_to_srgb[9] = {
3.2404542, -1.5371385, -0.4985314,
-0.9692660, 1.8760108, 0.0415560,
0.0556434, -0.2040259, 1.0572252,
};
static const float rec2020_to_xyz[9] = {
0.6369580, 0.1446169, 0.1688810,
0.2627002, 0.6779981, 0.0593017,
0.0000000, 0.0280727, 1.0609851,
};
static const float xyz_to_rec2020[9] = {
1.7166512, -0.3556708, -0.2533663,
-0.6666844, 1.6164812, 0.0157685,
0.0176399, -0.0427706, 0.9421031,
};
static const float pal_to_xyz[9] = {
0.4305538, 0.3415498, 0.1783523,
0.2220043, 0.7066548, 0.0713409,
0.0201822, 0.1295534, 0.9393222,
};
static const float xyz_to_pal[9] = {
3.0633611, -1.3933902, -0.4758237,
-0.9692436, 1.8759675, 0.0415551,
0.0678610, -0.2287993, 1.0690896,
};
static const float ntsc_to_xyz[9] = {
0.3935209, 0.3652581, 0.1916769,
0.2123764, 0.7010599, 0.0865638,
0.0187391, 0.1119339, 0.9583847,
};
static const float xyz_to_ntsc[9] = {
3.5060033, -1.7397907, -0.5440583,
-1.0690476, 1.9777789, 0.0351714,
0.0563066, -0.1969757, 1.0499523,
};
static const float p3_to_xyz[9] = {
0.4865709, 0.2656677, 0.1982173,
0.2289746, 0.6917385, 0.0792869,
0.0000000, 0.0451134, 1.0439444,
};
static const float xyz_to_p3[9] = {
2.4934969, -0.9313836, -0.4027108,
-0.8294890, 1.7626641, 0.0236247,
0.0358458, -0.0761724, 0.9568845,
};
/* premultiplied matrices for default conversions */
static const float rec2020_to_srgb[9] = {
1.660227, -0.587548, -0.072838,
-0.124553, 1.132926, -0.008350,
-0.018155, -0.100603, 1.118998,
};
static const float srgb_to_rec2020[9] = {
0.627504, 0.329275, 0.043303,
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,
};

View File

@@ -1,135 +0,0 @@
/* 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);
}

View File

@@ -1,107 +0,0 @@
/* 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

View File

@@ -1,950 +0,0 @@
/* gdkcolorstate.c
*
* Copyright 2024 Matthias Clasen
*
* 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"
#define GDK_COLOR_STATE_IMPL
#include "gdkcolorstateprivate.h"
#include <math.h>
#include "gdkcolordefs.h"
#include <glib/gi18n-lib.h>
/**
* GdkColorState:
*
* A `GdkColorState` object provides the information to interpret
* colors and pixels in a variety of ways.
*
* They are also known as
* [*color spaces*](https://en.wikipedia.org/wiki/Color_space).
*
* Crucially, GTK knows how to convert colors from one color
* state to another.
*
* `GdkColorState objects are immutable and therefore threadsafe.
*
* Since 4.16
*/
G_DEFINE_BOXED_TYPE (GdkColorState, gdk_color_state,
gdk_color_state_ref, gdk_color_state_unref);
/* {{{ Public API */
/**
* gdk_color_state_ref:
* @self: a `GdkColorState`
*
* Increase the reference count of @self.
*
* Returns: the object that was passed in
*
* Since: 4.16
*/
GdkColorState *
(gdk_color_state_ref) (GdkColorState *self)
{
return _gdk_color_state_ref (self);
}
/**
* gdk_color_state_unref:
* @self:a `GdkColorState`
*
* Decrease the reference count of @self.
*
* Unless @self is static, it will be freed
* when the reference count reaches zero.
*
* Since: 4.16
*/
void
(gdk_color_state_unref) (GdkColorState *self)
{
_gdk_color_state_unref (self);
}
/**
* gdk_color_state_get_srgb:
*
* Returns the color state object representing the sRGB color space.
*
* This color state uses the primaries defined by BT.709-6 and the transfer function
* defined by IEC 61966-2-1.
*
* It is equivalent to the [Cicp](class.CicpParams.html) tuple 1/13/0/1.
*
* See e.g. [the CSS Color Module](https://www.w3.org/TR/css-color-4/#predefined-sRGB)
* for details about this colorstate.
*
* Returns: the color state object for sRGB
*
* Since: 4.16
*/
GdkColorState *
gdk_color_state_get_srgb (void)
{
return GDK_COLOR_STATE_SRGB;
}
/**
* gdk_color_state_get_srgb_linear:
*
* Returns the color state object representing the linearized sRGB color space.
*
* This color state uses the primaries defined by BT.709-6 and a linear transfer function.
*
* It is equivalent to the [Cicp](class.CicpParams.html) tuple 1/8/0/1.
*
* See e.g. [the CSS Color Module](https://www.w3.org/TR/css-color-4/#predefined-sRGB-linear)
* for details about this colorstate.
*
* Returns: the color state object for linearized sRGB
*
* Since: 4.16
*/
GdkColorState *
gdk_color_state_get_srgb_linear (void)
{
return GDK_COLOR_STATE_SRGB_LINEAR;
}
/**
* gdk_color_state_get_rec2100_pq:
*
* Returns the color state object representing the rec2100-pq color space.
*
* This color state uses the primaries defined by BT.2020-2 and BT.2100-0 and the transfer
* function defined by SMPTE ST 2084 and BT.2100-2.
*
* It is equivalent to the [Cicp](class.CicpParams.html) tuple 9/16/0/1.
*
* See e.g. [the CSS HDR Module](https://drafts.csswg.org/css-color-hdr/#valdef-color-rec2100-pq)
* for details about this colorstate.
*
* Returns: the color state object for rec2100-pq
*
* Since: 4.16
*/
GdkColorState *
gdk_color_state_get_rec2100_pq (void)
{
return GDK_COLOR_STATE_REC2100_PQ;
}
/**
* gdk_color_state_get_rec2100_linear:
*
* Returns the color state object representing the linear rec2100 color space.
*
* This color state uses the primaries defined by BT.2020-2 and BT.2100-0 and a linear
* transfer function.
*
* It is equivalent to the [Cicp](class.CicpParams.html) tuple 9/8/0/1.
*
* See e.g. [the CSS HDR Module](https://drafts.csswg.org/css-color-hdr/#valdef-color-rec2100-linear)
* for details about this colorstate.
*
* Returns: the color state object for linearized rec2100
*
* Since: 4.16
*/
GdkColorState *
gdk_color_state_get_rec2100_linear (void)
{
return GDK_COLOR_STATE_REC2100_LINEAR;
}
/**
* gdk_color_state_equal:
* @self: a `GdkColorState`
* @other: another `GdkColorStatee`
*
* Compares two `GdkColorStates` for equality.
*
* Note that this function is not guaranteed to be perfect and two objects
* describing the same color state may compare not equal. However, different
* color states will never compare equal.
*
* Returns: %TRUE if the two color states compare equal
*
* Since: 4.16
*/
gboolean
(gdk_color_state_equal) (GdkColorState *self,
GdkColorState *other)
{
return _gdk_color_state_equal (self, other);
}
/**
* gdk_color_state_create_cicp_params:
* @self: a `GdkColorState`
*
* Create a [class@Gdk.CicpParams] representing the colorstate.
*
* It is not guaranteed that every `GdkColorState` can be
* represented with Cicp parameters. If that is the case,
* this function returns `NULL`.
*
* Returns: (transfer full) (nullable): A new [class@Gdk.CicpParams]
*
* Since: 4.16
*/
GdkCicpParams *
gdk_color_state_create_cicp_params (GdkColorState *self)
{
const GdkCicp *cicp = gdk_color_state_get_cicp (self);
if (cicp)
return gdk_cicp_params_new_for_cicp (cicp);
return NULL;
}
/* }}} */
/* {{{ Conversion functions */
typedef float (* GdkTransferFunc) (float v);
typedef const float GdkColorMatrix[9];
#define IDENTITY ((float*)0)
#define NONE ((GdkTransferFunc)0)
#define TRANSFORM(name, eotf, matrix, oetf) \
static void \
name (GdkColorState *self, \
float (*values)[4], \
gsize n_values) \
{ \
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 (matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = matrix[0] * values[i][0] + matrix[1] * values[i][1] + matrix[2] * values[i][2]; \
res[1] = matrix[3] * values[i][0] + matrix[4] * values[i][1] + matrix[5] * values[i][2]; \
res[2] = matrix[6] * values[i][0] + matrix[7] * values[i][1] + 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]); \
} \
} \
}
TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE);
TRANSFORM(gdk_default_srgb_linear_to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(gdk_default_rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE)
TRANSFORM(gdk_default_rec2100_linear_to_rec2100_pq, NONE, IDENTITY, pq_oetf)
TRANSFORM(gdk_default_srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE)
TRANSFORM(gdk_default_rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE)
TRANSFORM(gdk_default_srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE)
TRANSFORM(gdk_default_rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE)
TRANSFORM(gdk_default_srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, pq_oetf)
TRANSFORM(gdk_default_rec2100_linear_to_srgb, NONE, rec2020_to_srgb, srgb_oetf)
TRANSFORM(gdk_default_srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, pq_oetf)
TRANSFORM(gdk_default_rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, srgb_oetf)
/* }}} */
/* {{{ Default implementation */
/* {{{ Vfuncs */
static gboolean
gdk_default_color_state_equal (GdkColorState *self,
GdkColorState *other)
{
return self == other;
}
static const char *
gdk_default_color_state_get_name (GdkColorState *color_state)
{
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
return self->name;
}
static GdkColorState *
gdk_default_color_state_get_no_srgb_tf (GdkColorState *color_state)
{
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
return self->no_srgb;
}
static GdkFloatColorConvert
gdk_default_color_state_get_convert_to (GdkColorState *color_state,
GdkColorState *target)
{
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
if (GDK_IS_DEFAULT_COLOR_STATE (target))
return self->convert_to[GDK_DEFAULT_COLOR_STATE_ID (target)];
return NULL;
}
static GdkFloatColorConvert
gdk_default_color_state_get_convert_from (GdkColorState *color_state,
GdkColorState *source)
{
/* This is ok because the default-to-default conversion functions
* don't use the passed colorstate at all.
*/
return gdk_default_color_state_get_convert_to (source, color_state);
}
static const GdkCicp *
gdk_default_color_state_get_cicp (GdkColorState *color_state)
{
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
return &self->cicp;
}
/* }}} */
static const
GdkColorStateClass GDK_DEFAULT_COLOR_STATE_CLASS = {
.free = NULL, /* crash here if this ever happens */
.equal = gdk_default_color_state_equal,
.get_name = gdk_default_color_state_get_name,
.get_no_srgb_tf = gdk_default_color_state_get_no_srgb_tf,
.get_convert_to = gdk_default_color_state_get_convert_to,
.get_convert_from = gdk_default_color_state_get_convert_from,
.get_cicp = gdk_default_color_state_get_cicp,
};
GdkDefaultColorState gdk_default_color_states[] = {
[GDK_COLOR_STATE_ID_SRGB] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_U8_SRGB,
.rendering_color_state = GDK_COLOR_STATE_SRGB_LINEAR,
},
.name = "srgb",
.no_srgb = GDK_COLOR_STATE_SRGB_LINEAR,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_srgb_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_to_rec2100_linear,
},
.cicp = { 1, 13, 0, 1 },
},
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_U8,
.rendering_color_state = GDK_COLOR_STATE_SRGB_LINEAR,
},
.name = "srgb-linear",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_srgb_linear_to_srgb,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_linear_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_linear_to_rec2100_linear,
},
.cicp = { 1, 8, 0, 1 },
},
[GDK_COLOR_STATE_ID_REC2100_PQ] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "rec2100-pq",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_pq_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_pq_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_rec2100_pq_to_rec2100_linear,
},
.cicp = { 9, 16, 0, 1 },
},
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR,
},
.name = "rec2100-linear",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_linear_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_linear_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_rec2100_linear_to_rec2100_pq,
},
.cicp = { 9, 8, 0, 1 },
},
};
/* }}} */
/* {{{ Cicp implementation */
typedef struct _GdkCicpColorState GdkCicpColorState;
struct _GdkCicpColorState
{
GdkColorState parent;
GdkColorState *no_srgb;
const char *name;
GdkTransferFunc eotf;
GdkTransferFunc oetf;
float *to_srgb;
float *to_rec2020;
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 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_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)
/* }}} */
/* {{{ Vfuncs */
static void
gdk_cicp_color_state_free (GdkColorState *cs)
{
GdkCicpColorState *self = (GdkCicpColorState *) cs;
if (self->no_srgb)
gdk_color_state_unref (self->no_srgb);
g_free (self->to_srgb);
g_free (self->to_rec2020);
g_free (self->from_srgb);
g_free (self->from_rec2020);
g_free (self);
}
static gboolean
gdk_cicp_color_state_equal (GdkColorState *self,
GdkColorState *other)
{
GdkCicpColorState *cs1 = (GdkCicpColorState *) self;
GdkCicpColorState *cs2 = (GdkCicpColorState *) other;
return gdk_cicp_equal (&cs1->cicp, &cs2->cicp);
}
static const char *
gdk_cicp_color_state_get_name (GdkColorState *self)
{
GdkCicpColorState *cs = (GdkCicpColorState *) self;
return cs->name;
}
static GdkColorState *
gdk_cicp_color_state_get_no_srgb_tf (GdkColorState *self)
{
GdkCicpColorState *cs = (GdkCicpColorState *) self;
return cs->no_srgb;
}
static GdkFloatColorConvert
gdk_cicp_color_state_get_convert_to (GdkColorState *self,
GdkColorState *target)
{
if (!GDK_IS_DEFAULT_COLOR_STATE (target))
return NULL;
switch (GDK_DEFAULT_COLOR_STATE_ID (target))
{
case GDK_COLOR_STATE_ID_SRGB:
return gdk_cicp_to_srgb;
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
return gdk_cicp_to_srgb_linear;
case GDK_COLOR_STATE_ID_REC2100_PQ:
return gdk_cicp_to_rec2100_pq;
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
return gdk_cicp_to_rec2100_linear;
case GDK_COLOR_STATE_N_IDS:
default:
g_assert_not_reached ();
}
return NULL;
}
static GdkFloatColorConvert
gdk_cicp_color_state_get_convert_from (GdkColorState *self,
GdkColorState *source)
{
if (!GDK_IS_DEFAULT_COLOR_STATE (source))
return NULL;
switch (GDK_DEFAULT_COLOR_STATE_ID (source))
{
case GDK_COLOR_STATE_ID_SRGB:
return gdk_cicp_from_srgb;
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
return gdk_cicp_from_srgb_linear;
case GDK_COLOR_STATE_ID_REC2100_PQ:
return gdk_cicp_from_rec2100_pq;
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
return gdk_cicp_from_rec2100_linear;
case GDK_COLOR_STATE_N_IDS:
default:
g_assert_not_reached ();
}
return NULL;
}
static const GdkCicp *
gdk_cicp_color_state_get_cicp (GdkColorState *color_state)
{
GdkCicpColorState *self = (GdkCicpColorState *) color_state;
return &self->cicp;
}
/* }}} */
static const
GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
.free = gdk_cicp_color_state_free,
.equal = gdk_cicp_color_state_equal,
.get_name = gdk_cicp_color_state_get_name,
.get_no_srgb_tf = gdk_cicp_color_state_get_no_srgb_tf,
.get_convert_to = gdk_cicp_color_state_get_convert_to,
.get_convert_from = gdk_cicp_color_state_get_convert_from,
.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],
const float m2[9])
{
#define IDX(i,j) 3*i+j
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
res[IDX(i,j)] = m1[IDX(i,0)] * m2[IDX(0,j)]
+ m1[IDX(i,1)] * m2[IDX(1,j)]
+ m1[IDX(i,2)] * m2[IDX(2,j)];
return res;
}
GdkColorState *
gdk_color_state_new_for_cicp (const GdkCicp *cicp,
GError **error)
{
GdkCicpColorState *self;
GdkTransferFunc eotf;
GdkTransferFunc oetf;
gconstpointer to_xyz;
gconstpointer from_xyz;
gconstpointer to_yuv = NULL;
gconstpointer from_yuv = NULL;
if (cicp->color_primaries == 2 ||
cicp->transfer_function == 2 ||
cicp->matrix_coefficients == 2)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Unspecified parameters not supported"));
return NULL;
}
for (guint i = 0; i < GDK_COLOR_STATE_N_IDS; i++)
{
if (gdk_cicp_equal (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:
case 6:
case 14:
case 15:
eotf = bt709_eotf;
oetf = bt709_oetf;
break;
case 4:
eotf = gamma22_eotf;
oetf = gamma22_oetf;
break;
case 5:
eotf = gamma28_eotf;
oetf = gamma28_oetf;
break;
case 8:
eotf = NONE;
oetf = NONE;
break;
case 13:
eotf = srgb_eotf;
oetf = srgb_oetf;
break;
case 16:
eotf = pq_eotf;
oetf = pq_oetf;
break;
case 18:
eotf = hlg_eotf;
oetf = hlg_oetf;
break;
default:
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Transfer function %u not supported"),
cicp->transfer_function);
return NULL;
}
switch (cicp->color_primaries)
{
case 1:
to_xyz = srgb_to_xyz;
from_xyz = xyz_to_srgb;
break;
case 5:
to_xyz = pal_to_xyz;
from_xyz = xyz_to_pal;
break;
case 6:
case 7:
to_xyz = ntsc_to_xyz;
from_xyz = xyz_to_ntsc;
break;
case 9:
to_xyz = rec2020_to_xyz;
from_xyz = xyz_to_rec2020;
break;
case 12:
to_xyz = p3_to_xyz;
from_xyz = xyz_to_p3;
break;
default:
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Color primaries %u not supported"),
cicp->color_primaries);
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;
self->parent.ref_count = 1;
/* sRGB is special-cased by being a default colorstate */
self->parent.rendering_color_state = GDK_COLOR_STATE_REC2100_LINEAR;
self->parent.depth = GDK_MEMORY_FLOAT16;
memcpy (&self->cicp, cicp, sizeof (GdkCicp));
self->to_yuv = to_yuv;
self->from_yuv = from_yuv;
self->eotf = eotf;
self->oetf = oetf;
self->to_srgb = multiply (g_new (float, 9), xyz_to_srgb, to_xyz);
self->to_rec2020 = multiply (g_new (float, 9), xyz_to_rec2020, to_xyz);
self->from_srgb = multiply (g_new (float, 9), from_xyz, srgb_to_xyz);
self->from_rec2020 = multiply (g_new (float, 9), from_xyz, rec2020_to_xyz);
self->name = g_strdup_printf ("cicp-%u/%u/%u/%u",
cicp->color_primaries,
cicp->transfer_function,
cicp->matrix_coefficients,
cicp->range);
if (cicp->transfer_function == 13)
{
GdkCicp no_srgb;
memcpy (&no_srgb, cicp, sizeof (GdkCicp));
no_srgb.transfer_function = 8;
self->no_srgb = gdk_color_state_new_for_cicp (&no_srgb, NULL);
}
return (GdkColorState *) self;
}
/* }}} */
/* {{{ Private API */
/*<private>
* gdk_color_state_get_name:
* @self: a colorstate
*
* Returns the name of @self.
*
* This is *not* a translated, user-visible string.
*
* Returns: (transfer none): a name for representing the color state
* in diagnostic output
*/
const char *
gdk_color_state_get_name (GdkColorState *self)
{
return self->klass->get_name (self);
}
/*<private>
* gdk_color_state_get_no_srgb_tf:
* @self: a colorstate
*
* This function checks if the colorstate uses an sRGB transfer function
* as final operation. In that case, it is suitable for use with GL_SRGB
* (and the Vulkan equivalents).
*
* If it is suitable, the colorstate without the transfer function is
* returned. Otherwise, this function returns NULL.
*
* Returns: (transfer none): the colorstate without sRGB transfer function.
**/
GdkColorState *
gdk_color_state_get_no_srgb_tf (GdkColorState *self)
{
if (!GDK_DEBUG_CHECK (LINEAR))
return FALSE;
return self->klass->get_no_srgb_tf (self);
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@@ -1,62 +0,0 @@
/* gdkcolorstate.h
*
* Copyright 2024 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_COLOR_STATE (gdk_color_state_get_type ())
GDK_AVAILABLE_IN_4_16
GType gdk_color_state_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_ref (GdkColorState *self);
GDK_AVAILABLE_IN_4_16
void gdk_color_state_unref (GdkColorState *self);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_srgb (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_srgb_linear (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_rec2100_pq (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_rec2100_linear (void);
GDK_AVAILABLE_IN_4_16
gboolean gdk_color_state_equal (GdkColorState *self,
GdkColorState *other);
GDK_AVAILABLE_IN_4_16
GdkCicpParams *gdk_color_state_create_cicp_params (GdkColorState *self);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref);
G_END_DECLS

View File

@@ -1,220 +0,0 @@
#pragma once
#include "gdkcolorstate.h"
#include "gdkcicpparamsprivate.h"
#include "gdkdebugprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkrgba.h"
typedef enum
{
GDK_COLOR_STATE_ID_SRGB,
GDK_COLOR_STATE_ID_SRGB_LINEAR,
GDK_COLOR_STATE_ID_REC2100_PQ,
GDK_COLOR_STATE_ID_REC2100_LINEAR,
GDK_COLOR_STATE_N_IDS
} GdkColorStateId;
typedef struct _GdkColorStateClass GdkColorStateClass;
struct _GdkColorState
{
const GdkColorStateClass *klass;
gatomicrefcount ref_count;
GdkMemoryDepth depth;
GdkColorState *rendering_color_state;
};
/* Note: self may be the source or the target colorstate */
typedef void (* GdkFloatColorConvert)(GdkColorState *self,
float (*values)[4],
gsize n_values);
struct _GdkColorStateClass
{
void (* free) (GdkColorState *self);
gboolean (* equal) (GdkColorState *self,
GdkColorState *other);
const char * (* get_name) (GdkColorState *self);
GdkColorState * (* get_no_srgb_tf) (GdkColorState *self);
GdkFloatColorConvert (* get_convert_to) (GdkColorState *self,
GdkColorState *target);
GdkFloatColorConvert (* get_convert_from) (GdkColorState *self,
GdkColorState *source);
const GdkCicp * (* get_cicp) (GdkColorState *self);
};
typedef struct _GdkDefaultColorState GdkDefaultColorState;
struct _GdkDefaultColorState
{
GdkColorState parent;
const char *name;
GdkColorState *no_srgb;
GdkFloatColorConvert convert_to[GDK_COLOR_STATE_N_IDS];
GdkCicp cicp;
};
extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
#define GDK_COLOR_STATE_SRGB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
#define GDK_COLOR_STATE_REC2100_PQ ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_PQ])
#define GDK_COLOR_STATE_REC2100_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_LINEAR])
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
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)
{
if (GDK_DEBUG_CHECK (HDR))
self = GDK_COLOR_STATE_REC2100_PQ;
if (!GDK_DEBUG_CHECK (LINEAR))
return self;
return self->rendering_color_state;
}
static inline GdkMemoryDepth
gdk_color_state_get_depth (GdkColorState *self)
{
if (!GDK_DEBUG_CHECK (LINEAR) && self->depth == GDK_MEMORY_U8_SRGB)
return GDK_MEMORY_U8;
return self->depth;
}
static inline GdkColorState *
gdk_color_state_get_by_id (GdkColorStateId id)
{
return (GdkColorState *) &gdk_default_color_states[id];
}
#define gdk_color_state_ref(self) _gdk_color_state_ref (self)
static inline GdkColorState *
_gdk_color_state_ref (GdkColorState *self)
{
if (GDK_IS_DEFAULT_COLOR_STATE (self))
return self;
g_atomic_ref_count_inc (&self->ref_count);
return self;
}
#define gdk_color_state_unref(self) _gdk_color_state_unref (self)
static inline void
_gdk_color_state_unref (GdkColorState *self)
{
if (GDK_IS_DEFAULT_COLOR_STATE (self))
return;
if (g_atomic_ref_count_dec (&self->ref_count))
self->klass->free (self);
}
#define gdk_color_state_equal(a,b) _gdk_color_state_equal ((a), (b))
static inline gboolean
_gdk_color_state_equal (GdkColorState *self,
GdkColorState *other)
{
if (self == other)
return TRUE;
if (self->klass != other->klass)
return FALSE;
return self->klass->equal (self, other);
}
/* Note: the functions returned from this expect the source
* color state to be passed as self
*/
static inline GdkFloatColorConvert
gdk_color_state_get_convert_to (GdkColorState *self,
GdkColorState *target)
{
return self->klass->get_convert_to (self, target);
}
/* Note: the functions returned from this expect the target
* color state to be passed as self
*/
static inline GdkFloatColorConvert
gdk_color_state_get_convert_from (GdkColorState *self,
GdkColorState *source)
{
return self->klass->get_convert_from (self, source);
}
static inline const GdkCicp *
gdk_color_state_get_cicp (GdkColorState *self)
{
return self->klass->get_cicp (self);
}
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;
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);
}
#ifndef GDK_COLOR_STATE_IMPL
extern GdkColorState gdk_color_state_bt601_narrow;
extern GdkColorState gdk_color_state_bt601_full;
#endif
#define GDK_COLOR_STATE_YUV ((GdkColorState *) &gdk_color_state_bt601_narrow)
#define GDK_COLOR_STATE_JPEG ((GdkColorState *) &gdk_color_state_bt601_full)

View File

@@ -533,13 +533,16 @@ deserialize_not_found (GdkContentDeserializer *deserializer)
* @type: the GType to deserialize from
* @io_priority: the I/O priority of the operation
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): callback to call when the operation is done
* @user_data: data to pass to the callback function
* @callback: (scope async): callback to call when the operation is done
* @user_data: (closure): data to pass to the callback function
*
* Read content from the given input stream and deserialize it, asynchronously.
*
* The default I/O priority is %G_PRIORITY_DEFAULT (i.e. 0), and lower numbers
* indicate a higher priority.
*
* When the operation is finished, @callback will be called. You must then
* call [func@Gdk.content_deserialize_finish] to get the result of the operation.
*/
void
gdk_content_deserialize_async (GInputStream *stream,

View File

@@ -273,12 +273,16 @@ gdk_content_provider_content_changed (GdkContentProvider *provider)
* @stream: the `GOutputStream` to write to
* @io_priority: I/O priority of the request.
* @cancellable: (nullable): optional `GCancellable` object, %NULL to ignore.
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously writes the contents of @provider to @stream in the given
* @mime_type.
*
* When the operation is finished @callback will be called. You must then call
* [method@Gdk.ContentProvider.write_mime_type_finish] to get the result
* of the operation.
*
* The given mime type does not need to be listed in the formats returned by
* [method@Gdk.ContentProvider.ref_formats]. However, if the given `GType` is
* not supported, `G_IO_ERROR_NOT_SUPPORTED` will be reported.

View File

@@ -539,13 +539,16 @@ serialize_not_found (GdkContentSerializer *serializer)
* @value: the content to serialize
* @io_priority: the I/O priority of the operation
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure): callback to call when the operation is done
* @user_data: data to pass to the callback function
* @callback: (scope async): callback to call when the operation is done
* @user_data: (closure): data to pass to the callback function
*
* Serialize content and write it to the given output stream, asynchronously.
*
* The default I/O priority is %G_PRIORITY_DEFAULT (i.e. 0), and lower numbers
* indicate a higher priority.
*
* When the operation is finished, @callback will be called. You must then
* call [func@Gdk.content_serialize_finish] to get the result of the operation.
*/
void
gdk_content_serialize_async (GOutputStream *stream,

View File

@@ -52,7 +52,7 @@ GdkCursor* gdk_cursor_new_from_name (const char *name,
GdkCursor *fallback);
/**
* GdkCursorGetTextureCallback:
* GdkCursorGetTestureCallback:
* @cursor: the `GdkCursor`
* @cursor_size: the nominal cursor size, in application pixels
* @scale: the device scale

View File

@@ -40,21 +40,20 @@ typedef enum {
GDK_DEBUG_OFFLOAD = 1 << 12,
/* flags below are influencing behavior */
GDK_DEBUG_LINEAR = 1 << 13,
GDK_DEBUG_HDR = 1 << 14,
GDK_DEBUG_PORTALS = 1 << 15,
GDK_DEBUG_NO_PORTALS = 1 << 16,
GDK_DEBUG_GL_DISABLE = 1 << 17,
GDK_DEBUG_GL_NO_FRACTIONAL= 1 << 18,
GDK_DEBUG_FORCE_OFFLOAD = 1 << 19,
GDK_DEBUG_GL_DISABLE_GL = 1 << 20,
GDK_DEBUG_GL_DISABLE_GLES = 1 << 21,
GDK_DEBUG_GL_PREFER_GL = 1 << 22,
GDK_DEBUG_GL_DEBUG = 1 << 23,
GDK_DEBUG_GL_EGL = 1 << 24,
GDK_DEBUG_GL_GLX = 1 << 25,
GDK_DEBUG_GL_WGL = 1 << 26,
GDK_DEBUG_VULKAN_DISABLE = 1 << 27,
GDK_DEBUG_PORTALS = 1 << 14,
GDK_DEBUG_NO_PORTALS = 1 << 15,
GDK_DEBUG_GL_DISABLE = 1 << 16,
GDK_DEBUG_GL_NO_FRACTIONAL= 1 << 17,
GDK_DEBUG_FORCE_OFFLOAD = 1 << 18,
GDK_DEBUG_GL_DISABLE_GL = 1 << 19,
GDK_DEBUG_GL_DISABLE_GLES = 1 << 20,
GDK_DEBUG_GL_PREFER_GL = 1 << 21,
GDK_DEBUG_GL_DEBUG = 1 << 22,
GDK_DEBUG_GL_EGL = 1 << 23,
GDK_DEBUG_GL_GLX = 1 << 24,
GDK_DEBUG_GL_WGL = 1 << 25,
GDK_DEBUG_VULKAN_DISABLE = 1 << 26,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 27,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 28,
GDK_DEBUG_HIGH_DEPTH = 1 << 29,
GDK_DEBUG_NO_VSYNC = 1 << 30,

View File

@@ -1,82 +0,0 @@
#include "config.h"
#include "gdkdihedralprivate.h"
void
gdk_dihedral_get_mat2 (GdkDihedral transform,
float *xx,
float *xy,
float *yx,
float *yy)
{
const float mat[8][2][2] = {
[GDK_DIHEDRAL_NORMAL] = {
{ 1.0, 0.0 },
{ 0.0, 1.0 }
},
[GDK_DIHEDRAL_90] = {
{ 0.0, 1.0 },
{ -1.0, 0.0 }
},
[GDK_DIHEDRAL_180] = {
{ -1.0, 0.0 },
{ 0.0, -1.0 }
},
[GDK_DIHEDRAL_270] = {
{ 0.0, -1.0 },
{ 1.0, 0.0 }
},
[GDK_DIHEDRAL_FLIPPED] = {
{ -1.0, 0.0 },
{ 0.0, 1.0 }
},
[GDK_DIHEDRAL_FLIPPED_90] = {
{ 0.0, -1.0 },
{ -1.0, 0.0 }
},
[GDK_DIHEDRAL_FLIPPED_180] = {
{ 1.0, 0.0 },
{ 0.0, -1.0 }
},
[GDK_DIHEDRAL_FLIPPED_270] = {
{ 0.0, 1.0 },
{ 1.0, 0.0 }
},
};
*xx = mat[transform][0][0];
*xy = mat[transform][1][0];
*yx = mat[transform][0][1];
*yy = mat[transform][1][1];
}
GdkDihedral
gdk_dihedral_combine (GdkDihedral first,
GdkDihedral second)
{
return ((first & 4) ^ (second & 4)) |
((((first & 3) * (((second & 4) >> 1) + 1)) + second) & 3);
}
GdkDihedral
gdk_dihedral_invert (GdkDihedral self)
{
return ((4 - self) * (((self & 4) >> 1) + 1) & 3) | (self & 4);
}
gboolean
gdk_dihedral_swaps_xy (GdkDihedral self)
{
return (self & 1) ? TRUE : FALSE;
}
const char *
gdk_dihedral_get_name (GdkDihedral self)
{
const char *name[] = {
"normal", "90", "180", "270", "flipped", "flipped-90", "flipped-180", "flipped-270"
};
return name[self];
}

View File

@@ -1,49 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2024 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <glib.h>
G_BEGIN_DECLS
typedef enum {
GDK_DIHEDRAL_NORMAL,
GDK_DIHEDRAL_90,
GDK_DIHEDRAL_180,
GDK_DIHEDRAL_270,
GDK_DIHEDRAL_FLIPPED,
GDK_DIHEDRAL_FLIPPED_90,
GDK_DIHEDRAL_FLIPPED_180,
GDK_DIHEDRAL_FLIPPED_270,
} GdkDihedral;
void gdk_dihedral_get_mat2 (GdkDihedral transform,
float *xx,
float *xy,
float *yx,
float *yy);
GdkDihedral gdk_dihedral_combine (GdkDihedral first,
GdkDihedral second);
GdkDihedral gdk_dihedral_invert (GdkDihedral self);
gboolean gdk_dihedral_swaps_xy (GdkDihedral self);
const char * gdk_dihedral_get_name (GdkDihedral self);
G_END_DECLS

View File

@@ -1477,7 +1477,7 @@ gdk_display_create_gl_context (GdkDisplay *self,
if (!gdk_display_prepare_gl (self, error))
return NULL;
return gdk_gl_context_new (self, NULL, FALSE);
return gdk_gl_context_new (self, NULL);
}
/*< private >
@@ -1570,27 +1570,19 @@ describe_egl_config (EGLDisplay egl_display,
}
gpointer
gdk_display_get_egl_config (GdkDisplay *self,
GdkMemoryDepth depth)
gdk_display_get_egl_config (GdkDisplay *self)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
switch (depth)
{
case GDK_MEMORY_NONE:
case GDK_MEMORY_U8:
case GDK_MEMORY_U8_SRGB:
return priv->egl_config;
return priv->egl_config;
}
case GDK_MEMORY_U16:
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
return priv->egl_config_high_depth;
gpointer
gdk_display_get_egl_config_high_depth (GdkDisplay *self)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
case GDK_N_DEPTHS:
default:
g_return_val_if_reached (priv->egl_config);
}
return priv->egl_config_high_depth;
}
static EGLDisplay
@@ -1882,8 +1874,6 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
self->have_egl_dma_buf_export =
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
self->have_egl_gl_colorspace =
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_gl_colorspace");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,

View File

@@ -18,16 +18,15 @@
#pragma once
#include "gdkdisplay.h"
#include "gdksurface.h"
#include "gdkcursor.h"
#include "gdkdebugprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdmabufdownloaderprivate.h"
#include "gdkdmabufprivate.h"
#include "gdkkeysprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmonitor.h"
#include "gdkdebugprivate.h"
#include "gdksurfaceprivate.h"
#include "gdkkeysprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdmabufprivate.h"
#include "gdkdmabufdownloaderprivate.h"
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
@@ -45,9 +44,12 @@ typedef struct _GdkDisplayClass GdkDisplayClass;
typedef enum {
GDK_VULKAN_FEATURE_DMABUF = 1 << 0,
GDK_VULKAN_FEATURE_YCBCR = 1 << 1,
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 2,
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 3,
GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 4,
GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING = 1 << 2,
GDK_VULKAN_FEATURE_DYNAMIC_INDEXING = 1 << 3,
GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING = 1 << 4,
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 5,
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 6,
GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 7,
} GdkVulkanFeatures;
/* Tracks information about the device grab on this display */
@@ -128,7 +130,6 @@ struct _GdkDisplay
guint have_egl_pixel_format_float : 1;
guint have_egl_dma_buf_import : 1;
guint have_egl_dma_buf_export : 1;
guint have_egl_gl_colorspace : 1;
GdkDmabufFormats *dmabuf_formats;
GdkDmabufDownloader *dmabuf_downloaders[4];
@@ -246,8 +247,9 @@ gboolean gdk_display_init_egl (GdkDisplay *display
gboolean allow_any,
GError **error);
gpointer gdk_display_get_egl_display (GdkDisplay *display);
gpointer gdk_display_get_egl_config (GdkDisplay *display,
GdkMemoryDepth depth);
gpointer gdk_display_get_egl_config (GdkDisplay *display);
gpointer gdk_display_get_egl_config_high_depth
(GdkDisplay *display);
void gdk_display_set_rgba (GdkDisplay *display,
gboolean rgba);

View File

@@ -24,7 +24,6 @@
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkcolorstate.h"
#ifdef HAVE_DMABUF
#include <sys/mman.h>
@@ -72,7 +71,7 @@ download_memcpy (guchar *dst_data,
bpp = gdk_memory_format_bytes_per_pixel (dst_format);
src_stride = dmabuf->planes[0].stride;
src_data = src_datas[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + gdk_memory_format_min_buffer_size (dst_format, src_stride, width, height));
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + (height - 1) * dst_stride + width * bpp);
if (dst_stride == src_stride)
memcpy (dst_data, src_data, (height - 1) * dst_stride + width * bpp);
@@ -134,6 +133,49 @@ download_memcpy_3_1 (guchar *dst_data,
}
}
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static void
download_nv12 (guchar *dst_data,
gsize dst_stride,
@@ -184,95 +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_;
}
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
uv_data += uv_stride;
}
}
static void
download_p010 (guchar *dst,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
const guint16 *y_data, *uv_data;
guint16 *dst_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
guint16 SIZE;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_P010:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 10;
break;
case DRM_FORMAT_P012:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 12;
break;
case DRM_FORMAT_P016:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
SIZE = 16;
break;
default:
g_assert_not_reached ();
return;
}
y_stride = dmabuf->planes[0].stride / 2;
y_data = (const guint16 *) (src_data[0] + dmabuf->planes[0].offset);
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * dmabuf->planes[0].stride);
uv_stride = dmabuf->planes[1].stride / 2;
uv_data = (const guint16 *) (src_data[1] + dmabuf->planes[1].offset);
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * dmabuf->planes[1].stride);
dst_data = (guint16 *) dst;
dst_stride /= 2;
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
gsize xs, ys;
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);
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_;
}
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;
@@ -345,21 +306,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 +363,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;
@@ -1730,7 +1673,7 @@ static const GdkDrmFormatInfo supported_formats[] = {
.download = NULL,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
@@ -1739,10 +1682,10 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P010,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = NULL,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
@@ -1751,10 +1694,10 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P012,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = NULL,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
.format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
@@ -1763,10 +1706,10 @@ static const GdkDrmFormatInfo supported_formats[] = {
.fourcc = DRM_FORMAT_P016,
.memory_format = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.download = download_p010,
.download = NULL,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
.format = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
@@ -2085,8 +2028,8 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
if (gdk_dmabuf_ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
src_data[i] = mmap (NULL, sizes[i], PROT_READ, MAP_SHARED, dmabuf->planes[i].fd, 0);
if (src_data[i] == NULL || src_data[i] == MAP_FAILED)
src_data[i] = mmap (NULL, sizes[i], PROT_READ, MAP_SHARED, dmabuf->planes[i].fd, dmabuf->planes[i].offset);
if (src_data[i] == NULL)
{
g_warning ("Failed to mmap dmabuf: %s", g_strerror (errno));
goto out;
@@ -2094,14 +2037,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++)
@@ -2119,21 +2062,13 @@ out:
void
gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
GdkColorState *src_color_state = gdk_texture_get_color_state (texture);
if (format == src_format)
{
gdk_dmabuf_do_download_mmap (texture, data, stride);
gdk_memory_convert_color_state (data, stride, format,
src_color_state, color_state,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
gdk_dmabuf_do_download_mmap (texture, data, stride);
else
{
unsigned int width, height;
@@ -2148,8 +2083,8 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
gdk_memory_convert (data, stride, format, color_state,
src_data, src_stride, src_format, src_color_state,
gdk_memory_convert (data, stride, format,
src_data, src_stride, src_format,
width, height);
g_free (src_data);
@@ -2426,7 +2361,7 @@ gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
{
struct stat plane_stat;
if (fstat (dmabuf->planes[i].fd, &plane_stat) != 0)
if (fstat (dmabuf->planes[0].fd, &plane_stat) != 0)
return TRUE;
if (first_stat.st_ino != plane_stat.st_ino)
@@ -2437,20 +2372,3 @@ gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
}
#endif /* HAVE_DMABUF */
void
gdk_dmabuf_close_fds (GdkDmabuf *dmabuf)
{
guint i, j;
for (i = 0; i < dmabuf->n_planes; i++)
{
for (j = 0; j < i; j++)
{
if (dmabuf->planes[i].fd == dmabuf->planes[j].fd)
break;
}
if (i == j)
g_close (dmabuf->planes[i].fd, NULL);
}
}

View File

@@ -35,7 +35,6 @@ void
gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
@@ -44,6 +43,6 @@ gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
g_return_if_fail (GDK_IS_DMABUF_DOWNLOADER (self));
iface = GDK_DMABUF_DOWNLOADER_GET_IFACE (self);
iface->download (self, texture, format, color_state, data, stride);
iface->download (self, texture, format, data, stride);
}

View File

@@ -20,7 +20,6 @@ struct _GdkDmabufDownloaderInterface
void (* download) (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride);
};
@@ -32,7 +31,6 @@ gboolean gdk_dmabuf_downloader_supports (GdkDmabufDownlo
void gdk_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride);

View File

@@ -163,8 +163,6 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
return NULL;
previous = gdk_gl_context_get_current ();
if (previous)
g_object_ref (previous);
formats = gdk_dmabuf_formats_builder_new ();
external = gdk_dmabuf_formats_builder_new ();
@@ -196,10 +194,7 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display,
}
if (previous)
{
gdk_gl_context_make_current (previous);
g_object_unref (previous);
}
gdk_gl_context_make_current (previous);
return GDK_DMABUF_DOWNLOADER (renderer);
}
@@ -209,15 +204,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 +223,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 +236,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 +284,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 */

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 */

View File

@@ -207,8 +207,7 @@ gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
self->n_formats = n_formats;
self->formats = g_new (GdkDmabufFormat, n_formats);
if (n_formats != 0)
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
return self;
}

View File

@@ -55,6 +55,4 @@ GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
const GdkDmabufFormats *formats2);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref);
G_END_DECLS

View File

@@ -5,19 +5,11 @@
#include <drm_fourcc.h>
#endif
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
#ifndef fourcc_code
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
#endif
#ifndef DRM_FORMAT_INVALID
#define DRM_FORMAT_INVALID 0
#endif
#ifndef DRM_FORMAT_C1
#define DRM_FORMAT_C1 fourcc_code('C', '1', ' ', ' ')
#endif

View File

@@ -22,17 +22,15 @@ struct _GdkDmabuf
} planes[GDK_DMABUF_MAX_PLANES];
};
void gdk_dmabuf_close_fds (GdkDmabuf *dmabuf);
#ifdef HAVE_DMABUF
GdkDmabufFormats * gdk_dmabuf_get_mmap_formats (void) G_GNUC_CONST;
void gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride);
int gdk_dmabuf_ioctl (int fd,
unsigned long request,
void *arg);

View File

@@ -20,7 +20,6 @@
#include "gdkdmabuftextureprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdmabufdownloaderprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
@@ -63,13 +62,6 @@ struct _GdkDmabufTextureClass
GdkTextureClass parent_class;
};
/**
* gdk_dmabuf_error_quark:
*
* Registers an error quark for [class@Gdk.DmabufTexture] errors.
*
* Returns: the error quark
**/
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
@@ -97,7 +89,6 @@ struct _Download
{
GdkDmabufTexture *texture;
GdkMemoryFormat format;
GdkColorState *color_state;
guchar *data;
gsize stride;
volatile int spinlock;
@@ -111,7 +102,6 @@ gdk_dmabuf_texture_invoke_callback (gpointer data)
gdk_dmabuf_downloader_download (download->texture->downloader,
download->texture,
download->format,
download->color_state,
download->data,
download->stride);
@@ -123,17 +113,16 @@ gdk_dmabuf_texture_invoke_callback (gpointer data)
static void
gdk_dmabuf_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
Download download = { self, format, color_state, data, stride, 0 };
Download download = { self, format, data, stride, 0 };
if (self->downloader == NULL)
{
#ifdef HAVE_DMABUF
gdk_dmabuf_download_mmap (texture, format, color_state, data, stride);
gdk_dmabuf_download_mmap (texture, format, data, stride);
#endif
return;
}
@@ -182,7 +171,6 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GdkTexture *update_texture;
GdkDisplay *display;
GdkDmabuf dmabuf;
GdkColorState *color_state;
GError *local_error = NULL;
int width, height;
gboolean premultiplied;
@@ -202,21 +190,9 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
gdk_display_init_dmabuf (display);
color_state = gdk_dmabuf_texture_builder_get_color_state (builder);
if (color_state == NULL)
{
gboolean is_yuv;
if (gdk_dmabuf_fourcc_is_yuv (dmabuf.fourcc, &is_yuv) && is_yuv)
color_state = GDK_COLOR_STATE_YUV;
else
color_state = GDK_COLOR_STATE_SRGB;
}
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", width,
"height", height,
"color-state", color_state,
NULL);
g_set_object (&self->display, display);

View File

@@ -24,7 +24,6 @@
#include "gdkdebugprivate.h"
#include "gdkdisplay.h"
#include "gdkenumtypes.h"
#include "gdkcolorstate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdmabuftexturebuilderprivate.h"
@@ -42,8 +41,6 @@ struct _GdkDmabufTextureBuilder
GdkDmabuf dmabuf;
GdkColorState *color_state;
GdkTexture *update_texture;
cairo_region_t *update_region;
};
@@ -127,7 +124,6 @@ enum
PROP_MODIFIER,
PROP_PREMULTIPLIED,
PROP_N_PLANES,
PROP_COLOR_STATE,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
@@ -145,7 +141,6 @@ gdk_dmabuf_texture_builder_dispose (GObject *object)
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
G_OBJECT_CLASS (gdk_dmabuf_texture_builder_parent_class)->dispose (object);
}
@@ -188,10 +183,6 @@ gdk_dmabuf_texture_builder_get_property (GObject *object,
g_value_set_uint (value, self->dmabuf.n_planes);
break;
case PROP_COLOR_STATE:
g_value_set_boxed (value, self->color_state);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
@@ -244,10 +235,6 @@ gdk_dmabuf_texture_builder_set_property (GObject *object,
gdk_dmabuf_texture_builder_set_n_planes (self, g_value_get_uint (value));
break;
case PROP_COLOR_STATE:
gdk_dmabuf_texture_builder_set_color_state (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_REGION:
gdk_dmabuf_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
@@ -360,18 +347,6 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
1, GDK_DMABUF_MAX_PLANES, 1,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:color-state:
*
* The color state of the texture.
*
* Since: 4.16
*/
properties[PROP_COLOR_STATE] =
g_param_spec_boxed ("color-state", NULL, NULL,
GDK_TYPE_COLOR_STATE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_update_region org.gtk.Property.set=gdk_dmabuf_texture_builder_set_update_region)
*
@@ -408,8 +383,6 @@ gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self)
for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++)
self->dmabuf.planes[i].fd = -1;
self->color_state = NULL;
}
/**
@@ -870,55 +843,6 @@ gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
self->dmabuf.planes[plane].offset = offset;
}
/**
* gdk_dmabuf_texture_builder_get_color_state: (attributes org.gtk.Method.get_property=color-state)
* @self: a `GdkDmabufTextureBuilder`
*
* Gets the color state previously set via gdk_dmabuf_texture_builder_set_color_state().
*
* Returns: (nullable): the color state
*
* Since: 4.16
*/
GdkColorState *
gdk_dmabuf_texture_builder_get_color_state (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
return self->color_state;
}
/**
* gdk_dmabuf_texture_builder_set_color_state: (attributes org.gtk.Method.set_property=color-state)
* @self: a `GdkDmabufTextureBuilder`
* @color_state: (nullable): a `GdkColorState` or `NULL` to unset the colorstate.
*
* Sets the color state for the texture.
*
* By default, the colorstate is `NULL`. In that case, GTK will choose the
* correct colorstate based on the format.
* If you don't know what colorstates are, this is probably the right thing.
*
* Since: 4.16
*/
void
gdk_dmabuf_texture_builder_set_color_state (GdkDmabufTextureBuilder *self,
GdkColorState *color_state)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->color_state == color_state ||
(self->color_state != NULL && color_state != NULL && gdk_color_state_equal (self->color_state, color_state)))
return;
g_clear_pointer (&self->color_state, gdk_color_state_unref);
self->color_state = color_state;
if (color_state)
gdk_color_state_ref (color_state);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR_STATE]);
}
/**
* gdk_dmabuf_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
* @self: a `GdkDmabufTextureBuilder`

View File

@@ -100,12 +100,6 @@ void gdk_dmabuf_texture_builder_set_offset (GdkDmabufT
unsigned int plane,
unsigned int offset);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_dmabuf_texture_builder_get_color_state (GdkDmabufTextureBuilder *self);
GDK_AVAILABLE_IN_4_16
void gdk_dmabuf_texture_builder_set_color_state (GdkDmabufTextureBuilder *self,
GdkColorState *color_state);
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14

View File

@@ -48,8 +48,6 @@ struct _GdkDrawContextPrivate {
GdkSurface *surface;
cairo_region_t *frame_region;
GdkColorState *color_state;
GdkMemoryDepth depth;
};
enum {
@@ -203,12 +201,8 @@ static guint pixels_counter;
static void
gdk_draw_context_init (GdkDrawContext *self)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (self);
if (pixels_counter == 0)
pixels_counter = gdk_profiler_define_int_counter ("frame pixels", "Pixels drawn per frame");
priv->depth = GDK_N_DEPTHS;
}
/**
@@ -223,9 +217,6 @@ gdk_draw_context_init (GdkDrawContext *self)
*
* Returns: %TRUE if the context is between [method@Gdk.DrawContext.begin_frame]
* and [method@Gdk.DrawContext.end_frame] calls.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
gboolean
gdk_draw_context_is_in_frame (GdkDrawContext *context)
@@ -316,9 +307,6 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
* gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
* use of [GskRenderer](../gsk4/class.Renderer.html)s, so application code
* does not need to call these functions explicitly.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
void
gdk_draw_context_begin_frame (GdkDrawContext *context,
@@ -330,12 +318,11 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
g_return_if_fail (priv->surface != NULL);
g_return_if_fail (region != NULL);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region, NULL);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region);
}
/*
* @depth: best depth to render in
* @opaque: (nullable): opaque region of the rendering
*
* If the given depth is not `GDK_MEMORY_U8`, GDK will see about providing a
* rendering target that supports a higher bit depth than 8 bits per channel.
@@ -358,10 +345,9 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
* to choose.
*/
void
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque)
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
@@ -386,23 +372,13 @@ gdk_draw_context_begin_frame_full (GdkDrawContext *context,
return;
}
gdk_surface_set_opaque_rect (priv->surface, opaque);
if (gdk_display_get_debug_flags (priv->display) & GDK_DEBUG_HIGH_DEPTH)
depth = GDK_MEMORY_FLOAT32;
priv->frame_region = cairo_region_copy (region);
priv->surface->paint_context = g_object_ref (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context,
depth,
priv->frame_region,
&priv->color_state,
&priv->depth);
/* the callback is meant to set them */
g_assert (priv->color_state != NULL);
g_assert (priv->depth < GDK_N_DEPTHS);
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, depth, priv->frame_region);
cairo_region_intersect_rectangle (priv->frame_region,
&(cairo_rectangle_int_t) {
@@ -430,21 +406,6 @@ region_get_pixels (cairo_region_t *region)
}
#endif
void
gdk_draw_context_end_frame_full (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
g_clear_pointer (&priv->color_state, gdk_color_state_unref);
g_clear_pointer (&priv->frame_region, cairo_region_destroy);
g_clear_object (&priv->surface->paint_context);
priv->depth = GDK_N_DEPTHS;
}
/**
* gdk_draw_context_end_frame:
* @context: a `GdkDrawContext`
@@ -457,9 +418,6 @@ gdk_draw_context_end_frame_full (GdkDrawContext *context)
* When using a [class@Gdk.GLContext], this function may call `glFlush()`
* implicitly before returning; it is not recommended to call `glFlush()`
* explicitly before calling this function.
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
void
gdk_draw_context_end_frame (GdkDrawContext *context)
@@ -487,7 +445,12 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
return;
}
gdk_draw_context_end_frame_full (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
g_clear_pointer (&priv->frame_region, cairo_region_destroy);
g_clear_object (&priv->surface->paint_context);
}
/**
@@ -504,56 +467,15 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
* and [method@Gdk.DrawContext.end_frame], %NULL will be returned.
*
* Returns: (transfer none) (nullable): a Cairo region
*
* Deprecated: 4.16: Drawing directly to the surface is no longer recommended.
* Use `GskRenderNode` and `GskRenderer`.
*/
const cairo_region_t *
_gdk_draw_context_get_frame_region (GdkDrawContext *context)
gdk_draw_context_get_frame_region (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
return priv->frame_region;
}
const cairo_region_t *
(gdk_draw_context_get_frame_region) (GdkDrawContext *context)
{
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
return _gdk_draw_context_get_frame_region (context);
}
/*<private>
* gdk_draw_context_get_color_state:
* @self: a `GdkDrawContext`
*
* Gets the target color state while rendering. If no rendering is going on, %NULL is returned.
*
* Returns: (transfer none) (nullable): the target color state
**/
GdkColorState *
gdk_draw_context_get_color_state (GdkDrawContext *self)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (self);
return priv->color_state;
}
/*<private>
* gdk_draw_context_get_depth:
* @self: a `GdkDrawContext`
*
* Gets the target depth while rendering. If no rendering is going on, the return value is undefined.
*
* Returns: the target depth
**/
GdkMemoryDepth
gdk_draw_context_get_depth (GdkDrawContext *self)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (self);
return priv->depth;
return priv->frame_region;
}
void

View File

@@ -40,15 +40,15 @@ GdkDisplay * gdk_draw_context_get_display (GdkDrawContext
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_draw_context_get_surface (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
void gdk_draw_context_begin_frame (GdkDrawContext *context,
const cairo_region_t *region);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
void gdk_draw_context_end_frame (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
gboolean gdk_draw_context_is_in_frame (GdkDrawContext *context);
GDK_DEPRECATED_IN_4_16
GDK_AVAILABLE_IN_ALL
const cairo_region_t * gdk_draw_context_get_frame_region (GdkDrawContext *context);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrawContext, g_object_unref)

View File

@@ -22,11 +22,8 @@
#include "gdkdrawcontext.h"
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include <graphene.h>
G_BEGIN_DECLS
#define GDK_DRAW_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAW_CONTEXT, GdkDrawContextClass))
@@ -46,9 +43,7 @@ struct _GdkDrawContextClass
void (* begin_frame) (GdkDrawContext *context,
GdkMemoryDepth depth,
cairo_region_t *update_area,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth);
cairo_region_t *update_area);
void (* end_frame) (GdkDrawContext *context,
cairo_region_t *painted);
void (* empty_frame) (GdkDrawContext *context);
@@ -59,17 +54,10 @@ void gdk_draw_context_surface_resized (GdkDrawContext
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region,
const graphene_rect_t *opaque);
void gdk_draw_context_end_frame_full (GdkDrawContext *context);
const cairo_region_t *region);
void gdk_draw_context_empty_frame (GdkDrawContext *context);
#define gdk_draw_context_get_frame_region(...) _gdk_draw_context_get_frame_region(__VA_ARGS__)
const cairo_region_t * _gdk_draw_context_get_frame_region (GdkDrawContext *self);
GdkColorState * gdk_draw_context_get_color_state (GdkDrawContext *self);
GdkMemoryDepth gdk_draw_context_get_depth (GdkDrawContext *self);
G_END_DECLS

View File

@@ -134,7 +134,7 @@ gdk_drop_read_local_async (GdkDrop *self,
g_object_get (priv->drag, "content", &content, NULL);
content_formats = gdk_content_provider_ref_formats (content);
g_object_unref (content);
g_object_unref (content);
content_formats = gdk_content_formats_union_serialize_mime_types (content_formats);
mime_type = gdk_content_formats_match_mime_type (content_formats, formats);
@@ -651,9 +651,9 @@ gdk_drop_read_internal (GdkDrop *self,
* pointer to an array of mime types
* @io_priority: the I/O priority for the read operation
* @cancellable: (nullable): optional `GCancellable` object
* @callback: (scope async) (closure user_data): a `GAsyncReadyCallback` to call when
* @callback: (scope async): a `GAsyncReadyCallback` to call when
* the request is satisfied
* @user_data: the data to pass to @callback
* @user_data: (closure): the data to pass to @callback
*
* Asynchronously read the dropped data from a `GdkDrop`
* in a format that complies with one of the mime types.
@@ -784,7 +784,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
GdkContentFormats *formats;
GValue *value;
GTask *task;
g_return_if_fail (priv->state != GDK_DROP_STATE_FINISHED);
task = g_task_new (self, cancellable, callback, user_data);
@@ -843,12 +843,16 @@ gdk_drop_read_value_internal (GdkDrop *self,
* @type: a `GType` to read
* @io_priority: the I/O priority of the request.
* @cancellable: (nullable): optional `GCancellable` object, %NULL to ignore.
* @callback: (scope async) (closure user_data): callback to call when the request is satisfied
* @user_data: the data to pass to callback function
* @callback: (scope async): callback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
* Asynchronously request the drag operation's contents converted
* to the given @type.
*
* When the operation is finished @callback will be called. You must
* then call [method@Gdk.Drop.read_value_finish] to get the resulting
* `GValue`.
*
* For local drag-and-drop operations that are available in the given
* `GType`, the value will be copied directly. Otherwise, GDK will
* try to use [func@Gdk.content_deserialize_async] to convert the data.

View File

@@ -98,9 +98,9 @@ typedef enum
* @GDK_BUTTON3_MASK: the third mouse button.
* @GDK_BUTTON4_MASK: the fourth mouse button.
* @GDK_BUTTON5_MASK: the fifth mouse button.
* @GDK_SUPER_MASK: the Super modifier.
* @GDK_HYPER_MASK: the Hyper modifier.
* @GDK_META_MASK: the Meta modifier. Maps to Command on macOS.
* @GDK_SUPER_MASK: the Super modifier
* @GDK_HYPER_MASK: the Hyper modifier
* @GDK_META_MASK: the Meta modifier
*
* Flags to indicate the state of modifier keys and mouse buttons
* in events.

View File

@@ -1371,8 +1371,6 @@ gdk_event_get_modifier_state (GdkEvent *event)
* Extract the event surface relative x/y coordinates from an event.
*
* This position is in [surface coordinates](coordinates.html).
*
* Returns: whether the positions were set
*/
gboolean
gdk_event_get_position (GdkEvent *event,

View File

@@ -192,6 +192,13 @@ compute_smooth_frame_time (GdkFrameClock *clock,
* and new_frame_time >= old_frame_time. */
frames_passed = (new_frame_time - smoothed_frame_time_base + frame_interval / 2) / frame_interval;
if (frames_passed > 1)
gdk_profiler_add_markf ((smoothed_frame_time_base - (frame_interval * (frames_passed-1))) * 1000L,
frame_interval * (frames_passed-1) * 1000L,
"Dropped Frames",
"%u frames may have been dropped",
frames_passed-1);
/* We use an approximately whole number of frames in the future from
* last smoothed frame time. This way we avoid minor jitter in the
* frame times making the animation speed uneven, but still animate

View File

@@ -122,7 +122,6 @@ struct _GdkGLContextPrivate
GdkGLMemoryFlags memory_flags[GDK_MEMORY_N_FORMATS];
GdkGLFeatures features;
guint surface_attached : 1;
guint use_khr_debug : 1;
guint has_debug_output : 1;
guint extensions_checked : 1;
@@ -153,13 +152,6 @@ enum {
static GParamSpec *properties[LAST_PROP] = { NULL, };
/**
* gdk_gl_error_quark:
*
* Registers an error quark for [class@Gdk.GLContext] errors.
*
* Returns: the error quark
**/
G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW_CONTEXT)
@@ -330,7 +322,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
if (display->have_egl_no_config_context)
egl_config = NULL;
else
egl_config = gdk_display_get_egl_config (display, GDK_MEMORY_U8);
egl_config = gdk_display_get_egl_config (display);
if (debug_bit)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
@@ -610,41 +602,24 @@ gdk_gl_context_get_scale (GdkGLContext *self)
}
static void
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
G_GNUC_UNUSED GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
GdkColorState *color_state;
GdkSurface *surface;
cairo_region_t *damage;
double scale;
int ww, wh;
int i;
color_state = gdk_surface_get_color_state (surface);
surface = gdk_draw_context_get_surface (draw_context);
scale = gdk_gl_context_get_scale (context);
depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (color_state));
g_assert (depth != GDK_MEMORY_U8_SRGB || gdk_color_state_get_no_srgb_tf (color_state) != NULL);
#ifdef HAVE_EGL
if (priv->egl_context)
*out_depth = gdk_surface_ensure_egl_surface (surface, depth);
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;
#else
*out_color_state = gdk_color_state_get_srgb ();
*out_depth = GDK_MEMORY_U8;
gdk_surface_ensure_egl_surface (surface, depth != GDK_MEMORY_U8);
#endif
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
@@ -830,28 +805,20 @@ gdk_gl_context_init (GdkGLContext *self)
/* Must have called gdk_display_prepare_gl() before */
GdkGLContext *
gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface,
gboolean surface_attached)
GdkSurface *surface)
{
GdkGLContextPrivate *priv;
GdkGLContext *shared, *result;
GdkGLContext *shared;
g_assert (surface == NULL || display == gdk_surface_get_display (surface));
g_assert (!surface_attached || surface != NULL);
/* assert gdk_display_prepare_gl() had been called */
shared = gdk_display_get_gl_context (display);
g_assert (shared);
result = g_object_new (G_OBJECT_TYPE (shared),
"display", display,
"surface", surface,
NULL);
priv = gdk_gl_context_get_instance_private (result);
priv->surface_attached = surface_attached;
return result;
return g_object_new (G_OBJECT_TYPE (shared),
"display", display,
"surface", surface,
NULL);
}
void
@@ -1834,22 +1801,12 @@ gdk_gl_context_check_is_current (GdkGLContext *context)
void
gdk_gl_context_make_current (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
MaskedContext *current, *masked_context;
gboolean surfaceless;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (priv->surface_attached)
{
surfaceless = FALSE;
}
else
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
G_GNUC_END_IGNORE_DEPRECATIONS
}
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
masked_context = mask_context (context, surfaceless);
current = g_private_get (&thread_current_context);
@@ -1999,6 +1956,8 @@ gdk_gl_context_get_glsl_version_string (GdkGLContext *self)
return "#version 310 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else
return "#version 100";
}
@@ -2198,8 +2157,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
int target)
{
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
@@ -2211,8 +2168,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
width,
height,
dmabuf,
color_space_hint,
range_hint,
target);
if (image == EGL_NO_IMAGE)
return 0;
@@ -2236,8 +2191,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
gboolean *external)
{
GdkDisplay *display = gdk_gl_context_get_display (self);
@@ -2254,8 +2207,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
color_space_hint,
range_hint,
GL_TEXTURE_2D);
if (texture_id == 0)
{
@@ -2285,8 +2236,6 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
color_space_hint,
range_hint,
GL_TEXTURE_EXTERNAL_OES);
if (texture_id == 0)
{
@@ -2319,8 +2268,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)

View File

@@ -122,9 +122,8 @@ void gdk_gl_backend_use (GdkGLBackend
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface,
gboolean surface_attached);
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
@@ -185,8 +184,6 @@ guint gdk_gl_context_import_dmabuf (GdkGLContext
int width,
int height,
const GdkDmabuf *dmabuf,
int color_space_hint,
int range_hint,
gboolean *external);
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,

View File

@@ -20,7 +20,6 @@
#include "gdkgltextureprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkglcontextprivate.h"
#include "gdkmemoryformatprivate.h"
@@ -137,7 +136,6 @@ typedef struct _Download Download;
struct _Download
{
GdkMemoryFormat format;
GdkColorState *color_state;
guchar *data;
gsize stride;
};
@@ -153,7 +151,7 @@ gdk_gl_texture_find_format (GdkGLContext *context,
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
{
GLint q_internal_format, q_internal_srgb_format;
GLint q_internal_format;
GLenum q_format, q_type;
GLint q_swizzle[4];
@@ -166,7 +164,6 @@ gdk_gl_texture_find_format (GdkGLContext *context,
gdk_memory_format_gl_format (format,
gdk_gl_context_get_use_es (context),
&q_internal_format,
&q_internal_srgb_format,
&q_format,
&q_type,
q_swizzle);
@@ -190,7 +187,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
GdkMemoryFormat format;
gsize expected_stride;
Download *download = download_;
GLint gl_internal_format, gl_internal_srgb_format;
GLint gl_internal_format;
GLenum gl_format, gl_type;
GLint gl_swizzle[4];
@@ -202,7 +199,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
{
gdk_memory_format_gl_format (format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_internal_format,
&gl_format, &gl_type, gl_swizzle);
if (download->stride == expected_stride &&
download->format == format)
@@ -212,14 +209,6 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gl_format,
gl_type,
download->data);
gdk_memory_convert_color_state (download->data,
download->stride,
download->format,
download->color_state,
texture->color_state,
texture->width,
texture->height);
}
else
{
@@ -236,15 +225,14 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gdk_memory_convert (download->data,
download->stride,
download->format,
download->color_state,
pixels,
stride,
format,
texture->color_state,
texture->width,
texture->height);
g_free (pixels);
}
}
else
@@ -268,25 +256,25 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_internal_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_internal_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
@@ -298,14 +286,6 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gl_read_format,
gl_read_type,
download->data);
gdk_memory_convert_color_state (download->data,
download->stride,
download->format,
download->color_state,
texture->color_state,
texture->width,
texture->height);
}
else
{
@@ -397,11 +377,9 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gdk_memory_convert (download->data,
download->stride,
download->format,
download->color_state,
pixels,
stride,
actual_format,
texture->color_state,
texture->width,
texture->height);
@@ -415,7 +393,6 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
static void
gdk_gl_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
@@ -424,12 +401,11 @@ gdk_gl_texture_download (GdkTexture *texture,
if (self->saved)
{
gdk_texture_do_download (self->saved, format, color_state, data, stride);
gdk_texture_do_download (self->saved, format, data, stride);
return;
}
download.format = format;
download.color_state = color_state;
download.data = data;
download.stride = stride;
@@ -495,7 +471,8 @@ gdk_gl_texture_release (GdkGLTexture *self)
g_return_if_fail (self->saved == NULL);
texture = GDK_TEXTURE (self);
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture));
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
gdk_texture_get_format (texture)));
drop_gl_resources (self);
}
@@ -511,7 +488,6 @@ gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", gdk_gl_texture_builder_get_width (builder),
"height", gdk_gl_texture_builder_get_height (builder),
"color-state", gdk_gl_texture_builder_get_color_state (builder),
NULL);
self->context = g_object_ref (gdk_gl_texture_builder_get_context (builder));
@@ -706,7 +682,6 @@ gdk_gl_texture_new (GdkGLContext *context,
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", width,
"height", height,
"color-state", GDK_COLOR_STATE_SRGB,
NULL);
self->context = g_object_ref (context);

View File

@@ -23,7 +23,6 @@
#include "gdkenumtypes.h"
#include "gdkglcontext.h"
#include "gdkcolorstate.h"
#include "gdkgltextureprivate.h"
#include <cairo-gobject.h>
@@ -39,7 +38,6 @@ struct _GdkGLTextureBuilder
GdkMemoryFormat format;
gboolean has_mipmap;
gpointer sync;
GdkColorState *color_state;
GdkTexture *update_texture;
cairo_region_t *update_region;
@@ -77,7 +75,6 @@ enum
PROP_HEIGHT,
PROP_ID,
PROP_SYNC,
PROP_COLOR_STATE,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
PROP_WIDTH,
@@ -98,7 +95,6 @@ gdk_gl_texture_builder_dispose (GObject *object)
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
G_OBJECT_CLASS (gdk_gl_texture_builder_parent_class)->dispose (object);
}
@@ -137,10 +133,6 @@ gdk_gl_texture_builder_get_property (GObject *object,
g_value_set_pointer (value, self->sync);
break;
case PROP_COLOR_STATE:
g_value_set_boxed (value, self->color_state);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
@@ -193,10 +185,6 @@ gdk_gl_texture_builder_set_property (GObject *object,
gdk_gl_texture_builder_set_sync (self, g_value_get_pointer (value));
break;
case PROP_COLOR_STATE:
gdk_gl_texture_builder_set_color_state (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_REGION:
gdk_gl_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
@@ -298,18 +286,6 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
g_param_spec_pointer ("sync", NULL, NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:color-state:
*
* The color state of the texture.
*
* Since: 4.16
*/
properties[PROP_COLOR_STATE] =
g_param_spec_boxed ("color-state", NULL, NULL,
GDK_TYPE_COLOR_STATE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_region org.gtk.Property.set=gdk_gl_texture_builder_set_update_region)
*
@@ -353,7 +329,6 @@ static void
gdk_gl_texture_builder_init (GdkGLTextureBuilder *self)
{
self->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
self->color_state = gdk_color_state_ref (gdk_color_state_get_srgb ());
}
/**
@@ -393,7 +368,7 @@ gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
/**
* gdk_gl_texture_builder_set_context: (attributes org.gtk.Method.set_property=context)
* @self: a `GdkGLTextureBuilder`
* @context: (nullable): The context the texture belongs to or %NULL to unset
* @context: (nullable): The context the texture beongs to or %NULL to unset
*
* Sets the context to be used for the texture. This is the context that owns
* the texture.
@@ -641,51 +616,6 @@ gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYNC]);
}
/**
* gdk_gl_texture_builder_get_color_state: (attributes org.gtk.Method.get_property=color-state)
* @self: a `GdkGLTextureBuilder`
*
* Gets the color state previously set via gdk_gl_texture_builder_set_color_state().
*
* Returns: the color state
*
* Since: 4.16
*/
GdkColorState *
gdk_gl_texture_builder_get_color_state (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->color_state;
}
/**
* gdk_gl_texture_builder_set_color_state: (attributes org.gtk.Method.set_property=color-state)
* @self: a `GdkGLTextureBuilder`
* @color_state: a `GdkColorState`
*
* Sets the color state for the texture.
*
* By default, the sRGB colorstate is used. If you don't know what
* colorstates are, this is probably the right thing.
*
* Since: 4.16
*/
void
gdk_gl_texture_builder_set_color_state (GdkGLTextureBuilder *self,
GdkColorState *color_state)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
g_return_if_fail (color_state != NULL);
if (gdk_color_state_equal (self->color_state, color_state))
return;
g_clear_pointer (&self->color_state, gdk_color_state_unref);
self->color_state = gdk_color_state_ref (color_state);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR_STATE]);
}
/**
* gdk_gl_texture_builder_get_format: (attributes org.gtk.Method.get_property=format)
* @self: a `GdkGLTextureBuilder`

View File

@@ -76,12 +76,6 @@ GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
gpointer sync);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_gl_texture_builder_get_color_state (GdkGLTextureBuilder *self);
GDK_AVAILABLE_IN_4_16
void gdk_gl_texture_builder_set_color_state (GdkGLTextureBuilder *self,
GdkColorState *color_state);
GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12

File diff suppressed because it is too large Load Diff

View File

@@ -37,40 +37,26 @@ typedef enum {
} GdkMemoryAlpha;
typedef enum {
GDK_MEMORY_NONE,
GDK_MEMORY_U8,
GDK_MEMORY_U8_SRGB,
GDK_MEMORY_U16,
GDK_MEMORY_FLOAT16,
GDK_MEMORY_FLOAT32,
GDK_N_DEPTHS
GDK_MEMORY_FLOAT32
} GdkMemoryDepth;
#define GDK_MEMORY_DEPTH_BITS 3
gsize gdk_memory_format_alignment (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryAlpha gdk_memory_format_alpha (GdkMemoryFormat format) G_GNUC_CONST;
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_format_get_premultiplied (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_format_get_straight (GdkMemoryFormat format) G_GNUC_CONST;
const GdkMemoryFormat * gdk_memory_format_get_fallbacks (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format,
gboolean srgb) G_GNUC_CONST;
gsize gdk_memory_format_min_buffer_size (GdkMemoryFormat format,
gsize stride,
gsize width,
gsize height) G_GNUC_CONST;
gboolean gdk_memory_depth_is_srgb (GdkMemoryDepth depth) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth depth1,
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,
GLint *out_internal_srgb_format,
GLenum *out_format,
GLenum *out_type,
GLint out_swizzle[4]);
@@ -78,36 +64,25 @@ gboolean gdk_memory_format_gl_rgba_format (GdkMemoryFormat
gboolean gles,
GdkMemoryFormat *out_actual_format,
GLint *out_internal_format,
GLint *out_internal_srgb_format,
GLenum *out_format,
GLenum *out_type,
GLint out_swizzle[4]);
#ifdef GDK_RENDERING_VULKAN
VkFormat gdk_memory_format_vk_format (GdkMemoryFormat format,
VkComponentMapping *out_swizzle);
VkFormat gdk_memory_format_vk_srgb_format (GdkMemoryFormat format);
VkFormat gdk_memory_format_vk_rgba_format (GdkMemoryFormat format,
GdkMemoryFormat *out_rgba_format,
VkComponentMapping *out_swizzle);
#endif
guint32 gdk_memory_format_get_dmabuf_fourcc (GdkMemoryFormat format);
const char * gdk_memory_format_get_name (GdkMemoryFormat format);
void gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
GdkColorState *src_cs,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
GdkColorState *dest_cs,
gsize width,
gsize height);
void gdk_memory_convert_color_state (guchar *data,
gsize stride,
GdkMemoryFormat format,
GdkColorState *src_color_state,
GdkColorState *dest_color_state,
gsize width,
gsize height);

View File

@@ -21,8 +21,8 @@
#include "gdkmemorytextureprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gsk/gl/fp16private.h"
/**
* GdkMemoryTexture:
@@ -58,7 +58,6 @@ gdk_memory_texture_dispose (GObject *object)
static void
gdk_memory_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
@@ -66,11 +65,9 @@ gdk_memory_texture_download (GdkTexture *texture,
gdk_memory_convert (data, stride,
format,
color_state,
(guchar *) g_bytes_get_data (self->bytes, NULL),
self->stride,
texture->format,
texture->color_state,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
@@ -126,46 +123,6 @@ gdk_memory_sanitize (GBytes *bytes,
return g_bytes_new_take (copy, copy_stride * height);
}
GdkTexture *
gdk_memory_texture_new_from_builder (GdkMemoryTextureBuilder *builder)
{
GdkMemoryTexture *self;
GdkTexture *texture, *update_texture;
self = g_object_new (GDK_TYPE_MEMORY_TEXTURE,
"width", gdk_memory_texture_builder_get_width (builder),
"height", gdk_memory_texture_builder_get_height (builder),
"color-state", gdk_memory_texture_builder_get_color_state (builder),
NULL);
texture = GDK_TEXTURE (self);
texture->format = gdk_memory_texture_builder_get_format (builder);
self->bytes = gdk_memory_sanitize (g_bytes_ref (gdk_memory_texture_builder_get_bytes (builder)),
texture->width,
texture->height,
texture->format,
gdk_memory_texture_builder_get_stride (builder),
&self->stride);
update_texture = gdk_memory_texture_builder_get_update_texture (builder);
if (update_texture)
{
cairo_region_t *update_region = gdk_memory_texture_builder_get_update_region (builder);
if (update_region)
{
update_region = cairo_region_copy (update_region);
cairo_region_intersect_rectangle (update_region,
&(cairo_rectangle_int_t) {
0, 0,
update_texture->width, update_texture->height
});
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
}
}
return GDK_TEXTURE (self);
}
/**
* gdk_memory_texture_new:
* @width: the width of the texture
@@ -195,14 +152,13 @@ gdk_memory_texture_new (int width,
g_return_val_if_fail (bytes != NULL, NULL);
g_return_val_if_fail (stride >= width * gdk_memory_format_bytes_per_pixel (format), NULL);
/* needs to be this complex to support subtexture of the bottom right part */
g_return_val_if_fail (g_bytes_get_size (bytes) >= gdk_memory_format_min_buffer_size (format, stride, width, height), NULL);
g_return_val_if_fail (g_bytes_get_size (bytes) >= stride * (height - 1) + width * gdk_memory_format_bytes_per_pixel (format), NULL);
bytes = gdk_memory_sanitize (bytes, width, height, format, stride, &stride);
self = g_object_new (GDK_TYPE_MEMORY_TEXTURE,
"width", width,
"height", height,
"color-state", GDK_COLOR_STATE_SRGB,
NULL);
GDK_TEXTURE (self)->format = format;
@@ -220,7 +176,7 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
int height)
{
GdkTexture *texture, *result;
gsize offset, size;
gsize bpp, offset, size;
GBytes *bytes;
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
@@ -230,8 +186,9 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
texture = GDK_TEXTURE (source);
offset = y * source->stride + x * gdk_memory_format_bytes_per_pixel (texture->format);
size = gdk_memory_format_min_buffer_size (texture->format, source->stride, width, height);
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
offset = y * source->stride + x * bpp;
size = source->stride * (height - 1) + width * bpp;
bytes = g_bytes_new_from_bytes (source->bytes, offset, size);
result = gdk_memory_texture_new (width,
@@ -245,7 +202,8 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
}
GdkMemoryTexture *
gdk_memory_texture_from_texture (GdkTexture *texture)
gdk_memory_texture_from_texture (GdkTexture *texture,
GdkMemoryFormat format)
{
GdkTexture *result;
GBytes *bytes;
@@ -255,16 +213,21 @@ gdk_memory_texture_from_texture (GdkTexture *texture)
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
if (GDK_IS_MEMORY_TEXTURE (texture))
return g_object_ref (GDK_MEMORY_TEXTURE (texture));
{
GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (texture);
stride = texture->width * gdk_memory_format_bytes_per_pixel (texture->format);
if (gdk_texture_get_format (texture) == format)
return g_object_ref (memtex);
}
stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
data = g_malloc_n (stride, texture->height);
gdk_texture_do_download (texture, texture->format, texture->color_state, data, stride);
gdk_texture_do_download (texture, format, data, stride);
bytes = g_bytes_new_take (data, stride * texture->height);
result = gdk_memory_texture_new (texture->width,
texture->height,
texture->format,
format,
bytes,
stride);
g_bytes_unref (bytes);

View File

@@ -1,729 +0,0 @@
/*
* Copyright © 2024 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.1 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/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gdkmemorytexturebuilder.h"
#include "gdkcolorstate.h"
#include "gdkenumtypes.h"
#include "gdkmemorytextureprivate.h"
#include <cairo-gobject.h>
struct _GdkMemoryTextureBuilder
{
GObject parent_instance;
GBytes *bytes;
gsize stride;
int width;
int height;
GdkMemoryFormat format;
GdkColorState *color_state;
GdkTexture *update_texture;
cairo_region_t *update_region;
};
struct _GdkMemoryTextureBuilderClass
{
GObjectClass parent_class;
};
/**
* GdkMemoryTextureBuilder:
*
* `GdkMemoryTextureBuilder` is a builder used to construct [class@Gdk.Texture] objects
* from system memory provided via [struct@GLib.Bytes].
*
* The operation is quite simple: Create a texture builder, set all the necessary
* properties - keep in mind that the properties [property@Gdk.MemoryTextureBuilder:bytes],
* [property@Gdk.MemoryTextureBuilder:stride], [property@Gdk.MemoryTextureBuilder:width],
* and [property@Gdk.MemoryTextureBuilder:height] are mandatory - and then call
* [method@Gdk.MemoryTextureBuilder.build] to create the new texture.
*
* `GdkMemoryTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures.
*
* Since: 4.16
*/
enum
{
PROP_0,
PROP_BYTES,
PROP_COLOR_STATE,
PROP_FORMAT,
PROP_HEIGHT,
PROP_STRIDE,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
PROP_WIDTH,
N_PROPS
};
G_DEFINE_TYPE (GdkMemoryTextureBuilder, gdk_memory_texture_builder, G_TYPE_OBJECT)
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gdk_memory_texture_builder_dispose (GObject *object)
{
GdkMemoryTextureBuilder *self = GDK_MEMORY_TEXTURE_BUILDER (object);
g_clear_pointer (&self->bytes, g_bytes_unref);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
G_OBJECT_CLASS (gdk_memory_texture_builder_parent_class)->dispose (object);
}
static void
gdk_memory_texture_builder_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GdkMemoryTextureBuilder *self = GDK_MEMORY_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_BYTES:
g_value_set_boxed (value, self->bytes);
break;
case PROP_COLOR_STATE:
g_value_set_boxed (value, self->color_state);
break;
case PROP_FORMAT:
g_value_set_enum (value, self->format);
break;
case PROP_HEIGHT:
g_value_set_int (value, self->height);
break;
case PROP_STRIDE:
g_value_set_uint64 (value, self->stride);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
case PROP_UPDATE_TEXTURE:
g_value_set_object (value, self->update_texture);
break;
case PROP_WIDTH:
g_value_set_int (value, self->width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_memory_texture_builder_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GdkMemoryTextureBuilder *self = GDK_MEMORY_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_BYTES:
gdk_memory_texture_builder_set_bytes (self, g_value_get_boxed (value));
break;
case PROP_COLOR_STATE:
gdk_memory_texture_builder_set_color_state (self, g_value_get_boxed (value));
break;
case PROP_FORMAT:
gdk_memory_texture_builder_set_format (self, g_value_get_enum (value));
break;
case PROP_HEIGHT:
gdk_memory_texture_builder_set_height (self, g_value_get_int (value));
break;
case PROP_STRIDE:
gdk_memory_texture_builder_set_stride (self, g_value_get_uint64 (value));
break;
case PROP_UPDATE_REGION:
gdk_memory_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_TEXTURE:
gdk_memory_texture_builder_set_update_texture (self, g_value_get_object (value));
break;
case PROP_WIDTH:
gdk_memory_texture_builder_set_width (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_memory_texture_builder_class_init (GdkMemoryTextureBuilderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gdk_memory_texture_builder_dispose;
gobject_class->get_property = gdk_memory_texture_builder_get_property;
gobject_class->set_property = gdk_memory_texture_builder_set_property;
/**
* GdkMemoryTextureBuilder:bytes:
*
* The bytes holding the data.
*
* Since: 4.16
*/
properties[PROP_BYTES] =
g_param_spec_boxed ("bytes", NULL, NULL,
G_TYPE_BYTES,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:color-state:
*
* The colorstate describing the data.
*
* Since: 4.16
*/
properties[PROP_COLOR_STATE] =
g_param_spec_boxed ("color-state", NULL, NULL,
GDK_TYPE_COLOR_STATE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:format:
*
* The format of the data.
*
* Since: 4.16
*/
properties[PROP_FORMAT] =
g_param_spec_enum ("format", NULL, NULL,
GDK_TYPE_MEMORY_FORMAT,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:height:
*
* The height of the texture.
*
* Since: 4.16
*/
properties[PROP_HEIGHT] =
g_param_spec_int ("height", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:stride:
*
* The rowstride of the texture.
*
* The rowstride is the number of bytes between the first pixel
* in a row of image data, and the first pixel in the next row.
*
* Since: 4.16
*/
properties[PROP_STRIDE] =
g_param_spec_uint64 ("stride", NULL, NULL,
0, G_MAXUINT64, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:update-region:
*
* The update region for [property@Gdk.MemoryTextureBuilder:update-texture].
*
* Since: 4.16
*/
properties[PROP_UPDATE_REGION] =
g_param_spec_boxed ("update-region", NULL, NULL,
CAIRO_GOBJECT_TYPE_REGION,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:update-texture:
*
* The texture [property@Gdk.MemoryTextureBuilder:update-region] is an update for.
*
* Since: 4.16
*/
properties[PROP_UPDATE_TEXTURE] =
g_param_spec_object ("update-texture", NULL, NULL,
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkMemoryTextureBuilder:width:
*
* The width of the texture.
*
* Since: 4.16
*/
properties[PROP_WIDTH] =
g_param_spec_int ("width", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gdk_memory_texture_builder_init (GdkMemoryTextureBuilder *self)
{
self->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
self->color_state = gdk_color_state_ref (gdk_color_state_get_srgb ());
}
/**
* gdk_memory_texture_builder_new: (constructor):
*
* Creates a new texture builder.
*
* Returns: the new `GdkTextureBuilder`
*
* Since: 4.16
**/
GdkMemoryTextureBuilder *
gdk_memory_texture_builder_new (void)
{
return g_object_new (GDK_TYPE_MEMORY_TEXTURE_BUILDER, NULL);
}
/**
* gdk_memory_texture_builder_get_bytes:
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the bytes previously set via gdk_memory_texture_builder_set_bytes()
* or %NULL if none was set.
*
* Returns: (transfer none) (nullable): The bytes
*
* Since: 4.16
*/
GBytes *
gdk_memory_texture_builder_get_bytes (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), NULL);
return self->bytes;
}
/**
* gdk_memory_texture_builder_set_bytes: (attributes org.gtk.Method.set_property=bytes)
* @self: a `GdkMemoryTextureBuilder`
* @bytes: (nullable): The bytes the texture shows or %NULL to unset
*
* Sets the data to be shown but the texture.
*
* The bytes must be set before calling [method@Gdk.MemoryTextureBuilder.build].
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_bytes (GdkMemoryTextureBuilder *self,
GBytes *bytes)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
g_return_if_fail (bytes != NULL);
if (self->bytes == bytes)
return;
g_clear_pointer (&self->bytes, g_bytes_unref);
self->bytes = bytes;
if (bytes)
g_bytes_ref (bytes);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BYTES]);
}
/**
* gdk_memory_texture_builder_get_color_state: (attributes org.gtk.Method.get_property=color-state)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the colorstate previously set via gdk_memory_texture_builder_set_color_state().
*
* Returns: (transfer none): The colorstate
*
* Since: 4.16
*/
GdkColorState *
gdk_memory_texture_builder_get_color_state (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), NULL);
return self->color_state;
}
/**
* gdk_memory_texture_builder_set_color_state: (attributes org.gtk.Method.set_property=color-state)
* @self: a `GdkMemoryTextureBuilder`
* @color_state: (nullable): The colorstate describing the data
*
* Sets the colorstate describing the data.
*
* By default, the sRGB colorstate is used. If you don't know
* what colorstates are, this is probably the right thing.
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_color_state (GdkMemoryTextureBuilder *self,
GdkColorState *color_state)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
g_return_if_fail (color_state != NULL);
if (self->color_state == color_state)
return;
g_clear_pointer (&self->color_state, gdk_color_state_unref);
self->color_state = color_state;
if (color_state)
gdk_color_state_ref (color_state);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR_STATE]);
}
/**
* gdk_memory_texture_builder_get_height: (attributes org.gtk.Method.get_property=height)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the height previously set via gdk_memory_texture_builder_set_height()
* or 0 if the height wasn't set.
*
* Returns: The height
*
* Since: 4.16
*/
int
gdk_memory_texture_builder_get_height (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), 0);
return self->height;
}
/**
* gdk_memory_texture_builder_set_height: (attributes org.gtk.Method.set_property=height)
* @self: a `GdkMemoryTextureBuilder`
* @height: The texture's height or 0 to unset
*
* Sets the height of the texture.
*
* The height must be set before calling [method@Gdk.MemoryTextureBuilder.build].
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_height (GdkMemoryTextureBuilder *self,
int height)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
if (self->height == height)
return;
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEIGHT]);
}
/**
* gdk_memory_texture_builder_get_width: (attributes org.gtk.Method.get_property=width)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the width previously set via gdk_memory_texture_builder_set_width()
* or 0 if the width wasn't set.
*
* Returns: The width
*
* Since: 4.16
*/
int
gdk_memory_texture_builder_get_width (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), 0);
return self->width;
}
/**
* gdk_memory_texture_builder_set_width: (attributes org.gtk.Method.set_property=width)
* @self: a `GdkMemoryTextureBuilder`
* @width: The texture's width or 0 to unset
*
* Sets the width of the texture.
*
* The width must be set before calling [method@Gdk.MemoryTextureBuilder.build].
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_width (GdkMemoryTextureBuilder *self,
int width)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
if (self->width == width)
return;
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WIDTH]);
}
/* gdk_memory_texture_builder_get_stride: (attributes org.gtk.Method.get_property=stride) */
/**
* gdk_memory_texture_builder_get_stride:
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the stride previously set via gdk_memory_texture_builder_set_stride().
*
* Returns: the stride
*
* Since: 4.16
*/
gsize
gdk_memory_texture_builder_get_stride (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), 0);
return self->stride;
}
/* gdk_memory_texture_builder_set_stride: (attributes org.gtk.Method.set_property=stride) */
/**
* gdk_memory_texture_builder_set_stride:
* @self: a `GdkMemoryTextureBuilder`
* @stride: the stride or 0 to unset
*
* Sets the rowstride of the bytes used.
*
* The rowstride must be set before calling [method@Gdk.MemoryTextureBuilder.build].
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_stride (GdkMemoryTextureBuilder *self,
gsize stride)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
if (self->stride == stride)
return;
self->stride = stride;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STRIDE]);
}
/**
* gdk_memory_texture_builder_get_format: (attributes org.gtk.Method.get_property=format)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the format previously set via gdk_memory_texture_builder_set_format().
*
* Returns: The format
*
* Since: 4.16
*/
GdkMemoryFormat
gdk_memory_texture_builder_get_format (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
return self->format;
}
/**
* gdk_memory_texture_builder_set_format: (attributes org.gtk.Method.set_property=format)
* @self: a `GdkMemoryTextureBuilder`
* @format: The texture's format
*
* Sets the format of the bytes.
*
* The default is `GDK_MEMORY_R8G8B8A8_PREMULTIPLIED`.
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_format (GdkMemoryTextureBuilder *self,
GdkMemoryFormat format)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
if (self->format == format)
return;
self->format = format;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FORMAT]);
}
/**
* gdk_memory_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the texture previously set via gdk_memory_texture_builder_set_update_texture()
* or %NULL if none was set.
*
* Returns: (transfer none) (nullable): The update texture
*
* Since: 4.16
*/
GdkTexture *
gdk_memory_texture_builder_get_update_texture (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), NULL);
return self->update_texture;
}
/**
* gdk_memory_texture_builder_set_update_texture: (attributes org.gtk.Method.set_property=update-texture)
* @self: a `GdkMemoryTextureBuilder`
* @texture: (nullable): the texture to update
*
* Sets the texture to be updated by this texture.
*
* See [method@Gdk.MemoryTextureBuilder.set_update_region] for an explanation.
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_update_texture (GdkMemoryTextureBuilder *self,
GdkTexture *texture)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
if (!g_set_object (&self->update_texture, texture))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_TEXTURE]);
}
/**
* gdk_memory_texture_builder_get_update_region: (attributes org.gtk.Method.get_property=update-region)
* @self: a `GdkMemoryTextureBuilder`
*
* Gets the region previously set via gdk_memory_texture_builder_set_update_region()
* or %NULL if none was set.
*
* Returns: (transfer none) (nullable): The update region
*
* Since: 4.16
*/
cairo_region_t *
gdk_memory_texture_builder_get_update_region (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), NULL);
return self->update_region;
}
/**
* gdk_memory_texture_builder_set_update_region: (attributes org.gtk.Method.set_property=update-region)
* @self: a `GdkMemoryTextureBuilder`
* @region: (nullable): the region to update
*
* Sets the region to be updated by this texture.
*
* Together with [property@Gdk.MemoryTextureBuilder:update-texture],
* this describes an update of a previous texture.
*
* When rendering animations of large textures, it is possible that
* consecutive textures are only updating contents in parts of the texture.
* It is then possible to describe this update via these two properties,
* so that GTK can avoid rerendering parts that did not change.
*
* An example would be a screen recording where only the mouse pointer moves.
*
* Since: 4.16
*/
void
gdk_memory_texture_builder_set_update_region (GdkMemoryTextureBuilder *self,
cairo_region_t *region)
{
g_return_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self));
if (self->update_region == region)
return;
g_clear_pointer (&self->update_region, cairo_region_destroy);
if (region)
self->update_region = cairo_region_reference (region);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_REGION]);
}
/**
* gdk_memory_texture_builder_build:
* @self: a `GdkMemoryTextureBuilder`
*
* Builds a new `GdkTexture` with the values set up in the builder.
*
* Note that it is a programming error to call this function if any mandatory
* property has not been set.
*
* It is possible to call this function multiple times to create multiple textures,
* possibly with changing properties in between.
*
* Returns: (transfer full): a newly built `GdkTexture`
*
* Since: 4.16
*/
GdkTexture *
gdk_memory_texture_builder_build (GdkMemoryTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE_BUILDER (self), NULL);
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
g_return_val_if_fail (self->bytes != NULL, NULL);
g_return_val_if_fail (self->stride >= self->width * gdk_memory_format_bytes_per_pixel (self->format), NULL);
/* needs to be this complex to support subtexture of the bottom right part */
g_return_val_if_fail (g_bytes_get_size (self->bytes) >= gdk_memory_format_min_buffer_size (self->format, self->stride, self->width, self->height), NULL);
return gdk_memory_texture_new_from_builder (self);
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright © 2024 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.1 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/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_MEMORY_TEXTURE_BUILDER (gdk_memory_texture_builder_get_type ())
GDK_AVAILABLE_IN_4_16
GDK_DECLARE_INTERNAL_TYPE (GdkMemoryTextureBuilder, gdk_memory_texture_builder, GDK, MEMORY_TEXTURE_BUILDER, GObject)
GDK_AVAILABLE_IN_4_16
GdkMemoryTextureBuilder * gdk_memory_texture_builder_new (void);
GDK_AVAILABLE_IN_4_16
GBytes * gdk_memory_texture_builder_get_bytes (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_bytes (GdkMemoryTextureBuilder *self,
GBytes *bytes);
GDK_AVAILABLE_IN_4_16
gsize gdk_memory_texture_builder_get_stride (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_stride (GdkMemoryTextureBuilder *self,
gsize stride);
GDK_AVAILABLE_IN_4_16
int gdk_memory_texture_builder_get_width (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_width (GdkMemoryTextureBuilder *self,
int width);
GDK_AVAILABLE_IN_4_16
int gdk_memory_texture_builder_get_height (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_height (GdkMemoryTextureBuilder *self,
int height);
GDK_AVAILABLE_IN_4_16
GdkMemoryFormat gdk_memory_texture_builder_get_format (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_format (GdkMemoryTextureBuilder *self,
GdkMemoryFormat format);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_memory_texture_builder_get_color_state (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_color_state (GdkMemoryTextureBuilder *self,
GdkColorState *color_state);
GDK_AVAILABLE_IN_4_16
GdkTexture * gdk_memory_texture_builder_get_update_texture (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_update_texture (GdkMemoryTextureBuilder *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_16
cairo_region_t * gdk_memory_texture_builder_get_update_region (GdkMemoryTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_16
void gdk_memory_texture_builder_set_update_region (GdkMemoryTextureBuilder *self,
cairo_region_t *region);
GDK_AVAILABLE_IN_4_16
GdkTexture * gdk_memory_texture_builder_build (GdkMemoryTextureBuilder *self);
G_END_DECLS

View File

@@ -21,7 +21,6 @@
#include "gdkmemorytexture.h"
#include "gdkmemorytexturebuilder.h"
#include "gdktextureprivate.h"
G_BEGIN_DECLS
@@ -29,15 +28,14 @@ G_BEGIN_DECLS
#define GDK_MEMORY_GDK_PIXBUF_OPAQUE GDK_MEMORY_R8G8B8
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture);
GdkMemoryTexture * gdk_memory_texture_from_texture (GdkTexture *texture,
GdkMemoryFormat format);
GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *texture,
int x,
int y,
int width,
int height);
GdkTexture * gdk_memory_texture_new_from_builder (GdkMemoryTextureBuilder *builder);
GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self,
gsize *out_stride);

View File

@@ -109,7 +109,7 @@ gdk_popup_default_init (GdkPopupInterface *iface)
*
* Present @popup after having processed the `GdkPopupLayout` rules.
*
* If the popup was previously not showing, it will be shown,
* If the popup was previously now showing, it will be showed,
* otherwise it will change position according to @layout.
*
* After calling this function, the result should be handled in response

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