[gtk/wip/chergert/glproto: 560/920] sketch out some real basics for drawing
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto: 560/920] sketch out some real basics for drawing
- Date: Mon, 8 Feb 2021 19:15:28 +0000 (UTC)
commit aabbe8e1f0fa995842597149c54113315563e8e7
Author: Christian Hergert <chergert redhat com>
Date: Wed Dec 23 17:06:54 2020 -0800
sketch out some real basics for drawing
gsk/next/gskglcommandqueue.c | 123 +++++++++++++++++++++++++++++++++++++++++
gsk/next/gskglprogram.c | 9 ---
gsk/next/gskglprogramprivate.h | 2 -
gsk/next/gskglrenderjob.c | 61 +++++++++++++++++++-
4 files changed, 183 insertions(+), 12 deletions(-)
---
diff --git a/gsk/next/gskglcommandqueue.c b/gsk/next/gskglcommandqueue.c
index e815bbba21..5b9bec3664 100644
--- a/gsk/next/gskglcommandqueue.c
+++ b/gsk/next/gskglcommandqueue.c
@@ -756,6 +756,94 @@ gsk_gl_command_queue_set_uniform_rounded_rect (GskGLCommandQueue *self,
rounded_rect);
}
+static void
+apply_uniform (GskGLUniformState *state,
+ const GskGLUniformInfo *info,
+ guint location)
+{
+ const union {
+ graphene_matrix_t matrix[0];
+ GskRoundedRect rounded_rect[0];
+ float fval[0];
+ int ival[0];
+ } *data;
+
+ data = gsk_gl_uniform_state_get_uniform_data (state, info->offset);
+
+ switch (info->format)
+ {
+ case GSK_GL_UNIFORM_FORMAT_1F:
+ glUniform1f (location, data->fval[0]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_2F:
+ glUniform2f (location, data->fval[0], data->fval[1]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_3F:
+ glUniform3f (location, data->fval[0], data->fval[1], data->fval[2]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_4F:
+ glUniform4f (location, data->fval[0], data->fval[1], data->fval[2], data->fval[3]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_1FV:
+ glUniform1fv (location, info->array_count, data->fval);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_2FV:
+ glUniform2fv (location, info->array_count, data->fval);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_3FV:
+ glUniform3fv (location, info->array_count, data->fval);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_4FV:
+ glUniform4fv (location, info->array_count, data->fval);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_1I:
+ case GSK_GL_UNIFORM_FORMAT_TEXTURE:
+ glUniform1i (location, data->ival[0]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_2I:
+ glUniform2i (location, data->ival[0], data->ival[1]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_3I:
+ glUniform3i (location, data->ival[0], data->ival[1], data->ival[2]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_4I:
+ glUniform4i (location, data->ival[0], data->ival[1], data->ival[2], data->ival[3]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_MATRIX: {
+ float mat[16];
+ graphene_matrix_to_float (&data->matrix[0], mat);
+ glUniformMatrix4fv (location, 1, GL_FALSE, mat);
+ break;
+ }
+
+ case GSK_GL_UNIFORM_FORMAT_COLOR:
+ glUniform4fv (location, 1, &data->fval[0]);
+ break;
+
+ case GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT:
+ if (info->flags & GSK_GL_UNIFORM_FLAGS_SEND_CORNERS)
+ glUniform4fv (location, 3, (const float *)&data->rounded_rect[0]);
+ else
+ glUniform4fv (location, 1, (const float *)&data->rounded_rect[0]);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
/**
* gsk_gl_command_queue_execute:
* @self: a #GskGLCommandQueue
@@ -765,6 +853,7 @@ gsk_gl_command_queue_set_uniform_rounded_rect (GskGLCommandQueue *self,
void
gsk_gl_command_queue_execute (GskGLCommandQueue *self)
{
+ GLuint framebuffer = 0;
GLuint vao_id;
int next_batch_index;
@@ -801,6 +890,9 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self)
sizeof (GskGLDrawVertex),
(void *) G_STRUCT_OFFSET (GskGLDrawVertex, uv));
+ /* Start with default framebuffer */
+ glBindFramebuffer (GL_FRAMEBUFFER, 0);
+
next_batch_index = 0;
while (next_batch_index >= 0)
@@ -822,6 +914,37 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self)
break;
case GSK_GL_COMMAND_KIND_DRAW:
+ if (batch->draw.framebuffer != framebuffer)
+ {
+ framebuffer = batch->draw.framebuffer;
+ glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+ }
+
+ if (batch->draw.bind_count > 0)
+ {
+ for (guint i = 0; i < batch->draw.bind_count; i++)
+ {
+ guint index = batch->draw.bind_offset + i;
+ GskGLCommandBind *bind = &g_array_index (self->batch_binds, GskGLCommandBind, index);
+
+ glActiveTexture (GL_TEXTURE0 + bind->texture);
+ glBindTexture (GL_TEXTURE_2D, bind->id);
+ }
+ }
+
+ if (batch->draw.uniform_count > 0)
+ {
+ for (guint i = 0; i < batch->draw.uniform_count; i++)
+ {
+ guint index = batch->draw.uniform_offset + i;
+ GskGLCommandUniform *u = &g_array_index (self->batch_uniforms, GskGLCommandUniform, index);
+
+ apply_uniform (self->uniforms, &u->info, u->location);
+ }
+ }
+
+ glDrawArrays (GL_TRIANGLES, batch->draw.vbo_offset, batch->draw.vbo_count);
+
break;
default:
diff --git a/gsk/next/gskglprogram.c b/gsk/next/gskglprogram.c
index e6280c6574..9a6b4bbac4 100644
--- a/gsk/next/gskglprogram.c
+++ b/gsk/next/gskglprogram.c
@@ -337,12 +337,3 @@ gsk_gl_program_end_draw (GskGLProgram *self)
return gsk_gl_command_queue_end_draw (self->command_queue);
}
-
-GskGLDrawVertex *
-gsk_gl_program_add_vertices (GskGLProgram *self,
- const GskGLDrawVertex vertices[GSK_GL_N_VERTICES])
-{
- g_assert (GSK_IS_GL_PROGRAM (self));
-
- return gsk_gl_command_queue_add_vertices (self->command_queue, vertices);
-}
diff --git a/gsk/next/gskglprogramprivate.h b/gsk/next/gskglprogramprivate.h
index 42c41e2850..a8d047c214 100644
--- a/gsk/next/gskglprogramprivate.h
+++ b/gsk/next/gskglprogramprivate.h
@@ -85,8 +85,6 @@ void gsk_gl_program_set_uniform_rounded_rect (GskGLProgram
const GskRoundedRect *rounded_rect);
void gsk_gl_program_begin_draw (GskGLProgram *self);
void gsk_gl_program_end_draw (GskGLProgram *self);
-GskGLDrawVertex *gsk_gl_program_add_vertices (GskGLProgram *self,
- const GskGLDrawVertex
vertices[GSK_GL_N_VERTICES]);
G_END_DECLS
diff --git a/gsk/next/gskglrenderjob.c b/gsk/next/gskglrenderjob.c
index 311ebfd0e2..d30edff90b 100644
--- a/gsk/next/gskglrenderjob.c
+++ b/gsk/next/gskglrenderjob.c
@@ -30,6 +30,7 @@
#include "gskglcommandqueueprivate.h"
#include "gskgldriverprivate.h"
+#include "gskglprogramprivate.h"
#include "gskglrenderjobprivate.h"
#define ORTHO_NEAR_PLANE -10000
@@ -438,10 +439,55 @@ gsk_gl_render_job_node_overlaps_clip (GskGLRenderJob *job,
return rect_intersects (&clip->rect.bounds, &transformed_bounds);
}
+static void
+gsk_gl_render_job_draw_rect (GskGLRenderJob *job,
+ graphene_rect_t *rect)
+{
+ GskGLDrawVertex *vertices;
+ const float min_x = job->offset_x + rect->origin.x;
+ const float min_y = job->offset_y + rect->origin.y;
+ const float max_x = min_x + rect->size.width;
+ const float max_y = min_y + rect->size.height;
+
+ vertices = gsk_gl_command_queue_add_vertices (job->command_queue, NULL);
+
+ vertices[0].position[0] = min_x;
+ vertices[0].position[1] = min_y;
+ vertices[0].uv[0] = 0;
+ vertices[0].uv[1] = 0;
+
+ vertices[1].position[0] = min_x;
+ vertices[1].position[1] = max_y;
+ vertices[1].uv[0] = 0;
+ vertices[1].uv[1] = 1;
+
+ vertices[2].position[0] = max_x;
+ vertices[2].position[1] = min_y;
+ vertices[2].uv[0] = 1;
+ vertices[2].uv[1] = 0;
+
+ vertices[3].position[0] = max_x;
+ vertices[3].position[1] = max_y;
+ vertices[3].uv[0] = 1;
+ vertices[3].uv[1] = 1;
+
+ vertices[4].position[0] = min_x;
+ vertices[4].position[1] = max_y;
+ vertices[4].uv[0] = 0;
+ vertices[4].uv[1] = 1;
+
+ vertices[5].position[0] = max_x;
+ vertices[5].position[1] = min_y;
+ vertices[5].uv[0] = 1;
+ vertices[5].uv[1] = 0;
+}
+
static void
gsk_gl_render_job_visit_node (GskGLRenderJob *job,
GskRenderNode *node)
{
+ GskGLProgram *program;
+
g_assert (job != NULL);
g_assert (node != NULL);
g_assert (GSK_IS_NEXT_DRIVER (job->driver));
@@ -482,8 +528,21 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
}
break;
- case GSK_CAIRO_NODE:
case GSK_COLOR_NODE:
+ program = job->driver->color;
+
+ /* TODO: determine how we want to update mv/projection */
+ /* TODO: and how about change_viewport()? */
+
+ gsk_gl_program_begin_draw (program);
+ gsk_gl_program_set_uniform_color (program,
+ UNIFORM_COLOR_COLOR,
+ gsk_color_node_get_color (node));
+ gsk_gl_render_job_draw_rect (job, &node->bounds);
+ gsk_gl_program_end_draw (program);
+ break;
+
+ case GSK_CAIRO_NODE:
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]