Commit Graph

50 Commits

Author SHA1 Message Date
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
Emmanuele Bassi
8ac9127283 gsk: Drop opaque/transparent item split
We're not going to use separate rendering lists soon, and the way we
render items is less similar to a gaming engine and more similar to a
simpler compositor. This means we don't need to perform a two pass
rendering — opaque items first, transparent items later.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
03ab560fae gsk: Rename uniforms and attributes in shaders
Use appropriate names, and annotate the names with the types — 'u' for
uniforms, 'a' for attributes. The common preambles for shaders are split
from the bodies, so we need some way to distinguish the uniforms and the
attributes just from their name.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
24a6f3c055 gsk: Move resource handling inside GskGLDriver
We want the GL driver to cache as many resources as possible, so we can
always ensure that we're in a consistent state, and we can handle state
transitions more appropriately.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
bbfe4324e4 gsk: Simplify buffer handling in GskGLRenderer
We don't have optional stencil and depth buffers, like GtkGLArea: we
always create both of them internally.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
db4ade48e9 gsk: Drop render buffer code path from GskGLRenderer
We always use texturing, to preserve the alpha channel when blitting the
frame buffer object on the window surface.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
b169ce374e gsk: Rework surface -> texture API
Drop the texture parameters handling from the texture creation, and
associate them with the contents upload. Also, rename the function to
something more in line with what it does.
2016-10-18 11:49:09 +01:00
Emmanuele Bassi
30be7bd543 gsk: Add GL profiler
We can use the GL_ARB_timer_query extension (available since OpenGL
3.2, and part of the OpenGL specification since version 3.3) to query
the time elapsed when drawing each frame. This allows us to gather
timing information on our use of the GPU.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
8807f23f76 gsk: Split surface upload from texture creation
We're going to need a method to create textures without a surface.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
b98fb07419 gsk: Enable depth testing
Use the appropriate depth testing function for transparent items.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
46bb14e173 gsk: Add GskGLDriver
We can move the caching and management of textures, VAOs, and state of
the GL machinery into a single object, GskGLDriver.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
8555c6ba11 gsk: Use the right pointer to the parent RenderItem
We copy the local RenderItem into the render items array, so we need to
use the copy in the array in order to get the correct reference.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
0fbf638999 gsk: Add 'blit' program
For the root node we do not need to use blending, as it does not have
any backdrop to blend into. We can use a simpler 'blit' program that
only takes the content of the source and fills the texture quad with
it.
2016-10-18 11:49:08 +01:00
Emmanuele Bassi
4cda720ab9 gsk: Consolidate program creation and storage
We should use ShaderBuilder to create and store programs for the GL
renderer. This allows us to simplify the creation of programs (by moving
the compilation phase into the ShaderBuilder::create_program() method),
and move towards the ability to create multiple programs and just keep a
reference to the program id.
2016-10-18 11:49:07 +01:00
Emmanuele Bassi
9e3b0f5aa0 gsk: Don't store the uniform and attribute location twice
We should keep the ShaderBuilder around and use it to query the various
uniform and attribute locations when needed, instead of storing those
offsets into the Renderer instance, and copying them. This allows a bit
more flexibility, once we have more than one program built into the
renderer.
2016-10-18 11:49:07 +01:00
Emmanuele Bassi
28b490f14f gsk: Rework how GLSL shaders are built
The GL renderer should build the GLSL shaders using GskShaderBuilder.
This allows us to separate the common parts into separate files, and
assemble them as necessary, instead of shipping one big shader per type
of GL API (GL3, GL legacy, and GLES).
2016-10-18 11:49:07 +01:00
Emmanuele Bassi
1b1edcebd0 gsk: Use the node's blend mode in the GL renderer 2016-10-18 11:49:07 +01:00
Emmanuele Bassi
bf09ce93c8 gsk: Make GskBlendMode enumeration public 2016-10-18 11:49:07 +01:00
Emmanuele Bassi
638297a22e gsk: Allow sampling between parent and child nodes 2016-10-18 11:49:07 +01:00
Emmanuele Bassi
7416aa762f gsk: Group render state attributes 2016-10-18 11:49:06 +01:00
Emmanuele Bassi
074c77e7ac gsk: Rework GskRenderer and GskRenderNode semantics
This commit changes the way GskRenderer and GskRenderNode interact and
are meant to be used.

GskRenderNode should represent a transient tree of rendering nodes,
which are submitted to the GskRenderer at render time; this allows the
renderer to take ownership of the render tree. Once the toolkit and
application code have finished assembling it, the render tree ownership
is transferred to the renderer.
2016-10-18 11:29:34 +01:00
Emmanuele Bassi
d99f91f5fd gsk: Flush the GL render items cache
Whenever the render tree changes we want to drop the RenderItem arrays,
as each item contains a pointer to the GskRenderNode which becomes
dangling once the root node changed.
2016-10-18 11:29:34 +01:00
Emmanuele Bassi
9d3ca22b4c gsk: Port GskGLRenderer to GLES
Use the appropriate API and shaders if the GdkGLContext was created for
OpenGL ES instead of OpenGL.
2016-10-18 11:29:34 +01:00
Emmanuele Bassi
5909ce6897 gsk: Use surface-to-texture utility function
Now that we have it.
2016-10-18 11:29:34 +01:00
Emmanuele Bassi
eb9c0920ab gsk: Rename shaders for OpenGL 2016-10-18 11:29:34 +01:00
Emmanuele Bassi
7afdd3fdb5 Initial implementation of GSK rendering pipeline
GSK is conceptually split into two scene graphs:

 * a simple rendering tree of operations
 * a complex set of logical layers

The latter is built on the former, and adds convenience and high level
API for application developers.

The lower layer, though, is what gets transformed into the rendering
pipeline, as it's simple and thus can be transformed into appropriate
rendering commands with minimal state changes.

The lower layer is also suitable for reuse from more complex higher
layers, like the CSS machinery in GTK, without necessarily port those
layers to the GSK high level API.

This lower layer is based on GskRenderNode instances, which represent
the tree of rendering operations; and a GskRenderer instance, which
takes the render nodes and submits them (after potentially reordering
and transforming them to a more appropriate representation) to the
underlying graphic system.
2016-10-18 11:29:34 +01:00