gpu: Add gsk_gpu_image_get_projection_matrix()

... and use it to initialize the "proper" projection matrix to use in
shaders.

The resulting viewport will go from top left (0,0) to bottom right
(width, height) and the z clipping plane will go from -10000 to 10000.
This commit is contained in:
Benjamin Otte 2023-08-24 03:15:01 +02:00
parent 1152c93778
commit 286b473f55
5 changed files with 76 additions and 15 deletions

View File

@ -26,6 +26,18 @@ struct _GskGLImageClass
G_DEFINE_TYPE (GskGLImage, gsk_gl_image, GSK_TYPE_GPU_IMAGE)
static void
gsk_gl_image_get_projection_matrix (GskGpuImage *image,
graphene_matrix_t *out_projection)
{
GskGLImage *self = GSK_GL_IMAGE (image);
GSK_GPU_IMAGE_CLASS (gsk_gl_image_parent_class)->get_projection_matrix (image, out_projection);
if (self->texture_id == 0)
graphene_matrix_scale (out_projection, 1.f, -1.f, 1.f);
}
static void
gsk_gl_image_finalize (GObject *object)
{
@ -43,8 +55,11 @@ gsk_gl_image_finalize (GObject *object)
static void
gsk_gl_image_class_init (GskGLImageClass *klass)
{
GskGpuImageClass *image_class = GSK_GPU_IMAGE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
image_class->get_projection_matrix = gsk_gl_image_get_projection_matrix;
object_class->finalize = gsk_gl_image_finalize;
}

View File

@ -11,11 +11,28 @@ struct _GskGpuImagePrivate
gsize height;
};
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuImage, gsk_gpu_image, G_TYPE_OBJECT)
static void
gsk_gpu_image_get_default_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection)
{
GskGpuImagePrivate *priv = gsk_gpu_image_get_instance_private (self);
graphene_matrix_init_ortho (out_projection,
0, priv->width,
0, priv->height,
ORTHO_NEAR_PLANE,
ORTHO_FAR_PLANE);
}
static void
gsk_gpu_image_class_init (GskGpuImageClass *klass)
{
klass->get_projection_matrix = gsk_gpu_image_get_default_projection_matrix;
}
static void
@ -60,3 +77,9 @@ gsk_gpu_image_get_height (GskGpuImage *self)
return priv->height;
}
void
gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection)
{
GSK_GPU_IMAGE_GET_CLASS (self)->get_projection_matrix (self, out_projection);
}

View File

@ -2,6 +2,8 @@
#include "gskgputypesprivate.h"
#include <graphene.h>
G_BEGIN_DECLS
#define GSK_TYPE_GPU_IMAGE (gsk_gpu_image_get_type ())
@ -21,6 +23,9 @@ struct _GskGpuImage
struct _GskGpuImageClass
{
GObjectClass parent_class;
void (* get_projection_matrix) (GskGpuImage *self,
graphene_matrix_t *out_projection);
};
GType gsk_gpu_image_get_type (void) G_GNUC_CONST;
@ -34,6 +39,9 @@ GdkMemoryFormat gsk_gpu_image_get_format (GskGpuI
gsize gsk_gpu_image_get_width (GskGpuImage *self);
gsize gsk_gpu_image_get_height (GskGpuImage *self);
void gsk_gpu_image_get_projection_matrix (GskGpuImage *self,
graphene_matrix_t *out_projection);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskGpuImage, g_object_unref)

View File

@ -14,9 +14,6 @@
#include "gskroundedrectprivate.h"
#include "gsktransformprivate.h"
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
typedef struct _GskGpuNodeProcessor GskGpuNodeProcessor;
typedef enum {
@ -51,8 +48,7 @@ gsk_gpu_node_processor_finish (GskGpuNodeProcessor *self)
static void
gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
GskGpuFrame *frame,
gsize width,
gsize height,
GskGpuImage *target,
const cairo_rectangle_int_t *clip,
const graphene_rect_t *viewport)
{
@ -62,13 +58,9 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
gsk_gpu_clip_init_empty (&self->clip, &GRAPHENE_RECT_INIT (0, 0, viewport->size.width, viewport->size.height));
self->modelview = NULL;
graphene_matrix_init_ortho (&self->projection,
0, width,
0, height,
2 * ORTHO_NEAR_PLANE - ORTHO_FAR_PLANE,
ORTHO_FAR_PLANE);
graphene_vec2_init (&self->scale, width / viewport->size.width,
height / viewport->size.height);
gsk_gpu_image_get_projection_matrix (target, &self->projection);
graphene_vec2_init (&self->scale, gsk_gpu_image_get_width (target) / viewport->size.width,
gsk_gpu_image_get_height (target) / viewport->size.height);
self->offset = GRAPHENE_POINT_INIT (-viewport->origin.x,
-viewport->origin.y);
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP;
@ -106,8 +98,7 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
gsk_gpu_node_processor_init (&self,
frame,
gsk_gpu_image_get_width (target),
gsk_gpu_image_get_height (target),
target,
clip,
viewport);

View File

@ -785,6 +785,25 @@ gsk_vulkan_image_new_for_offscreen (GskVulkanDevice *device,
return GSK_GPU_IMAGE (self);
}
static void
gsk_vulkan_image_get_projection_matrix (GskGpuImage *image,
graphene_matrix_t *out_projection)
{
graphene_matrix_t scale_z;
GSK_GPU_IMAGE_CLASS (gsk_vulkan_image_parent_class)->get_projection_matrix (image, out_projection);
graphene_matrix_init_from_float (&scale_z,
(float[16]) {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0.5, 0,
0, 0, 0.5, 1
});
graphene_matrix_multiply (out_projection, &scale_z, out_projection);
}
static void
gsk_vulkan_image_finalize (GObject *object)
{
@ -817,7 +836,12 @@ gsk_vulkan_image_finalize (GObject *object)
static void
gsk_vulkan_image_class_init (GskVulkanImageClass *klass)
{
G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_image_finalize;
GskGpuImageClass *image_class = GSK_GPU_IMAGE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
image_class->get_projection_matrix = gsk_vulkan_image_get_projection_matrix;
object_class->finalize = gsk_vulkan_image_finalize;
}
static void