Compare commits

..

30 Commits

Author SHA1 Message Date
Matthias Clasen
3f8076a085 texture: Fix an oversight
construct-only properties also get set at construct time,
so we need to handle NULL here, until all our texture construction
methods pass a color state.
2024-06-24 07:39:36 -04:00
Matthias Clasen
ca6fe07b27 gl: Do linear compositing 2024-06-22 13:19:57 -04:00
Matthias Clasen
bdb6552408 gpu: Use stem darkening for linear composited glyphs
This involves tweaking a freetype driver property
directly, since cairo font options don't cover this.

So the code is a bit ugly, but it does make text
appear better, in particular at small sizes.

See https://freetype.org/freetype2/docs/hinting/text-rendering-general.html
2024-06-22 13:19:57 -04:00
Matthias Clasen
7626f8262d cairo: Use stem darkening for glyphs
This involves tweaking a freetype driver property
directly, since cairo font options don't cover this.

So the code is a bit ugly, but it does make text
appear better, in particular at small sizes.

See https://freetype.org/freetype2/docs/hinting/text-rendering-general.html
2024-06-22 13:19:57 -04:00
Matthias Clasen
05e470f2cd cairo: Convert the contents back to srgb
We let cairo operate in linear srgb (by giving it all colors and
texture input in linear srgb), and so we need to convert the
results back to srgb in the end.
2024-06-22 13:19:57 -04:00
Matthias Clasen
c5883853d7 cairo: Convert textures to srgb-linear
Use the new gdk_memort_format_convert_color_state api to
convert textures to linear srgb before passing them to
cairo.
2024-06-22 13:19:57 -04:00
Matthias Clasen
2250761474 cairo: Convert colors to srgb-linear 2024-06-22 13:19:57 -04:00
Matthias Clasen
d35df199b0 gdk: Add a fast-path
Special case u8 RGBA8p, which is the common case.
2024-06-22 13:19:57 -04:00
Matthias Clasen
87f9c26414 gdk: Add gdk_memory_format_convert_color_state
This allows in-place color state conversions.
2024-06-22 13:19:57 -04:00
Matthias Clasen
d2cc2b6ea8 Temporarily disable gsk compare test variant
Too much failure.
2024-06-22 13:19:57 -04:00
Matthias Clasen
f73a34e71a glx: Create srgb drawables if possible
Make our visual selection code prefer fbconfigs that are
'srgb framebuffer capable', and mark the surface as 'is srgb'
in this case.

This arranges things so that GSK knows not to use an offscreen
for converting contents back to srgb in the end.
2024-06-22 13:19:57 -04:00
Matthias Clasen
b5f5e6e34b gl: Enable GL_FRAMEBUFFER_SRGB
It seems that we need this for GL_SRGB to work in GLX.
2024-06-22 13:19:57 -04:00
Matthias Clasen
7f71443d6b gdk: Use the vulkan srgb image format
We want to do compositing in a linear colorspace, and this
will take care of the 'convert back to srgb in the end' step.
2024-06-22 13:19:57 -04:00
Matthias Clasen
bb130960e2 gdk: Create our egl surface with srgb colorspace
We want to do our compositing in a linear colorspace, and the
EXT_KHR_gl_colorspace extension helps for that. We don't hard-
require it, since it isn't super-common in the wild (37%).

If we have the extension, create our egl surface with the
srgb colorspace, and report that face in gdk_surface_gl_is_srgb().
2024-06-22 13:19:57 -04:00
Matthias Clasen
0ebc7660a2 gpu: Add debug spew 2024-06-22 13:19:57 -04:00
Matthias Clasen
fe885d9f41 gpu: Make compositing happen in linear space
For now, we always deliver our framebuffer in srgb, and we always
want to composite in srgb-linear. If GL/Vulkan have provided us
with a back buffer that does this conversion on its own, we just
use it. The is expected to work at least for cases where we use
an u8 frame buffer.

Otherwise, we pass the target and compositing color states down
to where we call into the node processor to process nodes, create
an offscreen for rendering to, and then do manual color conversion
afterwards to put the result into the frame buffer.
2024-06-22 13:19:57 -04:00
Matthias Clasen
3076cd9a47 gpu: Convert textures to the right color state
Add function to convert an image from one color state to another,
and call it whenever we upload a texture.
2024-06-22 13:19:57 -04:00
Matthias Clasen
b710e72e1e gpu: Return color state when uploading textures
We want to allow for the possibility that we can automatically
convert from srgb to srgb-linear by picking the right image
format, so we need the upload operation to return the proper
color state for the image that it created.

For now, we do nothing with the returned information.
2024-06-22 13:19:57 -04:00
Matthias Clasen
c6bb894507 gpu: Pass color state to upload ops
This is so we can make decisions about the kind of image to create
based on the kind of colorstate we are going to upload.
2024-06-22 13:19:57 -04:00
Matthias Clasen
a6351ea8be gpu: track color state in the texture cache
Keep the color state information around for cached images.

We keep up to two different images per texture - that is enough to
keep the original uploaded image and the one that has been converted
to the compositing colorstate.
2024-06-22 13:19:57 -04:00
Matthias Clasen
68e132d2c0 gpu: Pass linear colors to clear ops too
This was forgotten when colors were converted.
2024-06-22 13:19:57 -04:00
Matthias Clasen
dd79dd0a52 gpu: Pass colors in srgb-linear
GdkRGBA is defined to be in srgb. Since we want to do our
compositing in srgb-linear, convert the coors as we send
them to the shader.
2024-06-22 13:19:57 -04:00
Matthias Clasen
f7ff943d08 gpu: Pass compositing color states around
Make the node processor and the pattern writer track the current
compositing color state. Color state nodes change it. We pass
the surface color state down via the frame apis.
2024-06-22 13:19:57 -04:00
Matthias Clasen
6f37b64e4c gpu: Add a color convert shader
This shader converts between two color states, by using the
same functions that we use on the cpu. The conversion to perform
is passed as an integer encoding the pair of color states.

For now, the only possible color states are srgb and srgb-linear.
2024-06-22 13:19:57 -04:00
Matthias Clasen
7f7b104438 gpu: Mark images that convert srgb
This is a special property that gpu images can have, that they
automatically convert between the linear srgb that the shaders
see, and the nonlinear srgb that the image is stored in.
2024-06-22 13:19:57 -04:00
Matthias Clasen
c76a22224b gdk: Add gdk_surface_get_gl_is_srgb()
This is a way to query whether the framebuffer we use is using GL_SRGB
or equivalent. Currently, it just returns FALSE.
2024-06-22 13:19:57 -04:00
Matthias Clasen
531ca56a20 gdk: Add gdk_texture_get_color_state
This does not do anything yet, just return srgb.
2024-06-22 13:19:57 -04:00
Matthias Clasen
5eaba3b123 gdk: Add GdkColorState
This is mostly an empty shell for now. We only have static instances
for srgb and srgb-linear, which we will use as markers during our
node processing.

In the future, this object may grow more instances, as well as the
ability to create them from and save them to icc profiles or cicp
data. And a color conversion api.
2024-06-22 13:19:57 -04:00
Benjamin Otte
d697cce5b0 gdk: Allow querying GL SRGB formats
Nobody is using this yet.
2024-06-22 13:19:57 -04:00
Benjamin Otte
ccc646dda7 gdk: Allow querying Vulkan SRGB formats
Nobody is using this yet, this is just infrastructure.
2024-06-22 13:19:57 -04:00
593 changed files with 17118 additions and 30426 deletions

View File

@@ -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

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

@@ -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

106
NEWS
View File

@@ -1,114 +1,20 @@
Overview of Changes in 4.15.5, xx-xx-xxxx
=========================================
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
Overview of Changes in 4.15.2, xx-xx-xxxx
=========================================
* 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
@@ -116,25 +22,17 @@ Overview of Changes in 4.15.2, 28-06-2024
* 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
- nodeparser: 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

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

@@ -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

@@ -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

@@ -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,45 +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 | `narrow | full` | full | non-default |
Note that the primaries, transfer and matrix properties always need
to be specified, since GTK does not allow creating color state objects
with these being set to 2 (== unspecified).
# Colors
Colors can be specified with a variation of the modern CSS color syntax:
color(<color-state> <number> <number> <number> ["/" <number>])
The traditional syntax for sRGB colors still works as well:
rgba(<number>, <number>, <number>, <number)
rgb(<number, <number>, <number>)
# Nodes
### container

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

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

@@ -85,7 +85,6 @@ content_files = [
"x11.md",
"tools.md",
"visual_index.md",
"node-format.md",
]
content_images = [
"../images/favicon.svg",
@@ -252,12 +251,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

@@ -64,18 +64,6 @@ if get_option('documentation')
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'))
@@ -85,7 +73,6 @@ 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' ],

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

@@ -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

@@ -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

@@ -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,7 +29,6 @@
#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>
@@ -63,7 +62,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

@@ -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,481 +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
* - 2: unspecified
*
* 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,8 +515,8 @@ 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.
*
@@ -630,8 +630,8 @@ 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.
@@ -823,8 +823,8 @@ 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.
@@ -882,8 +882,8 @@ 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`.
*
@@ -944,8 +944,8 @@ 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.
*

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,224 +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,
};

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

@@ -20,10 +20,6 @@
#include "gdkcolorstateprivate.h"
#include <math.h>
#include "gdkcolordefs.h"
#include <glib/gi18n-lib.h>
/**
@@ -55,7 +51,7 @@ G_DEFINE_BOXED_TYPE (GdkColorState, gdk_color_state,
* Increase the reference count of @self.
*
* Returns: the object that was passed in
*
*
* Since: 4.16
*/
GdkColorState *
@@ -86,16 +82,6 @@ void
*
* 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 *
@@ -109,15 +95,6 @@ gdk_color_state_get_srgb (void)
*
* 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 *
@@ -126,52 +103,6 @@ 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`
@@ -194,579 +125,57 @@ gboolean
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)
const char *
gdk_color_state_get_name_from_id (GdkColorStateId id)
{
return self == other;
const char *names[] = {
"srgb", "srgb-linear",
};
return names[id];
}
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,
GdkColorState gdk_default_color_states[] = {
{ NULL, 0 },
{ NULL, 0 },
};
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;
GdkCicp cicp;
};
/* {{{ Conversion functions */
#define cicp ((GdkCicpColorState *)self)
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
#undef cicp
/* }}} */
/* }}} */
/* {{{ 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,
};
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;
if (cicp->range == GDK_CICP_RANGE_NARROW || cicp->matrix_coefficients != 0)
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
_("cicp: Narrow range or YUV not supported"));
return NULL;
}
if (cicp->color_primaries == 2 ||
cicp->transfer_function == 2 ||
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_equivalent (cicp, &gdk_default_color_states[i].cicp))
return (GdkColorState *) &gdk_default_color_states[i];
}
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:
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;
}
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->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)
{
if (GDK_IS_DEFAULT_COLOR_STATE (self))
{
switch (GDK_DEFAULT_COLOR_STATE_ID (self))
{
case GDK_COLOR_STATE_ID_SRGB: return "srgb";
case GDK_COLOR_STATE_ID_SRGB_LINEAR: return "srgb-linear";
default: g_assert_not_reached ();
}
}
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)
void
gdk_color_state_print (GdkColorState *self,
GString *string)
{
if (!GDK_DEBUG_CHECK (LINEAR))
return FALSE;
g_string_append (string, gdk_color_state_get_name (self));
}
return self->klass->get_no_srgb_tf (self);
GdkMemoryDepth
gdk_color_state_get_min_depth (GdkColorState *self)
{
if (self == GDK_COLOR_STATE_SRGB || self == GDK_COLOR_STATE_SRGB_LINEAR)
return GDK_MEMORY_U8;
return GDK_MEMORY_FLOAT16;
}
/* }}} */

View File

