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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
This commit is contained in:
Jonas Ådahl 2020-10-19 17:53:56 +02:00 committed by Robert Mader
parent 58eb1e87bf
commit d136c6510b
17 changed files with 250 additions and 162 deletions

View File

@ -73,14 +73,12 @@ struct _CoglDriverVtable
(* update_features) (CoglContext *context, (* update_features) (CoglContext *context,
GError **error); GError **error);
gboolean CoglFramebufferDriver *
(* offscreen_allocate) (CoglOffscreen *offscreen, (* create_framebuffer_driver) (CoglContext *context,
CoglOffscreenFlags flags, CoglFramebuffer *framebuffer,
const CoglFramebufferDriverConfig *driver_config,
GError **error); GError **error);
void
(* offscreen_free) (CoglOffscreen *offscreen);
void void
(* flush_framebuffer_state) (CoglContext *context, (* flush_framebuffer_state) (CoglContext *context,
CoglFramebuffer *draw_buffer, CoglFramebuffer *draw_buffer,

View File

@ -32,6 +32,7 @@
#ifndef __COGL_FRAMEBUFFER_PRIVATE_H #ifndef __COGL_FRAMEBUFFER_PRIVATE_H
#define __COGL_FRAMEBUFFER_PRIVATE_H #define __COGL_FRAMEBUFFER_PRIVATE_H
#include "cogl-framebuffer-driver.h"
#include "cogl-object-private.h" #include "cogl-object-private.h"
#include "cogl-matrix-stack-private.h" #include "cogl-matrix-stack-private.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
@ -39,6 +40,11 @@
#include "cogl-attribute-private.h" #include "cogl-attribute-private.h"
#include "cogl-clip-stack.h" #include "cogl-clip-stack.h"
struct _CoglFramebufferDriverConfig
{
gboolean disable_depth_and_stencil;
};
typedef struct typedef struct
{ {
CoglSwapChain *swap_chain; CoglSwapChain *swap_chain;
@ -293,12 +299,7 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
CoglJournal * CoglJournal *
cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer); cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer);
gpointer CoglFramebufferDriver *
cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer); cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer);
void
cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer,
gpointer driver_private,
GDestroyNotify desrtoy_notify);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View File

