gpu: Add GSK_GPU_SKIP env var

The env var allows skipping various optimizations in the GPU shader.

This is useful for testing during development when trying to figure
out how to make a renderer as fast as possible.

We could also use it to enable/disable optimizations depending on GL
version or so, but I didn't think about that too much yet.
This commit is contained in:
Benjamin Otte
2023-09-23 05:03:13 +02:00
parent e3bac4063c
commit e7a59d92ac
6 changed files with 44 additions and 7 deletions

View File

@@ -31,6 +31,7 @@ struct _GskGpuFramePrivate
{
GskGpuRenderer *renderer;
GskGpuDevice *device;
GskGpuOptimizations optimizations;
gint64 timestamp;
GskGpuOps ops;
@@ -120,15 +121,17 @@ gsk_gpu_frame_init (GskGpuFrame *self)
}
void
gsk_gpu_frame_setup (GskGpuFrame *self,
GskGpuRenderer *renderer,
GskGpuDevice *device)
gsk_gpu_frame_setup (GskGpuFrame *self,
GskGpuRenderer *renderer,
GskGpuDevice *device,
GskGpuOptimizations optimizations)
{
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
/* no reference, the renderer owns us */
priv->renderer = renderer;
priv->device = g_object_ref (device);
priv->optimizations = optimizations;
GSK_GPU_FRAME_GET_CLASS (self)->setup (self);
}
@@ -157,6 +160,15 @@ gsk_gpu_frame_get_timestamp (GskGpuFrame *self)
return priv->timestamp;
}
gboolean
gsk_gpu_frame_should_optimize (GskGpuFrame *self,
GskGpuOptimizations optimization)
{
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
return (priv->optimizations & optimization) == optimization;
}
static void
gsk_gpu_frame_verbose_print (GskGpuFrame *self,
const char *heading)

View File

@@ -45,11 +45,14 @@ GType gsk_gpu_frame_get_type (void) G
void gsk_gpu_frame_setup (GskGpuFrame *self,
GskGpuRenderer *renderer,
GskGpuDevice *device);
GskGpuDevice *device,
GskGpuOptimizations optimizations);
GdkDrawContext * gsk_gpu_frame_get_context (GskGpuFrame *self) G_GNUC_PURE;
GskGpuDevice * gsk_gpu_frame_get_device (GskGpuFrame *self) G_GNUC_PURE;
gint64 gsk_gpu_frame_get_timestamp (GskGpuFrame *self) G_GNUC_PURE;
gboolean gsk_gpu_frame_should_optimize (GskGpuFrame *self,
GskGpuOptimizations optimization) G_GNUC_PURE;
gpointer gsk_gpu_frame_alloc_op (GskGpuFrame *self,
gsize size);

View File

@@ -956,7 +956,8 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
&rect);
gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped);
if (gdk_rgba_is_opaque (color) &&
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) &&
gdk_rgba_is_opaque (color) &&
node->bounds.size.width * node->bounds.size.height > 100 * 100 && /* not worth the effort for small images */
gsk_gpu_node_processor_rect_is_integer (self, &clipped, &int_clipped))
{
@@ -1869,6 +1870,9 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuPatternWriter *self,
gsize tmp_size;
guint32 tex_id;
if (!gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_UBER))
return FALSE;
node_type = gsk_render_node_get_node_type (node);
if (node_type >= G_N_ELEMENTS (nodes_vtable))
{

View File

@@ -11,6 +11,7 @@
#include "gskgpuimageprivate.h"
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdebugprivate.h"
#include "gdk/gdkdrawcontextprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include "gdk/gdktextureprivate.h"
@@ -20,6 +21,11 @@
#define GSK_GPU_MAX_FRAMES 4
static const GdkDebugKey gsk_gpu_optimization_keys[] = {
{ "uber", GSK_GPU_OPTIMIZE_UBER, "Don't use the uber shader" },
{ "clear", GSK_GPU_OPTIMIZE_CLEAR, "Use shaders instead of vkCmdClearAttachment()/glClear()" },
};
typedef struct _GskGpuRendererPrivate GskGpuRendererPrivate;
struct _GskGpuRendererPrivate
@@ -71,11 +77,12 @@ static GskGpuFrame *
gsk_gpu_renderer_create_frame (GskGpuRenderer *self)
{
GskGpuRendererPrivate *priv = gsk_gpu_renderer_get_instance_private (self);
GskGpuRendererClass *klass = GSK_GPU_RENDERER_GET_CLASS (self);
GskGpuFrame *result;
result = g_object_new (GSK_GPU_RENDERER_GET_CLASS (self)->frame_type, NULL);
result = g_object_new (klass->frame_type, NULL);
gsk_gpu_frame_setup (result, self, priv->device);
gsk_gpu_frame_setup (result, self, priv->device, klass->optimizations);
return result;
}
@@ -269,6 +276,11 @@ gsk_gpu_renderer_class_init (GskGpuRendererClass *klass)
renderer_class->render_texture = gsk_gpu_renderer_render_texture;
gsk_ensure_resources ();
klass->optimizations = -1;
klass->optimizations &= ~gdk_parse_debug_var ("GSK_GPU_SKIP",
gsk_gpu_optimization_keys,
G_N_ELEMENTS (gsk_gpu_optimization_keys));
}
static void

View File

@@ -23,6 +23,7 @@ struct _GskGpuRendererClass
GskRendererClass parent_class;
GType frame_type;
GskGpuOptimizations optimizations;
GskGpuDevice * (* get_device) (GdkDisplay *display,
GError **error);

View File

@@ -54,3 +54,8 @@ typedef enum {
GSK_GPU_PATTERN_POP_MASK_INVERTED_LUMINANCE,
} GskGpuPatternType;
typedef enum {
GSK_GPU_OPTIMIZE_UBER = 1 << 0,
GSK_GPU_OPTIMIZE_CLEAR = 1 << 1,
} GskGpuOptimizations;