@@ -43,20 +43,8 @@ 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,108 +1,44 @@
#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;
GdkColorStateClass *klass;
int ref_count;
};
/* 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;
extern GdkColorState gdk_default_color_states[];
struct _GdkDefaultColorState
{
GdkColorState parent;
#define GDK_COLOR_STATE_SRGB (&gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
#define GDK_COLOR_STATE_SRGB_LINEAR (&gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
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))
#define GDK_IS_DEFAULT_COLOR_STATE(c) (GDK_COLOR_STATE_SRGB <= (c) && (c) <= GDK_COLOR_STATE_SRGB_LINEAR)
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (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);
const char * gdk_color_state_get_name_from_id (GdkColorStateId id);
void gdk_color_state_print (GdkColorState *color_state,
GString *string);
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];
}
GdkMemoryDepth gdk_color_state_get_min_depth (GdkColorState *color_state);
#define gdk_color_state_ref(self) _gdk_color_state_ref (self)
static inline GdkColorState *
@@ -111,7 +47,7 @@ _gdk_color_state_ref (GdkColorState *self)
if (GDK_IS_DEFAULT_COLOR_STATE (self))
return self;
g_atomic_ref_count_inc (&self->ref_count);
self->ref_count++;
return self;
}
@@ -123,7 +59,9 @@ _gdk_color_state_unref (GdkColorState *self)
if (GDK_IS_DEFAULT_COLOR_STATE (self))
return;
if (g_atomic_ref_count_dec (&self->ref_count))
self->ref_count--;
if (self->ref_count == 0)
self->klass->free (self);
}
@@ -135,79 +73,12 @@ _gdk_color_state_equal (GdkColorState *self,
if (self == other)
return TRUE;
if (GDK_IS_DEFAULT_COLOR_STATE (self) || GDK_IS_DEFAULT_COLOR_STATE (other))
return FALSE;
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);
}

View File

@@ -533,8 +533,8 @@ 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.
*

View File

@@ -273,8 +273,8 @@ 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.

View File

@@ -539,8 +539,8 @@ 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.
*

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

@@ -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

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 */
@@ -246,8 +248,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

@@ -71,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, dst_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);
@@ -241,108 +241,6 @@ download_nv12 (guchar *dst_data,
}
}
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static void
download_p010 (guchar *dst,
gsize dst_stride,
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, MASK;
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;
}
MASK = 0xFFFF << (16 - SIZE);
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)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u, v;
u = uv_data[x / X_SUB * 2 + U];
u = (u & MASK) | (u >> SIZE);
v = uv_data[x / X_SUB * 2 + V];
v = (v & MASK) | (v >> SIZE);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
{
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = (y_ & MASK) | (y_ >> SIZE);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
uv_data += uv_stride;
}
}
static void
download_yuv_3 (guchar *dst_data,
gsize dst_stride,
@@ -1775,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
@@ -1784,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
@@ -1796,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
@@ -1808,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
@@ -2130,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;
@@ -2164,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;
@@ -2193,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);
@@ -2471,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)
@@ -2482,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

@@ -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

