mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 20:28:02 +02:00
cogl: Move framebuffer creation functionality out of boilerplate
In order to be more consistent with backends such as gl, support for creating a surface from content, width, and height parameters was moved into the backend itself. The option to pass cairo-cogl a framebuffer to create a texture from still exists, just now it is not the only option. Signed-off-by: George Matsumura <gmmatsumura01@bvsd.org>
This commit is contained in:
parent
9248ba1419
commit
916408481f
3 changed files with 187 additions and 77 deletions
|
|
@ -31,27 +31,23 @@
|
|||
*/
|
||||
|
||||
#include "cairo-boilerplate-private.h"
|
||||
#include "cairo-malloc-private.h"
|
||||
|
||||
#include <cairo-cogl.h>
|
||||
#include <cogl/cogl2-experimental.h>
|
||||
|
||||
typedef struct _cogl_closure {
|
||||
cairo_device_t *device;
|
||||
CoglFramebuffer *fb;
|
||||
cairo_surface_t *surface;
|
||||
} cogl_closure_t;
|
||||
|
||||
static const cairo_user_data_key_t cogl_closure_key;
|
||||
|
||||
static CoglContext *context = NULL;
|
||||
|
||||
static void
|
||||
_cairo_boilerplate_cogl_cleanup (void *abstract_closure)
|
||||
{
|
||||
cogl_closure_t *closure = abstract_closure;
|
||||
|
||||
cogl_object_unref (closure->fb);
|
||||
|
||||
cairo_device_finish (closure->device);
|
||||
cairo_device_destroy (closure->device);
|
||||
|
||||
|
|
@ -68,9 +64,8 @@ _cairo_boilerplate_cogl_create_offscreen_color_surface (const char *name,
|
|||
cairo_boilerplate_mode_t mode,
|
||||
void **abstract_closure)
|
||||
{
|
||||
CoglContext *context;
|
||||
cairo_device_t *device;
|
||||
CoglTexture *tex;
|
||||
CoglFramebuffer *fb;
|
||||
cogl_closure_t *closure;
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -79,25 +74,17 @@ _cairo_boilerplate_cogl_create_offscreen_color_surface (const char *name,
|
|||
if (height < 1)
|
||||
height = 1;
|
||||
|
||||
if (!context)
|
||||
context = cogl_context_new (NULL, NULL);
|
||||
context = cogl_context_new (NULL, NULL);
|
||||
|
||||
device = cairo_cogl_device_create (context);
|
||||
tex = cogl_texture_2d_new_with_size (context, width, height);
|
||||
cogl_texture_set_components (tex, COGL_TEXTURE_COMPONENTS_RGBA);
|
||||
fb = cogl_offscreen_new_with_texture (tex);
|
||||
|
||||
cogl_framebuffer_allocate (fb, NULL);
|
||||
cogl_framebuffer_orthographic (fb, 0, 0,
|
||||
cogl_framebuffer_get_width (fb),
|
||||
cogl_framebuffer_get_height (fb),
|
||||
-1, 100);
|
||||
|
||||
closure = malloc (sizeof (cogl_closure_t));
|
||||
closure = _cairo_malloc (sizeof (cogl_closure_t));
|
||||
*abstract_closure = closure;
|
||||
closure->device = device;
|
||||
closure->fb = fb;
|
||||
closure->surface = cairo_cogl_surface_create (device, fb);
|
||||
closure->surface = cairo_cogl_offscreen_surface_create (device,
|
||||
content,
|
||||
width,
|
||||
height);
|
||||
|
||||
status = cairo_surface_set_user_data (closure->surface,
|
||||
&cogl_closure_key, closure, NULL);
|
||||
|
|
@ -118,8 +105,8 @@ _cairo_boilerplate_cogl_create_onscreen_color_surface (const char *name,
|
|||
cairo_boilerplate_mode_t mode,
|
||||
void **abstract_closure)
|
||||
{
|
||||
CoglContext *context;
|
||||
cairo_device_t *device;
|
||||
CoglFramebuffer *fb;
|
||||
cogl_closure_t *closure;
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -128,24 +115,17 @@ _cairo_boilerplate_cogl_create_onscreen_color_surface (const char *name,
|
|||
if (height < 1)
|
||||
height = 1;
|
||||
|
||||
if (!context)
|
||||
context = cogl_context_new (NULL, NULL);
|
||||
context = cogl_context_new (NULL, NULL);
|
||||
|
||||
device = cairo_cogl_device_create (context);
|
||||
fb = cogl_onscreen_new (context, width, height);
|
||||
|
||||
cogl_onscreen_show (fb);
|
||||
|
||||
cogl_framebuffer_orthographic (fb, 0, 0,
|
||||
cogl_framebuffer_get_width (fb),
|
||||
cogl_framebuffer_get_height (fb),
|
||||
-1, 100);
|
||||
|
||||
closure = malloc (sizeof (cogl_closure_t));
|
||||
closure = _cairo_malloc (sizeof (cogl_closure_t));
|
||||
*abstract_closure = closure;
|
||||
closure->device = device;
|
||||
closure->fb = fb;
|
||||
closure->surface = cairo_cogl_surface_create (device, fb);
|
||||
closure->surface = cairo_cogl_onscreen_surface_create (device,
|
||||
content,
|
||||
width,
|
||||
height);
|
||||
|
||||
status = cairo_surface_set_user_data (closure->surface,
|
||||
&cogl_closure_key, closure, NULL);
|
||||
|
|
@ -158,22 +138,15 @@ _cairo_boilerplate_cogl_create_onscreen_color_surface (const char *name,
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_boilerplate_cogl_finish (cairo_surface_t *surface)
|
||||
{
|
||||
cogl_closure_t *closure = cairo_surface_get_user_data (surface, &cogl_closure_key);
|
||||
|
||||
cairo_cogl_surface_end_frame (surface);
|
||||
|
||||
if (cogl_is_onscreen (closure->fb))
|
||||
cogl_onscreen_swap_buffers (closure->fb);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
{
|
||||
return cairo_cogl_surface_end_frame (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_boilerplate_cogl_synchronize (void *abstract_closure)
|
||||
{
|
||||
cogl_closure_t *closure = abstract_closure;
|
||||
cogl_framebuffer_finish (closure->fb);
|
||||
cairo_cogl_surface_synchronize (closure->surface);
|
||||
}
|
||||
|
||||
static const cairo_boilerplate_target_t targets[] = {
|
||||
|
|
|
|||
|
|
@ -211,10 +211,13 @@ _cairo_cogl_journal_flush (cairo_cogl_surface_t *surface);
|
|||
cairo_private extern const cairo_surface_backend_t _cairo_cogl_surface_backend;
|
||||
|
||||
slim_hidden_proto (cairo_cogl_device_create);
|
||||
slim_hidden_proto (cairo_cogl_surface_create);
|
||||
slim_hidden_proto (cairo_cogl_surface_create_for_fb);
|
||||
slim_hidden_proto (cairo_cogl_onscreen_surface_create);
|
||||
slim_hidden_proto (cairo_cogl_offscreen_surface_create);
|
||||
slim_hidden_proto (cairo_cogl_surface_get_framebuffer);
|
||||
slim_hidden_proto (cairo_cogl_surface_get_texture);
|
||||
slim_hidden_proto (cairo_cogl_surface_end_frame);
|
||||
slim_hidden_proto (cairo_cogl_surface_synchronize);
|
||||
|
||||
static cairo_cogl_device_t *
|
||||
to_device (cairo_device_t *device)
|
||||
|
|
@ -273,10 +276,11 @@ _cairo_cogl_surface_create_similar (void *abstract_surface,
|
|||
cairo_cogl_surface_t *surface;
|
||||
CoglTexture *texture;
|
||||
cairo_status_t status;
|
||||
cairo_cogl_device_t *dev =
|
||||
to_device(reference_surface->base.device);
|
||||
|
||||
texture =
|
||||
cogl_texture_2d_new_with_size (to_device(reference_surface->base.device)->cogl_context,
|
||||
width, height);
|
||||
texture = cogl_texture_2d_new_with_size (dev->cogl_context,
|
||||
width, height);
|
||||
if (!texture)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
||||
|
|
@ -286,7 +290,7 @@ _cairo_cogl_surface_create_similar (void *abstract_surface,
|
|||
COGL_TEXTURE_COMPONENTS_A);
|
||||
|
||||
surface = (cairo_cogl_surface_t *)
|
||||
_cairo_cogl_surface_create_full (to_device(reference_surface->base.device),
|
||||
_cairo_cogl_surface_create_full (dev,
|
||||
(content & CAIRO_CONTENT_ALPHA) == 0,
|
||||
NULL,
|
||||
texture);
|
||||
|
|
@ -346,20 +350,12 @@ static void
|
|||
_cairo_cogl_journal_discard (cairo_cogl_surface_t *surface)
|
||||
{
|
||||
GList *l;
|
||||
cairo_cogl_device_t *dev;
|
||||
|
||||
if (!surface->journal) {
|
||||
assert (surface->last_clip == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
dev = to_device(surface->base.device);
|
||||
if (dev->buffer_stack && dev->buffer_stack_offset) {
|
||||
cogl_buffer_unmap (dev->buffer_stack);
|
||||
cogl_object_unref (dev->buffer_stack);
|
||||
dev->buffer_stack = NULL;
|
||||
}
|
||||
|
||||
for (l = surface->journal->head; l; l = l->next) {
|
||||
cairo_cogl_journal_entry_t *entry = l->data;
|
||||
gsize entry_size;
|
||||
|
|
@ -604,18 +600,19 @@ _cairo_cogl_traps_to_triangles_buffer (cairo_cogl_surface_t *surface,
|
|||
int n_traps = traps->num_traps;
|
||||
int i;
|
||||
CoglVertexP2 *triangles;
|
||||
cairo_cogl_device_t *dev = to_device(surface->base.device);
|
||||
|
||||
if (one_shot) {
|
||||
buffer =
|
||||
_cairo_cogl_device_allocate_buffer_space (to_device(surface->base.device),
|
||||
n_traps * sizeof (CoglVertexP2) * 6,
|
||||
offset,
|
||||
(void **)&triangles);
|
||||
_cairo_cogl_device_allocate_buffer_space (dev,
|
||||
n_traps * sizeof (CoglVertexP2) * 6,
|
||||
offset,
|
||||
(void **)&triangles);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
} else {
|
||||
buffer =
|
||||
cogl_attribute_buffer_new (to_device(surface->base.device)->cogl_context,
|
||||
cogl_attribute_buffer_new (dev->cogl_context,
|
||||
n_traps * sizeof (CoglVertexP2) * 6,
|
||||
NULL);
|
||||
if (!buffer)
|
||||
|
|
@ -1310,6 +1307,23 @@ _cairo_cogl_surface_finish (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static CoglTextureComponents
|
||||
get_components_from_cairo_content (cairo_content_t content)
|
||||
{
|
||||
switch (content)
|
||||
{
|
||||
case CAIRO_CONTENT_ALPHA:
|
||||
return COGL_TEXTURE_COMPONENTS_A;
|
||||
case CAIRO_CONTENT_COLOR:
|
||||
return COGL_TEXTURE_COMPONENTS_RGB;
|
||||
case CAIRO_CONTENT_COLOR_ALPHA:
|
||||
return COGL_TEXTURE_COMPONENTS_RGBA;
|
||||
default:
|
||||
g_warning ("Unrecognized content type");
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
get_default_cogl_format_from_components (CoglTextureComponents components)
|
||||
{
|
||||
|
|
@ -1732,10 +1746,9 @@ _cairo_cogl_acquire_surface_texture (cairo_cogl_surface_t *reference_surf
|
|||
* accordingly. */
|
||||
*has_pre_transform = TRUE;
|
||||
|
||||
texture =
|
||||
cogl_texture_2d_new_with_size (to_device(reference_surface->base.device)->cogl_context,
|
||||
extents->width,
|
||||
extents->height);
|
||||
texture = cogl_texture_2d_new_with_size (dev->cogl_context,
|
||||
extents->width,
|
||||
extents->height);
|
||||
if (!texture) {
|
||||
g_warning ("Failed to allocate texture: %s", error->message);
|
||||
g_error_free (error);
|
||||
|
|
@ -1743,7 +1756,7 @@ _cairo_cogl_acquire_surface_texture (cairo_cogl_surface_t *reference_surf
|
|||
}
|
||||
|
||||
clone =
|
||||
_cairo_cogl_surface_create_full (to_device(reference_surface->base.device),
|
||||
_cairo_cogl_surface_create_full (dev,
|
||||
reference_surface->ignore_alpha,
|
||||
NULL,
|
||||
texture);
|
||||
|
|
@ -3514,8 +3527,8 @@ _cairo_cogl_surface_create_full (cairo_cogl_device_t *dev,
|
|||
}
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_cogl_surface_create (cairo_device_t *abstract_device,
|
||||
CoglFramebuffer *framebuffer)
|
||||
cairo_cogl_surface_create_for_fb (cairo_device_t *abstract_device,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
cairo_cogl_device_t *dev = (cairo_cogl_device_t *)abstract_device;
|
||||
|
||||
|
|
@ -3530,7 +3543,65 @@ cairo_cogl_surface_create (cairo_device_t *abstract_device,
|
|||
|
||||
return _cairo_cogl_surface_create_full (dev, FALSE, framebuffer, NULL);
|
||||
}
|
||||
slim_hidden_def (cairo_cogl_surface_create);
|
||||
slim_hidden_def (cairo_cogl_surface_create_for_fb);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_cogl_onscreen_surface_create (cairo_device_t *abstract_device,
|
||||
cairo_content_t content,
|
||||
int width, int height)
|
||||
{
|
||||
CoglFramebuffer *fb;
|
||||
CoglTextureComponents components;
|
||||
cairo_cogl_device_t *dev = (cairo_cogl_device_t *)abstract_device;
|
||||
|
||||
if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_COGL)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
|
||||
|
||||
/* We don't yet have a way to set the components of a framebuffer */
|
||||
components = get_components_from_cairo_content (content);
|
||||
|
||||
fb = cogl_onscreen_new (dev->cogl_context, width, height);
|
||||
|
||||
if (!cogl_framebuffer_allocate (fb, NULL))
|
||||
return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_ERROR);
|
||||
cogl_framebuffer_orthographic (fb, 0, 0,
|
||||
cogl_framebuffer_get_width (fb),
|
||||
cogl_framebuffer_get_height (fb),
|
||||
-1, 100);
|
||||
|
||||
return cairo_cogl_surface_create_for_fb (abstract_device, fb);
|
||||
}
|
||||
slim_hidden_def (cairo_cogl_onscreen_surface_create);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_cogl_offscreen_surface_create (cairo_device_t *abstract_device,
|
||||
cairo_content_t content,
|
||||
int width, int height)
|
||||
{
|
||||
CoglFramebuffer *fb;
|
||||
CoglTexture *tex;
|
||||
CoglTextureComponents components;
|
||||
cairo_cogl_device_t *dev = (cairo_cogl_device_t *)abstract_device;
|
||||
|
||||
if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_COGL)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
|
||||
|
||||
components = get_components_from_cairo_content (content);
|
||||
tex = cogl_texture_2d_new_with_size (dev->cogl_context,
|
||||
width, height);
|
||||
cogl_texture_set_components (tex, components);
|
||||
fb = cogl_offscreen_new_with_texture (tex);
|
||||
|
||||
if (!cogl_framebuffer_allocate (fb, NULL))
|
||||
return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_ERROR);
|
||||
cogl_framebuffer_orthographic (fb, 0, 0,
|
||||
cogl_framebuffer_get_width (fb),
|
||||
cogl_framebuffer_get_height (fb),
|
||||
-1, 100);
|
||||
|
||||
return cairo_cogl_surface_create_for_fb (abstract_device, fb);
|
||||
}
|
||||
slim_hidden_def (cairo_cogl_offscreen_surface_create);
|
||||
|
||||
CoglFramebuffer *
|
||||
cairo_cogl_surface_get_framebuffer (cairo_surface_t *abstract_surface)
|
||||
|
|
@ -3568,6 +3639,7 @@ static cairo_status_t
|
|||
_cairo_cogl_device_flush (void *device)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_cogl_device_t *dev = device;
|
||||
|
||||
status = cairo_device_acquire (device);
|
||||
if (unlikely (status))
|
||||
|
|
@ -3576,6 +3648,12 @@ _cairo_cogl_device_flush (void *device)
|
|||
/* XXX: we don't need to flush Cogl here, we just need to flush
|
||||
* any batching we do of compositing primitives. */
|
||||
|
||||
if (dev->buffer_stack && dev->buffer_stack_offset) {
|
||||
cogl_buffer_unmap (dev->buffer_stack);
|
||||
cogl_object_unref (dev->buffer_stack);
|
||||
dev->buffer_stack = NULL;
|
||||
}
|
||||
|
||||
cairo_device_release (device);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -3585,6 +3663,8 @@ static void
|
|||
_cairo_cogl_device_finish (void *device)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_cogl_device_t *dev = device;
|
||||
int i, j;
|
||||
|
||||
status = cairo_device_acquire (device);
|
||||
if (unlikely (status))
|
||||
|
|
@ -3592,6 +3672,27 @@ _cairo_cogl_device_finish (void *device)
|
|||
|
||||
/* XXX: Drop references to external resources */
|
||||
|
||||
_cairo_cache_fini (&dev->linear_cache);
|
||||
_cairo_cache_fini (&dev->path_fill_staging_cache);
|
||||
_cairo_cache_fini (&dev->path_fill_prim_cache);
|
||||
_cairo_cache_fini (&dev->path_stroke_staging_cache);
|
||||
_cairo_cache_fini (&dev->path_stroke_prim_cache);
|
||||
|
||||
if (dev->buffer_stack && dev->buffer_stack_offset) {
|
||||
cogl_buffer_unmap (dev->buffer_stack);
|
||||
cogl_object_unref (dev->buffer_stack);
|
||||
dev->buffer_stack = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < CAIRO_OPERATOR_SATURATE; i++)
|
||||
for (j = 0; j < CAIRO_COGL_TEMPLATE_TYPE_COUNT; j++)
|
||||
if (dev->template_pipelines[i][j] != NULL) {
|
||||
cogl_object_unref (dev->template_pipelines[i][j]);
|
||||
dev->template_pipelines[i][j] = NULL;
|
||||
}
|
||||
|
||||
cogl_object_unref (dev->cogl_context);
|
||||
|
||||
cairo_device_release (device);
|
||||
}
|
||||
|
||||
|
|
@ -3600,8 +3701,6 @@ _cairo_cogl_device_destroy (void *device)
|
|||
{
|
||||
cairo_cogl_device_t *dev = device;
|
||||
|
||||
/* FIXME: Free stuff! */
|
||||
|
||||
g_free (dev);
|
||||
}
|
||||
|
||||
|
|
@ -3679,13 +3778,38 @@ cairo_cogl_device_create (CoglContext *cogl_context)
|
|||
}
|
||||
slim_hidden_def (cairo_cogl_device_create);
|
||||
|
||||
void
|
||||
cairo_status_t
|
||||
cairo_cogl_surface_end_frame (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface;
|
||||
|
||||
if (abstract_surface->backend != &_cairo_cogl_surface_backend)
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
|
||||
cairo_surface_flush (abstract_surface);
|
||||
|
||||
if (surface->framebuffer)
|
||||
if (cogl_is_onscreen (surface->framebuffer))
|
||||
cogl_onscreen_swap_buffers (surface->framebuffer);
|
||||
|
||||
//g_print ("n_clip_updates_per_frame = %d\n", surface->n_clip_updates_per_frame);
|
||||
surface->n_clip_updates_per_frame = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_cogl_surface_end_frame);
|
||||
|
||||
cairo_status_t
|
||||
cairo_cogl_surface_synchronize (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface;
|
||||
|
||||
if (abstract_surface->backend != &_cairo_cogl_surface_backend)
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
|
||||
if (surface->framebuffer)
|
||||
cogl_framebuffer_finish (surface->framebuffer);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_cogl_surface_synchronize);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,18 @@ cairo_public cairo_device_t *
|
|||
cairo_cogl_device_create (CoglContext *context);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_cogl_surface_create (cairo_device_t *device,
|
||||
CoglFramebuffer *framebuffer);
|
||||
cairo_cogl_onscreen_surface_create (cairo_device_t *device,
|
||||
cairo_content_t content,
|
||||
int width, int height);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_cogl_offscreen_surface_create (cairo_device_t *device,
|
||||
cairo_content_t content,
|
||||
int width, int height);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_cogl_surface_create_for_fb (cairo_device_t *device,
|
||||
CoglFramebuffer *framebuffer);
|
||||
|
||||
cairo_public CoglFramebuffer *
|
||||
cairo_cogl_surface_get_framebuffer (cairo_surface_t *surface);
|
||||
|
|
@ -57,9 +67,12 @@ cairo_cogl_surface_get_framebuffer (cairo_surface_t *surface);
|
|||
cairo_public CoglTexture *
|
||||
cairo_cogl_surface_get_texture (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_public cairo_status_t
|
||||
cairo_cogl_surface_end_frame (cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_cogl_surface_synchronize (cairo_surface_t *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_COGL_SURFACE*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue