mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
Merge branch 'ngl-is-the-new-gl' into 'master'
Rename ngl to gl Closes #4318 See merge request GNOME/gtk!4037
This commit is contained in:
commit
49a64da7ec
@ -24,7 +24,7 @@
|
|||||||
#include "gtkrendererpaintableprivate.h"
|
#include "gtkrendererpaintableprivate.h"
|
||||||
|
|
||||||
#include "gsk/gskrendernodeparserprivate.h"
|
#include "gsk/gskrendernodeparserprivate.h"
|
||||||
#include "gsk/ngl/gsknglrenderer.h"
|
#include "gsk/gl/gskglrenderer.h"
|
||||||
#ifdef GDK_WINDOWING_BROADWAY
|
#ifdef GDK_WINDOWING_BROADWAY
|
||||||
#include "gsk/broadway/gskbroadwayrenderer.h"
|
#include "gsk/broadway/gskbroadwayrenderer.h"
|
||||||
#endif
|
#endif
|
||||||
@ -872,7 +872,7 @@ node_editor_window_realize (GtkWidget *widget)
|
|||||||
"Default");
|
"Default");
|
||||||
#endif
|
#endif
|
||||||
node_editor_window_add_renderer (self,
|
node_editor_window_add_renderer (self,
|
||||||
gsk_ngl_renderer_new (),
|
gsk_gl_renderer_new (),
|
||||||
"OpenGL");
|
"OpenGL");
|
||||||
#ifdef GDK_RENDERING_VULKAN
|
#ifdef GDK_RENDERING_VULKAN
|
||||||
node_editor_window_add_renderer (self,
|
node_editor_window_add_renderer (self,
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "gdkmemoryformatprivate.h"
|
#include "gdkmemoryformatprivate.h"
|
||||||
|
|
||||||
#include "gsk/ngl/fp16private.h"
|
#include "gsk/gl/fp16private.h"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "gdkmemorytextureprivate.h"
|
#include "gdkmemorytextureprivate.h"
|
||||||
|
|
||||||
#include "gdkmemoryformatprivate.h"
|
#include "gdkmemoryformatprivate.h"
|
||||||
#include "gsk/ngl/fp16private.h"
|
#include "gsk/gl/fp16private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GdkMemoryTexture:
|
* GdkMemoryTexture:
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "gdkprofilerprivate.h"
|
#include "gdkprofilerprivate.h"
|
||||||
#include "gdktexture.h"
|
#include "gdktexture.h"
|
||||||
#include "gdktextureprivate.h"
|
#include "gdktextureprivate.h"
|
||||||
#include "gsk/ngl/fp16private.h"
|
#include "gsk/gl/fp16private.h"
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglattachmentstate.c
|
/* gskglattachmentstate.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -20,14 +20,14 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gsknglattachmentstateprivate.h"
|
#include "gskglattachmentstateprivate.h"
|
||||||
|
|
||||||
GskNglAttachmentState *
|
GskGLAttachmentState *
|
||||||
gsk_ngl_attachment_state_new (void)
|
gsk_gl_attachment_state_new (void)
|
||||||
{
|
{
|
||||||
GskNglAttachmentState *self;
|
GskGLAttachmentState *self;
|
||||||
|
|
||||||
self = g_atomic_rc_box_new0 (GskNglAttachmentState);
|
self = g_atomic_rc_box_new0 (GskGLAttachmentState);
|
||||||
|
|
||||||
self->fbo.changed = FALSE;
|
self->fbo.changed = FALSE;
|
||||||
self->fbo.id = 0;
|
self->fbo.id = 0;
|
||||||
@ -49,25 +49,25 @@ gsk_ngl_attachment_state_new (void)
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglAttachmentState *
|
GskGLAttachmentState *
|
||||||
gsk_ngl_attachment_state_ref (GskNglAttachmentState *self)
|
gsk_gl_attachment_state_ref (GskGLAttachmentState *self)
|
||||||
{
|
{
|
||||||
return g_atomic_rc_box_acquire (self);
|
return g_atomic_rc_box_acquire (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_attachment_state_unref (GskNglAttachmentState *self)
|
gsk_gl_attachment_state_unref (GskGLAttachmentState *self)
|
||||||
{
|
{
|
||||||
g_atomic_rc_box_release (self);
|
g_atomic_rc_box_release (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_attachment_state_bind_texture (GskNglAttachmentState *self,
|
gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
GLenum texture,
|
GLenum texture,
|
||||||
guint id)
|
guint id)
|
||||||
{
|
{
|
||||||
GskNglBindTexture *attach;
|
GskGLBindTexture *attach;
|
||||||
|
|
||||||
g_assert (self != NULL);
|
g_assert (self != NULL);
|
||||||
g_assert (target == GL_TEXTURE_1D ||
|
g_assert (target == GL_TEXTURE_1D ||
|
||||||
@ -93,8 +93,8 @@ gsk_ngl_attachment_state_bind_texture (GskNglAttachmentState *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_attachment_state_bind_framebuffer (GskNglAttachmentState *self,
|
gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
|
||||||
guint id)
|
guint id)
|
||||||
{
|
{
|
||||||
g_assert (self != NULL);
|
g_assert (self != NULL);
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglattachmentstateprivate.h
|
/* gskglattachmentstateprivate.h
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -18,18 +18,18 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GSK_NGL_ATTACHMENT_STATE_PRIVATE_H__
|
#ifndef __GSK_GL_ATTACHMENT_STATE_PRIVATE_H__
|
||||||
#define __GSK_NGL_ATTACHMENT_STATE_PRIVATE_H__
|
#define __GSK_GL_ATTACHMENT_STATE_PRIVATE_H__
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GskNglAttachmentState GskNglAttachmentState;
|
typedef struct _GskGLAttachmentState GskGLAttachmentState;
|
||||||
typedef struct _GskNglBindFramebuffer GskNglBindFramebuffer;
|
typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
|
||||||
typedef struct _GskNglBindTexture GskNglBindTexture;
|
typedef struct _GskGLBindTexture GskGLBindTexture;
|
||||||
|
|
||||||
struct _GskNglBindTexture
|
struct _GskGLBindTexture
|
||||||
{
|
{
|
||||||
guint changed : 1;
|
guint changed : 1;
|
||||||
guint initial : 1;
|
guint initial : 1;
|
||||||
@ -38,34 +38,34 @@ struct _GskNglBindTexture
|
|||||||
guint id;
|
guint id;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglBindTexture) == 12);
|
G_STATIC_ASSERT (sizeof (GskGLBindTexture) == 12);
|
||||||
|
|
||||||
struct _GskNglBindFramebuffer
|
struct _GskGLBindFramebuffer
|
||||||
{
|
{
|
||||||
guint changed : 1;
|
guint changed : 1;
|
||||||
guint id : 31;
|
guint id : 31;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglBindFramebuffer) == 4);
|
G_STATIC_ASSERT (sizeof (GskGLBindFramebuffer) == 4);
|
||||||
|
|
||||||
struct _GskNglAttachmentState
|
struct _GskGLAttachmentState
|
||||||
{
|
{
|
||||||
GskNglBindFramebuffer fbo;
|
GskGLBindFramebuffer fbo;
|
||||||
/* Increase if shaders add more textures */
|
/* Increase if shaders add more textures */
|
||||||
GskNglBindTexture textures[4];
|
GskGLBindTexture textures[4];
|
||||||
guint n_changed;
|
guint n_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
GskNglAttachmentState *gsk_ngl_attachment_state_new (void);
|
GskGLAttachmentState *gsk_gl_attachment_state_new (void);
|
||||||
GskNglAttachmentState *gsk_ngl_attachment_state_ref (GskNglAttachmentState *self);
|
GskGLAttachmentState *gsk_gl_attachment_state_ref (GskGLAttachmentState *self);
|
||||||
void gsk_ngl_attachment_state_unref (GskNglAttachmentState *self);
|
void gsk_gl_attachment_state_unref (GskGLAttachmentState *self);
|
||||||
void gsk_ngl_attachment_state_bind_texture (GskNglAttachmentState *self,
|
void gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
GLenum texture,
|
GLenum texture,
|
||||||
guint id);
|
guint id);
|
||||||
void gsk_ngl_attachment_state_bind_framebuffer (GskNglAttachmentState *self,
|
void gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
|
||||||
guint id);
|
guint id);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GSK_NGL_ATTACHMENT_STATE_PRIVATE_H__ */
|
#endif /* __GSK_GL_ATTACHMENT_STATE_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglbufferprivate.h
|
/* gskglbufferprivate.h
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -22,21 +22,21 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gsknglbufferprivate.h"
|
#include "gskglbufferprivate.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_ngl_buffer_init:
|
* gsk_gl_buffer_init:
|
||||||
* @target: the target buffer such as %GL_ARRAY_BUFFER or %GL_UNIFORM_BUFFER
|
* @target: the target buffer such as %GL_ARRAY_BUFFER or %GL_UNIFORM_BUFFER
|
||||||
* @element_size: the size of elements within the buffer
|
* @element_size: the size of elements within the buffer
|
||||||
*
|
*
|
||||||
* Creates a new `GskNglBuffer` which can be used to deliver data to shaders
|
* Creates a new `GskGLBuffer` which can be used to deliver data to shaders
|
||||||
* within a GLSL program. You can use this to store vertices such as with
|
* within a GLSL program. You can use this to store vertices such as with
|
||||||
* %GL_ARRAY_BUFFER or uniform data with %GL_UNIFORM_BUFFER.
|
* %GL_ARRAY_BUFFER or uniform data with %GL_UNIFORM_BUFFER.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gsk_ngl_buffer_init (GskNglBuffer *self,
|
gsk_gl_buffer_init (GskGLBuffer *self,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
guint element_size)
|
guint element_size)
|
||||||
{
|
{
|
||||||
memset (self, 0, sizeof *self);
|
memset (self, 0, sizeof *self);
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ gsk_ngl_buffer_init (GskNglBuffer *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLuint
|
GLuint
|
||||||
gsk_ngl_buffer_submit (GskNglBuffer *buffer)
|
gsk_gl_buffer_submit (GskGLBuffer *buffer)
|
||||||
{
|
{
|
||||||
GLuint id;
|
GLuint id;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ gsk_ngl_buffer_submit (GskNglBuffer *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_buffer_destroy (GskNglBuffer *buffer)
|
gsk_gl_buffer_destroy (GskGLBuffer *buffer)
|
||||||
{
|
{
|
||||||
g_clear_pointer (&buffer->buffer, g_free);
|
g_clear_pointer (&buffer->buffer, g_free);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglbufferprivate.h
|
/* gskglbufferprivate.h
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -18,14 +18,14 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GSK_NGL_BUFFER_PRIVATE_H__
|
#ifndef __GSK_GL_BUFFER_PRIVATE_H__
|
||||||
#define __GSK_NGL_BUFFER_PRIVATE_H__
|
#define __GSK_GL_BUFFER_PRIVATE_H__
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GskNglBuffer
|
typedef struct _GskGLBuffer
|
||||||
{
|
{
|
||||||
guint8 *buffer;
|
guint8 *buffer;
|
||||||
gsize buffer_pos;
|
gsize buffer_pos;
|
||||||
@ -33,17 +33,17 @@ typedef struct _GskNglBuffer
|
|||||||
guint count;
|
guint count;
|
||||||
GLenum target;
|
GLenum target;
|
||||||
gsize element_size;
|
gsize element_size;
|
||||||
} GskNglBuffer;
|
} GskGLBuffer;
|
||||||
|
|
||||||
void gsk_ngl_buffer_init (GskNglBuffer *self,
|
void gsk_gl_buffer_init (GskGLBuffer *self,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
guint element_size);
|
guint element_size);
|
||||||
void gsk_ngl_buffer_destroy (GskNglBuffer *buffer);
|
void gsk_gl_buffer_destroy (GskGLBuffer *buffer);
|
||||||
GLuint gsk_ngl_buffer_submit (GskNglBuffer *buffer);
|
GLuint gsk_gl_buffer_submit (GskGLBuffer *buffer);
|
||||||
|
|
||||||
static inline gpointer
|
static inline gpointer
|
||||||
gsk_ngl_buffer_advance (GskNglBuffer *buffer,
|
gsk_gl_buffer_advance (GskGLBuffer *buffer,
|
||||||
guint count)
|
guint count)
|
||||||
{
|
{
|
||||||
gpointer ret;
|
gpointer ret;
|
||||||
gsize to_alloc = count * buffer->element_size;
|
gsize to_alloc = count * buffer->element_size;
|
||||||
@ -64,19 +64,19 @@ gsk_ngl_buffer_advance (GskNglBuffer *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gsk_ngl_buffer_retract (GskNglBuffer *buffer,
|
gsk_gl_buffer_retract (GskGLBuffer *buffer,
|
||||||
guint count)
|
guint count)
|
||||||
{
|
{
|
||||||
buffer->buffer_pos -= count * buffer->element_size;
|
buffer->buffer_pos -= count * buffer->element_size;
|
||||||
buffer->count -= count;
|
buffer->count -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline guint
|
static inline guint
|
||||||
gsk_ngl_buffer_get_offset (GskNglBuffer *buffer)
|
gsk_gl_buffer_get_offset (GskGLBuffer *buffer)
|
||||||
{
|
{
|
||||||
return buffer->count;
|
return buffer->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GSK_NGL_BUFFER_PRIVATE_H__ */
|
#endif /* __GSK_GL_BUFFER_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
362
gsk/gl/gskglcommandqueueprivate.h
Normal file
362
gsk/gl/gskglcommandqueueprivate.h
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
/* gskglcommandqueueprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_COMMAND_QUEUE_PRIVATE_H__
|
||||||
|
#define __GSK_GL_COMMAND_QUEUE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <gsk/gskprofilerprivate.h>
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
#include "gskglbufferprivate.h"
|
||||||
|
#include "gskglattachmentstateprivate.h"
|
||||||
|
#include "gskgluniformstateprivate.h"
|
||||||
|
|
||||||
|
#include "inlinearray.h"
|
||||||
|
|
||||||
|
#include "gskglprofilerprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_COMMAND_QUEUE (gsk_gl_command_queue_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLCommandQueue, gsk_gl_command_queue, GSK, GL_COMMAND_QUEUE, GObject)
|
||||||
|
|
||||||
|
typedef enum _GskGLCommandKind
|
||||||
|
{
|
||||||
|
/* The batch will perform a glClear() */
|
||||||
|
GSK_GL_COMMAND_KIND_CLEAR,
|
||||||
|
|
||||||
|
/* The batch will perform a glDrawArrays() */
|
||||||
|
GSK_GL_COMMAND_KIND_DRAW,
|
||||||
|
} GskGLCommandKind;
|
||||||
|
|
||||||
|
typedef struct _GskGLCommandBind
|
||||||
|
{
|
||||||
|
/* @texture is the value passed to glActiveTexture(), the "slot" the
|
||||||
|
* texture will be placed into. We always use GL_TEXTURE_2D so we don't
|
||||||
|
* waste any bits here to indicate that.
|
||||||
|
*/
|
||||||
|
guint texture : 5;
|
||||||
|
|
||||||
|
/* The identifier for the texture created with glGenTextures(). */
|
||||||
|
guint id : 27;
|
||||||
|
} GskGLCommandBind;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandBind) == 4);
|
||||||
|
|
||||||
|
typedef struct _GskGLCommandBatchAny
|
||||||
|
{
|
||||||
|
/* A GskGLCommandKind indicating what the batch will do */
|
||||||
|
guint kind : 8;
|
||||||
|
|
||||||
|
/* The program's identifier to use for determining if we can merge two
|
||||||
|
* batches together into a single set of draw operations. We put this
|
||||||
|
* here instead of the GskGLCommandDraw so that we can use the extra
|
||||||
|
* bits here without making the structure larger.
|
||||||
|
*/
|
||||||
|
guint program : 24;
|
||||||
|
|
||||||
|
/* The index of the next batch following this one. This is used
|
||||||
|
* as a sort of integer-based linked list to simplify out-of-order
|
||||||
|
* batching without moving memory around. -1 indicates last batch.
|
||||||
|
*/
|
||||||
|
gint16 next_batch_index;
|
||||||
|
|
||||||
|
/* Same but for reverse direction as we sort in reverse to get the
|
||||||
|
* batches ordered by framebuffer.
|
||||||
|
*/
|
||||||
|
gint16 prev_batch_index;
|
||||||
|
|
||||||
|
/* The viewport size of the batch. We check this as we process
|
||||||
|
* batches to determine if we need to resize the viewport.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
guint16 width;
|
||||||
|
guint16 height;
|
||||||
|
} viewport;
|
||||||
|
} GskGLCommandBatchAny;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandBatchAny) == 12);
|
||||||
|
|
||||||
|
typedef struct _GskGLCommandDraw
|
||||||
|
{
|
||||||
|
GskGLCommandBatchAny head;
|
||||||
|
|
||||||
|
/* There doesn't seem to be a limit on the framebuffer identifier that
|
||||||
|
* can be returned, so we have to use a whole unsigned for the framebuffer
|
||||||
|
* we are drawing to. When processing batches, we check to see if this
|
||||||
|
* changes and adjust the render target accordingly. Some sorting is
|
||||||
|
* performed to reduce the amount we change framebuffers.
|
||||||
|
*/
|
||||||
|
guint framebuffer;
|
||||||
|
|
||||||
|
/* The number of uniforms to change. This must be less than or equal to
|
||||||
|
* GL_MAX_UNIFORM_LOCATIONS but only guaranteed up to 1024 by any OpenGL
|
||||||
|
* implementation to be conformant.
|
||||||
|
*/
|
||||||
|
guint uniform_count : 11;
|
||||||
|
|
||||||
|
/* The number of textures to bind, which is only guaranteed up to 16
|
||||||
|
* by the OpenGL specification to be conformant.
|
||||||
|
*/
|
||||||
|
guint bind_count : 5;
|
||||||
|
|
||||||
|
/* GL_MAX_ELEMENTS_VERTICES specifies 33000 for this which requires 16-bit
|
||||||
|
* to address all possible counts <= GL_MAX_ELEMENTS_VERTICES.
|
||||||
|
*/
|
||||||
|
guint vbo_count : 16;
|
||||||
|
|
||||||
|
/* The offset within the VBO containing @vbo_count vertices to send with
|
||||||
|
* glDrawArrays().
|
||||||
|
*/
|
||||||
|
guint vbo_offset;
|
||||||
|
|
||||||
|
/* The offset within the array of uniform changes to be made containing
|
||||||
|
* @uniform_count `GskGLCommandUniform` elements to apply.
|
||||||
|
*/
|
||||||
|
guint uniform_offset;
|
||||||
|
|
||||||
|
/* The offset within the array of bind changes to be made containing
|
||||||
|
* @bind_count `GskGLCommandBind` elements to apply.
|
||||||
|
*/
|
||||||
|
guint bind_offset;
|
||||||
|
} GskGLCommandDraw;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandDraw) == 32);
|
||||||
|
|
||||||
|
typedef struct _GskGLCommandClear
|
||||||
|
{
|
||||||
|
GskGLCommandBatchAny any;
|
||||||
|
guint bits;
|
||||||
|
guint framebuffer;
|
||||||
|
} GskGLCommandClear;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandClear) == 20);
|
||||||
|
|
||||||
|
typedef struct _GskGLCommandUniform
|
||||||
|
{
|
||||||
|
GskGLUniformInfo info;
|
||||||
|
guint location;
|
||||||
|
} GskGLCommandUniform;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandUniform) == 8);
|
||||||
|
|
||||||
|
typedef union _GskGLCommandBatch
|
||||||
|
{
|
||||||
|
GskGLCommandBatchAny any;
|
||||||
|
GskGLCommandDraw draw;
|
||||||
|
GskGLCommandClear clear;
|
||||||
|
} GskGLCommandBatch;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLCommandBatch) == 32);
|
||||||
|
|
||||||
|
DEFINE_INLINE_ARRAY (GskGLCommandBatches, gsk_gl_command_batches, GskGLCommandBatch)
|
||||||
|
DEFINE_INLINE_ARRAY (GskGLCommandBinds, gsk_gl_command_binds, GskGLCommandBind)
|
||||||
|
DEFINE_INLINE_ARRAY (GskGLCommandUniforms, gsk_gl_command_uniforms, GskGLCommandUniform)
|
||||||
|
|
||||||
|
struct _GskGLCommandQueue
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
/* The GdkGLContext we make current before executing GL commands. */
|
||||||
|
GdkGLContext *context;
|
||||||
|
|
||||||
|
/* Array of GskGLCommandBatch which is a fixed size structure that will
|
||||||
|
* point into offsets of other arrays so that all similar data is stored
|
||||||
|
* together. The idea here is that we reduce the need for pointers so that
|
||||||
|
* using g_realloc()'d arrays is fine.
|
||||||
|
*/
|
||||||
|
GskGLCommandBatches batches;
|
||||||
|
|
||||||
|
/* Contains array of vertices and some wrapper code to help upload them
|
||||||
|
* to the GL driver. We can also tweak this to use double buffered arrays
|
||||||
|
* if we find that to be faster on some hardware and/or drivers.
|
||||||
|
*/
|
||||||
|
GskGLBuffer vertices;
|
||||||
|
|
||||||
|
/* The GskGLAttachmentState contains information about our FBO and texture
|
||||||
|
* attachments as we process incoming operations. We snapshot them into
|
||||||
|
* various batches so that we can compare differences between merge
|
||||||
|
* candidates.
|
||||||
|
*/
|
||||||
|
GskGLAttachmentState *attachments;
|
||||||
|
|
||||||
|
/* The uniform state across all programs. We snapshot this into batches so
|
||||||
|
* that we can compare uniform state between batches to give us more
|
||||||
|
* chances at merging draw commands.
|
||||||
|
*/
|
||||||
|
GskGLUniformState *uniforms;
|
||||||
|
|
||||||
|
/* Current program if we are in a draw so that we can send commands
|
||||||
|
* to the uniform state as needed.
|
||||||
|
*/
|
||||||
|
GskGLUniformProgram *program_info;
|
||||||
|
|
||||||
|
/* The profiler instance to deliver timing/etc data */
|
||||||
|
GskProfiler *profiler;
|
||||||
|
GskGLProfiler *gl_profiler;
|
||||||
|
|
||||||
|
/* Array of GskGLCommandBind which denote what textures need to be attached
|
||||||
|
* to which slot. GskGLCommandDraw.bind_offset and bind_count reference this
|
||||||
|
* array to determine what to attach.
|
||||||
|
*/
|
||||||
|
GskGLCommandBinds batch_binds;
|
||||||
|
|
||||||
|
/* Array of GskGLCommandUniform denoting which uniforms must be updated
|
||||||
|
* before the glDrawArrays() may be called. These are referenced from the
|
||||||
|
* GskGLCommandDraw.uniform_offset and uniform_count fields.
|
||||||
|
*/
|
||||||
|
GskGLCommandUniforms batch_uniforms;
|
||||||
|
|
||||||
|
/* Discovered max texture size when loading the command queue so that we
|
||||||
|
* can either scale down or slice textures to fit within this size. Assumed
|
||||||
|
* to be both height and width.
|
||||||
|
*/
|
||||||
|
int max_texture_size;
|
||||||
|
|
||||||
|
/* The index of the last batch in @batches, which may not be the element
|
||||||
|
* at the end of the array, as batches can be reordered. This is used to
|
||||||
|
* update the "next" index when adding a new batch.
|
||||||
|
*/
|
||||||
|
gint16 tail_batch_index;
|
||||||
|
gint16 head_batch_index;
|
||||||
|
|
||||||
|
/* Max framebuffer we used, so we can sort items faster */
|
||||||
|
guint fbo_max;
|
||||||
|
|
||||||
|
/* Various GSK and GDK metric counter ids */
|
||||||
|
struct {
|
||||||
|
GQuark n_frames;
|
||||||
|
GQuark cpu_time;
|
||||||
|
GQuark gpu_time;
|
||||||
|
guint n_binds;
|
||||||
|
guint n_fbos;
|
||||||
|
guint n_uniforms;
|
||||||
|
guint n_uploads;
|
||||||
|
guint n_programs;
|
||||||
|
guint queue_depth;
|
||||||
|
} metrics;
|
||||||
|
|
||||||
|
/* Counter for uploads on the frame */
|
||||||
|
guint n_uploads;
|
||||||
|
|
||||||
|
/* If we're inside a begin/end_frame pair */
|
||||||
|
guint in_frame : 1;
|
||||||
|
|
||||||
|
/* If we're inside of a begin_draw()/end_draw() pair. */
|
||||||
|
guint in_draw : 1;
|
||||||
|
|
||||||
|
/* If we've warned about truncating batches */
|
||||||
|
guint have_truncated : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
GskGLCommandQueue *gsk_gl_command_queue_new (GdkGLContext *context,
|
||||||
|
GskGLUniformState *uniforms);
|
||||||
|
void gsk_gl_command_queue_set_profiler (GskGLCommandQueue *self,
|
||||||
|
GskProfiler *profiler);
|
||||||
|
GdkGLContext *gsk_gl_command_queue_get_context (GskGLCommandQueue *self);
|
||||||
|
void gsk_gl_command_queue_make_current (GskGLCommandQueue *self);
|
||||||
|
void gsk_gl_command_queue_begin_frame (GskGLCommandQueue *self);
|
||||||
|
void gsk_gl_command_queue_end_frame (GskGLCommandQueue *self);
|
||||||
|
void gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||||
|
guint surface_height,
|
||||||
|
guint scale_factor,
|
||||||
|
const cairo_region_t *scissor);
|
||||||
|
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||||
|
GdkTexture *texture,
|
||||||
|
guint x_offset,
|
||||||
|
guint y_offset,
|
||||||
|
guint width,
|
||||||
|
guint height,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter);
|
||||||
|
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int format,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter);
|
||||||
|
guint gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self);
|
||||||
|
gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int format,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter,
|
||||||
|
guint *out_fbo_id,
|
||||||
|
guint *out_texture_id);
|
||||||
|
void gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
|
||||||
|
guint program_id);
|
||||||
|
void gsk_gl_command_queue_clear (GskGLCommandQueue *self,
|
||||||
|
guint clear_bits,
|
||||||
|
const graphene_rect_t *viewport);
|
||||||
|
void gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
|
||||||
|
GskGLUniformProgram *program_info,
|
||||||
|
guint width,
|
||||||
|
guint height);
|
||||||
|
void gsk_gl_command_queue_end_draw (GskGLCommandQueue *self);
|
||||||
|
void gsk_gl_command_queue_split_draw (GskGLCommandQueue *self);
|
||||||
|
|
||||||
|
static inline GskGLCommandBatch *
|
||||||
|
gsk_gl_command_queue_get_batch (GskGLCommandQueue *self)
|
||||||
|
{
|
||||||
|
return gsk_gl_command_batches_tail (&self->batches);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GskGLDrawVertex *
|
||||||
|
gsk_gl_command_queue_add_vertices (GskGLCommandQueue *self)
|
||||||
|
{
|
||||||
|
gsk_gl_command_queue_get_batch (self)->draw.vbo_count += GSK_GL_N_VERTICES;
|
||||||
|
return gsk_gl_buffer_advance (&self->vertices, GSK_GL_N_VERTICES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GskGLDrawVertex *
|
||||||
|
gsk_gl_command_queue_add_n_vertices (GskGLCommandQueue *self,
|
||||||
|
guint count)
|
||||||
|
{
|
||||||
|
/* This is a batch form of gsk_gl_command_queue_add_vertices(). Note that
|
||||||
|
* it does *not* add the count to .draw.vbo_count as the caller is responsible
|
||||||
|
* for that.
|
||||||
|
*/
|
||||||
|
return gsk_gl_buffer_advance (&self->vertices, GSK_GL_N_VERTICES * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_command_queue_retract_n_vertices (GskGLCommandQueue *self,
|
||||||
|
guint count)
|
||||||
|
{
|
||||||
|
/* Like gsk_gl_command_queue_add_n_vertices(), this does not tweak
|
||||||
|
* the draw vbo_count.
|
||||||
|
*/
|
||||||
|
gsk_gl_buffer_retract (&self->vertices, GSK_GL_N_VERTICES * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
|
||||||
|
guint framebuffer)
|
||||||
|
{
|
||||||
|
guint ret = self->attachments->fbo.id;
|
||||||
|
gsk_gl_attachment_state_bind_framebuffer (self->attachments, framebuffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_COMMAND_QUEUE_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglcompiler.c
|
/* gskglcompiler.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -24,20 +24,20 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gsknglcompilerprivate.h"
|
#include "gskglcompilerprivate.h"
|
||||||
#include "gsknglprogramprivate.h"
|
#include "gskglprogramprivate.h"
|
||||||
|
|
||||||
#define SHADER_VERSION_GLES 100
|
#define SHADER_VERSION_GLES 100
|
||||||
#define SHADER_VERSION_GL2_LEGACY 110
|
#define SHADER_VERSION_GL2_LEGACY 110
|
||||||
#define SHADER_VERSION_GL3_LEGACY 130
|
#define SHADER_VERSION_GL3_LEGACY 130
|
||||||
#define SHADER_VERSION_GL3 150
|
#define SHADER_VERSION_GL3 150
|
||||||
|
|
||||||
struct _GskNglCompiler
|
struct _GskGLCompiler
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GskNglDriver *driver;
|
GskGLDriver *driver;
|
||||||
|
|
||||||
GBytes *all_preamble;
|
GBytes *all_preamble;
|
||||||
GBytes *fragment_preamble;
|
GBytes *fragment_preamble;
|
||||||
@ -57,20 +57,20 @@ struct _GskNglCompiler
|
|||||||
guint debug_shaders : 1;
|
guint debug_shaders : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GskNglProgramAttrib
|
typedef struct _GskGLProgramAttrib
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
guint location;
|
guint location;
|
||||||
} GskNglProgramAttrib;
|
} GskGLProgramAttrib;
|
||||||
|
|
||||||
static GBytes *empty_bytes;
|
static GBytes *empty_bytes;
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglCompiler, gsk_ngl_compiler, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GskGLCompiler, gsk_gl_compiler, G_TYPE_OBJECT)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_compiler_finalize (GObject *object)
|
gsk_gl_compiler_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GskNglCompiler *self = (GskNglCompiler *)object;
|
GskGLCompiler *self = (GskGLCompiler *)object;
|
||||||
|
|
||||||
g_clear_pointer (&self->all_preamble, g_bytes_unref);
|
g_clear_pointer (&self->all_preamble, g_bytes_unref);
|
||||||
g_clear_pointer (&self->fragment_preamble, g_bytes_unref);
|
g_clear_pointer (&self->fragment_preamble, g_bytes_unref);
|
||||||
@ -82,24 +82,24 @@ gsk_ngl_compiler_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->attrib_locations, g_array_unref);
|
g_clear_pointer (&self->attrib_locations, g_array_unref);
|
||||||
g_clear_object (&self->driver);
|
g_clear_object (&self->driver);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_compiler_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gsk_gl_compiler_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_compiler_class_init (GskNglCompilerClass *klass)
|
gsk_gl_compiler_class_init (GskGLCompilerClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = gsk_ngl_compiler_finalize;
|
object_class->finalize = gsk_gl_compiler_finalize;
|
||||||
|
|
||||||
empty_bytes = g_bytes_new (NULL, 0);
|
empty_bytes = g_bytes_new (NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_compiler_init (GskNglCompiler *self)
|
gsk_gl_compiler_init (GskGLCompiler *self)
|
||||||
{
|
{
|
||||||
self->glsl_version = 150;
|
self->glsl_version = 150;
|
||||||
self->attrib_locations = g_array_new (FALSE, FALSE, sizeof (GskNglProgramAttrib));
|
self->attrib_locations = g_array_new (FALSE, FALSE, sizeof (GskGLProgramAttrib));
|
||||||
self->all_preamble = g_bytes_ref (empty_bytes);
|
self->all_preamble = g_bytes_ref (empty_bytes);
|
||||||
self->vertex_preamble = g_bytes_ref (empty_bytes);
|
self->vertex_preamble = g_bytes_ref (empty_bytes);
|
||||||
self->fragment_preamble = g_bytes_ref (empty_bytes);
|
self->fragment_preamble = g_bytes_ref (empty_bytes);
|
||||||
@ -109,21 +109,21 @@ gsk_ngl_compiler_init (GskNglCompiler *self)
|
|||||||
self->fragment_suffix = g_bytes_ref (empty_bytes);
|
self->fragment_suffix = g_bytes_ref (empty_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglCompiler *
|
GskGLCompiler *
|
||||||
gsk_ngl_compiler_new (GskNglDriver *driver,
|
gsk_gl_compiler_new (GskGLDriver *driver,
|
||||||
gboolean debug_shaders)
|
gboolean debug_shaders)
|
||||||
{
|
{
|
||||||
GskNglCompiler *self;
|
GskGLCompiler *self;
|
||||||
GdkGLContext *context;
|
GdkGLContext *context;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_NGL_DRIVER (driver), NULL);
|
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||||
g_return_val_if_fail (driver->shared_command_queue != NULL, NULL);
|
g_return_val_if_fail (driver->shared_command_queue != NULL, NULL);
|
||||||
|
|
||||||
self = g_object_new (GSK_TYPE_GL_COMPILER, NULL);
|
self = g_object_new (GSK_TYPE_GL_COMPILER, NULL);
|
||||||
self->driver = g_object_ref (driver);
|
self->driver = g_object_ref (driver);
|
||||||
self->debug_shaders = !!debug_shaders;
|
self->debug_shaders = !!debug_shaders;
|
||||||
|
|
||||||
context = gsk_ngl_command_queue_get_context (self->driver->shared_command_queue);
|
context = gsk_gl_command_queue_get_context (self->driver->shared_command_queue);
|
||||||
|
|
||||||
if (gdk_gl_context_get_use_es (context))
|
if (gdk_gl_context_get_use_es (context))
|
||||||
{
|
{
|
||||||
@ -149,19 +149,19 @@ gsk_ngl_compiler_new (GskNglDriver *driver,
|
|||||||
self->gl3 = TRUE;
|
self->gl3 = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gsk_ngl_command_queue_make_current (self->driver->shared_command_queue);
|
gsk_gl_command_queue_make_current (self->driver->shared_command_queue);
|
||||||
|
|
||||||
return g_steal_pointer (&self);
|
return g_steal_pointer (&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_bind_attribute (GskNglCompiler *self,
|
gsk_gl_compiler_bind_attribute (GskGLCompiler *self,
|
||||||
const char *name,
|
const char *name,
|
||||||
guint location)
|
guint location)
|
||||||
{
|
{
|
||||||
GskNglProgramAttrib attrib;
|
GskGLProgramAttrib attrib;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (name != NULL);
|
g_return_if_fail (name != NULL);
|
||||||
g_return_if_fail (location < 32);
|
g_return_if_fail (location < 32);
|
||||||
|
|
||||||
@ -172,28 +172,28 @@ gsk_ngl_compiler_bind_attribute (GskNglCompiler *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_clear_attributes (GskNglCompiler *self)
|
gsk_gl_compiler_clear_attributes (GskGLCompiler *self)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
|
|
||||||
g_array_set_size (self->attrib_locations, 0);
|
g_array_set_size (self->attrib_locations, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_preamble (GskNglCompiler *self,
|
gsk_gl_compiler_set_preamble (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
GBytes *preamble_bytes)
|
GBytes *preamble_bytes)
|
||||||
{
|
{
|
||||||
GBytes **loc = NULL;
|
GBytes **loc = NULL;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (preamble_bytes != NULL);
|
g_return_if_fail (preamble_bytes != NULL);
|
||||||
|
|
||||||
if (kind == GSK_NGL_COMPILER_ALL)
|
if (kind == GSK_GL_COMPILER_ALL)
|
||||||
loc = &self->all_preamble;
|
loc = &self->all_preamble;
|
||||||
else if (kind == GSK_NGL_COMPILER_FRAGMENT)
|
else if (kind == GSK_GL_COMPILER_FRAGMENT)
|
||||||
loc = &self->fragment_preamble;
|
loc = &self->fragment_preamble;
|
||||||
else if (kind == GSK_NGL_COMPILER_VERTEX)
|
else if (kind == GSK_GL_COMPILER_VERTEX)
|
||||||
loc = &self->vertex_preamble;
|
loc = &self->vertex_preamble;
|
||||||
else
|
else
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
@ -208,17 +208,17 @@ gsk_ngl_compiler_set_preamble (GskNglCompiler *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_preamble_from_resource (GskNglCompiler *self,
|
gsk_gl_compiler_set_preamble_from_resource (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
const char *resource_path)
|
const char *resource_path)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (kind == GSK_NGL_COMPILER_ALL ||
|
g_return_if_fail (kind == GSK_GL_COMPILER_ALL ||
|
||||||
kind == GSK_NGL_COMPILER_VERTEX ||
|
kind == GSK_GL_COMPILER_VERTEX ||
|
||||||
kind == GSK_NGL_COMPILER_FRAGMENT);
|
kind == GSK_GL_COMPILER_FRAGMENT);
|
||||||
g_return_if_fail (resource_path != NULL);
|
g_return_if_fail (resource_path != NULL);
|
||||||
|
|
||||||
bytes = g_resources_lookup_data (resource_path,
|
bytes = g_resources_lookup_data (resource_path,
|
||||||
@ -228,23 +228,23 @@ gsk_ngl_compiler_set_preamble_from_resource (GskNglCompiler *self,
|
|||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
g_warning ("Cannot set shader from resource: %s", error->message);
|
g_warning ("Cannot set shader from resource: %s", error->message);
|
||||||
else
|
else
|
||||||
gsk_ngl_compiler_set_preamble (self, kind, bytes);
|
gsk_gl_compiler_set_preamble (self, kind, bytes);
|
||||||
|
|
||||||
g_clear_pointer (&bytes, g_bytes_unref);
|
g_clear_pointer (&bytes, g_bytes_unref);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
gsk_gl_compiler_set_source (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
GBytes *source_bytes)
|
GBytes *source_bytes)
|
||||||
{
|
{
|
||||||
GBytes **loc = NULL;
|
GBytes **loc = NULL;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (kind == GSK_NGL_COMPILER_ALL ||
|
g_return_if_fail (kind == GSK_GL_COMPILER_ALL ||
|
||||||
kind == GSK_NGL_COMPILER_VERTEX ||
|
kind == GSK_GL_COMPILER_VERTEX ||
|
||||||
kind == GSK_NGL_COMPILER_FRAGMENT);
|
kind == GSK_GL_COMPILER_FRAGMENT);
|
||||||
|
|
||||||
if (source_bytes == NULL)
|
if (source_bytes == NULL)
|
||||||
source_bytes = empty_bytes;
|
source_bytes = empty_bytes;
|
||||||
@ -256,7 +256,7 @@ gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
|||||||
* use GBytes which reference the original bytes instead of
|
* use GBytes which reference the original bytes instead of
|
||||||
* copying them.
|
* copying them.
|
||||||
*/
|
*/
|
||||||
if (kind == GSK_NGL_COMPILER_ALL)
|
if (kind == GSK_GL_COMPILER_ALL)
|
||||||
{
|
{
|
||||||
gsize len = 0;
|
gsize len = 0;
|
||||||
const char *source;
|
const char *source;
|
||||||
@ -305,8 +305,8 @@ gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
|||||||
fragment_shader_start - source,
|
fragment_shader_start - source,
|
||||||
endpos - fragment_shader_start);
|
endpos - fragment_shader_start);
|
||||||
|
|
||||||
gsk_ngl_compiler_set_source (self, GSK_NGL_COMPILER_VERTEX, vertex_bytes);
|
gsk_gl_compiler_set_source (self, GSK_GL_COMPILER_VERTEX, vertex_bytes);
|
||||||
gsk_ngl_compiler_set_source (self, GSK_NGL_COMPILER_FRAGMENT, fragment_bytes);
|
gsk_gl_compiler_set_source (self, GSK_GL_COMPILER_FRAGMENT, fragment_bytes);
|
||||||
|
|
||||||
g_bytes_unref (fragment_bytes);
|
g_bytes_unref (fragment_bytes);
|
||||||
g_bytes_unref (vertex_bytes);
|
g_bytes_unref (vertex_bytes);
|
||||||
@ -314,9 +314,9 @@ gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == GSK_NGL_COMPILER_FRAGMENT)
|
if (kind == GSK_GL_COMPILER_FRAGMENT)
|
||||||
loc = &self->fragment_source;
|
loc = &self->fragment_source;
|
||||||
else if (kind == GSK_NGL_COMPILER_VERTEX)
|
else if (kind == GSK_GL_COMPILER_VERTEX)
|
||||||
loc = &self->vertex_source;
|
loc = &self->vertex_source;
|
||||||
else
|
else
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
@ -329,17 +329,17 @@ gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_source_from_resource (GskNglCompiler *self,
|
gsk_gl_compiler_set_source_from_resource (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
const char *resource_path)
|
const char *resource_path)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (kind == GSK_NGL_COMPILER_ALL ||
|
g_return_if_fail (kind == GSK_GL_COMPILER_ALL ||
|
||||||
kind == GSK_NGL_COMPILER_VERTEX ||
|
kind == GSK_GL_COMPILER_VERTEX ||
|
||||||
kind == GSK_NGL_COMPILER_FRAGMENT);
|
kind == GSK_GL_COMPILER_FRAGMENT);
|
||||||
g_return_if_fail (resource_path != NULL);
|
g_return_if_fail (resource_path != NULL);
|
||||||
|
|
||||||
bytes = g_resources_lookup_data (resource_path,
|
bytes = g_resources_lookup_data (resource_path,
|
||||||
@ -349,30 +349,30 @@ gsk_ngl_compiler_set_source_from_resource (GskNglCompiler *self,
|
|||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
g_warning ("Cannot set shader from resource: %s", error->message);
|
g_warning ("Cannot set shader from resource: %s", error->message);
|
||||||
else
|
else
|
||||||
gsk_ngl_compiler_set_source (self, kind, bytes);
|
gsk_gl_compiler_set_source (self, kind, bytes);
|
||||||
|
|
||||||
g_clear_pointer (&bytes, g_bytes_unref);
|
g_clear_pointer (&bytes, g_bytes_unref);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_suffix (GskNglCompiler *self,
|
gsk_gl_compiler_set_suffix (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
GBytes *suffix_bytes)
|
GBytes *suffix_bytes)
|
||||||
{
|
{
|
||||||
GBytes **loc;
|
GBytes **loc;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (kind == GSK_NGL_COMPILER_VERTEX ||
|
g_return_if_fail (kind == GSK_GL_COMPILER_VERTEX ||
|
||||||
kind == GSK_NGL_COMPILER_FRAGMENT);
|
kind == GSK_GL_COMPILER_FRAGMENT);
|
||||||
g_return_if_fail (suffix_bytes != NULL);
|
g_return_if_fail (suffix_bytes != NULL);
|
||||||
|
|
||||||
if (suffix_bytes == NULL)
|
if (suffix_bytes == NULL)
|
||||||
suffix_bytes = empty_bytes;
|
suffix_bytes = empty_bytes;
|
||||||
|
|
||||||
if (kind == GSK_NGL_COMPILER_FRAGMENT)
|
if (kind == GSK_GL_COMPILER_FRAGMENT)
|
||||||
loc = &self->fragment_suffix;
|
loc = &self->fragment_suffix;
|
||||||
else if (kind == GSK_NGL_COMPILER_VERTEX)
|
else if (kind == GSK_GL_COMPILER_VERTEX)
|
||||||
loc = &self->vertex_suffix;
|
loc = &self->vertex_suffix;
|
||||||
else
|
else
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
@ -385,16 +385,16 @@ gsk_ngl_compiler_set_suffix (GskNglCompiler *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_compiler_set_suffix_from_resource (GskNglCompiler *self,
|
gsk_gl_compiler_set_suffix_from_resource (GskGLCompiler *self,
|
||||||
GskNglCompilerKind kind,
|
GskGLCompilerKind kind,
|
||||||
const char *resource_path)
|
const char *resource_path)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_COMPILER (self));
|
g_return_if_fail (GSK_IS_GL_COMPILER (self));
|
||||||
g_return_if_fail (kind == GSK_NGL_COMPILER_VERTEX ||
|
g_return_if_fail (kind == GSK_GL_COMPILER_VERTEX ||
|
||||||
kind == GSK_NGL_COMPILER_FRAGMENT);
|
kind == GSK_GL_COMPILER_FRAGMENT);
|
||||||
g_return_if_fail (resource_path != NULL);
|
g_return_if_fail (resource_path != NULL);
|
||||||
|
|
||||||
bytes = g_resources_lookup_data (resource_path,
|
bytes = g_resources_lookup_data (resource_path,
|
||||||
@ -404,7 +404,7 @@ gsk_ngl_compiler_set_suffix_from_resource (GskNglCompiler *self,
|
|||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
g_warning ("Cannot set suffix from resource: %s", error->message);
|
g_warning ("Cannot set suffix from resource: %s", error->message);
|
||||||
else
|
else
|
||||||
gsk_ngl_compiler_set_suffix (self, kind, bytes);
|
gsk_gl_compiler_set_suffix (self, kind, bytes);
|
||||||
|
|
||||||
g_clear_pointer (&bytes, g_bytes_unref);
|
g_clear_pointer (&bytes, g_bytes_unref);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
@ -520,11 +520,11 @@ get_shader_string (GBytes *bytes)
|
|||||||
return str ? str : "";
|
return str ? str : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglProgram *
|
GskGLProgram *
|
||||||
gsk_ngl_compiler_compile (GskNglCompiler *self,
|
gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *clip,
|
const char *clip,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
char version[32];
|
char version[32];
|
||||||
const char *debug = "";
|
const char *debug = "";
|
||||||
@ -536,7 +536,7 @@ gsk_ngl_compiler_compile (GskNglCompiler *self,
|
|||||||
int fragment_id;
|
int fragment_id;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_NGL_COMPILER (self), NULL);
|
g_return_val_if_fail (GSK_IS_GL_COMPILER (self), NULL);
|
||||||
g_return_val_if_fail (self->all_preamble != NULL, NULL);
|
g_return_val_if_fail (self->all_preamble != NULL, NULL);
|
||||||
g_return_val_if_fail (self->fragment_preamble != NULL, NULL);
|
g_return_val_if_fail (self->fragment_preamble != NULL, NULL);
|
||||||
g_return_val_if_fail (self->vertex_preamble != NULL, NULL);
|
g_return_val_if_fail (self->vertex_preamble != NULL, NULL);
|
||||||
@ -544,7 +544,7 @@ gsk_ngl_compiler_compile (GskNglCompiler *self,
|
|||||||
g_return_val_if_fail (self->vertex_source != NULL, NULL);
|
g_return_val_if_fail (self->vertex_source != NULL, NULL);
|
||||||
g_return_val_if_fail (self->driver != NULL, NULL);
|
g_return_val_if_fail (self->driver != NULL, NULL);
|
||||||
|
|
||||||
gsk_ngl_command_queue_make_current (self->driver->command_queue);
|
gsk_gl_command_queue_make_current (self->driver->command_queue);
|
||||||
|
|
||||||
g_snprintf (version, sizeof version, "#version %d\n", self->glsl_version);
|
g_snprintf (version, sizeof version, "#version %d\n", self->glsl_version);
|
||||||
|
|
||||||
@ -633,9 +633,9 @@ gsk_ngl_compiler_compile (GskNglCompiler *self,
|
|||||||
|
|
||||||
for (guint i = 0; i < self->attrib_locations->len; i++)
|
for (guint i = 0; i < self->attrib_locations->len; i++)
|
||||||
{
|
{
|
||||||
const GskNglProgramAttrib *attrib;
|
const GskGLProgramAttrib *attrib;
|
||||||
|
|
||||||
attrib = &g_array_index (self->attrib_locations, GskNglProgramAttrib, i);
|
attrib = &g_array_index (self->attrib_locations, GskGLProgramAttrib, i);
|
||||||
glBindAttribLocation (program_id, attrib->location, attrib->name);
|
glBindAttribLocation (program_id, attrib->location, attrib->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,5 +679,5 @@ gsk_ngl_compiler_compile (GskNglCompiler *self,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gsk_ngl_program_new (self->driver, name, program_id);
|
return gsk_gl_program_new (self->driver, name, program_id);
|
||||||
}
|
}
|
70
gsk/gl/gskglcompilerprivate.h
Normal file
70
gsk/gl/gskglcompilerprivate.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* gskglcompilerprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_COMPILER_PRIVATE_H__
|
||||||
|
#define __GSK_GL_COMPILER_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum _GskGLCompilerKind
|
||||||
|
{
|
||||||
|
GSK_GL_COMPILER_ALL,
|
||||||
|
GSK_GL_COMPILER_FRAGMENT,
|
||||||
|
GSK_GL_COMPILER_VERTEX,
|
||||||
|
} GskGLCompilerKind;
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_COMPILER (gsk_gl_compiler_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLCompiler, gsk_gl_compiler, GSK, GL_COMPILER, GObject)
|
||||||
|
|
||||||
|
GskGLCompiler * gsk_gl_compiler_new (GskGLDriver *driver,
|
||||||
|
gboolean debug);
|
||||||
|
void gsk_gl_compiler_set_preamble (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
GBytes *preamble_bytes);
|
||||||
|
void gsk_gl_compiler_set_preamble_from_resource (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
const char *resource_path);
|
||||||
|
void gsk_gl_compiler_set_source (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
GBytes *source_bytes);
|
||||||
|
void gsk_gl_compiler_set_source_from_resource (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
const char *resource_path);
|
||||||
|
void gsk_gl_compiler_set_suffix (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
GBytes *suffix_bytes);
|
||||||
|
void gsk_gl_compiler_set_suffix_from_resource (GskGLCompiler *self,
|
||||||
|
GskGLCompilerKind kind,
|
||||||
|
const char *resource_path);
|
||||||
|
void gsk_gl_compiler_bind_attribute (GskGLCompiler *self,
|
||||||
|
const char *name,
|
||||||
|
guint location);
|
||||||
|
void gsk_gl_compiler_clear_attributes (GskGLCompiler *self);
|
||||||
|
GskGLProgram * gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||||
|
const char *name,
|
||||||
|
const char *clip,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_COMPILER_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
251
gsk/gl/gskgldriverprivate.h
Normal file
251
gsk/gl/gskgldriverprivate.h
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
/* gskgldriverprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_DRIVER_PRIVATE_H__
|
||||||
|
#define __GSK_GL_DRIVER_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <gdk/gdkgltextureprivate.h>
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
#include "gskgltextureprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UNIFORM_SHARED_ALPHA,
|
||||||
|
UNIFORM_SHARED_SOURCE,
|
||||||
|
UNIFORM_SHARED_CLIP_RECT,
|
||||||
|
UNIFORM_SHARED_VIEWPORT,
|
||||||
|
UNIFORM_SHARED_PROJECTION,
|
||||||
|
UNIFORM_SHARED_MODELVIEW,
|
||||||
|
|
||||||
|
UNIFORM_SHARED_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UNIFORM_CUSTOM_SIZE = UNIFORM_SHARED_LAST,
|
||||||
|
UNIFORM_CUSTOM_TEXTURE1,
|
||||||
|
UNIFORM_CUSTOM_TEXTURE2,
|
||||||
|
UNIFORM_CUSTOM_TEXTURE3,
|
||||||
|
UNIFORM_CUSTOM_TEXTURE4,
|
||||||
|
UNIFORM_CUSTOM_ARG0,
|
||||||
|
UNIFORM_CUSTOM_ARG1,
|
||||||
|
UNIFORM_CUSTOM_ARG2,
|
||||||
|
UNIFORM_CUSTOM_ARG3,
|
||||||
|
UNIFORM_CUSTOM_ARG4,
|
||||||
|
UNIFORM_CUSTOM_ARG5,
|
||||||
|
UNIFORM_CUSTOM_ARG6,
|
||||||
|
UNIFORM_CUSTOM_ARG7,
|
||||||
|
|
||||||
|
UNIFORM_CUSTOM_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gconstpointer pointer;
|
||||||
|
float scale_x;
|
||||||
|
float scale_y;
|
||||||
|
int filter;
|
||||||
|
int pointer_is_child;
|
||||||
|
graphene_rect_t parent_rect; /* Valid when pointer_is_child */
|
||||||
|
} GskTextureKey;
|
||||||
|
|
||||||
|
#define GSK_GL_NO_UNIFORMS CONCAT_EXPANDED(UNIFORM_INVALID_,__COUNTER__)
|
||||||
|
#define CONCAT_EXPANDED(a,b) CONCAT_EXPANDED2(a,b)
|
||||||
|
#define CONCAT_EXPANDED2(a,b) a##b
|
||||||
|
#define GSK_GL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos,
|
||||||
|
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms };
|
||||||
|
# include "gskglprograms.defs"
|
||||||
|
#undef GSK_GL_DEFINE_PROGRAM
|
||||||
|
#undef GSK_GL_ADD_UNIFORM
|
||||||
|
#undef GSK_GL_NO_UNIFORMS
|
||||||
|
#undef CONCAT_EXPANDED
|
||||||
|
#undef CONCAT_EXPANDED2
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_DRIVER (gsk_gl_driver_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLDriver, gsk_gl_driver, GSK, GL_DRIVER, GObject)
|
||||||
|
|
||||||
|
struct _GskGLRenderTarget
|
||||||
|
{
|
||||||
|
guint framebuffer_id;
|
||||||
|
guint texture_id;
|
||||||
|
int min_filter;
|
||||||
|
int mag_filter;
|
||||||
|
int format;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GskGLDriver
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
GskGLCommandQueue *shared_command_queue;
|
||||||
|
GskGLCommandQueue *command_queue;
|
||||||
|
|
||||||
|
GskGLGlyphLibrary *glyphs;
|
||||||
|
GskGLIconLibrary *icons;
|
||||||
|
GskGLShadowLibrary *shadows;
|
||||||
|
|
||||||
|
GArray *texture_pool;
|
||||||
|
GHashTable *textures;
|
||||||
|
GHashTable *key_to_texture_id;
|
||||||
|
GHashTable *texture_id_to_key;
|
||||||
|
|
||||||
|
GPtrArray *atlases;
|
||||||
|
|
||||||
|
GHashTable *shader_cache;
|
||||||
|
|
||||||
|
GArray *autorelease_framebuffers;
|
||||||
|
GPtrArray *render_targets;
|
||||||
|
|
||||||
|
#define GSK_GL_NO_UNIFORMS
|
||||||
|
#define GSK_GL_ADD_UNIFORM(pos, KEY, name)
|
||||||
|
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \
|
||||||
|
GskGLProgram *name ## _no_clip; \
|
||||||
|
GskGLProgram *name ## _rect_clip; \
|
||||||
|
GskGLProgram *name;
|
||||||
|
# include "gskglprograms.defs"
|
||||||
|
#undef GSK_GL_NO_UNIFORMS
|
||||||
|
#undef GSK_GL_ADD_UNIFORM
|
||||||
|
#undef GSK_GL_DEFINE_PROGRAM
|
||||||
|
|
||||||
|
gint64 current_frame_id;
|
||||||
|
|
||||||
|
/* Used to reduce number of comparisons */
|
||||||
|
guint stamps[UNIFORM_SHARED_LAST];
|
||||||
|
|
||||||
|
guint debug : 1;
|
||||||
|
guint in_frame : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
GskGLDriver * gsk_gl_driver_for_display (GdkDisplay *display,
|
||||||
|
gboolean debug_shaders,
|
||||||
|
GError **error);
|
||||||
|
GskGLCommandQueue * gsk_gl_driver_create_command_queue (GskGLDriver *self,
|
||||||
|
GdkGLContext *context);
|
||||||
|
GdkGLContext * gsk_gl_driver_get_context (GskGLDriver *self);
|
||||||
|
gboolean gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int format,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter,
|
||||||
|
GskGLRenderTarget **render_target);
|
||||||
|
guint gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||||
|
GskGLRenderTarget *render_target,
|
||||||
|
gboolean release_texture);
|
||||||
|
void gsk_gl_driver_begin_frame (GskGLDriver *self,
|
||||||
|
GskGLCommandQueue *command_queue);
|
||||||
|
void gsk_gl_driver_end_frame (GskGLDriver *self);
|
||||||
|
void gsk_gl_driver_after_frame (GskGLDriver *self);
|
||||||
|
GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||||
|
guint texture_id);
|
||||||
|
void gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||||
|
const GskTextureKey *key,
|
||||||
|
guint texture_id);
|
||||||
|
guint gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||||
|
GdkTexture *texture,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter);
|
||||||
|
GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||||
|
float width,
|
||||||
|
float height,
|
||||||
|
int format,
|
||||||
|
int min_filter,
|
||||||
|
int mag_filter);
|
||||||
|
void gsk_gl_driver_release_texture (GskGLDriver *self,
|
||||||
|
GskGLTexture *texture);
|
||||||
|
void gsk_gl_driver_release_texture_by_id (GskGLDriver *self,
|
||||||
|
guint texture_id);
|
||||||
|
GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *self,
|
||||||
|
guint texture_id);
|
||||||
|
void gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||||
|
GdkTexture *texture,
|
||||||
|
GskGLTextureSlice **out_slices,
|
||||||
|
guint *out_n_slices);
|
||||||
|
GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self,
|
||||||
|
GskGLShader *shader,
|
||||||
|
GError **error);
|
||||||
|
GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self);
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
|
||||||
|
const char *directory);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline GskGLTexture *
|
||||||
|
gsk_gl_driver_get_texture_by_id (GskGLDriver *self,
|
||||||
|
guint texture_id)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_gl_driver_lookup_texture:
|
||||||
|
* @self: a `GskGLDriver`
|
||||||
|
* @key: the key for the texture
|
||||||
|
*
|
||||||
|
* Looks up a texture in the texture cache by @key.
|
||||||
|
*
|
||||||
|
* If the texture could not be found, then zero is returned.
|
||||||
|
*
|
||||||
|
* Returns: a positive integer if the texture was found; otherwise 0.
|
||||||
|
*/
|
||||||
|
static inline guint
|
||||||
|
gsk_gl_driver_lookup_texture (GskGLDriver *self,
|
||||||
|
const GskTextureKey *key)
|
||||||
|
{
|
||||||
|
gpointer id;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended (self->key_to_texture_id, key, NULL, &id))
|
||||||
|
{
|
||||||
|
GskGLTexture *texture = g_hash_table_lookup (self->textures, id);
|
||||||
|
|
||||||
|
if (texture != NULL)
|
||||||
|
texture->last_used_in_frame = self->current_frame_id;
|
||||||
|
|
||||||
|
return GPOINTER_TO_UINT (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_driver_slice_texture (GskGLDriver *self,
|
||||||
|
GdkTexture *texture,
|
||||||
|
GskGLTextureSlice **out_slices,
|
||||||
|
guint *out_n_slices)
|
||||||
|
{
|
||||||
|
GskGLTexture *t;
|
||||||
|
|
||||||
|
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||||
|
{
|
||||||
|
*out_slices = t->slices;
|
||||||
|
*out_n_slices = t->n_slices;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsk_gl_driver_add_texture_slices (self, texture, out_slices, out_n_slices);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_DRIVER_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglglyphlibrary.c
|
/* gskglglyphlibrary.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -24,18 +24,18 @@
|
|||||||
#include <gdk/gdkmemoryformatprivate.h>
|
#include <gdk/gdkmemoryformatprivate.h>
|
||||||
#include <gdk/gdkprofilerprivate.h>
|
#include <gdk/gdkprofilerprivate.h>
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gskngldriverprivate.h"
|
#include "gskgldriverprivate.h"
|
||||||
#include "gsknglglyphlibraryprivate.h"
|
#include "gskglglyphlibraryprivate.h"
|
||||||
|
|
||||||
#define MAX_GLYPH_SIZE 128
|
#define MAX_GLYPH_SIZE 128
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglGlyphLibrary, gsk_ngl_glyph_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
G_DEFINE_TYPE (GskGLGlyphLibrary, gsk_gl_glyph_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
||||||
|
|
||||||
GskNglGlyphLibrary *
|
GskGLGlyphLibrary *
|
||||||
gsk_ngl_glyph_library_new (GskNglDriver *driver)
|
gsk_gl_glyph_library_new (GskGLDriver *driver)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_NGL_DRIVER (driver), NULL);
|
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||||
|
|
||||||
return g_object_new (GSK_TYPE_GL_GLYPH_LIBRARY,
|
return g_object_new (GSK_TYPE_GL_GLYPH_LIBRARY,
|
||||||
"driver", driver,
|
"driver", driver,
|
||||||
@ -43,13 +43,13 @@ gsk_ngl_glyph_library_new (GskNglDriver *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
gsk_ngl_glyph_key_hash (gconstpointer data)
|
gsk_gl_glyph_key_hash (gconstpointer data)
|
||||||
{
|
{
|
||||||
const GskNglGlyphKey *key = data;
|
const GskGLGlyphKey *key = data;
|
||||||
|
|
||||||
/* We do not store the hash within the key because GHashTable will already
|
/* We do not store the hash within the key because GHashTable will already
|
||||||
* store the hash value for us and so this is called only a single time per
|
* store the hash value for us and so this is called only a single time per
|
||||||
* cached item. This saves an extra 4 bytes per GskNglGlyphKey which means on
|
* cached item. This saves an extra 4 bytes per GskGLGlyphKey which means on
|
||||||
* 64-bit, we fit nicely within 2 pointers (the smallest allocation size
|
* 64-bit, we fit nicely within 2 pointers (the smallest allocation size
|
||||||
* for GSlice).
|
* for GSlice).
|
||||||
*/
|
*/
|
||||||
@ -62,83 +62,83 @@ gsk_ngl_glyph_key_hash (gconstpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gsk_ngl_glyph_key_equal (gconstpointer v1,
|
gsk_gl_glyph_key_equal (gconstpointer v1,
|
||||||
gconstpointer v2)
|
gconstpointer v2)
|
||||||
{
|
{
|
||||||
return memcmp (v1, v2, sizeof (GskNglGlyphKey)) == 0;
|
return memcmp (v1, v2, sizeof (GskGLGlyphKey)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_key_free (gpointer data)
|
gsk_gl_glyph_key_free (gpointer data)
|
||||||
{
|
{
|
||||||
GskNglGlyphKey *key = data;
|
GskGLGlyphKey *key = data;
|
||||||
|
|
||||||
g_clear_object (&key->font);
|
g_clear_object (&key->font);
|
||||||
g_slice_free (GskNglGlyphKey, key);
|
g_slice_free (GskGLGlyphKey, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_value_free (gpointer data)
|
gsk_gl_glyph_value_free (gpointer data)
|
||||||
{
|
{
|
||||||
g_slice_free (GskNglGlyphValue, data);
|
g_slice_free (GskGLGlyphValue, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_library_begin_frame (GskNglTextureLibrary *library,
|
gsk_gl_glyph_library_begin_frame (GskGLTextureLibrary *library,
|
||||||
gint64 frame_id,
|
gint64 frame_id,
|
||||||
GPtrArray *removed_atlases)
|
GPtrArray *removed_atlases)
|
||||||
{
|
{
|
||||||
GskNglGlyphLibrary *self = (GskNglGlyphLibrary *)library;
|
GskGLGlyphLibrary *self = (GskGLGlyphLibrary *)library;
|
||||||
|
|
||||||
memset (self->front, 0, sizeof self->front);
|
memset (self->front, 0, sizeof self->front);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_library_finalize (GObject *object)
|
gsk_gl_glyph_library_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GskNglGlyphLibrary *self = (GskNglGlyphLibrary *)object;
|
GskGLGlyphLibrary *self = (GskGLGlyphLibrary *)object;
|
||||||
|
|
||||||
g_clear_pointer (&self->surface_data, g_free);
|
g_clear_pointer (&self->surface_data, g_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_glyph_library_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gsk_gl_glyph_library_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_library_class_init (GskNglGlyphLibraryClass *klass)
|
gsk_gl_glyph_library_class_init (GskGLGlyphLibraryClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GskNglTextureLibraryClass *library_class = GSK_NGL_TEXTURE_LIBRARY_CLASS (klass);
|
GskGLTextureLibraryClass *library_class = GSK_GL_TEXTURE_LIBRARY_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = gsk_ngl_glyph_library_finalize;
|
object_class->finalize = gsk_gl_glyph_library_finalize;
|
||||||
|
|
||||||
library_class->begin_frame = gsk_ngl_glyph_library_begin_frame;
|
library_class->begin_frame = gsk_gl_glyph_library_begin_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_library_init (GskNglGlyphLibrary *self)
|
gsk_gl_glyph_library_init (GskGLGlyphLibrary *self)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *tl = (GskNglTextureLibrary *)self;
|
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||||
|
|
||||||
tl->max_entry_size = MAX_GLYPH_SIZE;
|
tl->max_entry_size = MAX_GLYPH_SIZE;
|
||||||
gsk_ngl_texture_library_set_funcs (tl,
|
gsk_gl_texture_library_set_funcs (tl,
|
||||||
gsk_ngl_glyph_key_hash,
|
gsk_gl_glyph_key_hash,
|
||||||
gsk_ngl_glyph_key_equal,
|
gsk_gl_glyph_key_equal,
|
||||||
gsk_ngl_glyph_key_free,
|
gsk_gl_glyph_key_free,
|
||||||
gsk_ngl_glyph_value_free);
|
gsk_gl_glyph_value_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
gsk_ngl_glyph_library_create_surface (GskNglGlyphLibrary *self,
|
gsk_gl_glyph_library_create_surface (GskGLGlyphLibrary *self,
|
||||||
int stride,
|
int stride,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int uwidth,
|
int uwidth,
|
||||||
int uheight)
|
int uheight)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
gsize n_bytes;
|
gsize n_bytes;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_GLYPH_LIBRARY (self));
|
g_assert (GSK_IS_GL_GLYPH_LIBRARY (self));
|
||||||
g_assert (width > 0);
|
g_assert (width > 0);
|
||||||
g_assert (height > 0);
|
g_assert (height > 0);
|
||||||
|
|
||||||
@ -162,8 +162,8 @@ gsk_ngl_glyph_library_create_surface (GskNglGlyphLibrary *self,
|
|||||||
static void
|
static void
|
||||||
render_glyph (cairo_surface_t *surface,
|
render_glyph (cairo_surface_t *surface,
|
||||||
const cairo_scaled_font_t *scaled_font,
|
const cairo_scaled_font_t *scaled_font,
|
||||||
const GskNglGlyphKey *key,
|
const GskGLGlyphKey *key,
|
||||||
const GskNglGlyphValue *value)
|
const GskGLGlyphValue *value)
|
||||||
{
|
{
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_glyph_t glyph;
|
cairo_glyph_t glyph;
|
||||||
@ -186,17 +186,17 @@ render_glyph (cairo_surface_t *surface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
|
gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
|
||||||
const GskNglGlyphKey *key,
|
const GskGLGlyphKey *key,
|
||||||
const GskNglGlyphValue *value,
|
const GskGLGlyphValue *value,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int uwidth,
|
int uwidth,
|
||||||
int uheight)
|
int uheight)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *tl = (GskNglTextureLibrary *)self;
|
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
cairo_scaled_font_t *scaled_font;
|
cairo_scaled_font_t *scaled_font;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
@ -207,7 +207,7 @@ gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
|
|||||||
guint texture_id;
|
guint texture_id;
|
||||||
gsize stride;
|
gsize stride;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_GLYPH_LIBRARY (self));
|
g_assert (GSK_IS_GL_GLYPH_LIBRARY (self));
|
||||||
g_assert (key != NULL);
|
g_assert (key != NULL);
|
||||||
g_assert (value != NULL);
|
g_assert (value != NULL);
|
||||||
|
|
||||||
@ -222,10 +222,10 @@ gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
|
|||||||
"Uploading glyph %d",
|
"Uploading glyph %d",
|
||||||
key->glyph);
|
key->glyph);
|
||||||
|
|
||||||
surface = gsk_ngl_glyph_library_create_surface (self, stride, width, height, uwidth, uheight);
|
surface = gsk_gl_glyph_library_create_surface (self, stride, width, height, uwidth, uheight);
|
||||||
render_glyph (surface, scaled_font, key, value);
|
render_glyph (surface, scaled_font, key, value);
|
||||||
|
|
||||||
texture_id = GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (value);
|
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (value);
|
||||||
|
|
||||||
g_assert (texture_id > 0);
|
g_assert (texture_id > 0);
|
||||||
|
|
||||||
@ -272,19 +272,19 @@ gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gsk_ngl_glyph_library_add (GskNglGlyphLibrary *self,
|
gsk_gl_glyph_library_add (GskGLGlyphLibrary *self,
|
||||||
GskNglGlyphKey *key,
|
GskGLGlyphKey *key,
|
||||||
const GskNglGlyphValue **out_value)
|
const GskGLGlyphValue **out_value)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *tl = (GskNglTextureLibrary *)self;
|
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||||
PangoRectangle ink_rect;
|
PangoRectangle ink_rect;
|
||||||
GskNglGlyphValue *value;
|
GskGLGlyphValue *value;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
guint packed_x;
|
guint packed_x;
|
||||||
guint packed_y;
|
guint packed_y;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_GLYPH_LIBRARY (self));
|
g_assert (GSK_IS_GL_GLYPH_LIBRARY (self));
|
||||||
g_assert (key != NULL);
|
g_assert (key != NULL);
|
||||||
g_assert (out_value != NULL);
|
g_assert (out_value != NULL);
|
||||||
|
|
||||||
@ -299,28 +299,28 @@ gsk_ngl_glyph_library_add (GskNglGlyphLibrary *self,
|
|||||||
width = (int) ceil (ink_rect.width * key->scale / 1024.0);
|
width = (int) ceil (ink_rect.width * key->scale / 1024.0);
|
||||||
height = (int) ceil (ink_rect.height * key->scale / 1024.0);
|
height = (int) ceil (ink_rect.height * key->scale / 1024.0);
|
||||||
|
|
||||||
value = gsk_ngl_texture_library_pack (tl,
|
value = gsk_gl_texture_library_pack (tl,
|
||||||
key,
|
key,
|
||||||
sizeof *value,
|
sizeof *value,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
1,
|
1,
|
||||||
&packed_x, &packed_y);
|
&packed_x, &packed_y);
|
||||||
|
|
||||||
memcpy (&value->ink_rect, &ink_rect, sizeof ink_rect);
|
memcpy (&value->ink_rect, &ink_rect, sizeof ink_rect);
|
||||||
|
|
||||||
if (key->scale > 0 && width > 0 && height > 0)
|
if (key->scale > 0 && width > 0 && height > 0)
|
||||||
gsk_ngl_glyph_library_upload_glyph (self,
|
gsk_gl_glyph_library_upload_glyph (self,
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
packed_x + 1,
|
packed_x + 1,
|
||||||
packed_y + 1,
|
packed_y + 1,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
ink_rect.width,
|
ink_rect.width,
|
||||||
ink_rect.height);
|
ink_rect.height);
|
||||||
|
|
||||||
*out_value = value;
|
*out_value = value;
|
||||||
|
|
||||||
return GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (value) != 0;
|
return GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (value) != 0;
|
||||||
}
|
}
|
103
gsk/gl/gskglglyphlibraryprivate.h
Normal file
103
gsk/gl/gskglglyphlibraryprivate.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/* gskglglyphlibraryprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_GLYPH_LIBRARY_PRIVATE_H__
|
||||||
|
#define __GSK_GL_GLYPH_LIBRARY_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <pango/pango.h>
|
||||||
|
|
||||||
|
#include "gskgltexturelibraryprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_GLYPH_LIBRARY (gsk_gl_glyph_library_get_type())
|
||||||
|
|
||||||
|
typedef struct _GskGLGlyphKey
|
||||||
|
{
|
||||||
|
PangoFont *font;
|
||||||
|
PangoGlyph glyph;
|
||||||
|
guint xshift : 2;
|
||||||
|
guint yshift : 2;
|
||||||
|
guint scale : 28; /* times 1024 */
|
||||||
|
} GskGLGlyphKey;
|
||||||
|
|
||||||
|
typedef struct _GskGLGlyphValue
|
||||||
|
{
|
||||||
|
GskGLTextureAtlasEntry entry;
|
||||||
|
PangoRectangle ink_rect;
|
||||||
|
} GskGLGlyphValue;
|
||||||
|
|
||||||
|
#if GLIB_SIZEOF_VOID_P == 8
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 16);
|
||||||
|
#elif GLIB_SIZEOF_VOID_P == 4
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 12);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLGlyphLibrary, gsk_gl_glyph_library, GSK, GL_GLYPH_LIBRARY, GskGLTextureLibrary)
|
||||||
|
|
||||||
|
struct _GskGLGlyphLibrary
|
||||||
|
{
|
||||||
|
GskGLTextureLibrary parent_instance;
|
||||||
|
guint8 *surface_data;
|
||||||
|
gsize surface_data_len;
|
||||||
|
struct {
|
||||||
|
GskGLGlyphKey key;
|
||||||
|
const GskGLGlyphValue *value;
|
||||||
|
} front[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
GskGLGlyphLibrary *gsk_gl_glyph_library_new (GskGLDriver *driver);
|
||||||
|
gboolean gsk_gl_glyph_library_add (GskGLGlyphLibrary *self,
|
||||||
|
GskGLGlyphKey *key,
|
||||||
|
const GskGLGlyphValue **out_value);
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
gsk_gl_glyph_library_lookup_or_add (GskGLGlyphLibrary *self,
|
||||||
|
const GskGLGlyphKey *key,
|
||||||
|
const GskGLGlyphValue **out_value)
|
||||||
|
{
|
||||||
|
GskGLTextureAtlasEntry *entry;
|
||||||
|
guint front_index = ((key->glyph << 2) | key->xshift) & 0xFF;
|
||||||
|
|
||||||
|
if (memcmp (key, &self->front[front_index], sizeof *key) == 0)
|
||||||
|
{
|
||||||
|
*out_value = self->front[front_index].value;
|
||||||
|
}
|
||||||
|
else if (gsk_gl_texture_library_lookup ((GskGLTextureLibrary *)self, key, &entry))
|
||||||
|
{
|
||||||
|
*out_value = (GskGLGlyphValue *)entry;
|
||||||
|
self->front[front_index].key = *key;
|
||||||
|
self->front[front_index].value = *out_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GskGLGlyphKey *k = g_slice_copy (sizeof *key, key);
|
||||||
|
g_object_ref (k->font);
|
||||||
|
gsk_gl_glyph_library_add (self, k, out_value);
|
||||||
|
self->front[front_index].key = *key;
|
||||||
|
self->front[front_index].value = *out_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_GLYPH_LIBRARY_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gskngliconlibrary.c
|
/* gskgliconlibrary.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -25,21 +25,21 @@
|
|||||||
#include <gdk/gdkprofilerprivate.h>
|
#include <gdk/gdkprofilerprivate.h>
|
||||||
#include <gdk/gdktextureprivate.h>
|
#include <gdk/gdktextureprivate.h>
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gskngldriverprivate.h"
|
#include "gskgldriverprivate.h"
|
||||||
#include "gskngliconlibraryprivate.h"
|
#include "gskgliconlibraryprivate.h"
|
||||||
|
|
||||||
struct _GskNglIconLibrary
|
struct _GskGLIconLibrary
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary parent_instance;
|
GskGLTextureLibrary parent_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglIconLibrary, gsk_ngl_icon_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
G_DEFINE_TYPE (GskGLIconLibrary, gsk_gl_icon_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
|
||||||
|
|
||||||
GskNglIconLibrary *
|
GskGLIconLibrary *
|
||||||
gsk_ngl_icon_library_new (GskNglDriver *driver)
|
gsk_gl_icon_library_new (GskGLDriver *driver)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_NGL_DRIVER (driver), NULL);
|
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||||
|
|
||||||
return g_object_new (GSK_TYPE_GL_ICON_LIBRARY,
|
return g_object_new (GSK_TYPE_GL_ICON_LIBRARY,
|
||||||
"driver", driver,
|
"driver", driver,
|
||||||
@ -47,39 +47,39 @@ gsk_ngl_icon_library_new (GskNglDriver *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_icon_data_free (gpointer data)
|
gsk_gl_icon_data_free (gpointer data)
|
||||||
{
|
{
|
||||||
GskNglIconData *icon_data = data;
|
GskGLIconData *icon_data = data;
|
||||||
|
|
||||||
g_clear_object (&icon_data->source_texture);
|
g_clear_object (&icon_data->source_texture);
|
||||||
g_slice_free (GskNglIconData, icon_data);
|
g_slice_free (GskGLIconData, icon_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_icon_library_class_init (GskNglIconLibraryClass *klass)
|
gsk_gl_icon_library_class_init (GskGLIconLibraryClass *klass)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_icon_library_init (GskNglIconLibrary *self)
|
gsk_gl_icon_library_init (GskGLIconLibrary *self)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *tl = (GskNglTextureLibrary *)self;
|
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||||
|
|
||||||
tl->max_entry_size = 128;
|
tl->max_entry_size = 128;
|
||||||
gsk_ngl_texture_library_set_funcs (tl,
|
gsk_gl_texture_library_set_funcs (tl,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
gsk_ngl_icon_data_free);
|
gsk_gl_icon_data_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_icon_library_add (GskNglIconLibrary *self,
|
gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||||
GdkTexture *key,
|
GdkTexture *key,
|
||||||
const GskNglIconData **out_value)
|
const GskGLIconData **out_value)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *tl = (GskNglTextureLibrary *)self;
|
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
|
||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
GskNglIconData *icon_data;
|
GskGLIconData *icon_data;
|
||||||
guint8 *pixel_data;
|
guint8 *pixel_data;
|
||||||
guint8 *surface_data;
|
guint8 *surface_data;
|
||||||
guint8 *free_data = NULL;
|
guint8 *free_data = NULL;
|
||||||
@ -91,18 +91,18 @@ gsk_ngl_icon_library_add (GskNglIconLibrary *self,
|
|||||||
int height;
|
int height;
|
||||||
guint texture_id;
|
guint texture_id;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_ICON_LIBRARY (self));
|
g_assert (GSK_IS_GL_ICON_LIBRARY (self));
|
||||||
g_assert (GDK_IS_TEXTURE (key));
|
g_assert (GDK_IS_TEXTURE (key));
|
||||||
g_assert (out_value != NULL);
|
g_assert (out_value != NULL);
|
||||||
|
|
||||||
width = key->width;
|
width = key->width;
|
||||||
height = key->height;
|
height = key->height;
|
||||||
|
|
||||||
icon_data = gsk_ngl_texture_library_pack (tl,
|
icon_data = gsk_gl_texture_library_pack (tl,
|
||||||
key,
|
key,
|
||||||
sizeof (GskNglIconData),
|
sizeof (GskGLIconData),
|
||||||
width, height, 1,
|
width, height, 1,
|
||||||
&packed_x, &packed_y);
|
&packed_x, &packed_y);
|
||||||
icon_data->source_texture = g_object_ref (key);
|
icon_data->source_texture = g_object_ref (key);
|
||||||
|
|
||||||
/* actually upload the texture */
|
/* actually upload the texture */
|
||||||
@ -128,7 +128,7 @@ gsk_ngl_icon_library_add (GskNglIconLibrary *self,
|
|||||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_id = GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
|
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
|
||||||
|
|
||||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||||
|
|
60
gsk/gl/gskgliconlibraryprivate.h
Normal file
60
gsk/gl/gskgliconlibraryprivate.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* gskgliconlibraryprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_ICON_LIBRARY_PRIVATE_H__
|
||||||
|
#define __GSK_GL_ICON_LIBRARY_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <pango/pango.h>
|
||||||
|
|
||||||
|
#include "gskgltexturelibraryprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_ICON_LIBRARY (gsk_gl_icon_library_get_type())
|
||||||
|
|
||||||
|
typedef struct _GskGLIconData
|
||||||
|
{
|
||||||
|
GskGLTextureAtlasEntry entry;
|
||||||
|
GdkTexture *source_texture;
|
||||||
|
} GskGLIconData;
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLIconLibrary, gsk_gl_icon_library, GSK, GL_ICON_LIBRARY, GskGLTextureLibrary)
|
||||||
|
|
||||||
|
GskGLIconLibrary *gsk_gl_icon_library_new (GskGLDriver *driver);
|
||||||
|
void gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||||
|
GdkTexture *key,
|
||||||
|
const GskGLIconData **out_value);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_icon_library_lookup_or_add (GskGLIconLibrary *self,
|
||||||
|
GdkTexture *key,
|
||||||
|
const GskGLIconData **out_value)
|
||||||
|
{
|
||||||
|
GskGLTextureAtlasEntry *entry;
|
||||||
|
|
||||||
|
if G_LIKELY (gsk_gl_texture_library_lookup ((GskGLTextureLibrary *)self, key, &entry))
|
||||||
|
*out_value = (GskGLIconData *)entry;
|
||||||
|
else
|
||||||
|
gsk_gl_icon_library_add (self, key, out_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_ICON_LIBRARY_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglprogram.c
|
/* gskglprogram.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -20,20 +20,20 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gsknglprogramprivate.h"
|
#include "gskglprogramprivate.h"
|
||||||
#include "gskngluniformstateprivate.h"
|
#include "gskgluniformstateprivate.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglProgram, gsk_ngl_program, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GskGLProgram, gsk_gl_program, G_TYPE_OBJECT)
|
||||||
|
|
||||||
GskNglProgram *
|
GskGLProgram *
|
||||||
gsk_ngl_program_new (GskNglDriver *driver,
|
gsk_gl_program_new (GskGLDriver *driver,
|
||||||
const char *name,
|
const char *name,
|
||||||
int program_id)
|
int program_id)
|
||||||
{
|
{
|
||||||
GskNglProgram *self;
|
GskGLProgram *self;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_NGL_DRIVER (driver), NULL);
|
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||||
g_return_val_if_fail (program_id >= -1, NULL);
|
g_return_val_if_fail (program_id >= -1, NULL);
|
||||||
|
|
||||||
self = g_object_new (GSK_TYPE_GL_PROGRAM, NULL);
|
self = g_object_new (GSK_TYPE_GL_PROGRAM, NULL);
|
||||||
@ -46,9 +46,9 @@ gsk_ngl_program_new (GskNglDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_program_finalize (GObject *object)
|
gsk_gl_program_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GskNglProgram *self = (GskNglProgram *)object;
|
GskGLProgram *self = (GskGLProgram *)object;
|
||||||
|
|
||||||
if (self->id >= 0)
|
if (self->id >= 0)
|
||||||
g_warning ("Leaking GLSL program %d (%s)",
|
g_warning ("Leaking GLSL program %d (%s)",
|
||||||
@ -58,19 +58,19 @@ gsk_ngl_program_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->name, g_free);
|
g_clear_pointer (&self->name, g_free);
|
||||||
g_clear_object (&self->driver);
|
g_clear_object (&self->driver);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_program_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gsk_gl_program_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_program_class_init (GskNglProgramClass *klass)
|
gsk_gl_program_class_init (GskGLProgramClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = gsk_ngl_program_finalize;
|
object_class->finalize = gsk_gl_program_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_program_init (GskNglProgram *self)
|
gsk_gl_program_init (GskGLProgram *self)
|
||||||
{
|
{
|
||||||
self->id = -1;
|
self->id = -1;
|
||||||
|
|
||||||
@ -79,8 +79,8 @@ gsk_ngl_program_init (GskNglProgram *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_ngl_program_add_uniform:
|
* gsk_gl_program_add_uniform:
|
||||||
* @self: a `GskNglProgram`
|
* @self: a `GskGLProgram`
|
||||||
* @name: the name of the uniform such as "u_source"
|
* @name: the name of the uniform such as "u_source"
|
||||||
* @key: the identifier to use for the uniform
|
* @key: the identifier to use for the uniform
|
||||||
*
|
*
|
||||||
@ -93,26 +93,26 @@ gsk_ngl_program_init (GskNglProgram *self)
|
|||||||
* program and then register each of them like:
|
* program and then register each of them like:
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* gsk_ngl_program_add_uniform (program, "u_source", UNIFORM_SOURCE);
|
* gsk_gl_program_add_uniform (program, "u_source", UNIFORM_SOURCE);
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* That allows you to set values for the program with something
|
* That allows you to set values for the program with something
|
||||||
* like the following:
|
* like the following:
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* gsk_ngl_program_set_uniform1i (program, UNIFORM_SOURCE, 1);
|
* gsk_gl_program_set_uniform1i (program, UNIFORM_SOURCE, 1);
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the uniform was found; otherwise %FALSE
|
* Returns: %TRUE if the uniform was found; otherwise %FALSE
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gsk_ngl_program_add_uniform (GskNglProgram *self,
|
gsk_gl_program_add_uniform (GskGLProgram *self,
|
||||||
const char *name,
|
const char *name,
|
||||||
guint key)
|
guint key)
|
||||||
{
|
{
|
||||||
GLint location;
|
GLint location;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_NGL_PROGRAM (self), FALSE);
|
g_return_val_if_fail (GSK_IS_GL_PROGRAM (self), FALSE);
|
||||||
g_return_val_if_fail (name != NULL, FALSE);
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
g_return_val_if_fail (key < G_N_ELEMENTS (self->mappings), FALSE);
|
g_return_val_if_fail (key < G_N_ELEMENTS (self->mappings), FALSE);
|
||||||
|
|
||||||
@ -133,41 +133,41 @@ gsk_ngl_program_add_uniform (GskNglProgram *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_ngl_program_delete:
|
* gsk_gl_program_delete:
|
||||||
* @self: a `GskNglProgram`
|
* @self: a `GskGLProgram`
|
||||||
*
|
*
|
||||||
* Deletes the GLSL program.
|
* Deletes the GLSL program.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gsk_ngl_program_delete (GskNglProgram *self)
|
gsk_gl_program_delete (GskGLProgram *self)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_NGL_PROGRAM (self));
|
g_return_if_fail (GSK_IS_GL_PROGRAM (self));
|
||||||
g_return_if_fail (self->driver->command_queue != NULL);
|
g_return_if_fail (self->driver->command_queue != NULL);
|
||||||
|
|
||||||
gsk_ngl_command_queue_delete_program (self->driver->command_queue, self->id);
|
gsk_gl_command_queue_delete_program (self->driver->command_queue, self->id);
|
||||||
self->id = -1;
|
self->id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_ngl_program_uniforms_added:
|
* gsk_gl_program_uniforms_added:
|
||||||
* @self: a `GskNglProgram`
|
* @self: a `GskGLProgram`
|
||||||
* @has_attachments: if any uniform is for a bind/texture attachment
|
* @has_attachments: if any uniform is for a bind/texture attachment
|
||||||
*
|
*
|
||||||
* This function should be called after all of the uniforms ahve
|
* This function should be called after all of the uniforms ahve
|
||||||
* been added with gsk_ngl_program_add_uniform().
|
* been added with gsk_gl_program_add_uniform().
|
||||||
*
|
*
|
||||||
* This function will setup the uniform state so that the program
|
* This function will setup the uniform state so that the program
|
||||||
* has fast access to the data buffers without as many lookups at
|
* has fast access to the data buffers without as many lookups at
|
||||||
* runtime for comparison data.
|
* runtime for comparison data.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gsk_ngl_program_uniforms_added (GskNglProgram *self,
|
gsk_gl_program_uniforms_added (GskGLProgram *self,
|
||||||
gboolean has_attachments)
|
gboolean has_attachments)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_NGL_PROGRAM (self));
|
g_return_if_fail (GSK_IS_GL_PROGRAM (self));
|
||||||
g_return_if_fail (self->uniforms == NULL);
|
g_return_if_fail (self->uniforms == NULL);
|
||||||
|
|
||||||
self->uniforms = self->driver->command_queue->uniforms;
|
self->uniforms = self->driver->command_queue->uniforms;
|
||||||
self->program_info = gsk_ngl_uniform_state_get_program (self->uniforms, self->id, self->mappings, self->n_mappings);
|
self->program_info = gsk_gl_uniform_state_get_program (self->uniforms, self->id, self->mappings, self->n_mappings);
|
||||||
self->program_info->has_attachments = has_attachments;
|
self->program_info->has_attachments = has_attachments;
|
||||||
}
|
}
|
282
gsk/gl/gskglprogramprivate.h
Normal file
282
gsk/gl/gskglprogramprivate.h
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
/* gskglprogramprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_PROGRAM_PRIVATE_H__
|
||||||
|
#define __GSK_GL_PROGRAM_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
|
#include "gskglattachmentstateprivate.h"
|
||||||
|
#include "gskglcommandqueueprivate.h"
|
||||||
|
#include "gskgldriverprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_PROGRAM (gsk_gl_program_get_type())
|
||||||
|
#define GSK_GL_PROGRAM_MAX_CUSTOM_TEXTURES 4
|
||||||
|
#define GSK_GL_PROGRAM_MAX_CUSTOM_ARGS 8
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLProgram, gsk_gl_program, GSK, GL_PROGRAM, GObject)
|
||||||
|
|
||||||
|
struct _GskGLProgram
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
char *name;
|
||||||
|
GskGLDriver *driver;
|
||||||
|
|
||||||
|
/* Cached pointer to avoid lots of pointer chasing/lookups */
|
||||||
|
GskGLUniformState *uniforms;
|
||||||
|
GskGLUniformProgram *program_info;
|
||||||
|
|
||||||
|
/* Static array for key->location transforms */
|
||||||
|
GskGLUniformMapping mappings[32];
|
||||||
|
guint n_mappings;
|
||||||
|
};
|
||||||
|
|
||||||
|
GskGLProgram * gsk_gl_program_new (GskGLDriver *driver,
|
||||||
|
const char *name,
|
||||||
|
int program_id);
|
||||||
|
gboolean gsk_gl_program_add_uniform (GskGLProgram *self,
|
||||||
|
const char *name,
|
||||||
|
guint key);
|
||||||
|
void gsk_gl_program_uniforms_added (GskGLProgram *self,
|
||||||
|
gboolean has_attachments);
|
||||||
|
void gsk_gl_program_delete (GskGLProgram *self);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform1fv (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *values)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set1fv (self->uniforms, self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
count,
|
||||||
|
values);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform2fv (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *values)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set2fv (self->uniforms, self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
count,
|
||||||
|
values);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform4fv (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *values)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set4fv (self->uniforms, self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
count,
|
||||||
|
values);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform_rounded_rect (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const GskRoundedRect *rounded_rect)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set_rounded_rect (self->uniforms, self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
rounded_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform1i (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set1i (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform2i (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set2i (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform3i (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1,
|
||||||
|
int value2)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set3i (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1, value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform4i (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1,
|
||||||
|
int value2,
|
||||||
|
int value3)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set4i (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1, value2, value3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform1f (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set1f (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform2f (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set2f (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform3f (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1,
|
||||||
|
float value2)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set3f (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1, value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform4f (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1,
|
||||||
|
float value2,
|
||||||
|
float value3)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set4f (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
value0, value1, value2, value3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform_color (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const GdkRGBA *color)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set_color (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
GLenum texture_target,
|
||||||
|
GLenum texture_slot,
|
||||||
|
guint texture_id)
|
||||||
|
{
|
||||||
|
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
||||||
|
texture_target,
|
||||||
|
texture_slot,
|
||||||
|
texture_id);
|
||||||
|
gsk_gl_uniform_state_set_texture (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
texture_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_program_set_uniform_matrix (GskGLProgram *self,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const graphene_matrix_t *matrix)
|
||||||
|
{
|
||||||
|
gsk_gl_uniform_state_set_matrix (self->uniforms,
|
||||||
|
self->program_info,
|
||||||
|
key,
|
||||||
|
stamp,
|
||||||
|
matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_PROGRAM_PRIVATE_H__ */
|
84
gsk/gl/gskglprograms.defs
Normal file
84
gsk/gl/gskglprograms.defs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
GSK_GL_DEFINE_PROGRAM (blend,
|
||||||
|
"/org/gtk/libgsk/gl/blend.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, BLEND_SOURCE2, u_source2)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, BLEND_MODE, u_mode))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (blit,
|
||||||
|
"/org/gtk/libgsk/gl/blit.glsl",
|
||||||
|
GSK_GL_NO_UNIFORMS)
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (blur,
|
||||||
|
"/org/gtk/libgsk/gl/blur.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, BLUR_RADIUS, u_blur_radius)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, BLUR_SIZE, u_blur_size)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, BLUR_DIR, u_blur_dir))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (border,
|
||||||
|
"/org/gtk/libgsk/gl/border.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, BORDER_WIDTHS, u_widths)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, BORDER_OUTLINE_RECT, u_outline_rect))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (color,
|
||||||
|
"/org/gtk/libgsk/gl/color.glsl",
|
||||||
|
GSK_GL_NO_UNIFORMS)
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (coloring,
|
||||||
|
"/org/gtk/libgsk/gl/coloring.glsl",
|
||||||
|
GSK_GL_NO_UNIFORMS)
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (color_matrix,
|
||||||
|
"/org/gtk/libgsk/gl/color_matrix.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, COLOR_MATRIX_COLOR_MATRIX, u_color_matrix)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, COLOR_MATRIX_COLOR_OFFSET, u_color_offset))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (conic_gradient,
|
||||||
|
"/org/gtk/libgsk/gl/conic_gradient.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, CONIC_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, CONIC_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, CONIC_GRADIENT_GEOMETRY, u_geometry))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (cross_fade,
|
||||||
|
"/org/gtk/libgsk/gl/cross_fade.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, CROSS_FADE_PROGRESS, u_progress)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, CROSS_FADE_SOURCE2, u_source2))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (filled_border,
|
||||||
|
"/org/gtk/libgsk/gl/filled_border.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, FILLED_BORDER_WIDTHS, u_widths)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, FILLED_BORDER_OUTLINE_RECT, u_outline_rect))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (inset_shadow,
|
||||||
|
"/org/gtk/libgsk/gl/inset_shadow.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, INSET_SHADOW_SPREAD, u_spread)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, INSET_SHADOW_OFFSET, u_offset)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, INSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (linear_gradient,
|
||||||
|
"/org/gtk/libgsk/gl/linear_gradient.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, LINEAR_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, LINEAR_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points)
|
||||||
|
GSK_GL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (outset_shadow,
|
||||||
|
"/org/gtk/libgsk/gl/outset_shadow.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (radial_gradient,
|
||||||
|
"/org/gtk/libgsk/gl/radial_gradient.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, RADIAL_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, RADIAL_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, RADIAL_GRADIENT_REPEAT, u_repeat)
|
||||||
|
GSK_GL_ADD_UNIFORM (4, RADIAL_GRADIENT_RANGE, u_range)
|
||||||
|
GSK_GL_ADD_UNIFORM (5, RADIAL_GRADIENT_GEOMETRY, u_geometry))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (repeat,
|
||||||
|
"/org/gtk/libgsk/gl/repeat.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, REPEAT_CHILD_BOUNDS, u_child_bounds)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, REPEAT_TEXTURE_RECT, u_texture_rect))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
||||||
|
"/org/gtk/libgsk/gl/unblurred_outset_shadow.glsl",
|
||||||
|
GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
|
||||||
|
GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglrenderer.c
|
/* gskglrenderer.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -28,18 +28,18 @@
|
|||||||
#include <gsk/gskrendererprivate.h>
|
#include <gsk/gskrendererprivate.h>
|
||||||
#include <gsk/gskrendernodeprivate.h>
|
#include <gsk/gskrendernodeprivate.h>
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gskngldriverprivate.h"
|
#include "gskgldriverprivate.h"
|
||||||
#include "gsknglprogramprivate.h"
|
#include "gskglprogramprivate.h"
|
||||||
#include "gsknglrenderjobprivate.h"
|
#include "gskglrenderjobprivate.h"
|
||||||
#include "gsknglrendererprivate.h"
|
#include "gskglrendererprivate.h"
|
||||||
|
|
||||||
struct _GskNglRendererClass
|
struct _GskGLRendererClass
|
||||||
{
|
{
|
||||||
GskRendererClass parent_class;
|
GskRendererClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GskNglRenderer
|
struct _GskGLRenderer
|
||||||
{
|
{
|
||||||
GskRenderer parent_instance;
|
GskRenderer parent_instance;
|
||||||
|
|
||||||
@ -55,45 +55,45 @@ struct _GskNglRenderer
|
|||||||
* contexts from other renderers on the display, texture atlases,
|
* contexts from other renderers on the display, texture atlases,
|
||||||
* programs, and other objects are available to them all.
|
* programs, and other objects are available to them all.
|
||||||
*/
|
*/
|
||||||
GskNglCommandQueue *command_queue;
|
GskGLCommandQueue *command_queue;
|
||||||
|
|
||||||
/* The driver manages our program state and command queues. It also
|
/* The driver manages our program state and command queues. It also
|
||||||
* deals with caching textures, shaders, shadows, glyph, and icon
|
* deals with caching textures, shaders, shadows, glyph, and icon
|
||||||
* caches through various helpers.
|
* caches through various helpers.
|
||||||
*/
|
*/
|
||||||
GskNglDriver *driver;
|
GskGLDriver *driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglRenderer, gsk_ngl_renderer, GSK_TYPE_RENDERER)
|
G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_RENDERER)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_ngl_renderer_new:
|
* gsk_gl_renderer_new:
|
||||||
*
|
*
|
||||||
* Creates a new `GskRenderer` using the new OpenGL renderer.
|
* Creates a new `GskRenderer` using the new OpenGL renderer.
|
||||||
*
|
*
|
||||||
* Returns: a new NGL renderer
|
* Returns: a new GL renderer
|
||||||
*
|
*
|
||||||
* Since: 4.2
|
* Since: 4.2
|
||||||
*/
|
*/
|
||||||
GskRenderer *
|
GskRenderer *
|
||||||
gsk_ngl_renderer_new (void)
|
gsk_gl_renderer_new (void)
|
||||||
{
|
{
|
||||||
return g_object_new (GSK_TYPE_NGL_RENDERER, NULL);
|
return g_object_new (GSK_TYPE_GL_RENDERER, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gsk_ngl_renderer_realize (GskRenderer *renderer,
|
gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||||
GdkSurface *surface,
|
GdkSurface *surface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
GskNglRenderer *self = (GskNglRenderer *)renderer;
|
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||||
GdkGLContext *context = NULL;
|
GdkGLContext *context = NULL;
|
||||||
GskNglDriver *driver = NULL;
|
GskGLDriver *driver = NULL;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gboolean debug_shaders = FALSE;
|
gboolean debug_shaders = FALSE;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_RENDERER (self));
|
g_assert (GSK_IS_GL_RENDERER (self));
|
||||||
g_assert (GDK_IS_SURFACE (surface));
|
g_assert (GDK_IS_SURFACE (surface));
|
||||||
|
|
||||||
if (self->context != NULL)
|
if (self->context != NULL)
|
||||||
@ -112,15 +112,15 @@ gsk_ngl_renderer_realize (GskRenderer *renderer,
|
|||||||
debug_shaders = TRUE;
|
debug_shaders = TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(driver = gsk_ngl_driver_for_display (gdk_surface_get_display (surface), debug_shaders, error)))
|
if (!(driver = gsk_gl_driver_for_display (gdk_surface_get_display (surface), debug_shaders, error)))
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
self->command_queue = gsk_ngl_driver_create_command_queue (driver, context);
|
self->command_queue = gsk_gl_driver_create_command_queue (driver, context);
|
||||||
self->context = g_steal_pointer (&context);
|
self->context = g_steal_pointer (&context);
|
||||||
self->driver = g_steal_pointer (&driver);
|
self->driver = g_steal_pointer (&driver);
|
||||||
|
|
||||||
gsk_ngl_command_queue_set_profiler (self->command_queue,
|
gsk_gl_command_queue_set_profiler (self->command_queue,
|
||||||
gsk_renderer_get_profiler (renderer));
|
gsk_renderer_get_profiler (renderer));
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
@ -128,17 +128,17 @@ failure:
|
|||||||
g_clear_object (&driver);
|
g_clear_object (&driver);
|
||||||
g_clear_object (&context);
|
g_clear_object (&context);
|
||||||
|
|
||||||
gdk_profiler_end_mark (start_time, "realize GskNglRenderer", NULL);
|
gdk_profiler_end_mark (start_time, "realize GskGLRenderer", NULL);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_renderer_unrealize (GskRenderer *renderer)
|
gsk_gl_renderer_unrealize (GskRenderer *renderer)
|
||||||
{
|
{
|
||||||
GskNglRenderer *self = (GskNglRenderer *)renderer;
|
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_RENDERER (renderer));
|
g_assert (GSK_IS_GL_RENDERER (renderer));
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->context);
|
gdk_gl_context_make_current (self->context);
|
||||||
|
|
||||||
@ -181,18 +181,18 @@ get_render_region (GdkSurface *surface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_renderer_render (GskRenderer *renderer,
|
gsk_gl_renderer_render (GskRenderer *renderer,
|
||||||
GskRenderNode *root,
|
GskRenderNode *root,
|
||||||
const cairo_region_t *update_area)
|
const cairo_region_t *update_area)
|
||||||
{
|
{
|
||||||
GskNglRenderer *self = (GskNglRenderer *)renderer;
|
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||||
cairo_region_t *render_region;
|
cairo_region_t *render_region;
|
||||||
graphene_rect_t viewport;
|
graphene_rect_t viewport;
|
||||||
GskNglRenderJob *job;
|
GskGLRenderJob *job;
|
||||||
GdkSurface *surface;
|
GdkSurface *surface;
|
||||||
float scale_factor;
|
float scale_factor;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_RENDERER (renderer));
|
g_assert (GSK_IS_GL_RENDERER (renderer));
|
||||||
g_assert (root != NULL);
|
g_assert (root != NULL);
|
||||||
|
|
||||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context));
|
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context));
|
||||||
@ -211,39 +211,39 @@ gsk_ngl_renderer_render (GskRenderer *renderer,
|
|||||||
/* Must be called *AFTER* gdk_draw_context_begin_frame() */
|
/* Must be called *AFTER* gdk_draw_context_begin_frame() */
|
||||||
render_region = get_render_region (surface, self->context);
|
render_region = get_render_region (surface, self->context);
|
||||||
|
|
||||||
gsk_ngl_driver_begin_frame (self->driver, self->command_queue);
|
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||||
job = gsk_ngl_render_job_new (self->driver, &viewport, scale_factor, render_region, 0);
|
job = gsk_gl_render_job_new (self->driver, &viewport, scale_factor, render_region, 0);
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||||
gsk_ngl_render_job_set_debug_fallback (job, TRUE);
|
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||||
#endif
|
#endif
|
||||||
gsk_ngl_render_job_render (job, root);
|
gsk_gl_render_job_render (job, root);
|
||||||
gsk_ngl_driver_end_frame (self->driver);
|
gsk_gl_driver_end_frame (self->driver);
|
||||||
gsk_ngl_render_job_free (job);
|
gsk_gl_render_job_free (job);
|
||||||
|
|
||||||
gdk_gl_context_make_current (self->context);
|
gdk_gl_context_make_current (self->context);
|
||||||
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));
|
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));
|
||||||
|
|
||||||
gsk_ngl_driver_after_frame (self->driver);
|
gsk_gl_driver_after_frame (self->driver);
|
||||||
|
|
||||||
cairo_region_destroy (render_region);
|
cairo_region_destroy (render_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkTexture *
|
static GdkTexture *
|
||||||
gsk_ngl_renderer_render_texture (GskRenderer *renderer,
|
gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||||
GskRenderNode *root,
|
GskRenderNode *root,
|
||||||
const graphene_rect_t *viewport)
|
const graphene_rect_t *viewport)
|
||||||
{
|
{
|
||||||
GskNglRenderer *self = (GskNglRenderer *)renderer;
|
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||||
GskNglRenderTarget *render_target;
|
GskGLRenderTarget *render_target;
|
||||||
GskNglRenderJob *job;
|
GskGLRenderJob *job;
|
||||||
GdkTexture *texture = NULL;
|
GdkTexture *texture = NULL;
|
||||||
guint texture_id;
|
guint texture_id;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_RENDERER (renderer));
|
g_assert (GSK_IS_GL_RENDERER (renderer));
|
||||||
g_assert (root != NULL);
|
g_assert (root != NULL);
|
||||||
|
|
||||||
width = ceilf (viewport->size.width);
|
width = ceilf (viewport->size.width);
|
||||||
@ -251,72 +251,121 @@ gsk_ngl_renderer_render_texture (GskRenderer *renderer,
|
|||||||
|
|
||||||
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
|
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
|
||||||
|
|
||||||
if (gsk_ngl_driver_create_render_target (self->driver,
|
if (gsk_gl_driver_create_render_target (self->driver,
|
||||||
width, height,
|
width, height,
|
||||||
format,
|
format,
|
||||||
GL_NEAREST, GL_NEAREST,
|
GL_NEAREST, GL_NEAREST,
|
||||||
&render_target))
|
&render_target))
|
||||||
{
|
{
|
||||||
gsk_ngl_driver_begin_frame (self->driver, self->command_queue);
|
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||||
job = gsk_ngl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id);
|
job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id);
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||||
gsk_ngl_render_job_set_debug_fallback (job, TRUE);
|
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||||
#endif
|
#endif
|
||||||
gsk_ngl_render_job_render_flipped (job, root);
|
gsk_gl_render_job_render_flipped (job, root);
|
||||||
texture_id = gsk_ngl_driver_release_render_target (self->driver, render_target, FALSE);
|
texture_id = gsk_gl_driver_release_render_target (self->driver, render_target, FALSE);
|
||||||
texture = gsk_ngl_driver_create_gdk_texture (self->driver, texture_id);
|
texture = gsk_gl_driver_create_gdk_texture (self->driver, texture_id);
|
||||||
gsk_ngl_driver_end_frame (self->driver);
|
gsk_gl_driver_end_frame (self->driver);
|
||||||
gsk_ngl_render_job_free (job);
|
gsk_gl_render_job_free (job);
|
||||||
|
|
||||||
gsk_ngl_driver_after_frame (self->driver);
|
gsk_gl_driver_after_frame (self->driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_steal_pointer (&texture);
|
return g_steal_pointer (&texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_renderer_dispose (GObject *object)
|
gsk_gl_renderer_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
GskNglRenderer *self = (GskNglRenderer *)object;
|
GskGLRenderer *self = (GskGLRenderer *)object;
|
||||||
|
|
||||||
g_assert (self->driver == NULL);
|
g_assert (self->driver == NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_renderer_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_renderer_class_init (GskNglRendererClass *klass)
|
gsk_gl_renderer_class_init (GskGLRendererClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
|
GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
|
||||||
|
|
||||||
object_class->dispose = gsk_ngl_renderer_dispose;
|
object_class->dispose = gsk_gl_renderer_dispose;
|
||||||
|
|
||||||
renderer_class->realize = gsk_ngl_renderer_realize;
|
renderer_class->realize = gsk_gl_renderer_realize;
|
||||||
renderer_class->unrealize = gsk_ngl_renderer_unrealize;
|
renderer_class->unrealize = gsk_gl_renderer_unrealize;
|
||||||
renderer_class->render = gsk_ngl_renderer_render;
|
renderer_class->render = gsk_gl_renderer_render;
|
||||||
renderer_class->render_texture = gsk_ngl_renderer_render_texture;
|
renderer_class->render_texture = gsk_gl_renderer_render_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_renderer_init (GskNglRenderer *self)
|
gsk_gl_renderer_init (GskGLRenderer *self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gsk_ngl_renderer_try_compile_gl_shader (GskNglRenderer *renderer,
|
gsk_gl_renderer_try_compile_gl_shader (GskGLRenderer *renderer,
|
||||||
GskGLShader *shader,
|
GskGLShader *shader,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GskNglProgram *program;
|
GskGLProgram *program;
|
||||||
|
|
||||||
g_return_val_if_fail (GSK_IS_NGL_RENDERER (renderer), FALSE);
|
g_return_val_if_fail (GSK_IS_GL_RENDERER (renderer), FALSE);
|
||||||
g_return_val_if_fail (shader != NULL, FALSE);
|
g_return_val_if_fail (shader != NULL, FALSE);
|
||||||
|
|
||||||
program = gsk_ngl_driver_lookup_shader (renderer->driver, shader, error);
|
program = gsk_gl_driver_lookup_shader (renderer->driver, shader, error);
|
||||||
|
|
||||||
return program != NULL;
|
return program != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GskRenderer parent_instance;
|
||||||
|
} GskNglRenderer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GskRendererClass parent_class;
|
||||||
|
} GskNglRendererClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GskNglRenderer, gsk_ngl_renderer, GSK_TYPE_RENDERER)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_ngl_renderer_init (GskNglRenderer *renderer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gsk_ngl_renderer_realize (GskRenderer *renderer,
|
||||||
|
GdkSurface *surface,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"please use the GL renderer instead");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_ngl_renderer_class_init (GskNglRendererClass *class)
|
||||||
|
{
|
||||||
|
GSK_RENDERER_CLASS (class)->realize = gsk_ngl_renderer_realize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_ngl_renderer_new:
|
||||||
|
*
|
||||||
|
* Same as gsk_gl_renderer_new().
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a new GL renderer
|
||||||
|
*
|
||||||
|
* Deprecated: 4.4: Use gsk_gl_renderer_new()
|
||||||
|
*/
|
||||||
|
GskRenderer *
|
||||||
|
gsk_ngl_renderer_new (void)
|
||||||
|
{
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||||
|
return g_object_new (gsk_ngl_renderer_get_type (), NULL);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
}
|
50
gsk/gl/gskglrenderer.h
Normal file
50
gsk/gl/gskglrenderer.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* gskglrenderer.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_RENDERER_H__
|
||||||
|
#define __GSK_GL_RENDERER_H__
|
||||||
|
|
||||||
|
#include <gsk/gskrenderer.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_RENDERER (gsk_gl_renderer_get_type())
|
||||||
|
|
||||||
|
#define GSK_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_RENDERER, GskGLRenderer))
|
||||||
|
#define GSK_IS_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_RENDERER))
|
||||||
|
#define GSK_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
|
||||||
|
#define GSK_IS_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_RENDERER))
|
||||||
|
#define GSK_GL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
|
||||||
|
|
||||||
|
typedef struct _GskGLRenderer GskGLRenderer;
|
||||||
|
typedef struct _GskGLRendererClass GskGLRendererClass;
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_2
|
||||||
|
GType gsk_gl_renderer_get_type (void) G_GNUC_CONST;
|
||||||
|
GDK_AVAILABLE_IN_4_2
|
||||||
|
GskRenderer *gsk_gl_renderer_new (void);
|
||||||
|
|
||||||
|
GDK_DEPRECATED_IN_4_4_FOR (gsk_gl_renderer_get_type)
|
||||||
|
GType gsk_ngl_renderer_get_type (void) G_GNUC_CONST;
|
||||||
|
GDK_DEPRECATED_IN_4_4_FOR (gsk_gl_renderer_new)
|
||||||
|
GskRenderer *gsk_ngl_renderer_new (void);
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_RENDERER__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglrendererprivate.h
|
/* gskglrendererprivate.h
|
||||||
*
|
*
|
||||||
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
* Copyright 2021 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -18,17 +18,17 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __GSK_NGL_RENDERER_PRIVATE_H__
|
#ifndef __GSK_GL_RENDERER_PRIVATE_H__
|
||||||
#define __GSK_NGL_RENDERER_PRIVATE_H__
|
#define __GSK_GL_RENDERER_PRIVATE_H__
|
||||||
|
|
||||||
#include "gsknglrenderer.h"
|
#include "gskglrenderer.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
gboolean gsk_ngl_renderer_try_compile_gl_shader (GskNglRenderer *renderer,
|
gboolean gsk_gl_renderer_try_compile_gl_shader (GskGLRenderer *renderer,
|
||||||
GskGLShader *shader,
|
GskGLShader *shader,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GSK_NGL_RENDERER_PRIVATE_H__ */
|
#endif /* __GSK_GL_RENDERER_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
39
gsk/gl/gskglrenderjobprivate.h
Normal file
39
gsk/gl/gskglrenderjobprivate.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* gskglrenderjobprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_RENDER_JOB_H__
|
||||||
|
#define __GSK_GL_RENDER_JOB_H__
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
|
GskGLRenderJob *gsk_gl_render_job_new (GskGLDriver *driver,
|
||||||
|
const graphene_rect_t *viewport,
|
||||||
|
float scale_factor,
|
||||||
|
const cairo_region_t *region,
|
||||||
|
guint framebuffer);
|
||||||
|
void gsk_gl_render_job_free (GskGLRenderJob *job);
|
||||||
|
void gsk_gl_render_job_render (GskGLRenderJob *job,
|
||||||
|
GskRenderNode *root);
|
||||||
|
void gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
|
||||||
|
GskRenderNode *root);
|
||||||
|
void gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
|
||||||
|
gboolean debug_fallback);
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_RENDER_JOB_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gsknglshadowlibrary.c
|
/* gskglshadowlibrary.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -22,15 +22,15 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gskngldriverprivate.h"
|
#include "gskgldriverprivate.h"
|
||||||
#include "gsknglshadowlibraryprivate.h"
|
#include "gskglshadowlibraryprivate.h"
|
||||||
|
|
||||||
#define MAX_UNUSED_FRAMES (16 * 5)
|
#define MAX_UNUSED_FRAMES (16 * 5)
|
||||||
|
|
||||||
struct _GskNglShadowLibrary
|
struct _GskGLShadowLibrary
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
GskNglDriver *driver;
|
GskGLDriver *driver;
|
||||||
GArray *shadows;
|
GArray *shadows;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ typedef struct _Shadow
|
|||||||
gint64 last_used_in_frame;
|
gint64 last_used_in_frame;
|
||||||
} Shadow;
|
} Shadow;
|
||||||
|
|
||||||
G_DEFINE_TYPE (GskNglShadowLibrary, gsk_ngl_shadow_library, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GskGLShadowLibrary, gsk_gl_shadow_library, G_TYPE_OBJECT)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -52,10 +52,10 @@ enum {
|
|||||||
|
|
||||||
static GParamSpec *properties [N_PROPS];
|
static GParamSpec *properties [N_PROPS];
|
||||||
|
|
||||||
GskNglShadowLibrary *
|
GskGLShadowLibrary *
|
||||||
gsk_ngl_shadow_library_new (GskNglDriver *driver)
|
gsk_gl_shadow_library_new (GskGLDriver *driver)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_NGL_DRIVER (driver), NULL);
|
g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
|
||||||
|
|
||||||
return g_object_new (GSK_TYPE_GL_SHADOW_LIBRARY,
|
return g_object_new (GSK_TYPE_GL_SHADOW_LIBRARY,
|
||||||
"driver", driver,
|
"driver", driver,
|
||||||
@ -63,29 +63,29 @@ gsk_ngl_shadow_library_new (GskNglDriver *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_shadow_library_dispose (GObject *object)
|
gsk_gl_shadow_library_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
GskNglShadowLibrary *self = (GskNglShadowLibrary *)object;
|
GskGLShadowLibrary *self = (GskGLShadowLibrary *)object;
|
||||||
|
|
||||||
for (guint i = 0; i < self->shadows->len; i++)
|
for (guint i = 0; i < self->shadows->len; i++)
|
||||||
{
|
{
|
||||||
const Shadow *shadow = &g_array_index (self->shadows, Shadow, i);
|
const Shadow *shadow = &g_array_index (self->shadows, Shadow, i);
|
||||||
gsk_ngl_driver_release_texture_by_id (self->driver, shadow->texture_id);
|
gsk_gl_driver_release_texture_by_id (self->driver, shadow->texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_pointer (&self->shadows, g_array_unref);
|
g_clear_pointer (&self->shadows, g_array_unref);
|
||||||
g_clear_object (&self->driver);
|
g_clear_object (&self->driver);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_shadow_library_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gsk_gl_shadow_library_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_shadow_library_get_property (GObject *object,
|
gsk_gl_shadow_library_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GskNglShadowLibrary *self = GSK_NGL_SHADOW_LIBRARY (object);
|
GskGLShadowLibrary *self = GSK_GL_SHADOW_LIBRARY (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -99,12 +99,12 @@ gsk_ngl_shadow_library_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_shadow_library_set_property (GObject *object,
|
gsk_gl_shadow_library_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GskNglShadowLibrary *self = GSK_NGL_SHADOW_LIBRARY (object);
|
GskGLShadowLibrary *self = GSK_GL_SHADOW_LIBRARY (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -118,43 +118,43 @@ gsk_ngl_shadow_library_set_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_shadow_library_class_init (GskNglShadowLibraryClass *klass)
|
gsk_gl_shadow_library_class_init (GskGLShadowLibraryClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->dispose = gsk_ngl_shadow_library_dispose;
|
object_class->dispose = gsk_gl_shadow_library_dispose;
|
||||||
object_class->get_property = gsk_ngl_shadow_library_get_property;
|
object_class->get_property = gsk_gl_shadow_library_get_property;
|
||||||
object_class->set_property = gsk_ngl_shadow_library_set_property;
|
object_class->set_property = gsk_gl_shadow_library_set_property;
|
||||||
|
|
||||||
properties [PROP_DRIVER] =
|
properties [PROP_DRIVER] =
|
||||||
g_param_spec_object ("driver",
|
g_param_spec_object ("driver",
|
||||||
"Driver",
|
"Driver",
|
||||||
"Driver",
|
"Driver",
|
||||||
GSK_TYPE_NGL_DRIVER,
|
GSK_TYPE_GL_DRIVER,
|
||||||
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_shadow_library_init (GskNglShadowLibrary *self)
|
gsk_gl_shadow_library_init (GskGLShadowLibrary *self)
|
||||||
{
|
{
|
||||||
self->shadows = g_array_new (FALSE, FALSE, sizeof (Shadow));
|
self->shadows = g_array_new (FALSE, FALSE, sizeof (Shadow));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_shadow_library_insert (GskNglShadowLibrary *self,
|
gsk_gl_shadow_library_insert (GskGLShadowLibrary *self,
|
||||||
const GskRoundedRect *outline,
|
const GskRoundedRect *outline,
|
||||||
float blur_radius,
|
float blur_radius,
|
||||||
guint texture_id)
|
guint texture_id)
|
||||||
{
|
{
|
||||||
Shadow *shadow;
|
Shadow *shadow;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_SHADOW_LIBRARY (self));
|
g_assert (GSK_IS_GL_SHADOW_LIBRARY (self));
|
||||||
g_assert (outline != NULL);
|
g_assert (outline != NULL);
|
||||||
g_assert (texture_id != 0);
|
g_assert (texture_id != 0);
|
||||||
|
|
||||||
gsk_ngl_driver_mark_texture_permanent (self->driver, texture_id);
|
gsk_gl_driver_mark_texture_permanent (self->driver, texture_id);
|
||||||
|
|
||||||
g_array_set_size (self->shadows, self->shadows->len + 1);
|
g_array_set_size (self->shadows, self->shadows->len + 1);
|
||||||
|
|
||||||
@ -166,13 +166,13 @@ gsk_ngl_shadow_library_insert (GskNglShadowLibrary *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
gsk_ngl_shadow_library_lookup (GskNglShadowLibrary *self,
|
gsk_gl_shadow_library_lookup (GskGLShadowLibrary *self,
|
||||||
const GskRoundedRect *outline,
|
const GskRoundedRect *outline,
|
||||||
float blur_radius)
|
float blur_radius)
|
||||||
{
|
{
|
||||||
Shadow *ret = NULL;
|
Shadow *ret = NULL;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_SHADOW_LIBRARY (self));
|
g_assert (GSK_IS_GL_SHADOW_LIBRARY (self));
|
||||||
g_assert (outline != NULL);
|
g_assert (outline != NULL);
|
||||||
|
|
||||||
/* Ensure GskRoundedRect is 12 packed floats without padding
|
/* Ensure GskRoundedRect is 12 packed floats without padding
|
||||||
@ -204,7 +204,7 @@ gsk_ngl_shadow_library_lookup (GskNglShadowLibrary *self,
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void
|
static void
|
||||||
write_shadow_to_png (GskNglDriver *driver,
|
write_shadow_to_png (GskGLDriver *driver,
|
||||||
const Shadow *shadow)
|
const Shadow *shadow)
|
||||||
{
|
{
|
||||||
int width = shadow->outline.bounds.size.width + (shadow->outline.bounds.origin.x * 2);
|
int width = shadow->outline.bounds.size.width + (shadow->outline.bounds.origin.x * 2);
|
||||||
@ -213,7 +213,7 @@ write_shadow_to_png (GskNglDriver *driver,
|
|||||||
width, height, shadow->texture_id);
|
width, height, shadow->texture_id);
|
||||||
GdkTexture *texture;
|
GdkTexture *texture;
|
||||||
|
|
||||||
texture = gdk_gl_texture_new (gsk_ngl_driver_get_context (driver),
|
texture = gdk_gl_texture_new (gsk_gl_driver_get_context (driver),
|
||||||
shadow->texture_id,
|
shadow->texture_id,
|
||||||
width, height,
|
width, height,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
@ -225,13 +225,13 @@ write_shadow_to_png (GskNglDriver *driver,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_shadow_library_begin_frame (GskNglShadowLibrary *self)
|
gsk_gl_shadow_library_begin_frame (GskGLShadowLibrary *self)
|
||||||
{
|
{
|
||||||
gint64 watermark;
|
gint64 watermark;
|
||||||
int i;
|
int i;
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_SHADOW_LIBRARY (self));
|
g_return_if_fail (GSK_IS_GL_SHADOW_LIBRARY (self));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (i = 0, p = self->shadows->len; i < p; i++)
|
for (i = 0, p = self->shadows->len; i < p; i++)
|
||||||
@ -249,7 +249,7 @@ gsk_ngl_shadow_library_begin_frame (GskNglShadowLibrary *self)
|
|||||||
|
|
||||||
if (shadow->last_used_in_frame < watermark)
|
if (shadow->last_used_in_frame < watermark)
|
||||||
{
|
{
|
||||||
gsk_ngl_driver_release_texture_by_id (self->driver, shadow->texture_id);
|
gsk_gl_driver_release_texture_by_id (self->driver, shadow->texture_id);
|
||||||
g_array_remove_index_fast (self->shadows, i);
|
g_array_remove_index_fast (self->shadows, i);
|
||||||
p--;
|
p--;
|
||||||
i--;
|
i--;
|
44
gsk/gl/gskglshadowlibraryprivate.h
Normal file
44
gsk/gl/gskglshadowlibraryprivate.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* gskglshadowlibraryprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_SHADOW_LIBRARY_PRIVATE_H__
|
||||||
|
#define __GSK_GL_SHADOW_LIBRARY_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gskgltexturelibraryprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_SHADOW_LIBRARY (gsk_gl_shadow_library_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GskGLShadowLibrary, gsk_gl_shadow_library, GSK, GL_SHADOW_LIBRARY, GObject)
|
||||||
|
|
||||||
|
GskGLShadowLibrary * gsk_gl_shadow_library_new (GskGLDriver *driver);
|
||||||
|
void gsk_gl_shadow_library_begin_frame (GskGLShadowLibrary *self);
|
||||||
|
guint gsk_gl_shadow_library_lookup (GskGLShadowLibrary *self,
|
||||||
|
const GskRoundedRect *outline,
|
||||||
|
float blur_radius);
|
||||||
|
void gsk_gl_shadow_library_insert (GskGLShadowLibrary *self,
|
||||||
|
const GskRoundedRect *outline,
|
||||||
|
float blur_radius,
|
||||||
|
guint texture_id);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_SHADOW_LIBRARY_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gskngltexture.c
|
/* gskgltexture.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
#include <gdk/gdktextureprivate.h>
|
#include <gdk/gdktextureprivate.h>
|
||||||
|
|
||||||
#include "gskngltextureprivate.h"
|
#include "gskgltextureprivate.h"
|
||||||
#include "ninesliceprivate.h"
|
#include "ninesliceprivate.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_texture_free (GskNglTexture *texture)
|
gsk_gl_texture_free (GskGLTexture *texture)
|
||||||
{
|
{
|
||||||
if (texture != NULL)
|
if (texture != NULL)
|
||||||
{
|
{
|
||||||
@ -51,22 +51,22 @@ gsk_ngl_texture_free (GskNglTexture *texture)
|
|||||||
g_clear_pointer (&texture->slices, g_free);
|
g_clear_pointer (&texture->slices, g_free);
|
||||||
g_clear_pointer (&texture->nine_slice, g_free);
|
g_clear_pointer (&texture->nine_slice, g_free);
|
||||||
|
|
||||||
g_slice_free (GskNglTexture, texture);
|
g_slice_free (GskGLTexture, texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglTexture *
|
GskGLTexture *
|
||||||
gsk_ngl_texture_new (guint texture_id,
|
gsk_gl_texture_new (guint texture_id,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int format,
|
int format,
|
||||||
int min_filter,
|
int min_filter,
|
||||||
int mag_filter,
|
int mag_filter,
|
||||||
gint64 frame_id)
|
gint64 frame_id)
|
||||||
{
|
{
|
||||||
GskNglTexture *texture;
|
GskGLTexture *texture;
|
||||||
|
|
||||||
texture = g_slice_new0 (GskNglTexture);
|
texture = g_slice_new0 (GskGLTexture);
|
||||||
texture->texture_id = texture_id;
|
texture->texture_id = texture_id;
|
||||||
texture->link.data = texture;
|
texture->link.data = texture;
|
||||||
texture->min_filter = min_filter;
|
texture->min_filter = min_filter;
|
||||||
@ -79,18 +79,18 @@ gsk_ngl_texture_new (guint texture_id,
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GskNglTextureNineSlice *
|
const GskGLTextureNineSlice *
|
||||||
gsk_ngl_texture_get_nine_slice (GskNglTexture *texture,
|
gsk_gl_texture_get_nine_slice (GskGLTexture *texture,
|
||||||
const GskRoundedRect *outline,
|
const GskRoundedRect *outline,
|
||||||
float extra_pixels_x,
|
float extra_pixels_x,
|
||||||
float extra_pixels_y)
|
float extra_pixels_y)
|
||||||
{
|
{
|
||||||
g_assert (texture != NULL);
|
g_assert (texture != NULL);
|
||||||
g_assert (outline != NULL);
|
g_assert (outline != NULL);
|
||||||
|
|
||||||
if G_UNLIKELY (texture->nine_slice == NULL)
|
if G_UNLIKELY (texture->nine_slice == NULL)
|
||||||
{
|
{
|
||||||
texture->nine_slice = g_new0 (GskNglTextureNineSlice, 9);
|
texture->nine_slice = g_new0 (GskGLTextureNineSlice, 9);
|
||||||
|
|
||||||
nine_slice_rounded_rect (texture->nine_slice, outline);
|
nine_slice_rounded_rect (texture->nine_slice, outline);
|
||||||
nine_slice_grow (texture->nine_slice, extra_pixels_x, extra_pixels_y);
|
nine_slice_grow (texture->nine_slice, extra_pixels_x, extra_pixels_y);
|
@ -1,4 +1,4 @@
|
|||||||
/* gskngltexturelibrary.c
|
/* gskgltexturelibrary.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -23,13 +23,13 @@
|
|||||||
#include <gdk/gdkglcontextprivate.h>
|
#include <gdk/gdkglcontextprivate.h>
|
||||||
#include <gsk/gskdebugprivate.h>
|
#include <gsk/gskdebugprivate.h>
|
||||||
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
#include "gskglcommandqueueprivate.h"
|
||||||
#include "gskngldriverprivate.h"
|
#include "gskgldriverprivate.h"
|
||||||
#include "gskngltexturelibraryprivate.h"
|
#include "gskgltexturelibraryprivate.h"
|
||||||
|
|
||||||
#define MAX_FRAME_AGE 60
|
#define MAX_FRAME_AGE 60
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (GskNglTextureLibrary, gsk_ngl_texture_library, G_TYPE_OBJECT)
|
G_DEFINE_ABSTRACT_TYPE (GskGLTextureLibrary, gsk_gl_texture_library, G_TYPE_OBJECT)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -40,30 +40,30 @@ enum {
|
|||||||
static GParamSpec *properties [N_PROPS];
|
static GParamSpec *properties [N_PROPS];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_constructed (GObject *object)
|
gsk_gl_texture_library_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS (gsk_ngl_texture_library_parent_class)->constructed (object);
|
G_OBJECT_CLASS (gsk_gl_texture_library_parent_class)->constructed (object);
|
||||||
|
|
||||||
g_assert (GSK_NGL_TEXTURE_LIBRARY (object)->hash_table != NULL);
|
g_assert (GSK_GL_TEXTURE_LIBRARY (object)->hash_table != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_dispose (GObject *object)
|
gsk_gl_texture_library_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *self = (GskNglTextureLibrary *)object;
|
GskGLTextureLibrary *self = (GskGLTextureLibrary *)object;
|
||||||
|
|
||||||
g_clear_object (&self->driver);
|
g_clear_object (&self->driver);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gsk_ngl_texture_library_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gsk_gl_texture_library_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_get_property (GObject *object,
|
gsk_gl_texture_library_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *self = GSK_NGL_TEXTURE_LIBRARY (object);
|
GskGLTextureLibrary *self = GSK_GL_TEXTURE_LIBRARY (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -77,12 +77,12 @@ gsk_ngl_texture_library_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_set_property (GObject *object,
|
gsk_gl_texture_library_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GskNglTextureLibrary *self = GSK_NGL_TEXTURE_LIBRARY (object);
|
GskGLTextureLibrary *self = GSK_GL_TEXTURE_LIBRARY (object);
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@ -96,38 +96,38 @@ gsk_ngl_texture_library_set_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_class_init (GskNglTextureLibraryClass *klass)
|
gsk_gl_texture_library_class_init (GskGLTextureLibraryClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->constructed = gsk_ngl_texture_library_constructed;
|
object_class->constructed = gsk_gl_texture_library_constructed;
|
||||||
object_class->dispose = gsk_ngl_texture_library_dispose;
|
object_class->dispose = gsk_gl_texture_library_dispose;
|
||||||
object_class->get_property = gsk_ngl_texture_library_get_property;
|
object_class->get_property = gsk_gl_texture_library_get_property;
|
||||||
object_class->set_property = gsk_ngl_texture_library_set_property;
|
object_class->set_property = gsk_gl_texture_library_set_property;
|
||||||
|
|
||||||
properties [PROP_DRIVER] =
|
properties [PROP_DRIVER] =
|
||||||
g_param_spec_object ("driver",
|
g_param_spec_object ("driver",
|
||||||
"Driver",
|
"Driver",
|
||||||
"Driver",
|
"Driver",
|
||||||
GSK_TYPE_NGL_DRIVER,
|
GSK_TYPE_GL_DRIVER,
|
||||||
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_library_init (GskNglTextureLibrary *self)
|
gsk_gl_texture_library_init (GskGLTextureLibrary *self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_texture_library_set_funcs (GskNglTextureLibrary *self,
|
gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self,
|
||||||
GHashFunc hash_func,
|
GHashFunc hash_func,
|
||||||
GEqualFunc equal_func,
|
GEqualFunc equal_func,
|
||||||
GDestroyNotify key_destroy,
|
GDestroyNotify key_destroy,
|
||||||
GDestroyNotify value_destroy)
|
GDestroyNotify value_destroy)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GSK_IS_NGL_TEXTURE_LIBRARY (self));
|
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||||
g_return_if_fail (self->hash_table == NULL);
|
g_return_if_fail (self->hash_table == NULL);
|
||||||
|
|
||||||
self->hash_table = g_hash_table_new_full (hash_func, equal_func,
|
self->hash_table = g_hash_table_new_full (hash_func, equal_func,
|
||||||
@ -135,20 +135,20 @@ gsk_ngl_texture_library_set_funcs (GskNglTextureLibrary *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self,
|
||||||
gint64 frame_id,
|
gint64 frame_id,
|
||||||
GPtrArray *removed_atlases)
|
GPtrArray *removed_atlases)
|
||||||
{
|
{
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
|
|
||||||
g_return_if_fail (GSK_IS_NGL_TEXTURE_LIBRARY (self));
|
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||||
|
|
||||||
if (GSK_NGL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame)
|
if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame)
|
||||||
GSK_NGL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id, removed_atlases);
|
GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id, removed_atlases);
|
||||||
|
|
||||||
if (removed_atlases != NULL)
|
if (removed_atlases != NULL)
|
||||||
{
|
{
|
||||||
GskNglTextureAtlasEntry *entry;
|
GskGLTextureAtlasEntry *entry;
|
||||||
guint dropped = 0;
|
guint dropped = 0;
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->hash_table);
|
g_hash_table_iter_init (&iter, self->hash_table);
|
||||||
@ -158,7 +158,7 @@ gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
|||||||
{
|
{
|
||||||
for (guint i = 0; i < removed_atlases->len; i++)
|
for (guint i = 0; i < removed_atlases->len; i++)
|
||||||
{
|
{
|
||||||
GskNglTextureAtlas *atlas = g_ptr_array_index (removed_atlases, i);
|
GskGLTextureAtlas *atlas = g_ptr_array_index (removed_atlases, i);
|
||||||
|
|
||||||
if (atlas == entry->atlas)
|
if (atlas == entry->atlas)
|
||||||
{
|
{
|
||||||
@ -178,7 +178,7 @@ gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
|||||||
|
|
||||||
if (frame_id % MAX_FRAME_AGE == 0)
|
if (frame_id % MAX_FRAME_AGE == 0)
|
||||||
{
|
{
|
||||||
GskNglTextureAtlasEntry *entry;
|
GskGLTextureAtlasEntry *entry;
|
||||||
int atlased = 0;
|
int atlased = 0;
|
||||||
int dropped = 0;
|
int dropped = 0;
|
||||||
|
|
||||||
@ -187,13 +187,13 @@ gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
|||||||
{
|
{
|
||||||
if (!entry->is_atlased && !entry->accessed)
|
if (!entry->is_atlased && !entry->accessed)
|
||||||
{
|
{
|
||||||
gsk_ngl_driver_release_texture (self->driver, entry->texture);
|
gsk_gl_driver_release_texture (self->driver, entry->texture);
|
||||||
g_hash_table_iter_remove (&iter);
|
g_hash_table_iter_remove (&iter);
|
||||||
dropped++;
|
dropped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gsk_ngl_texture_atlas_entry_mark_unused (entry);
|
gsk_gl_texture_atlas_entry_mark_unused (entry);
|
||||||
entry->accessed = FALSE;
|
entry->accessed = FALSE;
|
||||||
if (entry->is_atlased)
|
if (entry->is_atlased)
|
||||||
atlased++;
|
atlased++;
|
||||||
@ -210,14 +210,14 @@ gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GskNglTexture *
|
static GskGLTexture *
|
||||||
gsk_ngl_texture_library_pack_one (GskNglTextureLibrary *self,
|
gsk_gl_texture_library_pack_one (GskGLTextureLibrary *self,
|
||||||
guint width,
|
guint width,
|
||||||
guint height)
|
guint height)
|
||||||
{
|
{
|
||||||
GskNglTexture *texture;
|
GskGLTexture *texture;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_TEXTURE_LIBRARY (self));
|
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||||
|
|
||||||
if (width > self->driver->command_queue->max_texture_size ||
|
if (width > self->driver->command_queue->max_texture_size ||
|
||||||
height > self->driver->command_queue->max_texture_size)
|
height > self->driver->command_queue->max_texture_size)
|
||||||
@ -228,18 +228,18 @@ gsk_ngl_texture_library_pack_one (GskNglTextureLibrary *self,
|
|||||||
height = MIN (height, self->driver->command_queue->max_texture_size);
|
height = MIN (height, self->driver->command_queue->max_texture_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = gsk_ngl_driver_create_texture (self->driver, width, height, GL_RGBA8, GL_LINEAR, GL_LINEAR);
|
texture = gsk_gl_driver_create_texture (self->driver, width, height, GL_RGBA8, GL_LINEAR, GL_LINEAR);
|
||||||
texture->permanent = TRUE;
|
texture->permanent = TRUE;
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
gsk_ngl_texture_atlas_pack (GskNglTextureAtlas *self,
|
gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int *out_x,
|
int *out_x,
|
||||||
int *out_y)
|
int *out_y)
|
||||||
{
|
{
|
||||||
stbrp_rect rect;
|
stbrp_rect rect;
|
||||||
|
|
||||||
@ -258,8 +258,8 @@ gsk_ngl_texture_atlas_pack (GskNglTextureAtlas *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_atlas_initialize (GskNglDriver *driver,
|
gsk_gl_texture_atlas_initialize (GskGLDriver *driver,
|
||||||
GskNglTextureAtlas *atlas)
|
GskGLTextureAtlas *atlas)
|
||||||
{
|
{
|
||||||
/* Insert a single pixel at 0,0 for use in coloring */
|
/* Insert a single pixel at 0,0 for use in coloring */
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ gsk_ngl_texture_atlas_initialize (GskNglDriver *driver,
|
|||||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||||
"Initializing Atlas");
|
"Initializing Atlas");
|
||||||
|
|
||||||
packed = gsk_ngl_texture_atlas_pack (atlas, 3, 3, &x, &y);
|
packed = gsk_gl_texture_atlas_pack (atlas, 3, 3, &x, &y);
|
||||||
g_assert (packed);
|
g_assert (packed);
|
||||||
g_assert (x == 0 && y == 0);
|
g_assert (x == 0 && y == 0);
|
||||||
|
|
||||||
@ -303,21 +303,21 @@ gsk_ngl_texture_atlas_initialize (GskNglDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_texture_atlases_pack (GskNglDriver *driver,
|
gsk_gl_texture_atlases_pack (GskGLDriver *driver,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
GskNglTextureAtlas **out_atlas,
|
GskGLTextureAtlas **out_atlas,
|
||||||
int *out_x,
|
int *out_x,
|
||||||
int *out_y)
|
int *out_y)
|
||||||
{
|
{
|
||||||
GskNglTextureAtlas *atlas = NULL;
|
GskGLTextureAtlas *atlas = NULL;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
for (guint i = 0; i < driver->atlases->len; i++)
|
for (guint i = 0; i < driver->atlases->len; i++)
|
||||||
{
|
{
|
||||||
atlas = g_ptr_array_index (driver->atlases, i);
|
atlas = g_ptr_array_index (driver->atlases, i);
|
||||||
|
|
||||||
if (gsk_ngl_texture_atlas_pack (atlas, width, height, &x, &y))
|
if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
atlas = NULL;
|
atlas = NULL;
|
||||||
@ -326,12 +326,12 @@ gsk_ngl_texture_atlases_pack (GskNglDriver *driver,
|
|||||||
if (atlas == NULL)
|
if (atlas == NULL)
|
||||||
{
|
{
|
||||||
/* No atlas has enough space, so create a new one... */
|
/* No atlas has enough space, so create a new one... */
|
||||||
atlas = gsk_ngl_driver_create_atlas (driver);
|
atlas = gsk_gl_driver_create_atlas (driver);
|
||||||
|
|
||||||
gsk_ngl_texture_atlas_initialize (driver, atlas);
|
gsk_gl_texture_atlas_initialize (driver, atlas);
|
||||||
|
|
||||||
/* Pack it onto that one, which surely has enough space... */
|
/* Pack it onto that one, which surely has enough space... */
|
||||||
if (!gsk_ngl_texture_atlas_pack (atlas, width, height, &x, &y))
|
if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,21 +341,21 @@ gsk_ngl_texture_atlases_pack (GskNglDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
gsk_ngl_texture_library_pack (GskNglTextureLibrary *self,
|
gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||||
gpointer key,
|
gpointer key,
|
||||||
gsize valuelen,
|
gsize valuelen,
|
||||||
guint width,
|
guint width,
|
||||||
guint height,
|
guint height,
|
||||||
int padding,
|
int padding,
|
||||||
guint *out_packed_x,
|
guint *out_packed_x,
|
||||||
guint *out_packed_y)
|
guint *out_packed_y)
|
||||||
{
|
{
|
||||||
GskNglTextureAtlasEntry *entry;
|
GskGLTextureAtlasEntry *entry;
|
||||||
GskNglTextureAtlas *atlas = NULL;
|
GskGLTextureAtlas *atlas = NULL;
|
||||||
|
|
||||||
g_assert (GSK_IS_NGL_TEXTURE_LIBRARY (self));
|
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||||
g_assert (key != NULL);
|
g_assert (key != NULL);
|
||||||
g_assert (valuelen > sizeof (GskNglTextureAtlasEntry));
|
g_assert (valuelen > sizeof (GskGLTextureAtlasEntry));
|
||||||
g_assert (out_packed_x != NULL);
|
g_assert (out_packed_x != NULL);
|
||||||
g_assert (out_packed_y != NULL);
|
g_assert (out_packed_y != NULL);
|
||||||
|
|
||||||
@ -385,12 +385,12 @@ gsk_ngl_texture_library_pack (GskNglTextureLibrary *self,
|
|||||||
int packed_x;
|
int packed_x;
|
||||||
int packed_y;
|
int packed_y;
|
||||||
|
|
||||||
gsk_ngl_texture_atlases_pack (self->driver,
|
gsk_gl_texture_atlases_pack (self->driver,
|
||||||
padding + width + padding,
|
padding + width + padding,
|
||||||
padding + height + padding,
|
padding + height + padding,
|
||||||
&atlas,
|
&atlas,
|
||||||
&packed_x,
|
&packed_x,
|
||||||
&packed_y);
|
&packed_y);
|
||||||
|
|
||||||
entry->atlas = atlas;
|
entry->atlas = atlas;
|
||||||
entry->is_atlased = TRUE;
|
entry->is_atlased = TRUE;
|
||||||
@ -404,9 +404,9 @@ gsk_ngl_texture_library_pack (GskNglTextureLibrary *self,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GskNglTexture *texture = gsk_ngl_texture_library_pack_one (self,
|
GskGLTexture *texture = gsk_gl_texture_library_pack_one (self,
|
||||||
padding + width + padding,
|
padding + width + padding,
|
||||||
padding + height + padding);
|
padding + height + padding);
|
||||||
|
|
||||||
entry->texture = texture;
|
entry->texture = texture;
|
||||||
entry->is_atlased = FALSE;
|
entry->is_atlased = FALSE;
|
208
gsk/gl/gskgltexturelibraryprivate.h
Normal file
208
gsk/gl/gskgltexturelibraryprivate.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/* gskgltexturelibraryprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_TEXTURE_LIBRARY_PRIVATE_H__
|
||||||
|
#define __GSK_GL_TEXTURE_LIBRARY_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
#include "gskgltextureprivate.h"
|
||||||
|
|
||||||
|
#include "stb_rect_pack.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_TYPE_GL_TEXTURE_LIBRARY (gsk_gl_texture_library_get_type ())
|
||||||
|
#define GSK_GL_TEXTURE_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY, GskGLTextureLibrary))
|
||||||
|
#define GSK_IS_GL_TEXTURE_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY))
|
||||||
|
#define GSK_GL_TEXTURE_LIBRARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_TEXTURE_LIBRARY, GskGLTextureLibraryClass))
|
||||||
|
#define GSK_IS_GL_TEXTURE_LIBRARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_TEXTURE_LIBRARY))
|
||||||
|
#define GSK_GL_TEXTURE_LIBRARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY, GskGLTextureLibraryClass))
|
||||||
|
|
||||||
|
typedef struct _GskGLTextureAtlas
|
||||||
|
{
|
||||||
|
struct stbrp_context context;
|
||||||
|
struct stbrp_node *nodes;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
guint texture_id;
|
||||||
|
|
||||||
|
/* Pixels of rects that have been used at some point,
|
||||||
|
* But are now unused.
|
||||||
|
*/
|
||||||
|
int unused_pixels;
|
||||||
|
|
||||||
|
void *user_data;
|
||||||
|
} GskGLTextureAtlas;
|
||||||
|
|
||||||
|
typedef struct _GskGLTextureAtlasEntry
|
||||||
|
{
|
||||||
|
/* A backreference to either the atlas or texture containing
|
||||||
|
* the contents of the atlas entry. For larger items, no atlas
|
||||||
|
* is used and instead a direct texture.
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
GskGLTextureAtlas *atlas;
|
||||||
|
GskGLTexture *texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The area within the atlas translated to 0..1 bounds */
|
||||||
|
struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float x2;
|
||||||
|
float y2;
|
||||||
|
} area;
|
||||||
|
|
||||||
|
/* Number of pixels in the entry, used to calculate usage
|
||||||
|
* of an atlas while processing.
|
||||||
|
*/
|
||||||
|
guint n_pixels : 29;
|
||||||
|
|
||||||
|
/* If entry has marked pixels as used in the atlas this frame */
|
||||||
|
guint used : 1;
|
||||||
|
|
||||||
|
/* If entry was accessed this frame */
|
||||||
|
guint accessed : 1;
|
||||||
|
|
||||||
|
/* When true, backref is an atlas, otherwise texture */
|
||||||
|
guint is_atlased : 1;
|
||||||
|
} GskGLTextureAtlasEntry;
|
||||||
|
|
||||||
|
typedef struct _GskGLTextureLibrary
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
GskGLDriver *driver;
|
||||||
|
GHashTable *hash_table;
|
||||||
|
guint max_entry_size;
|
||||||
|
} GskGLTextureLibrary;
|
||||||
|
|
||||||
|
typedef struct _GskGLTextureLibraryClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (*begin_frame) (GskGLTextureLibrary *library,
|
||||||
|
gint64 frame_id,
|
||||||
|
GPtrArray *removed_atlases);
|
||||||
|
} GskGLTextureLibraryClass;
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskGLTextureLibrary, g_object_unref)
|
||||||
|
|
||||||
|
GType gsk_gl_texture_library_get_type (void) G_GNUC_CONST;
|
||||||
|
void gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self,
|
||||||
|
GHashFunc hash_func,
|
||||||
|
GEqualFunc equal_func,
|
||||||
|
GDestroyNotify key_destroy,
|
||||||
|
GDestroyNotify value_destroy);
|
||||||
|
void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self,
|
||||||
|
gint64 frame_id,
|
||||||
|
GPtrArray *removed_atlases);
|
||||||
|
gpointer gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||||
|
gpointer key,
|
||||||
|
gsize valuelen,
|
||||||
|
guint width,
|
||||||
|
guint height,
|
||||||
|
int padding,
|
||||||
|
guint *out_packed_x,
|
||||||
|
guint *out_packed_y);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_texture_atlas_mark_unused (GskGLTextureAtlas *self,
|
||||||
|
int n_pixels)
|
||||||
|
{
|
||||||
|
g_assert (n_pixels >= 0);
|
||||||
|
|
||||||
|
self->unused_pixels += n_pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_texture_atlas_entry_mark_used (GskGLTextureAtlasEntry *entry)
|
||||||
|
{
|
||||||
|
if (entry->used == TRUE || entry->is_atlased == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry->atlas->unused_pixels -= entry->n_pixels;
|
||||||
|
entry->used = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_texture_atlas_entry_mark_unused (GskGLTextureAtlasEntry *entry)
|
||||||
|
{
|
||||||
|
if (entry->used == FALSE || entry->is_atlased == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry->atlas->unused_pixels += entry->n_pixels;
|
||||||
|
entry->used = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
gsk_gl_texture_library_lookup (GskGLTextureLibrary *self,
|
||||||
|
gconstpointer key,
|
||||||
|
GskGLTextureAtlasEntry **out_entry)
|
||||||
|
{
|
||||||
|
GskGLTextureAtlasEntry *entry = g_hash_table_lookup (self->hash_table, key);
|
||||||
|
|
||||||
|
if G_LIKELY (entry != NULL && entry->accessed && entry->used)
|
||||||
|
{
|
||||||
|
*out_entry = entry;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry != NULL)
|
||||||
|
{
|
||||||
|
gsk_gl_texture_atlas_entry_mark_used (entry);
|
||||||
|
entry->accessed = TRUE;
|
||||||
|
*out_entry = entry;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (gconstpointer d)
|
||||||
|
{
|
||||||
|
const GskGLTextureAtlasEntry *e = d;
|
||||||
|
|
||||||
|
return e->is_atlased ? e->atlas->texture_id
|
||||||
|
: e->texture ? e->texture->texture_id : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
gsk_gl_texture_atlas_get_unused_ratio (const GskGLTextureAtlas *self)
|
||||||
|
{
|
||||||
|
if (self->unused_pixels > 0)
|
||||||
|
return (double)(self->unused_pixels) / (double)(self->width * self->height);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
gsk_gl_texture_library_can_cache (GskGLTextureLibrary *self,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
g_assert (self->max_entry_size > 0);
|
||||||
|
return width <= self->max_entry_size && height <= self->max_entry_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_TEXTURE_LIBRARY_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gskngltextureprivate.h
|
/* gskgltextureprivate.h
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -18,20 +18,20 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GSK_NGL_TEXTURE_PRIVATE_H__
|
#ifndef _GSK_GL_TEXTURE_PRIVATE_H__
|
||||||
#define _GSK_NGL_TEXTURE_PRIVATE_H__
|
#define _GSK_GL_TEXTURE_PRIVATE_H__
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
struct _GskNglTextureSlice
|
struct _GskGLTextureSlice
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
guint texture_id;
|
guint texture_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GskNglTextureNineSlice
|
struct _GskGLTextureNineSlice
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
struct {
|
struct {
|
||||||
@ -42,7 +42,7 @@ struct _GskNglTextureNineSlice
|
|||||||
} area;
|
} area;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GskNglTexture
|
struct _GskGLTexture
|
||||||
{
|
{
|
||||||
/* Used to insert into queue */
|
/* Used to insert into queue */
|
||||||
GList link;
|
GList link;
|
||||||
@ -54,10 +54,10 @@ struct _GskNglTexture
|
|||||||
GdkTexture *user;
|
GdkTexture *user;
|
||||||
|
|
||||||
/* Only used by nine-slice textures */
|
/* Only used by nine-slice textures */
|
||||||
GskNglTextureNineSlice *nine_slice;
|
GskGLTextureNineSlice *nine_slice;
|
||||||
|
|
||||||
/* Only used by sliced textures */
|
/* Only used by sliced textures */
|
||||||
GskNglTextureSlice *slices;
|
GskGLTextureSlice *slices;
|
||||||
guint n_slices;
|
guint n_slices;
|
||||||
|
|
||||||
/* The actual GL texture identifier in some shared context */
|
/* The actual GL texture identifier in some shared context */
|
||||||
@ -73,19 +73,19 @@ struct _GskNglTexture
|
|||||||
guint permanent : 1;
|
guint permanent : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
GskNglTexture *gsk_ngl_texture_new (guint texture_id,
|
GskGLTexture * gsk_gl_texture_new (guint texture_id,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int format,
|
int format,
|
||||||
int min_filter,
|
int min_filter,
|
||||||
int mag_filter,
|
int mag_filter,
|
||||||
gint64 frame_id);
|
gint64 frame_id);
|
||||||
const GskNglTextureNineSlice *gsk_ngl_texture_get_nine_slice (GskNglTexture *texture,
|
const GskGLTextureNineSlice * gsk_gl_texture_get_nine_slice (GskGLTexture *texture,
|
||||||
const GskRoundedRect *outline,
|
const GskRoundedRect *outline,
|
||||||
float extra_pixels_x,
|
float extra_pixels_x,
|
||||||
float extra_pixels_y);
|
float extra_pixels_y);
|
||||||
void gsk_ngl_texture_free (GskNglTexture *texture);
|
void gsk_gl_texture_free (GskGLTexture *texture);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* _GSK_NGL_TEXTURE_PRIVATE_H__ */
|
#endif /* _GSK_GL_TEXTURE_PRIVATE_H__ */
|
66
gsk/gl/gskgltypesprivate.h
Normal file
66
gsk/gl/gskgltypesprivate.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* gskgltypesprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSK_GL_TYPES_PRIVATE_H__
|
||||||
|
#define __GSK_GL_TYPES_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
#include <graphene.h>
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <gsk/gsk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSK_GL_N_VERTICES 6
|
||||||
|
|
||||||
|
typedef struct _GskGLAttachmentState GskGLAttachmentState;
|
||||||
|
typedef struct _GskGLBuffer GskGLBuffer;
|
||||||
|
typedef struct _GskGLCommandQueue GskGLCommandQueue;
|
||||||
|
typedef struct _GskGLCompiler GskGLCompiler;
|
||||||
|
typedef struct _GskGLDrawVertex GskGLDrawVertex;
|
||||||
|
typedef struct _GskGLRenderTarget GskGLRenderTarget;
|
||||||
|
typedef struct _GskGLGlyphLibrary GskGLGlyphLibrary;
|
||||||
|
typedef struct _GskGLIconLibrary GskGLIconLibrary;
|
||||||
|
typedef struct _GskGLProgram GskGLProgram;
|
||||||
|
typedef struct _GskGLRenderJob GskGLRenderJob;
|
||||||
|
typedef struct _GskGLShadowLibrary GskGLShadowLibrary;
|
||||||
|
typedef struct _GskGLTexture GskGLTexture;
|
||||||
|
typedef struct _GskGLTextureSlice GskGLTextureSlice;
|
||||||
|
typedef struct _GskGLTextureAtlas GskGLTextureAtlas;
|
||||||
|
typedef struct _GskGLTextureLibrary GskGLTextureLibrary;
|
||||||
|
typedef struct _GskGLTextureNineSlice GskGLTextureNineSlice;
|
||||||
|
typedef struct _GskGLUniformInfo GskGLUniformInfo;
|
||||||
|
typedef struct _GskGLUniformProgram GskGLUniformProgram;
|
||||||
|
typedef struct _GskGLUniformState GskGLUniformState;
|
||||||
|
typedef struct _GskGLDriver GskGLDriver;
|
||||||
|
|
||||||
|
struct _GskGLDrawVertex
|
||||||
|
{
|
||||||
|
float position[2];
|
||||||
|
union {
|
||||||
|
float uv[2];
|
||||||
|
guint16 color2[4];
|
||||||
|
};
|
||||||
|
guint16 color[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_GL_TYPES_PRIVATE_H__ */
|
@ -1,4 +1,4 @@
|
|||||||
/* gskngluniformstate.c
|
/* gskgluniformstate.c
|
||||||
*
|
*
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
*
|
*
|
||||||
@ -23,7 +23,7 @@
|
|||||||
#include <gsk/gskroundedrectprivate.h>
|
#include <gsk/gskroundedrectprivate.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gskngluniformstateprivate.h"
|
#include "gskgluniformstateprivate.h"
|
||||||
|
|
||||||
static const guint8 uniform_sizes[] = {
|
static const guint8 uniform_sizes[] = {
|
||||||
0,
|
0,
|
||||||
@ -54,12 +54,12 @@ static const guint8 uniform_sizes[] = {
|
|||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
GskNglUniformState *
|
GskGLUniformState *
|
||||||
gsk_ngl_uniform_state_new (void)
|
gsk_gl_uniform_state_new (void)
|
||||||
{
|
{
|
||||||
GskNglUniformState *state;
|
GskGLUniformState *state;
|
||||||
|
|
||||||
state = g_atomic_rc_box_new0 (GskNglUniformState);
|
state = g_atomic_rc_box_new0 (GskGLUniformState);
|
||||||
state->programs = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
state->programs = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||||
state->values_len = 4096;
|
state->values_len = 4096;
|
||||||
state->values_pos = 0;
|
state->values_pos = 0;
|
||||||
@ -70,41 +70,41 @@ gsk_ngl_uniform_state_new (void)
|
|||||||
return g_steal_pointer (&state);
|
return g_steal_pointer (&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglUniformState *
|
GskGLUniformState *
|
||||||
gsk_ngl_uniform_state_ref (GskNglUniformState *state)
|
gsk_gl_uniform_state_ref (GskGLUniformState *state)
|
||||||
{
|
{
|
||||||
return g_atomic_rc_box_acquire (state);
|
return g_atomic_rc_box_acquire (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gsk_ngl_uniform_state_finalize (gpointer data)
|
gsk_gl_uniform_state_finalize (gpointer data)
|
||||||
{
|
{
|
||||||
GskNglUniformState *state = data;
|
GskGLUniformState *state = data;
|
||||||
|
|
||||||
g_clear_pointer (&state->programs, g_hash_table_unref);
|
g_clear_pointer (&state->programs, g_hash_table_unref);
|
||||||
g_clear_pointer (&state->values_buf, g_free);
|
g_clear_pointer (&state->values_buf, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_uniform_state_unref (GskNglUniformState *state)
|
gsk_gl_uniform_state_unref (GskGLUniformState *state)
|
||||||
{
|
{
|
||||||
g_atomic_rc_box_release_full (state, gsk_ngl_uniform_state_finalize);
|
g_atomic_rc_box_release_full (state, gsk_gl_uniform_state_finalize);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
|
gsk_gl_uniform_state_init_value (GskGLUniformState *state,
|
||||||
GskNglUniformProgram *program,
|
GskGLUniformProgram *program,
|
||||||
GskNglUniformFormat format,
|
GskGLUniformFormat format,
|
||||||
guint array_count,
|
guint array_count,
|
||||||
guint key,
|
guint key,
|
||||||
GskNglUniformMapping **infoptr)
|
GskGLUniformMapping **infoptr)
|
||||||
{
|
{
|
||||||
GskNglUniformMapping *mapping;
|
GskGLUniformMapping *mapping;
|
||||||
guint offset;
|
guint offset;
|
||||||
|
|
||||||
g_assert (state != NULL);
|
g_assert (state != NULL);
|
||||||
g_assert (array_count < 32);
|
g_assert (array_count < 32);
|
||||||
g_assert ((int)format >= 0 && format < GSK_NGL_UNIFORM_FORMAT_LAST);
|
g_assert ((int)format >= 0 && format < GSK_GL_UNIFORM_FORMAT_LAST);
|
||||||
g_assert (format > 0);
|
g_assert (format > 0);
|
||||||
g_assert (program != NULL);
|
g_assert (program != NULL);
|
||||||
g_assert (key < program->n_mappings);
|
g_assert (key < program->n_mappings);
|
||||||
@ -122,7 +122,7 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
|
|||||||
if G_LIKELY (array_count <= mapping->info.array_count)
|
if G_LIKELY (array_count <= mapping->info.array_count)
|
||||||
{
|
{
|
||||||
*infoptr = mapping;
|
*infoptr = mapping;
|
||||||
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
return GSK_GL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We found the uniform, but there is not enough space for the
|
/* We found the uniform, but there is not enough space for the
|
||||||
@ -152,12 +152,12 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
|
|||||||
|
|
||||||
setup_info:
|
setup_info:
|
||||||
|
|
||||||
gsk_ngl_uniform_state_realloc (state,
|
gsk_gl_uniform_state_realloc (state,
|
||||||
uniform_sizes[format] * MAX (1, array_count),
|
uniform_sizes[format] * MAX (1, array_count),
|
||||||
&offset);
|
&offset);
|
||||||
|
|
||||||
/* we have 21 bits for offset */
|
/* we have 21 bits for offset */
|
||||||
g_assert (offset < (1 << GSK_NGL_UNIFORM_OFFSET_BITS));
|
g_assert (offset < (1 << GSK_GL_UNIFORM_OFFSET_BITS));
|
||||||
|
|
||||||
mapping->info.format = format;
|
mapping->info.format = format;
|
||||||
mapping->info.offset = offset;
|
mapping->info.offset = offset;
|
||||||
@ -167,14 +167,14 @@ setup_info:
|
|||||||
|
|
||||||
*infoptr = mapping;
|
*infoptr = mapping;
|
||||||
|
|
||||||
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
return GSK_GL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
|
gsk_gl_uniform_state_end_frame (GskGLUniformState *state)
|
||||||
{
|
{
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
GskNglUniformProgram *program;
|
GskGLUniformProgram *program;
|
||||||
guint allocator = 0;
|
guint allocator = 0;
|
||||||
|
|
||||||
g_return_if_fail (state != NULL);
|
g_return_if_fail (state != NULL);
|
||||||
@ -190,7 +190,7 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
|
|||||||
{
|
{
|
||||||
for (guint j = 0; j < program->n_mappings; j++)
|
for (guint j = 0; j < program->n_mappings; j++)
|
||||||
{
|
{
|
||||||
GskNglUniformMapping *mapping = &program->mappings[j];
|
GskGLUniformMapping *mapping = &program->mappings[j];
|
||||||
guint size;
|
guint size;
|
||||||
|
|
||||||
/* Skip unused uniform mappings */
|
/* Skip unused uniform mappings */
|
||||||
@ -201,7 +201,7 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
|
|||||||
size = uniform_sizes[mapping->info.format] * MAX (1, mapping->info.array_count);
|
size = uniform_sizes[mapping->info.format] * MAX (1, mapping->info.array_count);
|
||||||
|
|
||||||
/* Adjust alignment for value */
|
/* Adjust alignment for value */
|
||||||
allocator += gsk_ngl_uniform_state_align (allocator, size);
|
allocator += gsk_gl_uniform_state_align (allocator, size);
|
||||||
|
|
||||||
/* Offset is in slots of 4 bytes */
|
/* Offset is in slots of 4 bytes */
|
||||||
mapping->info.offset = allocator / 4;
|
mapping->info.offset = allocator / 4;
|
||||||
@ -231,21 +231,21 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gsize
|
gsize
|
||||||
gsk_ngl_uniform_format_size (GskNglUniformFormat format)
|
gsk_gl_uniform_format_size (GskGLUniformFormat format)
|
||||||
{
|
{
|
||||||
g_assert (format > 0);
|
g_assert (format > 0);
|
||||||
g_assert (format < GSK_NGL_UNIFORM_FORMAT_LAST);
|
g_assert (format < GSK_GL_UNIFORM_FORMAT_LAST);
|
||||||
|
|
||||||
return uniform_sizes[format];
|
return uniform_sizes[format];
|
||||||
}
|
}
|
||||||
|
|
||||||
GskNglUniformProgram *
|
GskGLUniformProgram *
|
||||||
gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
|
gsk_gl_uniform_state_get_program (GskGLUniformState *state,
|
||||||
guint program,
|
guint program,
|
||||||
const GskNglUniformMapping *mappings,
|
const GskGLUniformMapping *mappings,
|
||||||
guint n_mappings)
|
guint n_mappings)
|
||||||
{
|
{
|
||||||
GskNglUniformProgram *ret;
|
GskGLUniformProgram *ret;
|
||||||
|
|
||||||
g_return_val_if_fail (state != NULL, NULL);
|
g_return_val_if_fail (state != NULL, NULL);
|
||||||
g_return_val_if_fail (program > 0, NULL);
|
g_return_val_if_fail (program > 0, NULL);
|
||||||
@ -256,7 +256,7 @@ gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
|
|||||||
|
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
ret = g_new0 (GskNglUniformProgram, 1);
|
ret = g_new0 (GskGLUniformProgram, 1);
|
||||||
ret->program_id = program;
|
ret->program_id = program;
|
||||||
ret->n_mappings = n_mappings;
|
ret->n_mappings = n_mappings;
|
||||||
|
|
836
gsk/gl/gskgluniformstateprivate.h
Normal file
836
gsk/gl/gskgluniformstateprivate.h
Normal file
@ -0,0 +1,836 @@
|
|||||||
|
/* gskgluniformstateprivate.h
|
||||||
|
*
|
||||||
|
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GSK_GL_UNIFORM_STATE_PRIVATE_H
|
||||||
|
#define GSK_GL_UNIFORM_STATE_PRIVATE_H
|
||||||
|
|
||||||
|
#include "gskgltypesprivate.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct { float v0; } Uniform1f;
|
||||||
|
typedef struct { float v0; float v1; } Uniform2f;
|
||||||
|
typedef struct { float v0; float v1; float v2; } Uniform3f;
|
||||||
|
typedef struct { float v0; float v1; float v2; float v3; } Uniform4f;
|
||||||
|
|
||||||
|
typedef struct { int v0; } Uniform1i;
|
||||||
|
typedef struct { int v0; int v1; } Uniform2i;
|
||||||
|
typedef struct { int v0; int v1; int v2; } Uniform3i;
|
||||||
|
typedef struct { int v0; int v1; int v2; int v3; } Uniform4i;
|
||||||
|
|
||||||
|
typedef struct { guint v0; } Uniform1ui;
|
||||||
|
|
||||||
|
#define GSK_GL_UNIFORM_ARRAY_BITS 5
|
||||||
|
#define GSK_GL_UNIFORM_FORMAT_BITS 5
|
||||||
|
#define GSK_GL_UNIFORM_OFFSET_BITS 21
|
||||||
|
|
||||||
|
typedef struct _GskGLUniformInfo
|
||||||
|
{
|
||||||
|
guint initial : 1;
|
||||||
|
guint format : GSK_GL_UNIFORM_FORMAT_BITS;
|
||||||
|
guint array_count : GSK_GL_UNIFORM_ARRAY_BITS;
|
||||||
|
guint offset : GSK_GL_UNIFORM_OFFSET_BITS;
|
||||||
|
} GskGLUniformInfo;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (GskGLUniformInfo) == 4);
|
||||||
|
|
||||||
|
typedef struct _GskGLUniformMapping
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
GskGLUniformInfo info;
|
||||||
|
guint stamp;
|
||||||
|
int location;
|
||||||
|
} GskGLUniformMapping;
|
||||||
|
|
||||||
|
typedef struct _GskGLUniformProgram
|
||||||
|
{
|
||||||
|
guint program_id;
|
||||||
|
guint n_uniforms : 12;
|
||||||
|
guint has_attachments : 1;
|
||||||
|
guint n_mappings;
|
||||||
|
GskGLUniformMapping mappings[32];
|
||||||
|
} GskGLUniformProgram;
|
||||||
|
|
||||||
|
typedef struct _GskGLUniformState
|
||||||
|
{
|
||||||
|
GHashTable *programs;
|
||||||
|
guint8 *values_buf;
|
||||||
|
guint values_pos;
|
||||||
|
guint values_len;
|
||||||
|
GskGLUniformInfo apply_hash[512];
|
||||||
|
} GskGLUniformState;
|
||||||
|
|
||||||
|
typedef enum _GskGLUniformKind
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_FORMAT_1F = 1,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_2F,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_3F,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_4F,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_1FV,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_2FV,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_3FV,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_4FV,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_1I,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_2I,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_3I,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_4I,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_1UI,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_TEXTURE,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_MATRIX,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT,
|
||||||
|
GSK_GL_UNIFORM_FORMAT_COLOR,
|
||||||
|
|
||||||
|
GSK_GL_UNIFORM_FORMAT_LAST
|
||||||
|
} GskGLUniformFormat;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (GSK_GL_UNIFORM_FORMAT_LAST < (1 << GSK_GL_UNIFORM_FORMAT_BITS));
|
||||||
|
|
||||||
|
GskGLUniformState *gsk_gl_uniform_state_new (void);
|
||||||
|
GskGLUniformState *gsk_gl_uniform_state_ref (GskGLUniformState *state);
|
||||||
|
void gsk_gl_uniform_state_unref (GskGLUniformState *state);
|
||||||
|
GskGLUniformProgram *gsk_gl_uniform_state_get_program (GskGLUniformState *state,
|
||||||
|
guint program,
|
||||||
|
const GskGLUniformMapping *mappings,
|
||||||
|
guint n_mappings);
|
||||||
|
void gsk_gl_uniform_state_end_frame (GskGLUniformState *state);
|
||||||
|
gsize gsk_gl_uniform_format_size (GskGLUniformFormat format);
|
||||||
|
gpointer gsk_gl_uniform_state_init_value (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
GskGLUniformFormat format,
|
||||||
|
guint array_count,
|
||||||
|
guint key,
|
||||||
|
GskGLUniformMapping **out_mapping);
|
||||||
|
|
||||||
|
#define GSK_GL_UNIFORM_VALUE(base, offset) ((gpointer)((base) + ((offset) * 4)))
|
||||||
|
#define gsk_gl_uniform_state_get_uniform_data(state,offset) GSK_GL_UNIFORM_VALUE((state)->values_buf, offset)
|
||||||
|
|
||||||
|
static inline gpointer
|
||||||
|
gsk_gl_uniform_state_get_value (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
GskGLUniformFormat format,
|
||||||
|
guint array_count,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
GskGLUniformMapping **out_mapping)
|
||||||
|
{
|
||||||
|
GskGLUniformMapping *mapping;
|
||||||
|
|
||||||
|
g_assert (key < G_N_ELEMENTS (program->mappings));
|
||||||
|
g_assert (key < program->n_mappings);
|
||||||
|
|
||||||
|
mapping = &program->mappings[key];
|
||||||
|
|
||||||
|
/* Short-circuit if the program optimized the uniform out */
|
||||||
|
if (mapping->location == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* If the stamp is the same, then we can ignore the request
|
||||||
|
* and short-circuit as early as possible. This requires the
|
||||||
|
* caller to increment their private stamp when they change
|
||||||
|
* internal state.
|
||||||
|
*
|
||||||
|
* This is generally used for the shared uniforms like projection,
|
||||||
|
* modelview, clip, etc to avoid so many comparisons which cost
|
||||||
|
* considerable CPU.
|
||||||
|
*/
|
||||||
|
if (stamp != 0 && stamp == mapping->stamp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if G_LIKELY (format == mapping->info.format && array_count <= mapping->info.array_count)
|
||||||
|
{
|
||||||
|
*out_mapping = mapping;
|
||||||
|
return GSK_GL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gsk_gl_uniform_state_init_value (state, program, format, array_count, key, out_mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_PURE static inline guint
|
||||||
|
gsk_gl_uniform_state_align (guint current_pos,
|
||||||
|
guint size)
|
||||||
|
{
|
||||||
|
guint align = size > 8 ? 16 : (size > 4 ? 8 : 4);
|
||||||
|
guint masked = current_pos & (align - 1);
|
||||||
|
|
||||||
|
g_assert (size > 0);
|
||||||
|
g_assert (align == 4 || align == 8 || align == 16);
|
||||||
|
g_assert (masked < align);
|
||||||
|
|
||||||
|
return align - masked;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gpointer
|
||||||
|
gsk_gl_uniform_state_realloc (GskGLUniformState *state,
|
||||||
|
guint size,
|
||||||
|
guint *offset)
|
||||||
|
{
|
||||||
|
guint padding = gsk_gl_uniform_state_align (state->values_pos, size);
|
||||||
|
|
||||||
|
if G_UNLIKELY (state->values_len - padding - size < state->values_pos)
|
||||||
|
{
|
||||||
|
state->values_len *= 2;
|
||||||
|
state->values_buf = g_realloc (state->values_buf, state->values_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* offsets are in slots of 4 to use fewer bits */
|
||||||
|
g_assert ((state->values_pos + padding) % 4 == 0);
|
||||||
|
*offset = (state->values_pos + padding) / 4;
|
||||||
|
state->values_pos += padding + size;
|
||||||
|
|
||||||
|
return GSK_GL_UNIFORM_VALUE (state->values_buf, *offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GSK_GL_UNIFORM_STATE_REPLACE(info, u, type, count) \
|
||||||
|
G_STMT_START { \
|
||||||
|
if ((info)->info.initial && count == (info)->info.array_count) \
|
||||||
|
{ \
|
||||||
|
u = GSK_GL_UNIFORM_VALUE (state->values_buf, (info)->info.offset); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
guint offset; \
|
||||||
|
u = gsk_gl_uniform_state_realloc (state, sizeof(type) * MAX (1, count), &offset); \
|
||||||
|
g_assert (offset < (1 << GSK_GL_UNIFORM_OFFSET_BITS)); \
|
||||||
|
(info)->info.offset = offset; \
|
||||||
|
/* We might have increased array length */ \
|
||||||
|
(info)->info.array_count = count; \
|
||||||
|
} \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_info_changed (GskGLUniformMapping *info,
|
||||||
|
guint stamp)
|
||||||
|
{
|
||||||
|
info->stamp = stamp;
|
||||||
|
info->info.initial = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set1f (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0)
|
||||||
|
{
|
||||||
|
Uniform1f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != 0);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1F, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set2f (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1)
|
||||||
|
{
|
||||||
|
Uniform2f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2F, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set3f (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1,
|
||||||
|
float value2)
|
||||||
|
{
|
||||||
|
Uniform3f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3F, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
u->v2 = value2;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set4f (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
float value0,
|
||||||
|
float value1,
|
||||||
|
float value2,
|
||||||
|
float value3)
|
||||||
|
{
|
||||||
|
Uniform4f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4F, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
u->v2 = value2;
|
||||||
|
u->v3 = value3;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set1ui (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint value0)
|
||||||
|
{
|
||||||
|
Uniform1ui *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1UI, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set1i (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0)
|
||||||
|
{
|
||||||
|
Uniform1i *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1I, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set2i (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1)
|
||||||
|
{
|
||||||
|
Uniform2i *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2I, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set3i (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1,
|
||||||
|
int value2)
|
||||||
|
{
|
||||||
|
Uniform3i *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3I, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3i, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
u->v2 = value2;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set4i (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
int value0,
|
||||||
|
int value1,
|
||||||
|
int value2,
|
||||||
|
int value3)
|
||||||
|
{
|
||||||
|
Uniform4i *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4I, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4i, 1);
|
||||||
|
u->v0 = value0;
|
||||||
|
u->v1 = value1;
|
||||||
|
u->v2 = value2;
|
||||||
|
u->v3 = value3;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set_rounded_rect (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const GskRoundedRect *rounded_rect)
|
||||||
|
{
|
||||||
|
GskRoundedRect *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (rounded_rect != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || memcmp (u, rounded_rect, sizeof *u) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
|
||||||
|
memcpy (u, rounded_rect, sizeof *rounded_rect);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set_matrix (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const graphene_matrix_t *matrix)
|
||||||
|
{
|
||||||
|
graphene_matrix_t *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (matrix != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_MATRIX, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
|
||||||
|
memcpy (u, matrix, sizeof *matrix);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_gl_uniform_state_set_texture:
|
||||||
|
* @state: a `GskGLUniformState`
|
||||||
|
* @program: the program id
|
||||||
|
* @location: the location of the texture
|
||||||
|
* @texture_slot: a texturing slot such as GL_TEXTURE0
|
||||||
|
*
|
||||||
|
* Sets the uniform expecting a texture to @texture_slot. This API
|
||||||
|
* expects a texture slot such as GL_TEXTURE0 to reduce chances of
|
||||||
|
* miss-use by the caller.
|
||||||
|
*
|
||||||
|
* The value stored to the uniform is in the form of 0 for GL_TEXTURE0,
|
||||||
|
* 1 for GL_TEXTURE1, and so on.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set_texture (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint texture_slot)
|
||||||
|
{
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
guint *u;
|
||||||
|
|
||||||
|
g_assert (texture_slot >= GL_TEXTURE0);
|
||||||
|
g_assert (texture_slot < GL_TEXTURE16);
|
||||||
|
|
||||||
|
texture_slot -= GL_TEXTURE0;
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_TEXTURE, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || *u != texture_slot)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
|
||||||
|
*u = texture_slot;
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gsk_gl_uniform_state_set_color:
|
||||||
|
* @state: a `GskGLUniformState`
|
||||||
|
* @program: a program id > 0
|
||||||
|
* @location: the uniform location
|
||||||
|
* @color: a color to set or %NULL for transparent
|
||||||
|
*
|
||||||
|
* Sets a uniform to the color described by @color. This is a convenience
|
||||||
|
* function to allow callers to avoid having to translate colors to floats
|
||||||
|
* in other portions of the renderer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set_color (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
const GdkRGBA *color)
|
||||||
|
{
|
||||||
|
static const GdkRGBA transparent = {0};
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
GdkRGBA *u;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_COLOR, 1, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (color == NULL)
|
||||||
|
color = &transparent;
|
||||||
|
|
||||||
|
if (info->info.initial || memcmp (color, u, sizeof *u) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
|
||||||
|
memcpy (u, color, sizeof *color);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set1fv (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *value)
|
||||||
|
{
|
||||||
|
Uniform1f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (count > 0);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_1FV, count, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
|
||||||
|
memcpy (u, value, sizeof (Uniform1f) * count);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set2fv (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *value)
|
||||||
|
{
|
||||||
|
Uniform2f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (count > 0);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_2FV, count, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
|
||||||
|
memcpy (u, value, sizeof (Uniform2f) * count);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set3fv (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *value)
|
||||||
|
{
|
||||||
|
Uniform3f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (count > 0);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_3FV, count, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
|
||||||
|
memcpy (u, value, sizeof (Uniform3f) * count);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_set4fv (GskGLUniformState *state,
|
||||||
|
GskGLUniformProgram *program,
|
||||||
|
guint key,
|
||||||
|
guint stamp,
|
||||||
|
guint count,
|
||||||
|
const float *value)
|
||||||
|
{
|
||||||
|
Uniform4f *u;
|
||||||
|
GskGLUniformMapping *info;
|
||||||
|
|
||||||
|
g_assert (state != NULL);
|
||||||
|
g_assert (program != NULL);
|
||||||
|
g_assert (count > 0);
|
||||||
|
|
||||||
|
if ((u = gsk_gl_uniform_state_get_value (state, program, GSK_GL_UNIFORM_FORMAT_4FV, count, key, stamp, &info)))
|
||||||
|
{
|
||||||
|
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
||||||
|
{
|
||||||
|
GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
|
||||||
|
memcpy (u, value, sizeof (Uniform4f) * count);
|
||||||
|
gsk_gl_uniform_info_changed (info, stamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
gsk_gl_uniform_state_fmix (guint program,
|
||||||
|
guint location)
|
||||||
|
{
|
||||||
|
guint h = (program << 16) | location;
|
||||||
|
|
||||||
|
h ^= h >> 16;
|
||||||
|
h *= 0x85ebca6b;
|
||||||
|
h ^= h >> 13;
|
||||||
|
h *= 0xc2b2ae35;
|
||||||
|
h ^= h >> 16;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gsk_gl_uniform_state_apply:
|
||||||
|
* @state: the uniform state
|
||||||
|
* @program: the program id
|
||||||
|
* @location: the location of the uniform
|
||||||
|
* @offset: the offset of the data within the buffer
|
||||||
|
* @info: the uniform info
|
||||||
|
*
|
||||||
|
* This function can be used to apply state that was previously recorded
|
||||||
|
* by the `GskGLUniformState`.
|
||||||
|
*
|
||||||
|
* It is specifically useful from the `GskGLCommandQueue` to execute uniform
|
||||||
|
* changes but only when they have changed from the current value.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
gsk_gl_uniform_state_apply (GskGLUniformState *state,
|
||||||
|
guint program,
|
||||||
|
guint location,
|
||||||
|
GskGLUniformInfo info)
|
||||||
|
{
|
||||||
|
guint index = gsk_gl_uniform_state_fmix (program, location) % G_N_ELEMENTS (state->apply_hash);
|
||||||
|
gconstpointer dataptr = GSK_GL_UNIFORM_VALUE (state->values_buf, info.offset);
|
||||||
|
|
||||||
|
/* aligned, can treat as unsigned */
|
||||||
|
if (*(guint *)&info == *(guint *)&state->apply_hash[index])
|
||||||
|
return;
|
||||||
|
|
||||||
|
state->apply_hash[index] = info;
|
||||||
|
|
||||||
|
/* TODO: We could do additional comparisons here to make sure we are
|
||||||
|
* changing state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (info.format)
|
||||||
|
{
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_1F:
|
||||||
|
glUniform1fv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_2F:
|
||||||
|
glUniform2fv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_3F:
|
||||||
|
glUniform3fv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_4F:
|
||||||
|
glUniform4fv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_1FV:
|
||||||
|
glUniform1fv (location, info.array_count, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_2FV:
|
||||||
|
glUniform2fv (location, info.array_count, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_3FV:
|
||||||
|
glUniform3fv (location, info.array_count, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_4FV:
|
||||||
|
glUniform4fv (location, info.array_count, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_1I:
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_TEXTURE:
|
||||||
|
glUniform1iv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_2I:
|
||||||
|
glUniform2iv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_3I:
|
||||||
|
glUniform3iv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_4I:
|
||||||
|
glUniform4iv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_1UI:
|
||||||
|
glUniform1uiv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_MATRIX: {
|
||||||
|
float mat[16];
|
||||||
|
graphene_matrix_to_float (dataptr, mat);
|
||||||
|
glUniformMatrix4fv (location, 1, GL_FALSE, mat);
|
||||||
|
#if 0
|
||||||
|
/* TODO: If Graphene can give us a peek here on platforms
|
||||||
|
* where the format is float[16] (most/all x86_64?) then
|
||||||
|
* We can avoid the SIMD operation to convert the format.
|
||||||
|
*/
|
||||||
|
G_STATIC_ASSERT (sizeof (graphene_matrix_t) == 16*4);
|
||||||
|
glUniformMatrix4fv (location, 1, GL_FALSE, dataptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_COLOR:
|
||||||
|
glUniform4fv (location, 1, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_GL_UNIFORM_FORMAT_ROUNDED_RECT:
|
||||||
|
glUniform4fv (location, 3, dataptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* GSK_GL_UNIFORM_STATE_PRIVATE_H */
|
@ -22,7 +22,7 @@
|
|||||||
#ifndef __NINE_SLICE_PRIVATE_H__
|
#ifndef __NINE_SLICE_PRIVATE_H__
|
||||||
#define __NINE_SLICE_PRIVATE_H__
|
#define __NINE_SLICE_PRIVATE_H__
|
||||||
|
|
||||||
#include "gskngltextureprivate.h"
|
#include "gskgltextureprivate.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
# define DEBUG_NINE_SLICE
|
# define DEBUG_NINE_SLICE
|
||||||
@ -43,14 +43,14 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static inline bool G_GNUC_PURE
|
static inline bool G_GNUC_PURE
|
||||||
nine_slice_is_visible (const GskNglTextureNineSlice *slice)
|
nine_slice_is_visible (const GskGLTextureNineSlice *slice)
|
||||||
{
|
{
|
||||||
return slice->rect.width > 0 && slice->rect.height > 0;
|
return slice->rect.width > 0 && slice->rect.height > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
nine_slice_rounded_rect (GskNglTextureNineSlice *slices,
|
nine_slice_rounded_rect (GskGLTextureNineSlice *slices,
|
||||||
const GskRoundedRect *rect)
|
const GskRoundedRect *rect)
|
||||||
{
|
{
|
||||||
const graphene_point_t *origin = &rect->bounds.origin;
|
const graphene_point_t *origin = &rect->bounds.origin;
|
||||||
const graphene_size_t *size = &rect->bounds.size;
|
const graphene_size_t *size = &rect->bounds.size;
|
||||||
@ -130,16 +130,16 @@ nine_slice_rounded_rect (GskNglTextureNineSlice *slices,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
nine_slice_to_texture_coords (GskNglTextureNineSlice *slices,
|
nine_slice_to_texture_coords (GskGLTextureNineSlice *slices,
|
||||||
int texture_width,
|
int texture_width,
|
||||||
int texture_height)
|
int texture_height)
|
||||||
{
|
{
|
||||||
float fw = texture_width;
|
float fw = texture_width;
|
||||||
float fh = texture_height;
|
float fh = texture_height;
|
||||||
|
|
||||||
for (guint i = 0; i < 9; i++)
|
for (guint i = 0; i < 9; i++)
|
||||||
{
|
{
|
||||||
GskNglTextureNineSlice *slice = &slices[i];
|
GskGLTextureNineSlice *slice = &slices[i];
|
||||||
|
|
||||||
slice->area.x = slice->rect.x / fw;
|
slice->area.x = slice->rect.x / fw;
|
||||||
slice->area.y = 1.0 - ((slice->rect.y + slice->rect.height) / fh);
|
slice->area.y = 1.0 - ((slice->rect.y + slice->rect.height) / fh);
|
||||||
@ -158,9 +158,9 @@ nine_slice_to_texture_coords (GskNglTextureNineSlice *slices,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
nine_slice_grow (GskNglTextureNineSlice *slices,
|
nine_slice_grow (GskGLTextureNineSlice *slices,
|
||||||
int amount_x,
|
int amount_x,
|
||||||
int amount_y)
|
int amount_y)
|
||||||
{
|
{
|
||||||
if (amount_x == 0 && amount_y == 0)
|
if (amount_x == 0 && amount_y == 0)
|
||||||
return;
|
return;
|
@ -139,7 +139,7 @@
|
|||||||
#include "gskglshaderprivate.h"
|
#include "gskglshaderprivate.h"
|
||||||
#include "gskdebugprivate.h"
|
#include "gskdebugprivate.h"
|
||||||
|
|
||||||
#include "ngl/gsknglrendererprivate.h"
|
#include "gl/gskglrendererprivate.h"
|
||||||
|
|
||||||
static GskGLUniformType
|
static GskGLUniformType
|
||||||
uniform_type_from_glsl (const char *str)
|
uniform_type_from_glsl (const char *str)
|
||||||
@ -543,8 +543,8 @@ gsk_gl_shader_compile (GskGLShader *shader,
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GSK_IS_GL_SHADER (shader), FALSE);
|
g_return_val_if_fail (GSK_IS_GL_SHADER (shader), FALSE);
|
||||||
|
|
||||||
if (GSK_IS_NGL_RENDERER (renderer))
|
if (GSK_IS_GL_RENDERER (renderer))
|
||||||
return gsk_ngl_renderer_try_compile_gl_shader (GSK_NGL_RENDERER (renderer), shader, error);
|
return gsk_gl_renderer_try_compile_gl_shader (GSK_GL_RENDERER (renderer), shader, error);
|
||||||
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
"The renderer does not support gl shaders");
|
"The renderer does not support gl shaders");
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#include "gskcairorenderer.h"
|
#include "gskcairorenderer.h"
|
||||||
#include "gskdebugprivate.h"
|
#include "gskdebugprivate.h"
|
||||||
#include "ngl/gsknglrenderer.h"
|
#include "gl/gskglrenderer.h"
|
||||||
#include "gskprofilerprivate.h"
|
#include "gskprofilerprivate.h"
|
||||||
#include "gskrendernodeprivate.h"
|
#include "gskrendernodeprivate.h"
|
||||||
|
|
||||||
@ -505,8 +505,8 @@ get_renderer_for_name (const char *renderer_name)
|
|||||||
else if (g_ascii_strcasecmp (renderer_name, "cairo") == 0)
|
else if (g_ascii_strcasecmp (renderer_name, "cairo") == 0)
|
||||||
return GSK_TYPE_CAIRO_RENDERER;
|
return GSK_TYPE_CAIRO_RENDERER;
|
||||||
else if (g_ascii_strcasecmp (renderer_name, "opengl") == 0 ||
|
else if (g_ascii_strcasecmp (renderer_name, "opengl") == 0 ||
|
||||||
g_ascii_strcasecmp (renderer_name, "ngl") == 0)
|
g_ascii_strcasecmp (renderer_name, "gl") == 0)
|
||||||
return GSK_TYPE_NGL_RENDERER;
|
return GSK_TYPE_GL_RENDERER;
|
||||||
#ifdef GDK_RENDERING_VULKAN
|
#ifdef GDK_RENDERING_VULKAN
|
||||||
else if (g_ascii_strcasecmp (renderer_name, "vulkan") == 0)
|
else if (g_ascii_strcasecmp (renderer_name, "vulkan") == 0)
|
||||||
return GSK_TYPE_VULKAN_RENDERER;
|
return GSK_TYPE_VULKAN_RENDERER;
|
||||||
@ -520,8 +520,8 @@ get_renderer_for_name (const char *renderer_name)
|
|||||||
g_print ("broadway - Disabled during GTK build\n");
|
g_print ("broadway - Disabled during GTK build\n");
|
||||||
#endif
|
#endif
|
||||||
g_print (" cairo - Use the Cairo fallback renderer\n");
|
g_print (" cairo - Use the Cairo fallback renderer\n");
|
||||||
g_print (" opengl - Use the default OpenGL renderer\n");
|
g_print (" opengl - Use the OpenGL renderer\n");
|
||||||
g_print (" ngl - An OpenGL renderer\n");
|
g_print (" gl - Use the OpenGL renderer\n");
|
||||||
#ifdef GDK_RENDERING_VULKAN
|
#ifdef GDK_RENDERING_VULKAN
|
||||||
g_print (" vulkan - Use the Vulkan renderer\n");
|
g_print (" vulkan - Use the Vulkan renderer\n");
|
||||||
#else
|
#else
|
||||||
@ -567,11 +567,11 @@ get_renderer_for_backend (GdkSurface *surface)
|
|||||||
{
|
{
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
if (GDK_IS_X11_SURFACE (surface))
|
if (GDK_IS_X11_SURFACE (surface))
|
||||||
return GSK_TYPE_NGL_RENDERER;
|
return GSK_TYPE_GL_RENDERER;
|
||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_SURFACE (surface))
|
if (GDK_IS_WAYLAND_SURFACE (surface))
|
||||||
return GSK_TYPE_NGL_RENDERER;
|
return GSK_TYPE_GL_RENDERER;
|
||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_BROADWAY
|
#ifdef GDK_WINDOWING_BROADWAY
|
||||||
if (GDK_IS_BROADWAY_SURFACE (surface))
|
if (GDK_IS_BROADWAY_SURFACE (surface))
|
||||||
@ -579,7 +579,7 @@ get_renderer_for_backend (GdkSurface *surface)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_MACOS
|
#ifdef GDK_WINDOWING_MACOS
|
||||||
if (GDK_IS_MACOS_SURFACE (surface))
|
if (GDK_IS_MACOS_SURFACE (surface))
|
||||||
return GSK_TYPE_NGL_RENDERER;
|
return GSK_TYPE_GL_RENDERER;
|
||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_WIN32
|
#ifdef GDK_WINDOWING_WIN32
|
||||||
if (GDK_IS_WIN32_SURFACE (surface))
|
if (GDK_IS_WIN32_SURFACE (surface))
|
||||||
@ -589,7 +589,7 @@ get_renderer_for_backend (GdkSurface *surface)
|
|||||||
|
|
||||||
if (!(GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
if (!(GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||||
GDK_WIN32_DISPLAY (display)->running_on_arm64))
|
GDK_WIN32_DISPLAY (display)->running_on_arm64))
|
||||||
return GSK_TYPE_NGL_RENDERER;
|
return GSK_TYPE_GL_RENDERER;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
gsk_private_ngl_shaders = [
|
gsk_private_gl_shaders = [
|
||||||
'ngl/resources/preamble.glsl',
|
'gl/resources/preamble.glsl',
|
||||||
'ngl/resources/preamble.fs.glsl',
|
'gl/resources/preamble.fs.glsl',
|
||||||
'ngl/resources/preamble.vs.glsl',
|
'gl/resources/preamble.vs.glsl',
|
||||||
'ngl/resources/border.glsl',
|
'gl/resources/border.glsl',
|
||||||
'ngl/resources/blit.glsl',
|
'gl/resources/blit.glsl',
|
||||||
'ngl/resources/coloring.glsl',
|
'gl/resources/coloring.glsl',
|
||||||
'ngl/resources/color.glsl',
|
'gl/resources/color.glsl',
|
||||||
'ngl/resources/linear_gradient.glsl',
|
'gl/resources/linear_gradient.glsl',
|
||||||
'ngl/resources/radial_gradient.glsl',
|
'gl/resources/radial_gradient.glsl',
|
||||||
'ngl/resources/conic_gradient.glsl',
|
'gl/resources/conic_gradient.glsl',
|
||||||
'ngl/resources/color_matrix.glsl',
|
'gl/resources/color_matrix.glsl',
|
||||||
'ngl/resources/blur.glsl',
|
'gl/resources/blur.glsl',
|
||||||
'ngl/resources/inset_shadow.glsl',
|
'gl/resources/inset_shadow.glsl',
|
||||||
'ngl/resources/outset_shadow.glsl',
|
'gl/resources/outset_shadow.glsl',
|
||||||
'ngl/resources/unblurred_outset_shadow.glsl',
|
'gl/resources/unblurred_outset_shadow.glsl',
|
||||||
'ngl/resources/cross_fade.glsl',
|
'gl/resources/cross_fade.glsl',
|
||||||
'ngl/resources/blend.glsl',
|
'gl/resources/blend.glsl',
|
||||||
'ngl/resources/repeat.glsl',
|
'gl/resources/repeat.glsl',
|
||||||
'ngl/resources/custom.glsl',
|
'gl/resources/custom.glsl',
|
||||||
'ngl/resources/filled_border.glsl',
|
'gl/resources/filled_border.glsl',
|
||||||
]
|
]
|
||||||
|
|
||||||
gsk_public_sources = files([
|
gsk_public_sources = files([
|
||||||
@ -31,7 +31,7 @@ gsk_public_sources = files([
|
|||||||
'gskrendernodeparser.c',
|
'gskrendernodeparser.c',
|
||||||
'gskroundedrect.c',
|
'gskroundedrect.c',
|
||||||
'gsktransform.c',
|
'gsktransform.c',
|
||||||
'ngl/gsknglrenderer.c',
|
'gl/gskglrenderer.c',
|
||||||
])
|
])
|
||||||
|
|
||||||
gsk_private_sources = files([
|
gsk_private_sources = files([
|
||||||
@ -39,26 +39,26 @@ gsk_private_sources = files([
|
|||||||
'gskdebug.c',
|
'gskdebug.c',
|
||||||
'gskprivate.c',
|
'gskprivate.c',
|
||||||
'gskprofiler.c',
|
'gskprofiler.c',
|
||||||
'ngl/gsknglattachmentstate.c',
|
'gl/gskglattachmentstate.c',
|
||||||
'ngl/gsknglbuffer.c',
|
'gl/gskglbuffer.c',
|
||||||
'ngl/gsknglcommandqueue.c',
|
'gl/gskglcommandqueue.c',
|
||||||
'ngl/gsknglcompiler.c',
|
'gl/gskglcompiler.c',
|
||||||
'ngl/gskngldriver.c',
|
'gl/gskgldriver.c',
|
||||||
'ngl/gsknglglyphlibrary.c',
|
'gl/gskglglyphlibrary.c',
|
||||||
'ngl/gskngliconlibrary.c',
|
'gl/gskgliconlibrary.c',
|
||||||
'ngl/gsknglprogram.c',
|
'gl/gskglprogram.c',
|
||||||
'ngl/gsknglrenderjob.c',
|
'gl/gskglrenderjob.c',
|
||||||
'ngl/gsknglshadowlibrary.c',
|
'gl/gskglshadowlibrary.c',
|
||||||
'ngl/gskngltexturelibrary.c',
|
'gl/gskgltexturelibrary.c',
|
||||||
'ngl/gskngluniformstate.c',
|
'gl/gskgluniformstate.c',
|
||||||
'ngl/gskngltexture.c',
|
'gl/gskgltexture.c',
|
||||||
'ngl/gskglprofiler.c',
|
'gl/gskglprofiler.c',
|
||||||
'ngl/stb_rect_pack.c',
|
'gl/stb_rect_pack.c',
|
||||||
'ngl/fp16.c',
|
'gl/fp16.c',
|
||||||
])
|
])
|
||||||
|
|
||||||
gsk_f16c_sources = files([
|
gsk_f16c_sources = files([
|
||||||
'ngl/fp16i.c',
|
'gl/fp16i.c',
|
||||||
])
|
])
|
||||||
|
|
||||||
gsk_public_headers = files([
|
gsk_public_headers = files([
|
||||||
@ -75,7 +75,7 @@ gsk_public_headers = files([
|
|||||||
install_headers(gsk_public_headers, 'gsk.h', subdir: 'gtk-4.0/gsk')
|
install_headers(gsk_public_headers, 'gsk.h', subdir: 'gtk-4.0/gsk')
|
||||||
|
|
||||||
gsk_public_gl_headers = files([
|
gsk_public_gl_headers = files([
|
||||||
'ngl/gsknglrenderer.h',
|
'gl/gskglrenderer.h',
|
||||||
])
|
])
|
||||||
install_headers(gsk_public_gl_headers, subdir: 'gtk-4.0/gsk/gl')
|
install_headers(gsk_public_gl_headers, subdir: 'gtk-4.0/gsk/gl')
|
||||||
gsk_public_headers += gsk_public_gl_headers
|
gsk_public_headers += gsk_public_gl_headers
|
||||||
@ -145,7 +145,7 @@ gsk_resources_xml = configure_file(output: 'gsk.resources.xml',
|
|||||||
command: [
|
command: [
|
||||||
find_program('gen-gsk-gresources-xml.py'),
|
find_program('gen-gsk-gresources-xml.py'),
|
||||||
'@OUTPUT@',
|
'@OUTPUT@',
|
||||||
gsk_private_ngl_shaders,
|
gsk_private_gl_shaders,
|
||||||
gsk_private_vulkan_compiled_shaders,
|
gsk_private_vulkan_compiled_shaders,
|
||||||
gsk_private_vulkan_shaders
|
gsk_private_vulkan_shaders
|
||||||
],
|
],
|
||||||
|
@ -1,362 +0,0 @@
|
|||||||
/* gsknglcommandqueueprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_COMMAND_QUEUE_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_COMMAND_QUEUE_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <gsk/gskprofilerprivate.h>
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
#include "gsknglbufferprivate.h"
|
|
||||||
#include "gsknglattachmentstateprivate.h"
|
|
||||||
#include "gskngluniformstateprivate.h"
|
|
||||||
|
|
||||||
#include "inlinearray.h"
|
|
||||||
|
|
||||||
#include "gskglprofilerprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_COMMAND_QUEUE (gsk_ngl_command_queue_get_type())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglCommandQueue, gsk_ngl_command_queue, GSK, NGL_COMMAND_QUEUE, GObject)
|
|
||||||
|
|
||||||
typedef enum _GskNglCommandKind
|
|
||||||
{
|
|
||||||
/* The batch will perform a glClear() */
|
|
||||||
GSK_NGL_COMMAND_KIND_CLEAR,
|
|
||||||
|
|
||||||
/* The batch will perform a glDrawArrays() */
|
|
||||||
GSK_NGL_COMMAND_KIND_DRAW,
|
|
||||||
} GskNglCommandKind;
|
|
||||||
|
|
||||||
typedef struct _GskNglCommandBind
|
|
||||||
{
|
|
||||||
/* @texture is the value passed to glActiveTexture(), the "slot" the
|
|
||||||
* texture will be placed into. We always use GL_TEXTURE_2D so we don't
|
|
||||||
* waste any bits here to indicate that.
|
|
||||||
*/
|
|
||||||
guint texture : 5;
|
|
||||||
|
|
||||||
/* The identifier for the texture created with glGenTextures(). */
|
|
||||||
guint id : 27;
|
|
||||||
} GskNglCommandBind;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandBind) == 4);
|
|
||||||
|
|
||||||
typedef struct _GskNglCommandBatchAny
|
|
||||||
{
|
|
||||||
/* A GskNglCommandKind indicating what the batch will do */
|
|
||||||
guint kind : 8;
|
|
||||||
|
|
||||||
/* The program's identifier to use for determining if we can merge two
|
|
||||||
* batches together into a single set of draw operations. We put this
|
|
||||||
* here instead of the GskNglCommandDraw so that we can use the extra
|
|
||||||
* bits here without making the structure larger.
|
|
||||||
*/
|
|
||||||
guint program : 24;
|
|
||||||
|
|
||||||
/* The index of the next batch following this one. This is used
|
|
||||||
* as a sort of integer-based linked list to simplify out-of-order
|
|
||||||
* batching without moving memory around. -1 indicates last batch.
|
|
||||||
*/
|
|
||||||
gint16 next_batch_index;
|
|
||||||
|
|
||||||
/* Same but for reverse direction as we sort in reverse to get the
|
|
||||||
* batches ordered by framebuffer.
|
|
||||||
*/
|
|
||||||
gint16 prev_batch_index;
|
|
||||||
|
|
||||||
/* The viewport size of the batch. We check this as we process
|
|
||||||
* batches to determine if we need to resize the viewport.
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
guint16 width;
|
|
||||||
guint16 height;
|
|
||||||
} viewport;
|
|
||||||
} GskNglCommandBatchAny;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandBatchAny) == 12);
|
|
||||||
|
|
||||||
typedef struct _GskNglCommandDraw
|
|
||||||
{
|
|
||||||
GskNglCommandBatchAny head;
|
|
||||||
|
|
||||||
/* There doesn't seem to be a limit on the framebuffer identifier that
|
|
||||||
* can be returned, so we have to use a whole unsigned for the framebuffer
|
|
||||||
* we are drawing to. When processing batches, we check to see if this
|
|
||||||
* changes and adjust the render target accordingly. Some sorting is
|
|
||||||
* performed to reduce the amount we change framebuffers.
|
|
||||||
*/
|
|
||||||
guint framebuffer;
|
|
||||||
|
|
||||||
/* The number of uniforms to change. This must be less than or equal to
|
|
||||||
* GL_MAX_UNIFORM_LOCATIONS but only guaranteed up to 1024 by any OpenGL
|
|
||||||
* implementation to be conformant.
|
|
||||||
*/
|
|
||||||
guint uniform_count : 11;
|
|
||||||
|
|
||||||
/* The number of textures to bind, which is only guaranteed up to 16
|
|
||||||
* by the OpenGL specification to be conformant.
|
|
||||||
*/
|
|
||||||
guint bind_count : 5;
|
|
||||||
|
|
||||||
/* GL_MAX_ELEMENTS_VERTICES specifies 33000 for this which requires 16-bit
|
|
||||||
* to address all possible counts <= GL_MAX_ELEMENTS_VERTICES.
|
|
||||||
*/
|
|
||||||
guint vbo_count : 16;
|
|
||||||
|
|
||||||
/* The offset within the VBO containing @vbo_count vertices to send with
|
|
||||||
* glDrawArrays().
|
|
||||||
*/
|
|
||||||
guint vbo_offset;
|
|
||||||
|
|
||||||
/* The offset within the array of uniform changes to be made containing
|
|
||||||
* @uniform_count `GskNglCommandUniform` elements to apply.
|
|
||||||
*/
|
|
||||||
guint uniform_offset;
|
|
||||||
|
|
||||||
/* The offset within the array of bind changes to be made containing
|
|
||||||
* @bind_count `GskNglCommandBind` elements to apply.
|
|
||||||
*/
|
|
||||||
guint bind_offset;
|
|
||||||
} GskNglCommandDraw;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandDraw) == 32);
|
|
||||||
|
|
||||||
typedef struct _GskNglCommandClear
|
|
||||||
{
|
|
||||||
GskNglCommandBatchAny any;
|
|
||||||
guint bits;
|
|
||||||
guint framebuffer;
|
|
||||||
} GskNglCommandClear;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandClear) == 20);
|
|
||||||
|
|
||||||
typedef struct _GskNglCommandUniform
|
|
||||||
{
|
|
||||||
GskNglUniformInfo info;
|
|
||||||
guint location;
|
|
||||||
} GskNglCommandUniform;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandUniform) == 8);
|
|
||||||
|
|
||||||
typedef union _GskNglCommandBatch
|
|
||||||
{
|
|
||||||
GskNglCommandBatchAny any;
|
|
||||||
GskNglCommandDraw draw;
|
|
||||||
GskNglCommandClear clear;
|
|
||||||
} GskNglCommandBatch;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglCommandBatch) == 32);
|
|
||||||
|
|
||||||
DEFINE_INLINE_ARRAY (GskNglCommandBatches, gsk_ngl_command_batches, GskNglCommandBatch)
|
|
||||||
DEFINE_INLINE_ARRAY (GskNglCommandBinds, gsk_ngl_command_binds, GskNglCommandBind)
|
|
||||||
DEFINE_INLINE_ARRAY (GskNglCommandUniforms, gsk_ngl_command_uniforms, GskNglCommandUniform)
|
|
||||||
|
|
||||||
struct _GskNglCommandQueue
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
/* The GdkGLContext we make current before executing GL commands. */
|
|
||||||
GdkGLContext *context;
|
|
||||||
|
|
||||||
/* Array of GskNglCommandBatch which is a fixed size structure that will
|
|
||||||
* point into offsets of other arrays so that all similar data is stored
|
|
||||||
* together. The idea here is that we reduce the need for pointers so that
|
|
||||||
* using g_realloc()'d arrays is fine.
|
|
||||||
*/
|
|
||||||
GskNglCommandBatches batches;
|
|
||||||
|
|
||||||
/* Contains array of vertices and some wrapper code to help upload them
|
|
||||||
* to the GL driver. We can also tweak this to use double buffered arrays
|
|
||||||
* if we find that to be faster on some hardware and/or drivers.
|
|
||||||
*/
|
|
||||||
GskNglBuffer vertices;
|
|
||||||
|
|
||||||
/* The GskNglAttachmentState contains information about our FBO and texture
|
|
||||||
* attachments as we process incoming operations. We snapshot them into
|
|
||||||
* various batches so that we can compare differences between merge
|
|
||||||
* candidates.
|
|
||||||
*/
|
|
||||||
GskNglAttachmentState *attachments;
|
|
||||||
|
|
||||||
/* The uniform state across all programs. We snapshot this into batches so
|
|
||||||
* that we can compare uniform state between batches to give us more
|
|
||||||
* chances at merging draw commands.
|
|
||||||
*/
|
|
||||||
GskNglUniformState *uniforms;
|
|
||||||
|
|
||||||
/* Current program if we are in a draw so that we can send commands
|
|
||||||
* to the uniform state as needed.
|
|
||||||
*/
|
|
||||||
GskNglUniformProgram *program_info;
|
|
||||||
|
|
||||||
/* The profiler instance to deliver timing/etc data */
|
|
||||||
GskProfiler *profiler;
|
|
||||||
GskGLProfiler *gl_profiler;
|
|
||||||
|
|
||||||
/* Array of GskNglCommandBind which denote what textures need to be attached
|
|
||||||
* to which slot. GskNglCommandDraw.bind_offset and bind_count reference this
|
|
||||||
* array to determine what to attach.
|
|
||||||
*/
|
|
||||||
GskNglCommandBinds batch_binds;
|
|
||||||
|
|
||||||
/* Array of GskNglCommandUniform denoting which uniforms must be updated
|
|
||||||
* before the glDrawArrays() may be called. These are referenced from the
|
|
||||||
* GskNglCommandDraw.uniform_offset and uniform_count fields.
|
|
||||||
*/
|
|
||||||
GskNglCommandUniforms batch_uniforms;
|
|
||||||
|
|
||||||
/* Discovered max texture size when loading the command queue so that we
|
|
||||||
* can either scale down or slice textures to fit within this size. Assumed
|
|
||||||
* to be both height and width.
|
|
||||||
*/
|
|
||||||
int max_texture_size;
|
|
||||||
|
|
||||||
/* The index of the last batch in @batches, which may not be the element
|
|
||||||
* at the end of the array, as batches can be reordered. This is used to
|
|
||||||
* update the "next" index when adding a new batch.
|
|
||||||
*/
|
|
||||||
gint16 tail_batch_index;
|
|
||||||
gint16 head_batch_index;
|
|
||||||
|
|
||||||
/* Max framebuffer we used, so we can sort items faster */
|
|
||||||
guint fbo_max;
|
|
||||||
|
|
||||||
/* Various GSK and GDK metric counter ids */
|
|
||||||
struct {
|
|
||||||
GQuark n_frames;
|
|
||||||
GQuark cpu_time;
|
|
||||||
GQuark gpu_time;
|
|
||||||
guint n_binds;
|
|
||||||
guint n_fbos;
|
|
||||||
guint n_uniforms;
|
|
||||||
guint n_uploads;
|
|
||||||
guint n_programs;
|
|
||||||
guint queue_depth;
|
|
||||||
} metrics;
|
|
||||||
|
|
||||||
/* Counter for uploads on the frame */
|
|
||||||
guint n_uploads;
|
|
||||||
|
|
||||||
/* If we're inside a begin/end_frame pair */
|
|
||||||
guint in_frame : 1;
|
|
||||||
|
|
||||||
/* If we're inside of a begin_draw()/end_draw() pair. */
|
|
||||||
guint in_draw : 1;
|
|
||||||
|
|
||||||
/* If we've warned about truncating batches */
|
|
||||||
guint have_truncated : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
GskNglCommandQueue *gsk_ngl_command_queue_new (GdkGLContext *context,
|
|
||||||
GskNglUniformState *uniforms);
|
|
||||||
void gsk_ngl_command_queue_set_profiler (GskNglCommandQueue *self,
|
|
||||||
GskProfiler *profiler);
|
|
||||||
GdkGLContext *gsk_ngl_command_queue_get_context (GskNglCommandQueue *self);
|
|
||||||
void gsk_ngl_command_queue_make_current (GskNglCommandQueue *self);
|
|
||||||
void gsk_ngl_command_queue_begin_frame (GskNglCommandQueue *self);
|
|
||||||
void gsk_ngl_command_queue_end_frame (GskNglCommandQueue *self);
|
|
||||||
void gsk_ngl_command_queue_execute (GskNglCommandQueue *self,
|
|
||||||
guint surface_height,
|
|
||||||
guint scale_factor,
|
|
||||||
const cairo_region_t *scissor);
|
|
||||||
int gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
|
|
||||||
GdkTexture *texture,
|
|
||||||
guint x_offset,
|
|
||||||
guint y_offset,
|
|
||||||
guint width,
|
|
||||||
guint height,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter);
|
|
||||||
int gsk_ngl_command_queue_create_texture (GskNglCommandQueue *self,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int format,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter);
|
|
||||||
guint gsk_ngl_command_queue_create_framebuffer (GskNglCommandQueue *self);
|
|
||||||
gboolean gsk_ngl_command_queue_create_render_target (GskNglCommandQueue *self,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int format,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter,
|
|
||||||
guint *out_fbo_id,
|
|
||||||
guint *out_texture_id);
|
|
||||||
void gsk_ngl_command_queue_delete_program (GskNglCommandQueue *self,
|
|
||||||
guint program_id);
|
|
||||||
void gsk_ngl_command_queue_clear (GskNglCommandQueue *self,
|
|
||||||
guint clear_bits,
|
|
||||||
const graphene_rect_t *viewport);
|
|
||||||
void gsk_ngl_command_queue_begin_draw (GskNglCommandQueue *self,
|
|
||||||
GskNglUniformProgram *program_info,
|
|
||||||
guint width,
|
|
||||||
guint height);
|
|
||||||
void gsk_ngl_command_queue_end_draw (GskNglCommandQueue *self);
|
|
||||||
void gsk_ngl_command_queue_split_draw (GskNglCommandQueue *self);
|
|
||||||
|
|
||||||
static inline GskNglCommandBatch *
|
|
||||||
gsk_ngl_command_queue_get_batch (GskNglCommandQueue *self)
|
|
||||||
{
|
|
||||||
return gsk_ngl_command_batches_tail (&self->batches);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GskNglDrawVertex *
|
|
||||||
gsk_ngl_command_queue_add_vertices (GskNglCommandQueue *self)
|
|
||||||
{
|
|
||||||
gsk_ngl_command_queue_get_batch (self)->draw.vbo_count += GSK_NGL_N_VERTICES;
|
|
||||||
return gsk_ngl_buffer_advance (&self->vertices, GSK_NGL_N_VERTICES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GskNglDrawVertex *
|
|
||||||
gsk_ngl_command_queue_add_n_vertices (GskNglCommandQueue *self,
|
|
||||||
guint count)
|
|
||||||
{
|
|
||||||
/* This is a batch form of gsk_ngl_command_queue_add_vertices(). Note that
|
|
||||||
* it does *not* add the count to .draw.vbo_count as the caller is responsible
|
|
||||||
* for that.
|
|
||||||
*/
|
|
||||||
return gsk_ngl_buffer_advance (&self->vertices, GSK_NGL_N_VERTICES * count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_command_queue_retract_n_vertices (GskNglCommandQueue *self,
|
|
||||||
guint count)
|
|
||||||
{
|
|
||||||
/* Like gsk_ngl_command_queue_add_n_vertices(), this does not tweak
|
|
||||||
* the draw vbo_count.
|
|
||||||
*/
|
|
||||||
gsk_ngl_buffer_retract (&self->vertices, GSK_NGL_N_VERTICES * count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
gsk_ngl_command_queue_bind_framebuffer (GskNglCommandQueue *self,
|
|
||||||
guint framebuffer)
|
|
||||||
{
|
|
||||||
guint ret = self->attachments->fbo.id;
|
|
||||||
gsk_ngl_attachment_state_bind_framebuffer (self->attachments, framebuffer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_COMMAND_QUEUE_PRIVATE_H__ */
|
|
@ -1,70 +0,0 @@
|
|||||||
/* gsknglcompilerprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_COMPILER_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_COMPILER_PRIVATE_H__
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
typedef enum _GskNglCompilerKind
|
|
||||||
{
|
|
||||||
GSK_NGL_COMPILER_ALL,
|
|
||||||
GSK_NGL_COMPILER_FRAGMENT,
|
|
||||||
GSK_NGL_COMPILER_VERTEX,
|
|
||||||
} GskNglCompilerKind;
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_COMPILER (gsk_ngl_compiler_get_type())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglCompiler, gsk_ngl_compiler, GSK, NGL_COMPILER, GObject)
|
|
||||||
|
|
||||||
GskNglCompiler *gsk_ngl_compiler_new (GskNglDriver *driver,
|
|
||||||
gboolean debug);
|
|
||||||
void gsk_ngl_compiler_set_preamble (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
GBytes *preamble_bytes);
|
|
||||||
void gsk_ngl_compiler_set_preamble_from_resource (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
const char *resource_path);
|
|
||||||
void gsk_ngl_compiler_set_source (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
GBytes *source_bytes);
|
|
||||||
void gsk_ngl_compiler_set_source_from_resource (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
const char *resource_path);
|
|
||||||
void gsk_ngl_compiler_set_suffix (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
GBytes *suffix_bytes);
|
|
||||||
void gsk_ngl_compiler_set_suffix_from_resource (GskNglCompiler *self,
|
|
||||||
GskNglCompilerKind kind,
|
|
||||||
const char *resource_path);
|
|
||||||
void gsk_ngl_compiler_bind_attribute (GskNglCompiler *self,
|
|
||||||
const char *name,
|
|
||||||
guint location);
|
|
||||||
void gsk_ngl_compiler_clear_attributes (GskNglCompiler *self);
|
|
||||||
GskNglProgram *gsk_ngl_compiler_compile (GskNglCompiler *self,
|
|
||||||
const char *name,
|
|
||||||
const char *clip,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_COMPILER_PRIVATE_H__ */
|
|
@ -1,251 +0,0 @@
|
|||||||
/* gskngldriverprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This file is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_DRIVER_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_DRIVER_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <gdk/gdkgltextureprivate.h>
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
#include "gskngltextureprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
enum {
|
|
||||||
UNIFORM_SHARED_ALPHA,
|
|
||||||
UNIFORM_SHARED_SOURCE,
|
|
||||||
UNIFORM_SHARED_CLIP_RECT,
|
|
||||||
UNIFORM_SHARED_VIEWPORT,
|
|
||||||
UNIFORM_SHARED_PROJECTION,
|
|
||||||
UNIFORM_SHARED_MODELVIEW,
|
|
||||||
|
|
||||||
UNIFORM_SHARED_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
UNIFORM_CUSTOM_SIZE = UNIFORM_SHARED_LAST,
|
|
||||||
UNIFORM_CUSTOM_TEXTURE1,
|
|
||||||
UNIFORM_CUSTOM_TEXTURE2,
|
|
||||||
UNIFORM_CUSTOM_TEXTURE3,
|
|
||||||
UNIFORM_CUSTOM_TEXTURE4,
|
|
||||||
UNIFORM_CUSTOM_ARG0,
|
|
||||||
UNIFORM_CUSTOM_ARG1,
|
|
||||||
UNIFORM_CUSTOM_ARG2,
|
|
||||||
UNIFORM_CUSTOM_ARG3,
|
|
||||||
UNIFORM_CUSTOM_ARG4,
|
|
||||||
UNIFORM_CUSTOM_ARG5,
|
|
||||||
UNIFORM_CUSTOM_ARG6,
|
|
||||||
UNIFORM_CUSTOM_ARG7,
|
|
||||||
|
|
||||||
UNIFORM_CUSTOM_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
gconstpointer pointer;
|
|
||||||
float scale_x;
|
|
||||||
float scale_y;
|
|
||||||
int filter;
|
|
||||||
int pointer_is_child;
|
|
||||||
graphene_rect_t parent_rect; /* Valid when pointer_is_child */
|
|
||||||
} GskTextureKey;
|
|
||||||
|
|
||||||
#define GSK_NGL_NO_UNIFORMS CONCAT_EXPANDED(UNIFORM_INVALID_,__COUNTER__)
|
|
||||||
#define CONCAT_EXPANDED(a,b) CONCAT_EXPANDED2(a,b)
|
|
||||||
#define CONCAT_EXPANDED2(a,b) a##b
|
|
||||||
#define GSK_NGL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos,
|
|
||||||
#define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms };
|
|
||||||
# include "gsknglprograms.defs"
|
|
||||||
#undef GSK_NGL_DEFINE_PROGRAM
|
|
||||||
#undef GSK_NGL_ADD_UNIFORM
|
|
||||||
#undef GSK_NGL_NO_UNIFORMS
|
|
||||||
#undef CONCAT_EXPANDED
|
|
||||||
#undef CONCAT_EXPANDED2
|
|
||||||
|
|
||||||
#define GSK_TYPE_NGL_DRIVER (gsk_ngl_driver_get_type())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglDriver, gsk_ngl_driver, GSK, NGL_DRIVER, GObject)
|
|
||||||
|
|
||||||
struct _GskNglRenderTarget
|
|
||||||
{
|
|
||||||
guint framebuffer_id;
|
|
||||||
guint texture_id;
|
|
||||||
int min_filter;
|
|
||||||
int mag_filter;
|
|
||||||
int format;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GskNglDriver
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
GskNglCommandQueue *shared_command_queue;
|
|
||||||
GskNglCommandQueue *command_queue;
|
|
||||||
|
|
||||||
GskNglGlyphLibrary *glyphs;
|
|
||||||
GskNglIconLibrary *icons;
|
|
||||||
GskNglShadowLibrary *shadows;
|
|
||||||
|
|
||||||
GArray *texture_pool;
|
|
||||||
GHashTable *textures;
|
|
||||||
GHashTable *key_to_texture_id;
|
|
||||||
GHashTable *texture_id_to_key;
|
|
||||||
|
|
||||||
GPtrArray *atlases;
|
|
||||||
|
|
||||||
GHashTable *shader_cache;
|
|
||||||
|
|
||||||
GArray *autorelease_framebuffers;
|
|
||||||
GPtrArray *render_targets;
|
|
||||||
|
|
||||||
#define GSK_NGL_NO_UNIFORMS
|
|
||||||
#define GSK_NGL_ADD_UNIFORM(pos, KEY, name)
|
|
||||||
#define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) \
|
|
||||||
GskNglProgram *name ## _no_clip; \
|
|
||||||
GskNglProgram *name ## _rect_clip; \
|
|
||||||
GskNglProgram *name;
|
|
||||||
# include "gsknglprograms.defs"
|
|
||||||
#undef GSK_NGL_NO_UNIFORMS
|
|
||||||
#undef GSK_NGL_ADD_UNIFORM
|
|
||||||
#undef GSK_NGL_DEFINE_PROGRAM
|
|
||||||
|
|
||||||
gint64 current_frame_id;
|
|
||||||
|
|
||||||
/* Used to reduce number of comparisons */
|
|
||||||
guint stamps[UNIFORM_SHARED_LAST];
|
|
||||||
|
|
||||||
guint debug : 1;
|
|
||||||
guint in_frame : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
GskNglDriver *gsk_ngl_driver_for_display (GdkDisplay *display,
|
|
||||||
gboolean debug_shaders,
|
|
||||||
GError **error);
|
|
||||||
GskNglCommandQueue *gsk_ngl_driver_create_command_queue (GskNglDriver *self,
|
|
||||||
GdkGLContext *context);
|
|
||||||
GdkGLContext *gsk_ngl_driver_get_context (GskNglDriver *self);
|
|
||||||
gboolean gsk_ngl_driver_create_render_target (GskNglDriver *self,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int format,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter,
|
|
||||||
GskNglRenderTarget **render_target);
|
|
||||||
guint gsk_ngl_driver_release_render_target (GskNglDriver *self,
|
|
||||||
GskNglRenderTarget *render_target,
|
|
||||||
gboolean release_texture);
|
|
||||||
void gsk_ngl_driver_begin_frame (GskNglDriver *self,
|
|
||||||
GskNglCommandQueue *command_queue);
|
|
||||||
void gsk_ngl_driver_end_frame (GskNglDriver *self);
|
|
||||||
void gsk_ngl_driver_after_frame (GskNglDriver *self);
|
|
||||||
GdkTexture *gsk_ngl_driver_create_gdk_texture (GskNglDriver *self,
|
|
||||||
guint texture_id);
|
|
||||||
void gsk_ngl_driver_cache_texture (GskNglDriver *self,
|
|
||||||
const GskTextureKey *key,
|
|
||||||
guint texture_id);
|
|
||||||
guint gsk_ngl_driver_load_texture (GskNglDriver *self,
|
|
||||||
GdkTexture *texture,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter);
|
|
||||||
GskNglTexture *gsk_ngl_driver_create_texture (GskNglDriver *self,
|
|
||||||
float width,
|
|
||||||
float height,
|
|
||||||
int format,
|
|
||||||
int min_filter,
|
|
||||||
int mag_filter);
|
|
||||||
void gsk_ngl_driver_release_texture (GskNglDriver *self,
|
|
||||||
GskNglTexture *texture);
|
|
||||||
void gsk_ngl_driver_release_texture_by_id (GskNglDriver *self,
|
|
||||||
guint texture_id);
|
|
||||||
GskNglTexture *gsk_ngl_driver_mark_texture_permanent (GskNglDriver *self,
|
|
||||||
guint texture_id);
|
|
||||||
void gsk_ngl_driver_add_texture_slices (GskNglDriver *self,
|
|
||||||
GdkTexture *texture,
|
|
||||||
GskNglTextureSlice **out_slices,
|
|
||||||
guint *out_n_slices);
|
|
||||||
GskNglProgram *gsk_ngl_driver_lookup_shader (GskNglDriver *self,
|
|
||||||
GskGLShader *shader,
|
|
||||||
GError **error);
|
|
||||||
GskNglTextureAtlas *gsk_ngl_driver_create_atlas (GskNglDriver *self);
|
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
|
||||||
void gsk_ngl_driver_save_atlases_to_png (GskNglDriver *self,
|
|
||||||
const char *directory);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline GskNglTexture *
|
|
||||||
gsk_ngl_driver_get_texture_by_id (GskNglDriver *self,
|
|
||||||
guint texture_id)
|
|
||||||
{
|
|
||||||
return g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_ngl_driver_lookup_texture:
|
|
||||||
* @self: a `GskNglDriver`
|
|
||||||
* @key: the key for the texture
|
|
||||||
*
|
|
||||||
* Looks up a texture in the texture cache by @key.
|
|
||||||
*
|
|
||||||
* If the texture could not be found, then zero is returned.
|
|
||||||
*
|
|
||||||
* Returns: a positive integer if the texture was found; otherwise 0.
|
|
||||||
*/
|
|
||||||
static inline guint
|
|
||||||
gsk_ngl_driver_lookup_texture (GskNglDriver *self,
|
|
||||||
const GskTextureKey *key)
|
|
||||||
{
|
|
||||||
gpointer id;
|
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended (self->key_to_texture_id, key, NULL, &id))
|
|
||||||
{
|
|
||||||
GskNglTexture *texture = g_hash_table_lookup (self->textures, id);
|
|
||||||
|
|
||||||
if (texture != NULL)
|
|
||||||
texture->last_used_in_frame = self->current_frame_id;
|
|
||||||
|
|
||||||
return GPOINTER_TO_UINT (id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_driver_slice_texture (GskNglDriver *self,
|
|
||||||
GdkTexture *texture,
|
|
||||||
GskNglTextureSlice **out_slices,
|
|
||||||
guint *out_n_slices)
|
|
||||||
{
|
|
||||||
GskNglTexture *t;
|
|
||||||
|
|
||||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
|
||||||
{
|
|
||||||
*out_slices = t->slices;
|
|
||||||
*out_n_slices = t->n_slices;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gsk_ngl_driver_add_texture_slices (self, texture, out_slices, out_n_slices);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_DRIVER_PRIVATE_H__ */
|
|
@ -1,103 +0,0 @@
|
|||||||
/* gsknglglyphlibraryprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_GLYPH_LIBRARY_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_GLYPH_LIBRARY_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <pango/pango.h>
|
|
||||||
|
|
||||||
#include "gskngltexturelibraryprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_GLYPH_LIBRARY (gsk_ngl_glyph_library_get_type())
|
|
||||||
|
|
||||||
typedef struct _GskNglGlyphKey
|
|
||||||
{
|
|
||||||
PangoFont *font;
|
|
||||||
PangoGlyph glyph;
|
|
||||||
guint xshift : 2;
|
|
||||||
guint yshift : 2;
|
|
||||||
guint scale : 28; /* times 1024 */
|
|
||||||
} GskNglGlyphKey;
|
|
||||||
|
|
||||||
typedef struct _GskNglGlyphValue
|
|
||||||
{
|
|
||||||
GskNglTextureAtlasEntry entry;
|
|
||||||
PangoRectangle ink_rect;
|
|
||||||
} GskNglGlyphValue;
|
|
||||||
|
|
||||||
#if GLIB_SIZEOF_VOID_P == 8
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglGlyphKey) == 16);
|
|
||||||
#elif GLIB_SIZEOF_VOID_P == 4
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglGlyphKey) == 12);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglGlyphLibrary, gsk_ngl_glyph_library, GSK, NGL_GLYPH_LIBRARY, GskNglTextureLibrary)
|
|
||||||
|
|
||||||
struct _GskNglGlyphLibrary
|
|
||||||
{
|
|
||||||
GskNglTextureLibrary parent_instance;
|
|
||||||
guint8 *surface_data;
|
|
||||||
gsize surface_data_len;
|
|
||||||
struct {
|
|
||||||
GskNglGlyphKey key;
|
|
||||||
const GskNglGlyphValue *value;
|
|
||||||
} front[256];
|
|
||||||
};
|
|
||||||
|
|
||||||
GskNglGlyphLibrary *gsk_ngl_glyph_library_new (GskNglDriver *driver);
|
|
||||||
gboolean gsk_ngl_glyph_library_add (GskNglGlyphLibrary *self,
|
|
||||||
GskNglGlyphKey *key,
|
|
||||||
const GskNglGlyphValue **out_value);
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
gsk_ngl_glyph_library_lookup_or_add (GskNglGlyphLibrary *self,
|
|
||||||
const GskNglGlyphKey *key,
|
|
||||||
const GskNglGlyphValue **out_value)
|
|
||||||
{
|
|
||||||
GskNglTextureAtlasEntry *entry;
|
|
||||||
guint front_index = ((key->glyph << 2) | key->xshift) & 0xFF;
|
|
||||||
|
|
||||||
if (memcmp (key, &self->front[front_index], sizeof *key) == 0)
|
|
||||||
{
|
|
||||||
*out_value = self->front[front_index].value;
|
|
||||||
}
|
|
||||||
else if (gsk_ngl_texture_library_lookup ((GskNglTextureLibrary *)self, key, &entry))
|
|
||||||
{
|
|
||||||
*out_value = (GskNglGlyphValue *)entry;
|
|
||||||
self->front[front_index].key = *key;
|
|
||||||
self->front[front_index].value = *out_value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GskNglGlyphKey *k = g_slice_copy (sizeof *key, key);
|
|
||||||
g_object_ref (k->font);
|
|
||||||
gsk_ngl_glyph_library_add (self, k, out_value);
|
|
||||||
self->front[front_index].key = *key;
|
|
||||||
self->front[front_index].value = *out_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_GLYPH_LIBRARY_PRIVATE_H__ */
|
|
@ -1,60 +0,0 @@
|
|||||||
/* gskngliconlibraryprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_ICON_LIBRARY_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_ICON_LIBRARY_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <pango/pango.h>
|
|
||||||
|
|
||||||
#include "gskngltexturelibraryprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_ICON_LIBRARY (gsk_ngl_icon_library_get_type())
|
|
||||||
|
|
||||||
typedef struct _GskNglIconData
|
|
||||||
{
|
|
||||||
GskNglTextureAtlasEntry entry;
|
|
||||||
GdkTexture *source_texture;
|
|
||||||
} GskNglIconData;
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglIconLibrary, gsk_ngl_icon_library, GSK, NGL_ICON_LIBRARY, GskNglTextureLibrary)
|
|
||||||
|
|
||||||
GskNglIconLibrary *gsk_ngl_icon_library_new (GskNglDriver *driver);
|
|
||||||
void gsk_ngl_icon_library_add (GskNglIconLibrary *self,
|
|
||||||
GdkTexture *key,
|
|
||||||
const GskNglIconData **out_value);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_icon_library_lookup_or_add (GskNglIconLibrary *self,
|
|
||||||
GdkTexture *key,
|
|
||||||
const GskNglIconData **out_value)
|
|
||||||
{
|
|
||||||
GskNglTextureAtlasEntry *entry;
|
|
||||||
|
|
||||||
if G_LIKELY (gsk_ngl_texture_library_lookup ((GskNglTextureLibrary *)self, key, &entry))
|
|
||||||
*out_value = (GskNglIconData *)entry;
|
|
||||||
else
|
|
||||||
gsk_ngl_icon_library_add (self, key, out_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_ICON_LIBRARY_PRIVATE_H__ */
|
|
@ -1,282 +0,0 @@
|
|||||||
/* gsknglprogramprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_PROGRAM_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_PROGRAM_PRIVATE_H__
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
|
|
||||||
#include "gsknglattachmentstateprivate.h"
|
|
||||||
#include "gsknglcommandqueueprivate.h"
|
|
||||||
#include "gskngldriverprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_PROGRAM (gsk_ngl_program_get_type())
|
|
||||||
#define GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES 4
|
|
||||||
#define GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS 8
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglProgram, gsk_ngl_program, GSK, NGL_PROGRAM, GObject)
|
|
||||||
|
|
||||||
struct _GskNglProgram
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
int id;
|
|
||||||
char *name;
|
|
||||||
GskNglDriver *driver;
|
|
||||||
|
|
||||||
/* Cached pointer to avoid lots of pointer chasing/lookups */
|
|
||||||
GskNglUniformState *uniforms;
|
|
||||||
GskNglUniformProgram *program_info;
|
|
||||||
|
|
||||||
/* Static array for key->location transforms */
|
|
||||||
GskNglUniformMapping mappings[32];
|
|
||||||
guint n_mappings;
|
|
||||||
};
|
|
||||||
|
|
||||||
GskNglProgram *gsk_ngl_program_new (GskNglDriver *driver,
|
|
||||||
const char *name,
|
|
||||||
int program_id);
|
|
||||||
gboolean gsk_ngl_program_add_uniform (GskNglProgram *self,
|
|
||||||
const char *name,
|
|
||||||
guint key);
|
|
||||||
void gsk_ngl_program_uniforms_added (GskNglProgram *self,
|
|
||||||
gboolean has_attachments);
|
|
||||||
void gsk_ngl_program_delete (GskNglProgram *self);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform1fv (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *values)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set1fv (self->uniforms, self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
count,
|
|
||||||
values);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform2fv (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *values)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set2fv (self->uniforms, self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
count,
|
|
||||||
values);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform4fv (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *values)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set4fv (self->uniforms, self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
count,
|
|
||||||
values);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform_rounded_rect (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const GskRoundedRect *rounded_rect)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set_rounded_rect (self->uniforms, self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
rounded_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform1i (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set1i (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform2i (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set2i (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform3i (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1,
|
|
||||||
int value2)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set3i (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1, value2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform4i (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1,
|
|
||||||
int value2,
|
|
||||||
int value3)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set4i (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1, value2, value3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform1f (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set1f (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform2f (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set2f (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform3f (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1,
|
|
||||||
float value2)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set3f (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1, value2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform4f (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1,
|
|
||||||
float value2,
|
|
||||||
float value3)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set4f (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
value0, value1, value2, value3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform_color (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const GdkRGBA *color)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set_color (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
color);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform_texture (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
GLenum texture_target,
|
|
||||||
GLenum texture_slot,
|
|
||||||
guint texture_id)
|
|
||||||
{
|
|
||||||
gsk_ngl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
|
||||||
texture_target,
|
|
||||||
texture_slot,
|
|
||||||
texture_id);
|
|
||||||
gsk_ngl_uniform_state_set_texture (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
texture_slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_program_set_uniform_matrix (GskNglProgram *self,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const graphene_matrix_t *matrix)
|
|
||||||
{
|
|
||||||
gsk_ngl_uniform_state_set_matrix (self->uniforms,
|
|
||||||
self->program_info,
|
|
||||||
key,
|
|
||||||
stamp,
|
|
||||||
matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_PROGRAM_PRIVATE_H__ */
|
|
@ -1,84 +0,0 @@
|
|||||||
GSK_NGL_DEFINE_PROGRAM (blend,
|
|
||||||
"/org/gtk/libgsk/ngl/blend.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, BLEND_SOURCE2, u_source2)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, BLEND_MODE, u_mode))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (blit,
|
|
||||||
"/org/gtk/libgsk/ngl/blit.glsl",
|
|
||||||
GSK_NGL_NO_UNIFORMS)
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (blur,
|
|
||||||
"/org/gtk/libgsk/ngl/blur.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, BLUR_RADIUS, u_blur_radius)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, BLUR_SIZE, u_blur_size)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, BLUR_DIR, u_blur_dir))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (border,
|
|
||||||
"/org/gtk/libgsk/ngl/border.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, BORDER_WIDTHS, u_widths)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, BORDER_OUTLINE_RECT, u_outline_rect))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (color,
|
|
||||||
"/org/gtk/libgsk/ngl/color.glsl",
|
|
||||||
GSK_NGL_NO_UNIFORMS)
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (coloring,
|
|
||||||
"/org/gtk/libgsk/ngl/coloring.glsl",
|
|
||||||
GSK_NGL_NO_UNIFORMS)
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (color_matrix,
|
|
||||||
"/org/gtk/libgsk/ngl/color_matrix.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, COLOR_MATRIX_COLOR_MATRIX, u_color_matrix)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, COLOR_MATRIX_COLOR_OFFSET, u_color_offset))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (conic_gradient,
|
|
||||||
"/org/gtk/libgsk/ngl/conic_gradient.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, CONIC_GRADIENT_COLOR_STOPS, u_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, CONIC_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, CONIC_GRADIENT_GEOMETRY, u_geometry))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (cross_fade,
|
|
||||||
"/org/gtk/libgsk/ngl/cross_fade.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, CROSS_FADE_PROGRESS, u_progress)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, CROSS_FADE_SOURCE2, u_source2))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (filled_border,
|
|
||||||
"/org/gtk/libgsk/ngl/filled_border.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, FILLED_BORDER_WIDTHS, u_widths)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, FILLED_BORDER_OUTLINE_RECT, u_outline_rect))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (inset_shadow,
|
|
||||||
"/org/gtk/libgsk/ngl/inset_shadow.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, INSET_SHADOW_SPREAD, u_spread)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, INSET_SHADOW_OFFSET, u_offset)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, INSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (linear_gradient,
|
|
||||||
"/org/gtk/libgsk/ngl/linear_gradient.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, LINEAR_GRADIENT_COLOR_STOPS, u_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, LINEAR_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points)
|
|
||||||
GSK_NGL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (outset_shadow,
|
|
||||||
"/org/gtk/libgsk/ngl/outset_shadow.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (radial_gradient,
|
|
||||||
"/org/gtk/libgsk/ngl/radial_gradient.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, RADIAL_GRADIENT_COLOR_STOPS, u_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, RADIAL_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, RADIAL_GRADIENT_REPEAT, u_repeat)
|
|
||||||
GSK_NGL_ADD_UNIFORM (4, RADIAL_GRADIENT_RANGE, u_range)
|
|
||||||
GSK_NGL_ADD_UNIFORM (5, RADIAL_GRADIENT_GEOMETRY, u_geometry))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (repeat,
|
|
||||||
"/org/gtk/libgsk/ngl/repeat.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, REPEAT_CHILD_BOUNDS, u_child_bounds)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, REPEAT_TEXTURE_RECT, u_texture_rect))
|
|
||||||
|
|
||||||
GSK_NGL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
|
||||||
"/org/gtk/libgsk/ngl/unblurred_outset_shadow.glsl",
|
|
||||||
GSK_NGL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
|
|
||||||
GSK_NGL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
|
|
||||||
GSK_NGL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
|
@ -1,46 +0,0 @@
|
|||||||
/* gsknglrenderer.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_RENDERER_H__
|
|
||||||
#define __GSK_NGL_RENDERER_H__
|
|
||||||
|
|
||||||
#include <gsk/gskrenderer.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_NGL_RENDERER (gsk_ngl_renderer_get_type())
|
|
||||||
|
|
||||||
#define GSK_NGL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_NGL_RENDERER, GskNglRenderer))
|
|
||||||
#define GSK_IS_NGL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_NGL_RENDERER))
|
|
||||||
#define GSK_NGL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_NGL_RENDERER, GskNglRendererClass))
|
|
||||||
#define GSK_IS_NGL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_NGL_RENDERER))
|
|
||||||
#define GSK_NGL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_NGL_RENDERER, GskNglRendererClass))
|
|
||||||
|
|
||||||
typedef struct _GskNglRenderer GskNglRenderer;
|
|
||||||
typedef struct _GskNglRendererClass GskNglRendererClass;
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_4_2
|
|
||||||
GType gsk_ngl_renderer_get_type (void) G_GNUC_CONST;
|
|
||||||
GDK_AVAILABLE_IN_4_2
|
|
||||||
GskRenderer *gsk_ngl_renderer_new (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_RENDERER__ */
|
|
@ -1,39 +0,0 @@
|
|||||||
/* gsknglrenderjobprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_RENDER_JOB_H__
|
|
||||||
#define __GSK_NGL_RENDER_JOB_H__
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
|
|
||||||
GskNglRenderJob *gsk_ngl_render_job_new (GskNglDriver *driver,
|
|
||||||
const graphene_rect_t *viewport,
|
|
||||||
float scale_factor,
|
|
||||||
const cairo_region_t *region,
|
|
||||||
guint framebuffer);
|
|
||||||
void gsk_ngl_render_job_free (GskNglRenderJob *job);
|
|
||||||
void gsk_ngl_render_job_render (GskNglRenderJob *job,
|
|
||||||
GskRenderNode *root);
|
|
||||||
void gsk_ngl_render_job_render_flipped (GskNglRenderJob *job,
|
|
||||||
GskRenderNode *root);
|
|
||||||
void gsk_ngl_render_job_set_debug_fallback (GskNglRenderJob *job,
|
|
||||||
gboolean debug_fallback);
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_RENDER_JOB_H__ */
|
|
@ -1,44 +0,0 @@
|
|||||||
/* gsknglshadowlibraryprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_SHADOW_LIBRARY_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_SHADOW_LIBRARY_PRIVATE_H__
|
|
||||||
|
|
||||||
#include "gskngltexturelibraryprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_SHADOW_LIBRARY (gsk_ngl_shadow_library_get_type())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GskNglShadowLibrary, gsk_ngl_shadow_library, GSK, NGL_SHADOW_LIBRARY, GObject)
|
|
||||||
|
|
||||||
GskNglShadowLibrary *gsk_ngl_shadow_library_new (GskNglDriver *driver);
|
|
||||||
void gsk_ngl_shadow_library_begin_frame (GskNglShadowLibrary *self);
|
|
||||||
guint gsk_ngl_shadow_library_lookup (GskNglShadowLibrary *self,
|
|
||||||
const GskRoundedRect *outline,
|
|
||||||
float blur_radius);
|
|
||||||
void gsk_ngl_shadow_library_insert (GskNglShadowLibrary *self,
|
|
||||||
const GskRoundedRect *outline,
|
|
||||||
float blur_radius,
|
|
||||||
guint texture_id);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_SHADOW_LIBRARY_PRIVATE_H__ */
|
|
@ -1,208 +0,0 @@
|
|||||||
/* gskngltexturelibraryprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU Lesser General Public License as published by the Free
|
|
||||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This file is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
* License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_TEXTURE_LIBRARY_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_TEXTURE_LIBRARY_PRIVATE_H__
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
#include "gskngltextureprivate.h"
|
|
||||||
|
|
||||||
#include "stb_rect_pack.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_TYPE_GL_TEXTURE_LIBRARY (gsk_ngl_texture_library_get_type ())
|
|
||||||
#define GSK_NGL_TEXTURE_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY, GskNglTextureLibrary))
|
|
||||||
#define GSK_IS_NGL_TEXTURE_LIBRARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY))
|
|
||||||
#define GSK_NGL_TEXTURE_LIBRARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_TEXTURE_LIBRARY, GskNglTextureLibraryClass))
|
|
||||||
#define GSK_IS_NGL_TEXTURE_LIBRARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_TEXTURE_LIBRARY))
|
|
||||||
#define GSK_NGL_TEXTURE_LIBRARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_TEXTURE_LIBRARY, GskNglTextureLibraryClass))
|
|
||||||
|
|
||||||
typedef struct _GskNglTextureAtlas
|
|
||||||
{
|
|
||||||
struct stbrp_context context;
|
|
||||||
struct stbrp_node *nodes;
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
guint texture_id;
|
|
||||||
|
|
||||||
/* Pixels of rects that have been used at some point,
|
|
||||||
* But are now unused.
|
|
||||||
*/
|
|
||||||
int unused_pixels;
|
|
||||||
|
|
||||||
void *user_data;
|
|
||||||
} GskNglTextureAtlas;
|
|
||||||
|
|
||||||
typedef struct _GskNglTextureAtlasEntry
|
|
||||||
{
|
|
||||||
/* A backreference to either the atlas or texture containing
|
|
||||||
* the contents of the atlas entry. For larger items, no atlas
|
|
||||||
* is used and instead a direct texture.
|
|
||||||
*/
|
|
||||||
union {
|
|
||||||
GskNglTextureAtlas *atlas;
|
|
||||||
GskNglTexture *texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The area within the atlas translated to 0..1 bounds */
|
|
||||||
struct {
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float x2;
|
|
||||||
float y2;
|
|
||||||
} area;
|
|
||||||
|
|
||||||
/* Number of pixels in the entry, used to calculate usage
|
|
||||||
* of an atlas while processing.
|
|
||||||
*/
|
|
||||||
guint n_pixels : 29;
|
|
||||||
|
|
||||||
/* If entry has marked pixels as used in the atlas this frame */
|
|
||||||
guint used : 1;
|
|
||||||
|
|
||||||
/* If entry was accessed this frame */
|
|
||||||
guint accessed : 1;
|
|
||||||
|
|
||||||
/* When true, backref is an atlas, otherwise texture */
|
|
||||||
guint is_atlased : 1;
|
|
||||||
} GskNglTextureAtlasEntry;
|
|
||||||
|
|
||||||
typedef struct _GskNglTextureLibrary
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
GskNglDriver *driver;
|
|
||||||
GHashTable *hash_table;
|
|
||||||
guint max_entry_size;
|
|
||||||
} GskNglTextureLibrary;
|
|
||||||
|
|
||||||
typedef struct _GskNglTextureLibraryClass
|
|
||||||
{
|
|
||||||
GObjectClass parent_class;
|
|
||||||
|
|
||||||
void (*begin_frame) (GskNglTextureLibrary *library,
|
|
||||||
gint64 frame_id,
|
|
||||||
GPtrArray *removed_atlases);
|
|
||||||
} GskNglTextureLibraryClass;
|
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskNglTextureLibrary, g_object_unref)
|
|
||||||
|
|
||||||
GType gsk_ngl_texture_library_get_type (void) G_GNUC_CONST;
|
|
||||||
void gsk_ngl_texture_library_set_funcs (GskNglTextureLibrary *self,
|
|
||||||
GHashFunc hash_func,
|
|
||||||
GEqualFunc equal_func,
|
|
||||||
GDestroyNotify key_destroy,
|
|
||||||
GDestroyNotify value_destroy);
|
|
||||||
void gsk_ngl_texture_library_begin_frame (GskNglTextureLibrary *self,
|
|
||||||
gint64 frame_id,
|
|
||||||
GPtrArray *removed_atlases);
|
|
||||||
gpointer gsk_ngl_texture_library_pack (GskNglTextureLibrary *self,
|
|
||||||
gpointer key,
|
|
||||||
gsize valuelen,
|
|
||||||
guint width,
|
|
||||||
guint height,
|
|
||||||
int padding,
|
|
||||||
guint *out_packed_x,
|
|
||||||
guint *out_packed_y);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_texture_atlas_mark_unused (GskNglTextureAtlas *self,
|
|
||||||
int n_pixels)
|
|
||||||
{
|
|
||||||
g_assert (n_pixels >= 0);
|
|
||||||
|
|
||||||
self->unused_pixels += n_pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_texture_atlas_entry_mark_used (GskNglTextureAtlasEntry *entry)
|
|
||||||
{
|
|
||||||
if (entry->used == TRUE || entry->is_atlased == FALSE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
entry->atlas->unused_pixels -= entry->n_pixels;
|
|
||||||
entry->used = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_texture_atlas_entry_mark_unused (GskNglTextureAtlasEntry *entry)
|
|
||||||
{
|
|
||||||
if (entry->used == FALSE || entry->is_atlased == FALSE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
entry->atlas->unused_pixels += entry->n_pixels;
|
|
||||||
entry->used = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
gsk_ngl_texture_library_lookup (GskNglTextureLibrary *self,
|
|
||||||
gconstpointer key,
|
|
||||||
GskNglTextureAtlasEntry **out_entry)
|
|
||||||
{
|
|
||||||
GskNglTextureAtlasEntry *entry = g_hash_table_lookup (self->hash_table, key);
|
|
||||||
|
|
||||||
if G_LIKELY (entry != NULL && entry->accessed && entry->used)
|
|
||||||
{
|
|
||||||
*out_entry = entry;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry != NULL)
|
|
||||||
{
|
|
||||||
gsk_ngl_texture_atlas_entry_mark_used (entry);
|
|
||||||
entry->accessed = TRUE;
|
|
||||||
*out_entry = entry;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (gconstpointer d)
|
|
||||||
{
|
|
||||||
const GskNglTextureAtlasEntry *e = d;
|
|
||||||
|
|
||||||
return e->is_atlased ? e->atlas->texture_id
|
|
||||||
: e->texture ? e->texture->texture_id : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double
|
|
||||||
gsk_ngl_texture_atlas_get_unused_ratio (const GskNglTextureAtlas *self)
|
|
||||||
{
|
|
||||||
if (self->unused_pixels > 0)
|
|
||||||
return (double)(self->unused_pixels) / (double)(self->width * self->height);
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gboolean
|
|
||||||
gsk_ngl_texture_library_can_cache (GskNglTextureLibrary *self,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
g_assert (self->max_entry_size > 0);
|
|
||||||
return width <= self->max_entry_size && height <= self->max_entry_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_TEXTURE_LIBRARY_PRIVATE_H__ */
|
|
@ -1,66 +0,0 @@
|
|||||||
/* gskngltypesprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GSK_NGL_TYPES_PRIVATE_H__
|
|
||||||
#define __GSK_NGL_TYPES_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
|
||||||
#include <graphene.h>
|
|
||||||
#include <gdk/gdk.h>
|
|
||||||
#include <gsk/gsk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GSK_NGL_N_VERTICES 6
|
|
||||||
|
|
||||||
typedef struct _GskNglAttachmentState GskNglAttachmentState;
|
|
||||||
typedef struct _GskNglBuffer GskNglBuffer;
|
|
||||||
typedef struct _GskNglCommandQueue GskNglCommandQueue;
|
|
||||||
typedef struct _GskNglCompiler GskNglCompiler;
|
|
||||||
typedef struct _GskNglDrawVertex GskNglDrawVertex;
|
|
||||||
typedef struct _GskNglRenderTarget GskNglRenderTarget;
|
|
||||||
typedef struct _GskNglGlyphLibrary GskNglGlyphLibrary;
|
|
||||||
typedef struct _GskNglIconLibrary GskNglIconLibrary;
|
|
||||||
typedef struct _GskNglProgram GskNglProgram;
|
|
||||||
typedef struct _GskNglRenderJob GskNglRenderJob;
|
|
||||||
typedef struct _GskNglShadowLibrary GskNglShadowLibrary;
|
|
||||||
typedef struct _GskNglTexture GskNglTexture;
|
|
||||||
typedef struct _GskNglTextureSlice GskNglTextureSlice;
|
|
||||||
typedef struct _GskNglTextureAtlas GskNglTextureAtlas;
|
|
||||||
typedef struct _GskNglTextureLibrary GskNglTextureLibrary;
|
|
||||||
typedef struct _GskNglTextureNineSlice GskNglTextureNineSlice;
|
|
||||||
typedef struct _GskNglUniformInfo GskNglUniformInfo;
|
|
||||||
typedef struct _GskNglUniformProgram GskNglUniformProgram;
|
|
||||||
typedef struct _GskNglUniformState GskNglUniformState;
|
|
||||||
typedef struct _GskNglDriver GskNglDriver;
|
|
||||||
|
|
||||||
struct _GskNglDrawVertex
|
|
||||||
{
|
|
||||||
float position[2];
|
|
||||||
union {
|
|
||||||
float uv[2];
|
|
||||||
guint16 color2[4];
|
|
||||||
};
|
|
||||||
guint16 color[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GSK_NGL_TYPES_PRIVATE_H__ */
|
|
@ -1,836 +0,0 @@
|
|||||||
/* gskngluniformstateprivate.h
|
|
||||||
*
|
|
||||||
* Copyright 2020 Christian Hergert <chergert@redhat.com>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GSK_NGL_UNIFORM_STATE_PRIVATE_H
|
|
||||||
#define GSK_NGL_UNIFORM_STATE_PRIVATE_H
|
|
||||||
|
|
||||||
#include "gskngltypesprivate.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
typedef struct { float v0; } Uniform1f;
|
|
||||||
typedef struct { float v0; float v1; } Uniform2f;
|
|
||||||
typedef struct { float v0; float v1; float v2; } Uniform3f;
|
|
||||||
typedef struct { float v0; float v1; float v2; float v3; } Uniform4f;
|
|
||||||
|
|
||||||
typedef struct { int v0; } Uniform1i;
|
|
||||||
typedef struct { int v0; int v1; } Uniform2i;
|
|
||||||
typedef struct { int v0; int v1; int v2; } Uniform3i;
|
|
||||||
typedef struct { int v0; int v1; int v2; int v3; } Uniform4i;
|
|
||||||
|
|
||||||
typedef struct { guint v0; } Uniform1ui;
|
|
||||||
|
|
||||||
#define GSK_NGL_UNIFORM_ARRAY_BITS 5
|
|
||||||
#define GSK_NGL_UNIFORM_FORMAT_BITS 5
|
|
||||||
#define GSK_NGL_UNIFORM_OFFSET_BITS 21
|
|
||||||
|
|
||||||
typedef struct _GskNglUniformInfo
|
|
||||||
{
|
|
||||||
guint initial : 1;
|
|
||||||
guint format : GSK_NGL_UNIFORM_FORMAT_BITS;
|
|
||||||
guint array_count : GSK_NGL_UNIFORM_ARRAY_BITS;
|
|
||||||
guint offset : GSK_NGL_UNIFORM_OFFSET_BITS;
|
|
||||||
} GskNglUniformInfo;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (sizeof (GskNglUniformInfo) == 4);
|
|
||||||
|
|
||||||
typedef struct _GskNglUniformMapping
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
GskNglUniformInfo info;
|
|
||||||
guint stamp;
|
|
||||||
int location;
|
|
||||||
} GskNglUniformMapping;
|
|
||||||
|
|
||||||
typedef struct _GskNglUniformProgram
|
|
||||||
{
|
|
||||||
guint program_id;
|
|
||||||
guint n_uniforms : 12;
|
|
||||||
guint has_attachments : 1;
|
|
||||||
guint n_mappings;
|
|
||||||
GskNglUniformMapping mappings[32];
|
|
||||||
} GskNglUniformProgram;
|
|
||||||
|
|
||||||
typedef struct _GskNglUniformState
|
|
||||||
{
|
|
||||||
GHashTable *programs;
|
|
||||||
guint8 *values_buf;
|
|
||||||
guint values_pos;
|
|
||||||
guint values_len;
|
|
||||||
GskNglUniformInfo apply_hash[512];
|
|
||||||
} GskNglUniformState;
|
|
||||||
|
|
||||||
typedef enum _GskNglUniformKind
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_1F = 1,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_2F,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_3F,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_4F,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_1FV,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_2FV,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_3FV,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_4FV,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_1I,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_2I,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_3I,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_4I,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_1UI,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_TEXTURE,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_MATRIX,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT,
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_COLOR,
|
|
||||||
|
|
||||||
GSK_NGL_UNIFORM_FORMAT_LAST
|
|
||||||
} GskNglUniformFormat;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT (GSK_NGL_UNIFORM_FORMAT_LAST < (1 << GSK_NGL_UNIFORM_FORMAT_BITS));
|
|
||||||
|
|
||||||
GskNglUniformState *gsk_ngl_uniform_state_new (void);
|
|
||||||
GskNglUniformState *gsk_ngl_uniform_state_ref (GskNglUniformState *state);
|
|
||||||
void gsk_ngl_uniform_state_unref (GskNglUniformState *state);
|
|
||||||
GskNglUniformProgram *gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
|
|
||||||
guint program,
|
|
||||||
const GskNglUniformMapping *mappings,
|
|
||||||
guint n_mappings);
|
|
||||||
void gsk_ngl_uniform_state_end_frame (GskNglUniformState *state);
|
|
||||||
gsize gsk_ngl_uniform_format_size (GskNglUniformFormat format);
|
|
||||||
gpointer gsk_ngl_uniform_state_init_value (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
GskNglUniformFormat format,
|
|
||||||
guint array_count,
|
|
||||||
guint key,
|
|
||||||
GskNglUniformMapping **out_mapping);
|
|
||||||
|
|
||||||
#define GSK_NGL_UNIFORM_VALUE(base, offset) ((gpointer)((base) + ((offset) * 4)))
|
|
||||||
#define gsk_ngl_uniform_state_get_uniform_data(state,offset) GSK_NGL_UNIFORM_VALUE((state)->values_buf, offset)
|
|
||||||
|
|
||||||
static inline gpointer
|
|
||||||
gsk_ngl_uniform_state_get_value (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
GskNglUniformFormat format,
|
|
||||||
guint array_count,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
GskNglUniformMapping **out_mapping)
|
|
||||||
{
|
|
||||||
GskNglUniformMapping *mapping;
|
|
||||||
|
|
||||||
g_assert (key < G_N_ELEMENTS (program->mappings));
|
|
||||||
g_assert (key < program->n_mappings);
|
|
||||||
|
|
||||||
mapping = &program->mappings[key];
|
|
||||||
|
|
||||||
/* Short-circuit if the program optimized the uniform out */
|
|
||||||
if (mapping->location == -1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* If the stamp is the same, then we can ignore the request
|
|
||||||
* and short-circuit as early as possible. This requires the
|
|
||||||
* caller to increment their private stamp when they change
|
|
||||||
* internal state.
|
|
||||||
*
|
|
||||||
* This is generally used for the shared uniforms like projection,
|
|
||||||
* modelview, clip, etc to avoid so many comparisons which cost
|
|
||||||
* considerable CPU.
|
|
||||||
*/
|
|
||||||
if (stamp != 0 && stamp == mapping->stamp)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if G_LIKELY (format == mapping->info.format && array_count <= mapping->info.array_count)
|
|
||||||
{
|
|
||||||
*out_mapping = mapping;
|
|
||||||
return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gsk_ngl_uniform_state_init_value (state, program, format, array_count, key, out_mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_GNUC_PURE static inline guint
|
|
||||||
gsk_ngl_uniform_state_align (guint current_pos,
|
|
||||||
guint size)
|
|
||||||
{
|
|
||||||
guint align = size > 8 ? 16 : (size > 4 ? 8 : 4);
|
|
||||||
guint masked = current_pos & (align - 1);
|
|
||||||
|
|
||||||
g_assert (size > 0);
|
|
||||||
g_assert (align == 4 || align == 8 || align == 16);
|
|
||||||
g_assert (masked < align);
|
|
||||||
|
|
||||||
return align - masked;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gpointer
|
|
||||||
gsk_ngl_uniform_state_realloc (GskNglUniformState *state,
|
|
||||||
guint size,
|
|
||||||
guint *offset)
|
|
||||||
{
|
|
||||||
guint padding = gsk_ngl_uniform_state_align (state->values_pos, size);
|
|
||||||
|
|
||||||
if G_UNLIKELY (state->values_len - padding - size < state->values_pos)
|
|
||||||
{
|
|
||||||
state->values_len *= 2;
|
|
||||||
state->values_buf = g_realloc (state->values_buf, state->values_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* offsets are in slots of 4 to use fewer bits */
|
|
||||||
g_assert ((state->values_pos + padding) % 4 == 0);
|
|
||||||
*offset = (state->values_pos + padding) / 4;
|
|
||||||
state->values_pos += padding + size;
|
|
||||||
|
|
||||||
return GSK_NGL_UNIFORM_VALUE (state->values_buf, *offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GSK_NGL_UNIFORM_STATE_REPLACE(info, u, type, count) \
|
|
||||||
G_STMT_START { \
|
|
||||||
if ((info)->info.initial && count == (info)->info.array_count) \
|
|
||||||
{ \
|
|
||||||
u = GSK_NGL_UNIFORM_VALUE (state->values_buf, (info)->info.offset); \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
guint offset; \
|
|
||||||
u = gsk_ngl_uniform_state_realloc (state, sizeof(type) * MAX (1, count), &offset); \
|
|
||||||
g_assert (offset < (1 << GSK_NGL_UNIFORM_OFFSET_BITS)); \
|
|
||||||
(info)->info.offset = offset; \
|
|
||||||
/* We might have increased array length */ \
|
|
||||||
(info)->info.array_count = count; \
|
|
||||||
} \
|
|
||||||
} G_STMT_END
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_info_changed (GskNglUniformMapping *info,
|
|
||||||
guint stamp)
|
|
||||||
{
|
|
||||||
info->stamp = stamp;
|
|
||||||
info->info.initial = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set1f (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0)
|
|
||||||
{
|
|
||||||
Uniform1f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != 0);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1)
|
|
||||||
{
|
|
||||||
Uniform2f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1,
|
|
||||||
float value2)
|
|
||||||
{
|
|
||||||
Uniform3f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
u->v2 = value2;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
float value0,
|
|
||||||
float value1,
|
|
||||||
float value2,
|
|
||||||
float value3)
|
|
||||||
{
|
|
||||||
Uniform4f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
u->v2 = value2;
|
|
||||||
u->v3 = value3;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set1ui (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint value0)
|
|
||||||
{
|
|
||||||
Uniform1ui *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set1i (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0)
|
|
||||||
{
|
|
||||||
Uniform1i *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1)
|
|
||||||
{
|
|
||||||
Uniform2i *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1,
|
|
||||||
int value2)
|
|
||||||
{
|
|
||||||
Uniform3i *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3i, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
u->v2 = value2;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
int value0,
|
|
||||||
int value1,
|
|
||||||
int value2,
|
|
||||||
int value3)
|
|
||||||
{
|
|
||||||
Uniform4i *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4i, 1);
|
|
||||||
u->v0 = value0;
|
|
||||||
u->v1 = value1;
|
|
||||||
u->v2 = value2;
|
|
||||||
u->v3 = value3;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const GskRoundedRect *rounded_rect)
|
|
||||||
{
|
|
||||||
GskRoundedRect *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (rounded_rect != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || memcmp (u, rounded_rect, sizeof *u) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
|
|
||||||
memcpy (u, rounded_rect, sizeof *rounded_rect);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const graphene_matrix_t *matrix)
|
|
||||||
{
|
|
||||||
graphene_matrix_t *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (matrix != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
|
|
||||||
memcpy (u, matrix, sizeof *matrix);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_ngl_uniform_state_set_texture:
|
|
||||||
* @state: a `GskNglUniformState`
|
|
||||||
* @program: the program id
|
|
||||||
* @location: the location of the texture
|
|
||||||
* @texture_slot: a texturing slot such as GL_TEXTURE0
|
|
||||||
*
|
|
||||||
* Sets the uniform expecting a texture to @texture_slot. This API
|
|
||||||
* expects a texture slot such as GL_TEXTURE0 to reduce chances of
|
|
||||||
* miss-use by the caller.
|
|
||||||
*
|
|
||||||
* The value stored to the uniform is in the form of 0 for GL_TEXTURE0,
|
|
||||||
* 1 for GL_TEXTURE1, and so on.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set_texture (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint texture_slot)
|
|
||||||
{
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
guint *u;
|
|
||||||
|
|
||||||
g_assert (texture_slot >= GL_TEXTURE0);
|
|
||||||
g_assert (texture_slot < GL_TEXTURE16);
|
|
||||||
|
|
||||||
texture_slot -= GL_TEXTURE0;
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || *u != texture_slot)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
|
|
||||||
*u = texture_slot;
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gsk_ngl_uniform_state_set_color:
|
|
||||||
* @state: a `GskNglUniformState`
|
|
||||||
* @program: a program id > 0
|
|
||||||
* @location: the uniform location
|
|
||||||
* @color: a color to set or %NULL for transparent
|
|
||||||
*
|
|
||||||
* Sets a uniform to the color described by @color. This is a convenience
|
|
||||||
* function to allow callers to avoid having to translate colors to floats
|
|
||||||
* in other portions of the renderer.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set_color (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
const GdkRGBA *color)
|
|
||||||
{
|
|
||||||
static const GdkRGBA transparent = {0};
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
GdkRGBA *u;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_COLOR, 1, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (color == NULL)
|
|
||||||
color = &transparent;
|
|
||||||
|
|
||||||
if (info->info.initial || memcmp (color, u, sizeof *u) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
|
|
||||||
memcpy (u, color, sizeof *color);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set1fv (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *value)
|
|
||||||
{
|
|
||||||
Uniform1f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (count > 0);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
|
|
||||||
memcpy (u, value, sizeof (Uniform1f) * count);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set2fv (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *value)
|
|
||||||
{
|
|
||||||
Uniform2f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (count > 0);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
|
|
||||||
memcpy (u, value, sizeof (Uniform2f) * count);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set3fv (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *value)
|
|
||||||
{
|
|
||||||
Uniform3f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (count > 0);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
|
|
||||||
memcpy (u, value, sizeof (Uniform3f) * count);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_set4fv (GskNglUniformState *state,
|
|
||||||
GskNglUniformProgram *program,
|
|
||||||
guint key,
|
|
||||||
guint stamp,
|
|
||||||
guint count,
|
|
||||||
const float *value)
|
|
||||||
{
|
|
||||||
Uniform4f *u;
|
|
||||||
GskNglUniformMapping *info;
|
|
||||||
|
|
||||||
g_assert (state != NULL);
|
|
||||||
g_assert (program != NULL);
|
|
||||||
g_assert (count > 0);
|
|
||||||
|
|
||||||
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, key, stamp, &info)))
|
|
||||||
{
|
|
||||||
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
|
|
||||||
{
|
|
||||||
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
|
|
||||||
memcpy (u, value, sizeof (Uniform4f) * count);
|
|
||||||
gsk_ngl_uniform_info_changed (info, stamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
gsk_ngl_uniform_state_fmix (guint program,
|
|
||||||
guint location)
|
|
||||||
{
|
|
||||||
guint h = (program << 16) | location;
|
|
||||||
|
|
||||||
h ^= h >> 16;
|
|
||||||
h *= 0x85ebca6b;
|
|
||||||
h ^= h >> 13;
|
|
||||||
h *= 0xc2b2ae35;
|
|
||||||
h ^= h >> 16;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gsk_ngl_uniform_state_apply:
|
|
||||||
* @state: the uniform state
|
|
||||||
* @program: the program id
|
|
||||||
* @location: the location of the uniform
|
|
||||||
* @offset: the offset of the data within the buffer
|
|
||||||
* @info: the uniform info
|
|
||||||
*
|
|
||||||
* This function can be used to apply state that was previously recorded
|
|
||||||
* by the `GskNglUniformState`.
|
|
||||||
*
|
|
||||||
* It is specifically useful from the `GskNglCommandQueue` to execute uniform
|
|
||||||
* changes but only when they have changed from the current value.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
gsk_ngl_uniform_state_apply (GskNglUniformState *state,
|
|
||||||
guint program,
|
|
||||||
guint location,
|
|
||||||
GskNglUniformInfo info)
|
|
||||||
{
|
|
||||||
guint index = gsk_ngl_uniform_state_fmix (program, location) % G_N_ELEMENTS (state->apply_hash);
|
|
||||||
gconstpointer dataptr = GSK_NGL_UNIFORM_VALUE (state->values_buf, info.offset);
|
|
||||||
|
|
||||||
/* aligned, can treat as unsigned */
|
|
||||||
if (*(guint *)&info == *(guint *)&state->apply_hash[index])
|
|
||||||
return;
|
|
||||||
|
|
||||||
state->apply_hash[index] = info;
|
|
||||||
|
|
||||||
/* TODO: We could do additional comparisons here to make sure we are
|
|
||||||
* changing state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (info.format)
|
|
||||||
{
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_1F:
|
|
||||||
glUniform1fv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_2F:
|
|
||||||
glUniform2fv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_3F:
|
|
||||||
glUniform3fv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_4F:
|
|
||||||
glUniform4fv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_1FV:
|
|
||||||
glUniform1fv (location, info.array_count, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_2FV:
|
|
||||||
glUniform2fv (location, info.array_count, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_3FV:
|
|
||||||
glUniform3fv (location, info.array_count, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_4FV:
|
|
||||||
glUniform4fv (location, info.array_count, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_1I:
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_TEXTURE:
|
|
||||||
glUniform1iv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_2I:
|
|
||||||
glUniform2iv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_3I:
|
|
||||||
glUniform3iv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_4I:
|
|
||||||
glUniform4iv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_1UI:
|
|
||||||
glUniform1uiv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_MATRIX: {
|
|
||||||
float mat[16];
|
|
||||||
graphene_matrix_to_float (dataptr, mat);
|
|
||||||
glUniformMatrix4fv (location, 1, GL_FALSE, mat);
|
|
||||||
#if 0
|
|
||||||
/* TODO: If Graphene can give us a peek here on platforms
|
|
||||||
* where the format is float[16] (most/all x86_64?) then
|
|
||||||
* We can avoid the SIMD operation to convert the format.
|
|
||||||
*/
|
|
||||||
G_STATIC_ASSERT (sizeof (graphene_matrix_t) == 16*4);
|
|
||||||
glUniformMatrix4fv (location, 1, GL_FALSE, dataptr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_COLOR:
|
|
||||||
glUniform4fv (location, 1, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT:
|
|
||||||
glUniform4fv (location, 3, dataptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* GSK_NGL_UNIFORM_STATE_PRIVATE_H */
|
|
@ -79,6 +79,8 @@ for f in funcs:
|
|||||||
file_output += ['#ifdef GDK_RENDERING_VULKAN']
|
file_output += ['#ifdef GDK_RENDERING_VULKAN']
|
||||||
file_output += ['*tp++ = {0}();'.format(f)]
|
file_output += ['*tp++ = {0}();'.format(f)]
|
||||||
file_output += ['#endif']
|
file_output += ['#endif']
|
||||||
|
elif f.startswith('gsk_ngl'):
|
||||||
|
file_output += ['']
|
||||||
else:
|
else:
|
||||||
file_output += ['*tp++ = {0}();'.format(f)]
|
file_output += ['*tp++ = {0}();'.format(f)]
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#define GTK_COMPILATION
|
#define GTK_COMPILATION
|
||||||
|
|
||||||
#include <gsk/ngl/gsknglrenderer.h>
|
#include <gsk/gl/gskglrenderer.h>
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_BROADWAY
|
#ifdef GDK_WINDOWING_BROADWAY
|
||||||
#include <gsk/broadway/gskbroadwayrenderer.h>
|
#include <gsk/broadway/gskbroadwayrenderer.h>
|
||||||
|
@ -158,8 +158,6 @@ init_version (GtkInspectorGeneral *gen)
|
|||||||
renderer = "Vulkan";
|
renderer = "Vulkan";
|
||||||
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskGLRenderer") == 0)
|
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskGLRenderer") == 0)
|
||||||
renderer = "GL";
|
renderer = "GL";
|
||||||
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskNglRenderer") == 0)
|
|
||||||
renderer = "NGL";
|
|
||||||
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskCairoRenderer") == 0)
|
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskCairoRenderer") == 0)
|
||||||
renderer = "Cairo";
|
renderer = "Cairo";
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "gsk/ngl/gsknglrenderer.h"
|
#include "gsk/gl/gskglrenderer.h"
|
||||||
|
|
||||||
#define N 20
|
#define N 20
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ main (int argc, char *argv[])
|
|||||||
add_test ("/memorytexture/download_float_4x4", test_download_float_4x4);
|
add_test ("/memorytexture/download_float_4x4", test_download_float_4x4);
|
||||||
|
|
||||||
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||||
gl_renderer = gsk_ngl_renderer_new ();
|
gl_renderer = gsk_gl_renderer_new ();
|
||||||
if (!gsk_renderer_realize (gl_renderer, surface, NULL))
|
if (!gsk_renderer_realize (gl_renderer, surface, NULL))
|
||||||
{
|
{
|
||||||
g_clear_object (&gl_renderer);
|
g_clear_object (&gl_renderer);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "gsk/ngl/gsknglrenderer.h"
|
#include "gsk/gl/gskglrenderer.h"
|
||||||
|
|
||||||
/* This function will be called from a thread and/or the main loop.
|
/* This function will be called from a thread and/or the main loop.
|
||||||
* Textures are threadsafe after all. */
|
* Textures are threadsafe after all. */
|
||||||
@ -73,7 +73,7 @@ texture_threads (void)
|
|||||||
|
|
||||||
/* 1. Get a GL renderer */
|
/* 1. Get a GL renderer */
|
||||||
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||||
gl_renderer = gsk_ngl_renderer_new ();
|
gl_renderer = gsk_gl_renderer_new ();
|
||||||
g_assert_true (gsk_renderer_realize (gl_renderer, surface, NULL));
|
g_assert_true (gsk_renderer_realize (gl_renderer, surface, NULL));
|
||||||
|
|
||||||
/* 2. Get a GL texture */
|
/* 2. Get a GL texture */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "gsk/ngl/fp16private.h"
|
#include "gsk/gl/fp16private.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_constants (void)
|
test_constants (void)
|
||||||
|
@ -94,7 +94,7 @@ informative_render_tests = [
|
|||||||
|
|
||||||
renderers = [
|
renderers = [
|
||||||
# name exclude term
|
# name exclude term
|
||||||
[ 'ngl', '' ],
|
[ 'gl', '' ],
|
||||||
[ 'broadway', '-3d' ],
|
[ 'broadway', '-3d' ],
|
||||||
[ 'cairo', '-3d' ],
|
[ 'cairo', '-3d' ],
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user