From d136c6510bcc6db1c76ac9843d0fa22b016b9806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 19 Oct 2020 17:53:56 +0200 Subject: [PATCH] cogl: Init framebuffer driver up front The framebuffer driver was lazilly initialized on demand in some cases (onscreen), and up front other (offscreen). Replace this with a more predictable up front initialization, done at framebuffer allocation. Part-of: --- cogl/cogl/cogl-driver.h | 12 +- cogl/cogl/cogl-framebuffer-private.h | 15 +- cogl/cogl/cogl-framebuffer.c | 75 ++++++---- cogl/cogl/cogl-framebuffer.h | 2 + cogl/cogl/cogl-offscreen.c | 29 ++-- .../driver/gl/cogl-framebuffer-gl-private.h | 3 - cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 141 +++++++++--------- cogl/cogl/driver/gl/cogl-util-gl-private.h | 6 + cogl/cogl/driver/gl/cogl-util-gl.c | 3 +- cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 3 +- cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 3 +- cogl/cogl/driver/nop/cogl-driver-nop.c | 15 +- .../driver/nop/cogl-framebuffer-nop-private.h | 8 - cogl/cogl/driver/nop/cogl-framebuffer-nop.c | 13 -- cogl/cogl/driver/nop/cogl-nop-framebuffer.c | 46 ++++++ cogl/cogl/driver/nop/cogl-nop-framebuffer.h | 36 +++++ cogl/cogl/meson.build | 2 + 17 files changed, 250 insertions(+), 162 deletions(-) create mode 100644 cogl/cogl/driver/nop/cogl-nop-framebuffer.c create mode 100644 cogl/cogl/driver/nop/cogl-nop-framebuffer.h diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index 5e07eb5b8..e2cf98927 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -73,13 +73,11 @@ struct _CoglDriverVtable (* update_features) (CoglContext *context, GError **error); - gboolean - (* offscreen_allocate) (CoglOffscreen *offscreen, - CoglOffscreenFlags flags, - GError **error); - - void - (* offscreen_free) (CoglOffscreen *offscreen); + CoglFramebufferDriver * + (* create_framebuffer_driver) (CoglContext *context, + CoglFramebuffer *framebuffer, + const CoglFramebufferDriverConfig *driver_config, + GError **error); void (* flush_framebuffer_state) (CoglContext *context, diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h index 1d8f471d3..f00a5bc4b 100644 --- a/cogl/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl/cogl-framebuffer-private.h @@ -32,6 +32,7 @@ #ifndef __COGL_FRAMEBUFFER_PRIVATE_H #define __COGL_FRAMEBUFFER_PRIVATE_H +#include "cogl-framebuffer-driver.h" #include "cogl-object-private.h" #include "cogl-matrix-stack-private.h" #include "cogl-journal-private.h" @@ -39,6 +40,11 @@ #include "cogl-attribute-private.h" #include "cogl-clip-stack.h" +struct _CoglFramebufferDriverConfig +{ + gboolean disable_depth_and_stencil; +}; + typedef struct { CoglSwapChain *swap_chain; @@ -293,12 +299,7 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer); CoglJournal * cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer); -gpointer -cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer); - -void -cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer, - gpointer driver_private, - GDestroyNotify desrtoy_notify); +CoglFramebufferDriver * +cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer); #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index cf7355103..b83c3c19a 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -58,6 +58,7 @@ enum PROP_0, PROP_CONTEXT, + PROP_DRIVER_CONFIG, PROP_WIDTH, PROP_HEIGHT, @@ -86,6 +87,9 @@ typedef struct _CoglFramebufferPrivate /* The user configuration before allocation... */ CoglFramebufferConfig config; + CoglFramebufferDriverConfig driver_config; + CoglFramebufferDriver *driver; + int width; int height; /* Format of the pixels in the framebuffer (including the expected @@ -139,9 +143,6 @@ typedef struct _CoglFramebufferPrivate * usually means it needs to be cleared before being reused next. */ gboolean depth_buffer_clear_needed; - - gpointer driver_private; - GDestroyNotify driver_private_destroy; } CoglFramebufferPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer, @@ -174,6 +175,9 @@ cogl_framebuffer_get_property (GObject *object, case PROP_CONTEXT: g_value_set_boxed (value, priv->context); break; + case PROP_DRIVER_CONFIG: + g_value_set_pointer (value, &priv->driver_config); + break; case PROP_WIDTH: g_value_set_int (value, priv->width); break; @@ -194,12 +198,18 @@ cogl_framebuffer_set_property (GObject *object, CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); CoglFramebufferPrivate *priv = cogl_framebuffer_get_instance_private (framebuffer); + CoglFramebufferDriverConfig *driver_config; switch (prop_id) { case PROP_CONTEXT: priv->context = g_value_get_boxed (value); break; + case PROP_DRIVER_CONFIG: + driver_config = g_value_get_pointer (value); + if (driver_config) + priv->driver_config = *driver_config; + break; case PROP_WIDTH: priv->width = g_value_get_int (value); break; @@ -343,10 +353,7 @@ cogl_framebuffer_dispose (GObject *object) if (ctx->current_read_buffer == framebuffer) ctx->current_read_buffer = NULL; - if (priv->driver_private_destroy) - priv->driver_private_destroy (priv->driver_private); - priv->driver_private = NULL; - priv->driver_private_destroy = NULL; + g_clear_object (&priv->driver); } static void @@ -377,6 +384,13 @@ cogl_framebuffer_class_init (CoglFramebufferClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_props[PROP_DRIVER_CONFIG] = + g_param_spec_pointer ("driver-config", + "driver-config", + "CoglFramebufferDriverConfig", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_props[PROP_WIDTH] = g_param_spec_int ("width", "width", @@ -901,17 +915,42 @@ cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer) return priv->allocated; } +static gboolean +cogl_framebuffer_init_driver (CoglFramebuffer *framebuffer, + GError **error) + +{ + CoglFramebufferPrivate *priv = + cogl_framebuffer_get_instance_private (framebuffer); + const CoglDriverVtable *driver_vtable = priv->context->driver_vtable; + CoglFramebufferDriver *driver; + + driver = driver_vtable->create_framebuffer_driver (priv->context, + framebuffer, + &priv->driver_config, + error); + if (!driver) + return FALSE; + + priv->driver = driver; + return TRUE; +} + gboolean cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, GError **error) { CoglFramebufferPrivate *priv = cogl_framebuffer_get_instance_private (framebuffer); + CoglFramebufferClass *klass = COGL_FRAMEBUFFER_GET_CLASS (framebuffer); if (priv->allocated) return TRUE; - if (!COGL_FRAMEBUFFER_GET_CLASS (framebuffer)->allocate (framebuffer, error)) + if (!klass->allocate (framebuffer, error)) + return FALSE; + + if (!cogl_framebuffer_init_driver (framebuffer, error)) return FALSE; priv->allocated = TRUE; @@ -2652,25 +2691,11 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, n_rectangles); } -gpointer -cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer) +CoglFramebufferDriver * +cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer) { CoglFramebufferPrivate *priv = cogl_framebuffer_get_instance_private (framebuffer); - return priv->driver_private; -} - -void -cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer, - gpointer driver_private, - GDestroyNotify destroy_notify) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_warn_if_fail (!priv->driver_private); - - priv->driver_private = driver_private; - priv->driver_private_destroy = destroy_notify; + return priv->driver; } diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h index fab99ef2c..993de7a25 100644 --- a/cogl/cogl/cogl-framebuffer.h +++ b/cogl/cogl/cogl-framebuffer.h @@ -85,6 +85,8 @@ G_BEGIN_DECLS * configuration. */ +typedef struct _CoglFramebufferDriverConfig CoglFramebufferDriverConfig; + #define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ()) COGL_EXPORT G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer, diff --git a/cogl/cogl/cogl-offscreen.c b/cogl/cogl/cogl-offscreen.c index bc4ecf0df..ae05f7343 100644 --- a/cogl/cogl/cogl-offscreen.c +++ b/cogl/cogl/cogl-offscreen.c @@ -38,33 +38,33 @@ struct _CoglOffscreen CoglTexture *texture; int texture_level; - - /* FIXME: _cogl_offscreen_new_with_texture_full should be made to use - * fb->config to configure if we want a depth or stencil buffer so - * we can get rid of these flags */ - CoglOffscreenFlags create_flags; }; G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen, COGL_TYPE_FRAMEBUFFER) CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags create_flags, - int level) +_cogl_offscreen_new_with_texture_full (CoglTexture *texture, + CoglOffscreenFlags flags, + int level) { CoglContext *ctx = texture->context; + CoglFramebufferDriverConfig driver_config; CoglOffscreen *offscreen; CoglFramebuffer *fb; g_return_val_if_fail (cogl_is_texture (texture), NULL); + driver_config = (CoglFramebufferDriverConfig) { + .disable_depth_and_stencil = + !!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL), + }; offscreen = g_object_new (COGL_TYPE_OFFSCREEN, "context", ctx, + "driver-config", &driver_config, NULL); offscreen->texture = cogl_object_ref (texture); offscreen->texture_level = level; - offscreen->create_flags = create_flags; fb = COGL_FRAMEBUFFER (offscreen); @@ -101,7 +101,6 @@ cogl_offscreen_allocate (CoglFramebuffer *framebuffer, GError **error) { CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); CoglPixelFormat texture_format; int width, height; @@ -125,11 +124,6 @@ cogl_offscreen_allocate (CoglFramebuffer *framebuffer, texture_format = _cogl_texture_get_format (offscreen->texture); _cogl_framebuffer_set_internal_format (framebuffer, texture_format); - if (!ctx->driver_vtable->offscreen_allocate (offscreen, - offscreen->create_flags, - error)) - return FALSE; - return TRUE; } @@ -143,11 +137,6 @@ static void cogl_offscreen_dispose (GObject *object) { CoglOffscreen *offscreen = COGL_OFFSCREEN (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - if (offscreen->texture) - ctx->driver_vtable->offscreen_free (offscreen); G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object); diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h index 6fe059d30..2f96f6f8f 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h @@ -41,9 +41,6 @@ G_DECLARE_FINAL_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer, COGL, GL_FRAMEBUFFER, CoglFramebufferDriver) -CoglGlFramebuffer * -cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer); - gboolean _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, CoglOffscreenFlags flags, diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c index 4ac0ae7c4..95e4a39b6 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c @@ -151,9 +151,6 @@ struct _CoglGlFramebuffer G_DEFINE_TYPE_WITH_PRIVATE (CoglGlFramebuffer, cogl_gl_framebuffer, COGL_TYPE_FRAMEBUFFER_DRIVER) -static CoglGlFramebuffer * -ensure_gl_framebuffer (CoglFramebuffer *framebuffer); - static void _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer) { @@ -355,6 +352,16 @@ cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer, COGL_FLAGS_FOREACH_END; } +static CoglGlFramebuffer * +cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer) +{ + CoglFramebufferDriver *driver = cogl_framebuffer_get_driver (framebuffer); + + g_assert (driver); + + return COGL_GL_FRAMEBUFFER (driver); +} + void _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target) { @@ -362,11 +369,11 @@ _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target) if (COGL_IS_OFFSCREEN (framebuffer)) { - CoglGlFramebuffer *gl_framebuffer; - CoglGlFramebufferPrivate *priv; + CoglGlFramebuffer *gl_framebuffer = + cogl_gl_framebuffer_from_framebuffer (framebuffer); + CoglGlFramebufferPrivate *priv = + cogl_gl_framebuffer_get_instance_private (gl_framebuffer); - gl_framebuffer = ensure_gl_framebuffer (framebuffer); - priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer); GE (ctx, glBindFramebuffer (target, priv->gl_fbo.fbo_handle)); } else @@ -633,14 +640,14 @@ try_creating_fbo (CoglContext *ctx, return TRUE; } -gboolean -_cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, - CoglOffscreenFlags flags, - GError **error) +CoglFramebufferDriver * +_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, + CoglFramebuffer *framebuffer, + const CoglFramebufferDriverConfig *driver_config, + GError **error) { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); CoglOffscreenAllocateFlags allocate_flags; + CoglOffscreen *offscreen; CoglGlFramebuffer *gl_framebuffer; CoglGlFramebufferPrivate *priv; CoglGlFbo *gl_fbo; @@ -650,6 +657,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, int level_width; int level_height; + if (COGL_IS_ONSCREEN (framebuffer)) + { + return g_object_new (COGL_TYPE_GL_FRAMEBUFFER, + "framebuffer", framebuffer, + NULL); + } + + offscreen = COGL_OFFSCREEN (framebuffer); texture = cogl_offscreen_get_texture (offscreen); texture_level = cogl_offscreen_get_texture_level (offscreen); @@ -677,12 +692,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, config = cogl_framebuffer_get_config (framebuffer); - gl_framebuffer = ensure_gl_framebuffer (framebuffer); + gl_framebuffer = g_object_new (COGL_TYPE_GL_FRAMEBUFFER, + "framebuffer", framebuffer, + NULL); priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer); gl_fbo = &priv->gl_fbo; - if (((flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL) && - try_creating_fbo (ctx, + if ((driver_config->disable_depth_and_stencil && + try_creating_fbo (context, texture, texture_level, level_width, @@ -691,24 +708,24 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, allocate_flags = 0, gl_fbo)) || - (ctx->have_last_offscreen_allocate_flags && - try_creating_fbo (ctx, + (context->have_last_offscreen_allocate_flags && + try_creating_fbo (context, texture, texture_level, level_width, level_height, config, - allocate_flags = ctx->last_offscreen_allocate_flags, + allocate_flags = context->last_offscreen_allocate_flags, gl_fbo)) || ( /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't * need an extension to handle _FLAG_DEPTH_STENCIL */ (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || + (context, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || _cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && - try_creating_fbo (ctx, + (context, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && + try_creating_fbo (context, texture, texture_level, level_width, @@ -717,7 +734,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL, gl_fbo)) || - try_creating_fbo (ctx, + try_creating_fbo (context, texture, texture_level, level_width, @@ -727,7 +744,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, gl_fbo) || - try_creating_fbo (ctx, + try_creating_fbo (context, texture, texture_level, level_width, @@ -736,7 +753,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, gl_fbo) || - try_creating_fbo (ctx, + try_creating_fbo (context, texture, texture_level, level_width, @@ -745,7 +762,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH, gl_fbo) || - try_creating_fbo (ctx, + try_creating_fbo (context, texture, texture_level, level_width, @@ -757,35 +774,38 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, cogl_framebuffer_update_samples_per_pixel (framebuffer, gl_fbo->samples_per_pixel); - if (!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL)) + if (!driver_config->disable_depth_and_stencil) { /* Record that the last set of flags succeeded so that we can try that set first next time */ - ctx->last_offscreen_allocate_flags = allocate_flags; - ctx->have_last_offscreen_allocate_flags = TRUE; + context->last_offscreen_allocate_flags = allocate_flags; + context->have_last_offscreen_allocate_flags = TRUE; } - return TRUE; + return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); } else { + g_object_unref (gl_framebuffer); g_set_error (error, COGL_FRAMEBUFFER_ERROR, COGL_FRAMEBUFFER_ERROR_ALLOCATE, "Failed to create an OpenGL framebuffer object"); - return FALSE; + return NULL; } } -void -_cogl_offscreen_gl_free (CoglOffscreen *offscreen) +static void +cogl_gl_framebuffer_dispose (GObject *object) { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); + CoglGlFramebuffer *gl_framebuffer = COGL_GL_FRAMEBUFFER (object); + CoglGlFramebufferPrivate *priv = + cogl_gl_framebuffer_get_instance_private (gl_framebuffer); + CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object); + CoglFramebuffer *framebuffer = + cogl_framebuffer_driver_get_framebuffer (driver); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGlFramebuffer *gl_framebuffer; - CoglGlFramebufferPrivate *priv; - gl_framebuffer = ensure_gl_framebuffer (framebuffer); - priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer); + G_OBJECT_CLASS (cogl_gl_framebuffer_parent_class)->dispose (object); delete_renderbuffers (ctx, priv->gl_fbo.renderbuffers); @@ -837,40 +857,14 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer, GE (ctx, glClear (gl_buffers)); } -CoglGlFramebuffer * -cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer) -{ - return ensure_gl_framebuffer (framebuffer); -} - -static CoglGlFramebuffer * -ensure_gl_framebuffer (CoglFramebuffer *framebuffer) -{ - CoglGlFramebuffer *gl_framebuffer; - - gl_framebuffer = cogl_framebuffer_get_driver_private (framebuffer); - if (!gl_framebuffer) - { - gl_framebuffer = g_object_new (COGL_TYPE_GL_FRAMEBUFFER, - "framebuffer", framebuffer, - NULL); - cogl_framebuffer_set_driver_private (framebuffer, - gl_framebuffer, - g_object_unref); - } - - return gl_framebuffer; -} - static inline void _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer) { + CoglGlFramebuffer *gl_framebuffer = + cogl_gl_framebuffer_from_framebuffer (framebuffer); + CoglGlFramebufferPrivate *priv = + cogl_gl_framebuffer_get_instance_private (gl_framebuffer); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGlFramebuffer *gl_framebuffer; - CoglGlFramebufferPrivate *priv; - - gl_framebuffer = ensure_gl_framebuffer (framebuffer); - priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer); if (!priv->dirty_bitmasks) return; @@ -963,15 +957,15 @@ void _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, CoglFramebufferBits *bits) { - CoglGlFramebuffer *gl_framebuffer; - CoglGlFramebufferPrivate *priv; + CoglGlFramebuffer *gl_framebuffer = + cogl_gl_framebuffer_from_framebuffer (framebuffer); + CoglGlFramebufferPrivate *priv = + cogl_gl_framebuffer_get_instance_private (gl_framebuffer); _cogl_framebuffer_init_bits (framebuffer); /* TODO: cache these in some driver specific location not * directly as part of CoglFramebuffer. */ - gl_framebuffer = ensure_gl_framebuffer (framebuffer); - priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer); *bits = priv->bits; } @@ -1380,4 +1374,7 @@ cogl_gl_framebuffer_init (CoglGlFramebuffer *gl_framebuffer) static void cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = cogl_gl_framebuffer_dispose; } diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index f72c74194..6bada2cd0 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -100,6 +100,12 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext *context, CoglFramebuffer *read_buffer, CoglFramebufferState state); +CoglFramebufferDriver * +_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, + CoglFramebuffer *framebuffer, + const CoglFramebufferDriverConfig *driver_config, + GError **error); + GLenum _cogl_gl_util_get_error (CoglContext *ctx); diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index 1ca513e8d..2c1c4e544 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -214,7 +214,8 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext *ctx, differences &= ~COGL_FRAMEBUFFER_STATE_BIND; } - draw_gl_framebuffer = cogl_gl_framebuffer_from_framebuffer (draw_buffer); + draw_gl_framebuffer = + COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (draw_buffer)); cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer, differences); diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 77c7bbcf8..31f6c898f 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -569,8 +569,7 @@ _cogl_driver_gl = _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, - _cogl_offscreen_gl_allocate, - _cogl_offscreen_gl_free, + _cogl_driver_gl_create_framebuffer_driver, _cogl_driver_gl_flush_framebuffer_state, _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 3c652486e..506d5250b 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -457,8 +457,7 @@ _cogl_driver_gles = _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, - _cogl_offscreen_gl_allocate, - _cogl_offscreen_gl_free, + _cogl_driver_gl_create_framebuffer_driver, _cogl_driver_gl_flush_framebuffer_state, _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 8c6aab47c..7dfc1c5bc 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -40,6 +40,7 @@ #include "cogl-texture-2d-nop-private.h" #include "cogl-attribute-nop-private.h" #include "cogl-clip-stack-nop-private.h" +#include "driver/nop/cogl-nop-framebuffer.h" static gboolean _cogl_driver_update_features (CoglContext *ctx, @@ -67,6 +68,17 @@ _cogl_driver_nop_is_hardware_accelerated (CoglContext *context) return FALSE; } +static CoglFramebufferDriver * +_cogl_driver_nop_create_framebuffer_driver (CoglContext *context, + CoglFramebuffer *framebuffer, + const CoglFramebufferDriverConfig *driver_config, + GError **error) +{ + return g_object_new (COGL_TYPE_NOP_FRAMEBUFFER, + "framebuffer", framebuffer, + NULL); +} + static void _cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx, CoglFramebuffer *draw_buffer, @@ -85,8 +97,7 @@ _cogl_driver_nop = NULL, /* pixel_format_from_gl_internal */ NULL, /* pixel_format_to_gl */ _cogl_driver_update_features, - _cogl_offscreen_nop_allocate, - _cogl_offscreen_nop_free, + _cogl_driver_nop_create_framebuffer_driver, _cogl_driver_nop_flush_framebuffer_state, _cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_query_bits, diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h index 788bde6cc..19013c752 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h @@ -37,14 +37,6 @@ #include "cogl-types.h" #include "cogl-context-private.h" -gboolean -_cogl_offscreen_nop_allocate (CoglOffscreen *offscreen, - CoglOffscreenFlags flags, - GError **error); - -void -_cogl_offscreen_nop_free (CoglOffscreen *offscreen); - void _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer, unsigned long buffers, diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c index 6dc5e7e91..d7fc293f2 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c @@ -35,19 +35,6 @@ #include #include -gboolean -_cogl_offscreen_nop_allocate (CoglOffscreen *offscreen, - CoglOffscreenFlags flags, - GError **error) -{ - return TRUE; -} - -void -_cogl_offscreen_nop_free (CoglOffscreen *offscreen) -{ -} - void _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer, unsigned long buffers, diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.c b/cogl/cogl/driver/nop/cogl-nop-framebuffer.c new file mode 100644 index 000000000..85bed95a7 --- /dev/null +++ b/cogl/cogl/driver/nop/cogl-nop-framebuffer.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 Red Hat + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include "cogl-config.h" + +#include "cogl-nop-framebuffer.h" + +struct _CoglNopFramebuffer +{ + CoglFramebufferDriver parent; +}; + +G_DEFINE_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, + COGL_TYPE_FRAMEBUFFER_DRIVER) + +static void +cogl_nop_framebuffer_init (CoglNopFramebuffer *nop_framebuffer) +{ +} + +static void +cogl_nop_framebuffer_class_init (CoglNopFramebufferClass *klass) +{ +} diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.h b/cogl/cogl/driver/nop/cogl-nop-framebuffer.h new file mode 100644 index 000000000..7c9f729a6 --- /dev/null +++ b/cogl/cogl/driver/nop/cogl-nop-framebuffer.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 Red Hat + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef COGL_NOP_FRAMEBUFFER_H +#define COGL_NOP_FRAMEBUFFER_H + +#include "cogl-framebuffer-driver.h" + +#define COGL_TYPE_NOP_FRAMEBUFFER (cogl_nop_framebuffer_get_type ()) +G_DECLARE_FINAL_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, + COGL, NOP_FRAMEBUFFER_DRIVER, + CoglFramebufferDriver) + +#endif /* COGL_NOP_FRAMEBUFFER_H */ diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index 5a361b42d..638f5a827 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -132,6 +132,8 @@ cogl_noop_driver_sources = [ 'driver/nop/cogl-driver-nop.c', 'driver/nop/cogl-framebuffer-nop-private.h', 'driver/nop/cogl-framebuffer-nop.c', + 'driver/nop/cogl-nop-framebuffer.c', + 'driver/nop/cogl-nop-framebuffer.h', 'driver/nop/cogl-attribute-nop-private.h', 'driver/nop/cogl-attribute-nop.c', 'driver/nop/cogl-clip-stack-nop-private.h',