From e9e37dd0d1e4185807d46892ff8f4bbbbcfbbd91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 18 Oct 2020 21:11:21 +0200 Subject: [PATCH] cogl/offscreen: Move CoglOffscreen code to its own file Moving the external direct struct access will come later. Part-of: --- cogl/cogl/cogl-context-private.h | 1 + cogl/cogl/cogl-framebuffer-private.h | 59 --------- cogl/cogl/cogl-framebuffer.c | 126 ------------------ cogl/cogl/cogl-offscreen-private.h | 91 +++++++++++++ cogl/cogl/cogl-offscreen.c | 152 ++++++++++++++++++++++ cogl/cogl/cogl-texture.c | 1 + cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 1 + cogl/cogl/meson.build | 2 + 8 files changed, 248 insertions(+), 185 deletions(-) create mode 100644 cogl/cogl/cogl-offscreen-private.h create mode 100644 cogl/cogl/cogl-offscreen.c diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 3bccd51d8..25004c393 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -48,6 +48,7 @@ #include "cogl-sampler-cache-private.h" #include "cogl-gl-header.h" #include "cogl-framebuffer-private.h" +#include "cogl-offscreen-private.h" #include "cogl-onscreen-private.h" #include "cogl-fence-private.h" #include "cogl-poll-private.h" diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h index ac0b8ac1b..a7241f325 100644 --- a/cogl/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl/cogl-framebuffer-private.h @@ -37,8 +37,6 @@ #include "cogl-journal-private.h" #include "winsys/cogl-winsys-private.h" #include "cogl-attribute-private.h" -#include "cogl-offscreen.h" -#include "cogl-gl-header.h" #include "cogl-clip-stack.h" typedef struct @@ -49,12 +47,6 @@ typedef struct gboolean stereo_enabled; } CoglFramebufferConfig; -/* Flags to pass to _cogl_offscreen_new_with_texture_full */ -typedef enum -{ - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1 -} CoglOffscreenFlags; - /* XXX: The order of these indices determines the order they are * flushed. * @@ -110,39 +102,6 @@ typedef struct int stencil; } CoglFramebufferBits; -typedef enum -{ - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL = 1L<<0, - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH = 1L<<1, - COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL = 1L<<2 -} CoglOffscreenAllocateFlags; - -typedef struct _CoglGlFbo -{ - GLuint fbo_handle; - GList *renderbuffers; - int samples_per_pixel; -} CoglGlFbo; - -struct _CoglOffscreen -{ - CoglFramebuffer parent; - - CoglGlFbo gl_fbo; - - CoglTexture *texture; - int texture_level; - - CoglTexture *depth_texture; - - CoglOffscreenAllocateFlags allocation_flags; - - /* 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; -}; - gboolean cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer); @@ -243,24 +202,6 @@ _cogl_create_framebuffer_stack (void); void _cogl_free_framebuffer_stack (GSList *stack); -/* - * _cogl_offscreen_new_with_texture_full: - * @texture: A #CoglTexture pointer - * @create_flags: Flags specifying how to create the FBO - * @level: The mipmap level within the texture to target - * - * Creates a new offscreen buffer which will target the given - * texture. By default the buffer will have a depth and stencil - * buffer. This can be disabled by passing - * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags. - * - * Return value: the new CoglOffscreen object. - */ -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags create_flags, - int level); - void _cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer); diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index 1073685b6..6b793cd28 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -147,9 +147,6 @@ typedef struct _CoglFramebufferPrivate G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer, G_TYPE_OBJECT) -G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen, - COGL_TYPE_FRAMEBUFFER) - uint32_t cogl_framebuffer_error_quark (void) { @@ -893,129 +890,6 @@ _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer) priv->deps = NULL; } -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags create_flags, - int level) -{ - CoglContext *ctx = texture->context; - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - - g_return_val_if_fail (cogl_is_texture (texture), NULL); - - offscreen = g_object_new (COGL_TYPE_OFFSCREEN, - "context", ctx, - NULL); - offscreen->texture = cogl_object_ref (texture); - offscreen->texture_level = level; - offscreen->create_flags = create_flags; - - fb = COGL_FRAMEBUFFER (offscreen); - - /* NB: we can't assume we can query the texture's width yet, since - * it might not have been allocated yet and for example if the - * texture is being loaded from a file then the file might not - * have been read yet. */ - - _cogl_texture_associate_framebuffer (texture, fb); - - return offscreen; -} - -CoglOffscreen * -cogl_offscreen_new_with_texture (CoglTexture *texture) -{ - return _cogl_offscreen_new_with_texture_full (texture, 0, 0); -} - -CoglTexture * -cogl_offscreen_get_texture (CoglOffscreen *offscreen) -{ - return offscreen->texture; -} - -static gboolean -cogl_offscreen_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (!cogl_texture_allocate (offscreen->texture, error)) - return FALSE; - - /* NB: it's only after allocating the texture that we will - * determine whether a texture needs slicing... */ - if (cogl_texture_is_sliced (offscreen->texture)) - { - g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create offscreen framebuffer from " - "sliced texture"); - return FALSE; - } - - /* Now that the texture has been allocated we can determine a - * size for the framebuffer... */ - priv->width = cogl_texture_get_width (offscreen->texture); - priv->height = cogl_texture_get_height (offscreen->texture); - priv->viewport_width = priv->width; - priv->viewport_height = priv->height; - - /* Forward the texture format as the internal format of the - * framebuffer */ - priv->internal_format = - _cogl_texture_get_format (offscreen->texture); - - if (!ctx->driver_vtable->offscreen_allocate (offscreen, error)) - return FALSE; - - return TRUE; -} - -static gboolean -cogl_offscreen_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return TRUE; -} - -static void -cogl_offscreen_dispose (GObject *object) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglContext *ctx = priv->context; - - if (offscreen->texture) - ctx->driver_vtable->offscreen_free (offscreen); - - G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object); - - cogl_clear_object (&offscreen->texture); - cogl_clear_object (&offscreen->depth_texture); -} - -static void -cogl_offscreen_init (CoglOffscreen *offscreen) -{ -} - -static void -cogl_offscreen_class_init (CoglOffscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_offscreen_dispose; - - framebuffer_class->allocate = cogl_offscreen_allocate; - framebuffer_class->is_y_flipped = cogl_offscreen_is_y_flipped; -} - gboolean cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer) { diff --git a/cogl/cogl/cogl-offscreen-private.h b/cogl/cogl/cogl-offscreen-private.h new file mode 100644 index 000000000..2b6241edb --- /dev/null +++ b/cogl/cogl/cogl-offscreen-private.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2007,2008,2009 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * 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_OFFSCREEN_PRIVATE_H +#define COGL_OFFSCREEN_PRIVATE_H + +#include "cogl-gl-header.h" +#include "cogl-offscreen.h" + +/* Flags to pass to _cogl_offscreen_new_with_texture_full */ +typedef enum +{ + COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1 +} CoglOffscreenFlags; + +typedef enum +{ + COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL = 1 << 0, + COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH = 1 << 1, + COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL = 1 << 2, +} CoglOffscreenAllocateFlags; + +typedef struct _CoglGLFramebuffer +{ + GLuint fbo_handle; + GList *renderbuffers; + int samples_per_pixel; +} CoglGlFbo; + +struct _CoglOffscreen +{ + CoglFramebuffer parent; + + CoglGlFbo gl_fbo; + + CoglTexture *texture; + int texture_level; + + CoglTexture *depth_texture; + + CoglOffscreenAllocateFlags allocation_flags; + + /* 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; +}; + +/* + * _cogl_offscreen_new_with_texture_full: + * @texture: A #CoglTexture pointer + * @create_flags: Flags specifying how to create the FBO + * @level: The mipmap level within the texture to target + * + * Creates a new offscreen buffer which will target the given + * texture. By default the buffer will have a depth and stencil + * buffer. This can be disabled by passing + * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags. + * + * Return value: the new CoglOffscreen object. + */ +CoglOffscreen * +_cogl_offscreen_new_with_texture_full (CoglTexture *texture, + CoglOffscreenFlags create_flags, + int level); + +#endif /* COGL_OFFSCREEN_PRIVATE_H */ diff --git a/cogl/cogl/cogl-offscreen.c b/cogl/cogl/cogl-offscreen.c new file mode 100644 index 000000000..7ba5ad483 --- /dev/null +++ b/cogl/cogl/cogl-offscreen.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2007,2008,2009,2012 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * 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-context-private.h" +#include "cogl-framebuffer-private.h" +#include "cogl-offscreen-private.h" +#include "cogl-texture-private.h" + +G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen, + COGL_TYPE_FRAMEBUFFER) + +CoglOffscreen * +_cogl_offscreen_new_with_texture_full (CoglTexture *texture, + CoglOffscreenFlags create_flags, + int level) +{ + CoglContext *ctx = texture->context; + CoglOffscreen *offscreen; + CoglFramebuffer *fb; + + g_return_val_if_fail (cogl_is_texture (texture), NULL); + + offscreen = g_object_new (COGL_TYPE_OFFSCREEN, + "context", ctx, + NULL); + offscreen->texture = cogl_object_ref (texture); + offscreen->texture_level = level; + offscreen->create_flags = create_flags; + + fb = COGL_FRAMEBUFFER (offscreen); + + /* NB: we can't assume we can query the texture's width yet, since + * it might not have been allocated yet and for example if the + * texture is being loaded from a file then the file might not + * have been read yet. */ + + _cogl_texture_associate_framebuffer (texture, fb); + + return offscreen; +} + +CoglOffscreen * +cogl_offscreen_new_with_texture (CoglTexture *texture) +{ + return _cogl_offscreen_new_with_texture_full (texture, 0, 0); +} + +CoglTexture * +cogl_offscreen_get_texture (CoglOffscreen *offscreen) +{ + return offscreen->texture; +} + +static gboolean +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; + + if (!cogl_texture_allocate (offscreen->texture, error)) + return FALSE; + + /* NB: it's only after allocating the texture that we will + * determine whether a texture needs slicing... */ + if (cogl_texture_is_sliced (offscreen->texture)) + { + g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, + "Can't create offscreen framebuffer from " + "sliced texture"); + return FALSE; + } + + width = cogl_texture_get_width (offscreen->texture); + height = cogl_texture_get_height (offscreen->texture); + cogl_framebuffer_update_size (framebuffer, width, height); + + texture_format = _cogl_texture_get_format (offscreen->texture); + _cogl_framebuffer_set_internal_format (framebuffer, texture_format); + + if (!ctx->driver_vtable->offscreen_allocate (offscreen, error)) + return FALSE; + + return TRUE; +} + +static gboolean +cogl_offscreen_is_y_flipped (CoglFramebuffer *framebuffer) +{ + return TRUE; +} + +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); + + cogl_clear_object (&offscreen->texture); + cogl_clear_object (&offscreen->depth_texture); +} + +static void +cogl_offscreen_init (CoglOffscreen *offscreen) +{ +} + +static void +cogl_offscreen_class_init (CoglOffscreenClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); + + object_class->dispose = cogl_offscreen_dispose; + + framebuffer_class->allocate = cogl_offscreen_allocate; + framebuffer_class->is_y_flipped = cogl_offscreen_is_y_flipped; +} diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c index 8a7ec49b2..866a0b584 100644 --- a/cogl/cogl/cogl-texture.c +++ b/cogl/cogl/cogl-texture.c @@ -52,6 +52,7 @@ #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-object-private.h" +#include "cogl-offscreen-private.h" #include "cogl-framebuffer-private.h" #include "cogl1-context.h" #include "cogl-sub-texture.h" diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c index 38e6afdd3..625d55367 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c @@ -34,6 +34,7 @@ #include "cogl-context-private.h" #include "cogl-framebuffer-private.h" #include "cogl-framebuffer.h" +#include "cogl-offscreen-private.h" #include "cogl-texture-private.h" #include "driver/gl/cogl-util-gl-private.h" #include "driver/gl/cogl-framebuffer-gl-private.h" diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index e565d74b2..2aa0bfbac 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -308,6 +308,8 @@ cogl_sources = [ 'cogl-spans.c', 'cogl-journal-private.h', 'cogl-journal.c', + 'cogl-offscreen-private.h', + 'cogl-offscreen.c', 'cogl-frame-info-private.h', 'cogl-frame-info.c', 'cogl-framebuffer-private.h',