@ -58,6 +58,7 @@ enum
PROP_0, PROP_0,
PROP_CONTEXT, PROP_CONTEXT,
PROP_DRIVER_CONFIG,
PROP_WIDTH, PROP_WIDTH,
PROP_HEIGHT, PROP_HEIGHT,
@ -86,6 +87,9 @@ typedef struct _CoglFramebufferPrivate
/* The user configuration before allocation... */ /* The user configuration before allocation... */
CoglFramebufferConfig config; CoglFramebufferConfig config;
CoglFramebufferDriverConfig driver_config;
CoglFramebufferDriver *driver;
int width; int width;
int height; int height;
/* Format of the pixels in the framebuffer (including the expected /* 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. * usually means it needs to be cleared before being reused next.
*/ */
gboolean depth_buffer_clear_needed; gboolean depth_buffer_clear_needed;
gpointer driver_private;
GDestroyNotify driver_private_destroy;
} CoglFramebufferPrivate; } CoglFramebufferPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer, G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer,
@ -174,6 +175,9 @@ cogl_framebuffer_get_property (GObject *object,
case PROP_CONTEXT: case PROP_CONTEXT:
g_value_set_boxed (value, priv->context); g_value_set_boxed (value, priv->context);
break; break;
case PROP_DRIVER_CONFIG:
g_value_set_pointer (value, &priv->driver_config);
break;
case PROP_WIDTH: case PROP_WIDTH:
g_value_set_int (value, priv->width); g_value_set_int (value, priv->width);
break; break;
@ -194,12 +198,18 @@ cogl_framebuffer_set_property (GObject *object,
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
CoglFramebufferPrivate *priv = CoglFramebufferPrivate *priv =
cogl_framebuffer_get_instance_private (framebuffer); cogl_framebuffer_get_instance_private (framebuffer);
CoglFramebufferDriverConfig *driver_config;
switch (prop_id) switch (prop_id)
{ {
case PROP_CONTEXT: case PROP_CONTEXT:
priv->context = g_value_get_boxed (value); priv->context = g_value_get_boxed (value);
break; break;
case PROP_DRIVER_CONFIG:
driver_config = g_value_get_pointer (value);
if (driver_config)
priv->driver_config = *driver_config;
break;
case PROP_WIDTH: case PROP_WIDTH:
priv->width = g_value_get_int (value); priv->width = g_value_get_int (value);
break; break;
@ -343,10 +353,7 @@ cogl_framebuffer_dispose (GObject *object)
if (ctx->current_read_buffer == framebuffer) if (ctx->current_read_buffer == framebuffer)
ctx->current_read_buffer = NULL; ctx->current_read_buffer = NULL;
if (priv->driver_private_destroy) g_clear_object (&priv->driver);
priv->driver_private_destroy (priv->driver_private);
priv->driver_private = NULL;
priv->driver_private_destroy = NULL;
} }
static void static void
@ -377,6 +384,13 @@ cogl_framebuffer_class_init (CoglFramebufferClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS); 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] = obj_props[PROP_WIDTH] =
g_param_spec_int ("width", g_param_spec_int ("width",
"width", "width",
@ -901,17 +915,42 @@ cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer)
return priv->allocated; 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 gboolean
cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
GError **error) GError **error)
{ {
CoglFramebufferPrivate *priv = CoglFramebufferPrivate *priv =
cogl_framebuffer_get_instance_private (framebuffer); cogl_framebuffer_get_instance_private (framebuffer);
CoglFramebufferClass *klass = COGL_FRAMEBUFFER_GET_CLASS (framebuffer);
if (priv->allocated) if (priv->allocated)
return TRUE; 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; return FALSE;
priv->allocated = TRUE; priv->allocated = TRUE;
@ -2652,25 +2691,11 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer,
n_rectangles); n_rectangles);
} }
gpointer CoglFramebufferDriver *
cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer) cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer)
{ {
CoglFramebufferPrivate *priv = CoglFramebufferPrivate *priv =
cogl_framebuffer_get_instance_private (framebuffer); cogl_framebuffer_get_instance_private (framebuffer);
return priv->driver_private; return priv->driver;
}
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;
} }

View File

@ -85,6 +85,8 @@ G_BEGIN_DECLS
* configuration. * configuration.
*/ */
typedef struct _CoglFramebufferDriverConfig CoglFramebufferDriverConfig;
#define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ()) #define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ())
COGL_EXPORT COGL_EXPORT
G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer, G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer,

View File

