Compare commits
6 Commits
main
...
underline-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f8dc14dc9 | ||
|
|
835adc81a7 | ||
|
|
df6d8a283b | ||
|
|
112d84b15c | ||
|
|
1c7c9503e6 | ||
|
|
11dca18449 |
@@ -34,7 +34,7 @@ gsk_gpu_colorize_op_print (GskGpuOp *op,
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
|
||||
const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
|
||||
{
|
||||
GSK_GPU_OP_SIZE (GskGpuColorizeOp),
|
||||
GSK_GPU_STAGE_SHADER,
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
extern const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS;
|
||||
|
||||
void gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
|
||||
@@ -179,6 +179,10 @@ struct _GskGpuCachedAtlas
|
||||
|
||||
GskGpuImage *image;
|
||||
|
||||
gboolean has_colorize;
|
||||
gsize colorize_x;
|
||||
gsize colorize_y;
|
||||
|
||||
gsize n_slices;
|
||||
struct {
|
||||
gsize width;
|
||||
@@ -233,6 +237,8 @@ gsk_gpu_cached_atlas_new (GskGpuDevice *device)
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_ATLAS_CLASS, NULL);
|
||||
self->image = GSK_GPU_DEVICE_GET_CLASS (device)->create_atlas_image (device, ATLAS_SIZE, ATLAS_SIZE);
|
||||
|
||||
self->has_colorize = FALSE;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -981,5 +987,43 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_get_solid_image (GskGpuDevice *self,
|
||||
GskGpuFrame *frame,
|
||||
graphene_rect_t *out_bounds)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE);
|
||||
|
||||
if (!priv->current_atlas->has_colorize)
|
||||
{
|
||||
gsize x, y;
|
||||
|
||||
if (!gsk_gpu_cached_atlas_allocate (priv->current_atlas, 5, 5, &x, &y))
|
||||
{
|
||||
gsk_gpu_device_ensure_atlas (self, TRUE);
|
||||
gsk_gpu_cached_atlas_allocate (priv->current_atlas, 5, 5, &x, &y);
|
||||
}
|
||||
|
||||
gsk_gpu_upload_solid_op (frame,
|
||||
priv->current_atlas->image,
|
||||
&(cairo_rectangle_int_t) { x, y, 5, 5 },
|
||||
&GRAPHENE_POINT_INIT (1, 1));
|
||||
|
||||
priv->current_atlas->colorize_x = x + 2;
|
||||
priv->current_atlas->colorize_y = y + 2;
|
||||
|
||||
priv->current_atlas->has_colorize = TRUE;
|
||||
}
|
||||
|
||||
out_bounds->origin.x = priv->current_atlas->colorize_x;
|
||||
out_bounds->origin.y = priv->current_atlas->colorize_y;
|
||||
out_bounds->size.width = 1;
|
||||
out_bounds->size.height = 1;
|
||||
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -98,6 +98,9 @@ GskGpuImage * gsk_gpu_device_lookup_glyph_image (GskGpuD
|
||||
graphene_rect_t *out_bounds,
|
||||
graphene_point_t *out_origin);
|
||||
|
||||
GskGpuImage * gsk_gpu_device_get_solid_image (GskGpuDevice *self,
|
||||
GskGpuFrame *frame,
|
||||
graphene_rect_t *out_bounds);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuDevice, g_object_unref)
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ struct _GskGpuFramePrivate
|
||||
|
||||
GskGpuOps ops;
|
||||
GskGpuOp *first_op;
|
||||
GskGpuOp *last_op;
|
||||
|
||||
GskGpuBuffer *vertex_buffer;
|
||||
guchar *vertex_buffer_data;
|
||||
@@ -70,6 +71,8 @@ gsk_gpu_frame_default_cleanup (GskGpuFrame *self)
|
||||
gsk_gpu_op_finish (op);
|
||||
}
|
||||
gsk_gpu_ops_set_size (&priv->ops, 0);
|
||||
|
||||
priv->last_op = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -331,7 +334,7 @@ gsk_gpu_frame_sort_ops (GskGpuFrame *self)
|
||||
{
|
||||
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
|
||||
SortData sort_data = { { NULL, }, };
|
||||
|
||||
|
||||
gsk_gpu_frame_sort_render_pass (self, priv->first_op, &sort_data);
|
||||
|
||||
if (sort_data.upload.first)
|
||||
@@ -343,6 +346,8 @@ gsk_gpu_frame_sort_ops (GskGpuFrame *self)
|
||||
priv->first_op = sort_data.command.first;
|
||||
if (sort_data.command.last)
|
||||
sort_data.command.last->next = NULL;
|
||||
|
||||
priv->last_op = NULL;
|
||||
}
|
||||
|
||||
gpointer
|
||||
@@ -360,7 +365,17 @@ gsk_gpu_frame_alloc_op (GskGpuFrame *self,
|
||||
NULL,
|
||||
size);
|
||||
|
||||
return gsk_gpu_ops_index (&priv->ops, pos);
|
||||
priv->last_op = (GskGpuOp *) gsk_gpu_ops_index (&priv->ops, pos);
|
||||
|
||||
return priv->last_op;
|
||||
}
|
||||
|
||||
GskGpuOp *
|
||||
gsk_gpu_frame_get_last_op (GskGpuFrame *self)
|
||||
{
|
||||
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
|
||||
|
||||
return priv->last_op;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
|
||||
@@ -83,6 +83,7 @@ void gsk_gpu_frame_download_texture (GskGpuF
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GskGpuOp *gsk_gpu_frame_get_last_op (GskGpuFrame *self);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuFrame, g_object_unref)
|
||||
|
||||
|
||||
@@ -1775,6 +1775,57 @@ gsk_gpu_node_processor_add_opacity_node (GskGpuNodeProcessor *self,
|
||||
self->opacity = old_opacity;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_color_op (GskGpuNodeProcessor *self,
|
||||
GskGpuShaderClip clip,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskGpuOp *last_op = gsk_gpu_frame_get_last_op (self->frame);
|
||||
|
||||
if (last_op &&
|
||||
last_op->op_class == (const GskGpuOpClass *) &GSK_GPU_COLORIZE_OP_CLASS &&
|
||||
gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_COLORIZE))
|
||||
{
|
||||
GskGpuDevice *device;
|
||||
GskGpuImage *image;
|
||||
guint32 descriptor;
|
||||
graphene_rect_t bounds, tex_rect;
|
||||
|
||||
device = gsk_gpu_frame_get_device (self->frame);
|
||||
image = gsk_gpu_device_get_solid_image (device, self->frame, &bounds);
|
||||
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
|
||||
gsk_rect_scale (&GRAPHENE_RECT_INIT (- bounds.origin.x,
|
||||
- bounds.origin.y,
|
||||
gsk_gpu_image_get_width (image),
|
||||
gsk_gpu_image_get_height (image)),
|
||||
rect->size.width / bounds.size.width,
|
||||
rect->size.height / bounds.size.height,
|
||||
&tex_rect);
|
||||
gsk_rect_init_offset (&tex_rect, &tex_rect, rect->origin.x, rect->origin.y);
|
||||
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
clip,
|
||||
self->desc,
|
||||
descriptor,
|
||||
rect,
|
||||
offset,
|
||||
&tex_rect,
|
||||
color);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_color_op (self->frame,
|
||||
clip,
|
||||
rect,
|
||||
offset,
|
||||
color);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
@@ -1809,11 +1860,11 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
if (self->modelview)
|
||||
{
|
||||
/* Yuck, rounded clip and modelview. I give up. */
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
gsk_color_node_get_color (node));
|
||||
gsk_gpu_node_processor_color_op (self,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
gsk_color_node_get_color (node));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1879,11 +1930,11 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
&GDK_RGBA_INIT_ALPHA (color, self->opacity));
|
||||
gsk_gpu_node_processor_color_op (self,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
&GDK_RGBA_INIT_ALPHA (color, self->opacity));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -31,7 +31,9 @@ static const GdkDebugKey gsk_gpu_optimization_keys[] = {
|
||||
{ "gradients", GSK_GPU_OPTIMIZE_GRADIENTS, "Don't supersample gradients" },
|
||||
{ "mipmap", GSK_GPU_OPTIMIZE_MIPMAP, "Avoid creating mipmaps" },
|
||||
{ "glyph-align", GSK_GPU_OPTIMIZE_GLYPH_ALIGN, "Never align glyphs to the subpixel grid" },
|
||||
{ "colorize", GSK_GPU_OPTIMIZE_COLORIZE, "Don't replace color by colorize" },
|
||||
|
||||
/* These require hardware support */
|
||||
{ "gl-baseinstance", GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE, "Assume no ARB/EXT_base_instance support" },
|
||||
};
|
||||
|
||||
|
||||
@@ -119,7 +119,9 @@ typedef enum {
|
||||
GSK_GPU_OPTIMIZE_GRADIENTS = 1 << 4,
|
||||
GSK_GPU_OPTIMIZE_MIPMAP = 1 << 5,
|
||||
GSK_GPU_OPTIMIZE_GLYPH_ALIGN = 1 << 6,
|
||||
GSK_GPU_OPTIMIZE_COLORIZE = 1 << 7,
|
||||
|
||||
/* These require hardware support */
|
||||
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 7,
|
||||
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 16,
|
||||
} GskGpuOptimizations;
|
||||
|
||||
|
||||
@@ -636,3 +636,134 @@ gsk_gpu_upload_glyph_op (GskGpuFrame *frame,
|
||||
self->glyph = glyph;
|
||||
self->origin = *origin;
|
||||
}
|
||||
|
||||
typedef struct _GskGpuUploadSolidOp GskGpuUploadSolidOp;
|
||||
|
||||
struct _GskGpuUploadSolidOp
|
||||
{
|
||||
GskGpuOp op;
|
||||
|
||||
GskGpuImage *image;
|
||||
cairo_rectangle_int_t area;
|
||||
graphene_point_t origin;
|
||||
|
||||
GskGpuBuffer *buffer;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_upload_solid_op_finish (GskGpuOp *op)
|
||||
{
|
||||
GskGpuUploadSolidOp *self = (GskGpuUploadSolidOp *) op;
|
||||
|
||||
g_object_unref (self->image);
|
||||
|
||||
g_clear_object (&self->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_upload_solid_op_print (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GskGpuUploadSolidOp *self = (GskGpuUploadSolidOp *) op;
|
||||
|
||||
gsk_gpu_print_op (string, indent, "upload-solid");
|
||||
gsk_gpu_print_int_rect (string, &self->area);
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_upload_solid_op_draw (GskGpuOp *op,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GskGpuUploadSolidOp *self = (GskGpuUploadSolidOp *) op;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
self->area.width,
|
||||
self->area.height,
|
||||
stride);
|
||||
cairo_surface_set_device_offset (surface, self->origin.x, self->origin.y);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
/* Make sure the entire surface is initialized to black */
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_rectangle (cr, 0.0, 0.0, self->area.width, self->area.height);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Draw solid */
|
||||
cairo_set_source_rgba (cr, 1, 1, 1, 1);
|
||||
cairo_rectangle (cr, 0, 0, self->area.width, self->area.height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
static GskGpuOp *
|
||||
gsk_gpu_upload_solid_op_vk_command (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GskVulkanCommandState *state)
|
||||
{
|
||||
GskGpuUploadSolidOp *self = (GskGpuUploadSolidOp *) op;
|
||||
|
||||
return gsk_gpu_upload_op_vk_command_with_area (op,
|
||||
frame,
|
||||
state,
|
||||
GSK_VULKAN_IMAGE (self->image),
|
||||
&self->area,
|
||||
gsk_gpu_upload_solid_op_draw,
|
||||
&self->buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
static GskGpuOp *
|
||||
gsk_gpu_upload_solid_op_gl_command (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GskGLCommandState *state)
|
||||
{
|
||||
GskGpuUploadSolidOp *self = (GskGpuUploadSolidOp *) op;
|
||||
|
||||
return gsk_gpu_upload_op_gl_command_with_area (op,
|
||||
frame,
|
||||
self->image,
|
||||
&self->area,
|
||||
gsk_gpu_upload_solid_op_draw);
|
||||
}
|
||||
|
||||
static const GskGpuOpClass GSK_GPU_UPLOAD_SOLID_OP_CLASS = {
|
||||
GSK_GPU_OP_SIZE (GskGpuUploadSolidOp),
|
||||
GSK_GPU_STAGE_UPLOAD,
|
||||
gsk_gpu_upload_solid_op_finish,
|
||||
gsk_gpu_upload_solid_op_print,
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
gsk_gpu_upload_solid_op_vk_command,
|
||||
#endif
|
||||
gsk_gpu_upload_solid_op_gl_command,
|
||||
};
|
||||
|
||||
void
|
||||
gsk_gpu_upload_solid_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
const cairo_rectangle_int_t *area,
|
||||
const graphene_point_t *origin)
|
||||
{
|
||||
GskGpuUploadSolidOp *self;
|
||||
|
||||
self = (GskGpuUploadSolidOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_UPLOAD_SOLID_OP_CLASS);
|
||||
|
||||
self->image = g_object_ref (image);
|
||||
self->area = *area;
|
||||
self->origin = *origin;
|
||||
}
|
||||
|
||||
@@ -27,5 +27,9 @@ void gsk_gpu_upload_glyph_op (GskGpuF
|
||||
const cairo_rectangle_int_t *area,
|
||||
const graphene_point_t *origin);
|
||||
|
||||
void gsk_gpu_upload_solid_op (GskGpuFrame *frame,
|
||||
GskGpuImage *image,
|
||||
const cairo_rectangle_int_t *area,
|
||||
const graphene_point_t *origin);
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user