@@ -10,10 +10,6 @@
((__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"
@@ -97,7 +96,6 @@ struct _Download
{
GdkDmabufTexture *texture;
GdkMemoryFormat format;
GdkColorState *color_state;
guchar *data;
gsize stride;
volatile int spinlock;
@@ -111,7 +109,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 +120,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 +178,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,24 +197,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)
{
g_warning_once ("FIXME: Implement the proper colorstate for YUV dmabufs");
color_state = gdk_color_state_get_srgb ();
}
else
color_state = gdk_color_state_get_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;
}
/**
@@ -384,15 +378,7 @@ gdk_draw_context_begin_frame_full (GdkDrawContext *context,
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) {
@@ -463,10 +449,8 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
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;
}
/**
@@ -494,38 +478,6 @@ gdk_draw_context_get_frame_region (GdkDrawContext *context)
return priv->frame_region;
}
/*<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;
}
void
gdk_draw_context_empty_frame (GdkDrawContext *context)
{

View File

@@ -22,7 +22,6 @@
#include "gdkdrawcontext.h"
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
G_BEGIN_DECLS
@@ -44,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);
@@ -61,9 +58,6 @@ void gdk_draw_context_begin_frame_full (GdkDrawContext
void gdk_draw_context_empty_frame (GdkDrawContext *context);
GdkColorState * gdk_draw_context_get_color_state (GdkDrawContext *self);
GdkMemoryDepth gdk_draw_context_get_depth (GdkDrawContext *self);
G_END_DECLS

View File

@@ -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.
@@ -843,8 +843,8 @@ 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.

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

@@ -329,7 +329,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;
@@ -609,41 +609,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);
@@ -1775,6 +1758,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->features = supported_features & ~disabled_features;
glEnable (GL_FRAMEBUFFER_SRGB);
gdk_gl_context_init_memory_flags (context);
if ((priv->features & GDK_GL_FEATURE_DEBUG) && gl_debug)

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;
};
@@ -212,14 +210,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 +226,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,7 +257,7 @@ 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);
@@ -280,7 +269,7 @@ 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);
@@ -298,14 +287,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 +378,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 +394,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 +402,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;
@@ -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

View File

@@ -30,66 +30,68 @@
#include <epoxy/gl.h>
G_STATIC_ASSERT ((1 << GDK_MEMORY_DEPTH_BITS) > GDK_N_DEPTHS);
typedef struct _GdkMemoryFormatDescription GdkMemoryFormatDescription;
#define TYPED_FUNCS(name, T, R, G, B, A, bpp, scale) \
static void \
name ## _to_float (float (*dest)[4], \
const guchar *src_data, \
gsize n) \
name ## _to_float (float *dest, \
const guchar *src_data, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *src = (T *) (src_data + i * bpp); \
dest[i][0] = (float) src[R] / scale; \
dest[i][1] = (float) src[G] / scale; \
dest[i][2] = (float) src[B] / scale; \
if (A >= 0) dest[i][3] = (float) src[A] / scale; else dest[i][3] = 1.0; \
dest[0] = (float) src[R] / scale; \
dest[1] = (float) src[G] / scale; \
dest[2] = (float) src[B] / scale; \
if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
dest += 4; \
} \
} \
\
static void \
name ## _from_float (guchar *dest_data, \
const float (*src)[4], \
gsize n) \
name ## _from_float (guchar *dest_data, \
const float *src, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *dest = (T *) (dest_data + i * bpp); \
dest[R] = CLAMP (src[i][0] * scale + 0.5, 0, scale); \
dest[G] = CLAMP (src[i][1] * scale + 0.5, 0, scale); \
dest[B] = CLAMP (src[i][2] * scale + 0.5, 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[i][3] * scale + 0.5, 0, scale); \
dest[R] = CLAMP (src[0] * scale + 0.5, 0, scale); \
dest[G] = CLAMP (src[1] * scale + 0.5, 0, scale); \
dest[B] = CLAMP (src[2] * scale + 0.5, 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[3] * scale + 0.5, 0, scale); \
src += 4; \
} \
}
#define TYPED_GRAY_FUNCS(name, T, G, A, bpp, scale) \
static void \
name ## _to_float (float (*dest)[4], \
const guchar *src_data, \
gsize n) \
name ## _to_float (float *dest, \
const guchar *src_data, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *src = (T *) (src_data + i * bpp); \
if (A >= 0) dest[i][3] = (float) src[A] / scale; else dest[i][3] = 1.0; \
if (G >= 0) dest[i][0] = (float) src[G] / scale; else dest[i][0] = dest[i][3]; \
dest[i][1] = dest[i][2] = dest[i][0]; \
if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
if (G >= 0) dest[0] = (float) src[G] / scale; else dest[0] = dest[3]; \
dest[1] = dest[2] = dest[0]; \
dest += 4; \
} \
} \
\
static void \
name ## _from_float (guchar *dest_data, \
const float (*src)[4], \
gsize n) \
name ## _from_float (guchar *dest_data, \
const float *src, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *dest = (T *) (dest_data + i * bpp); \
if (G >= 0) dest[G] = CLAMP ((src[i][0] + src[i][1] + src[i][2]) * scale / 3.f + 0.5, 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[i][3] * scale + 0.5, 0, scale); \
if (G >= 0) dest[G] = CLAMP ((src[0] + src[1] + src[2]) * scale / 3.f + 0.5, 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[3] * scale + 0.5, 0, scale); \
src += 4; \
} \
}
@@ -122,146 +124,158 @@ TYPED_GRAY_FUNCS (g16, guint16, 0, -1, 2, 65535)
TYPED_GRAY_FUNCS (a16, guint16, -1, 0, 2, 65535)
static void
r16g16b16_float_to_float (float (*dest)[4],
const guchar *src_data,
gsize n)
r16g16b16_float_to_float (float *dest,
const guchar *src_data,
gsize n)
{
guint16 *src = (guint16 *) src_data;
for (gsize i = 0; i < n; i++)
{
half_to_float (src, dest[i], 3);
dest[i][3] = 1.0;
half_to_float (src, dest, 3);
dest[3] = 1.0;
dest += 4;
src += 3;
}
}
static void
r16g16b16_float_from_float (guchar *dest_data,
const float (*src)[4],
gsize n)
r16g16b16_float_from_float (guchar *dest_data,
const float *src,
gsize n)
{
guint16 *dest = (guint16 *) dest_data;
for (gsize i = 0; i < n; i++)
{
float_to_half (src[i], dest, 3);
float_to_half (src, dest, 3);
dest += 3;
src += 4;
}
}
static void
r16g16b16a16_float_to_float (float (*dest)[4],
const guchar *src,
gsize n)
r16g16b16a16_float_to_float (float *dest,
const guchar *src,
gsize n)
{
half_to_float ((const guint16 *) src, (float *) dest, 4 * n);
half_to_float ((const guint16 *) src, dest, 4 * n);
}
static void
r16g16b16a16_float_from_float (guchar *dest,
const float (*src)[4],
gsize n)
r16g16b16a16_float_from_float (guchar *dest,
const float *src,
gsize n)
{
float_to_half ((const float *) src, (guint16 *) dest, 4 * n);
float_to_half (src, (guint16 *) dest, 4 * n);
}
static void
a16_float_to_float (float (*dest)[4],
const guchar *src_data,
gsize n)
a16_float_to_float (float *dest,
const guchar *src_data,
gsize n)
{
const guint16 *src = (const guint16 *) src_data;
for (gsize i = 0; i < n; i++)
{
half_to_float (src, &dest[i][0], 1);
dest[i][1] = dest[i][0];
dest[i][2] = dest[i][0];
dest[i][3] = dest[i][0];
half_to_float (src, dest, 1);
dest[1] = dest[0];
dest[2] = dest[0];
dest[3] = dest[0];
src++;
dest += 4;
}
}
static void
a16_float_from_float (guchar *dest_data,
const float (*src)[4],
gsize n)
a16_float_from_float (guchar *dest_data,
const float *src,
gsize n)
{
guint16 *dest = (guint16 *) dest_data;
for (gsize i = 0; i < n; i++)
{
float_to_half (&src[i][3], dest, 1);
float_to_half (&src[3], dest, 1);
dest ++;
src += 4;
}
}
static void
r32g32b32_float_to_float (float (*dest)[4],
const guchar *src_data,
gsize n)
r32g32b32_float_to_float (float *dest,
const guchar *src_data,
gsize n)
{
const float (*src)[3] = (const float (*)[3]) src_data;
float *src = (float *) src_data;
for (gsize i = 0; i < n; i++)
{
dest[i][0] = src[i][0];
dest[i][1] = src[i][1];
dest[i][2] = src[i][2];
dest[i][3] = 1.0;
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = 1.0;
dest += 4;
src += 3;
}
}
static void
r32g32b32_float_from_float (guchar *dest_data,
const float (*src)[4],
gsize n)
{
float (*dest)[3] = (float (*)[3]) dest_data;
for (gsize i = 0; i < n; i++)
{
dest[i][0] = src[i][0];
dest[i][1] = src[i][1];
dest[i][2] = src[i][2];
}
}
static void
r32g32b32a32_float_to_float (float (*dest)[4],
const guchar *src,
gsize n)
{
memcpy (dest, src, sizeof (float) * n * 4);
}
static void
r32g32b32a32_float_from_float (guchar *dest,
const float (*src)[4],
gsize n)
{
memcpy (dest, src, sizeof (float) * n * 4);
}
static void
a32_float_to_float (float (*dest)[4],
const guchar *src_data,
gsize n)
{
const float *src = (const float *) src_data;
for (gsize i = 0; i < n; i++)
{
dest[i][0] = src[i];
dest[i][1] = src[i];
dest[i][2] = src[i];
dest[i][3] = src[i];
}
}
static void
a32_float_from_float (guchar *dest_data,
const float (*src)[4],
gsize n)
r32g32b32_float_from_float (guchar *dest_data,
const float *src,
gsize n)
{
float *dest = (float *) dest_data;
for (gsize i = 0; i < n; i++)
{
dest[i] = src[i][3];
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest += 3;
src += 4;
}
}
static void
r32g32b32a32_float_to_float (float *dest,
const guchar *src,
gsize n)
{
memcpy (dest, src, sizeof (float) * n * 4);
}
static void
r32g32b32a32_float_from_float (guchar *dest,
const float *src,
gsize n)
{
memcpy (dest, src, sizeof (float) * n * 4);
}
static void
a32_float_to_float (float *dest,
const guchar *src_data,
gsize n)
{
const float *src = (const float *) src_data;
for (gsize i = 0; i < n; i++)
{
dest[0] = src[0];
dest[1] = src[0];
dest[2] = src[0];
dest[3] = src[0];
src++;
dest += 4;
}
}
static void
a32_float_from_float (guchar *dest_data,
const float *src,
gsize n)
{
float *dest = (float *) dest_data;
for (gsize i = 0; i < n; i++)
{
dest[0] = src[3];
dest ++;
src += 4;
}
}
@@ -344,8 +358,8 @@ struct _GdkMemoryFormatDescription
guint32 dmabuf_fourcc;
#endif
/* no premultiplication going on here */
void (* to_float) (float (*)[4], const guchar*, gsize);
void (* from_float) (guchar *, const float (*)[4], gsize);
void (* to_float) (float *, const guchar*, gsize);
void (* from_float) (guchar *, const float *, gsize);
};
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -1488,19 +1502,9 @@ gdk_memory_format_get_fallbacks (GdkMemoryFormat format)
return memory_formats[format].fallbacks;
}
gsize
gdk_memory_format_min_buffer_size (GdkMemoryFormat format,
gsize stride,
gsize width,
gsize height)
{
return stride * (height - 1) + width * gdk_memory_format_bytes_per_pixel (format);
}
/*<private>
* gdk_memory_format_get_depth:
* @format: a memory format
* @srgb: whether an SRGB depth should be returned.
*
* Gets the depth of the individual channels of the format.
* See gsk_render_node_prefers_high_depth() for more
@@ -1512,16 +1516,9 @@ gdk_memory_format_min_buffer_size (GdkMemoryFormat format,
* Returns: The depth of this format
**/
GdkMemoryDepth
gdk_memory_format_get_depth (GdkMemoryFormat format,
gboolean srgb)
gdk_memory_format_get_depth (GdkMemoryFormat format)
{
GdkMemoryDepth depth;
depth = memory_formats[format].depth;
if (depth == GDK_MEMORY_U8 && srgb)
depth = GDK_MEMORY_U8_SRGB;
return depth;
return memory_formats[format].depth;
}
/*<private>
@@ -1538,20 +1535,25 @@ GdkMemoryDepth
gdk_memory_depth_merge (GdkMemoryDepth depth1,
GdkMemoryDepth depth2)
{
static const GdkMemoryDepth merged_depths[GDK_N_DEPTHS][GDK_N_DEPTHS] = {
/* NONE U8 U8_SRGB U16 FLOAT16 FLOAT32 */
[GDK_MEMORY_NONE] = { GDK_MEMORY_NONE, GDK_MEMORY_U8, GDK_MEMORY_U8_SRGB, GDK_MEMORY_U16, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT32 },
[GDK_MEMORY_U8] = { GDK_MEMORY_U8, GDK_MEMORY_U8, GDK_MEMORY_FLOAT16, GDK_MEMORY_U16, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT32 },
[GDK_MEMORY_U8_SRGB] = { GDK_MEMORY_U8_SRGB, GDK_MEMORY_FLOAT16, GDK_MEMORY_U8_SRGB, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT32 },
[GDK_MEMORY_U16] = { GDK_MEMORY_U16, GDK_MEMORY_U16, GDK_MEMORY_FLOAT32, GDK_MEMORY_U16, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32 },
[GDK_MEMORY_FLOAT16] = { GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT16, GDK_MEMORY_FLOAT32 },
[GDK_MEMORY_FLOAT32] = { GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32, GDK_MEMORY_FLOAT32 },
};
switch (depth1)
{
case GDK_MEMORY_U8:
return depth2;
g_assert (depth1 < GDK_N_DEPTHS);
g_assert (depth2 < GDK_N_DEPTHS);
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_FLOAT32;
return merged_depths[depth1][depth2];
case GDK_MEMORY_U16:
case GDK_MEMORY_FLOAT16:
if (depth2 == depth1 || depth2 == GDK_MEMORY_U8)
return depth1;
else
return GDK_MEMORY_FLOAT32;
default:
g_assert_not_reached ();
return GDK_MEMORY_U8;
}
}
/*
@@ -1568,9 +1570,7 @@ gdk_memory_depth_get_format (GdkMemoryDepth depth)
{
switch (depth)
{
case GDK_MEMORY_NONE:
case GDK_MEMORY_U8:
case GDK_MEMORY_U8_SRGB:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_U16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
@@ -1578,7 +1578,6 @@ gdk_memory_depth_get_format (GdkMemoryDepth depth)
return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_N_DEPTHS:
default:
g_return_val_if_reached (GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
}
@@ -1598,9 +1597,7 @@ gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
{
switch (depth)
{
case GDK_MEMORY_NONE:
case GDK_MEMORY_U8:
case GDK_MEMORY_U8_SRGB:
return GDK_MEMORY_A8;
case GDK_MEMORY_U16:
return GDK_MEMORY_A16;
@@ -1608,32 +1605,6 @@ gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
return GDK_MEMORY_A16_FLOAT;
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_A32_FLOAT;
case GDK_N_DEPTHS:
default:
g_return_val_if_reached (GDK_MEMORY_A8);
}
}
gboolean
gdk_memory_depth_is_srgb (GdkMemoryDepth depth)
{
/* Putting a switch here instead of a simple check
* so the compiler makes us look here
* when adding new formats */
switch (depth)
{
case GDK_MEMORY_U8_SRGB:
return TRUE;
case GDK_MEMORY_NONE:
case GDK_MEMORY_U8:
case GDK_MEMORY_U16:
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
return FALSE;
case GDK_N_DEPTHS:
default:
g_return_val_if_reached (GDK_MEMORY_A8);
}
@@ -1816,29 +1787,31 @@ gdk_memory_format_get_name (GdkMemoryFormat format)
}
static void
premultiply (float (*rgba)[4],
premultiply (float *rgba,
gsize n)
{
for (gsize i = 0; i < n; i++)
{
rgba[i][0] *= rgba[i][3];
rgba[i][1] *= rgba[i][3];
rgba[i][2] *= rgba[i][3];
rgba[0] *= rgba[3];
rgba[1] *= rgba[3];
rgba[2] *= rgba[3];
rgba += 4;
}
}
static void
unpremultiply (float (*rgba)[4],
gsize n)
unpremultiply (float *rgba,
gsize n)
{
for (gsize i = 0; i < n; i++)
{
if (rgba[i][3] > 1/255.0)
if (rgba[3] > 1/255.0)
{
rgba[i][0] /= rgba[i][3];
rgba[i][1] /= rgba[i][3];
rgba[i][2] /= rgba[i][3];
rgba[0] /= rgba[3];
rgba[1] /= rgba[3];
rgba[2] /= rgba[3];
}
rgba += 4;
}
}
@@ -1846,32 +1819,26 @@ void
gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
GdkColorState *dest_cs,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
GdkColorState *src_cs,
gsize width,
gsize height)
{
const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
float (*tmp)[4];
float *tmp;
gsize y;
GdkFloatColorConvert convert_func = NULL;
GdkFloatColorConvert convert_func2 = NULL;
void (*func) (guchar *, const guchar *, gsize) = NULL;
gboolean needs_premultiply, needs_unpremultiply;
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
g_assert (src_format < GDK_MEMORY_N_FORMATS);
/* We don't allow overlap here. If you want to do in-place color state conversions,
* use gdk_memory_convert_color_state.
*/
g_assert (dest_data + gdk_memory_format_min_buffer_size (dest_format, dest_stride, width, height) <= src_data ||
src_data + gdk_memory_format_min_buffer_size (src_format, src_stride, width, height) <= dest_data);
g_assert (dest_data + height * dest_stride < src_data || src_data + height * src_stride < dest_data);
if (src_format == dest_format && gdk_color_state_equal (dest_cs, src_cs))
if (src_format == dest_format)
{
gsize bytes_per_row = src_desc->bytes_per_pixel * width;
@@ -1891,21 +1858,7 @@ gdk_memory_convert (guchar *dest_data,
return;
}
if (!gdk_color_state_equal (dest_cs, src_cs))
{
convert_func = gdk_color_state_get_convert_to (src_cs, dest_cs);
if (!convert_func)
convert_func2 = gdk_color_state_get_convert_from (dest_cs, src_cs);
if (!convert_func && !convert_func2)
{
GdkColorState *connection = GDK_COLOR_STATE_REC2100_LINEAR;
convert_func = gdk_color_state_get_convert_to (src_cs, connection);
convert_func2 = gdk_color_state_get_convert_from (dest_cs, connection);
}
}
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
@@ -1953,37 +1906,16 @@ gdk_memory_convert (guchar *dest_data,
return;
}
tmp = g_malloc (sizeof (*tmp) * width);
if (convert_func)
{
needs_unpremultiply = src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED;
needs_premultiply = src_desc->alpha != GDK_MEMORY_ALPHA_OPAQUE && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT;
}
else
{
needs_unpremultiply = src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT;
needs_premultiply = src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT;
}
tmp = g_new (float, width * 4);
for (y = 0; y < height; y++)
{
src_desc->to_float (tmp, src_data, width);
if (needs_unpremultiply)
if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT)
unpremultiply (tmp, width);
if (convert_func)
convert_func (src_cs, tmp, width);
if (convert_func2)
convert_func2 (dest_cs, tmp, width);
if (needs_premultiply)
else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
premultiply (tmp, width);
dest_desc->from_float (dest_data, tmp, width);
src_data += src_stride;
dest_data += dest_stride;
}
@@ -2035,28 +1967,24 @@ convert_srgb_to_srgb_linear (guchar *data,
{
for (gsize i = 0; i < n; i++)
{
guint16 r = data[0];
guint16 g = data[1];
guint16 b = data[2];
guint8 r = data[0];
guint8 g = data[1];
guint8 b = data[2];
guchar a = data[3];
if (a != 0)
float f = a / 255.0;
if (a < 255)
{
r = (r * 255 + a / 2) / a;
g = (g * 255 + a / 2) / a;
b = (b * 255 + a / 2) / a;
r = srgb_inverse_lookup[r];
g = srgb_inverse_lookup[g];
b = srgb_inverse_lookup[b];
r = r * a + 127;
g = g * a + 127;
b = b * a + 127;
data[0] = (r + (r >> 8) + 1) >> 8;
data[1] = (g + (g >> 8) + 1) >> 8;
data[2] = (b + (b >> 8) + 1) >> 8;
r = r / f;
g = g / f;
b = b / f;
}
r = srgb_inverse_lookup[r];
g = srgb_inverse_lookup[g];
b = srgb_inverse_lookup[b];
data[0] = r * f;
data[1] = g * f;
data[2] = b * f;
data += 4;
}
}
@@ -2067,29 +1995,24 @@ convert_srgb_linear_to_srgb (guchar *data,
{
for (gsize i = 0; i < n; i++)
{
guint16 r = data[0];
guint16 g = data[1];
guint16 b = data[2];
guint8 r = data[0];
guint8 g = data[1];
guint8 b = data[2];
guchar a = data[3];
if (a != 0)
float f = a / 255.0;
if (a < 255)
{
r = (r * 255 + a / 2) / a;
g = (g * 255 + a / 2) / a;
b = (b * 255 + a / 2) / a;
r = srgb_lookup[r];
g = srgb_lookup[g];
b = srgb_lookup[b];
r = r * a + 127;
g = g * a + 127;
b = b * a + 127;
data[0] = (r + (r >> 8) + 1) >> 8;
data[1] = (g + (g >> 8) + 1) >> 8;
data[2] = (b + (b >> 8) + 1) >> 8;
r = r / f;
g = g / f;
b = b / f;
}
r = srgb_lookup[r];
g = srgb_lookup[g];
b = srgb_lookup[b];
data[0] = r * f;
data[1] = g * f;
data[2] = b * f;
data += 4;
}
}
@@ -2134,73 +2057,66 @@ convert_srgb_linear_to_srgb_in_place (guchar *data,
}
}
typedef void (* StepFunc) (float s0, float s1, float s2,
float *d0, float *d1, float *d2);
void
gdk_memory_convert_color_state (guchar *data,
gsize stride,
GdkMemoryFormat format,
GdkColorState *src_cs,
GdkColorState *dest_cs,
GdkColorState *src_color_state,
GdkColorState *dest_color_state,
gsize width,
gsize height)
{
const GdkMemoryFormatDescription *desc = &memory_formats[format];
GdkFloatColorConvert convert_func = NULL;
GdkFloatColorConvert convert_func2 = NULL;
float (*tmp)[4];
if (gdk_color_state_equal (src_cs, dest_cs))
return;
if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB &&
dest_cs == GDK_COLOR_STATE_SRGB_LINEAR)
src_color_state == GDK_COLOR_STATE_SRGB &&
dest_color_state == GDK_COLOR_STATE_SRGB_LINEAR)
{
convert_srgb_to_srgb_linear_in_place (data, stride, width, height);
return;
}
else if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB_LINEAR &&
dest_cs == GDK_COLOR_STATE_SRGB)
src_color_state == GDK_COLOR_STATE_SRGB_LINEAR &&
dest_color_state == GDK_COLOR_STATE_SRGB)
{
convert_srgb_linear_to_srgb_in_place (data, stride, width, height);
return;
}
convert_func = gdk_color_state_get_convert_to (src_cs, dest_cs);
if (!convert_func)
else
{
convert_func2 = gdk_color_state_get_convert_from (dest_cs, src_cs);
/* General case, treat it just like gdk_memory_convert */
const GdkMemoryFormatDescription *desc = &memory_formats[format];
StepFunc func;
float *tmp;
if (src_color_state == GDK_COLOR_STATE_SRGB &&
dest_color_state == GDK_COLOR_STATE_SRGB_LINEAR)
func = gtk_rgb_to_linear_srgb;
else if (src_color_state == GDK_COLOR_STATE_SRGB_LINEAR &&
dest_color_state == GDK_COLOR_STATE_SRGB)
func = gtk_linear_srgb_to_rgb;
else
return;
tmp = g_new (float, width * 4);
for (gsize y = 0; y < height; y++)
{
desc->to_float (tmp, data, width);
if (desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
unpremultiply (tmp, width);
for (gsize x = 0; x < 4 * width; x += 4)
func (tmp[x], tmp[x+1], tmp[x+2], &tmp[x], &tmp[x+1], &tmp[x+2]);
if (desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
premultiply (tmp, width);
desc->from_float (data, tmp, width);
data += stride;
}
g_free (tmp);
}
if (!convert_func && !convert_func2)
{
GdkColorState *connection = GDK_COLOR_STATE_REC2100_LINEAR;
convert_func = gdk_color_state_get_convert_to (src_cs, connection);
convert_func2 = gdk_color_state_get_convert_from (dest_cs, connection);
}
tmp = g_malloc (sizeof (*tmp) * width);
for (gsize y = 0; y < height; y++)
{
desc->to_float (tmp, data, width);
if (desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
unpremultiply (tmp, width);
if (convert_func)
convert_func (src_cs, tmp, width);
if (convert_func2)
convert_func2 (dest_cs, tmp, width);
if (desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
premultiply (tmp, width);
desc->from_float (data, tmp, width);
data += stride;
}
g_free (tmp);
}

View File

@@ -37,31 +37,19 @@ 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;
@@ -95,11 +83,9 @@ const char * gdk_memory_format_get_name (GdkMemoryFormat
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,

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,
@@ -260,7 +217,7 @@ gdk_memory_texture_from_texture (GdkTexture *texture)
stride = texture->width * gdk_memory_format_bytes_per_pixel (texture->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, texture->format, data, stride);
bytes = g_bytes_new_take (data, stride * texture->height);
result = gdk_memory_texture_new (texture->width,
texture->height,

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
@@ -36,8 +35,6 @@ GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *
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

View File

@@ -29,14 +29,11 @@ gdk_subsurface_init (GdkSubsurface *self)
{
}
static void remove_subsurface (GdkSubsurface *subsurface);
static void
gdk_subsurface_finalize (GObject *object)
{
GdkSubsurface *subsurface = GDK_SUBSURFACE (object);
remove_subsurface (subsurface);
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
g_clear_object (&subsurface->parent);
@@ -147,7 +144,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkDihedral transform,
GdkTextureTransform transform,
const graphene_rect_t *background,
gboolean above,
GdkSubsurface *sibling)
@@ -159,8 +156,8 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
g_return_val_if_fail (source != NULL &&
gsk_rect_contains_rect (&GRAPHENE_RECT_INIT (0, 0,
gdk_dihedral_swaps_xy (transform) ? gdk_texture_get_height (texture) : gdk_texture_get_width (texture),
gdk_dihedral_swaps_xy (transform) ? gdk_texture_get_width (texture) : gdk_texture_get_height (texture)),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture)),
source), FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (sibling != subsurface, FALSE);
@@ -323,10 +320,10 @@ gdk_subsurface_get_sibling (GdkSubsurface *subsurface,
*
* Returns: the transform
*/
GdkDihedral
GdkTextureTransform
gdk_subsurface_get_transform (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), GDK_DIHEDRAL_NORMAL);
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), GDK_TEXTURE_TRANSFORM_NORMAL);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_transform (subsurface);
}

View File

@@ -20,7 +20,6 @@
#pragma once
#include "gdkenumtypes.h"
#include "gdkdihedralprivate.h"
#include "gdksurface.h"
#include <graphene.h>
@@ -48,6 +47,17 @@ struct _GdkSubsurface
GdkSubsurface *sibling_below;
};
typedef enum {
GDK_TEXTURE_TRANSFORM_NORMAL,
GDK_TEXTURE_TRANSFORM_90,
GDK_TEXTURE_TRANSFORM_180,
GDK_TEXTURE_TRANSFORM_270,
GDK_TEXTURE_TRANSFORM_FLIPPED,
GDK_TEXTURE_TRANSFORM_FLIPPED_90,
GDK_TEXTURE_TRANSFORM_FLIPPED_180,
GDK_TEXTURE_TRANSFORM_FLIPPED_270,
} GdkTextureTransform;
struct _GdkSubsurfaceClass
{
GObjectClass parent_class;
@@ -56,7 +66,7 @@ struct _GdkSubsurfaceClass
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkDihedral transform,
GdkTextureTransform transform,
const graphene_rect_t *bg,
gboolean above,
GdkSubsurface *sibling);
@@ -66,7 +76,7 @@ struct _GdkSubsurfaceClass
graphene_rect_t *rect);
void (* get_texture_rect) (GdkSubsurface *subsurface,
graphene_rect_t *rect);
GdkDihedral
GdkTextureTransform
(* get_transform) (GdkSubsurface *subsurface);
gboolean (* get_background_rect) (GdkSubsurface *subsurface,
graphene_rect_t *rect);
@@ -80,7 +90,7 @@ gboolean gdk_subsurface_attach (GdkSubsurface *subsu
GdkTexture *texture,
const graphene_rect_t *source,
const graphene_rect_t *dest,
GdkDihedral transform,
GdkTextureTransform transform,
const graphene_rect_t *background,
gboolean above,
GdkSubsurface *sibling);
@@ -93,7 +103,7 @@ void gdk_subsurface_get_texture_rect (GdkSubsurface *subsu
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
GdkSubsurface * gdk_subsurface_get_sibling (GdkSubsurface *subsurface,
gboolean above);
GdkDihedral
GdkTextureTransform
gdk_subsurface_get_transform (GdkSubsurface *subsurface);
gboolean gdk_subsurface_get_background_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect);