@ -38,11 +38,6 @@ struct _CoglOffscreen
CoglTexture *texture; CoglTexture *texture;
int texture_level; 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, G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen,
@ -50,21 +45,26 @@ G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen,
CoglOffscreen * CoglOffscreen *
_cogl_offscreen_new_with_texture_full (CoglTexture *texture, _cogl_offscreen_new_with_texture_full (CoglTexture *texture,
CoglOffscreenFlags create_flags, CoglOffscreenFlags flags,
int level) int level)
{ {
CoglContext *ctx = texture->context; CoglContext *ctx = texture->context;
CoglFramebufferDriverConfig driver_config;
CoglOffscreen *offscreen; CoglOffscreen *offscreen;
CoglFramebuffer *fb; CoglFramebuffer *fb;
g_return_val_if_fail (cogl_is_texture (texture), NULL); 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, offscreen = g_object_new (COGL_TYPE_OFFSCREEN,
"context", ctx, "context", ctx,
"driver-config", &driver_config,
NULL); NULL);
offscreen->texture = cogl_object_ref (texture); offscreen->texture = cogl_object_ref (texture);
offscreen->texture_level = level; offscreen->texture_level = level;
offscreen->create_flags = create_flags;
fb = COGL_FRAMEBUFFER (offscreen); fb = COGL_FRAMEBUFFER (offscreen);
@ -101,7 +101,6 @@ cogl_offscreen_allocate (CoglFramebuffer *framebuffer,
GError **error) GError **error)
{ {
CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
CoglPixelFormat texture_format; CoglPixelFormat texture_format;
int width, height; int width, height;
@ -125,11 +124,6 @@ cogl_offscreen_allocate (CoglFramebuffer *framebuffer,
texture_format = _cogl_texture_get_format (offscreen->texture); texture_format = _cogl_texture_get_format (offscreen->texture);
_cogl_framebuffer_set_internal_format (framebuffer, texture_format); _cogl_framebuffer_set_internal_format (framebuffer, texture_format);
if (!ctx->driver_vtable->offscreen_allocate (offscreen,
offscreen->create_flags,
error))
return FALSE;
return TRUE; return TRUE;
} }
@ -143,11 +137,6 @@ static void
cogl_offscreen_dispose (GObject *object) cogl_offscreen_dispose (GObject *object)
{ {
CoglOffscreen *offscreen = COGL_OFFSCREEN (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); G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object);

View File

@ -41,9 +41,6 @@ G_DECLARE_FINAL_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer,
COGL, GL_FRAMEBUFFER, COGL, GL_FRAMEBUFFER,
CoglFramebufferDriver) CoglFramebufferDriver)
CoglGlFramebuffer *
cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer);
gboolean gboolean
_cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
CoglOffscreenFlags flags, CoglOffscreenFlags flags,

View File

