mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-03-14 15:40:38 +01:00
gl: Only allocate a framebuffer if we need one
This way, we don't clobber the current target when creating textures for image surfaces.
This commit is contained in:
parent
1c15510c3d
commit
1ddff8aba3
3 changed files with 29 additions and 19 deletions
|
|
@ -221,6 +221,31 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
{
|
||||
GLenum status;
|
||||
|
||||
if (likely (surface->fb))
|
||||
return;
|
||||
|
||||
/* Create a framebuffer object wrapping the texture so that we can render
|
||||
* to it.
|
||||
*/
|
||||
glGenFramebuffersEXT (1, &surface->fb);
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
|
||||
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
ctx->tex_target,
|
||||
surface->tex,
|
||||
0);
|
||||
|
||||
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
fprintf (stderr, "destination is framebuffer incomplete\n");
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
|
|
@ -233,6 +258,7 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
|
|||
ctx->current_target = surface;
|
||||
|
||||
if (_cairo_gl_surface_is_texture (surface)) {
|
||||
_cairo_gl_ensure_framebuffer (ctx, surface);
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
|
||||
glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
|
||||
glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ _cairo_gl_surface_init (cairo_device_t *device,
|
|||
static cairo_always_inline cairo_bool_t cairo_warn
|
||||
_cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
|
||||
{
|
||||
return surface->fb != 0;
|
||||
return surface->tex != 0;
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
|
|
|||
|
|
@ -242,7 +242,6 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
|
|||
{
|
||||
cairo_gl_surface_t *surface;
|
||||
GLenum format;
|
||||
cairo_status_t status;
|
||||
|
||||
assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
|
||||
|
||||
|
|
@ -289,22 +288,6 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
|
|||
glTexImage2D (ctx->tex_target, 0, format, width, height, 0,
|
||||
format, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
/* Create a framebuffer object wrapping the texture so that we can render
|
||||
* to it.
|
||||
*/
|
||||
glGenFramebuffersEXT (1, &surface->fb);
|
||||
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
|
||||
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
ctx->tex_target,
|
||||
surface->tex,
|
||||
0);
|
||||
ctx->current_target = NULL;
|
||||
|
||||
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
fprintf (stderr, "destination is framebuffer incomplete\n");
|
||||
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
|
|
@ -707,7 +690,8 @@ _cairo_gl_surface_finish (void *abstract_surface)
|
|||
if (ctx->current_target == surface)
|
||||
ctx->current_target = NULL;
|
||||
|
||||
glDeleteFramebuffersEXT (1, &surface->fb);
|
||||
if (surface->fb)
|
||||
glDeleteFramebuffersEXT (1, &surface->fb);
|
||||
glDeleteTextures (1, &surface->tex);
|
||||
|
||||
_cairo_gl_context_release (ctx);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue