mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
gsk gl: Handle subsurfaces during rendering
During rendering, restack offloaded subsurfaces below the main surface, and clear the area so they peek through. After rendering, raise the last subsurface if we haven't drawn over it.
This commit is contained in:
parent
c636baf6f5
commit
904d44074f
@ -24,10 +24,13 @@
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdksubsurfaceprivate.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gsk/gskdebugprivate.h>
|
||||
#include <gsk/gskrendererprivate.h>
|
||||
#include <gsk/gskrendernodeprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
|
||||
#include "gskglcommandqueueprivate.h"
|
||||
#include "gskgldriverprivate.h"
|
||||
@ -289,6 +292,12 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context));
|
||||
scale = gdk_gl_context_get_scale (self->context);
|
||||
|
||||
if (cairo_region_is_empty (update_area))
|
||||
{
|
||||
gdk_draw_context_empty_frame (GDK_DRAW_CONTEXT (self->context));
|
||||
return;
|
||||
}
|
||||
|
||||
viewport.origin.x = 0;
|
||||
viewport.origin.y = 0;
|
||||
viewport.size.width = gdk_surface_get_width (surface) * scale;
|
||||
@ -305,7 +314,7 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
clear_framebuffer = update_area_requires_clear (surface, render_region);
|
||||
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, clear_framebuffer);
|
||||
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, clear_framebuffer, offload);
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||
gsk_gl_render_job_render (job, root);
|
||||
@ -377,7 +386,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
format = GL_RGBA32F;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
format = GL_RGBA8;
|
||||
gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
@ -391,7 +400,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
&render_target))
|
||||
{
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id, TRUE);
|
||||
job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id, TRUE, NULL);
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||
gsk_gl_render_job_render_flipped (job, root);
|
||||
|
@ -31,9 +31,13 @@
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include <gdk/gdkmemorytextureprivate.h>
|
||||
#include <gdk/gdkdmabuftexture.h>
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdksubsurfaceprivate.h>
|
||||
#include <gsk/gsktransformprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
#include <gsk/gskrendererprivate.h>
|
||||
#include <gsk/gskoffloadprivate.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -44,10 +48,12 @@
|
||||
#include "gskglprogramprivate.h"
|
||||
#include "gskglrenderjobprivate.h"
|
||||
#include "gskglshadowlibraryprivate.h"
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include "ninesliceprivate.h"
|
||||
#include "fp16private.h"
|
||||
|
||||
#define ALLOW_OFFLOAD_FOR_ANY_TEXTURE 1
|
||||
|
||||
#define ORTHO_NEAR_PLANE -10000
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
@ -174,6 +180,8 @@ struct _GskGLRenderJob
|
||||
* looking at the format of the framebuffer we are rendering on.
|
||||
*/
|
||||
int target_format;
|
||||
|
||||
GskOffload *offload;
|
||||
};
|
||||
|
||||
typedef struct _GskGLRenderOffscreen
|
||||
@ -3998,6 +4006,36 @@ gsk_gl_render_job_visit_repeat_node (GskGLRenderJob *job,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_subsurface_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
GdkSubsurface *subsurface;
|
||||
|
||||
subsurface = (GdkSubsurface *) gsk_subsurface_node_get_subsurface (node);
|
||||
|
||||
if (job->offload &&
|
||||
gsk_offload_subsurface_is_offloaded (job->offload, subsurface))
|
||||
{
|
||||
/* Clear the area so we can see through */
|
||||
if (gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color)))
|
||||
{
|
||||
GskGLCommandBatch *batch;
|
||||
guint16 color[4];
|
||||
rgba_to_half (&(GdkRGBA){0,0,0,0}, color);
|
||||
|
||||
batch = gsk_gl_command_queue_get_batch (job->command_queue);
|
||||
batch->draw.blend = 0;
|
||||
gsk_gl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gl_render_job_visit_node (job, gsk_subsurface_node_get_child (node));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
@ -4195,8 +4233,7 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
break;
|
||||
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
// FIXME do something here
|
||||
gsk_gl_render_job_visit_node (job, gsk_subsurface_node_get_child (node));
|
||||
gsk_gl_render_job_visit_subsurface_node (job, node);
|
||||
break;
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
@ -4520,6 +4557,7 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
|
||||
gsk_gl_render_job_visit_node (job, root);
|
||||
gdk_gl_context_pop_debug_group (job->command_queue->context);
|
||||
|
||||
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Build GL command queue", "");
|
||||
|
||||
#if 0
|
||||
@ -4580,7 +4618,8 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
float scale,
|
||||
const cairo_region_t *region,
|
||||
guint framebuffer,
|
||||
gboolean clear_framebuffer)
|
||||
gboolean clear_framebuffer,
|
||||
GskOffload *offload)
|
||||
{
|
||||
const graphene_rect_t *clip_rect = viewport;
|
||||
graphene_rect_t transformed_extents;
|
||||
@ -4616,6 +4655,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
job->scale_y = scale;
|
||||
job->viewport = *viewport;
|
||||
job->target_format = get_framebuffer_format (job->command_queue->context, framebuffer);
|
||||
job->offload = offload;
|
||||
|
||||
gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, viewport, NULL);
|
||||
|
@ -27,7 +27,8 @@ GskGLRenderJob *gsk_gl_render_job_new (GskGLDriver *dri
|
||||
float scale,
|
||||
const cairo_region_t *region,
|
||||
guint framebuffer,
|
||||
gboolean clear_framebuffer);
|
||||
gboolean clear_framebuffer,
|
||||
GskOffload *offload);
|
||||
void gsk_gl_render_job_free (GskGLRenderJob *job);
|
||||
void gsk_gl_render_job_render (GskGLRenderJob *job,
|
||||
GskRenderNode *root);
|
||||
|
Loading…
Reference in New Issue
Block a user