@ -151,9 +151,6 @@ struct _CoglGlFramebuffer
G_DEFINE_TYPE_WITH_PRIVATE (CoglGlFramebuffer, cogl_gl_framebuffer, G_DEFINE_TYPE_WITH_PRIVATE (CoglGlFramebuffer, cogl_gl_framebuffer,
COGL_TYPE_FRAMEBUFFER_DRIVER) COGL_TYPE_FRAMEBUFFER_DRIVER)
static CoglGlFramebuffer *
ensure_gl_framebuffer (CoglFramebuffer *framebuffer);
static void static void
_cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer) _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; 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 void
_cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target) _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)) if (COGL_IS_OFFSCREEN (framebuffer))
{ {
CoglGlFramebuffer *gl_framebuffer; CoglGlFramebuffer *gl_framebuffer =
CoglGlFramebufferPrivate *priv; 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)); GE (ctx, glBindFramebuffer (target, priv->gl_fbo.fbo_handle));
} }
else else
@ -633,14 +640,14 @@ try_creating_fbo (CoglContext *ctx,
return TRUE; return TRUE;
} }
gboolean CoglFramebufferDriver *
_cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, _cogl_driver_gl_create_framebuffer_driver (CoglContext *context,
CoglOffscreenFlags flags, CoglFramebuffer *framebuffer,
const CoglFramebufferDriverConfig *driver_config,
GError **error) GError **error)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
CoglOffscreenAllocateFlags allocate_flags; CoglOffscreenAllocateFlags allocate_flags;
CoglOffscreen *offscreen;
CoglGlFramebuffer *gl_framebuffer; CoglGlFramebuffer *gl_framebuffer;
CoglGlFramebufferPrivate *priv; CoglGlFramebufferPrivate *priv;
CoglGlFbo *gl_fbo; CoglGlFbo *gl_fbo;
@ -650,6 +657,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
int level_width; int level_width;
int level_height; 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 = cogl_offscreen_get_texture (offscreen);
texture_level = cogl_offscreen_get_texture_level (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); 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); priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
gl_fbo = &priv->gl_fbo; gl_fbo = &priv->gl_fbo;
if (((flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL) && if ((driver_config->disable_depth_and_stencil &&
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -691,24 +708,24 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
allocate_flags = 0, allocate_flags = 0,
gl_fbo)) || gl_fbo)) ||
(ctx->have_last_offscreen_allocate_flags && (context->have_last_offscreen_allocate_flags &&
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
level_height, level_height,
config, config,
allocate_flags = ctx->last_offscreen_allocate_flags, allocate_flags = context->last_offscreen_allocate_flags,
gl_fbo)) || gl_fbo)) ||
( (
/* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't
* need an extension to handle _FLAG_DEPTH_STENCIL */ * need an extension to handle _FLAG_DEPTH_STENCIL */
(_cogl_has_private_feature (_cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || (context, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) ||
_cogl_has_private_feature _cogl_has_private_feature
(ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && (context, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) &&
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -717,7 +734,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL,
gl_fbo)) || gl_fbo)) ||
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -727,7 +744,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
gl_fbo) || gl_fbo) ||
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -736,7 +753,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
gl_fbo) || gl_fbo) ||
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -745,7 +762,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH, allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH,
gl_fbo) || gl_fbo) ||
try_creating_fbo (ctx, try_creating_fbo (context,
texture, texture,
texture_level, texture_level,
level_width, level_width,
@ -757,35 +774,38 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
cogl_framebuffer_update_samples_per_pixel (framebuffer, cogl_framebuffer_update_samples_per_pixel (framebuffer,
gl_fbo->samples_per_pixel); 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 /* Record that the last set of flags succeeded so that we can
try that set first next time */ try that set first next time */
ctx->last_offscreen_allocate_flags = allocate_flags; context->last_offscreen_allocate_flags = allocate_flags;
ctx->have_last_offscreen_allocate_flags = TRUE; context->have_last_offscreen_allocate_flags = TRUE;
} }
return TRUE; return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer);
} }
else else
{ {
g_object_unref (gl_framebuffer);
g_set_error (error, COGL_FRAMEBUFFER_ERROR, g_set_error (error, COGL_FRAMEBUFFER_ERROR,
COGL_FRAMEBUFFER_ERROR_ALLOCATE, COGL_FRAMEBUFFER_ERROR_ALLOCATE,
"Failed to create an OpenGL framebuffer object"); "Failed to create an OpenGL framebuffer object");
return FALSE; return NULL;
} }
} }
void static void
_cogl_offscreen_gl_free (CoglOffscreen *offscreen) 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); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
CoglGlFramebuffer *gl_framebuffer;
CoglGlFramebufferPrivate *priv;
gl_framebuffer = ensure_gl_framebuffer (framebuffer); G_OBJECT_CLASS (cogl_gl_framebuffer_parent_class)->dispose (object);
priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
delete_renderbuffers (ctx, priv->gl_fbo.renderbuffers); delete_renderbuffers (ctx, priv->gl_fbo.renderbuffers);
@ -837,40 +857,14 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
GE (ctx, glClear (gl_buffers)); 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 static inline void
_cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer) _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); 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) if (!priv->dirty_bitmasks)
return; return;
@ -963,15 +957,15 @@ void
_cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
CoglFramebufferBits *bits) CoglFramebufferBits *bits)
{ {
CoglGlFramebuffer *gl_framebuffer; CoglGlFramebuffer *gl_framebuffer =
CoglGlFramebufferPrivate *priv; cogl_gl_framebuffer_from_framebuffer (framebuffer);
CoglGlFramebufferPrivate *priv =
cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
_cogl_framebuffer_init_bits (framebuffer); _cogl_framebuffer_init_bits (framebuffer);
/* TODO: cache these in some driver specific location not /* TODO: cache these in some driver specific location not
* directly as part of CoglFramebuffer. */ * directly as part of CoglFramebuffer. */
gl_framebuffer = ensure_gl_framebuffer (framebuffer);
priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
*bits = priv->bits; *bits = priv->bits;
} }
@ -1380,4 +1374,7 @@ cogl_gl_framebuffer_init (CoglGlFramebuffer *gl_framebuffer)
static void static void
cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass) cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = cogl_gl_framebuffer_dispose;
} }

View File

@ -100,6 +100,12 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext *context,
CoglFramebuffer *read_buffer, CoglFramebuffer *read_buffer,
CoglFramebufferState state); CoglFramebufferState state);
CoglFramebufferDriver *
_cogl_driver_gl_create_framebuffer_driver (CoglContext *context,
CoglFramebuffer *framebuffer,
const CoglFramebufferDriverConfig *driver_config,
GError **error);
GLenum GLenum
_cogl_gl_util_get_error (CoglContext *ctx); _cogl_gl_util_get_error (CoglContext *ctx);

