Compare commits

...

76 Commits

Author SHA1 Message Date
Matthias Clasen 1ae7240932 Update callers
Adapt all our tests and examples to the new initialization api.
2016-12-28 18:57:55 -05:00
Matthias Clasen a3e2fc2df6 Drop gdk init api
Supporting separately initialized gdk is just not worth it.
2016-12-28 18:57:39 -05:00
Matthias Clasen deed306e5a Drop arguments from gtk_init
This is our ultimate goal: no more commandline argument handling.
Lots of callers will have to be updated.
2016-12-28 08:49:37 -05:00
Matthias Clasen 9cc64449a8 Simplify initialization code
Now that gtk_get_option_group and gtk_parse_args are no longer
public, we can get rid of them.
2016-12-28 07:46:56 -05:00
Matthias Clasen 72877343fd Drop the --gtk-debug and --gtk-no-debug options
We have environment variables that cover this.
2016-12-27 18:49:30 -05:00
Matthias Clasen 8a816dbc19 Drop the --g-fatal-warnings argument
We don't need it, GLib has an environment variable for this.
2016-12-27 18:48:02 -05:00
Matthias Clasen 002d616ca4 Drop the --gtk-modules argument
We don't need it; the environment variable is enough.
2016-12-27 18:46:45 -05:00
Matthias Clasen 3ea1b37aff Don't export gtk_get_option_group
We want to get rid of commandline option handling in GTK+.
This is a step in that direction.
2016-12-27 18:45:53 -05:00
Matthias Clasen 1d6435db48 Stop exporting gtk_parse_args
We want to stop handling commandline arguments, and that is the
sole purpose of this function. So it has to go
2016-12-27 18:36:19 -05:00
Matthias Clasen 5b411031ba Drop gtk_init_with_args
We want to simplify our initialization code and remove all commandline
argument handling from it. The first stop for this is to reduce the
number of gtk_init variants we have.
2016-12-27 18:31:03 -05:00
Benjamin Otte 68b39a4727 gsk: Add GSK_RENDERING_MODE=full-redraw
Forces a full redraw every frame.
This is done generically, so it's supported on every renderer.

For widget-factory first page (with the spinner spinning and progressbar
pulsing), I get these numbers per frame:

action                  clipped         full redraw
snapshot                   0ms           7-10ms
cairo rendering            0ms          10-15ms
Vulkan rendering         3-5ms          18-20ms
Vulkan expected *          0ms            1-2ms
GL rendering            unsupported     55-62ms

* expected means disabling rendering of unsupported render nodes,
instead of doing fallback drawing. So it overestimates the performance,
because borders and box-shadows are disabled.
2016-12-27 00:48:00 +01:00
Benjamin Otte a5f8a74ec1 vulkan: Only render minimal region
It's faster to render once for every rectangle in the clip region than
rendering the outline of the clip region.
Especially because this reduces the time necessary to build up the frame
data.

In widget-factory (where we have 3 rectangles), this leads to a 5x
speedup in the rendering time rendering alone.
Snapshotting time goes from 10ms to ~1ms, which is another huge
improvement.
2016-12-27 00:31:33 +01:00
Benjamin Otte 293248c1d3 gdkvulkan: Track changes per swapchain image
... and use those in begin_frame() to ensure all of the invalid area
gets invalidated.
2016-12-26 22:24:22 +01:00
Benjamin Otte af917c4ade vulkan: Handle linear gradients
Note: We interpolate premultiplied colors as per the CSS spec. This i
different from Cairo, which interpolates unpremultiplied.

So in testcases with translucent gradients, it's actually Cairo that is
wrong.
2016-12-26 17:22:02 +01:00
Benjamin Otte c0c44c7b9c tests: Add linear gradient test 2016-12-26 17:22:02 +01:00
Benjamin Otte 573ceb0340 tests: Add a patternspec argument for test creation
That way, I don't need to recreate all the tests I don't care about.

This is particularly useful when I want to change the size of the
testcase.
2016-12-26 17:22:01 +01:00
Benjamin Otte d7e867aa95 tests: Make rendernode --dump-variant actually work 2016-12-26 17:22:01 +01:00
Benjamin Otte 3c8518dce3 gsk: Add missing Mozilla copyright header
I stole one of their shader functions, and if I steal, I might as well
do it right.
2016-12-26 17:22:01 +01:00
Benjamin Otte 599cc995f3 css: Handle repeating gradients with only one offset
Example:
  repeating-linear-gradient(red 50%, blue 50%)

Those gradients in Firefox draw a solid image of the last color, so do
the same here.
2016-12-26 17:22:01 +01:00
Benjamin Otte 5017c3be65 gsk: Insist on ordered color stops
I don't want to sort them later for the shader preparation, so make
sure they come in ordered.
2016-12-26 17:22:01 +01:00
Benjamin Otte 3a79b17309 vulkan: Fix coordinate setup
This makes rendering textures work when the top left of the rendered
texture is not at (0, 0).
2016-12-26 17:22:01 +01:00
Benjamin Otte c7083a5d37 tests: Make sure number of runs is 1. 2016-12-26 17:22:01 +01:00
Daniel Boles 2a7171534e Box: Restore an accidentally deleted comment
Also, split a MAX() onto its own line to match the others.
2016-12-26 10:57:51 +00:00
Daniel Boles 71bbd8881f Box: avoid recalc/reassignments, improve var names
Homogeneous branches repeated the calculation/assignment of the initial
space available to children. This avoids that by shuffling some code.

Perhaps more importantly, in doing that, I ended up with some ambiguous
names, and Company and I realised how vague the pre-existing naming was.
"size" becomes "extra_space", as this is what it represents. Conversely,
"extra" becomes "size_given_to_child" (albeit still given out in two
different ways depending on whether the Box is homogeneous). My hope is
that these sections of code are now somewhat less baffling than before!
2016-12-25 23:16:14 +00:00
Daniel Boles 5d10174031 Box: Don't unnecessarily repeat a function call
The spacing was already saved in a variable just above.
2016-12-25 21:46:40 +00:00
djb 476cadc7f8 tests: Remove executable bit from C files 2016-12-25 21:46:40 +00:00
Benjamin Otte 78582dd5e9 tests: Fix logic to detect argument length 2016-12-25 06:23:12 +01:00
Benjamin Otte eacf725778 tests: Add a --runs argument to rendernode
This way we can rerun fast tests lots of times - not so much for
averaging times, but more for sysprof'ing.
2016-12-25 06:23:12 +01:00
Benjamin Otte c99b46c46d tests: Add another test
In this test, Cairo is almost as fast as Vulkan. I wonder why.
2016-12-25 06:23:12 +01:00
Benjamin Otte 5878f9d8af vulkan: Add shader for color drawing with rectangle clip 2016-12-25 06:23:12 +01:00
Benjamin Otte b30225e67c vulkan: We use VK_FORMAT_B8G8R8A8_UNORM
... not SRGB. SRGB messes up alpha compositing, GdkRGBA and everything
else.
2016-12-25 06:23:12 +01:00
Marek Černocký 16a9a82021 Updated Czech translation 2016-12-24 14:40:35 +01:00
Benjamin Otte aa0ec774bf vulkan: Add proof-of-concept clip implementation
We can now clip to cicular rounded rectangles when drawing colors.
2016-12-24 06:19:16 +01:00
Benjamin Otte 81c487b841 vulkan: Fold clip into push constants
As a side effect, the clipping data is now available inside shaders.

Not that any shader would use them yet, but they could!
2016-12-24 06:19:16 +01:00
Benjamin Otte 18b65a2378 vulkan: Change handling of push constants
Instead of storing the wire format, store the true structs and only
convert to the wire format when needed.
2016-12-24 06:19:16 +01:00
Benjamin Otte b11b7dfb1a gsk: Add debug category for fallbacks
... and use it for the cases in Vulkan where we fall back to Cairo.
2016-12-24 06:19:16 +01:00
Benjamin Otte 2bca24c455 gsk: Add GskVulkanClip
This is now tracking the clips added by the clip nodes.
If any particular node can't deal with a clip, it falls back to Cairo
rendering. But if it can, it will render it directly.
2016-12-24 06:19:16 +01:00
Benjamin Otte 1d84555729 iconhelper: Invalidate style before accessing texture
Invalidating the style might cause invalidation of the texture. So we
end up with a pointer to freed memory.
SAD!
2016-12-24 06:19:16 +01:00
Benjamin Otte 89d38ae93f vulkan: Try combining draw calls
This gives a 5-7% speedup in the case where we're just drawing N colors
and nothing else. So it;s not tremendously useful, but noticeable.
2016-12-24 06:19:16 +01:00
Garrett Regier 23d10df6c6 gsk: Fix memory leak in gsk_render_node_write_to_file() 2016-12-23 07:22:41 -08:00
Piotr Drąg 2750bb5e87 Update POTFILES.in 2016-12-23 16:18:23 +01:00
Benjamin Otte 6cc08d60ef calendar: Implement snapshot() 2016-12-23 12:07:22 +01:00
Benjamin Otte b97e4e8631 tests: Improve rendernode test further
- Print benchmark output in fallback path
- Always run rendering, even when no filename given
- Don't require a filename when running with --benchmark
2016-12-23 11:31:35 +01:00
Benjamin Otte a36e5ceea7 cellrenderer: Remove render() vfunc
Make the last 2 cell renderers create the cairo node themselves.
2016-12-23 11:11:52 +01:00
Benjamin Otte 513a8c46af cellrendererpixbuf: Implement snapshot() 2016-12-23 10:50:04 +01:00
Benjamin Otte a0f65d16bc cellrendererprogress: Implement snapshot() 2016-12-23 10:44:49 +01:00
Benjamin Otte b901572d86 cellrenderertoggle: Implement snapshot() 2016-12-23 09:31:54 +01:00
Benjamin Otte c412a717f1 cellrenderertext: Implement snapshot() 2016-12-23 09:23:07 +01:00
Benjamin Otte 677c5bdedf cellrenderer: Move snapshotting down into cell renderers
Now that every call to GtkCellArea is a snapshot call and no more cairo
calls are left, move the actual differentiation between Cairo and
Snapshot down to the cell renderer.
2016-12-23 09:23:04 +01:00
Benjamin Otte af6e7cc169 tests: Add rendernode-create-tests
Little tool that creates a bunch of test files to throw add the
rendernode binary.
They should really be part of a testsuite, but we have none, so OI just
put them here.
2016-12-23 08:11:01 +01:00
Benjamin Otte 4bb0c70c11 gsk: Add docs and error handling to serialization API 2016-12-23 08:11:01 +01:00
Benjamin Otte 4e866ec06b tests: Add some command-line flags to rendernode 2016-12-23 08:11:01 +01:00
Benjamin Otte 5e089c4345 gsk: Add gsk_render_node_write_to_file()
For when you're in a debugger and need to have a closer look at this
node...
2016-12-23 08:11:01 +01:00
Benjamin Otte 087ea8e531 gsk: Warn on cairo errors during gsk_render_node_draw()
It's the same warning we use inside GTK for when stuff weirdly goes
wrong.
2016-12-23 08:11:01 +01:00
Benjamin Otte 08f9a6078b gsk: Include config.h
The more you know:
Not including config.h causes the public API implemented in this file to
not be exported in the resulting library.
2016-12-23 08:11:01 +01:00
Benjamin Otte adcde3034e gsk: Implement gsk_renderer_render_texture() on GL 2016-12-23 08:11:01 +01:00
Benjamin Otte 786d3a013e vulkan: Implement gsk_renderer_render_texture() 2016-12-23 08:11:01 +01:00
Benjamin Otte b0d5224de5 tests: Use gsk_renderer_render_texture()
Only keep the version that calls gsk_render_node_draw() if people
specify the --fallback option.

The actual renderer selection works just as for regular GTK. The easiest
way to influence it is setting the GSK_RENDERER environment variable.
2016-12-23 08:11:01 +01:00
Benjamin Otte 6c56793147 gsk: Add gsk_texture_download() API
Now users can download pixels and make everything slooooooow.
2016-12-23 08:11:01 +01:00
Benjamin Otte d58799ff7a gdk: Export gdk_cairo_surface_paint_pixbuf() into private header 2016-12-23 08:11:01 +01:00
Benjamin Otte be8c999fe8 docs: Add GskTexture 2016-12-23 08:11:01 +01:00
Benjamin Otte 2d2209859e gsk: Rename to gsk_texture_download_surface()
I want to reuse the name gsk_texture_download() for downloading the
actual bytes.
2016-12-23 08:11:01 +01:00
Benjamin Otte 373e08d6d4 gsk: Add gsk_renderer_render_texture()
... and implement it for the Cairo renderer.

It's an API that instructs a renderer to render to a texture.
So far this is mostly meant to be used for testing, but I could imagine
it being useful for rendering DND icons.
2016-12-23 08:11:01 +01:00
Benjamin Otte 98086014d8 gskcairo: Don't store the viewport in the global struct
Just query it locally.
2016-12-23 08:11:01 +01:00
Benjamin Otte d2622d93ad gsk: Don't overdraw with transparent
That code doesn't do anything.

And what the code should be doing (clearing the abckground) isn't
necessary as cairo drawing is guaranteed to clear the surface.
2016-12-23 08:11:01 +01:00
Benjamin Otte df5e12fc1d rendernode: Fix typo 2016-12-23 08:11:00 +01:00
Benjamin Otte 814b66e1a8 gsk: Remove nonexisting functions
The function was removed when gsk_render_node_draw() was and
gsk_renderer_realize() was refactored respectively.
2016-12-23 08:11:00 +01:00
Benjamin Otte b4ac7ffed4 tests: Add a simple test to convert rendernode to png
Takes a rendernode file, outputs a PNG. Nothing more.
2016-12-23 08:11:00 +01:00
Benjamin Otte 735846cc82 gsk: Export gsk_render_node_get_bounds()
I'll need it in tests/testsuite soon.
2016-12-23 08:11:00 +01:00
Benjamin Otte 91c71b10e6 inspector: Add a render node save button
Now we can select buggy nodes, save them to a file, and add that file to
our testsuite.
2016-12-23 08:11:00 +01:00
Benjamin Otte c88d279416 gsk: Add gsk_render_node_serialize/deserialize()
This does a conversion to/from GBytes and is intended for writing tests.

It's really crude but it works.
And that probably means Alex will (ab)use it for broadway.
2016-12-23 08:11:00 +01:00
Benjamin Otte 3a38bc9bf7 gsk: Remove spread member from GskShadow
I had originally thought I'd use GskShadow for box-shadow, but didn't in
the end.

So now it's only used for text-shadow and icon-shadow, and those don't
have a spread.
2016-12-23 08:11:00 +01:00
Marek Černocký 5fa1733944 Updated Czech translation 2016-12-22 23:50:53 +01:00
Benjamin Otte 0efeaf9508 treeview: Port rest of stuff to snapshot()
The only thing still drawn with Cairo are grid lines.
2016-12-22 03:37:32 +01:00
Benjamin Otte f1825f5eff treeview: Partially convert to snapshot()
The big fat scary bin drawing function that actually draws the cell
renderers - that one is still missing.
2016-12-22 03:37:32 +01:00
Chun-wei Fan 23edff1606 gtkcssimagelinear.c: Avoid VLAs
VLAs are not supported by Visual Studio and possibly other compilers that
are supported by GTK+-3.90+, and probably never will be, although it is a
C99 specification, and it became optional for C11.  It is also not a part
of the newer compiler requirements that are listed out for GTK+-3.90.x.

There exist concerns about the implementation of VLAs in compilers that
support them as well, so change it to a g_newa() approach.

https://bugzilla.gnome.org/show_bug.cgi?id=773299
2016-12-22 08:40:32 +08:00
247 changed files with 5259 additions and 1957 deletions
+27
View File
@@ -12,6 +12,7 @@ gsk_renderer_unrealize
gsk_renderer_begin_draw_frame
gsk_renderer_end_draw_frame
gsk_renderer_render
gsk_renderer_render_texture
<SUBSECTION Standard>
GSK_IS_RENDERER
GSK_RENDERER
@@ -29,9 +30,15 @@ gsk_render_node_unref
GskRenderNodeType
gsk_render_node_get_node_type
gsk_render_node_draw
GskSerializationError
gsk_render_node_serialize
gsk_render_node_deserialize
gsk_render_node_write_to_file
GskScalingFilter
gsk_render_node_set_scaling_filters
gsk_render_node_set_name
gsk_render_node_get_name
gsk_render_node_get_bounds
gsk_color_node_new
gsk_linear_gradient_node_new
gsk_repeating_linear_gradient_node_new
@@ -66,6 +73,26 @@ GskRenderNode
GskRenderNodeClass
gsk_render_node_get_type
GSK_TYPE_BLEND_MODE
<SUBSECTION Standard>
gsk_serialization_error_quark
GSK_SERIALIZATION_ERROR
GSK_TYPE_SERIALIZATION_ERROR
</SECTION>
<SECTION>
<FILE>GskTexture</FILE>
gsk_texture_ref
gsk_texture_unref
gsk_texture_new_for_data
gsk_texture_new_for_pixbuf
gsk_texture_get_width
gsk_texture_get_height
gsk_texture_download
<SUBSECTION Standard>
GskTexture
gsk_texture_get_type
GSK_TYPE_TEXTURE
GSK_IS_TEXTURE
</SECTION>
<SECTION>
+2 -2
View File
@@ -4052,7 +4052,7 @@ gtk_cell_area_has_renderer
gtk_cell_area_foreach
gtk_cell_area_foreach_alloc
gtk_cell_area_event
gtk_cell_area_render
gtk_cell_area_snapshot
gtk_cell_area_get_cell_allocation
gtk_cell_area_get_cell_at_position
gtk_cell_area_create_context
@@ -4170,7 +4170,7 @@ GtkCellRendererClass
gtk_cell_renderer_class_set_accessible_type
gtk_cell_renderer_get_aligned_area
gtk_cell_renderer_get_size
gtk_cell_renderer_render
gtk_cell_renderer_snapshot
gtk_cell_renderer_activate
gtk_cell_renderer_start_editing
gtk_cell_renderer_stop_editing
+1 -1
View File
@@ -15,7 +15,7 @@ main (int argc,
GObject *window;
GObject *button;
gtk_init (&argc, &argv);
gtk_init ();
/* Construct a GtkBuilder instance and load our UI description */
builder = gtk_builder_new ();
-187
View File
@@ -173,93 +173,7 @@ static const GDebugKey gdk_debug_keys[] = {
{ "opengl", GDK_DEBUG_OPENGL },
{ "vulkan", GDK_DEBUG_VULKAN }
};
static gboolean
gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
{
guint debug_value = g_parse_debug_string (value,
(GDebugKey *) gdk_debug_keys,
G_N_ELEMENTS (gdk_debug_keys));
if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
{
g_set_error (error,
G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
_("Error parsing option --gdk-debug"));
return FALSE;
}
_gdk_debug_flags |= debug_value;
return TRUE;
}
static gboolean
gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data, GError **error)
{
guint debug_value = g_parse_debug_string (value,
(GDebugKey *) gdk_debug_keys,
G_N_ELEMENTS (gdk_debug_keys));
if (debug_value == 0 && value != NULL && strcmp (value, "") != 0)
{
g_set_error (error,
G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
_("Error parsing option --gdk-no-debug"));
return FALSE;
}
_gdk_debug_flags &= ~debug_value;
return TRUE;
}
#endif /* G_ENABLE_DEBUG */
static gboolean
gdk_arg_class_cb (const char *key, const char *value, gpointer user_data, GError **error)
{
gdk_set_program_class (value);
gdk_progclass_overridden = TRUE;
return TRUE;
}
static gboolean
gdk_arg_name_cb (const char *key, const char *value, gpointer user_data, GError **error)
{
g_set_prgname (value);
return TRUE;
}
static const GOptionEntry gdk_args[] = {
{ "class", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_class_cb,
/* Description of --class=CLASS in --help output */ N_("Program class as used by the window manager"),
/* Placeholder in --class=CLASS in --help output */ N_("CLASS") },
{ "name", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_name_cb,
/* Description of --name=NAME in --help output */ N_("Program name as used by the window manager"),
/* Placeholder in --name=NAME in --help output */ N_("NAME") },
#ifndef G_OS_WIN32
{ "display", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &_gdk_display_name,
/* Description of --display=DISPLAY in --help output */ N_("X display to use"),
/* Placeholder in --display=DISPLAY in --help output */ N_("DISPLAY") },
#endif
#ifdef G_ENABLE_DEBUG
{ "gdk-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_debug_cb,
/* Description of --gdk-debug=FLAGS in --help output */ N_("GDK debugging flags to set"),
/* Placeholder in --gdk-debug=FLAGS in --help output */ N_("FLAGS") },
{ "gdk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_no_debug_cb,
/* Description of --gdk-no-debug=FLAGS in --help output */ N_("GDK debugging flags to unset"),
/* Placeholder in --gdk-no-debug=FLAGS in --help output */ N_("FLAGS") },
#endif
{ NULL }
};
void
gdk_add_option_entries (GOptionGroup *group)
{
g_option_group_add_entries (group, gdk_args);
}
static gpointer
register_resources (gpointer dummy G_GNUC_UNUSED)
@@ -328,53 +242,6 @@ gdk_pre_parse (void)
}
}
/**
* gdk_parse_args:
* @argc: the number of command line arguments.
* @argv: (inout) (array length=argc): the array of command line arguments.
*
* Parse command line arguments, and store for future
* use by calls to gdk_display_open().
*
* Any arguments used by GDK are removed from the array and @argc and @argv are
* updated accordingly.
*
* You shouldnt call this function explicitly if you are using
* gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check().
*
* Since: 2.2
**/
void
gdk_parse_args (int *argc,
char ***argv)
{
GOptionContext *option_context;
GOptionGroup *option_group;
GError *error = NULL;
if (gdk_initialized)
return;
gdk_pre_parse ();
option_context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (option_context, TRUE);
g_option_context_set_help_enabled (option_context, FALSE);
option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
g_option_context_set_main_group (option_context, option_group);
g_option_group_add_entries (option_group, gdk_args);
if (!g_option_context_parse (option_context, argc, argv, &error))
{
g_warning ("%s", error->message);
g_error_free (error);
}
g_option_context_free (option_context);
GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
}
/**
* gdk_get_display_arg_name:
*
@@ -424,60 +291,6 @@ gdk_display_open_default (void)
return display;
}
/**
* gdk_init_check:
* @argc: (inout): the number of command line arguments.
* @argv: (array length=argc) (inout): the array of command line arguments.
*
* Initializes the GDK library and connects to the windowing system,
* returning %TRUE on success.
*
* Any arguments used by GDK are removed from the array and @argc and @argv
* are updated accordingly.
*
* GTK+ initializes GDK in gtk_init() and so this function is not usually
* needed by GTK+ applications.
*
* Returns: %TRUE if initialization succeeded.
*/
gboolean
gdk_init_check (int *argc,
char ***argv)
{
gdk_parse_args (argc, argv);
return gdk_display_open_default () != NULL;
}
/**
* gdk_init:
* @argc: (inout): the number of command line arguments.
* @argv: (array length=argc) (inout): the array of command line arguments.
*
* Initializes the GDK library and connects to the windowing system.
* If initialization fails, a warning message is output and the application
* terminates with a call to `exit(1)`.
*
* Any arguments used by GDK are removed from the array and @argc and @argv
* are updated accordingly.
*
* GTK+ initializes GDK in gtk_init() and so this function is not usually
* needed by GTK+ applications.
*/
void
gdk_init (int *argc, char ***argv)
{
if (!gdk_init_check (argc, argv))
{
const char *display_name = gdk_get_display_arg_name ();
g_warning ("cannot open display: %s", display_name ? display_name : "");
exit(1);
}
}
/**
* SECTION:threads
* @Short_description: Functions for using GDK in multi-threaded programs
+3 -1
View File
@@ -151,7 +151,7 @@ gdk_cairo_region (cairo_t *cr,
}
}
static void
void
gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
const GdkPixbuf *pixbuf)
{
@@ -198,7 +198,9 @@ gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
q[0] = p[2];
q[1] = p[1];
q[2] = p[0];
q[3] = 0xFF;
#else
q[0] = 0xFF;
q[1] = p[0];
q[2] = p[1];
q[3] = p[2];
+3
View File
@@ -343,6 +343,9 @@ void gdk_gl_texture_quads (GdkGLContext *paint_context,
GdkTexturedQuad *quads,
gboolean flip_colors);
void gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
const GdkPixbuf *pixbuf);
void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
GdkWindow *window);
cairo_region_t *gdk_cairo_region_from_clip (cairo_t *cr);
-10
View File
@@ -40,16 +40,6 @@ G_BEGIN_DECLS
#define GDK_PRIORITY_EVENTS (G_PRIORITY_DEFAULT)
GDK_AVAILABLE_IN_ALL
void gdk_parse_args (gint *argc,
gchar ***argv);
GDK_AVAILABLE_IN_ALL
void gdk_init (gint *argc,
gchar ***argv);
GDK_AVAILABLE_IN_ALL
gboolean gdk_init_check (gint *argc,
gchar ***argv);
GDK_AVAILABLE_IN_ALL
const gchar * gdk_get_program_class (void);
GDK_AVAILABLE_IN_ALL
+34 -1
View File
@@ -41,6 +41,7 @@ struct _GdkVulkanContextPrivate {
guint n_images;
VkImage *images;
cairo_region_t **regions;
#endif
guint32 draw_index;
@@ -127,7 +128,13 @@ gdk_vulkan_context_dispose (GObject *gobject)
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
GdkDisplay *display;
VkDevice device;
guint i;
for (i = 0; i < priv->n_images; i++)
{
cairo_region_destroy (priv->regions[i]);
}
g_clear_pointer (&priv->regions, g_free);
g_clear_pointer (&priv->images, g_free);
priv->n_images = 0;
@@ -176,6 +183,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
VkSwapchainKHR new_swapchain;
VkResult res;
VkDevice device;
guint i;
if (gdk_window_get_width (window) == priv->swapchain_width &&
gdk_window_get_height (window) == priv->swapchain_height)
@@ -239,6 +247,11 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
vkDestroySwapchainKHR (device,
priv->swapchain,
NULL);
for (i = 0; i < priv->n_images; i++)
{
cairo_region_destroy (priv->regions[i]);
}
g_clear_pointer (&priv->regions, g_free);
g_clear_pointer (&priv->images, g_free);
priv->n_images = 0;
}
@@ -258,6 +271,15 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
priv->swapchain,
&priv->n_images,
priv->images);
priv->regions = g_new (cairo_region_t *, priv->n_images);
for (i = 0; i < priv->n_images; i++)
{
priv->regions[i] = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gdk_window_get_width (window),
gdk_window_get_height (window),
});
}
}
else
{
@@ -281,6 +303,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
GError *error = NULL;
guint i;
if (!gdk_vulkan_context_check_swapchain (context, &error))
{
@@ -289,12 +312,19 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
return;
}
for (i = 0; i < priv->n_images; i++)
{
cairo_region_union (priv->regions[i], region);
}
GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
priv->swapchain,
UINT64_MAX,
priv->draw_semaphore,
VK_NULL_HANDLE,
&priv->draw_index);
cairo_region_union (region, priv->regions[priv->draw_index]);
}
static void
@@ -320,6 +350,9 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
priv->draw_index
},
});
cairo_region_destroy (priv->regions[priv->draw_index]);
priv->regions[priv->draw_index] = cairo_region_create ();
}
static void
@@ -404,7 +437,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
&n_formats, formats);
for (i = 0; i < n_formats; i++)
{
if (formats[i].format == VK_FORMAT_B8G8R8A8_SRGB)
if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM)
break;
}
if (i == n_formats)
+4
View File
@@ -26,8 +26,10 @@ if HAVE_VULKAN
gsk_private_vulkan_source_h = \
gskvulkanblendpipelineprivate.h \
gskvulkanbufferprivate.h \
gskvulkanclipprivate.h \
gskvulkancolorpipelineprivate.h \
gskvulkancommandpoolprivate.h \
gskvulkanlineargradientpipelineprivate.h \
gskvulkanimageprivate.h \
gskvulkanmemoryprivate.h \
gskvulkanpipelineprivate.h \
@@ -39,8 +41,10 @@ gsk_private_vulkan_source_h = \
gsk_private_vulkan_source_c = \
gskvulkanblendpipeline.c \
gskvulkanbuffer.c \
gskvulkanclip.c \
gskvulkancolorpipeline.c \
gskvulkancommandpool.c \
gskvulkanlineargradientpipeline.c \
gskvulkanimage.c \
gskvulkanmemory.c \
gskvulkanpipeline.c \
+61 -34
View File
@@ -18,8 +18,6 @@ struct _GskCairoRenderer
{
GskRenderer parent_instance;
graphene_rect_t viewport;
#ifdef G_ENABLE_DEBUG
ProfileTimers profile_timers;
#endif
@@ -47,44 +45,16 @@ gsk_cairo_renderer_unrealize (GskRenderer *renderer)
}
static void
gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
gsk_cairo_renderer_do_render (GskRenderer *renderer,
cairo_t *cr,
GskRenderNode *root)
{
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
#ifdef G_ENABLE_DEBUG
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
GskProfiler *profiler;
gint64 cpu_time;
#endif
cairo_t *cr;
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);
gsk_renderer_get_viewport (renderer, &self->viewport);
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba (cr, 0, 0, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr,
self->viewport.origin.x,
self->viewport.origin.y,
self->viewport.size.width,
self->viewport.size.height);
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
cairo_stroke (cr);
cairo_restore (cr);
}
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
@@ -100,6 +70,62 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
#endif
}
static GskTexture *
gsk_cairo_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
GskTexture *texture;
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ceil (viewport->size.width), ceil (viewport->size.height));
cr = cairo_create (surface);
cairo_translate (cr, - viewport->origin.x, - viewport->origin.y);
gsk_cairo_renderer_do_render (renderer, cr, root);
cairo_destroy (cr);
texture = gsk_texture_new_for_surface (surface);
cairo_surface_destroy (surface);
return texture;
}
static void
gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
{
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
graphene_rect_t viewport;
cairo_t *cr;
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);
gsk_renderer_get_viewport (renderer, &viewport);
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr,
viewport.origin.x,
viewport.origin.y,
viewport.size.width,
viewport.size.height);
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
cairo_stroke (cr);
cairo_restore (cr);
}
gsk_cairo_renderer_do_render (renderer, cr, root);
}
static void
gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
{
@@ -108,6 +134,7 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
renderer_class->realize = gsk_cairo_renderer_realize;
renderer_class->unrealize = gsk_cairo_renderer_unrealize;
renderer_class->render = gsk_cairo_renderer_render;
renderer_class->render_texture = gsk_cairo_renderer_render_texture;
}
static void
+3 -1
View File
@@ -9,7 +9,8 @@ static const GDebugKey gsk_debug_keys[] = {
{ "shaders", GSK_DEBUG_SHADERS },
{ "transforms", GSK_DEBUG_TRANSFORMS },
{ "surface", GSK_DEBUG_SURFACE },
{ "vulkan", GSK_DEBUG_VULKAN }
{ "vulkan", GSK_DEBUG_VULKAN },
{ "fallback", GSK_DEBUG_FALLBACK }
};
#endif
@@ -17,6 +18,7 @@ static const GDebugKey gsk_rendering_keys[] = {
{ "geometry", GSK_RENDERING_MODE_GEOMETRY },
{ "shaders", GSK_RENDERING_MODE_SHADERS },
{ "sync", GSK_RENDERING_MODE_SYNC },
{ "full-redraw", GSK_RENDERING_MODE_FULL_REDRAW},
{ "staging-image", GSK_RENDERING_MODE_STAGING_IMAGE },
{ "staging-buffer", GSK_RENDERING_MODE_STAGING_BUFFER }
};
+5 -3
View File
@@ -13,15 +13,17 @@ typedef enum {
GSK_DEBUG_SHADERS = 1 << 4,
GSK_DEBUG_TRANSFORMS = 1 << 5,
GSK_DEBUG_SURFACE = 1 << 6,
GSK_DEBUG_VULKAN = 1 << 7
GSK_DEBUG_VULKAN = 1 << 7,
GSK_DEBUG_FALLBACK = 1 << 8
} GskDebugFlags;
typedef enum {
GSK_RENDERING_MODE_GEOMETRY = 1 << 0,
GSK_RENDERING_MODE_SHADERS = 1 << 1,
GSK_RENDERING_MODE_SYNC = 1 << 2,
GSK_RENDERING_MODE_STAGING_IMAGE = 1 << 3,
GSK_RENDERING_MODE_STAGING_BUFFER = 1 << 4
GSK_RENDERING_MODE_FULL_REDRAW = 1 << 3,
GSK_RENDERING_MODE_STAGING_IMAGE = 1 << 4,
GSK_RENDERING_MODE_STAGING_BUFFER = 1 << 5
} GskRenderingMode;
gboolean gsk_check_debug_flags (GskDebugFlags flags);
+17
View File
@@ -152,4 +152,21 @@ typedef enum {
GSK_CORNER_BOTTOM_LEFT
} GskCorner;
/**
* GskSerializationError:
* @GSK_SERIALIZATION_UNSUPPORTED_FORMAT: The format can not be
* identified
* @GSK_SERIALIZATION_UNSUPPORTED_VERSION: The version of the data
* is not understood
* @GSK_SERIALIZATION_INVALID_DATA: The given data may not exist in
* a proper serialization
*
* Errors that can happen during (de)serialization.
*/
typedef enum {
GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
GSK_SERIALIZATION_UNSUPPORTED_VERSION,
GSK_SERIALIZATION_INVALID_DATA
} GskSerializationError;
#endif /* __GSK_TYPES_H__ */
+1 -1
View File
@@ -462,7 +462,7 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
if (gsk_texture_set_render_data (texture, driver, t, gsk_gl_driver_release_texture))
t->user = texture;
surface = gsk_texture_download (texture);
surface = gsk_texture_download_surface (texture);
gsk_gl_driver_bind_source_texture (driver, t->texture_id);
gsk_gl_driver_init_texture_with_surface (driver,
t->texture_id,
+92 -26
View File
@@ -102,6 +102,7 @@ struct _GskGLRenderer
guint frame_buffer;
guint depth_stencil_buffer;
guint texture_id;
GQuark uniforms[N_UNIFORMS];
GQuark attributes[N_ATTRIBUTES];
@@ -154,6 +155,17 @@ gsk_gl_renderer_create_buffers (GskGLRenderer *self,
GSK_NOTE (OPENGL, g_print ("Creating buffers (w:%d, h:%d, scale:%d)\n", width, height, scale_factor));
if (self->texture_id == 0)
{
self->texture_id = gsk_gl_driver_create_texture (self->gl_driver,
width * scale_factor,
height * scale_factor);
gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
gsk_gl_driver_init_texture_empty (self->gl_driver, self->texture_id);
}
gsk_gl_driver_create_render_target (self->gl_driver, self->texture_id, TRUE, TRUE);
self->has_buffers = TRUE;
}
@@ -170,6 +182,12 @@ gsk_gl_renderer_destroy_buffers (GskGLRenderer *self)
gdk_gl_context_make_current (self->gl_context);
if (self->texture_id != 0)
{
gsk_gl_driver_destroy_texture (self->gl_driver, self->texture_id);
self->texture_id = 0;
}
self->has_buffers = FALSE;
}
@@ -603,7 +621,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
GskRenderNode *node,
RenderItem *parent)
{
graphene_rect_t viewport;
RenderItem item;
RenderItem *ritem = NULL;
int program_id;
@@ -611,8 +628,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
memset (&item, 0, sizeof (RenderItem));
gsk_renderer_get_viewport (GSK_RENDERER (self), &viewport);
scale_factor = gsk_renderer_get_scale_factor (GSK_RENDERER (self));
if (scale_factor < 1)
scale_factor = 1;
@@ -685,7 +700,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
}
else
{
item.render_data.render_target_id = 0;
item.render_data.render_target_id = self->texture_id;
item.children = NULL;
}
@@ -908,47 +923,37 @@ gsk_gl_renderer_setup_render_mode (GskGLRenderer *self)
#define ORTHO_FAR_PLANE 10000
static void
gsk_gl_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
gsk_gl_renderer_do_render (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport,
int scale_factor)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
graphene_matrix_t modelview, projection;
graphene_rect_t viewport;
guint i;
int scale_factor;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 gpu_time, cpu_time;
#endif
if (self->gl_context == NULL)
return;
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
#endif
gdk_gl_context_make_current (self->gl_context);
gsk_renderer_get_viewport (renderer, &viewport);
scale_factor = gsk_renderer_get_scale_factor (renderer);
gsk_gl_driver_begin_frame (self->gl_driver);
gsk_gl_renderer_create_buffers (self, viewport.size.width, viewport.size.height, scale_factor);
gsk_gl_driver_end_frame (self->gl_driver);
/* Set up the modelview and projection matrices to fit our viewport */
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
graphene_matrix_init_ortho (&projection,
0, viewport.size.width * scale_factor,
viewport.size.height * scale_factor, 0,
viewport->origin.x,
viewport->origin.x + viewport->size.width * scale_factor,
viewport->origin.y + viewport->size.height * scale_factor,
viewport->origin.y,
ORTHO_NEAR_PLANE,
ORTHO_FAR_PLANE);
gsk_gl_renderer_update_frustum (self, &modelview, &projection);
if (!gsk_gl_renderer_validate_tree (self, root, &projection))
goto out;
return;
gsk_gl_driver_begin_frame (self->gl_driver);
@@ -958,8 +963,8 @@ gsk_gl_renderer_render (GskRenderer *renderer,
#endif
/* Ensure that the viewport is up to date */
if (gsk_gl_driver_bind_render_target (self->gl_driver, 0))
gsk_gl_renderer_resize_viewport (self, &viewport, scale_factor);
if (gsk_gl_driver_bind_render_target (self->gl_driver, self->texture_id))
gsk_gl_renderer_resize_viewport (self, viewport, scale_factor);
gsk_gl_renderer_setup_render_mode (self);
@@ -993,8 +998,68 @@ gsk_gl_renderer_render (GskRenderer *renderer,
gsk_profiler_push_samples (profiler);
#endif
}
static GskTexture *
gsk_gl_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
GskTexture *texture;
cairo_surface_t *surface;
cairo_t *cr;
g_return_val_if_fail (self->gl_context != NULL, NULL);
self->render_mode = RENDER_FULL;
gdk_gl_context_make_current (self->gl_context);
gsk_gl_driver_begin_frame (self->gl_driver);
gsk_gl_renderer_create_buffers (self, ceilf (viewport->size.width), ceilf (viewport->size.height), 1);
gsk_gl_driver_end_frame (self->gl_driver);
gsk_gl_renderer_do_render (renderer, root, viewport, 1);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
ceilf (viewport->size.width),
ceilf (viewport->size.height));
cr = cairo_create (surface);
gdk_cairo_draw_from_gl (cr,
gsk_renderer_get_window (renderer),
self->texture_id,
GL_TEXTURE,
1.0,
0, 0,
viewport->size.width,
viewport->size.height);
cairo_destroy (cr);
texture = gsk_texture_new_for_surface (surface);
cairo_surface_destroy (surface);
return texture;
}
static void
gsk_gl_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
graphene_rect_t viewport;
int scale_factor;
if (self->gl_context == NULL)
return;
gdk_gl_context_make_current (self->gl_context);
gsk_renderer_get_viewport (renderer, &viewport);
scale_factor = gsk_renderer_get_scale_factor (renderer);
gsk_gl_renderer_do_render (renderer, root, &viewport, scale_factor);
out:
gdk_gl_context_make_current (self->gl_context);
gsk_gl_renderer_clear_tree (self);
gsk_gl_renderer_destroy_buffers (self);
@@ -1012,6 +1077,7 @@ gsk_gl_renderer_class_init (GskGLRendererClass *klass)
renderer_class->unrealize = gsk_gl_renderer_unrealize;
renderer_class->begin_draw_frame = gsk_gl_renderer_begin_draw_frame;
renderer_class->render = gsk_gl_renderer_render;
renderer_class->render_texture = gsk_gl_renderer_render_texture;
}
static void
+97 -1
View File
@@ -113,6 +113,15 @@ gsk_renderer_real_unrealize (GskRenderer *self)
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, unrealize);
}
static GskTexture *
gsk_renderer_real_render_texture (GskRenderer *self,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render_texture);
return NULL;
}
static GdkDrawingContext *
gsk_renderer_real_begin_draw_frame (GskRenderer *self,
const cairo_region_t *region)
@@ -259,6 +268,7 @@ gsk_renderer_class_init (GskRendererClass *klass)
klass->begin_draw_frame = gsk_renderer_real_begin_draw_frame;
klass->end_draw_frame = gsk_renderer_real_end_draw_frame;
klass->render = gsk_renderer_real_render;
klass->render_texture = gsk_renderer_real_render_texture;
klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface;
gobject_class->constructed = gsk_renderer_constructed;
@@ -606,6 +616,75 @@ gsk_renderer_unrealize (GskRenderer *renderer)
priv->is_realized = FALSE;
}
/**
* gsk_renderer_render_texture:
* @renderer: a realized #GdkRenderer
* @root: a #GskRenderNode
* @viewport: (allow-none): the section to draw or %NULL to use @root's bounds
*
* Renders the scene graph, described by a tree of #GskRenderNode instances,
* to a #GskTexture.
*
* The @renderer will acquire a reference on the #GskRenderNode tree while
* the rendering is in progress, and will make the tree immutable.
*
* If you want to apply any transformations to @root, you should put it into a
* transform node and pass that node instead.
*
* Returns: (transfer full): a #GskTexture with the rendered contents of @root.
*
* Since: 3.90
*/
GskTexture *
gsk_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
graphene_rect_t real_viewport;
GskTexture *texture;
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
g_return_val_if_fail (priv->is_realized, NULL);
g_return_val_if_fail (GSK_IS_RENDER_NODE (root), NULL);
g_return_val_if_fail (priv->root_node == NULL, NULL);
priv->root_node = gsk_render_node_ref (root);
if (viewport == NULL)
{
gsk_render_node_get_bounds (root, &real_viewport);
viewport = &real_viewport;
}
#ifdef G_ENABLE_DEBUG
gsk_profiler_reset (priv->profiler);
#endif
texture = GSK_RENDERER_GET_CLASS (renderer)->render_texture (renderer, root, viewport);
#ifdef G_ENABLE_DEBUG
if (GSK_DEBUG_CHECK (RENDERER))
{
GString *buf = g_string_new ("*** Texture stats ***\n\n");
gsk_profiler_append_counters (priv->profiler, buf);
g_string_append_c (buf, '\n');
gsk_profiler_append_timers (priv->profiler, buf);
g_string_append_c (buf, '\n');
g_print ("%s\n***\n\n", buf->str);
g_string_free (buf, TRUE);
}
#endif
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
return texture;
}
/**
* gsk_renderer_render:
* @renderer: a #GskRenderer
@@ -837,7 +916,24 @@ gsk_renderer_begin_draw_frame (GskRenderer *renderer,
g_return_val_if_fail (region != NULL, NULL);
g_return_val_if_fail (priv->drawing_context == NULL, NULL);
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, region);
if (GSK_RENDER_MODE_CHECK (FULL_REDRAW))
{
cairo_region_t *full_window;
full_window = cairo_region_create_rectangle (&(GdkRectangle) {
0, 0,
gdk_window_get_width (priv->window),
gdk_window_get_height (priv->window)
});
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, full_window);
cairo_region_destroy (full_window);
}
else
{
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, region);
}
return priv->drawing_context;
}
+3 -6
View File
@@ -53,9 +53,6 @@ void gsk_renderer_set_scale_factor (GskRenderer
GDK_AVAILABLE_IN_3_90
int gsk_renderer_get_scale_factor (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90
void gsk_renderer_set_window (GskRenderer *renderer,
GdkWindow *window);
GDK_AVAILABLE_IN_3_90
GdkWindow * gsk_renderer_get_window (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90
@@ -69,9 +66,9 @@ GDK_AVAILABLE_IN_3_90
void gsk_renderer_unrealize (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90
GskRenderer * gsk_renderer_create_fallback (GskRenderer *renderer,
const graphene_rect_t *viewport,
cairo_t *cr);
GskTexture * gsk_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport);
GDK_AVAILABLE_IN_3_90
GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer *renderer,
+3
View File
@@ -42,6 +42,9 @@ struct _GskRendererClass
GError **error);
void (* unrealize) (GskRenderer *renderer);
GskTexture * (* render_texture) (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport);
GdkDrawingContext * (* begin_draw_frame) (GskRenderer *renderer,
const cairo_region_t *region);
void (* end_draw_frame) (GskRenderer *renderer,
+134
View File
@@ -65,6 +65,8 @@ G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node,
gsk_render_node_ref,
gsk_render_node_unref)
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
static void
gsk_render_node_finalize (GskRenderNode *self)
{
@@ -253,6 +255,7 @@ gsk_render_node_draw (GskRenderNode *node,
{
g_return_if_fail (GSK_IS_RENDER_NODE (node));
g_return_if_fail (cr != NULL);
g_return_if_fail (cairo_status (cr) == CAIRO_STATUS_SUCCESS);
cairo_save (cr);
@@ -283,6 +286,137 @@ gsk_render_node_draw (GskRenderNode *node,
}
cairo_restore (cr);
if (cairo_status (cr))
{
g_warning ("drawing failure for render node %s '%s': %s",
node->node_class->type_name,
gsk_render_node_get_name (node),
cairo_status_to_string (cairo_status (cr)));
}
}
#define GSK_RENDER_NODE_SERIALIZATION_VERSION 0
#define GSK_RENDER_NODE_SERIALIZATION_ID "GskRenderNode"
/**
* gsk_render_node_serialize:
* @node: a #GskRenderNode
*
* Serializes the @node for later deserialization via
* gsk_render_node_deserialize(). No guarantees are made about the format
* used other than that the same version of GTK+ will be able to deserialize
* the result of a call to gsk_render_node_serialize() and
* gsk_render_node_deserialize() will correctly reject files it cannot open
* that were created with previous versions of GTK+.
*
* The intended use of this functions is testing, benchmarking and debugging.
* The format is not meant as a permanent storage format.
*
* Returns: a #GBytes representing the node.
**/
GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
GVariant *node_variant, *variant;
GBytes *result;
node_variant = gsk_render_node_serialize_node (node);
variant = g_variant_new ("(suuv)",
GSK_RENDER_NODE_SERIALIZATION_ID,
(guint32) GSK_RENDER_NODE_SERIALIZATION_VERSION,
(guint32) gsk_render_node_get_node_type (node),
node_variant);
result = g_variant_get_data_as_bytes (variant);
g_variant_unref (variant);
return result;
}
/**
* gsk_render_node_write_to_file:
* @node: a #GskRenderNode
* @filename: the file to save it to.
* @error: Return location for a potential error
*
* This function is equivalent to calling gsk_render_node_serialize()
* followed by g_file_set_contents(). See those two functions for details
* on the arguments.
*
* It is mostly intended for use inside a debugger to quickly dump a render
* node to a file for later inspection.
*
* Returns: %TRUE if saving was successful
**/
gboolean
gsk_render_node_write_to_file (GskRenderNode *node,
const char *filename,
GError **error)
{
GBytes *bytes;
gboolean result;
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
bytes = gsk_render_node_serialize (node);
result = g_file_set_contents (filename,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
error);
g_bytes_unref (bytes);
return result;
}
/**
* gsk_render_node_deserialize:
* @bytes: the bytes containing the data
* @error: (allow-none): location to store error or %NULL
*
* Loads data previously created via gsk_render_node_serialize(). For a
* discussion of the supported format, see that function.
*
* Returns: (nullable) (transfer full): a new #GskRenderNode or %NULL on
* error.
**/
GskRenderNode *
gsk_render_node_deserialize (GBytes *bytes,
GError **error)
{
char *id_string;
guint32 version, node_type;
GVariant *variant, *node_variant;
GskRenderNode *node = NULL;
variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE);
g_variant_get (variant, "(suuv)", &id_string, &version, &node_type, &node_variant);
if (!g_str_equal (id_string, GSK_RENDER_NODE_SERIALIZATION_ID))
{
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
"Data not in GskRenderNode serialization format.");
goto out;
}
if (version != GSK_RENDER_NODE_SERIALIZATION_VERSION)
{
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_VERSION,
"Format version %u not supported.", version);
goto out;
}
node = gsk_render_node_deserialize_node (node_type, node_variant, error);
out:
g_free (id_string);
g_variant_unref (node_variant);
g_variant_unref (variant);
return node;
}
+20 -2
View File
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
#define GSK_IS_RENDER_NODE(obj) ((obj) != NULL)
#define GSK_SERIALIZATION_ERROR (gsk_serialization_error_quark ())
typedef struct _GskRenderNode GskRenderNode;
typedef struct _GskColorStop GskColorStop;
typedef struct _GskShadow GskShadow;
@@ -47,12 +49,14 @@ struct _GskShadow
GdkRGBA color;
float dx;
float dy;
float spread;
float radius;
};
GDK_AVAILABLE_IN_3_90
GType gsk_render_node_get_type (void) G_GNUC_CONST;
GType gsk_render_node_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_90
GQuark gsk_serialization_error_quark (void);
GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_render_node_ref (GskRenderNode *node);
@@ -167,10 +171,24 @@ void gsk_render_node_set_name (GskRenderNode *
const char *name);
GDK_AVAILABLE_IN_3_90
const char * gsk_render_node_get_name (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
void gsk_render_node_get_bounds (GskRenderNode *node,
graphene_rect_t *frame);
GDK_AVAILABLE_IN_3_90
void gsk_render_node_draw (GskRenderNode *node,
cairo_t *cr);
GDK_AVAILABLE_IN_3_90
GBytes * gsk_render_node_serialize (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
gboolean gsk_render_node_write_to_file (GskRenderNode *node,
const char *filename,
GError **error);
GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_render_node_deserialize (GBytes *bytes,
GError **error);
G_END_DECLS
#endif /* __GSK_RENDER_NODE_H__ */
+1019 -2
View File
File diff suppressed because it is too large Load Diff
+12 -2
View File
@@ -34,18 +34,28 @@ struct _GskRenderNodeClass
void (* finalize) (GskRenderNode *node);
void (* draw) (GskRenderNode *node,
cairo_t *cr);
GVariant * (* serialize) (GskRenderNode *node);
GskRenderNode * (* deserialize) (GVariant *variant,
GError **error);
};
GskRenderNode *gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size);
void gsk_render_node_get_bounds (GskRenderNode *node,
graphene_rect_t *frame);
GVariant * gsk_render_node_serialize_node (GskRenderNode *node);
GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type, GVariant *variant, GError **error);
double gsk_opacity_node_get_opacity (GskRenderNode *node);
const graphene_point_t * gsk_linear_gradient_node_peek_start (GskRenderNode *node);
const graphene_point_t * gsk_linear_gradient_node_peek_end (GskRenderNode *node);
const gsize gsk_linear_gradient_node_get_n_color_stops (GskRenderNode *node);
const GskColorStop * gsk_linear_gradient_node_peek_color_stops (GskRenderNode *node);
const GskRoundedRect * gsk_border_node_peek_outline (GskRenderNode *node);
float gsk_border_node_get_width (GskRenderNode *node, guint i);
const GdkRGBA * gsk_border_node_peek_color (GskRenderNode *node, guint i);
GskRenderNode *gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds, cairo_surface_t *surface);
cairo_surface_t *gsk_cairo_node_get_surface (GskRenderNode *node);
GskTexture *gsk_texture_node_get_texture (GskRenderNode *node);
+45
View File
@@ -277,6 +277,21 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
return self;
}
/* XXX: Fina a better name */
gboolean
gsk_rounded_rect_is_circular (const GskRoundedRect *self)
{
guint i;
for (i = 0; i < 4; i++)
{
if (self->corner[i].width != self->corner[i].height)
return FALSE;
}
return TRUE;
}
/**
* gsk_rounded_rect_is_rectilinear:
* @self: the #GskRoundedRect to check
@@ -486,3 +501,33 @@ gsk_rounded_rect_path (const GskRoundedRect *self,
cairo_close_path (cr);
}
/*
* Converts to the format we use in our shaders:
* vec4 rect;
* vec4 corner_widths;
* vec4 corner_heights;
* rect is (x, y, width, height), the corners are the same
* order as in the rounded rect.
*
* This is so that shaders can use just the first vec4 for
* rectilinear rects, the 2nd vec4 for circular rects and
* only look at the last vec4 if they have to.
*/
void
gsk_rounded_rect_to_float (const GskRoundedRect *self,
float rect[12])
{
guint i;
rect[0] = self->bounds.origin.x;
rect[1] = self->bounds.origin.y;
rect[2] = self->bounds.size.width;
rect[3] = self->bounds.size.height;
for (i = 0; i < 4; i++)
{
rect[4 + i] = self->corner[i].width;
rect[8 + i] = self->corner[i].height;
}
}
+4
View File
@@ -7,8 +7,12 @@
G_BEGIN_DECLS
gboolean gsk_rounded_rect_is_circular (const GskRoundedRect *self);
void gsk_rounded_rect_path (const GskRoundedRect *self,
cairo_t *cr);
void gsk_rounded_rect_to_float (const GskRoundedRect *self,
float rect[12]);
G_END_DECLS
+101 -6
View File
@@ -37,6 +37,8 @@
#include "gskdebugprivate.h"
#include "gskrenderer.h"
#include "gdk/gdkinternals.h"
/**
* GskTexture: (ref-func gsk_texture_ref) (unref-func gsk_texture_unref)
*
@@ -135,18 +137,43 @@ gsk_texture_cairo_finalize (GskTexture *texture)
}
static cairo_surface_t *
gsk_texture_cairo_download (GskTexture *texture)
gsk_texture_cairo_download_surface (GskTexture *texture)
{
GskCairoTexture *cairo = (GskCairoTexture *) texture;
return cairo_surface_reference (cairo->surface);
}
static void
gsk_texture_cairo_download (GskTexture *texture,
guchar *data,
gsize stride)
{
GskCairoTexture *cairo = (GskCairoTexture *) texture;
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
texture->width, texture->height,
stride);
cr = cairo_create (surface);
cairo_set_source_surface (cr, cairo->surface, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_finish (surface);
cairo_surface_destroy (surface);
}
static const GskTextureClass GSK_TEXTURE_CLASS_CAIRO = {
"cairo",
sizeof (GskCairoTexture),
gsk_texture_cairo_finalize,
gsk_texture_cairo_download
gsk_texture_cairo_download,
gsk_texture_cairo_download_surface
};
GskTexture *
@@ -208,8 +235,25 @@ gsk_texture_pixbuf_finalize (GskTexture *texture)
g_object_unref (pixbuf->pixbuf);
}
static void
gsk_texture_pixbuf_download (GskTexture *texture,
guchar *data,
gsize stride)
{
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
cairo_surface_t *surface;
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
texture->width, texture->height,
stride);
gdk_cairo_surface_paint_pixbuf (surface, pixbuf->pixbuf);
cairo_surface_finish (surface);
cairo_surface_destroy (surface);
}
static cairo_surface_t *
gsk_texture_pixbuf_download (GskTexture *texture)
gsk_texture_pixbuf_download_surface (GskTexture *texture)
{
GskPixbufTexture *pixbuf = (GskPixbufTexture *) texture;
@@ -220,7 +264,8 @@ static const GskTextureClass GSK_TEXTURE_CLASS_PIXBUF = {
"pixbuf",
sizeof (GskPixbufTexture),
gsk_texture_pixbuf_finalize,
gsk_texture_pixbuf_download
gsk_texture_pixbuf_download,
gsk_texture_pixbuf_download_surface
};
GskTexture *
@@ -276,9 +321,59 @@ gsk_texture_get_height (GskTexture *texture)
}
cairo_surface_t *
gsk_texture_download (GskTexture *texture)
gsk_texture_download_surface (GskTexture *texture)
{
return texture->klass->download (texture);
cairo_surface_t *surface;
if (texture->klass->download_surface)
return texture->klass->download_surface (texture);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
gsk_texture_download (texture,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
cairo_surface_mark_dirty (surface);
return surface;
}
/**
* gsk_texture_download:
* @texture: a #GskTexture
* @data: pointer to enough memory to be filled with the
* downloaded data of @texture
* @stride: rowstride in bytes
*
* Downloads the @texture into local memory. This may be
* an expensive operation, as the actual texture data may
* reside on a GPU or on a remote display server.
*
* The data format of the downloaded data is equivalent to
* %CAIRO_FORMAT_ARGB32, so every downloaded pixel requires
* 4 bytes of memory.
*
* Downloading a texture into a Cairo image surface:
* |[<!-- language="C" -->
* surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
* gsk_texture_get_width (texture),
* gsk_texture_get_height (texture));
* gsk_texture_download (texture,
* cairo_image_surface_get_data (surface),
* cairo_image_surface_get_stride (surface));
* cairo_surface_mark_dirty (surface);
* ]|
**/
void
gsk_texture_download (GskTexture *texture,
guchar *data,
gsize stride)
{
g_return_if_fail (GSK_IS_TEXTURE (texture));
g_return_if_fail (data != NULL);
g_return_if_fail (stride >= gsk_texture_get_width (texture) * 4);
return texture->klass->download (texture, data, stride);
}
gboolean
+5
View File
@@ -52,6 +52,11 @@ int gsk_texture_get_width (GskTexture
GDK_AVAILABLE_IN_3_90
int gsk_texture_get_height (GskTexture *texture);
GDK_AVAILABLE_IN_3_90
void gsk_texture_download (GskTexture *texture,
guchar *data,
gsize stride);
G_END_DECLS
#endif /* __GSK_TEXTURE_H__ */
+5 -2
View File
@@ -30,14 +30,17 @@ struct _GskTextureClass {
gsize size;
void (* finalize) (GskTexture *texture);
cairo_surface_t * (* download) (GskTexture *texture);
void (* download) (GskTexture *texture,
guchar *data,
gsize stride);
cairo_surface_t * (* download_surface) (GskTexture *texture);
};
gpointer gsk_texture_new (const GskTextureClass *klass,
int width,
int height);
GskTexture * gsk_texture_new_for_surface (cairo_surface_t *surface);
cairo_surface_t * gsk_texture_download (GskTexture *texture);
cairo_surface_t * gsk_texture_download_surface (GskTexture *texture);
gboolean gsk_texture_set_render_data (GskTexture *self,
gpointer key,
+6
View File
@@ -71,6 +71,12 @@ gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
return gsk_vulkan_buffer_new_internal (context, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
}
GskVulkanBuffer *
gsk_vulkan_buffer_new_download (GdkVulkanContext *context,
gsize size)
{
return gsk_vulkan_buffer_new_internal (context, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
}
void
gsk_vulkan_buffer_free (GskVulkanBuffer *self)
{
+2
View File
@@ -11,6 +11,8 @@ GskVulkanBuffer * gsk_vulkan_buffer_new (GdkVulk
gsize size);
GskVulkanBuffer * gsk_vulkan_buffer_new_staging (GdkVulkanContext *context,
gsize size);
GskVulkanBuffer * gsk_vulkan_buffer_new_download (GdkVulkanContext *context,
gsize size);
void gsk_vulkan_buffer_free (GskVulkanBuffer *buffer);
VkBuffer gsk_vulkan_buffer_get_buffer (GskVulkanBuffer *self);
+179
View File
@@ -0,0 +1,179 @@
#include "config.h"
#include "gskvulkanclipprivate.h"
#include "gskroundedrectprivate.h"
void
gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
const graphene_rect_t *rect)
{
clip->type = GSK_VULKAN_CLIP_NONE;
gsk_rounded_rect_init_from_rect (&clip->rect, rect, 0);
}
static void
gsk_vulkan_clip_init_copy (GskVulkanClip *self,
const GskVulkanClip *src)
{
self->type = src->type;
gsk_rounded_rect_init_copy (&self->rect, &src->rect);
}
gboolean
gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
const GskVulkanClip *src,
const graphene_rect_t *rect)
{
if (graphene_rect_contains_rect (rect, &src->rect.bounds))
{
gsk_vulkan_clip_init_copy (dest, src);
return TRUE;
}
if (!graphene_rect_intersection (rect, &src->rect.bounds, NULL))
{
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
return TRUE;
}
switch (src->type)
{
case GSK_VULKAN_CLIP_ALL_CLIPPED:
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
break;
case GSK_VULKAN_CLIP_NONE:
gsk_vulkan_clip_init_copy (dest, src);
if (graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
dest->type = GSK_VULKAN_CLIP_RECT;
else
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
break;
case GSK_VULKAN_CLIP_RECT:
gsk_vulkan_clip_init_copy (dest, src);
if (!graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
break;
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
if (gsk_rounded_rect_contains_rect (&src->rect, rect))
{
dest->type = GSK_VULKAN_CLIP_RECT;
gsk_rounded_rect_init_from_rect (&dest->rect, rect, 0);
}
else
{
/* some points of rect are inside src's rounded rect,
* some are outside. */
/* XXX: If the 2 rects don't intersect on rounded corners,
* we could actually compute a new clip here.
*/
return FALSE;
}
}
return TRUE;
}
gboolean
gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
const GskVulkanClip *src,
const GskRoundedRect *rounded)
{
if (gsk_rounded_rect_contains_rect (rounded, &src->rect.bounds))
{
gsk_vulkan_clip_init_copy (dest, src);
return TRUE;
}
if (!graphene_rect_intersection (&rounded->bounds, &src->rect.bounds, NULL))
{
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
return TRUE;
}
switch (src->type)
{
case GSK_VULKAN_CLIP_ALL_CLIPPED:
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
break;
case GSK_VULKAN_CLIP_NONE:
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
gsk_rounded_rect_init_copy (&dest->rect, rounded);
break;
case GSK_VULKAN_CLIP_RECT:
if (graphene_rect_contains_rect (&src->rect.bounds, &rounded->bounds))
{
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
gsk_rounded_rect_init_copy (&dest->rect, rounded);
return TRUE;
}
/* some points of rect are inside src's rounded rect,
* some are outside. */
/* XXX: If the 2 rects don't intersect on rounded corners,
* we could actually compute a new clip here.
*/
return FALSE;
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
/* XXX: improve */
return FALSE;
}
return TRUE;
}
gboolean
gsk_vulkan_clip_transform (GskVulkanClip *dest,
const GskVulkanClip *src,
const graphene_matrix_t *transform,
const graphene_rect_t *viewport)
{
switch (dest->type)
{
default:
g_assert_not_reached();
return FALSE;
case GSK_VULKAN_CLIP_ALL_CLIPPED:
gsk_vulkan_clip_init_copy (dest, src);
return TRUE;
case GSK_VULKAN_CLIP_NONE:
gsk_vulkan_clip_init_empty (dest, viewport);
return TRUE;
case GSK_VULKAN_CLIP_RECT:
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
/* FIXME: Handle 2D operations, in particular transform and scale */
return FALSE;
}
}
gboolean
gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
const graphene_rect_t *rect)
{
switch (self->type)
{
default:
g_assert_not_reached();
case GSK_VULKAN_CLIP_ALL_CLIPPED:
return FALSE;
case GSK_VULKAN_CLIP_NONE:
return TRUE;
case GSK_VULKAN_CLIP_RECT:
return graphene_rect_contains_rect (&self->rect.bounds, rect);
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
return gsk_rounded_rect_contains_rect (&self->rect, rect);
}
}
+57
View File
@@ -0,0 +1,57 @@
#ifndef __GSK_VULKAN_CLIP_PRIVATE_H__
#define __GSK_VULKAN_CLIP_PRIVATE_H__
#include <gdk/gdk.h>
#include <graphene.h>
#include <gsk/gskroundedrect.h>
G_BEGIN_DECLS
typedef enum {
/* The whole area is clipped, no drawing is necessary.
* This can't be handled by return values because for return
* values we return if clips could even be computed.
*/
GSK_VULKAN_CLIP_ALL_CLIPPED,
/* No clipping is necesary, but the clip rect is set
* to the actual bounds of the underlying framebuffer
*/
GSK_VULKAN_CLIP_NONE,
/* The clip is a rectangular area */
GSK_VULKAN_CLIP_RECT,
/* The clip is a rounded rectangle, and for every corner
* corner.width == corner.height is true
*/
GSK_VULKAN_CLIP_ROUNDED_CIRCULAR,
/* The clip is a rounded rectangle */
GSK_VULKAN_CLIP_ROUNDED
} GskVulkanClipComplexity;
typedef struct _GskVulkanClip GskVulkanClip;
struct _GskVulkanClip
{
GskVulkanClipComplexity type;
GskRoundedRect rect;
};
void gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
const graphene_rect_t *rect);
gboolean gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
const GskVulkanClip *src,
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
gboolean gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
const GskVulkanClip *src,
const GskRoundedRect *rounded) G_GNUC_WARN_UNUSED_RESULT;
gboolean gsk_vulkan_clip_transform (GskVulkanClip *dest,
const GskVulkanClip *src,
const graphene_matrix_t*transform,
const graphene_rect_t *viewport) G_GNUC_WARN_UNUSED_RESULT;
gboolean gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
#endif /* __GSK_VULKAN_CLIP_PRIVATE_H__ */
+3 -3
View File
@@ -101,9 +101,9 @@ gsk_vulkan_color_pipeline_collect_vertex_data (GskVulkanColorPipeline *pipeline,
instance->rect[1] = rect->origin.y;
instance->rect[2] = rect->size.width;
instance->rect[3] = rect->size.height;
instance->color[0] = pow (color->red, 2.2);
instance->color[1] = pow (color->green, 2.2);
instance->color[2] = pow (color->blue, 2.2);
instance->color[0] = color->red;
instance->color[1] = color->green;
instance->color[2] = color->blue;
instance->color[3] = color->alpha;
}
+4
View File
@@ -83,10 +83,12 @@ gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
1,
&(VkSubmitInfo) {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
#if 0
.waitSemaphoreCount = 1,
.pWaitSemaphores = (VkSemaphore[1]) {
gdk_vulkan_context_get_draw_semaphore (self->vulkan)
},
#endif
.pWaitDstStageMask = (VkPipelineStageFlags []) {
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
},
@@ -94,10 +96,12 @@ gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
.pCommandBuffers = (VkCommandBuffer[1]) {
command_buffer
},
#if 0
.signalSemaphoreCount = 1,
.pSignalSemaphores = (VkSemaphore[1]) {
gdk_vulkan_context_get_draw_semaphore (self->vulkan)
}
#endif
},
fence);
}
+90 -5
View File
@@ -167,7 +167,7 @@ gsk_vulkan_image_new (GdkVulkanContext *context,
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.flags = 0,
.imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_B8G8R8A8_SRGB,
.format = VK_FORMAT_B8G8R8A8_UNORM,
.extent = { width, height, 1 },
.mipLevels = 1,
.arrayLayers = 1,
@@ -359,7 +359,7 @@ gsk_vulkan_image_new_from_data_via_staging_buffer (GskVulkanUploader *uploader,
uploader->staging_buffer_free_list = g_slist_prepend (uploader->staging_buffer_free_list, staging);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
return self;
}
@@ -478,7 +478,7 @@ gsk_vulkan_image_new_from_data_via_staging_image (GskVulkanUploader *uploader,
uploader->staging_image_free_list = g_slist_prepend (uploader->staging_image_free_list, staging);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
return self;
}
@@ -521,7 +521,7 @@ gsk_vulkan_image_new_from_data_directly (GskVulkanUploader *uploader,
}
});
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
return self;
}
@@ -557,11 +557,96 @@ gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
self->height = height;
self->vk_image = image;
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_SRGB);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
return self;
}
GskVulkanImage *
gsk_vulkan_image_new_for_framebuffer (GdkVulkanContext *context,
gsize width,
gsize height)
{
GskVulkanImage *self;
self = gsk_vulkan_image_new (context,
width,
height,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
gsk_vulkan_image_ensure_view (self, VK_FORMAT_B8G8R8A8_UNORM);
return self;
}
GskTexture *
gsk_vulkan_image_download (GskVulkanImage *self,
GskVulkanUploader *uploader)
{
GskVulkanBuffer *buffer;
GskTexture *texture;
guchar *mem;
gsk_vulkan_uploader_add_image_barrier (uploader,
FALSE,
&(VkImageMemoryBarrier) {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = self->vk_image,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1
}
});
buffer = gsk_vulkan_buffer_new_download (self->vulkan, self->width * self->height * 4);
vkCmdCopyImageToBuffer (gsk_vulkan_uploader_get_copy_buffer (uploader),
self->vk_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
gsk_vulkan_buffer_get_buffer (buffer),
1,
(VkBufferImageCopy[1]) {
{
.bufferOffset = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1
},
.imageOffset = { 0, 0, 0 },
.imageExtent = {
.width = self->width,
.height = self->height,
.depth = 1
}
}
});
gsk_vulkan_uploader_upload (uploader);
GSK_VK_CHECK (vkQueueWaitIdle, gdk_vulkan_context_get_queue (self->vulkan));
mem = gsk_vulkan_buffer_map (buffer);
texture = gsk_texture_new_for_data (mem, self->width, self->height, self->width * 4);
gsk_vulkan_buffer_unmap (buffer);
gsk_vulkan_buffer_free (buffer);
return texture;
}
void
gsk_vulkan_image_finalize (GObject *object)
{
+7
View File
@@ -3,6 +3,7 @@
#include <gdk/gdk.h>
#include "gsk/gsktexture.h"
#include "gsk/gskvulkancommandpoolprivate.h"
G_BEGIN_DECLS
@@ -30,6 +31,12 @@ GskVulkanImage * gsk_vulkan_image_new_from_data (GskVulk
gsize width,
gsize height,
gsize stride);
GskVulkanImage * gsk_vulkan_image_new_for_framebuffer (GdkVulkanContext *context,
gsize width,
gsize height);
GskTexture * gsk_vulkan_image_download (GskVulkanImage *self,
GskVulkanUploader *uploader);
gsize gsk_vulkan_image_get_width (GskVulkanImage *self);
gsize gsk_vulkan_image_get_height (GskVulkanImage *self);
+224
View File
@@ -0,0 +1,224 @@
#include "config.h"
#include "gskvulkanlineargradientpipelineprivate.h"
struct _GskVulkanLinearGradientPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanLinearGradientInstance GskVulkanLinearGradientInstance;
struct _GskVulkanLinearGradientInstance
{
float rect[4];
float start[2];
float end[2];
gint32 repeating;
gint32 stop_count;
float offsets[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS];
float colors[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS][4];
};
G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanLinearGradientInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, start),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, end),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, repeating),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets) + sizeof (float) * 4,
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[0]),
},
{
.location = 8,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[1]),
},
{
.location = 9,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[2]),
},
{
.location = 10,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[3]),
},
{
.location = 11,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[4]),
},
{
.location = 12,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[5]),
},
{
.location = 13,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[6]),
},
{
.location = 14,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[7]),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
}
static void
gsk_vulkan_linear_gradient_pipeline_finalize (GObject *gobject)
{
//GskVulkanLinearGradientPipeline *self = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (gobject);
G_OBJECT_CLASS (gsk_vulkan_linear_gradient_pipeline_parent_class)->finalize (gobject);
}
static void
gsk_vulkan_linear_gradient_pipeline_class_init (GskVulkanLinearGradientPipelineClass *klass)
{
GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_linear_gradient_pipeline_finalize;
pipeline_class->get_input_state_create_info = gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info;
}
static void
gsk_vulkan_linear_gradient_pipeline_init (GskVulkanLinearGradientPipeline *self)
{
}
GskVulkanPipeline *
gsk_vulkan_linear_gradient_pipeline_new (GskVulkanPipelineLayout *layout,
const char *shader_name,
VkRenderPass render_pass)
{
return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_LINEAR_GRADIENT_PIPELINE, layout, shader_name, render_pass);
}
gsize
gsk_vulkan_linear_gradient_pipeline_count_vertex_data (GskVulkanLinearGradientPipeline *pipeline)
{
return sizeof (GskVulkanLinearGradientInstance);
}
void
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradientPipeline *pipeline,
guchar *data,
const graphene_rect_t *rect,
const graphene_point_t *start,
const graphene_point_t *end,
gboolean repeating,
gsize n_stops,
const GskColorStop *stops)
{
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
gsize i;
if (n_stops > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
{
g_warning ("Only %u color stops supported.", GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
n_stops = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS;
}
instance->rect[0] = rect->origin.x;
instance->rect[1] = rect->origin.y;
instance->rect[2] = rect->size.width;
instance->rect[3] = rect->size.height;
instance->start[0] = start->x;
instance->start[1] = start->y;
instance->end[0] = end->x;
instance->end[1] = end->y;
instance->repeating = repeating;
instance->stop_count = n_stops;
for (i = 0; i < n_stops; i++)
{
instance->offsets[i] = stops[i].offset;
instance->colors[i][0] = stops[i].color.red;
instance->colors[i][1] = stops[i].color.green;
instance->colors[i][2] = stops[i].color.blue;
instance->colors[i][3] = stops[i].color.alpha;
}
}
gsize
gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline *pipeline,
VkCommandBuffer command_buffer,
gsize offset,
gsize n_commands)
{
vkCmdDraw (command_buffer,
6, n_commands,
0, offset);
return n_commands;
}
@@ -0,0 +1,41 @@
#ifndef __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__
#define __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__
#include <graphene.h>
#include "gskvulkanpipelineprivate.h"
#include "gskrendernode.h"
G_BEGIN_DECLS
#define GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS 8
typedef struct _GskVulkanLinearGradientPipelineLayout GskVulkanLinearGradientPipelineLayout;
#define GSK_TYPE_VULKAN_LINEAR_GRADIENT_PIPELINE (gsk_vulkan_linear_gradient_pipeline_get_type ())
G_DECLARE_FINAL_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK, VULKAN_LINEAR_GRADIENT_PIPELINE, GskVulkanPipeline)
GskVulkanPipeline * gsk_vulkan_linear_gradient_pipeline_new (GskVulkanPipelineLayout * layout,
const char *shader_name,
VkRenderPass render_pass);
gsize gsk_vulkan_linear_gradient_pipeline_count_vertex_data
(GskVulkanLinearGradientPipeline*pipeline);
void gsk_vulkan_linear_gradient_pipeline_collect_vertex_data
(GskVulkanLinearGradientPipeline*pipeline,
guchar *data,
const graphene_rect_t *rect,
const graphene_point_t *start,
const graphene_point_t *end,
gboolean repeating,
gsize n_stops,
const GskColorStop *stops);
gsize gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline*pipeline,
VkCommandBuffer command_buffer,
gsize offset,
gsize n_commands);
G_END_DECLS
#endif /* __GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_PRIVATE_H__ */
+58 -24
View File
@@ -2,13 +2,15 @@
#include "gskvulkanpushconstantsprivate.h"
#include <math.h>
#include "gskroundedrectprivate.h"
void
gsk_vulkan_push_constants_init (GskVulkanPushConstants *constants,
const graphene_matrix_t *mvp)
const graphene_matrix_t *mvp,
const graphene_rect_t *viewport)
{
gsk_vulkan_push_constants_set_mvp (constants, mvp);
graphene_matrix_init_from_matrix (&constants->mvp, mvp);
gsk_vulkan_clip_init_empty (&constants->clip, viewport);
}
void
@@ -18,35 +20,67 @@ gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants *self,
*self = *src;
}
void
gsk_vulkan_push_constants_set_mvp (GskVulkanPushConstants *self,
const graphene_matrix_t *mvp)
gboolean
gsk_vulkan_push_constants_transform (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const graphene_matrix_t *transform,
const graphene_rect_t *viewport)
{
graphene_matrix_to_float (mvp, self->vertex.mvp);
if (!gsk_vulkan_clip_transform (&self->clip, &src->clip, transform, viewport))
return FALSE;
graphene_matrix_multiply (transform, &src->mvp, &self->mvp);
return TRUE;
}
gboolean
gsk_vulkan_push_constants_intersect_rect (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const graphene_rect_t *rect)
{
if (!gsk_vulkan_clip_intersect_rect (&self->clip, &src->clip, rect))
return FALSE;
graphene_matrix_init_from_matrix (&self->mvp, &src->mvp);
return TRUE;
}
gboolean
gsk_vulkan_push_constants_intersect_rounded (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const GskRoundedRect *rect)
{
if (!gsk_vulkan_clip_intersect_rounded_rect (&self->clip, &src->clip, rect))
return FALSE;
graphene_matrix_init_from_matrix (&self->mvp, &src->mvp);
return TRUE;
}
static void
gsk_vulkan_push_constants_wire_init (GskVulkanPushConstantsWire *wire,
const GskVulkanPushConstants *self)
{
graphene_matrix_to_float (&self->mvp, wire->vertex.mvp);
gsk_rounded_rect_to_float (&self->clip.rect, wire->vertex.clip);
}
void
gsk_vulkan_push_constants_multiply_mvp (GskVulkanPushConstants *self,
const graphene_matrix_t *transform)
gsk_vulkan_push_constants_push_vertex (const GskVulkanPushConstants *self,
VkCommandBuffer command_buffer,
VkPipelineLayout pipeline_layout)
{
graphene_matrix_t old_mvp, new_mvp;
GskVulkanPushConstantsWire wire;
graphene_matrix_init_from_float (&old_mvp, self->vertex.mvp);
graphene_matrix_multiply (transform, &old_mvp, &new_mvp);
gsk_vulkan_push_constants_set_mvp (self, &new_mvp);
}
gsk_vulkan_push_constants_wire_init (&wire, self);
void
gsk_vulkan_push_constants_push_vertex (GskVulkanPushConstants *self,
VkCommandBuffer command_buffer,
VkPipelineLayout pipeline_layout)
{
vkCmdPushConstants (command_buffer,
pipeline_layout,
VK_SHADER_STAGE_VERTEX_BIT,
G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
sizeof (self->vertex),
&self->vertex);
G_STRUCT_OFFSET (GskVulkanPushConstantsWire, vertex),
sizeof (wire.vertex),
&wire.vertex);
}
#if 0
@@ -76,8 +110,8 @@ gst_vulkan_push_constants_get_ranges (void)
static const VkPushConstantRange ranges[2] = {
{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
.size = sizeof (((GskVulkanPushConstants *) 0)->vertex)
.offset = G_STRUCT_OFFSET (GskVulkanPushConstantsWire, vertex),
.size = sizeof (((GskVulkanPushConstantsWire *) 0)->vertex)
#if 0
},
{
+22 -6
View File
@@ -3,15 +3,24 @@
#include <gdk/gdk.h>
#include <graphene.h>
#include <gsk/gskvulkanclipprivate.h>
G_BEGIN_DECLS
typedef struct _GskVulkanPushConstants GskVulkanPushConstants;
typedef struct _GskVulkanPushConstantsWire GskVulkanPushConstantsWire;
struct _GskVulkanPushConstants
{
graphene_matrix_t mvp;
GskVulkanClip clip;
};
struct _GskVulkanPushConstantsWire
{
struct {
float mvp[16];
float clip[12];
} vertex;
#if 0
struct {
@@ -24,16 +33,23 @@ const VkPushConstantRange *
uint32_t gst_vulkan_push_constants_get_range_count (void) G_GNUC_PURE;
void gsk_vulkan_push_constants_init (GskVulkanPushConstants *constants,
const graphene_matrix_t *mvp);
const graphene_matrix_t *mvp,
const graphene_rect_t *viewport);
void gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src);
void gsk_vulkan_push_constants_set_mvp (GskVulkanPushConstants *self,
const graphene_matrix_t *mvp);
void gsk_vulkan_push_constants_multiply_mvp (GskVulkanPushConstants *self,
const graphene_matrix_t *transform);
gboolean gsk_vulkan_push_constants_transform (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const graphene_matrix_t *transform,
const graphene_rect_t *viewport);
gboolean gsk_vulkan_push_constants_intersect_rect (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const graphene_rect_t *rect);
gboolean gsk_vulkan_push_constants_intersect_rounded (GskVulkanPushConstants *self,
const GskVulkanPushConstants *src,
const GskRoundedRect *rect);
void gsk_vulkan_push_constants_push_vertex (GskVulkanPushConstants *self,
void gsk_vulkan_push_constants_push_vertex (const GskVulkanPushConstants *self,
VkCommandBuffer command_buffer,
VkPipelineLayout pipeline_layout);
+92 -49
View File
@@ -10,6 +10,7 @@
#include "gskvulkanblendpipelineprivate.h"
#include "gskvulkancolorpipelineprivate.h"
#include "gskvulkanlineargradientpipelineprivate.h"
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
@@ -24,8 +25,8 @@ struct _GskVulkanRender
graphene_matrix_t mvp;
int scale_factor;
VkExtent2D size;
VkRect2D scissor;
VkRect2D viewport;
cairo_region_t *clip;
GHashTable *framebuffers;
GskVulkanCommandPool *command_pool;
@@ -48,29 +49,40 @@ struct _GskVulkanRender
};
static void
gsk_vulkan_render_compute_mvp (GskVulkanRender *self)
gsk_vulkan_render_setup (GskVulkanRender *self,
GskVulkanImage *target,
const graphene_rect_t *rect)
{
GdkWindow *window = gsk_renderer_get_window (self->renderer);
graphene_matrix_t modelview, projection;
cairo_rectangle_int_t extents;
cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer)),
&extents);
self->target = g_object_ref (target);
self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
self->size.width = gdk_window_get_width (window) * self->scale_factor;
self->size.height = gdk_window_get_height (window) * self->scale_factor;
self->scissor.offset.x = extents.x * self->scale_factor;
self->scissor.offset.y = extents.y * self->scale_factor;
self->scissor.extent.width = extents.width * self->scale_factor;
self->scissor.extent.height = extents.height * self->scale_factor;
if (rect)
{
self->viewport = (VkRect2D) { { rect->origin.x, rect->origin.y }, { rect->size.width, rect->size.height } };
self->scale_factor = 1;
self->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (target), gsk_vulkan_image_get_height (target)
});
}
else
{
self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
self->viewport.offset = (VkOffset2D) { 0, 0 };
self->viewport.extent.width = gdk_window_get_width (window) * self->scale_factor;
self->viewport.extent.height = gdk_window_get_height (window) * self->scale_factor;
self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer));
}
graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
graphene_matrix_init_ortho (&projection,
0, self->size.width,
0, self->size.height,
self->viewport.offset.x, self->viewport.offset.x + self->viewport.extent.width,
self->viewport.offset.y, self->viewport.offset.y + self->viewport.extent.height,
ORTHO_NEAR_PLANE,
ORTHO_FAR_PLANE);
graphene_matrix_multiply (&modelview, &projection, &self->mvp);
}
@@ -231,7 +243,14 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
self->render_passes = g_slist_prepend (self->render_passes, pass);
gsk_vulkan_render_pass_add (pass, self, &self->mvp, node);
gsk_vulkan_render_pass_add (pass,
self,
&self->mvp,
&GRAPHENE_RECT_INIT (
self->viewport.offset.x, self->viewport.offset.y,
self->viewport.extent.width, self->viewport.extent.height
),
node);
}
void
@@ -295,7 +314,12 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
GskVulkanPipeline * (* create_func) (GskVulkanPipelineLayout *layout, const char *name, VkRenderPass render_pass);
} pipeline_info[GSK_VULKAN_N_PIPELINES] = {
{ "blit", gsk_vulkan_blend_pipeline_new },
{ "color", gsk_vulkan_color_pipeline_new }
{ "color", gsk_vulkan_color_pipeline_new },
{ "color-clip", gsk_vulkan_color_pipeline_new },
{ "color-clip-rounded", gsk_vulkan_color_pipeline_new },
{ "linear", gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip", gsk_vulkan_linear_gradient_pipeline_new },
{ "linear-clip-rounded", gsk_vulkan_linear_gradient_pipeline_new }
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
@@ -439,6 +463,7 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
GskVulkanBuffer *buffer;
VkCommandBuffer command_buffer;
GSList *l;
guint i;
gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
@@ -452,39 +477,49 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
&(VkViewport) {
.x = 0,
.y = 0,
.width = self->size.width,
.height = self->size.height,
.width = self->viewport.extent.width,
.height = self->viewport.extent.height,
.minDepth = 0,
.maxDepth = 1
});
vkCmdSetScissor (command_buffer,
0,
1,
&self->scissor);
vkCmdBeginRenderPass (command_buffer,
&(VkRenderPassBeginInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = self->render_pass,
.framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
.renderArea = {
{ 0, 0 },
{ self->size.width, self->size.height }
},
.clearValueCount = 1,
.pClearValues = (VkClearValue [1]) {
{ .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
}
},
VK_SUBPASS_CONTENTS_INLINE);
for (l = self->render_passes; l; l = l->next)
for (i = 0; i < cairo_region_num_rectangles (self->clip); i++)
{
gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
}
cairo_rectangle_int_t rect;
vkCmdEndRenderPass (command_buffer);
cairo_region_get_rectangle (self->clip, i, &rect);
vkCmdSetScissor (command_buffer,
0,
1,
&(VkRect2D) {
{ rect.x * self->scale_factor, rect.y * self->scale_factor },
{ rect.width * self->scale_factor, rect.height * self->scale_factor }
});
vkCmdBeginRenderPass (command_buffer,
&(VkRenderPassBeginInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = self->render_pass,
.framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
.renderArea = {
{ rect.x * self->scale_factor, rect.y * self->scale_factor },
{ rect.width * self->scale_factor, rect.height * self->scale_factor }
},
.clearValueCount = 1,
.pClearValues = (VkClearValue [1]) {
{ .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
}
},
VK_SUBPASS_CONTENTS_INLINE);
for (l = self->render_passes; l; l = l->next)
{
gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
}
vkCmdEndRenderPass (command_buffer);
}
gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, self->fence);
@@ -500,6 +535,14 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
}
}
GskTexture *
gsk_vulkan_render_download_target (GskVulkanRender *self)
{
gsk_vulkan_uploader_reset (self->uploader);
return gsk_vulkan_image_download (self->target, self->uploader);
}
static void
gsk_vulkan_render_cleanup (GskVulkanRender *self)
{
@@ -527,6 +570,7 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
g_slist_free_full (self->cleanup_images, g_object_unref);
self->cleanup_images = NULL;
g_clear_pointer (&self->clip, cairo_region_destroy);
g_clear_object (&self->target);
}
@@ -589,14 +633,13 @@ gsk_vulkan_render_is_busy (GskVulkanRender *self)
}
void
gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target)
gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target,
const graphene_rect_t *rect)
{
gsk_vulkan_render_cleanup (self);
self->target = g_object_ref (target);
gsk_vulkan_render_compute_mvp (self);
gsk_vulkan_render_setup (self, target, rect);
}
GskRenderer *
+53 -16
View File
@@ -170,6 +170,54 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
g_clear_object (&self->vulkan);
}
static GskTexture *
gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GskVulkanRender *render;
GskVulkanImage *image;
GskTexture *texture;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
#endif
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
render = gsk_vulkan_render_new (renderer, self->vulkan);
image = gsk_vulkan_image_new_for_framebuffer (self->vulkan,
ceil (viewport->size.width),
ceil (viewport->size.height));
gsk_vulkan_render_reset (render, image, viewport);
gsk_vulkan_render_add_node (render, root);
gsk_vulkan_render_upload (render);
gsk_vulkan_render_draw (render, self->sampler);
texture = gsk_vulkan_render_download_target (render);
g_object_unref (image);
gsk_vulkan_render_free (render);
#ifdef G_ENABLE_DEBUG
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
gsk_profiler_push_samples (profiler);
#endif
return texture;
}
static void
gsk_vulkan_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
@@ -188,7 +236,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
render = self->render;
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)]);
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL);
gsk_vulkan_render_add_node (render, root);
@@ -209,23 +257,11 @@ gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
const cairo_region_t *region)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
cairo_region_t *whole_window;
GdkDrawingContext *result;
GdkWindow *window;
window = gsk_renderer_get_window (renderer);
whole_window = cairo_region_create_rectangle (&(GdkRectangle) {
0, 0,
gdk_window_get_width (window),
gdk_window_get_height (window)
});
result = gdk_window_begin_draw_frame (window,
result = gdk_window_begin_draw_frame (gsk_renderer_get_window (renderer),
GDK_DRAW_CONTEXT (self->vulkan),
whole_window);
cairo_region_destroy (whole_window);
region);
return result;
}
@@ -238,6 +274,7 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
renderer_class->realize = gsk_vulkan_renderer_realize;
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
renderer_class->render = gsk_vulkan_renderer_render;
renderer_class->render_texture = gsk_vulkan_renderer_render_texture;
renderer_class->begin_draw_frame = gsk_vulkan_renderer_begin_draw_frame;
}
@@ -281,7 +318,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
if (data)
return g_object_ref (data->image);
surface = gsk_texture_download (texture);
surface = gsk_texture_download_surface (texture);
image = gsk_vulkan_image_new_from_data (uploader,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_width (surface),
+218 -28
View File
@@ -2,11 +2,15 @@
#include "gskvulkanrenderpassprivate.h"
#include "gskvulkanblendpipelineprivate.h"
#include "gskvulkancolorpipelineprivate.h"
#include "gskvulkanimageprivate.h"
#include "gskdebugprivate.h"
#include "gskrendernodeprivate.h"
#include "gskrenderer.h"
#include "gskroundedrectprivate.h"
#include "gskvulkanblendpipelineprivate.h"
#include "gskvulkanclipprivate.h"
#include "gskvulkancolorpipelineprivate.h"
#include "gskvulkanlineargradientpipelineprivate.h"
#include "gskvulkanimageprivate.h"
#include "gskvulkanpushconstantsprivate.h"
#include "gskvulkanrendererprivate.h"
@@ -17,9 +21,12 @@ typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants;
typedef enum {
/* GskVulkanOpRender */
GSK_VULKAN_OP_FALLBACK,
GSK_VULKAN_OP_FALLBACK_CLIP,
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
GSK_VULKAN_OP_SURFACE,
GSK_VULKAN_OP_TEXTURE,
GSK_VULKAN_OP_COLOR,
GSK_VULKAN_OP_LINEAR_GRADIENT,
/* GskVulkanOpPushConstants */
GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS
} GskVulkanOpType;
@@ -29,6 +36,7 @@ struct _GskVulkanOpRender
GskVulkanOpType type;
GskRenderNode *node; /* node that's the source of this op */
GskVulkanPipeline *pipeline; /* pipeline to use */
GskRoundedRect clip; /* clip rect (or random memory if not relevant) */
GskVulkanImage *source; /* source image to render */
gsize vertex_offset; /* offset into vertex buffer */
gsize vertex_count; /* number of vertices */
@@ -77,6 +85,11 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
g_slice_free (GskVulkanRenderPass, self);
}
#define FALLBACK(...) G_STMT_START { \
GSK_NOTE (FALLBACK, g_print (__VA_ARGS__)); \
goto fallback; \
}G_STMT_END
void
gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
GskVulkanRender *render,
@@ -87,39 +100,66 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
.type = GSK_VULKAN_OP_FALLBACK,
.render.node = node
};
GskVulkanPipelineType pipeline_type;
switch (gsk_render_node_get_node_type (node))
{
case GSK_NOT_A_RENDER_NODE:
g_assert_not_reached ();
break;
return;
default:
op.type = GSK_VULKAN_OP_FALLBACK;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
g_array_append_val (self->render_ops, op);
break;
FALLBACK ("Unsupported node '%s'\n", node->node_class->type_name);
case GSK_CAIRO_NODE:
if (gsk_cairo_node_get_surface (node) != NULL)
{
op.type = GSK_VULKAN_OP_SURFACE;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
g_array_append_val (self->render_ops, op);
}
break;
if (gsk_cairo_node_get_surface (node) == NULL)
return;
if (!gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
FALLBACK ("Cairo nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_SURFACE;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
g_array_append_val (self->render_ops, op);
return;
case GSK_TEXTURE_NODE:
if (!gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
FALLBACK ("Texture nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_TEXTURE;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
g_array_append_val (self->render_ops, op);
break;
return;
case GSK_COLOR_NODE:
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
pipeline_type = GSK_VULKAN_PIPELINE_COLOR;
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP;
else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED;
else
FALLBACK ("Color nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_COLOR;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_COLOR);
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type);
g_array_append_val (self->render_ops, op);
break;
return;
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
if (gsk_linear_gradient_node_get_n_color_stops (node) > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
FALLBACK ("Linear gradient with %zu color stops, hardcoded limit is %u\n",
gsk_linear_gradient_node_get_n_color_stops (node),
GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT;
else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP;
else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED;
else
FALLBACK ("Linear gradient nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_LINEAR_GRADIENT;
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type);
g_array_append_val (self->render_ops, op);
return;
case GSK_CONTAINER_NODE:
{
@@ -130,36 +170,107 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
gsk_vulkan_render_pass_add_node (self, render, constants, gsk_container_node_get_child (node, i));
}
}
break;
return;
case GSK_TRANSFORM_NODE:
{
graphene_matrix_t transform;
GskRenderNode *child;
#if 0
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
FALLBACK ("Transform nodes can't deal with clip type %u\n", clip->type);
#endif
gsk_transform_node_get_transform (node, &transform);
child = gsk_transform_node_get_child (node);
if (!gsk_vulkan_push_constants_transform (&op.constants.constants, constants, &transform, &child->bounds))
FALLBACK ("Transform nodes can't deal with clip type %u\n", constants->clip.type);
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
gsk_vulkan_push_constants_multiply_mvp (&op.constants.constants, &transform);
g_array_append_val (self->render_ops, op);
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_transform_node_get_child (node));
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, child);
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
g_array_append_val (self->render_ops, op);
}
break;
return;
case GSK_CLIP_NODE:
{
if (!gsk_vulkan_push_constants_intersect_rect (&op.constants.constants, constants, gsk_clip_node_peek_clip (node)))
FALLBACK ("Failed to find intersection between clip of type %u and rectangle\n", constants->clip.type);
if (&op.constants.constants.clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
return;
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
g_array_append_val (self->render_ops, op);
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_clip_node_get_child (node));
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
g_array_append_val (self->render_ops, op);
}
return;
case GSK_ROUNDED_CLIP_NODE:
{
if (!gsk_vulkan_push_constants_intersect_rounded (&op.constants.constants,
constants,
gsk_rounded_clip_node_peek_clip (node)))
FALLBACK ("Failed to find intersection between clip of type %u and rounded rectangle\n", constants->clip.type);
if (&op.constants.constants.clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
return;
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
g_array_append_val (self->render_ops, op);
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_rounded_clip_node_get_child (node));
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
g_array_append_val (self->render_ops, op);
}
return;
}
g_assert_not_reached ();
return;
fallback:
switch (constants->clip.type)
{
case GSK_VULKAN_CLIP_NONE:
op.type = GSK_VULKAN_OP_FALLBACK;
break;
case GSK_VULKAN_CLIP_RECT:
op.type = GSK_VULKAN_OP_FALLBACK_CLIP;
gsk_rounded_rect_init_copy (&op.render.clip, &constants->clip.rect);
break;
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
case GSK_VULKAN_CLIP_ROUNDED:
op.type = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP;
gsk_rounded_rect_init_copy (&op.render.clip, &constants->clip.rect);
break;
case GSK_VULKAN_CLIP_ALL_CLIPPED:
default:
g_assert_not_reached ();
return;
}
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
g_array_append_val (self->render_ops, op);
}
#undef FALLBACK
void
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
const graphene_matrix_t *mvp,
const graphene_rect_t *viewport,
GskRenderNode *node)
{
GskVulkanOp op = { 0, };
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
gsk_vulkan_push_constants_init (&op.constants.constants, mvp);
gsk_vulkan_push_constants_init (&op.constants.constants, mvp, viewport);
g_array_append_val (self->render_ops, op);
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, node);
@@ -177,12 +288,30 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
node = op->node;
/* XXX: We could intersect bounds with clip bounds here */
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
ceil (node->bounds.size.width),
ceil (node->bounds.size.height));
cr = cairo_create (surface);
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
if (op->type == GSK_VULKAN_OP_FALLBACK_CLIP)
{
cairo_rectangle (cr,
op->clip.bounds.origin.x, op->clip.bounds.origin.y,
op->clip.bounds.size.width, op->clip.bounds.size.height);
cairo_clip (cr);
}
else if (op->type == GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP)
{
gsk_rounded_rect_path (&op->clip, cr);
cairo_clip (cr);
}
else
{
g_assert (op->type == GSK_VULKAN_OP_FALLBACK);
}
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
@@ -213,6 +342,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader);
break;
@@ -240,6 +371,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_COLOR:
case GSK_VULKAN_OP_LINEAR_GRADIENT:
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
break;
}
@@ -261,6 +393,8 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline));
@@ -272,6 +406,11 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
n_bytes += op->render.vertex_count;
break;
case GSK_VULKAN_OP_LINEAR_GRADIENT:
op->render.vertex_count = gsk_vulkan_linear_gradient_pipeline_count_vertex_data (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (op->render.pipeline));
n_bytes += op->render.vertex_count;
break;
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
@@ -300,6 +439,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
{
@@ -322,6 +463,21 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
}
break;
case GSK_VULKAN_OP_LINEAR_GRADIENT:
{
op->render.vertex_offset = offset + n_bytes;
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (op->render.pipeline),
data + n_bytes + offset,
&op->render.node->bounds,
gsk_linear_gradient_node_peek_start (op->render.node),
gsk_linear_gradient_node_peek_end (op->render.node),
gsk_render_node_get_node_type (op->render.node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
gsk_linear_gradient_node_get_n_color_stops (op->render.node),
gsk_linear_gradient_node_peek_color_stops (op->render.node));
n_bytes += op->render.vertex_count;
}
break;
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
@@ -348,6 +504,8 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source);
@@ -356,6 +514,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_COLOR:
case GSK_VULKAN_OP_LINEAR_GRADIENT:
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
break;
}
@@ -372,15 +531,18 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanPipeline *current_pipeline = NULL;
gsize current_draw_index = 0;
GskVulkanOp *op;
guint i;
guint i, step;
for (i = 0; i < self->render_ops->len; i++)
for (i = 0; i < self->render_ops->len; i += step)
{
op = &g_array_index (self->render_ops, GskVulkanOp, i);
step = 1;
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_FALLBACK_CLIP:
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
if (current_pipeline != op->render.pipeline)
@@ -432,9 +594,37 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
current_draw_index = 0;
}
for (step = 1; step + i < self->render_ops->len; step++)
{
GskVulkanOp *cmp = &g_array_index (self->render_ops, GskVulkanOp, i + step);
if (cmp->type != GSK_VULKAN_OP_COLOR ||
cmp->render.pipeline != current_pipeline)
break;
}
current_draw_index += gsk_vulkan_color_pipeline_draw (GSK_VULKAN_COLOR_PIPELINE (current_pipeline),
command_buffer,
current_draw_index, 1);
current_draw_index, step);
break;
case GSK_VULKAN_OP_LINEAR_GRADIENT:
if (current_pipeline != op->render.pipeline)
{
current_pipeline = op->render.pipeline;
vkCmdBindPipeline (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
gsk_vulkan_pipeline_get_pipeline (current_pipeline));
vkCmdBindVertexBuffers (command_buffer,
0,
1,
(VkBuffer[1]) {
gsk_vulkan_buffer_get_buffer (vertex_buffer)
},
(VkDeviceSize[1]) { op->render.vertex_offset });
current_draw_index = 0;
}
current_draw_index += gsk_vulkan_linear_gradient_pipeline_draw (GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (current_pipeline),
command_buffer,
current_draw_index, 1);
break;
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+1
View File
@@ -17,6 +17,7 @@ void gsk_vulkan_render_pass_free (GskVulk
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
const graphene_matrix_t*mvp,
const graphene_rect_t *viewport,
GskRenderNode *node);
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
+9 -1
View File
@@ -12,6 +12,11 @@ G_BEGIN_DECLS
typedef enum {
GSK_VULKAN_PIPELINE_BLIT,
GSK_VULKAN_PIPELINE_COLOR,
GSK_VULKAN_PIPELINE_COLOR_CLIP,
GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP,
GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED,
/* add more */
GSK_VULKAN_N_PIPELINES
} GskVulkanPipelineType;
@@ -24,7 +29,8 @@ void gsk_vulkan_render_free (GskVulk
gboolean gsk_vulkan_render_is_busy (GskVulkanRender *self);
void gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target);
GskVulkanImage *target,
const graphene_rect_t *rect);
GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self);
@@ -47,6 +53,8 @@ void gsk_vulkan_render_draw (GskVulk
void gsk_vulkan_render_submit (GskVulkanRender *self);
GskTexture * gsk_vulkan_render_download_target (GskVulkanRender *self);
G_END_DECLS
#endif /* __GSK_VULKAN_RENDER_PRIVATE_H__ */
+3
View File
@@ -5,6 +5,9 @@ layout(location = 1) in vec2 inTexCoord;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out vec2 outTexCoord;
Binary file not shown.
@@ -0,0 +1,56 @@
#version 420 core
layout(location = 0) in vec2 inPos;
layout(location = 1) in vec4 inColor;
layout(location = 2) in vec4 inClipBounds;
layout(location = 3) in vec4 inClipWidths;
layout(location = 0) out vec4 color;
struct RoundedRect {
vec4 bounds;
vec4 corners;
};
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
float clip(vec2 pos, RoundedRect r) {
vec2 ref_tl = r.bounds.xy + vec2( r.corners.x, r.corners.x);
vec2 ref_tr = r.bounds.zy + vec2(-r.corners.y, r.corners.y);
vec2 ref_br = r.bounds.zw + vec2(-r.corners.z, -r.corners.z);
vec2 ref_bl = r.bounds.xw + vec2( r.corners.w, -r.corners.w);
float d_tl = distance(pos, ref_tl);
float d_tr = distance(pos, ref_tr);
float d_br = distance(pos, ref_br);
float d_bl = distance(pos, ref_bl);
float pixels_per_fragment = length(fwidth(pos.xy));
float nudge = 0.5 * pixels_per_fragment;
vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - r.corners + nudge;
bvec4 is_out = bvec4(pos.x < ref_tl.x && pos.y < ref_tl.y,
pos.x > ref_tr.x && pos.y < ref_tr.y,
pos.x > ref_br.x && pos.y > ref_br.y,
pos.x < ref_bl.x && pos.y > ref_bl.y);
float distance_from_border = dot(vec4(is_out),
max(vec4(0.0, 0.0, 0.0, 0.0), distances));
// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;
// Apply a more gradual fade out to transparent.
//distance_from_border -= 0.5;
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
}
void main()
{
RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
color = vec4(inColor.rgb * inColor.a, inColor.a) * clip (inPos, r);
}
Binary file not shown.
@@ -0,0 +1,36 @@
#version 420 core
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inColor;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out vec2 outPos;
layout(location = 1) out flat vec4 outColor;
layout(location = 2) out flat vec4 outClipBounds;
layout(location = 3) out flat vec4 outClipWidths;
out gl_PerVertex {
vec4 gl_Position;
};
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0) };
void main() {
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outPos = pos;
outColor = inColor;
outClipBounds = push.clip_bounds;
outClipWidths = push.clip_widths;
}
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
#version 420 core
layout(location = 0) in vec4 inColor;
layout(location = 0) out vec4 color;
void main()
{
color = vec4(inColor.rgb * inColor.a, inColor.a);
}
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
#version 420 core
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inColor;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
out gl_PerVertex {
vec4 gl_Position;
};
layout(location = 0) out vec4 outColor;
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0) };
vec4 intersect(vec4 a, vec4 b)
{
a = vec4(a.xy, a.xy + a.zw);
b = vec4(b.xy, b.xy + b.zw);
vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
if (any (greaterThanEqual (result.xy, result.zw)))
return vec4(0.0,0.0,0.0,0.0);
return vec4(result.xy, result.zw - result.xy);
}
void main() {
vec4 rect = intersect(inRect, push.clip_bounds);
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outColor = inColor;
}
Binary file not shown.
+1 -1
View File
@@ -6,5 +6,5 @@ layout(location = 0) out vec4 color;
void main()
{
color = inColor;
color = vec4(inColor.rgb * inColor.a, inColor.a);
}
Binary file not shown.
+3
View File
@@ -5,6 +5,9 @@ layout(location = 1) in vec4 inColor;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out vec4 outColor;
Binary file not shown.
@@ -0,0 +1,78 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
struct RoundedRect {
vec4 bounds;
vec4 corners;
};
layout(location = 0) in vec2 inPos;
layout(location = 1) in float inGradientPos;
layout(location = 2) in flat int inRepeating;
layout(location = 3) in flat int inStopCount;
layout(location = 4) in flat vec4 inClipBounds;
layout(location = 5) in flat vec4 inClipWidths;
layout(location = 6) in flat ColorStop inStops[8];
layout(location = 0) out vec4 outColor;
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
float clip(vec2 pos, RoundedRect r) {
vec2 ref_tl = r.bounds.xy + vec2( r.corners.x, r.corners.x);
vec2 ref_tr = r.bounds.zy + vec2(-r.corners.y, r.corners.y);
vec2 ref_br = r.bounds.zw + vec2(-r.corners.z, -r.corners.z);
vec2 ref_bl = r.bounds.xw + vec2( r.corners.w, -r.corners.w);
float d_tl = distance(pos, ref_tl);
float d_tr = distance(pos, ref_tr);
float d_br = distance(pos, ref_br);
float d_bl = distance(pos, ref_bl);
float pixels_per_fragment = length(fwidth(pos.xy));
float nudge = 0.5 * pixels_per_fragment;
vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - r.corners + nudge;
bvec4 is_out = bvec4(pos.x < ref_tl.x && pos.y < ref_tl.y,
pos.x > ref_tr.x && pos.y < ref_tr.y,
pos.x > ref_br.x && pos.y > ref_br.y,
pos.x < ref_bl.x && pos.y > ref_bl.y);
float distance_from_border = dot(vec4(is_out),
max(vec4(0.0, 0.0, 0.0, 0.0), distances));
// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;
// Apply a more gradual fade out to transparent.
//distance_from_border -= 0.5;
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
}
void main()
{
RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths);
float pos;
if (inRepeating != 0)
pos = fract (inGradientPos);
else
pos = clamp (inGradientPos, 0, 1);
vec4 color = inStops[0].color;
int n = clamp (inStopCount, 2, 8);
for (int i = 1; i < n; i++)
{
if (inStops[i].offset > inStops[i-1].offset)
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
}
//outColor = vec4(pos, pos, pos, 1.0);
outColor = color * clip (inPos, r);
}
Binary file not shown.
@@ -0,0 +1,84 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec2 inStart;
layout(location = 2) in vec2 inEnd;
layout(location = 3) in int inRepeating;
layout(location = 4) in int inStopCount;
layout(location = 5) in vec4 inOffsets0;
layout(location = 6) in vec4 inOffsets1;
layout(location = 7) in vec4 inColors0;
layout(location = 8) in vec4 inColors1;
layout(location = 9) in vec4 inColors2;
layout(location = 10) in vec4 inColors3;
layout(location = 11) in vec4 inColors4;
layout(location = 12) in vec4 inColors5;
layout(location = 13) in vec4 inColors6;
layout(location = 14) in vec4 inColors7;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out vec2 outPos;
layout(location = 1) out float outGradientPos;
layout(location = 2) out flat int outRepeating;
layout(location = 3) out flat int outStopCount;
layout(location = 4) out flat vec4 outClipBounds;
layout(location = 5) out flat vec4 outClipWidths;
layout(location = 6) out flat ColorStop outStops[8];
out gl_PerVertex {
vec4 gl_Position;
};
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0) };
float
get_gradient_pos (vec2 pos)
{
pos = pos - inStart;
vec2 grad = inEnd - inStart;
return dot (pos, grad) / dot (grad, grad);
}
void main() {
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outPos = pos;
outGradientPos = get_gradient_pos (pos);
outClipBounds = push.clip_bounds;
outClipWidths = push.clip_widths;
outRepeating = inRepeating;
outStopCount = inStopCount;
outStops[0].offset = inOffsets0[0];
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
outStops[1].offset = inOffsets0[1];
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
outStops[2].offset = inOffsets0[2];
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
outStops[3].offset = inOffsets0[3];
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
outStops[4].offset = inOffsets1[0];
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
outStops[5].offset = inOffsets1[1];
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
outStops[6].offset = inOffsets1[2];
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
outStops[7].offset = inOffsets1[3];
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
}
Binary file not shown.
@@ -0,0 +1,33 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in float inGradientPos;
layout(location = 1) in flat int inRepeating;
layout(location = 2) in flat int inStopCount;
layout(location = 3) in flat ColorStop inStops[8];
layout(location = 0) out vec4 outColor;
void main()
{
float pos;
if (inRepeating != 0)
pos = fract (inGradientPos);
else
pos = clamp (inGradientPos, 0, 1);
vec4 color = inStops[0].color;
int n = clamp (inStopCount, 2, 8);
for (int i = 1; i < n; i++)
{
if (inStops[i].offset > inStops[i-1].offset)
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
}
//outColor = vec4(pos, pos, pos, 1.0);
outColor = color;
}
Binary file not shown.
@@ -0,0 +1,78 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec2 inStart;
layout(location = 2) in vec2 inEnd;
layout(location = 3) in int inRepeating;
layout(location = 4) in int inStopCount;
layout(location = 5) in vec4 inOffsets0;
layout(location = 6) in vec4 inOffsets1;
layout(location = 7) in vec4 inColors0;
layout(location = 8) in vec4 inColors1;
layout(location = 9) in vec4 inColors2;
layout(location = 10) in vec4 inColors3;
layout(location = 11) in vec4 inColors4;
layout(location = 12) in vec4 inColors5;
layout(location = 13) in vec4 inColors6;
layout(location = 14) in vec4 inColors7;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out float outGradientPos;
layout(location = 1) out flat int outRepeating;
layout(location = 2) out flat int outStopCount;
layout(location = 3) out flat ColorStop outStops[8];
out gl_PerVertex {
vec4 gl_Position;
};
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0) };
float
get_gradient_pos (vec2 pos)
{
pos = pos - inStart;
vec2 grad = inEnd - inStart;
return dot (pos, grad) / dot (grad, grad);
}
void main() {
vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outGradientPos = get_gradient_pos (pos);
outRepeating = inRepeating;
outStopCount = inStopCount;
outStops[0].offset = inOffsets0[0];
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
outStops[1].offset = inOffsets0[1];
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
outStops[2].offset = inOffsets0[2];
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
outStops[3].offset = inOffsets0[3];
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
outStops[4].offset = inOffsets1[0];
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
outStops[5].offset = inOffsets1[1];
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
outStops[6].offset = inOffsets1[2];
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
outStops[7].offset = inOffsets1[3];
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
}
Binary file not shown.
+33
View File
@@ -0,0 +1,33 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in float inGradientPos;
layout(location = 1) in flat int inRepeating;
layout(location = 2) in flat int inStopCount;
layout(location = 3) in flat ColorStop inStops[8];
layout(location = 0) out vec4 outColor;
void main()
{
float pos;
if (inRepeating != 0)
pos = fract (inGradientPos);
else
pos = clamp (inGradientPos, 0, 1);
vec4 color = inStops[0].color;
int n = clamp (inStopCount, 2, 8);
for (int i = 1; i < n; i++)
{
if (inStops[i].offset > inStops[i-1].offset)
color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
}
//outColor = vec4(pos, pos, pos, 1.0);
outColor = color;
}
Binary file not shown.
+89
View File
@@ -0,0 +1,89 @@
#version 420 core
struct ColorStop {
float offset;
vec4 color;
};
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec2 inStart;
layout(location = 2) in vec2 inEnd;
layout(location = 3) in int inRepeating;
layout(location = 4) in int inStopCount;
layout(location = 5) in vec4 inOffsets0;
layout(location = 6) in vec4 inOffsets1;
layout(location = 7) in vec4 inColors0;
layout(location = 8) in vec4 inColors1;
layout(location = 9) in vec4 inColors2;
layout(location = 10) in vec4 inColors3;
layout(location = 11) in vec4 inColors4;
layout(location = 12) in vec4 inColors5;
layout(location = 13) in vec4 inColors6;
layout(location = 14) in vec4 inColors7;
layout(push_constant) uniform PushConstants {
mat4 mvp;
vec4 clip_bounds;
vec4 clip_widths;
vec4 clip_heights;
} push;
layout(location = 0) out float outGradientPos;
layout(location = 1) out flat int outRepeating;
layout(location = 2) out flat int outStopCount;
layout(location = 3) out flat ColorStop outStops[8];
out gl_PerVertex {
vec4 gl_Position;
};
vec2 offsets[6] = { vec2(0.0, 0.0),
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, 1.0),
vec2(1.0, 0.0),
vec2(1.0, 1.0) };
vec4 intersect(vec4 a, vec4 b)
{
a = vec4(a.xy, a.xy + a.zw);
b = vec4(b.xy, b.xy + b.zw);
vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
if (any (greaterThanEqual (result.xy, result.zw)))
return vec4(0.0,0.0,0.0,0.0);
return vec4(result.xy, result.zw - result.xy);
}
float
get_gradient_pos (vec2 pos)
{
pos = pos - inStart;
vec2 grad = inEnd - inStart;
return dot (pos, grad) / dot (grad, grad);
}
void main() {
vec4 rect = intersect(inRect, push.clip_bounds);
vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outGradientPos = get_gradient_pos (pos);
outRepeating = inRepeating;
outStopCount = inStopCount;
outStops[0].offset = inOffsets0[0];
outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
outStops[1].offset = inOffsets0[1];
outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
outStops[2].offset = inOffsets0[2];
outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
outStops[3].offset = inOffsets0[3];
outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
outStops[4].offset = inOffsets1[0];
outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
outStops[5].offset = inOffsets1[1];
outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
outStops[6].offset = inOffsets1[2];
outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
outStops[7].offset = inOffsets1[3];
outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
}
Binary file not shown.
+1 -1
View File
@@ -1071,7 +1071,7 @@ main (int argc, const char *argv[])
{
g_set_prgname ("gtk-builder-tool");
gtk_init (NULL, NULL);
gtk_init ();
gtk_test_register_all_types ();
+1 -3
View File
@@ -79,8 +79,6 @@ main (int argc, char *argv[])
"optionally passing one or more URIs as arguments.");
g_option_context_set_summary (context, summary);
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
g_option_context_add_group (context, gtk_get_option_group (FALSE));
g_option_context_parse (context, &argc, &argv, &error);
g_option_context_free (context);
@@ -116,7 +114,7 @@ main (int argc, char *argv[])
}
gtk_init (&argc, &argv);
gtk_init ();
app_name = *args;
#ifdef G_OS_UNIX
+1 -1
View File
@@ -30,7 +30,7 @@ main (int argc, char **argv)
int max_prop_name_length = 0;
gchar *pattern = NULL;
gtk_init (&argc, &argv);
gtk_init ();
if (argc > 1)
pattern = argv[1];
+1 -3
View File
@@ -290,7 +290,7 @@ gtk_application_startup (GApplication *g_application)
gtk_action_muxer_insert (application->priv->muxer, "app", G_ACTION_GROUP (application));
gtk_init (NULL, NULL);
gtk_init ();
application->priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
gtk_application_impl_startup (application->priv->impl, application->priv->register_session);
@@ -327,8 +327,6 @@ gtk_application_local_command_line (GApplication *application,
gchar ***arguments,
gint *exit_status)
{
g_application_add_option_group (application, gtk_get_option_group (FALSE));
return G_APPLICATION_CLASS (gtk_application_parent_class)->local_command_line (application, arguments, exit_status);
}
+59 -53
View File
@@ -481,8 +481,9 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
GtkPackType packing;
gint size;
gint extra;
gint extra_space;
gint children_minimum_size = 0;
gint size_given_to_child;
gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
gint x = 0, y = 0, i;
gint child_size;
@@ -500,9 +501,9 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
spacing = get_spacing (box);
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
size = allocation->width - (nvis_children - 1) * spacing;
extra_space = allocation->width - (nvis_children - 1) * spacing;
else
size = allocation->height - (nvis_children - 1) * spacing;
extra_space = allocation->height - (nvis_children - 1) * spacing;
have_baseline = FALSE;
minimum_above = natural_above = 0;
@@ -541,7 +542,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
size -= sizes[i].minimum_size;
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
@@ -550,32 +551,32 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
if (private->homogeneous)
{
/* If were homogenous we still need to run the above loop to get the
* minimum sizes for children that are not going to fill
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
size = allocation->width - (nvis_children - 1) * get_spacing (box);
else
size = allocation->height - (nvis_children - 1) * get_spacing (box);
extra = size / nvis_children;
n_extra_widgets = size % nvis_children;
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
size = gtk_distribute_natural_allocation (MAX (0, size), nvis_children, sizes);
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
extra = size / nexpand_children;
n_extra_widgets = size % nexpand_children;
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
extra = 0;
{
size_given_to_child = 0;
}
}
/* Allocate child sizes. */
@@ -603,7 +604,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
/* Assign the child's size. */
if (private->homogeneous)
{
child_size = extra;
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
@@ -617,7 +618,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
{
child_size += extra;
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
@@ -815,7 +816,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
GtkPackType packing;
gint min_size[2];
gint nat_size[2];
gint extra[2];
gint size_given_to_child[2];
gint n_extra_widgets[2];
gint x = 0, y = 0, i;
gint child_size;
@@ -895,30 +896,34 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
if (priv->homogeneous)
{
extra[0] = ((box_size - center_size) / 2 - nvis[0] * spacing) / nvis[0];
extra[1] = ((box_size - center_size) / 2 - nvis[1] * spacing) / nvis[1];
extra[0] = MIN (extra[0], extra[1]);
size_given_to_child[0] = ((box_size - center_size) / 2 - nvis[0] * spacing) / nvis[0];
size_given_to_child[1] = ((box_size - center_size) / 2 - nvis[1] * spacing) / nvis[1];
size_given_to_child[0] = MIN (size_given_to_child[0], size_given_to_child[1]);
n_extra_widgets[0] = 0;
}
else
{
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; packing++)
{
gint s;
gint extra_space;
/* Distribute the remainder naturally on each side */
s = MIN ((box_size - center_size) / 2 - min_size[packing], box_size - center_size - min_size[0] - min_size[1]);
s = gtk_distribute_natural_allocation (MAX (0, s), nvis[packing], sizes[packing]);
extra_space = MIN ((box_size - center_size) / 2 - min_size[packing],
box_size - center_size - min_size[0] - min_size[1]);
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis[packing], sizes[packing]);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexp[packing] > 0)
{
extra[packing] = s / nexp[packing];
n_extra_widgets[packing] = s % nexp[packing];
size_given_to_child[packing] = extra_space / nexp[packing];
n_extra_widgets[packing] = extra_space % nexp[packing];
}
else
{
size_given_to_child[packing] = 0;
}
else
extra[packing] = 0;
}
}
@@ -944,7 +949,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
/* Assign the child's size. */
if (priv->homogeneous)
{
child_size = extra[0];
child_size = size_given_to_child[0];
if (n_extra_widgets[0] > 0)
{
@@ -958,7 +963,7 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
if (child->expand || gtk_widget_compute_expand (child->widget, priv->orientation))
{
child_size += extra[packing];
child_size += size_given_to_child[packing];
if (n_extra_widgets[packing] > 0)
{
@@ -1679,7 +1684,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxPrivate *private = box->priv;
GtkBoxPrivate *private = box->priv;
GtkBoxChild *child;
GList *children;
gint nvis_children;
@@ -1690,7 +1695,8 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
GtkRequestedSize *sizes;
GtkPackType packing;
gint size, extra, i;
gint extra_space, size_given_to_child, i;
gint children_minimum_size = 0;
gint child_size, child_minimum, child_natural;
gint child_minimum_baseline, child_natural_baseline;
gint n_extra_widgets = 0;
@@ -1704,7 +1710,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
spacing = get_spacing (box);
sizes = g_newa (GtkRequestedSize, nvis_children);
size = avail_size - (nvis_children - 1) * spacing;
extra_space = avail_size - (nvis_children - 1) * spacing;
/* Retrieve desired size for visible children */
for (i = 0, children = private->children; children; children = children->next)
@@ -1733,7 +1739,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
sizes[i].natural_size,
sizes[i].minimum_size);
size -= sizes[i].minimum_size;
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
@@ -1743,28 +1749,32 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
if (private->homogeneous)
{
/* If were homogenous we still need to run the above loop to get the
* minimum sizes for children that are not going to fill
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
size = avail_size - (nvis_children - 1) * spacing;
extra = size / nvis_children;
n_extra_widgets = size % nvis_children;
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
size = gtk_distribute_natural_allocation (MAX (0, size), nvis_children, sizes);
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
extra = size / nexpand_children;
n_extra_widgets = size % nexpand_children;
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
extra = 0;
{
size_given_to_child = 0;
}
}
have_baseline = FALSE;
@@ -1795,7 +1805,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
/* Assign the child's size. */
if (private->homogeneous)
{
child_size = extra;
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
@@ -1809,7 +1819,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
{
child_size += extra;
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
@@ -1820,13 +1830,9 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
}
if (child->fill)
{
child_size = MAX (1, child_size);
}
child_size = MAX (1, child_size);
else
{
child_size = sizes[i].minimum_size;
}
child_size = sizes[i].minimum_size;
child_minimum_baseline = child_natural_baseline = -1;
+108 -115
View File
@@ -79,7 +79,9 @@
#include "gtkmarshalers.h"
#include "gtktooltip.h"
#include "gtkprivate.h"
#include "gtkrender.h"
#include "gtkrendericonprivate.h"
#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#define TIMEOUT_INITIAL 500
#define TIMEOUT_REPEAT 50
@@ -270,8 +272,8 @@ static void gtk_calendar_measure (GtkWidget *widget,
int *natural_baseline);
static void gtk_calendar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_calendar_draw (GtkWidget *widget,
cairo_t *cr);
static void gtk_calendar_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static gboolean gtk_calendar_button_press (GtkWidget *widget,
GdkEventButton *event);
static gboolean gtk_calendar_button_release (GtkWidget *widget,
@@ -365,7 +367,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
widget_class->unrealize = gtk_calendar_unrealize;
widget_class->map = gtk_calendar_map;
widget_class->unmap = gtk_calendar_unmap;
widget_class->draw = gtk_calendar_draw;
widget_class->snapshot = gtk_calendar_snapshot;
widget_class->measure = gtk_calendar_measure;
widget_class->size_allocate = gtk_calendar_size_allocate;
widget_class->button_press_event = gtk_calendar_button_press;
@@ -2132,7 +2134,8 @@ gtk_calendar_size_allocate (GtkWidget *widget,
****************************************/
static void
calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
calendar_snapshot_header (GtkCalendar *calendar,
GtkSnapshot *snapshot)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
@@ -2155,8 +2158,7 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
get_component_paddings (calendar, &padding, NULL, NULL, NULL);
context = gtk_widget_get_style_context (widget);
cairo_save (cr);
cairo_translate (cr, padding.left, padding.top);
gtk_snapshot_translate_2d (snapshot, padding.left, padding.top);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
year_left = priv->year_before;
@@ -2178,8 +2180,8 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
gtk_style_context_set_state (context, state);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HEADER);
gtk_render_background (context, cr, 0, 0, header_width, priv->header_h);
gtk_render_frame (context, cr, 0, 0, header_width, priv->header_h);
gtk_snapshot_render_background (snapshot, context, 0, 0, header_width, priv->header_h);
gtk_snapshot_render_frame (snapshot, context, 0, 0, header_width, priv->header_h);
tmp_time = 1; /* Jan 1 1970, 00:00:01 UTC */
tm = gmtime (&tmp_time);
@@ -2220,7 +2222,7 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
x = header_width - (3 + priv->arrow_width + max_year_width
- (max_year_width - logical_rect.width)/2);
gtk_render_layout (context, cr, x, y, layout);
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
/* Draw month */
g_snprintf (buffer, sizeof (buffer), "%s", default_monthname[priv->month]);
@@ -2240,16 +2242,16 @@ calendar_paint_header (GtkCalendar *calendar, cairo_t *cr)
else
x = 3 + priv->arrow_width + (max_month_width - logical_rect.width)/2;
gtk_render_layout (context, cr, x, y, layout);
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
g_object_unref (layout);
gtk_style_context_restore (context);
cairo_restore (cr);
gtk_snapshot_translate_2d (snapshot, -padding.left, -padding.top);
}
static void
calendar_paint_day_names (GtkCalendar *calendar,
cairo_t *cr)
calendar_snapshot_day_names (GtkCalendar *calendar,
GtkSnapshot *snapshot)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
@@ -2270,11 +2272,9 @@ calendar_paint_day_names (GtkCalendar *calendar,
get_component_paddings (calendar, &padding, NULL, &day_name_padding, NULL);
context = gtk_widget_get_style_context (widget);
cairo_save (cr);
cairo_translate (cr,
padding.left + inner_border,
priv->header_h + padding.top + inner_border);
gtk_snapshot_translate_2d (snapshot,
padding.left + inner_border,
priv->header_h + padding.top + inner_border);
gtk_widget_get_allocation (widget, &allocation);
@@ -2294,17 +2294,17 @@ calendar_paint_day_names (GtkCalendar *calendar,
gtk_style_context_set_state (context, state);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
gtk_render_background (context, cr,
CALENDAR_MARGIN, CALENDAR_MARGIN,
cal_width - CALENDAR_MARGIN * 2,
priv->day_name_h - CALENDAR_MARGIN);
gtk_snapshot_render_background (snapshot, context,
CALENDAR_MARGIN, CALENDAR_MARGIN,
cal_width - CALENDAR_MARGIN * 2,
priv->day_name_h - CALENDAR_MARGIN);
if (priv->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
gtk_render_background (context, cr,
CALENDAR_MARGIN,
priv->day_name_h - calendar_ysep,
priv->week_width - calendar_ysep - CALENDAR_MARGIN,
calendar_ysep);
gtk_snapshot_render_background (snapshot, context,
CALENDAR_MARGIN,
priv->day_name_h - calendar_ysep,
priv->week_width - calendar_ysep - CALENDAR_MARGIN,
calendar_ysep);
/*
* Write the labels
@@ -2323,26 +2323,28 @@ calendar_paint_day_names (GtkCalendar *calendar,
pango_layout_set_text (layout, buffer, -1);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
gtk_render_layout (context, cr,
(CALENDAR_MARGIN +
+ (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
(priv->week_width + (priv->week_width ? calendar_xsep : 0))
: 0)
+ day_wid_sep * i
+ (day_width - logical_rect.width)/2),
CALENDAR_MARGIN + day_name_padding.top + logical_rect.y,
layout);
gtk_snapshot_render_layout (snapshot, context,
(CALENDAR_MARGIN +
+ (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
(priv->week_width + (priv->week_width ? calendar_xsep : 0))
: 0)
+ day_wid_sep * i
+ (day_width - logical_rect.width)/2),
CALENDAR_MARGIN + day_name_padding.top + logical_rect.y,
layout);
}
g_object_unref (layout);
gtk_style_context_restore (context);
cairo_restore (cr);
gtk_snapshot_translate_2d (snapshot,
- (padding.left + inner_border),
- (priv->header_h + padding.top + inner_border));
}
static void
calendar_paint_week_numbers (GtkCalendar *calendar,
cairo_t *cr)
calendar_snapshot_week_numbers (GtkCalendar *calendar,
GtkSnapshot *snapshot)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
@@ -2361,8 +2363,6 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
get_component_paddings (calendar, &padding, NULL, NULL, &week_padding);
context = gtk_widget_get_style_context (widget);
cairo_save (cr);
y = priv->header_h + priv->day_name_h + (padding.top + inner_border);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
x = padding.left + inner_border;
@@ -2378,16 +2378,16 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
if (priv->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
gtk_render_background (context, cr,
x + CALENDAR_MARGIN, y,
priv->week_width - CALENDAR_MARGIN,
priv->main_h - CALENDAR_MARGIN);
gtk_snapshot_render_background (snapshot, context,
x + CALENDAR_MARGIN, y,
priv->week_width - CALENDAR_MARGIN,
priv->main_h - CALENDAR_MARGIN);
else
gtk_render_background (context, cr,
x + CALENDAR_MARGIN,
y + CALENDAR_MARGIN,
priv->week_width - CALENDAR_MARGIN,
priv->main_h - 2 * CALENDAR_MARGIN);
gtk_snapshot_render_background (snapshot, context,
x + CALENDAR_MARGIN,
y + CALENDAR_MARGIN,
priv->week_width - CALENDAR_MARGIN,
priv->main_h - 2 * CALENDAR_MARGIN);
/*
* Write the labels
@@ -2438,13 +2438,12 @@ calendar_paint_week_numbers (GtkCalendar *calendar,
- logical_rect.width
- calendar_xsep - week_padding.right);
gtk_render_layout (context, cr, x_loc, y_loc, layout);
gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
}
g_object_unref (layout);
gtk_style_context_restore (context);
cairo_restore (cr);
}
static void
@@ -2496,10 +2495,10 @@ is_color_attribute (PangoAttribute *attribute,
}
static void
calendar_paint_day (GtkCalendar *calendar,
cairo_t *cr,
gint row,
gint col)
calendar_snapshot_day (GtkCalendar *calendar,
GtkSnapshot *snapshot,
gint row,
gint col)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
@@ -2544,9 +2543,9 @@ calendar_paint_day (GtkCalendar *calendar,
state |= GTK_STATE_FLAG_SELECTED;
gtk_style_context_set_state (context, state);
gtk_render_background (context, cr,
day_rect.x, day_rect.y,
day_rect.width, day_rect.height);
gtk_snapshot_render_background (snapshot, context,
day_rect.x, day_rect.y,
day_rect.width, day_rect.height);
}
}
@@ -2575,11 +2574,11 @@ calendar_paint_day (GtkCalendar *calendar,
x_loc = day_rect.x + (day_rect.width - logical_rect.width) / 2;
y_loc = day_rect.y;
gtk_render_layout (context, cr, x_loc, y_loc, layout);
gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
if (priv->day_month[row][col] == MONTH_CURRENT &&
(priv->marked_date[day-1] || (detail && !show_details)))
gtk_render_layout (context, cr, x_loc - 1, y_loc, layout);
gtk_snapshot_render_layout (snapshot, context, x_loc - 1, y_loc, layout);
y_loc += priv->max_day_char_descent;
@@ -2587,17 +2586,15 @@ calendar_paint_day (GtkCalendar *calendar,
{
GdkRGBA color;
cairo_save (cr);
gtk_style_context_get_color (context, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_set_line_width (cr, 1);
cairo_move_to (cr, day_rect.x + 2, y_loc + 0.5);
cairo_line_to (cr, day_rect.x + day_rect.width - 2, y_loc + 0.5);
cairo_stroke (cr);
cairo_restore (cr);
gtk_snapshot_append_color_node (snapshot,
&color,
&GRAPHENE_RECT_INIT (
day_rect.x + 2, y_loc,
day_rect.width - 2, 1
),
"CalendarDetailSeparator");
y_loc += 2;
}
@@ -2631,15 +2628,14 @@ calendar_paint_day (GtkCalendar *calendar,
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
}
cairo_move_to (cr, day_rect.x, y_loc);
pango_cairo_show_layout (cr, layout);
gtk_snapshot_render_layout (snapshot, context, day_rect.x, y_loc, layout);
}
if (gtk_widget_has_visible_focus (widget) &&
priv->focus_row == row && priv->focus_col == col)
gtk_render_focus (context, cr,
day_rect.x, day_rect.y,
day_rect.width, day_rect.height);
gtk_snapshot_render_focus (snapshot, context,
day_rect.x, day_rect.y,
day_rect.width, day_rect.height);
if (overflow)
priv->detail_overflow[row] |= (1 << col);
@@ -2652,18 +2648,14 @@ calendar_paint_day (GtkCalendar *calendar,
}
static void
calendar_paint_main (GtkCalendar *calendar,
cairo_t *cr)
calendar_snapshot_main (GtkCalendar *calendar,
GtkSnapshot *snapshot)
{
gint row, col;
cairo_save (cr);
for (col = 0; col < 7; col++)
for (row = 0; row < 6; row++)
calendar_paint_day (calendar, cr, row, col);
cairo_restore (cr);
calendar_snapshot_day (calendar, snapshot, row, col);
}
static void
@@ -2688,24 +2680,22 @@ calendar_invalidate_arrow (GtkCalendar *calendar,
}
static void
calendar_paint_arrow (GtkCalendar *calendar,
cairo_t *cr,
guint arrow)
calendar_snapshot_arrow (GtkCalendar *calendar,
GtkSnapshot *snapshot,
guint arrow)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
GtkCssImageBuiltinType image_type;
GtkStyleContext *context;
GtkStateFlags state;
GdkRectangle rect;
gdouble angle;
if (!priv->arrow_win[arrow])
return;
calendar_arrow_rectangle (calendar, arrow, &rect);
cairo_save (cr);
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
@@ -2718,27 +2708,32 @@ calendar_paint_arrow (GtkCalendar *calendar,
gtk_style_context_set_state (context, state);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
gtk_render_background (context, cr,
rect.x, rect.y,
rect.width, rect.height);
gtk_snapshot_render_background (snapshot, context,
rect.x, rect.y,
rect.width, rect.height);
if (arrow == ARROW_MONTH_LEFT || arrow == ARROW_YEAR_LEFT)
angle = 3 * (G_PI / 2);
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_LEFT;
else
angle = G_PI / 2;
image_type = GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT;
gtk_render_arrow (context, cr, angle,
rect.x + (rect.width - 8) / 2,
rect.y + (rect.height - 8) / 2,
8);
gtk_snapshot_translate_2d (snapshot,
rect.x + (rect.width - 8) / 2,
rect.y + (rect.height - 8) / 2);
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
snapshot,
8, 8,
image_type);
gtk_snapshot_translate_2d (snapshot,
- rect.x - (rect.width - 8) / 2,
- rect.y - (rect.height - 8) / 2);
gtk_style_context_restore (context);
cairo_restore (cr);
}
static gboolean
gtk_calendar_draw (GtkWidget *widget,
cairo_t *cr)
static void
gtk_calendar_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
@@ -2750,31 +2745,29 @@ gtk_calendar_draw (GtkWidget *widget,
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
gtk_render_background (context, cr, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_render_frame (context, cr, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_snapshot_render_background (snapshot, context, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_snapshot_render_frame (snapshot, context, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_style_context_restore (context);
calendar_paint_main (calendar, cr);
calendar_snapshot_main (calendar, snapshot);
if (priv->display_flags & GTK_CALENDAR_SHOW_HEADING)
{
calendar_paint_header (calendar, cr);
calendar_snapshot_header (calendar, snapshot);
for (i = 0; i < 4; i++)
calendar_paint_arrow (calendar, cr, i);
calendar_snapshot_arrow (calendar, snapshot, i);
}
if (priv->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
calendar_paint_day_names (calendar, cr);
calendar_snapshot_day_names (calendar, snapshot);
if (priv->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
calendar_paint_week_numbers (calendar, cr);
return FALSE;
calendar_snapshot_week_numbers (calendar, snapshot);
}
+31 -84
View File
@@ -390,10 +390,10 @@ static gint gtk_cell_area_real_event (GtkCellArea
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
static void gtk_cell_area_real_render (GtkCellArea *area,
static void gtk_cell_area_real_snapshot (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
GtkSnapshot *snapshot,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
@@ -487,7 +487,7 @@ typedef struct {
typedef struct {
GtkCellArea *area;
GtkWidget *widget;
cairo_t *cr;
GtkSnapshot *snapshot;
GdkRectangle focus_rect;
GtkCellRendererState render_flags;
guint paint_focus : 1;
@@ -653,7 +653,7 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
class->foreach = gtk_cell_area_real_foreach;
class->foreach_alloc = gtk_cell_area_real_foreach_alloc;
class->event = gtk_cell_area_real_event;
class->render = gtk_cell_area_real_render;
class->snapshot = gtk_cell_area_real_snapshot;
class->apply_attributes = gtk_cell_area_real_apply_attributes;
/* geometry */
@@ -1110,10 +1110,10 @@ gtk_cell_area_real_event (GtkCellArea *area,
}
static gboolean
render_cell (GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
const GdkRectangle *cell_background,
CellRenderData *data)
snapshot_cell (GtkCellRenderer *renderer,
const GdkRectangle *cell_area,
const GdkRectangle *cell_background,
CellRenderData *data)
{
GtkCellRenderer *focus_cell;
GtkCellRendererState flags;
@@ -1145,27 +1145,27 @@ render_cell (GtkCellRenderer *renderer,
}
}
gtk_cell_renderer_render (renderer, data->cr, data->widget,
cell_background, &inner_area, flags);
gtk_cell_renderer_snapshot (renderer, data->snapshot, data->widget,
cell_background, &inner_area, flags);
return FALSE;
}
static void
gtk_cell_area_real_render (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
gboolean paint_focus)
gtk_cell_area_real_snapshot (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
GtkSnapshot *snapshot,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
gboolean paint_focus)
{
CellRenderData render_data =
{
area,
widget,
cr,
snapshot,
{ 0, },
flags,
paint_focus,
@@ -1188,7 +1188,7 @@ gtk_cell_area_real_render (GtkCellArea *area,
render_data.focus_all = TRUE;
gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area,
(GtkCellAllocCallback)render_cell, &render_data);
(GtkCellAllocCallback) snapshot_cell, &render_data);
if (render_data.paint_focus &&
render_data.focus_rect.width != 0 &&
@@ -1203,17 +1203,11 @@ gtk_cell_area_real_render (GtkCellArea *area,
renderer_state = gtk_cell_renderer_get_state (NULL, widget, flags);
gtk_style_context_set_state (style_context, renderer_state);
cairo_save (cr);
gdk_cairo_rectangle (cr, background_area);
cairo_clip (cr);
gtk_render_focus (style_context, cr,
render_data.focus_rect.x, render_data.focus_rect.y,
render_data.focus_rect.width, render_data.focus_rect.height);
gtk_snapshot_render_focus (snapshot, style_context,
render_data.focus_rect.x, render_data.focus_rect.y,
render_data.focus_rect.width, render_data.focus_rect.height);
gtk_style_context_restore (style_context);
cairo_restore (cr);
}
}
@@ -1804,50 +1798,6 @@ gtk_cell_area_event (GtkCellArea *area,
return 0;
}
/**
* gtk_cell_area_render:
* @area: a #GtkCellArea
* @context: the #GtkCellAreaContext for this row of data.
* @widget: the #GtkWidget that @area is rendering to
* @cr: the #cairo_t to render with
* @background_area: the @widget relative coordinates for @areas background
* @cell_area: the @widget relative coordinates for @area
* @flags: the #GtkCellRendererState for @area in this row.
* @paint_focus: whether @area should paint focus on focused cells for focused rows or not.
*
* Renders @areas cells according to @areas layout onto @widget at
* the given coordinates.
*
* Since: 3.0
*/
void
gtk_cell_area_render (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
gboolean paint_focus)
{
GtkCellAreaClass *class;
g_return_if_fail (GTK_IS_CELL_AREA (area));
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (cr != NULL);
g_return_if_fail (background_area != NULL);
g_return_if_fail (cell_area != NULL);
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->render)
class->render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
else
g_warning ("GtkCellAreaClass::render not implemented for '%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
}
/**
* gtk_cell_area_snapshot:
* @area: a #GtkCellArea
@@ -1874,7 +1824,7 @@ gtk_cell_area_snapshot (GtkCellArea *area,
GtkCellRendererState flags,
gboolean paint_focus)
{
cairo_t *cr;
GtkCellAreaClass *class;
g_return_if_fail (GTK_IS_CELL_AREA (area));
g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -1883,16 +1833,13 @@ gtk_cell_area_snapshot (GtkCellArea *area,
g_return_if_fail (background_area != NULL);
g_return_if_fail (cell_area != NULL);
cr = gtk_snapshot_append_cairo_node (snapshot,
&GRAPHENE_RECT_INIT (
background_area->x,
background_area->y,
background_area->width,
background_area->height
),
"CellArea<%s>", G_OBJECT_TYPE_NAME (area));
gtk_cell_area_render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
cairo_destroy (cr);
class = GTK_CELL_AREA_GET_CLASS (area);
if (class->snapshot)
class->snapshot (area, context, widget, snapshot, background_area, cell_area, flags, paint_focus);
else
g_warning ("GtkCellAreaClass::snapshot not implemented for '%s'",
g_type_name (G_TYPE_FROM_INSTANCE (area)));
}
static gboolean
+3 -12
View File
@@ -112,7 +112,7 @@ struct _GtkCellArea
* @event: Handle an event in the area, this is generally used to activate
* a cell at the event location for button events but can also be used
* to generically pass events to #GtkWidgets drawn onto the area.
* @render: Actually render the areas cells to the specified rectangle,
* @snapshot: Actually snapshot the areas cells to the specified rectangle,
* @background_area should be correctly distributed to the cells
* corresponding background areas.
* @apply_attributes: Apply the cell attributes to the cells. This is
@@ -198,10 +198,10 @@ struct _GtkCellAreaClass
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
void (* render) (GtkCellArea *area,
void (* snapshot) (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
GtkSnapshot *snapshot,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
@@ -308,15 +308,6 @@ gint gtk_cell_area_event (GtkCellArea
GdkEvent *event,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
GDK_AVAILABLE_IN_ALL
void gtk_cell_area_render (GtkCellArea *area,
GtkCellAreaContext *context,
GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags,
gboolean paint_focus);
GDK_AVAILABLE_IN_3_90
void gtk_cell_area_snapshot (GtkCellArea *area,
GtkCellAreaContext *context,
+35 -27
View File
@@ -43,7 +43,7 @@
* CellRenderer keep any permanent state around. Instead, any state is set
* just prior to use using #GObjects property system. Then, the
* cell is measured using gtk_cell_renderer_get_size(). Finally, the cell
* is rendered in the correct location using gtk_cell_renderer_render().
* is rendered in the correct location using gtk_cell_renderer_snapshot().
*
* There are a number of rules that must be followed when writing a new
* #GtkCellRenderer. First and foremost, its important that a certain set
@@ -202,7 +202,7 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
object_class->get_property = gtk_cell_renderer_get_property;
object_class->set_property = gtk_cell_renderer_set_property;
class->render = NULL;
class->snapshot = NULL;
class->get_size = NULL;
class->get_request_mode = gtk_cell_renderer_real_get_request_mode;
class->get_preferred_width = gtk_cell_renderer_real_get_preferred_width;
@@ -680,7 +680,7 @@ set_cell_bg_color (GtkCellRenderer *cell,
*
* Obtains the width and height needed to render the cell. Used by view
* widgets to determine the appropriate size for the cell_area passed to
* gtk_cell_renderer_render(). If @cell_area is not %NULL, fills in the
* gtk_cell_renderer_snapshot(). If @cell_area is not %NULL, fills in the
* x and y offsets (if set) of the cell relative to this location.
*
* Please note that the values set in @width and @height, as well as those
@@ -716,9 +716,9 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
}
/**
* gtk_cell_renderer_render:
* gtk_cell_renderer_snapshot:
* @cell: a #GtkCellRenderer
* @cr: a cairo context to draw to
* @snapshot: a #GtkSnapshot to draw to
* @widget: the widget owning @window
* @background_area: entire cell area (including tree expanders and maybe
* padding on the sides)
@@ -732,14 +732,16 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
* blank space around the cell, and also the area containing the tree expander;
* so the @background_area rectangles for all cells tile to cover the entire
* @window.
*
* Since: 3.90
**/
void
gtk_cell_renderer_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
gboolean selected = FALSE;
GtkCellRendererPrivate *priv = cell->priv;
@@ -747,22 +749,28 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
GtkStateFlags state;
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
g_return_if_fail (cr != NULL);
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot != NULL);
g_return_if_fail (snapshot != NULL);
selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED;
cairo_save (cr);
if (priv->cell_background_set && !selected)
{
gdk_cairo_rectangle (cr, background_area);
gdk_cairo_set_source_rgba (cr, &priv->cell_background);
cairo_fill (cr);
gtk_snapshot_append_color_node (snapshot,
&priv->cell_background,
&GRAPHENE_RECT_INIT (
background_area->x, background_area->y,
background_area->width, background_area->height
),
"CellBackground");
}
gdk_cairo_rectangle (cr, background_area);
cairo_clip (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT (
background_area->x, background_area->y,
background_area->width, background_area->height
),
"CellClip");
context = gtk_widget_get_style_context (widget);
@@ -772,14 +780,14 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
state = gtk_cell_renderer_get_state (cell, widget, flags);
gtk_style_context_set_state (context, state);
GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
cr,
widget,
background_area,
cell_area,
flags);
GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot (cell,
snapshot,
widget,
background_area,
cell_area,
flags);
gtk_style_context_restore (context);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
}
/**
+6 -6
View File
@@ -100,7 +100,7 @@ struct _GtkCellRenderer
* @get_preferred_width_for_height: Called to get a renderers natural width for height.
* @get_aligned_area: Called to get the aligned area used by @cell inside @cell_area.
* @get_size: Called to get the width and height needed to render the cell. Deprecated: 3.0.
* @render: Called to render the content of the #GtkCellRenderer.
* @snapshot: Called to snapshot the content of the #GtkCellRenderer.
* @activate: Called to activate the content of the #GtkCellRenderer.
* @start_editing: Called to initiate editing the content of the #GtkCellRenderer.
* @editing_canceled: Signal gets emitted when the user cancels the process of editing a cell.
@@ -145,8 +145,8 @@ struct _GtkCellRendererClass
gint *y_offset,
gint *width,
gint *height);
void (* render) (GtkCellRenderer *cell,
cairo_t *cr,
void (* snapshot) (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -229,9 +229,9 @@ void gtk_cell_renderer_get_size (GtkCellRenderer *cell,
gint *y_offset,
gint *width,
gint *height);
GDK_AVAILABLE_IN_ALL
void gtk_cell_renderer_render (GtkCellRenderer *cell,
cairo_t *cr,
GDK_AVAILABLE_IN_3_90
void gtk_cell_renderer_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
+13 -12
View File
@@ -62,8 +62,8 @@ static void gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cel
gint *y_offset,
gint *width,
gint *height);
static void gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
cairo_t *cr,
static void gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -138,7 +138,7 @@ gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
cell_class->get_size = gtk_cell_renderer_pixbuf_get_size;
cell_class->render = gtk_cell_renderer_pixbuf_render;
cell_class->snapshot = gtk_cell_renderer_pixbuf_snapshot;
g_object_class_install_property (object_class,
PROP_PIXBUF,
@@ -482,12 +482,12 @@ gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
}
static void
gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
@@ -541,9 +541,10 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
if (icon_helper == NULL)
icon_helper = create_icon_helper (cellpixbuf, widget);
_gtk_icon_helper_draw (icon_helper,
cr,
pix_rect.x, pix_rect.y);
gtk_snapshot_translate_2d (snapshot, pix_rect.x, pix_rect.y);
gtk_icon_helper_snapshot (icon_helper, snapshot);
gtk_snapshot_translate_2d (snapshot, - pix_rect.x, - pix_rect.y);
g_object_unref (icon_helper);
gtk_style_context_restore (context);
+44 -35
View File
@@ -30,7 +30,7 @@
#include "gtkintl.h"
#include "gtkorientable.h"
#include "gtkprivate.h"
#include "gtkrender.h"
#include "gtksnapshot.h"
/**
@@ -99,8 +99,8 @@ static void gtk_cell_renderer_progress_get_size (GtkCellRenderer *ce
gint *y_offset,
gint *width,
gint *height);
static void gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
cairo_t *cr,
static void gtk_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -122,7 +122,7 @@ gtk_cell_renderer_progress_class_init (GtkCellRendererProgressClass *klass)
object_class->set_property = gtk_cell_renderer_progress_set_property;
cell_class->get_size = gtk_cell_renderer_progress_get_size;
cell_class->render = gtk_cell_renderer_progress_render;
cell_class->snapshot = gtk_cell_renderer_progress_snapshot;
/**
* GtkCellRendererProgress:value:
@@ -544,12 +544,12 @@ get_bar_position (gint start,
}
static void
gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_progress_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererProgress *cellprogress = GTK_CELL_RENDERER_PROGRESS (cell);
GtkCellRendererProgressPrivate *priv= cellprogress->priv;
@@ -574,8 +574,8 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
gtk_render_background (context, cr, x, y, w, h);
gtk_render_frame (context, cr, x, y, w, h);
gtk_snapshot_render_background (snapshot, context, x, y, w, h);
gtk_snapshot_render_frame (snapshot, context, x, y, w, h);
gtk_style_context_get_padding (context, &padding);
@@ -632,8 +632,8 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
gtk_render_background (context, cr, clip.x, clip.y, clip.width, clip.height);
gtk_render_frame (context, cr, clip.x, clip.y, clip.width, clip.height);
gtk_snapshot_render_background (snapshot, context, clip.x, clip.y, clip.width, clip.height);
gtk_snapshot_render_frame (snapshot, context, clip.x, clip.y, clip.width, clip.height);
gtk_style_context_restore (context);
}
@@ -656,19 +656,22 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
y_pos = y + padding.top + priv->text_yalign *
(h - padding.top - padding.bottom - logical_rect.height);
cairo_save (cr);
gdk_cairo_rectangle (cr, &clip);
cairo_clip (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
clip.x, clip.y,
clip.width, clip.height
),
"CellProgressClip");
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
gtk_render_layout (context, cr,
x_pos, y_pos,
layout);
gtk_snapshot_render_layout (snapshot, context,
x_pos, y_pos,
layout);
gtk_style_context_restore (context);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH);
@@ -686,15 +689,18 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
clip.height = bar_position - y;
}
cairo_save (cr);
gdk_cairo_rectangle (cr, &clip);
cairo_clip (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
clip.x, clip.y,
clip.width, clip.height
),
"CellTroughClip");
gtk_render_layout (context, cr,
x_pos, y_pos,
layout);
gtk_snapshot_render_layout (snapshot, context,
x_pos, y_pos,
layout);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
}
if (bar_position + bar_size < start + full_size)
@@ -710,15 +716,18 @@ gtk_cell_renderer_progress_render (GtkCellRenderer *cell,
clip.height = y + h - (bar_position + bar_size);
}
cairo_save (cr);
gdk_cairo_rectangle (cr, &clip);
cairo_clip (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
clip.x, clip.y,
clip.width, clip.height
),
"CellTroughClip");
gtk_render_layout (context, cr,
x_pos, y_pos,
layout);
gtk_snapshot_render_layout (snapshot, context,
x_pos, y_pos,
layout);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
}
gtk_style_context_restore (context);
+18 -19
View File
@@ -31,15 +31,11 @@
#include "gtkicontheme.h"
#include "gtkintl.h"
#include "gtksettings.h"
#include "gtksnapshot.h"
#include "gtktypebuiltins.h"
#include <math.h>
#undef GDK_DEPRECATED
#undef GDK_DEPRECATED_FOR
#define GDK_DEPRECATED
#define GDK_DEPRECATED_FOR(f)
/**
* SECTION:gtkcellrendererspinner
* @Short_description: Renders a spinning animation in a cell
@@ -90,8 +86,8 @@ static void gtk_cell_renderer_spinner_get_size (GtkCellRenderer *cell,
gint *y_offset,
gint *width,
gint *height);
static void gtk_cell_renderer_spinner_render (GtkCellRenderer *cell,
cairo_t *cr,
static void gtk_cell_renderer_spinner_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -109,7 +105,7 @@ gtk_cell_renderer_spinner_class_init (GtkCellRendererSpinnerClass *klass)
object_class->set_property = gtk_cell_renderer_spinner_set_property;
cell_class->get_size = gtk_cell_renderer_spinner_get_size;
cell_class->render = gtk_cell_renderer_spinner_render;
cell_class->snapshot = gtk_cell_renderer_spinner_snapshot;
/* GtkCellRendererSpinner:active:
*
@@ -388,18 +384,19 @@ gtk_paint_spinner (GtkStyleContext *context,
}
static void
gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_spinner_snapshot (GtkCellRenderer *cellr,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererSpinner *cell = GTK_CELL_RENDERER_SPINNER (cellr);
GtkCellRendererSpinnerPrivate *priv = cell->priv;
GdkRectangle pix_rect;
GdkRectangle draw_rect;
gint xpad, ypad;
cairo_t *cr;
if (!priv->active)
return;
@@ -420,10 +417,12 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
return;
cairo_save (cr);
gdk_cairo_rectangle (cr, cell_area);
cairo_clip (cr);
cr = gtk_snapshot_append_cairo_node (snapshot,
&GRAPHENE_RECT_INIT (
cell_area->x, cell_area->y,
cell_area->width, cell_area->height
),
"CellSpinner");
gtk_paint_spinner (gtk_widget_get_style_context (widget),
cr,
@@ -431,5 +430,5 @@ gtk_cell_renderer_spinner_render (GtkCellRenderer *cellr,
draw_rect.x, draw_rect.y,
draw_rect.width, draw_rect.height);
cairo_restore (cr);
cairo_destroy (cr);
}
+27 -21
View File
@@ -55,8 +55,8 @@ static void gtk_cell_renderer_text_set_property (GObject *obje
guint param_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_cell_renderer_text_render (GtkCellRenderer *cell,
cairo_t *cr,
static void gtk_cell_renderer_text_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -241,7 +241,7 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
object_class->get_property = gtk_cell_renderer_text_get_property;
object_class->set_property = gtk_cell_renderer_text_set_property;
cell_class->render = gtk_cell_renderer_text_render;
cell_class->snapshot = gtk_cell_renderer_text_snapshot;
cell_class->start_editing = gtk_cell_renderer_text_start_editing;
cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
@@ -1712,12 +1712,12 @@ get_size (GtkCellRenderer *cell,
}
static void
gtk_cell_renderer_text_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_text_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
@@ -1735,9 +1735,13 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
if (priv->background_set && (flags & GTK_CELL_RENDERER_SELECTED) == 0)
{
gdk_cairo_rectangle (cr, background_area);
gdk_cairo_set_source_rgba (cr, &priv->background);
cairo_fill (cr);
gtk_snapshot_append_color_node (snapshot,
&priv->background,
&GRAPHENE_RECT_INIT(
background_area->x, background_area->y,
background_area->width, background_area->height
),
"CellTextBackground");
}
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
@@ -1751,17 +1755,19 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
pango_layout_get_pixel_extents (layout, NULL, &rect);
x_offset = x_offset - rect.x;
cairo_save (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
cell_area->x, cell_area->y,
cell_area->width, cell_area->height
),
"CellTextClip");
gdk_cairo_rectangle (cr, cell_area);
cairo_clip (cr);
gtk_snapshot_render_layout (snapshot, context,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
layout);
gtk_render_layout (context, cr,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
layout);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
g_object_unref (layout);
}
+46 -32
View File
@@ -21,6 +21,7 @@
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
#include "gtkrendericonprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtktreeprivate.h"
#include "a11y/gtkbooleancellaccessible.h"
@@ -53,8 +54,8 @@ static void gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cel
gint *y_offset,
gint *width,
gint *height);
static void gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
cairo_t *cr,
static void gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
@@ -125,7 +126,7 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
object_class->set_property = gtk_cell_renderer_toggle_set_property;
cell_class->get_size = gtk_cell_renderer_toggle_get_size;
cell_class->render = gtk_cell_renderer_toggle_render;
cell_class->snapshot = gtk_cell_renderer_toggle_snapshot;
cell_class->activate = gtk_cell_renderer_toggle_activate;
g_object_class_install_property (object_class,
@@ -373,12 +374,12 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
}
static void
gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (cell);
GtkCellRendererTogglePrivate *priv = celltoggle->priv;
@@ -388,6 +389,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
gint xpad, ypad;
GtkStateFlags state;
GtkBorder padding, border;
GtkCssImageBuiltinType image_type;
context = gtk_widget_get_style_context (widget);
gtk_cell_renderer_toggle_get_size (cell, widget, cell_area,
@@ -413,45 +415,57 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
if (priv->active)
state |= GTK_STATE_FLAG_CHECKED;
cairo_save (cr);
gdk_cairo_rectangle (cr, cell_area);
cairo_clip (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT (
cell_area->x, cell_area->y,
cell_area->width, cell_area->height
),
"CellToggleClip");
context = gtk_cell_renderer_toggle_save_context (cell, widget);
gtk_style_context_set_state (context, state);
gtk_render_background (context, cr,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
width, height);
gtk_render_frame (context, cr,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
width, height);
gtk_snapshot_render_background (snapshot, context,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
width, height);
gtk_snapshot_render_frame (snapshot, context,
cell_area->x + x_offset + xpad,
cell_area->y + y_offset + ypad,
width, height);
gtk_style_context_get_padding (context, &padding);
gtk_style_context_get_border (context, &border);
if (priv->radio)
{
gtk_render_option (context, cr,
cell_area->x + x_offset + xpad + padding.left + border.left,
cell_area->y + y_offset + ypad + padding.top + border.top,
width - padding.left - padding.right - border.left - border.right,
height - padding.top - padding.bottom - border.top - border.bottom);
if (state & GTK_STATE_FLAG_INCONSISTENT)
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT;
else if (state & GTK_STATE_FLAG_CHECKED)
image_type = GTK_CSS_IMAGE_BUILTIN_OPTION;
else
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
}
else
{
gtk_render_check (context, cr,
cell_area->x + x_offset + xpad + padding.left + border.left,
cell_area->y + y_offset + ypad + padding.top + border.top,
width - padding.left - padding.right - border.left - border.right,
height - padding.top - padding.bottom - border.top - border.bottom);
if (state & GTK_STATE_FLAG_INCONSISTENT)
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT;
else if (state & GTK_STATE_FLAG_CHECKED)
image_type = GTK_CSS_IMAGE_BUILTIN_CHECK;
else
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
}
gtk_snapshot_translate_2d (snapshot,
cell_area->x + x_offset + xpad + padding.left + border.left,
cell_area->y + y_offset + ypad + padding.top + border.top);
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot,
width - padding.left - padding.right - border.left - border.right,
height - padding.top - padding.bottom - border.top - border.bottom,
image_type);
gtk_style_context_restore (context);
cairo_restore (cr);
gtk_snapshot_pop_and_append (snapshot);
}
static gint
+17 -1
View File
@@ -134,7 +134,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
double height)
{
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
GskColorStop stops[linear->stops->len];
GskColorStop *stops;
GskRenderNode *node;
double off_x, off_y; /* snapshot offset */
double angle; /* actual angle of the gradiant line in degrees */
@@ -181,8 +181,23 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
length = sqrt (x * x + y * y);
gtk_css_image_linear_get_start_end (linear, length, &start, &end);
if (start == end)
{
/* repeating gradients with all color stops sharing the same offset
* get the color of the last color stop */
GtkCssImageLinearColorStop *stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, linear->stops->len - 1);
gtk_snapshot_append_color_node (snapshot,
_gtk_css_rgba_value_get_rgba (stop->color),
&GRAPHENE_RECT_INIT (0, 0, width, height),
"RepeatingLinearGradient<degenerate>");
return;
}
offset = start;
last = -1;
stops = g_newa (GskColorStop, linear->stops->len);
for (i = 0; i < linear->stops->len; i++)
{
GtkCssImageLinearColorStop *stop;
@@ -238,6 +253,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
stops,
linear->stops->len);
}
name = g_strdup_printf ("%sLinearGradient<%ustops>", linear->repeating ? "Repeating" : "", linear->stops->len);
gsk_render_node_set_name (node, name);
g_free (name);
-1
View File
@@ -631,7 +631,6 @@ gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
shadow->color = *_gtk_css_rgba_value_get_rgba (value->color);
shadow->dx = _gtk_css_number_value_get (value->hoffset, 0);
shadow->dy = _gtk_css_number_value_get (value->voffset, 0);
shadow->spread = _gtk_css_number_value_get (value->spread, 0);
shadow->radius = _gtk_css_number_value_get (value->radius, 0);
}
+2 -2
View File
@@ -873,13 +873,13 @@ gtk_icon_helper_snapshot (GtkIconHelper *self,
GtkCssStyle *style;
GskTexture *texture;
style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
gtk_icon_helper_ensure_texture (self);
texture = self->priv->texture;
if (texture == NULL)
return;
style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
gtk_css_style_snapshot_icon_texture (style,
snapshot,
texture,
+21 -313
View File
@@ -396,62 +396,6 @@ gtk_disable_setlocale (void)
#endif
static GString *gtk_modules_string = NULL;
static gboolean g_fatal_warnings = FALSE;
#ifdef G_ENABLE_DEBUG
static gboolean
gtk_arg_debug_cb (const char *key, const char *value, gpointer user_data)
{
debug_flags[0].flags |= g_parse_debug_string (value,
gtk_debug_keys,
G_N_ELEMENTS (gtk_debug_keys));
return TRUE;
}
static gboolean
gtk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data)
{
debug_flags[0].flags &= ~g_parse_debug_string (value,
gtk_debug_keys,
G_N_ELEMENTS (gtk_debug_keys));
return TRUE;
}
#endif /* G_ENABLE_DEBUG */
static gboolean
gtk_arg_module_cb (const char *key, const char *value, gpointer user_data)
{
if (value && *value)
{
if (gtk_modules_string)
g_string_append_c (gtk_modules_string, G_SEARCHPATH_SEPARATOR);
else
gtk_modules_string = g_string_new (NULL);
g_string_append (gtk_modules_string, value);
}
return TRUE;
}
static const GOptionEntry gtk_args[] = {
{ "gtk-module", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_module_cb,
/* Description of --gtk-module=MODULES in --help output */ N_("Load additional GTK+ modules"),
/* Placeholder in --gtk-module=MODULES in --help output */ N_("MODULES") },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings,
/* Description of --g-fatal-warnings in --help output */ N_("Make all warnings fatal"), NULL },
#ifdef G_ENABLE_DEBUG
{ "gtk-debug", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_debug_cb,
/* Description of --gtk-debug=FLAGS in --help output */ N_("GTK+ debugging flags to set"),
/* Placeholder in --gtk-debug=FLAGS in --help output */ N_("FLAGS") },
{ "gtk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_no_debug_cb,
/* Description of --gtk-no-debug=FLAGS in --help output */ N_("GTK+ debugging flags to unset"),
/* Placeholder in --gtk-no-debug=FLAGS in --help output */ N_("FLAGS") },
#endif
{ NULL }
};
#ifdef G_OS_WIN32
@@ -617,12 +561,11 @@ setlocale_initialization (void)
}
static void
do_pre_parse_initialization (int *argc,
char ***argv)
do_pre_parse_initialization (void)
{
const gchar *env_string;
double slowdown;
if (pre_initialized)
return;
@@ -680,7 +623,7 @@ gettext_initialization (void)
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
bind_textdomain_codeset (GETTEXT_PACKAGE "-properties", "UTF-8");
# endif
#endif
#endif
}
static void
@@ -691,8 +634,7 @@ default_display_notify_cb (GdkDisplayManager *dm)
}
static void
do_post_parse_initialization (int *argc,
char ***argv)
do_post_parse_initialization (void)
{
GdkDisplayManager *display_manager;
@@ -705,15 +647,6 @@ do_post_parse_initialization (int *argc,
signal (SIGPIPE, SIG_IGN);
#endif
if (g_fatal_warnings)
{
GLogLevelFlags fatal_mask;
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
}
if (debug_flags[0].flags & GTK_DEBUG_UPDATES)
gtk_debug_updates_set_enabled (TRUE);
@@ -727,12 +660,12 @@ do_post_parse_initialization (int *argc,
if (gtk_modules_string)
{
_gtk_modules_init (argc, argv, gtk_modules_string->str);
_gtk_modules_init (NULL, NULL, gtk_modules_string->str);
g_string_free (gtk_modules_string, TRUE);
}
else
{
_gtk_modules_init (argc, argv, NULL);
_gtk_modules_init (NULL, NULL, NULL);
}
display_manager = gdk_display_manager_get ();
@@ -744,52 +677,6 @@ do_post_parse_initialization (int *argc,
NULL);
}
typedef struct
{
gboolean open_default_display;
} OptionGroupInfo;
static gboolean
pre_parse_hook (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
{
do_pre_parse_initialization (NULL, NULL);
return TRUE;
}
static gboolean
post_parse_hook (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
{
OptionGroupInfo *info = data;
do_post_parse_initialization (NULL, NULL);
if (info->open_default_display)
{
if (gdk_display_open_default () == NULL)
{
const char *display_name = gdk_get_display_arg_name ();
g_set_error (error,
G_OPTION_ERROR,
G_OPTION_ERROR_FAILED,
_("Cannot open display: %s"),
display_name ? display_name : "" );
return FALSE;
}
}
return TRUE;
}
guint
gtk_get_display_debug_flags (GdkDisplay *display)
{
@@ -861,179 +748,12 @@ gtk_simulate_touchscreen (void)
return test_touchscreen > 0 || (gtk_get_debug_flags () & GTK_DEBUG_TOUCHSCREEN) != 0;
}
/**
* gtk_get_option_group:
* @open_default_display: whether to open the default display
* when parsing the commandline arguments
*
* Returns a #GOptionGroup for the commandline arguments recognized
* by GTK+ and GDK.
*
* You should add this group to your #GOptionContext
* with g_option_context_add_group(), if you are using
* g_option_context_parse() to parse your commandline arguments.
*
* Returns: (transfer full): a #GOptionGroup for the commandline
* arguments recognized by GTK+
*
* Since: 2.6
*/
GOptionGroup *
gtk_get_option_group (gboolean open_default_display)
{
GOptionGroup *group;
OptionGroupInfo *info;
gettext_initialization ();
info = g_new0 (OptionGroupInfo, 1);
info->open_default_display = open_default_display;
group = g_option_group_new ("gtk", _("GTK+ Options"), _("Show GTK+ Options"), info, g_free);
g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook);
gdk_add_option_entries (group);
g_option_group_add_entries (group, gtk_args);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
return group;
}
/**
* gtk_init_with_args:
* @argc: (inout): Address of the `argc` parameter of
* your main() function (or 0 if @argv is %NULL). This will be changed if
* any arguments were handled.
* @argv: (array length=argc) (inout) (allow-none): Address of the
* `argv` parameter of main(), or %NULL. Any options
* understood by GTK+ are stripped before return.
* @parameter_string: (allow-none): a string which is displayed in
* the first line of `--help` output, after
* `programname [OPTION...]`
* @entries: (array zero-terminated=1): a %NULL-terminated array
* of #GOptionEntrys describing the options of your program
* @translation_domain: (nullable): a translation domain to use for translating
* the `--help` output for the options in @entries
* and the @parameter_string with gettext(), or %NULL
* @error: a return location for errors
*
* This function does the same work as gtk_init_check().
* Additionally, it allows you to add your own commandline options,
* and it automatically generates nicely formatted
* `--help` output. Note that your program will
* be terminated after writing out the help output.
*
* Returns: %TRUE if the windowing system has been successfully
* initialized, %FALSE otherwise
*
* Since: 2.6
*/
gboolean
gtk_init_with_args (gint *argc,
gchar ***argv,
const gchar *parameter_string,
const GOptionEntry *entries,
const gchar *translation_domain,
GError **error)
{
GOptionContext *context;
GOptionGroup *gtk_group;
gboolean retval;
if (gtk_initialized)
goto done;
gettext_initialization ();
if (!check_setugid ())
return FALSE;
gtk_group = gtk_get_option_group (FALSE);
context = g_option_context_new (parameter_string);
g_option_context_add_group (context, gtk_group);
g_option_context_set_translation_domain (context, translation_domain);
if (entries)
g_option_context_add_main_entries (context, entries, translation_domain);
retval = g_option_context_parse (context, argc, argv, error);
g_option_context_free (context);
if (!retval)
return FALSE;
done:
return gdk_display_open_default () != NULL;
}
/**
* gtk_parse_args:
* @argc: (inout): a pointer to the number of command line arguments
* @argv: (array length=argc) (inout): a pointer to the array of
* command line arguments
*
* Parses command line arguments, and initializes global
* attributes of GTK+, but does not actually open a connection
* to a display. (See gdk_display_open(), gdk_get_display_arg_name())
*
* Any arguments used by GTK+ or GDK are removed from the array and
* @argc and @argv are updated accordingly.
*
* There is no need to call this function explicitly if you are using
* gtk_init(), or gtk_init_check().
*
* Note that many aspects of GTK+ require a display connection to
* function, so this way of initializing GTK+ is really only useful
* for specialized use cases.
*
* Returns: %TRUE if initialization succeeded, otherwise %FALSE
*/
gboolean
gtk_parse_args (int *argc,
char ***argv)
{
GOptionContext *option_context;
GOptionGroup *gtk_group;
GError *error = NULL;
if (gtk_initialized)
return TRUE;
gettext_initialization ();
if (!check_setugid ())
return FALSE;
option_context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (option_context, TRUE);
g_option_context_set_help_enabled (option_context, FALSE);
gtk_group = gtk_get_option_group (FALSE);
g_option_context_set_main_group (option_context, gtk_group);
if (!g_option_context_parse (option_context, argc, argv, &error))
{
g_warning ("%s", error->message);
g_error_free (error);
}
g_option_context_free (option_context);
return TRUE;
}
#ifdef G_PLATFORM_WIN32
#undef gtk_init_check
#endif
/**
* gtk_init_check:
* @argc: (inout): Address of the `argc` parameter of
* your main() function (or 0 if @argv is %NULL). This will be changed if
* any arguments were handled.
* @argv: (array length=argc) (inout) (allow-none): Address of the
* `argv` parameter of main(), or %NULL. Any options
* understood by GTK+ are stripped before return.
*
* This function does the same work as gtk_init() with only a single
* change: It does not terminate the program if the windowing system
@@ -1047,14 +767,21 @@ gtk_parse_args (int *argc,
* initialized, %FALSE otherwise
*/
gboolean
gtk_init_check (int *argc,
char ***argv)
gtk_init_check (void)
{
gboolean ret;
if (!gtk_parse_args (argc, argv))
if (gtk_initialized)
return TRUE;
gettext_initialization ();
if (!check_setugid ())
return FALSE;
do_pre_parse_initialization ();
do_post_parse_initialization ();
ret = gdk_display_open_default () != NULL;
if (gtk_get_debug_flags () & GTK_DEBUG_INTERACTIVE)
@@ -1069,32 +796,13 @@ gtk_init_check (int *argc,
/**
* gtk_init:
* @argc: (inout): Address of the `argc` parameter of
* your main() function (or 0 if @argv is %NULL). This will be changed if
* any arguments were handled.
* @argv: (array length=argc) (inout) (allow-none): Address of the
* `argv` parameter of main(), or %NULL. Any options
* understood by GTK+ are stripped before return.
*
* Call this function before using any other GTK+ functions in your GUI
* applications. It will initialize everything needed to operate the
* toolkit and parses some standard command line options.
*
* Although you are expected to pass the @argc, @argv parameters from main() to
* this function, it is possible to pass %NULL if @argv is not available or
* commandline handling is not required.
*
* @argc and @argv are adjusted accordingly so your own code will
* never see those standard arguments.
*
* Note that there are some alternative ways to initialize GTK+:
* if you are calling gtk_parse_args(), gtk_init_check(),
* gtk_init_with_args() or g_option_context_parse() with
* the option group returned by gtk_get_option_group(),
* you dont have to call gtk_init().
*
* And if you are using #GtkApplication, you don't have to call any of the
* initialization functions either; the #GtkApplication::startup handler
* If you are using #GtkApplication, you don't have to call gtk_init()
* or gtk_init_check(); the #GtkApplication::startup handler
* does it for you.
*
* This function will terminate your program if it was unable to
@@ -1110,13 +818,13 @@ gtk_init_check (int *argc,
* similar things.
*/
void
gtk_init (int *argc, char ***argv)
gtk_init (void)
{
if (!gtk_init_check (argc, argv))
if (!gtk_init_check ())
{
const char *display_name_arg = gdk_get_display_arg_name ();
if (display_name_arg == NULL)
display_name_arg = getenv("DISPLAY");
display_name_arg = getenv ("DISPLAY");
g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : "");
exit (1);
}
+2 -19
View File
@@ -73,27 +73,10 @@ const gchar* gtk_check_version (guint required_major,
*/
GDK_AVAILABLE_IN_ALL
gboolean gtk_parse_args (int *argc,
char ***argv);
void gtk_init (void);
GDK_AVAILABLE_IN_ALL
void gtk_init (int *argc,
char ***argv);
GDK_AVAILABLE_IN_ALL
gboolean gtk_init_check (int *argc,
char ***argv);
GDK_AVAILABLE_IN_ALL
gboolean gtk_init_with_args (gint *argc,
gchar ***argv,
const gchar *parameter_string,
const GOptionEntry *entries,
const gchar *translation_domain,
GError **error);
GDK_AVAILABLE_IN_ALL
GOptionGroup *gtk_get_option_group (gboolean open_default_display);
gboolean gtk_init_check (void);
#ifdef G_OS_WIN32
+1 -1
View File
@@ -96,7 +96,7 @@ gtk_test_init (int *argcp,
*/
gdk_disable_multidevice ();
gtk_init (argcp, argvp);
gtk_init ();
}
static GSList*
+2 -2
View File
@@ -126,8 +126,8 @@ gboolean _gtk_tree_view_column_is_blank_at_pos (GtkTreeViewColumn *co
gint x,
gint y);
void _gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
cairo_t *cr,
void gtk_tree_view_column_cell_snapshot (GtkTreeViewColumn *tree_column,
GtkSnapshot *snapshot,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
guint flags,
+254 -191
View File
@@ -50,9 +50,11 @@
#include "gtkstylecontextprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcssrgbavalueprivate.h"
#include "gtkrendericonprivate.h"
#include "gtktypebuiltins.h"
#include "gtkmain.h"
#include "gtksettingsprivate.h"
#include "gtksnapshotprivate.h"
#include "gtkwidgetpath.h"
#include "a11y/gtktreeviewaccessibleprivate.h"
@@ -596,8 +598,8 @@ static void gtk_tree_view_measure (GtkWidget *widget,
int *natural_baseline);
static void gtk_tree_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_tree_view_draw (GtkWidget *widget,
cairo_t *cr);
static void gtk_tree_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static gboolean gtk_tree_view_key_press (GtkWidget *widget,
GdkEventKey *event);
static gboolean gtk_tree_view_key_release (GtkWidget *widget,
@@ -733,8 +735,8 @@ static void gtk_tree_view_queue_draw_path (GtkTreeView
static void gtk_tree_view_queue_draw_arrow (GtkTreeView *tree_view,
GtkRBTree *tree,
GtkRBNode *node);
static void gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
cairo_t *cr,
static void gtk_tree_view_snapshot_arrow (GtkTreeView *tree_view,
GtkSnapshot *snapshot,
GtkRBTree *tree,
GtkRBNode *node);
static void gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view,
@@ -978,7 +980,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
widget_class->measure = gtk_tree_view_measure;
widget_class->size_allocate = gtk_tree_view_size_allocate;
widget_class->motion_notify_event = gtk_tree_view_motion;
widget_class->draw = gtk_tree_view_draw;
widget_class->snapshot = gtk_tree_view_snapshot;
widget_class->key_press_event = gtk_tree_view_key_press;
widget_class->key_release_event = gtk_tree_view_key_release;
widget_class->enter_notify_event = gtk_tree_view_enter_notify;
@@ -4485,8 +4487,8 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
}
static void
gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
cairo_t *cr)
gtk_tree_view_snapshot_rubber_band (GtkTreeView *tree_view,
GtkSnapshot *snapshot)
{
gdouble start_x, start_y, offset_x, offset_y;
GdkRectangle rect;
@@ -4505,8 +4507,6 @@ gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
bin_x = MAX (0, bin_x + offset_x);
bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy);
cairo_save (cr);
context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
gtk_style_context_save_to_node (context, tree_view->priv->rubber_band_cssnode);
@@ -4516,18 +4516,14 @@ gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
rect.width = ABS (tree_view->priv->press_start_x - bin_x) + 1;
rect.height = ABS (tree_view->priv->press_start_y - bin_y) + 1;
gdk_cairo_rectangle (cr, &rect);
cairo_clip (cr);
gtk_render_background (context, cr,
rect.x, rect.y,
rect.width, rect.height);
gtk_render_frame (context, cr,
rect.x, rect.y,
rect.width, rect.height);
gtk_snapshot_render_background (snapshot, context,
rect.x, rect.y,
rect.width, rect.height);
gtk_snapshot_render_frame (snapshot, context,
rect.x, rect.y,
rect.width, rect.height);
gtk_style_context_restore (context);
cairo_restore (cr);
}
static void
@@ -4647,22 +4643,21 @@ invalidate_empty_focus (GtkTreeView *tree_view)
* used when the tree is empty.
*/
static void
draw_empty (GtkTreeView *tree_view,
cairo_t *cr)
snapshot_empty (GtkTreeView *tree_view,
GtkSnapshot *snapshot)
{
GtkWidget *widget = GTK_WIDGET (tree_view);
GtkStyleContext *context;
gint width, height;
context = gtk_widget_get_style_context (widget);
width = gdk_window_get_width (tree_view->priv->bin_window);
height = gdk_window_get_height (tree_view->priv->bin_window);
gtk_render_background (context, cr, 0, 0, width, height);
if (gtk_widget_has_visible_focus (widget))
gtk_render_focus (context, cr, 0, 0, width, height);
{
gtk_snapshot_render_focus (snapshot, context,
0, 0,
gdk_window_get_width (tree_view->priv->bin_window),
gdk_window_get_height (tree_view->priv->bin_window));
}
}
typedef enum {
@@ -4672,17 +4667,25 @@ typedef enum {
} GtkTreeViewLineType;
static void
gtk_tree_view_draw_line (GtkTreeView *tree_view,
cairo_t *cr,
GtkTreeViewLineType type,
int x1,
int y1,
int x2,
int y2)
gtk_tree_view_snapshot_line (GtkTreeView *tree_view,
GtkSnapshot *snapshot,
GtkTreeViewLineType type,
int x1,
int y1,
int x2,
int y2)
{
GtkStyleContext *context;
cairo_t *cr;
cairo_save (cr);
cr = gtk_snapshot_append_cairo_node (snapshot,
&GRAPHENE_RECT_INIT (
MIN (x1, x2),
MIN (y1, y2),
ABS (x2 - x1) + 1,
ABS (y2 - y1) + 1
),
"TreeViewGridLine");
context = gtk_widget_get_style_context (GTK_WIDGET (tree_view));
@@ -4733,12 +4736,12 @@ gtk_tree_view_draw_line (GtkTreeView *tree_view,
cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
cairo_stroke (cr);
cairo_restore (cr);
cairo_destroy (cr);
}
static void
gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
cairo_t *cr)
gtk_tree_view_snapshot_grid_lines (GtkTreeView *tree_view,
GtkSnapshot *snapshot)
{
GList *list, *first, *last;
gboolean rtl;
@@ -4768,10 +4771,10 @@ gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
current_x += gtk_tree_view_column_get_width (column);
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_GRID_LINE,
current_x - 1, 0,
current_x - 1, gtk_tree_view_get_height (tree_view));
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_GRID_LINE,
current_x - 1, 0,
current_x - 1, gtk_tree_view_get_height (tree_view));
}
}
@@ -4781,9 +4784,9 @@ gtk_tree_view_draw_grid_lines (GtkTreeView *tree_view,
* KEEP IN SYNC WITH gtk_tree_view_create_row_drag_icon()!
* FIXME: Its not...
*/
static gboolean
gtk_tree_view_bin_draw (GtkWidget *widget,
cairo_t *cr)
static void
gtk_tree_view_bin_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
GtkTreePath *path;
@@ -4818,18 +4821,13 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
if (tree_view->priv->tree == NULL)
{
draw_empty (tree_view, cr);
return TRUE;
snapshot_empty (tree_view, snapshot);
return;
}
bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
cairo_clip (cr);
if (!gdk_cairo_get_clip_rectangle (cr, &clip))
return TRUE;
clip = (GdkRectangle) { 0, 0, bin_window_width, bin_window_height };
new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, clip.y);
y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
@@ -4838,16 +4836,16 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_CELL);
gtk_render_background (context, cr,
0, gtk_tree_view_get_height (tree_view),
bin_window_width,
bin_window_height - gtk_tree_view_get_height (tree_view));
gtk_snapshot_render_background (snapshot, context,
0, gtk_tree_view_get_height (tree_view),
bin_window_width,
bin_window_height - gtk_tree_view_get_height (tree_view));
gtk_style_context_restore (context);
}
if (node == NULL)
return TRUE;
return;
/* find the path for the node */
path = _gtk_tree_path_new_from_rbtree (tree, node);
@@ -5046,18 +5044,18 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
draw_focus = FALSE;
/* Draw background */
gtk_render_background (context, cr,
background_area.x,
background_area.y,
background_area.width,
background_area.height);
gtk_snapshot_render_background (snapshot, context,
background_area.x,
background_area.y,
background_area.width,
background_area.height);
/* Draw frame */
gtk_render_frame (context, cr,
background_area.x,
background_area.y,
background_area.width,
background_area.height);
gtk_snapshot_render_frame (snapshot, context,
background_area.x,
background_area.y,
background_area.width,
background_area.height);
if (gtk_tree_view_is_expander_column (tree_view, column))
{
@@ -5074,75 +5072,89 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
if (is_separator)
{
GdkRGBA color;
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
gtk_render_line (context, cr,
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
cell_area.y + cell_area.height / 2);
gtk_style_context_get_color (context, &color);
gtk_snapshot_append_color_node (snapshot,
&color,
&GRAPHENE_RECT_INIT(
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
1
),
"Separator");
gtk_style_context_restore (context);
}
else
{
_gtk_tree_view_column_cell_render (column,
cr,
&background_area,
&cell_area,
flags,
draw_focus);
gtk_tree_view_column_cell_snapshot (column,
snapshot,
&background_area,
&cell_area,
flags,
draw_focus);
}
if (gtk_tree_view_draw_expanders (tree_view)
&& (node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
{
gtk_tree_view_draw_arrow (GTK_TREE_VIEW (widget),
cr,
tree,
node);
gtk_tree_view_snapshot_arrow (GTK_TREE_VIEW (widget),
snapshot,
tree,
node);
}
}
else
{
if (is_separator)
{
GdkRGBA color;
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
gtk_render_line (context, cr,
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
cell_area.y + cell_area.height / 2);
gtk_style_context_get_color (context, &color);
gtk_snapshot_append_color_node (snapshot,
&color,
&GRAPHENE_RECT_INIT(
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
1
),
"Separator");
gtk_style_context_restore (context);
}
else
_gtk_tree_view_column_cell_render (column,
cr,
&background_area,
&cell_area,
flags,
draw_focus);
gtk_tree_view_column_cell_snapshot (column,
snapshot,
&background_area,
&cell_area,
flags,
draw_focus);
}
if (draw_hgrid_lines)
{
if (background_area.y >= clip.y)
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_GRID_LINE,
background_area.x, background_area.y,
background_area.x + background_area.width,
background_area.y);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_GRID_LINE,
background_area.x, background_area.y,
background_area.x + background_area.width,
background_area.y);
if (background_area.y + max_height < clip.y + clip.height)
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_GRID_LINE,
background_area.x, background_area.y + max_height,
background_area.x + background_area.width,
background_area.y + max_height);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_GRID_LINE,
background_area.x, background_area.y + max_height,
background_area.x + background_area.width,
background_area.y + max_height);
}
if (gtk_tree_view_is_expander_column (tree_view, column) &&
@@ -5160,21 +5172,21 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT
&& depth > 1)
{
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y1,
x + expander_size * (depth - 1.1) * mult,
y1);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y1,
x + expander_size * (depth - 1.1) * mult,
y1);
}
else if (depth > 1)
{
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y1,
x + expander_size * (depth - 0.5) * mult,
y1);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y1,
x + expander_size * (depth - 0.5) * mult,
y1);
}
if (depth > 1)
@@ -5184,19 +5196,19 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
GtkRBTree *tmp_tree;
if (!_gtk_rbtree_next (tree, node))
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y0,
x + expander_size * (depth - 1.5) * mult,
y1);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y0,
x + expander_size * (depth - 1.5) * mult,
y1);
else
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y0,
x + expander_size * (depth - 1.5) * mult,
y2);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (depth - 1.5) * mult,
y0,
x + expander_size * (depth - 1.5) * mult,
y2);
tmp_node = tree->parent_node;
tmp_tree = tree->parent_tree;
@@ -5204,12 +5216,12 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
for (i = depth - 2; i > 0; i--)
{
if (_gtk_rbtree_next (tmp_tree, tmp_node))
gtk_tree_view_draw_line (tree_view, cr,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (i - 0.5) * mult,
y0,
x + expander_size * (i - 0.5) * mult,
y2);
gtk_tree_view_snapshot_line (tree_view, snapshot,
GTK_TREE_VIEW_TREE_LINE,
x + expander_size * (i - 0.5) * mult,
y0,
x + expander_size * (i - 0.5) * mult,
y2);
tmp_node = tmp_tree->parent_node;
tmp_tree = tmp_tree->parent_tree;
@@ -5249,10 +5261,10 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
_gtk_tree_view_find_node (tree_view, drag_dest_path, &drag_tree, &drag_node);
if (drag_tree != NULL)
gtk_render_frame (context, cr,
0, gtk_tree_view_get_row_y_offset (tree_view, drag_tree, drag_node),
gdk_window_get_width (tree_view->priv->bin_window),
gtk_tree_view_get_row_height (tree_view, drag_node));
gtk_snapshot_render_frame (snapshot, context,
0, gtk_tree_view_get_row_y_offset (tree_view, drag_tree, drag_node),
gdk_window_get_width (tree_view->priv->bin_window),
gtk_tree_view_get_row_height (tree_view, drag_node));
gtk_style_context_restore (context);
}
@@ -5281,10 +5293,10 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
tmp_height = gtk_tree_view_get_row_height (tree_view, node);
}
gtk_render_focus (context, cr,
0, tmp_y,
gdk_window_get_width (tree_view->priv->bin_window),
tmp_height);
gtk_snapshot_render_focus (snapshot, context,
0, tmp_y,
gdk_window_get_width (tree_view->priv->bin_window),
tmp_height);
gtk_style_context_restore (context);
}
@@ -5304,7 +5316,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
depth++;
/* Sanity Check! */
TREE_VIEW_INTERNAL_ASSERT (has_child, FALSE);
TREE_VIEW_INTERNAL_ASSERT_VOID (has_child);
}
else
{
@@ -5319,7 +5331,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
done = TRUE;
/* Sanity Check! */
TREE_VIEW_INTERNAL_ASSERT (has_next, FALSE);
TREE_VIEW_INTERNAL_ASSERT_VOID (has_next);
}
else
{
@@ -5337,7 +5349,7 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
depth--;
/* Sanity check */
TREE_VIEW_INTERNAL_ASSERT (has_parent, FALSE);
TREE_VIEW_INTERNAL_ASSERT_VOID (has_parent);
}
}
while (!done);
@@ -5346,39 +5358,48 @@ gtk_tree_view_bin_draw (GtkWidget *widget,
while (y_offset < clip.height);
done:
gtk_tree_view_draw_grid_lines (tree_view, cr);
gtk_tree_view_snapshot_grid_lines (tree_view, snapshot);
if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
gtk_tree_view_paint_rubber_band (tree_view, cr);
gtk_tree_view_snapshot_rubber_band (tree_view, snapshot);
if (drag_dest_path)
gtk_tree_path_free (drag_dest_path);
return FALSE;
}
static gboolean
gtk_tree_view_draw (GtkWidget *widget,
cairo_t *cr)
static void
gtk_tree_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
GtkWidget *button;
GtkStyleContext *context;
GList *list;
gint width, height;
context = gtk_widget_get_style_context (widget);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
gtk_render_background (context, cr,
0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_snapshot_render_background (snapshot, context,
0, 0,
width, height);
cairo_save (cr);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
0, gtk_tree_view_get_effective_header_height (tree_view),
width,
height - gtk_tree_view_get_effective_header_height (tree_view)
),
"TreeViewContentClip");
gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
gtk_tree_view_bin_draw (widget, cr);
cairo_restore (cr);
gtk_snapshot_translate_2d (snapshot,
- (gint) gtk_adjustment_get_value (tree_view->priv->hadjustment),
gtk_tree_view_get_effective_header_height (tree_view));
gtk_tree_view_bin_snapshot (widget, snapshot);
gtk_snapshot_translate_2d (snapshot,
(gint) gtk_adjustment_get_value (tree_view->priv->hadjustment),
- gtk_tree_view_get_effective_header_height (tree_view));
/* We can't just chain up to Container::draw as it will try to send the
* event to the headers, so we handle propagating it to our children
@@ -5388,9 +5409,13 @@ gtk_tree_view_draw (GtkWidget *widget,
{
GtkTreeViewChild *child = list->data;
gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
gtk_container_snapshot_child (GTK_CONTAINER (tree_view), child->widget, snapshot);
}
gtk_snapshot_pop_and_append (snapshot);
#if 0
Thyis clearly does not work. priv->drag_highlight_window is potentially a toplevel...
if (tree_view->priv->drag_highlight_window)
{
GdkRGBA color;
@@ -5416,6 +5441,15 @@ gtk_tree_view_draw (GtkWidget *widget,
}
cairo_restore (cr);
}
#endif
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(
0, 0,
width,
gtk_tree_view_get_effective_header_height (tree_view)
),
"TreeViewHeaderClip");
gtk_style_context_save (context);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_VIEW);
@@ -5430,21 +5464,21 @@ gtk_tree_view_draw (GtkWidget *widget,
if (gtk_tree_view_column_get_visible (column))
{
button = gtk_tree_view_column_get_button (column);
gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
button, cr);
gtk_container_snapshot_child (GTK_CONTAINER (tree_view),
button, snapshot);
}
}
if (tree_view->priv->drag_window)
{
button = gtk_tree_view_column_get_button (tree_view->priv->drag_column);
gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
button, cr);
gtk_container_snapshot_child (GTK_CONTAINER (tree_view),
button, snapshot);
}
gtk_style_context_restore (context);
return FALSE;
gtk_snapshot_pop_and_append (snapshot);
}
enum
@@ -9962,10 +9996,10 @@ gtk_tree_view_queue_draw_path (GtkTreeView *tree_view,
/* x and y are the mouse position
*/
static void
gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
cairo_t *cr,
GtkRBTree *tree,
GtkRBNode *node)
gtk_tree_view_snapshot_arrow (GtkTreeView *tree_view,
GtkSnapshot *snapshot,
GtkRBTree *tree,
GtkRBNode *node)
{
GdkRectangle area;
GtkStateFlags state = 0;
@@ -9974,9 +10008,12 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
gint x_offset = 0;
gint x2;
GtkCellRendererState flags = 0;
GtkCssImageBuiltinType image_type;
gboolean rtl;
widget = GTK_WIDGET (tree_view);
context = gtk_widget_get_style_context (widget);
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT))
return;
@@ -9998,18 +10035,27 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
state = gtk_cell_renderer_get_state (NULL, widget, flags);
if (node->children != NULL)
state |= GTK_STATE_FLAG_CHECKED;
{
state |= GTK_STATE_FLAG_CHECKED;
image_type = rtl ? GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT_EXPANDED
: GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT_EXPANDED;
}
else
state &= ~(GTK_STATE_FLAG_CHECKED);
{
state &= ~(GTK_STATE_FLAG_CHECKED);
image_type = rtl ? GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_RIGHT
: GTK_CSS_IMAGE_BUILTIN_EXPANDER_VERTICAL_LEFT;
}
gtk_style_context_save (context);
gtk_style_context_set_state (context, state);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER);
gtk_render_expander (context, cr,
area.x, area.y,
area.width, area.height);
gtk_snapshot_translate_2d (snapshot, area.x, area.y);
gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context), snapshot,
area.width, area.height, image_type);
gtk_snapshot_translate_2d (snapshot, -area.x, -area.y);
gtk_style_context_restore (context);
}
@@ -14101,6 +14147,8 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
GList *list;
GdkRectangle background_area;
GtkWidget *widget;
GtkSnapshot snapshot;
GskRenderNode *rendernode;
gint depth;
/* start drawing inside the black outline */
gint x = 1, y = 1;
@@ -14149,11 +14197,12 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
bin_window_width + 2,
background_area.height + 2);
cr = cairo_create (surface);
gtk_snapshot_init (&snapshot, NULL, NULL, "TreeView DragIcon");
gtk_render_background (context, cr, 0, 0,
bin_window_width + 2,
background_area.height + 2);
gtk_snapshot_render_background (&snapshot, context,
0, 0,
bin_window_width + 2,
background_area.height + 2);
rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL;
@@ -14195,29 +14244,42 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
{
if (is_separator)
{
GdkRGBA color;
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SEPARATOR);
gtk_render_line (context, cr,
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
cell_area.y + cell_area.height / 2);
gtk_style_context_get_color (context, &color);
gtk_snapshot_append_color_node (&snapshot,
&color,
&GRAPHENE_RECT_INIT(
cell_area.x,
cell_area.y + cell_area.height / 2,
cell_area.x + cell_area.width,
1
),
"Separator");
gtk_style_context_restore (context);
}
else
{
_gtk_tree_view_column_cell_render (column,
cr,
&background_area,
&cell_area,
0, FALSE);
gtk_tree_view_column_cell_snapshot (column,
&snapshot,
&background_area,
&cell_area,
0, FALSE);
}
}
cell_offset += gtk_tree_view_column_get_width (column);
}
rendernode = gtk_snapshot_finish (&snapshot);
cr = cairo_create (surface);
gsk_render_node_draw (rendernode, cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr,
0.5, 0.5,
@@ -14227,6 +14289,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
cairo_stroke (cr);
cairo_destroy (cr);
gsk_render_node_unref (rendernode);
cairo_surface_set_device_offset (surface, 2, 2);
+13 -17
View File
@@ -2865,9 +2865,9 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
}
/**
* gtk_tree_view_column_cell_render:
* gtk_tree_view_column_cell_snapshot:
* @tree_column: A #GtkTreeViewColumn.
* @cr: cairo context to draw to
* @snapshot: #GtkSnapshot to draw to
* @background_area: entire cell area (including tree expanders and maybe padding on the sides)
* @cell_area: area normally rendered by a cell renderer
* @flags: flags that affect rendering
@@ -2876,30 +2876,26 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
* #GtkTreeView.
**/
void
_gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
cairo_t *cr,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
guint flags,
gboolean draw_focus)
gtk_tree_view_column_cell_snapshot (GtkTreeViewColumn *tree_column,
GtkSnapshot *snapshot,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
guint flags,
gboolean draw_focus)
{
GtkTreeViewColumnPrivate *priv;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
g_return_if_fail (cr != NULL);
g_return_if_fail (snapshot != NULL);
g_return_if_fail (background_area != NULL);
g_return_if_fail (cell_area != NULL);
priv = tree_column->priv;
cairo_save (cr);
gtk_cell_area_render (priv->cell_area, priv->cell_area_context,
priv->tree_view, cr,
background_area, cell_area, flags,
draw_focus);
cairo_restore (cr);
gtk_cell_area_snapshot (priv->cell_area, priv->cell_area_context,
priv->tree_view, snapshot,
background_area, cell_area, flags,
draw_focus);
}
gboolean
+17 -7
View File
@@ -153,12 +153,12 @@ gtk_cell_renderer_graph_get_size (GtkCellRenderer *cell,
}
static void
gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
gtk_cell_renderer_graph_snapshot (GtkCellRenderer *cell,
GtkSnapshot *snapshot,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
GtkCellRendererGraph *graph = GTK_CELL_RENDERER_GRAPH (cell);
GtkCellRendererGraphPrivate *priv = graph->priv;
@@ -166,6 +166,7 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
double minimum, maximum, diff;
double x, y, width, height;
int xpad, ypad;
cairo_t *cr;
GdkRGBA color;
guint i, n;
@@ -194,6 +195,13 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
context = gtk_widget_get_style_context (widget);
gtk_style_context_get_color (context, &color);
cr = gtk_snapshot_append_cairo_node (snapshot,
&GRAPHENE_RECT_INIT (
background_area->x, background_area->y,
background_area->width, background_area->height
),
"CellGraph");
cairo_set_line_width (cr, 1.0);
x = background_area->x + xpad + LINE_WIDTH / 2.0;
@@ -226,6 +234,8 @@ gtk_cell_renderer_graph_render (GtkCellRenderer *cell,
color.alpha *= 0.2;
gdk_cairo_set_source_rgba (cr, &color);
cairo_fill (cr);
cairo_destroy (cr);
}
static void
@@ -239,7 +249,7 @@ gtk_cell_renderer_graph_class_init (GtkCellRendererGraphClass *klass)
object_class->set_property = gtk_cell_renderer_graph_set_property;
cell_class->get_size = gtk_cell_renderer_graph_get_size;
cell_class->render = gtk_cell_renderer_graph_render;
cell_class->snapshot = gtk_cell_renderer_graph_snapshot;
g_object_class_install_property (object_class,
PROP_DATA,
+84 -1
View File
@@ -21,8 +21,10 @@
#include "recorder.h"
#include <gtk/gtkbox.h>
#include <gtk/gtkfilechooserdialog.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklistbox.h>
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtktreeview.h>
@@ -43,6 +45,7 @@ struct _GtkInspectorRecorderPrivate
GtkWidget *recordings_list;
GtkWidget *render_node_view;
GtkWidget *render_node_tree;
GtkWidget *render_node_save_button;
GtkWidget *node_property_tree;
GtkTreeModel *render_node_properties;
@@ -219,14 +222,92 @@ render_node_list_selection_changed (GtkTreeSelection *selection,
GtkTreeIter iter;
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
return;
{
gtk_widget_set_sensitive (priv->render_node_save_button, FALSE);
return;
}
gtk_widget_set_sensitive (priv->render_node_save_button, TRUE);
node = gtk_tree_model_render_node_get_node_from_iter (GTK_TREE_MODEL_RENDER_NODE (priv->render_node_model), &iter);
gtk_render_node_view_set_render_node (GTK_RENDER_NODE_VIEW (priv->render_node_view), node);
populate_render_node_properties (GTK_LIST_STORE (priv->render_node_properties), node);
}
static void
render_node_save_response (GtkWidget *dialog,
gint response,
GskRenderNode *node)
{
gtk_widget_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
GBytes *bytes = gsk_render_node_serialize (node);
GError *error = NULL;
if (!g_file_replace_contents (gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)),
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
NULL,
FALSE,
0,
NULL,
NULL,
&error))
{
GtkWidget *message_dialog;
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))),
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
_("Saving RenderNode failed"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
"%s", error->message);
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (message_dialog);
g_error_free (error);
}
g_bytes_unref (bytes);
}
gtk_widget_destroy (dialog);
}
static void
render_node_save (GtkButton *button,
GtkInspectorRecorder *recorder)
{
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
GskRenderNode *node;
GtkTreeIter iter;
GtkWidget *dialog;
char *filename;
if (!gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->render_node_tree)), NULL, &iter))
return;
node = gtk_tree_model_render_node_get_node_from_iter (GTK_TREE_MODEL_RENDER_NODE (priv->render_node_model), &iter);
dialog = gtk_file_chooser_dialog_new ("",
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (recorder))),
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_ACCEPT,
NULL);
filename = g_strdup_printf ("%s.node", gsk_render_node_get_name (node) ? gsk_render_node_get_name (node)
: node_type_name (gsk_render_node_get_node_type (node)));
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
g_free (filename);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
g_signal_connect (dialog, "response", G_CALLBACK (render_node_save_response), node);
gtk_widget_show (dialog);
}
static char *
format_timespan (gint64 timespan)
{
@@ -394,11 +475,13 @@ gtk_inspector_recorder_class_init (GtkInspectorRecorderClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings_list);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_view);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_tree);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, render_node_save_button);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, node_property_tree);
gtk_widget_class_bind_template_callback (widget_class, recordings_clear_all);
gtk_widget_class_bind_template_callback (widget_class, recordings_list_row_selected);
gtk_widget_class_bind_template_callback (widget_class, render_node_list_selection_changed);
gtk_widget_class_bind_template_callback (widget_class, render_node_save);
}
static void
+12
View File
@@ -33,6 +33,18 @@
<property name="stack">render_stack</property>
</object>
</child>
<child>
<object class="GtkButton" id="render_node_save_button">
<property name="visible">1</property>
<property name="relief">none</property>
<property name="sensitive">0</property>
<property name="icon-name">document-save-as-symbolic</property>
<signal name="clicked" handler="render_node_save"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
</object>
</child>
<child>
+1
View File
@@ -292,6 +292,7 @@ gtk/inspector/gtkstackcombo.c
gtk/inspector/menu.c
gtk/inspector/misc-info.c
gtk/inspector/prop-editor.c
gtk/inspector/recorder.c
gtk/inspector/signals-list.c
gtk/inspector/size-groups.c
gtk/inspector/statistics.c
+259 -260
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -306,6 +306,7 @@ gtk/inspector/object-hierarchy.ui
gtk/inspector/object-tree.ui
gtk/inspector/prop-editor.c
gtk/inspector/prop-list.ui
gtk/inspector/recorder.c
gtk/inspector/resource-list.ui
gtk/inspector/selector.ui
gtk/inspector/signals-list.c

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