Commit Graph

75 Commits

Author SHA1 Message Date
Benjamin Otte
adcde3034e gsk: Implement gsk_renderer_render_texture() on GL 2016-12-23 08:11:01 +01:00
Alexander Larsson
22110ef5a4 gsk: Add bounds member to RenderNode
Instead of constantly recalculating this (especially recursively for
parents!) we do it only on construction, because everything is
immutable anyway. Also, most nodes had a bounds already and can
use the new parent member instead.

We also do direct access to the node bounds rather than calling
gsk_render_node_get_bounds in various places, which means
we do less copying.
2016-12-21 14:01:34 +01:00
Benjamin Otte
3ef03c8bc0 gsk: Check for NULL in calls to gsk_cairo_node_get_surface()
That function does actually sometimes return NULL and is documented to
do so, so handle that case in the renderers (by omitting the node).
2016-12-20 18:01:11 +01:00
Benjamin Otte
cf520b7a1f gsk: Add blend nodes
Implement blend mode support in GTK background compositing with it.
2016-12-20 18:01:11 +01:00
Benjamin Otte
07d39299ea gsk: Replace gsk_render_node_set_opacity()
... with gsk_opacity_node_new().

Also implement support for opacity in gtk_widget_snapshot() using this
new node.
2016-12-20 18:01:10 +01:00
Benjamin Otte
ee9aca882d gsk: Add fallback code to renderers
This code makes renderers fall back to Cairo rendering if they don't
know how to handle a render node's type.

This allows adding new render nodes with impunity.
2016-12-20 18:01:10 +01:00
Benjamin Otte
67fb129ed7 gsk: gsk_render_node_set_transform() => GskTransformNode
Instead of having a setter for the transform, have a GskTransformNode.

Most of the oprations that GTK does do not require a transform, so it
doesn't make sense to have it as a primary attribute.

Also, changing the transform requires updating the uniforms of the GL
renderer, so we're happy if we can avoid that.
2016-12-20 18:01:10 +01:00
Benjamin Otte
19753062c4 gsK: Move children handling to GskContainerNode 2016-12-20 18:01:09 +01:00
Benjamin Otte
e2625f8649 gsk: Remove GskRenderNode::parent
... and all related APIs.
2016-12-20 18:01:09 +01:00
Benjamin Otte
a8f2b3e75e gsk: Remove world matrix support
Use the real transform and compute it manually.
2016-12-20 18:01:09 +01:00
Benjamin Otte
4d376c80f3 gsk: Remove gsk_render_node_get_size()
In the brave new world of refactored render nodes, this function doesn't
really make any sense anymore. We could turn it into a vfunc, but I
don't think it's useful.

Especially because even in the brave old world, this function was
causing a vastl overallocation of nodes when the GL renderer needed render
targets.
2016-12-20 18:01:09 +01:00
Benjamin Otte
e4ee65fd19 gsk: Remove gsk_render_node_set_opaque()
If we ever feel, we need this function again, we can readd it later.

But nobody is using it other than for overriding opactiy. And you can
just override opacity directly if you care.
2016-12-20 18:01:09 +01:00
Benjamin Otte
abd184efc9 gsk: Remove gsk_render_node_is_surface/texture()
Use gsk_render_node_get_node_type() instead.
2016-12-20 18:01:09 +01:00
Benjamin Otte
52d2faef88 gsk: Add gsk_cairo_node_new()
Split off Cairo drawn content nodes and require you to allocate them
using this new function.
2016-12-20 18:01:09 +01:00
Benjamin Otte
8c8691b469 gsk: Add gsk_texture_node_new()
Start the transition into the different node types.
2016-12-20 18:01:09 +01:00
Benjamin Otte
f258af9cce gsk: Remove GskRenderNodeIter 2016-12-20 18:01:09 +01:00
Benjamin Otte
ff884385c0 gsk: Remove GskRenderNode::hidden
If you want to hide something, don't render it.
2016-12-20 18:01:09 +01:00
Benjamin Otte
8915be00d1 gdkgl: Add gdk_gl_context_get_damage()
This is a way to query the damaged area of the backbuffer.

The GL renderer uses this to compute the extents of that damage region
(computed via buffer age) and use them to minimize the area to redraw.

This changes the semantics of GL rendering to "When calling
gdk_window_begin_frame() with a GL context, the area by
gdk_gl_context_get_damage() needs to be redrawn and every other pixel of
the backbuffer is guaranteed to be correct.
After gdk_window_end_frame() on a GL-drawn window, the whole backbuffer
must be correct.

We can always glXBufferSwap() now because of this.
2016-12-05 15:02:47 +01:00
Benjamin Otte
9597caef5e glrenderer: Always redraw the whole screen 2016-12-05 15:02:47 +01:00
Benjamin Otte
ca78f5d3cb gdk: Make gdk_window_begin_draw_frame() take a draw context
... instead of a gl context.

This requires some refactoring in the way we mark the shared context as
drawing: We now call begin_frame/end_frame() on it and ignore the call
on the main context.
Unfortunately we need to do this check in all vfuncs, which sucks. But I
haven't found a better way.
2016-12-05 15:02:47 +01:00
Benjamin Otte
358aca9e20 glrenderer: Always redraw the whole screen 2016-12-05 15:02:47 +01:00
Benjamin Otte
e38bd27d58 gdk: Redo GL drawing
Reenable GL drawing, but do it without Cairo.

Now, the context passed to gdk_window_begin_draw_frame() decides how
drawing is going to happen. If it is NULL, Cairo is used like before.

If a context is passed, Cairo may not be used for drawing and
gdk_drawing_context_get_cairo_context() is going to return NULL.
Instead, the GL renderer must draw to the GL backbuffer and
end_draw_frame() is then swapping that to the front.

The GskGLRenderer has lost the texture it used to render to and adapted
to render directly to the backbuffer instead.

The only thing missing is for GtkGLArea to gain back a performant way to
render. But it didn't have one since the introduction of GSK, this
patchset doesn't change anything about it.

The new rendering avoids two indirections (the GSK renderer's texture
and the GDK double buffering surface).
It improves icon count in the fishbowl demo by 30%.
2016-12-05 15:02:47 +01:00
Benjamin Otte
e42e27304a gskrenderer: Store the GL context
And use it to create the drawing context with it.

Note that this doesn't yet have any effect and is all infrastructure
preparation work.
2016-12-05 15:02:47 +01:00
Benjamin Otte
318e19f570 gskrenderer: Add GError argument to gsk_renderer_realize()
This way, we don't spam criticals when GL is not available. Instead, we
print a useful debug message to stderr and continue with the Cairo renderer.

Signed-off-by: Emmanuele Bassi <ebassi@gnome.org>
2016-11-30 15:58:07 +01:00
Benjamin Otte
ce98df881f gsk: Change gsk_renderer_realize()
Instead of having a gsk_renderer_set_window() call, pass the window to
realize(). This way, the realization can fail with the wrong window.

Signed-off-by: Emmanuele Bassi <ebassi@gnome.org>
2016-11-30 15:55:45 +01:00
Benjamin Otte
48e7f4191f gsktexture: Allow attaching render data to textures
This allows renderers (or anyone really) to attach "render data" to
textures. Only the first render data sticks.

You can gsk_texture_set_render_data() with the key you will use to
look the data up again, and if no data has been set yet, yours will be
set.

You can retrieve this data via gsk_texture_get_render_data() later on.
If your data has been cleared, NULL will be returned.

When gsk_texture_clear_render_data() is called (which the texture will
call when it is finalized), your destory notify will be called and you
have to release your render data.

The GL driver uses this to attach texture ids to GskTextures.
2016-11-16 17:36:33 +01:00
Benjamin Otte
40565fb030 gsk: Rework GskTexture
We do no longer bind textures to a renderer, instead they are a way for
applications to provide texture data.

For now, that's it. We've reverted to uploading it from scratch every
frame.
2016-11-16 17:36:33 +01:00
Benjamin Otte
46eb2c1be9 gsk: Add GskTexture 2016-11-08 20:31:34 +01:00
Benjamin Otte
e201c4dc92 gsk: Remove gsk_render_node_get_scale_factor()
Scale factors belong to the renderers, not the nodes. The nodes should
just use whatever scale factor the renderer tells them to when
rendering.
2016-11-01 16:32:26 +01:00
Emmanuele Bassi
02c615cc34 gsk: Use the appropriate GLSL version
The GLSL versions are:

  OpenGL 2.1: #version 110
  OpenGL 3.0: #version 130
  OpenGL 3.2: #version 150

  OpenGLES 2.0: #version 100
  OpenGLES 3.0: #version 300 es

So we need to check the version of the GdkGLContext if we want use the
appropriate version, especially for legacy OpenGL contexts, which can be
both 3.x and 2.x.
2016-11-01 15:00:31 +00:00
Emmanuele Bassi
dace0791a9 gsk: Add the ability to create fallback renderers
While porting GTK to GskRenderer we noticed that the current fallback
code for widgets using Cairo to draw is not enough to cover all the
possible cases.

For instance, if a container widget still uses GtkWidget::draw to render
its children, and at least one of them has been ported to using render
nodes instead, the container won't know how to draw it.

For this reason we want to provide to layers above GSK the ability to
create a "fallback" renderer instance, created using a "parent"
GskRenderer instance, but using a Cairo context as the rendering target
instead of a GdkDrawingContext.

GTK will use this inside the gtk_widget_draw() implementation, if a
widget implements GtkWidgetClass.get_render_node().
2016-10-18 11:49:16 +01:00
Emmanuele Bassi
6b3c0052fc gsk: Make GskRenderer.render() drawing context-agnostic
We're going to need to allow rendering on a specific cairo_t in order to
implement fallback code paths inside GTK; this means that there will be
times when we have a transient GskRenderer instance that does not have a
GdkDrawingContext to draw on.

Instead of adding a new render() implementation for those cases and then
decide which one to use, we can remove the drawing context argument from
the virtual function itself, and allow using a NULL GdkDrawingContext
when calling gsk_renderer_render(). A later commit will add a generic
function to create a transient GskRenderer with a cairo_t attached to
it.

Renderers inside GSK will have to check whether we have access to a
GdkDrawingContext, in which case we're going to use it; or if we have
access to a cairo_t and a window.
2016-10-18 11:49:15 +01:00
Matthias Clasen
9a2de80497 Add blend mode to debug spew 2016-10-18 11:49:14 +01:00
Alexander Larsson
e0ab6d5a3c gsk: Fix hidpi scaling
We store the vertices in (unscaled) window coords (but the item size
is still scaled to match the texture size). Also, the
projection/model-view multiplication order is switched so that the scale
is applied at the right place.
2016-10-18 11:49:14 +01:00
Emmanuele Bassi
387ed37f74 gsk: Move scaling filters to GskRenderNode
The renderer will always use nearest-neighbor filters because it renders
at 1:1 pixel to texel ratio.

On the other hand, render nodes may be scaled, so we need to offer a way
to control the minification and magnification filters.
2016-10-18 11:49:14 +01:00
Emmanuele Bassi
3bdd9c270a gsk: Allow adding a GL texture as a node content
If we already have a GL texture we definitely don't want to use
gdk_cairo_draw_from_gl() to draw on a Cairo context if we're going
to take the Cairo surface to which we draw and put it into an OpenGL
texture.
2016-10-18 11:49:14 +01:00
Emmanuele Bassi
ce67336577 gsk: Drop modelview/projection from GskRenderer API
The details of the modelview and projection matrices are only useful for
the GL renderer; there's really no point in having those details
available in the generic API — especially as the Cairo fallback renderer
cannot really set up a complex modelview or a projection matrix.
2016-10-18 11:49:14 +01:00
Emmanuele Bassi
c9514b45ff gsk: Ensure that non-drawing nodes are supported
Non-drawing nodes should skip the texturing phase.
2016-10-18 11:49:14 +01:00
Emmanuele Bassi
955d9a8463 gsk: Fix the blend mode
The default blend mode should be the equivalent of Cairo's OVER
operator.
2016-10-18 11:49:13 +01:00
Emmanuele Bassi
0812d691b3 gsk: Reuse VAOs with identical buffers
Just like we reuse texture ids with the same size we can, at the expense
of a little memory, reuse vertex buffers if they reference the same
attributes and contain the same data.

Each VAO is marked as free at the end of the frame, and if it's not
reused in the following frame, it gets dropped.
2016-10-18 11:49:13 +01:00
Emmanuele Bassi
32d45b0081 gsk: Pass the appropriate value for the n_quads argument
Instead of passing the size of the buffer, we should pass the number of
quads; we know what the size of a single quad structure is, so we can do
the multiplication internally when creating the VAO.

This allows us to print the quads for debugging purposes.
2016-10-18 11:49:12 +01:00
Emmanuele Bassi
702befc697 gsk: Recycle textures across frames
We keep the textures used inside a frame around until the end of the
following frame; whenever we need a texture with the same size, and
it's not marked in use, then we just reuse the existing texture.
2016-10-18 11:49:11 +01:00
Matthias Clasen
ff20a68ca3 gsk: Split of debug spew for transforms
This was overwhelming other useful debug output, so make it
opt-in. We print the render items for both opengl and transforms,
since the matrices bleed into each other, otherwise.
2016-10-18 11:49:11 +01:00
Matthias Clasen
23745462a4 gsk: Improve debug output a bit
Indent render node debug spew to make the tree structure obvious.
2016-10-18 11:49:11 +01:00
Emmanuele Bassi
d227b9ce38 gsk: Add GskProfiler to GskRenderer
The profiler instance is per-renderer, and is accesible to
implementations.
2016-10-18 11:49:10 +01:00
Emmanuele Bassi
1ab1fd4391 Use the projection to flip around the content
Since we use an FBO to render the contents of the render node tree, the
coordinate space is going to be flipped in GL. We can undo the flip by
using an appropriate projection matrix, instead of changing the sampling
coordinates in the shaders and updating all our coordinates at render
time.
2016-10-18 11:49:10 +01:00
Emmanuele Bassi
9982b66906 gsk: Add texture size to debug message 2016-10-18 11:49:10 +01:00
Emmanuele Bassi
a8a8f97511 gsk: Take into account the scaling factor
We need to apply a scaling factor whenever we deal with user-supplied
coordinates, like:

 - when creating textures
 - when setting up the viewport
 - when submitting the scene
2016-10-18 11:49:10 +01:00
Emmanuele Bassi
ab8420ec52 gsk: Bind GL context to the GL profiler
Similarly to how we bind it to the GL driver object used by the GSK GL
renderer.
2016-10-18 11:49:10 +01:00
Emmanuele Bassi
9e22118feb gsk: Add redirection to FBOs for opacity groups
If a node is non-opaque and has a non-zero opacity we need to paint its
contents and children first to an off screen buffer, and then render the
resulting texture at the desired opacity — otherwise the opacities will
combine and result in the wrong rendering.
2016-10-18 11:49:09 +01:00