View File

@ -214,7 +214,8 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext *ctx,
differences &= ~COGL_FRAMEBUFFER_STATE_BIND; 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, cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer,
differences); differences);

View File

@ -569,8 +569,7 @@ _cogl_driver_gl =
_cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_from_gl_internal,
_cogl_driver_pixel_format_to_gl, _cogl_driver_pixel_format_to_gl,
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_gl_allocate, _cogl_driver_gl_create_framebuffer_driver,
_cogl_offscreen_gl_free,
_cogl_driver_gl_flush_framebuffer_state, _cogl_driver_gl_flush_framebuffer_state,
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,

View File

@ -457,8 +457,7 @@ _cogl_driver_gles =
_cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_from_gl_internal,
_cogl_driver_pixel_format_to_gl, _cogl_driver_pixel_format_to_gl,
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_gl_allocate, _cogl_driver_gl_create_framebuffer_driver,
_cogl_offscreen_gl_free,
_cogl_driver_gl_flush_framebuffer_state, _cogl_driver_gl_flush_framebuffer_state,
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,

View File

@ -40,6 +40,7 @@
#include "cogl-texture-2d-nop-private.h" #include "cogl-texture-2d-nop-private.h"
#include "cogl-attribute-nop-private.h" #include "cogl-attribute-nop-private.h"
#include "cogl-clip-stack-nop-private.h" #include "cogl-clip-stack-nop-private.h"
#include "driver/nop/cogl-nop-framebuffer.h"
static gboolean static gboolean
_cogl_driver_update_features (CoglContext *ctx, _cogl_driver_update_features (CoglContext *ctx,
@ -67,6 +68,17 @@ _cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
return FALSE; 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 static void
_cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx, _cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx,
CoglFramebuffer *draw_buffer, CoglFramebuffer *draw_buffer,
@ -85,8 +97,7 @@ _cogl_driver_nop =
NULL, /* pixel_format_from_gl_internal */ NULL, /* pixel_format_from_gl_internal */
NULL, /* pixel_format_to_gl */ NULL, /* pixel_format_to_gl */
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_nop_allocate, _cogl_driver_nop_create_framebuffer_driver,
_cogl_offscreen_nop_free,
_cogl_driver_nop_flush_framebuffer_state, _cogl_driver_nop_flush_framebuffer_state,
_cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_clear,
_cogl_framebuffer_nop_query_bits, _cogl_framebuffer_nop_query_bits,

View File

@ -37,14 +37,6 @@
#include "cogl-types.h" #include "cogl-types.h"
#include "cogl-context-private.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 void
_cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
unsigned long buffers, unsigned long buffers,

View File

@ -35,19 +35,6 @@
#include <glib.h> #include <glib.h>
#include <string.h> #include <string.h>
gboolean
_cogl_offscreen_nop_allocate (CoglOffscreen *offscreen,
CoglOffscreenFlags flags,
GError **error)
{
return TRUE;
}
void
_cogl_offscreen_nop_free (CoglOffscreen *offscreen)
{
}
void void
_cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
unsigned long buffers, unsigned long buffers,

View File

@ -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)
{
}

View File

@ -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 */

View File

@ -132,6 +132,8 @@ cogl_noop_driver_sources = [
'driver/nop/cogl-driver-nop.c', 'driver/nop/cogl-driver-nop.c',
'driver/nop/cogl-framebuffer-nop-private.h', 'driver/nop/cogl-framebuffer-nop-private.h',
'driver/nop/cogl-framebuffer-nop.c', '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-private.h',
'driver/nop/cogl-attribute-nop.c', 'driver/nop/cogl-attribute-nop.c',
'driver/nop/cogl-clip-stack-nop-private.h', 'driver/nop/cogl-clip-stack-nop-private.h',