[gtk/wip/chergert/glproto: 51/69] sketch out some real basics for drawing




commit 44a5a5e63476ec8ec14953d1f485396457710f8a
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]