View File

@@ -72,12 +72,10 @@ struct _GdkSurfacePrivate
gpointer egl_native_window;
#ifdef HAVE_EGL
EGLSurface egl_surface;
GdkMemoryDepth egl_surface_depth;
gboolean egl_surface_high_depth;
#endif
gpointer widget;
GdkColorState *color_state;
};
enum {
@@ -477,8 +475,6 @@ gdk_surface_event_marshallerv (GClosure *closure,
static void
gdk_surface_init (GdkSurface *surface)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
/* 0-initialization is good for all other fields. */
surface->state = 0;
@@ -492,8 +488,6 @@ gdk_surface_init (GdkSurface *surface)
NULL, g_object_unref);
surface->subsurfaces = g_ptr_array_new ();
priv->color_state = gdk_color_state_ref (gdk_color_state_get_srgb ());
}
static double
@@ -751,7 +745,6 @@ static void
gdk_surface_finalize (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
g_clear_handle_id (&surface->request_motion_id, g_source_remove);
@@ -780,8 +773,6 @@ gdk_surface_finalize (GObject *object)
g_ptr_array_unref (surface->subsurfaces);
g_clear_pointer (&priv->color_state, gdk_color_state_unref);
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
}
@@ -1148,18 +1139,20 @@ gdk_surface_get_egl_surface (GdkSurface *self)
return priv->egl_surface;
}
GdkMemoryDepth
gdk_surface_ensure_egl_surface (GdkSurface *self,
GdkMemoryDepth depth)
void
gdk_surface_ensure_egl_surface (GdkSurface *self,
gboolean high_depth)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
GdkDisplay *display = gdk_surface_get_display (self);
g_return_val_if_fail (priv->egl_native_window != NULL, depth);
g_return_if_fail (priv->egl_native_window != NULL);
if (priv->egl_surface_depth != depth &&
priv->egl_surface != NULL &&
gdk_display_get_egl_config (display, priv->egl_surface_depth) != gdk_display_get_egl_config (display, depth))
if (gdk_display_get_egl_config_high_depth (display) == gdk_display_get_egl_config (display))
high_depth = FALSE;
if (priv->egl_surface_high_depth != high_depth &&
priv->egl_surface != NULL)
{
gdk_gl_context_clear_current_if_surface (self);
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
@@ -1172,32 +1165,22 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
int i;
i = 0;
if (depth == GDK_MEMORY_U8_SRGB && display->have_egl_gl_colorspace)
if (!high_depth && display->have_egl_gl_colorspace)
{
attribs[i++] = EGL_GL_COLORSPACE_KHR;
attribs[i++] = EGL_GL_COLORSPACE_SRGB_KHR;
self->is_srgb = TRUE;
}
g_assert (i < G_N_ELEMENTS (attribs));
attribs[i++] = EGL_NONE;
priv->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display),
gdk_display_get_egl_config (display, depth),
high_depth ? gdk_display_get_egl_config_high_depth (display)
: gdk_display_get_egl_config (display),
(EGLNativeWindowType) priv->egl_native_window,
attribs);
if (priv->egl_surface == EGL_NO_SURFACE)
{
/* just assume the error is no srgb support and try again without */
self->is_srgb = FALSE;
priv->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display),
gdk_display_get_egl_config (display, depth),
(EGLNativeWindowType) priv->egl_native_window,
NULL);
}
priv->egl_surface_depth = depth;
priv->egl_surface_high_depth = high_depth;
self->is_srgb = !high_depth && display->have_egl_gl_colorspace;
}
return priv->egl_surface_depth;
#endif
}
@@ -3114,26 +3097,3 @@ gdk_surface_get_subsurface (GdkSurface *surface,
{
return g_ptr_array_index (surface->subsurfaces, idx);
}
GdkColorState *
gdk_surface_get_color_state (GdkSurface *surface)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
return priv->color_state;
}
void
gdk_surface_set_color_state (GdkSurface *surface,
GdkColorState *color_state)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (surface);
if (gdk_color_state_equal (priv->color_state, color_state))
return;
gdk_color_state_unref (priv->color_state);
priv->color_state = gdk_color_state_ref (color_state);
gdk_surface_invalidate_rect (surface, NULL);
}

View File

@@ -21,7 +21,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "gdkenumtypes.h"
#include "gdkmemoryformatprivate.h"
#include "gdksurface.h"
#include "gdktoplevel.h"
#include <graphene.h>
@@ -300,8 +299,8 @@ void gdk_surface_set_frame_clock (GdkSurface
GdkFrameClock *clock);
void gdk_surface_set_egl_native_window (GdkSurface *self,
gpointer native_window);
GdkMemoryDepth gdk_surface_ensure_egl_surface (GdkSurface *self,
GdkMemoryDepth depth);
void gdk_surface_ensure_egl_surface (GdkSurface *self,
gboolean hdr);
gpointer /*EGLSurface*/ gdk_surface_get_egl_surface (GdkSurface *self);
gboolean gdk_surface_get_gl_is_srgb (GdkSurface *self);
@@ -343,6 +342,12 @@ void gdk_surface_queue_state_change (GdkSurface *surface,
void gdk_surface_apply_state_change (GdkSurface *surface);
void gdk_surface_emit_size_changed (GdkSurface *surface,
int width,
int height);
void gdk_surface_request_compute_size (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_request_motion (GdkSurface *surface);
@@ -353,8 +358,4 @@ gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
gsize idx);
GdkColorState * gdk_surface_get_color_state (GdkSurface *surface);
void gdk_surface_set_color_state (GdkSurface *surface,
GdkColorState *color_state);
G_END_DECLS

View File

@@ -40,14 +40,12 @@
#include "gdktextureprivate.h"
#include "gdkcairoprivate.h"
#include "gdkcolorstateprivate.h"
#include <glib/gi18n-lib.h>
#include "gdkmemorytextureprivate.h"
#include "gdkpaintable.h"
#include "gdksnapshot.h"
#include "gdktexturedownloaderprivate.h"
#include "gdkcolorstateprivate.h"
#include <glib/gi18n-lib.h>
#include <graphene.h>
#include "loaders/gdkpngprivate.h"
#include "loaders/gdktiffprivate.h"
@@ -262,7 +260,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkTexture, gdk_texture, G_TYPE_OBJECT,
static void
gdk_texture_default_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
@@ -288,8 +285,12 @@ gdk_texture_set_property (GObject *gobject,
break;
case PROP_COLOR_STATE:
self->color_state = g_value_dup_boxed (value);
g_assert (self->color_state);
if (self->color_state)
gdk_color_state_unref (self->color_state);
if (g_value_get_boxed (value))
self->color_state = gdk_color_state_ref (g_value_get_boxed (value));
else
self->color_state = GDK_COLOR_STATE_SRGB;
break;
default:
@@ -358,19 +359,11 @@ gdk_texture_dispose (GObject *object)
gdk_texture_clear_render_data (self);
g_clear_pointer (&self->color_state, gdk_color_state_unref);
G_OBJECT_CLASS (gdk_texture_parent_class)->dispose (object);
}
static void
gdk_texture_finalize (GObject *object)
{
GdkTexture *self = GDK_TEXTURE (object);
gdk_color_state_unref (self->color_state);
G_OBJECT_CLASS (gdk_texture_parent_class)->finalize (object);
}
static void
gdk_texture_class_init (GdkTextureClass *klass)
{
@@ -381,7 +374,6 @@ gdk_texture_class_init (GdkTextureClass *klass)
gobject_class->set_property = gdk_texture_set_property;
gobject_class->get_property = gdk_texture_get_property;
gobject_class->dispose = gdk_texture_dispose;
gobject_class->finalize = gdk_texture_finalize;
/**
* GdkTexture:width: (attributes org.gtk.Property.get=gdk_texture_get_width)
@@ -434,49 +426,16 @@ gdk_texture_class_init (GdkTextureClass *klass)
static void
gdk_texture_init (GdkTexture *self)
{
self->color_state = gdk_color_state_get_srgb ();
self->color_state = GDK_COLOR_STATE_SRGB;
}
static GdkMemoryFormat
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;
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;
}
}
/*<private>
/**
* gdk_texture_new_for_surface:
* @surface: a cairo image surface
*
* Creates a new texture object representing the surface.
*
* The @surface must be an image surface with a format supperted by GTK.
* The @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
*
* The newly created texture will acquire a reference on the @surface.
*
@@ -500,7 +459,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
cairo_format_to_memory_format (cairo_image_surface_get_format (surface)),
GDK_MEMORY_DEFAULT,
bytes,
cairo_image_surface_get_stride (surface));
@@ -803,30 +762,28 @@ gdk_texture_get_height (GdkTexture *texture)
/**
* gdk_texture_get_color_state: (attributes org.gtk.Method.get_property=color-state)
* @self: a `GdkTexture`
* @texture: a `GdkTexture`
*
* Returns the color state associated with the texture.
* Returns the color state associsated with @texture.
*
* Returns: (transfer none): the color state of the `GdkTexture`
*
* Since: 4.16
*/
GdkColorState *
gdk_texture_get_color_state (GdkTexture *self)
gdk_texture_get_color_state (GdkTexture *texture)
{
g_return_val_if_fail (GDK_IS_TEXTURE (self), NULL);
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
return self->color_state;
return texture->color_state;
}
void
gdk_texture_do_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride)
{
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, color_state, data, stride);
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
}
static gboolean
@@ -922,46 +879,22 @@ gdk_texture_set_diff (GdkTexture *self,
}
cairo_surface_t *
gdk_texture_download_surface (GdkTexture *texture,
GdkColorState *color_state)
gdk_texture_download_surface (GdkTexture *texture)
{
GdkMemoryDepth depth;
cairo_surface_t *surface;
cairo_status_t surface_status;
cairo_format_t surface_format;
GdkTextureDownloader downloader;
depth = gdk_texture_get_depth (texture);
#if 0
/* disabled for performance reasons. Enjoy living with some banding. */
if (!gdk_color_state_equal (texture->color_state, color_state))
depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (color_state));
#else
if (depth == GDK_MEMORY_U8_SRGB)
depth = GDK_MEMORY_U8;
#endif
surface_format = gdk_cairo_format_for_depth (depth);
surface = cairo_image_surface_create (surface_format,
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
surface_status = cairo_surface_status (surface);
if (surface_status != CAIRO_STATUS_SUCCESS)
{
g_warning ("%s: surface error: %s", __FUNCTION__,
cairo_status_to_string (surface_status));
return surface;
}
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader,
gdk_cairo_format_to_memory_format (surface_format));
gdk_texture_downloader_set_color_state (&downloader, color_state);
gdk_texture_downloader_download_into (&downloader,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
gdk_texture_downloader_finish (&downloader);
g_warning ("%s: surface error: %s", __FUNCTION__,
cairo_status_to_string (surface_status));
gdk_texture_download (texture,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
cairo_surface_mark_dirty (surface);
return surface;
@@ -1008,7 +941,6 @@ gdk_texture_download (GdkTexture *texture,
gdk_texture_do_download (texture,
GDK_MEMORY_DEFAULT,
GDK_COLOR_STATE_SRGB,
data,
stride);
}
@@ -1039,13 +971,6 @@ gdk_texture_get_format (GdkTexture *self)
return self->format;
}
GdkMemoryDepth
gdk_texture_get_depth (GdkTexture *self)
{
return gdk_memory_format_get_depth (self->format,
gdk_color_state_get_no_srgb_tf (self->color_state) != NULL);
}
gboolean
gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
@@ -1064,14 +989,6 @@ gdk_texture_set_render_data (GdkTexture *self,
return TRUE;
}
void
gdk_texture_steal_render_data (GdkTexture *self)
{
self->render_key = NULL;
self->render_data = NULL;
self->render_notify = NULL;
}
void
gdk_texture_clear_render_data (GdkTexture *self)
{
@@ -1219,4 +1136,3 @@ gdk_texture_save_to_tiff_bytes (GdkTexture *texture)
return gdk_save_tiff (texture);
}

View File

@@ -36,7 +36,6 @@
#include "gdktexturedownloaderprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdktextureprivate.h"
@@ -52,14 +51,12 @@ gdk_texture_downloader_init (GdkTextureDownloader *self,
{
self->texture = g_object_ref (texture);
self->format = GDK_MEMORY_DEFAULT;
self->color_state = gdk_color_state_ref (GDK_COLOR_STATE_SRGB);
}
void
gdk_texture_downloader_finish (GdkTextureDownloader *self)
{
g_object_unref (self->texture);
gdk_color_state_unref (self->color_state);
}
/**
@@ -68,9 +65,6 @@ gdk_texture_downloader_finish (GdkTextureDownloader *self)
*
* Creates a new texture downloader for @texture.
*
* By default, the downloader will convert the data to
* the default memory format, and to the sRGB color state.
*
* Returns: A new texture downloader
*
* Since: 4.10
@@ -205,45 +199,6 @@ gdk_texture_downloader_get_format (const GdkTextureDownloader *self)
return self->format;
}
/**
* gdk_texture_downloader_set_color_state:
* @self: a texture downloader
* @color_state: the color state to use
*
* Sets the color state the downloader will convert the data to.
*
* By default, the sRGB colorstate returned by [func@ColorState.get_srgb]
* is used.
*
* Since: 4.16
*/
void
gdk_texture_downloader_set_color_state (GdkTextureDownloader *self,
GdkColorState *color_state)
{
if (self->color_state == color_state)
return;
gdk_color_state_unref (self->color_state);
self->color_state = gdk_color_state_ref (color_state);
}
/**
* gdk_texture_downloader_get_color_state:
* @self: a texture downloader
*
* Gets the color state that the data will be downloaded in.
*
* Returns: The color state of the download
*
* Since: 4.16
**/
GdkColorState *
gdk_texture_downloader_get_color_state (const GdkTextureDownloader *self)
{
return self->color_state;
}
/**
* gdk_texture_downloader_download_into:
* @self: a texture downloader
@@ -264,7 +219,7 @@ gdk_texture_downloader_download_into (const GdkTextureDownloader *self,
g_return_if_fail (data != NULL);
g_return_if_fail (stride >= gdk_texture_get_width (self->texture) * gdk_memory_format_bytes_per_pixel (self->format));
gdk_texture_do_download (self->texture, self->format, self->color_state, data, stride);
gdk_texture_do_download (self->texture, self->format, data, stride);
}
/**
@@ -295,8 +250,7 @@ gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
g_return_val_if_fail (out_stride != NULL, NULL);
if (GDK_IS_MEMORY_TEXTURE (self->texture) &&
gdk_texture_get_format (self->texture) == self->format &&
gdk_color_state_equal (gdk_texture_get_color_state (self->texture), self->color_state))
gdk_texture_get_format (self->texture) == self->format)
{
GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture);
@@ -306,7 +260,7 @@ gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format);
data = g_malloc_n (stride, self->texture->height);
gdk_texture_do_download (self->texture, self->format, self->color_state, data, stride);
gdk_texture_do_download (self->texture, self->format, data, stride);
*out_stride = stride;
return g_bytes_new_take (data, stride * self->texture->height);

View File

@@ -30,7 +30,7 @@ G_BEGIN_DECLS
GDK_AVAILABLE_IN_4_10
GType gdk_texture_downloader_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_10
GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture);
GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture);
GDK_AVAILABLE_IN_4_10
GdkTextureDownloader * gdk_texture_downloader_copy (const GdkTextureDownloader *self);
@@ -48,11 +48,6 @@ void gdk_texture_downloader_set_format (GdkTextureDownl
GdkMemoryFormat format);
GDK_AVAILABLE_IN_4_10
GdkMemoryFormat gdk_texture_downloader_get_format (const GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_16
void gdk_texture_downloader_set_color_state (GdkTextureDownloader *self,
GdkColorState *color_state);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_texture_downloader_get_color_state (const GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_10

View File

@@ -28,7 +28,6 @@ struct _GdkTextureDownloader
/*< private >*/
GdkTexture *texture;
GdkMemoryFormat format;
GdkColorState *color_state;
};
void gdk_texture_downloader_init (GdkTextureDownloader *self,

View File

@@ -3,7 +3,6 @@
#include "gdktexture.h"
#include "gdkenums.h"
#include "gdkmemoryformatprivate.h"
G_BEGIN_DECLS
@@ -26,6 +25,7 @@ struct _GdkTexture
GdkMemoryFormat format;
int width;
int height;
GdkColorState *color_state;
gpointer render_key;
@@ -48,7 +48,6 @@ struct _GdkTextureClass {
/* mandatory: Download in the given format into data */
void (* download) (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride);
};
@@ -56,14 +55,10 @@ struct _GdkTextureClass {
gboolean gdk_texture_can_load (GBytes *bytes);
GdkTexture * gdk_texture_new_for_surface (cairo_surface_t *surface);
cairo_surface_t * gdk_texture_download_surface (GdkTexture *texture,
GdkColorState *color_state);
GdkMemoryDepth gdk_texture_get_depth (GdkTexture *self);
cairo_surface_t * gdk_texture_download_surface (GdkTexture *texture);
void gdk_texture_do_download (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
gsize stride);
void gdk_texture_diff (GdkTexture *self,
@@ -78,7 +73,6 @@ gboolean gdk_texture_set_render_data (GdkTexture
gpointer key,
gpointer data,
GDestroyNotify notify);
void gdk_texture_steal_render_data (GdkTexture *self);
void gdk_texture_clear_render_data (GdkTexture *self);
gpointer gdk_texture_get_render_data (GdkTexture *self,
gpointer key);

View File

@@ -745,10 +745,6 @@ gdk_toplevel_begin_move (GdkToplevel *toplevel,
* @toplevel: a `GdkToplevel`
* @gesture: a `GdkTitlebarGesture`
*
* Performs a title bar gesture.
*
* Returns: whether the gesture was performed
*
* Since: 4.4
*/
gboolean

View File

@@ -74,7 +74,6 @@ typedef cairo_rectangle_int_t GdkRectangle;
/* Forward declarations of commonly used types */
typedef struct _GdkRGBA GdkRGBA;
typedef struct _GdkCicpParams GdkCicpParams;
typedef struct _GdkColorState GdkColorState;
typedef struct _GdkContentFormats GdkContentFormats;
typedef struct _GdkContentProvider GdkContentProvider;
@@ -101,7 +100,7 @@ typedef struct _GdkVulkanContext GdkVulkanContext;
typedef struct _GdkDmabufFormats GdkDmabufFormats;
typedef struct _GdkDmabufTexture GdkDmabufTexture;
/*<private>
/*
* GDK_DECLARE_INTERNAL_TYPE:
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
* @module_obj_name: The name of the new type in lowercase, with words

View File

@@ -37,7 +37,10 @@
#ifdef GDK_RENDERING_VULKAN
static const GdkDebugKey gsk_vulkan_feature_keys[] = {
{ "dmabuf", GDK_VULKAN_FEATURE_DMABUF, "Never import Dmabufs" },
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures (also disables dmabufs)" },
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures" },
{ "descriptor-indexing", GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING, "Force slow descriptor set layout codepath" },
{ "dynamic-indexing", GDK_VULKAN_FEATURE_DYNAMIC_INDEXING, "Hardcode small number of buffer and texture arrays" },
{ "nonuniform-indexing", GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING, "Split draw calls to ensure uniform texture accesses" },
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
{ "semaphore-import", GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT, "Disable sync of imported dmabufs" },
{ "incremental-present", GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT, "Do not send damage regions" },
@@ -69,16 +72,16 @@ struct _GdkVulkanContextPrivate {
struct {
VkSurfaceFormatKHR vk_format;
GdkMemoryFormat gdk_format;
} formats[GDK_N_DEPTHS];
GdkMemoryDepth current_depth;
} formats[4];
GdkMemoryDepth current_format;
GdkMemoryFormat offscreen_formats[4];
VkSwapchainKHR swapchain;
VkSemaphore draw_semaphore;
guint n_images;
VkImage *images;
cairo_region_t **regions;
VkSemaphore draw_semaphore;
#endif
guint32 draw_index;
@@ -365,6 +368,14 @@ gdk_vulkan_context_dispose (GObject *gobject)
device = gdk_vulkan_context_get_device (context);
if (priv->draw_semaphore != VK_NULL_HANDLE)
{
vkDestroySemaphore (device,
priv->draw_semaphore,
NULL);
priv->draw_semaphore = VK_NULL_HANDLE;
}
if (priv->swapchain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR (device,
@@ -463,8 +474,8 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
.minImageCount = CLAMP (4,
capabilities.minImageCount,
capabilities.maxImageCount ? capabilities.maxImageCount : G_MAXUINT32),
.imageFormat = priv->formats[priv->current_depth].vk_format.format,
.imageColorSpace = priv->formats[priv->current_depth].vk_format.colorSpace,
.imageFormat = priv->formats[priv->current_format].vk_format.format,
.imageColorSpace = priv->formats[priv->current_format].vk_format.colorSpace,
.imageExtent = capabilities.currentExtent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
@@ -582,6 +593,23 @@ physical_device_check_features (VkPhysicalDevice device)
features = 0;
if (v10_features.features.shaderUniformBufferArrayDynamicIndexing &&
v10_features.features.shaderSampledImageArrayDynamicIndexing)
features |= GDK_VULKAN_FEATURE_DYNAMIC_INDEXING;
if (v12_features.descriptorIndexing &&
v12_features.descriptorBindingPartiallyBound &&
v12_features.descriptorBindingVariableDescriptorCount &&
v12_features.descriptorBindingSampledImageUpdateAfterBind &&
v12_features.descriptorBindingStorageBufferUpdateAfterBind)
features |= GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING;
else if (physical_device_supports_extension (device, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
features |= GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING;
if (v12_features.shaderSampledImageArrayNonUniformIndexing &&
v12_features.shaderStorageBufferArrayNonUniformIndexing)
features |= GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING;
if (ycbcr_features.samplerYcbcrConversion ||
physical_device_supports_extension (device, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME))
features |= GDK_VULKAN_FEATURE_YCBCR;
@@ -607,40 +635,29 @@ physical_device_check_features (VkPhysicalDevice device)
}
static void
gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
GdkColorState *color_state;
VkResult acquire_result;
guint i;
g_assert (priv->draw_semaphore != VK_NULL_HANDLE);
color_state = gdk_surface_get_color_state (surface);
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);
if (depth != priv->current_depth && depth != GDK_MEMORY_NONE)
if (depth != priv->current_format)
{
if (priv->formats[depth].vk_format.format != priv->formats[priv->current_depth].vk_format.format ||
priv->formats[depth].vk_format.colorSpace != priv->formats[priv->current_depth].vk_format.colorSpace)
if (priv->formats[depth].gdk_format != priv->formats[priv->current_format].gdk_format)
{
GdkMemoryDepth old_depth = priv->current_depth;
GdkMemoryDepth old_format = priv->current_format;
GError *error = NULL;
priv->current_depth = depth;
priv->current_format = depth;
if (!gdk_vulkan_context_check_swapchain (context, &error))
{
g_warning ("%s", error->message);
g_error_free (error);
priv->current_depth = old_depth;
priv->current_format = old_format;
return;
}
}
}
@@ -649,40 +666,31 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_union (priv->regions[i], region);
}
while (TRUE)
acquire_next_image:
acquire_result = GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
priv->swapchain,
UINT64_MAX,
priv->draw_semaphore,
VK_NULL_HANDLE,
&priv->draw_index);
if ((acquire_result == VK_ERROR_OUT_OF_DATE_KHR) ||
(acquire_result == VK_SUBOPTIMAL_KHR))
{
acquire_result = GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
priv->swapchain,
UINT64_MAX,
priv->draw_semaphore,
VK_NULL_HANDLE,
&priv->draw_index);
if ((acquire_result == VK_ERROR_OUT_OF_DATE_KHR) ||
(acquire_result == VK_SUBOPTIMAL_KHR))
GError *error = NULL;
GDK_DEBUG (VULKAN, "Recreating the swapchain");
if (!gdk_vulkan_context_check_swapchain (context, &error))
{
GError *error = NULL;
GDK_DEBUG (VULKAN, "Recreating the swapchain");
if (gdk_vulkan_context_check_swapchain (context, &error))
continue;
g_warning ("%s", error->message);
g_error_free (error);
return;
}
break;
}
priv->draw_semaphore = VK_NULL_HANDLE;
goto acquire_next_image;
}
cairo_region_union (region, priv->regions[priv->draw_index]);
if (priv->current_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_depth = priv->current_depth;
}
static void
@@ -728,8 +736,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
GDK_VK_CHECK (vkQueuePresentKHR, gdk_vulkan_context_get_queue (context),
&(VkPresentInfoKHR) {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 0,
.pWaitSemaphores = NULL,
.waitSemaphoreCount = 1,
.pWaitSemaphores = (VkSemaphore[]) {
priv->draw_semaphore
},
.swapchainCount = 1,
.pSwapchains = (VkSwapchainKHR[]) {
priv->swapchain
@@ -818,6 +828,11 @@ gdk_vulkan_context_real_init (GInitable *initable,
if (!priv->vulkan_ref)
return FALSE;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U16] = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT16] = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT32] = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (surface == NULL)
{
for (i = 0; i < G_N_ELEMENTS (priv->formats); i++)
@@ -869,37 +884,26 @@ gdk_vulkan_context_real_init (GInitable *initable,
switch ((int) formats[i].format)
{
case VK_FORMAT_B8G8R8A8_UNORM:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
case VK_FORMAT_B8G8R8A8_SRGB:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED ||
priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_B8G8R8A8_UNORM)
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
};
break;
case VK_FORMAT_R8G8B8A8_UNORM:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
case VK_FORMAT_R8G8B8A8_SRGB:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED ||
priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_R8G8B8A8_UNORM)
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
break;
case VK_FORMAT_B8G8R8A8_SRGB:
if (priv->formats[GDK_MEMORY_U8_SRGB].vk_format.format == VK_FORMAT_UNDEFINED)
{
priv->formats[GDK_MEMORY_U8_SRGB].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8_SRGB].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
}
break;
case VK_FORMAT_R8G8B8A8_SRGB:
if (priv->formats[GDK_MEMORY_U8_SRGB].vk_format.format == VK_FORMAT_UNDEFINED)
{
priv->formats[GDK_MEMORY_U8_SRGB].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8_SRGB].gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
break;
case VK_FORMAT_R16G16B16A16_UNORM:
priv->formats[GDK_MEMORY_U16].vk_format = formats[i];
priv->formats[GDK_MEMORY_U16].gdk_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
@@ -943,11 +947,17 @@ gdk_vulkan_context_real_init (GInitable *initable,
priv->formats[GDK_MEMORY_FLOAT16] = priv->formats[GDK_MEMORY_FLOAT32];
if (priv->formats[GDK_MEMORY_U16].vk_format.format == VK_FORMAT_UNDEFINED)
priv->formats[GDK_MEMORY_U16] = priv->formats[GDK_MEMORY_FLOAT32];
priv->formats[GDK_MEMORY_NONE] = priv->formats[GDK_MEMORY_U8];
if (!gdk_vulkan_context_check_swapchain (context, error))
goto out_surface;
GDK_VK_CHECK (vkCreateSemaphore, gdk_vulkan_context_get_device (context),
&(VkSemaphoreCreateInfo) {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
},
NULL,
&priv->draw_semaphore);
return TRUE;
}
@@ -959,6 +969,15 @@ out_surface:
return FALSE;
}
GdkMemoryFormat
gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
return priv->offscreen_formats[depth];
}
static void
gdk_vulkan_context_initable_init (GInitableIface *iface)
{
@@ -1167,7 +1186,7 @@ gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
file = gdk_vulkan_get_pipeline_cache_file (display);
GDK_DEBUG (VULKAN, "Saving pipeline cache of size %" G_GSIZE_FORMAT " to %s", size, g_file_peek_path (file));
GDK_DEBUG (VULKAN, "Saving pipeline cache of size %lu to %s", size, g_file_peek_path (file));
if (!g_file_replace_contents (file,
data,
@@ -1261,7 +1280,7 @@ gdk_display_create_pipeline_cache (GdkDisplay *display)
}
else
{
GDK_DEBUG (VULKAN, "Loading pipeline cache (%" G_GSIZE_FORMAT " bytes)", display->vk_pipeline_cache_size);
GDK_DEBUG (VULKAN, "Loading pipeline cache (%lu bytes)", display->vk_pipeline_cache_size);
}
}
@@ -1280,7 +1299,7 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context)
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_FORMAT_UNDEFINED);
return priv->formats[priv->current_depth].vk_format.format;
return priv->formats[priv->current_format].vk_format.format;
}
GdkMemoryFormat
@@ -1290,7 +1309,7 @@ gdk_vulkan_context_get_memory_format (GdkVulkanContext *context)
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), GDK_MEMORY_DEFAULT);
return priv->formats[priv->current_depth].gdk_format;
return priv->formats[priv->current_format].gdk_format;
}
/**
* gdk_vulkan_context_get_n_images:
@@ -1354,28 +1373,26 @@ gdk_vulkan_context_get_draw_index (GdkVulkanContext *context)
}
/**
* gdk_vulkan_context_set_draw_semaphore:
* gdk_vulkan_context_get_draw_semaphore:
* @context: a `GdkVulkanContext`
* @semaphore: a `VkSemaphore`
*
* Sets the Vulkan semaphore that will be used in the immediately following
* gdk_draw_context_begin_frame() call.
* This is essentially an extra argument for that call, but without extending the
* arguments of that generic function with Vulkan-specific things.
* Gets the Vulkan semaphore that protects access to the image that is
* currently being drawn.
*
* This function must be called or begin_frame() will abort.
* This function can only be used between [method@Gdk.DrawContext.begin_frame]
* and [method@Gdk.DrawContext.end_frame] calls.
*
* Returns: (transfer none): the VkSemaphore
*/
void
gdk_vulkan_context_set_draw_semaphore (GdkVulkanContext *context,
VkSemaphore semaphore)
VkSemaphore
gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
g_return_if_fail (GDK_IS_VULKAN_CONTEXT (context));
g_return_if_fail (!gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)));
g_return_if_fail (priv->draw_semaphore == VK_NULL_HANDLE);
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_NULL_HANDLE);
g_return_val_if_fail (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)), VK_NULL_HANDLE);
priv->draw_semaphore = semaphore;
return priv->draw_semaphore;
}
static gboolean
@@ -1410,8 +1427,6 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
skip_features = gdk_parse_debug_var ("GDK_VULKAN_DISABLE",
gsk_vulkan_feature_keys,
G_N_ELEMENTS (gsk_vulkan_feature_keys));
if (skip_features & GDK_VULKAN_FEATURE_YCBCR)
skip_features |= GDK_VULKAN_FEATURE_DMABUF;
override = g_getenv ("GDK_VULKAN_DEVICE");
list_devices = FALSE;
@@ -1512,6 +1527,8 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
device_extensions = g_ptr_array_new ();
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME);
if (features & GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING)
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
if (features & GDK_VULKAN_FEATURE_YCBCR)
{
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
@@ -1554,6 +1571,16 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
.pNext = &(VkPhysicalDeviceVulkan11Features) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
.samplerYcbcrConversion = ENABLE_IF (GDK_VULKAN_FEATURE_YCBCR),
.pNext = &(VkPhysicalDeviceVulkan12Features) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.shaderSampledImageArrayNonUniformIndexing = ENABLE_IF (GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING),
.shaderStorageBufferArrayNonUniformIndexing = ENABLE_IF (GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING),
.descriptorIndexing = ENABLE_IF (GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING),
.descriptorBindingPartiallyBound = ENABLE_IF (GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING),
.descriptorBindingVariableDescriptorCount = ENABLE_IF (GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING),
.descriptorBindingSampledImageUpdateAfterBind = ENABLE_IF (GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING),
.descriptorBindingStorageBufferUpdateAfterBind = ENABLE_IF (GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING),
}
}
},
NULL,
@@ -1625,7 +1652,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
uint32_t i;
GPtrArray *used_extensions;
gboolean have_debug_report = FALSE;
GPtrArray *used_layers;
gboolean validate = FALSE, have_debug_report = FALSE;
VkResult res;
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_DISABLE)
@@ -1674,6 +1702,43 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
}
uint32_t n_layers;
GDK_VK_CHECK (vkEnumerateInstanceLayerProperties, &n_layers, NULL);
VkLayerProperties *layers = g_newa (VkLayerProperties, n_layers);
GDK_VK_CHECK (vkEnumerateInstanceLayerProperties, &n_layers, layers);
used_layers = g_ptr_array_new ();
for (i = 0; i < n_layers; i++)
{
if (GDK_DISPLAY_DEBUG_CHECK (display, VULKAN))
g_print ("Layer available: %s v%u.%u.%u (%s)\n",
layers[i].layerName,
VK_VERSION_MAJOR (layers[i].specVersion),
VK_VERSION_MINOR (layers[i].specVersion),
VK_VERSION_PATCH (layers[i].specVersion),
layers[i].description);
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_VALIDATE)
{
const char *validation_layer_names[] = {
"VK_LAYER_LUNARG_standard_validation",
"VK_LAYER_KHRONOS_validation",
NULL,
};
if (g_strv_contains (validation_layer_names, layers[i].layerName))
{
g_ptr_array_add (used_layers, layers[i].layerName);
validate = TRUE;
}
}
}
if ((gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_VALIDATE) && !validate)
{
g_warning ("Vulkan validation layers were requested, but not found. Running without.");
}
res = GDK_VK_CHECK (vkCreateInstance, &(VkInstanceCreateInfo) {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = NULL,
@@ -1687,13 +1752,14 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
.engineVersion = VK_MAKE_VERSION (GDK_MAJOR_VERSION, GDK_MINOR_VERSION, GDK_MICRO_VERSION),
.apiVersion = VK_API_VERSION_1_3
},
.enabledLayerCount = 0,
.ppEnabledLayerNames = NULL,
.enabledLayerCount = used_layers->len,
.ppEnabledLayerNames = (const char * const *) used_layers->pdata,
.enabledExtensionCount = used_extensions->len,
.ppEnabledExtensionNames = (const char * const *) used_extensions->pdata,
},
NULL,
&display->vk_instance);
g_ptr_array_free (used_layers, TRUE);
g_ptr_array_free (used_extensions, TRUE);
if (res != VK_SUCCESS)

View File

@@ -99,9 +99,10 @@ uint32_t gdk_vulkan_context_get_n_images (GdkVulk
VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context,
guint id);
uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context);
VkSemaphore gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context);
void gdk_vulkan_context_set_draw_semaphore (GdkVulkanContext *context,
VkSemaphore semaphore);
GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth);
#else /* !GDK_RENDERING_VULKAN */

View File

@@ -24,8 +24,6 @@
#include <glib/gi18n-lib.h>
#include "gdktexture.h"
#include "gdktexturedownloaderprivate.h"
#include "gdkmemorytexturebuilder.h"
#include "gdkcolorstateprivate.h"
#include "gdkprofilerprivate.h"
@@ -78,6 +76,31 @@ output_message_handler (j_common_ptr cinfo)
/* }}} */
/* {{{ Format conversion */
static void
convert_grayscale_to_rgb (guchar *data,
int width,
int height,
int stride)
{
gsize x, y;
guchar *dest, *src;
for (y = 0; y < height; y++)
{
src = data + width;
dest = data + 3 * width;
for (x = 0; x < width; x++)
{
dest -= 3;
src -= 1;
dest[0] = *src;
dest[1] = *src;
dest[2] = *src;
}
data += stride;
}
}
static void
convert_cmyk_to_rgba (guchar *data,
int width,
@@ -108,7 +131,7 @@ convert_cmyk_to_rgba (guchar *data,
}
}
/* }}} */
/* }}} */
/* {{{ Public API */
GdkTexture *
@@ -121,10 +144,8 @@ gdk_load_jpeg (GBytes *input_bytes,
unsigned char *data = NULL;
unsigned char *row[1];
GBytes *bytes;
GdkMemoryTextureBuilder *builder;
GdkTexture *texture;
GdkMemoryFormat format;
GdkColorState *color_state;
G_GNUC_UNUSED guint64 before = GDK_PROFILER_CURRENT_TIME;
info.err = jpeg_std_error (&jerr.pub);
@@ -154,15 +175,9 @@ gdk_load_jpeg (GBytes *input_bytes,
width = info.output_width;
height = info.output_height;
color_state = GDK_COLOR_STATE_SRGB;
switch ((int)info.out_color_space)
{
case JCS_GRAYSCALE:
stride = width;
data = g_try_malloc_n (stride, height);
format = GDK_MEMORY_G8;
break;
case JCS_RGB:
stride = 3 * width;
data = g_try_malloc_n (stride, height);
@@ -196,31 +211,34 @@ gdk_load_jpeg (GBytes *input_bytes,
jpeg_read_scanlines (&info, row, 1);
}
if (info.out_color_space == JCS_CMYK)
convert_cmyk_to_rgba (data, width, height, stride);
switch ((int)info.out_color_space)
{
case JCS_GRAYSCALE:
convert_grayscale_to_rgb (data, width, height, stride);
format = GDK_MEMORY_R8G8B8;
break;
case JCS_RGB:
break;
case JCS_CMYK:
convert_cmyk_to_rgba (data, width, height, stride);
break;
default:
g_assert_not_reached ();
}
jpeg_finish_decompress (&info);
jpeg_destroy_decompress (&info);
bytes = g_bytes_new_take (data, stride * height);
builder = gdk_memory_texture_builder_new ();
texture = gdk_memory_texture_new (width, height,
format,
bytes, stride);
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_width (builder, width);
gdk_memory_texture_builder_set_height (builder, height);
gdk_memory_texture_builder_set_format (builder, format);
gdk_memory_texture_builder_set_color_state (builder, color_state);
texture = gdk_memory_texture_builder_build (builder);
gdk_color_state_unref (color_state);
g_object_unref (builder);
g_bytes_unref (bytes);
gdk_profiler_end_mark (before, "Load jpeg", NULL);
return texture;
}
@@ -274,7 +292,6 @@ gdk_save_jpeg (GdkTexture *texture)
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8);
gdk_texture_downloader_set_color_state (&downloader, GDK_COLOR_STATE_SRGB);
texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride);
gdk_texture_downloader_finish (&downloader);
texdata = g_bytes_get_data (texbytes, NULL);

View File

@@ -20,13 +20,11 @@
#include "gdkpngprivate.h"
#include <glib/gi18n-lib.h>
#include "gdkcolorstateprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytexturebuilder.h"
#include "gdkmemorytexture.h"
#include "gdkprofilerprivate.h"
#include "gdktexturedownloaderprivate.h"
#include "gsk/gl/fp16private.h"
#include <png.h>
#include <stdio.h>
@@ -128,141 +126,6 @@ png_simple_warning_callback (png_structp png,
{
}
/* }}} */
/* {{{ Color profile handling */
typedef struct
{
gboolean cicp_chunk_read;
int color_primaries;
int transfer_function;
int matrix_coefficients;
int range;
} CICPData;
static int
png_read_chunk_func (png_structp png,
png_unknown_chunkp chunk)
{
if (strcmp ((char *) chunk->name, "cICP") == 0 &&
chunk->size == 4)
{
CICPData *cicp = png_get_user_chunk_ptr (png);
cicp->cicp_chunk_read = TRUE;
cicp->color_primaries = chunk->data[0];
cicp->transfer_function = chunk->data[1];
cicp->matrix_coefficients = chunk->data[2];
cicp->range = chunk->data[3];
return 1;
}
return 0;
}
static GdkColorState *
gdk_png_get_color_state_from_cicp (const CICPData *data,
GError **error)
{
GdkCicp cicp;
cicp.color_primaries = data->color_primaries;
cicp.transfer_function = data->transfer_function;
cicp.matrix_coefficients= data->matrix_coefficients;
cicp.range = data->range;
return gdk_color_state_new_for_cicp (&cicp, error);
}
static GdkColorState *
gdk_png_get_color_state (png_struct *png,
png_info *info,
GError **error)
{
GdkColorState *color_state;
CICPData *cicp;
int intent;
cicp = png_get_user_chunk_ptr (png);
if (cicp->cicp_chunk_read)
{
GError *local_error = NULL;
color_state = gdk_png_get_color_state_from_cicp (cicp, &local_error);
if (color_state)
{
g_debug ("Color state from cICP data: %s", gdk_color_state_get_name (color_state));
return color_state;
}
else
{
g_set_error_literal (error,
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED_CONTENT,
local_error->message);
g_error_free (local_error);
}
}
#if 0
if (png_get_iCCP (png, info, &name, NULL, &icc_data, &icc_len))
{
}
#endif
if (png_get_sRGB (png, info, &intent))
return gdk_color_state_ref (GDK_COLOR_STATE_SRGB);
/* If neither of those is valid, the result is sRGB */
if (!png_get_valid (png, info, PNG_INFO_gAMA) &&
!png_get_valid (png, info, PNG_INFO_cHRM))
return GDK_COLOR_STATE_SRGB;
g_debug ("Failed to find color state, assuming SRGB");
return GDK_COLOR_STATE_SRGB;
}
static void
gdk_png_set_color_state (png_struct *png,
png_info *info,
GdkColorState *color_state,
png_byte *chunk_data)
{
const GdkCicp *cicp;
cicp = gdk_color_state_get_cicp (color_state);
if (cicp)
{
png_unknown_chunk chunk = {
.name = { 'c', 'I', 'C', 'P', '\0' },
.data = chunk_data,
.size = 4,
.location = PNG_HAVE_IHDR,
};
chunk_data[0] = (png_byte) cicp->color_primaries;
chunk_data[1] = (png_byte) cicp->transfer_function;
chunk_data[2] = (png_byte) 0; /* png only supports this */
chunk_data[3] = (png_byte) cicp->range;
png_set_unknown_chunks (png, info, &chunk, 1);
}
else
{
/* unsupported color state. Fall back to sRGB */
gdk_color_state_unref (color_state);
color_state = gdk_color_state_ref (gdk_color_state_get_srgb ());
}
/* For good measure, we add an sRGB chunk too */
if (gdk_color_state_equal (color_state, GDK_COLOR_STATE_SRGB))
png_set_sRGB (png, info, PNG_sRGB_INTENT_PERCEPTUAL);
}
/* }}} */
/* {{{ Public API */
@@ -280,16 +143,12 @@ gdk_load_png (GBytes *bytes,
gsize i, stride;
int depth, color_type;
int interlace;
GdkMemoryTextureBuilder *builder;
GdkMemoryFormat format;
guchar *buffer = NULL;
guchar **row_pointers = NULL;
GBytes *out_bytes;
GdkColorState *color_state;
GdkTexture *texture;
int bpp;
CICPData cicp = { FALSE, };
G_GNUC_UNUSED gint64 before = GDK_PROFILER_CURRENT_TIME;
io.data = (guchar *)g_bytes_get_data (bytes, &io.size);
@@ -310,7 +169,6 @@ gdk_load_png (GBytes *bytes,
g_error ("Out of memory");
png_set_read_fn (png, &io, png_read_func);
png_set_read_user_chunk_fn (png, &cicp, png_read_chunk_func);
if (sigsetjmp (png_jmpbuf (png), 1))
{
@@ -408,10 +266,6 @@ gdk_load_png (GBytes *bytes,
return NULL;
}
color_state = gdk_png_get_color_state (png, info, error);
if (color_state == NULL)
return NULL;
bpp = gdk_memory_format_bytes_per_pixel (format);
if (!g_size_checked_mul (&stride, width, bpp) ||
!g_size_checked_add (&stride, stride, (8 - stride % 8) % 8))
@@ -427,7 +281,6 @@ gdk_load_png (GBytes *bytes,
if (!buffer || !row_pointers)
{
gdk_color_state_unref (color_state);
g_free (buffer);
g_free (row_pointers);
png_destroy_read_struct (&png, &info, NULL);
@@ -444,17 +297,8 @@ gdk_load_png (GBytes *bytes,
png_read_end (png, info);
out_bytes = g_bytes_new_take (buffer, height * stride);
builder = gdk_memory_texture_builder_new ();
gdk_memory_texture_builder_set_format (builder, format);
gdk_memory_texture_builder_set_color_state (builder, color_state);
gdk_memory_texture_builder_set_width (builder, width);
gdk_memory_texture_builder_set_height (builder, height);
gdk_memory_texture_builder_set_bytes (builder, out_bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
texture = gdk_memory_texture_builder_build (builder);
g_object_unref (builder);
texture = gdk_memory_texture_new (width, height, format, out_bytes, stride);
g_bytes_unref (out_bytes);
gdk_color_state_unref (color_state);
if (options && png_get_text (png, info, &text, &num_texts))
{
@@ -493,14 +337,11 @@ gdk_save_png (GdkTexture *texture)
GBytes *bytes;
gsize stride;
const guchar *data;
GdkColorState *color_state;
int png_format;
int depth;
png_byte chunk_data[4];
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
color_state = gdk_texture_get_color_state (texture);
format = gdk_texture_get_format (texture);
switch (format)
@@ -595,8 +436,6 @@ gdk_save_png (GdkTexture *texture)
/* 2^31-1 is the maximum size for PNG files */
png_set_user_limits (png, (1u << 31) - 1, (1u << 31) - 1);
png_set_keep_unknown_chunks (png, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0);
info = png_create_info_struct (png);
if (!info)
{
@@ -604,13 +443,15 @@ gdk_save_png (GdkTexture *texture)
return NULL;
}
gdk_color_state_ref (color_state);
bytes = NULL;
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, format);
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
gdk_texture_downloader_finish (&downloader);
data = g_bytes_get_data (bytes, NULL);
if (sigsetjmp (png_jmpbuf (png), 1))
{
gdk_color_state_unref (color_state);
g_clear_pointer (&bytes, g_bytes_unref);
g_bytes_unref (bytes);
g_free (io.data);
png_destroy_read_struct (&png, &info, NULL);
return NULL;
@@ -624,20 +465,12 @@ gdk_save_png (GdkTexture *texture)
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
gdk_png_set_color_state (png, info, color_state, chunk_data);
png_write_info (png, info);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
png_set_swap (png);
#endif
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, format);
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
gdk_texture_downloader_finish (&downloader);
data = g_bytes_get_data (bytes, NULL);
for (y = 0; y < height; y++)
png_write_row (png, data + y * stride);
@@ -645,7 +478,6 @@ gdk_save_png (GdkTexture *texture)
png_destroy_write_struct (&png, &info);
gdk_color_state_unref (color_state);
g_bytes_unref (bytes);
return g_bytes_new_take (io.data, io.size);

View File

@@ -785,13 +785,20 @@ typedef NSString *CALayerContentsGravity;
if (decorated)
{
style_mask |= NSWindowStyleMaskTitled;
style_mask &= ~NSWindowStyleMaskFullSizeContentView;
[self setTitleVisibility:NSWindowTitleVisible];
}
else
{
style_mask &= ~NSWindowStyleMaskTitled;
style_mask |= NSWindowStyleMaskFullSizeContentView;
[self setTitleVisibility:NSWindowTitleHidden];
}
[self setTitlebarAppearsTransparent:!decorated];
[[self standardWindowButton:NSWindowCloseButton] setHidden:!decorated];
[[self standardWindowButton:NSWindowMiniaturizeButton] setHidden:!decorated];
[[self standardWindowButton:NSWindowZoomButton] setHidden:!decorated];
[self setStyleMask:style_mask];
}

View File

@@ -197,11 +197,9 @@ clamp_region_to_surface (cairo_region_t *region,
}
static void
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
GdkMacosBuffer *buffer;
@@ -251,9 +249,6 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_destroy (copy);
}
}
*out_color_state = GDK_COLOR_STATE_SRGB;
*out_depth = gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
}
static void

View File

@@ -176,7 +176,6 @@ void _gdk_macos_display_set_drop (GdkMacosDisp
GdkDrop *drop);
void _gdk_macos_display_position_surface (GdkMacosDisplay *self,
GdkMacosSurface *surface,
GdkMonitor *monitor,
int *x,
int *y);

View File

@@ -32,6 +32,7 @@
#include "gdk/gdkeventsprivate.h"
#define GDK_MOD2_MASK (1 << 4)
#define GRIP_WIDTH 15
#define GRIP_HEIGHT 15
#define GDK_LION_RESIZE 5
@@ -174,7 +175,7 @@ get_keyboard_modifiers_from_ns_flags (NSUInteger nsflags)
if (nsflags & NSEventModifierFlagOption)
modifiers |= GDK_ALT_MASK;
if (nsflags & NSEventModifierFlagCommand)
modifiers |= GDK_META_MASK;
modifiers |= GDK_MOD2_MASK;
return modifiers;
}
@@ -313,6 +314,13 @@ get_group_from_ns_event (NSEvent *nsevent)
return ([nsevent modifierFlags] & NSEventModifierFlagOption) ? 1 : 0;
}
static void
add_virtual_modifiers (GdkModifierType *state)
{
if (*state & GDK_MOD2_MASK)
*state |= GDK_META_MASK;
}
static GdkEvent *
fill_key_event (GdkMacosDisplay *display,
GdkMacosSurface *surface,
@@ -359,7 +367,7 @@ fill_key_event (GdkMacosDisplay *display,
{
case GDK_KEY_Meta_R:
case GDK_KEY_Meta_L:
mask = GDK_META_MASK;
mask = GDK_MOD2_MASK;
break;
case GDK_KEY_Shift_R:
case GDK_KEY_Shift_L:
@@ -387,6 +395,7 @@ fill_key_event (GdkMacosDisplay *display,
}
state |= _gdk_macos_display_get_current_mouse_modifiers (display);
add_virtual_modifiers (&state);
translated.keyval = keyval;
translated.consumed = consumed;

View File

@@ -82,7 +82,6 @@ has_surface_at_origin (const GList *surfaces,
static void
_gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
GdkMacosSurface *surface,
GdkMonitor *selected_monitor,
int *x,
int *y)
{
@@ -96,11 +95,7 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
mouse = [NSEvent mouseLocation];
if (!selected_monitor)
monitor = _gdk_macos_display_get_monitor_at_display_coords (self, mouse.x, mouse.y);
else
monitor = selected_monitor;
monitor = _gdk_macos_display_get_monitor_at_display_coords (self, mouse.x, mouse.y);
gdk_macos_monitor_get_workarea (monitor, &workarea);
/* First place at top-left of current monitor */
@@ -109,7 +104,7 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
surface_rect.x = workarea.x + ((workarea.width - surface_rect.width) / 2);
surface_rect.y = workarea.y + ((workarea.height - surface_rect.height) / 2);
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (selected_monitor ? selected_monitor : surface->best_monitor), &surface_rect);
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (surface->best_monitor), &surface_rect);
*x = surface_rect.x;
*y = surface_rect.y;
@@ -143,7 +138,6 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
void
_gdk_macos_display_position_surface (GdkMacosDisplay *self,
GdkMacosSurface *surface,
GdkMonitor *monitor,
int *x,
int *y)
{
@@ -157,5 +151,5 @@ _gdk_macos_display_position_surface (GdkMacosDisplay *self,
if (transient_for != NULL)
_gdk_macos_display_position_toplevel_with_parent (self, surface, GDK_MACOS_SURFACE (transient_for), x, y);
else
_gdk_macos_display_position_toplevel (self, surface, monitor, x, y);
_gdk_macos_display_position_toplevel (self, surface, x, y);
}

View File

@@ -478,11 +478,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
}
static void
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
GdkMemoryDepth depth,
cairo_region_t *region,
GdkColorState **out_color_state,
GdkMemoryDepth *out_depth)
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
GdkMacosBuffer *buffer;
@@ -500,7 +498,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
gdk_macos_gl_context_allocate (self);
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, depth, region, out_color_state, out_depth);
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, depth, region);
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
CHECK_GL (NULL, glBindFramebuffer (GL_FRAMEBUFFER, self->fbo));

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