diff options
author | David Reveman <davidr@novell.com> | 2005-02-10 01:03:00 +0000 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2005-02-10 01:03:00 +0000 |
commit | 39b5acfa12d126d255627059e36a9471d8473103 (patch) | |
tree | cea9e45c503187308c2fc330f5c8142fa162d83c /src | |
parent | 19a83a4372d737df43c87068409085a962d727bf (diff) |
Add preliminary support for EXT_framebuffer_object
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 43 | ||||
-rw-r--r-- | src/glitz.h | 4 | ||||
-rw-r--r-- | src/glitz_framebuffer.c | 74 | ||||
-rw-r--r-- | src/glitz_gl.h | 23 | ||||
-rw-r--r-- | src/glitz_surface.c | 117 | ||||
-rw-r--r-- | src/glitz_util.c | 22 | ||||
-rw-r--r-- | src/glitzint.h | 26 |
7 files changed, 251 insertions, 58 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 79b63f8..7f0a0be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,27 +3,28 @@ SUBDIRS = . glx agl lib_LTLIBRARIES = libglitz.la include_HEADERS = glitz.h -libglitz_la_SOURCES = \ - glitz.h \ - glitz.c \ - glitz_operator.c \ - glitz_drawable.c \ - glitz_surface.c \ - glitz_texture.c \ - glitz_rect.c \ - glitz_status.c \ - glitz_util.c \ - glitz_region.c \ - glitz_format.c \ - glitz_program.c \ - glitz_compose.c \ - glitz_filter.c \ - glitz_buffer.c \ - glitz_geometry.c \ - glitz_pixel.c \ - glitz_trap.c \ - glitz_trapimp.h \ - glitz_gl.h \ +libglitz_la_SOURCES = \ + glitz.h \ + glitz.c \ + glitz_operator.c \ + glitz_drawable.c \ + glitz_surface.c \ + glitz_texture.c \ + glitz_rect.c \ + glitz_status.c \ + glitz_util.c \ + glitz_region.c \ + glitz_format.c \ + glitz_program.c \ + glitz_compose.c \ + glitz_filter.c \ + glitz_buffer.c \ + glitz_geometry.c \ + glitz_pixel.c \ + glitz_trap.c \ + glitz_framebuffer.c \ + glitz_trapimp.h \ + glitz_gl.h \ glitzint.h libglitz_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined diff --git a/src/glitz.h b/src/glitz.h index 36c1233..a700636 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -135,6 +135,7 @@ typedef enum { #define GLITZ_FEATURE_BLEND_COLOR_MASK (1L << 13) #define GLITZ_FEATURE_PACKED_PIXELS_MASK (1L << 14) #define GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK (1L << 15) +#define GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK (1L << 16) typedef enum { GLITZ_STANDARD_ARGB32, @@ -370,6 +371,9 @@ glitz_surface_set_clip_region (glitz_surface_t *surface, glitz_box_t *box, int n_box); +glitz_bool_t +glitz_surface_valid_target (glitz_surface_t *surface); + /* glitz_rect.c */ diff --git a/src/glitz_framebuffer.c b/src/glitz_framebuffer.c new file mode 100644 index 0000000..24a214f --- /dev/null +++ b/src/glitz_framebuffer.c @@ -0,0 +1,74 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman <davidr@novell.com> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitzint.h" + +void +glitz_framebuffer_init (glitz_framebuffer_t *framebuffer) +{ + framebuffer->name = 0; +} + +void +glitz_framebuffer_fini (glitz_gl_proc_address_list_t *gl, + glitz_framebuffer_t *framebuffer) +{ + gl->delete_framebuffers (1, &framebuffer->name); +} + +void +glitz_framebuffer_unbind (glitz_gl_proc_address_list_t *gl) +{ + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, 0); +} + +glitz_bool_t +glitz_framebuffer_complete (glitz_gl_proc_address_list_t *gl, + glitz_framebuffer_t *framebuffer, + glitz_texture_t *texture) +{ + if (!framebuffer->name) + { + if (!TEXTURE_ALLOCATED (texture)) + glitz_texture_allocate (gl, texture); + + gl->gen_framebuffers (1, &framebuffer->name); + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, framebuffer->name); + + gl->framebuffer_texture_2d (GLITZ_GL_FRAMEBUFFER, + GLITZ_GL_COLOR_ATTACHMENT0, + GLITZ_GL_TEXTURE_2D, texture->name, + 0); + } + else + gl->bind_framebuffer (GLITZ_GL_FRAMEBUFFER, framebuffer->name); + + return (gl->check_framebuffer_status (GLITZ_GL_FRAMEBUFFER) == + GLITZ_GL_FRAMEBUFFER_COMPLETE); +} diff --git a/src/glitz_gl.h b/src/glitz_gl.h index aad2862..85d96ef 100644 --- a/src/glitz_gl.h +++ b/src/glitz_gl.h @@ -303,6 +303,18 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_WRITE_ONLY 0x88B9 #define GLITZ_GL_READ_WRITE 0x88BA +#define GLITZ_GL_FRAMEBUFFER 0x8D40 +#define GLITZ_GL_COLOR_ATTACHMENT0 0x8CE0 +#define GLITZ_GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT 0x8CD8 +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_FORMATS 0x8CDA +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GLITZ_GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GLITZ_GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GLITZ_GL_FRAMEBUFFER_STATUS_ERROR 0x8CDE typedef glitz_gl_void_t (* glitz_gl_enable_t) (glitz_gl_enum_t cap); @@ -500,5 +512,16 @@ typedef glitz_gl_void_t *(* glitz_gl_map_buffer_t) (glitz_gl_enum_t, glitz_gl_enum_t); typedef glitz_gl_boolean_t (* glitz_gl_unmap_buffer_t) (glitz_gl_enum_t); +typedef void (* glitz_gl_gen_framebuffers_t) + (glitz_gl_sizei_t, glitz_gl_uint_t *); +typedef void (* glitz_gl_delete_framebuffers_t) + (glitz_gl_sizei_t, const glitz_gl_uint_t *); +typedef glitz_gl_void_t (* glitz_gl_bind_framebuffer_t) + (glitz_gl_enum_t, glitz_gl_uint_t); +typedef glitz_gl_enum_t (* glitz_gl_check_framebuffer_status_t) + (glitz_gl_enum_t); +typedef void (* glitz_gl_framebuffer_texture_2d_t) + (glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_enum_t, + glitz_gl_uint_t, glitz_gl_int_t); #endif /* GLITZ_GL_H_INCLUDED */ diff --git a/src/glitz_surface.c b/src/glitz_surface.c index e82c016..4e2fad9 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -91,6 +91,8 @@ glitz_surface_create (glitz_drawable_t *drawable, glitz_texture_init (&surface->texture, width, height, drawable->backend->texture_formats[format->id], feature_mask, unnormalized); + + glitz_framebuffer_init (&surface->framebuffer); if (width > 64 || height > 64) { @@ -122,7 +124,11 @@ glitz_surface_destroy (glitz_surface_t *surface) if (surface->texture.name) { glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT); + if (surface->framebuffer.name) + glitz_framebuffer_fini (&surface->drawable->backend->gl, + &surface->framebuffer); glitz_texture_fini (&surface->drawable->backend->gl, &surface->texture); + glitz_surface_pop_current (surface); } @@ -416,40 +422,52 @@ glitz_surface_status_add (glitz_surface_t *surface, static void _glitz_surface_update_state (glitz_surface_t *surface) { - glitz_rectangle_t *viewport; + glitz_drawable_t *drawable; + int width, height; GLITZ_GL_SURFACE (surface); + + if (surface->attached) + { + drawable = surface->attached; + width = drawable->width; + height = drawable->height; + } + else + { + drawable = surface->drawable; + width = surface->texture.width; + height = surface->texture.height; + } - viewport = &surface->attached->viewport; - - if (surface->attached->update_all || - viewport->x != surface->x || - viewport->y != surface->y || - viewport->width != surface->box.x2 || - viewport->height != surface->box.y2) + if (drawable->update_all || + drawable->viewport.x != surface->x || + drawable->viewport.y != surface->y || + drawable->viewport.width != surface->box.x2 || + drawable->viewport.height != surface->box.y2) { gl->viewport (surface->x, - surface->attached->height - surface->y - surface->box.y2, + height - surface->y - surface->box.y2, surface->box.x2, surface->box.y2); gl->matrix_mode (GLITZ_GL_PROJECTION); gl->load_identity (); gl->ortho (0.0, surface->box.x2, - surface->attached->height - surface->box.y2, - surface->attached->height, + height - surface->box.y2, + height, -1.0, 1.0); gl->matrix_mode (GLITZ_GL_MODELVIEW); gl->load_identity (); gl->scale_f (1.0f, -1.0f, 1.0f); - gl->translate_f (0.0f, -surface->attached->height, 0.0f); + gl->translate_f (0.0f, -height, 0.0f); - viewport->x = surface->x; - viewport->y = surface->y; - viewport->width = surface->box.x2; - viewport->height = surface->box.y2; + drawable->viewport.x = surface->x; + drawable->viewport.y = surface->y; + drawable->viewport.width = surface->box.x2; + drawable->viewport.height = surface->box.y2; - surface->attached->update_all = 0; + drawable->update_all = 0; } gl->draw_buffer (surface->buffer); @@ -458,14 +476,6 @@ _glitz_surface_update_state (glitz_surface_t *surface) gl->enable (GLITZ_GL_DITHER); else gl->disable (GLITZ_GL_DITHER); - - if (surface->attached->format->samples > 1) - { - gl->enable (GLITZ_GL_MULTISAMPLE); - if (surface->attached->backend->feature_mask & - GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) - gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST); - } } void @@ -512,6 +522,9 @@ glitz_surface_detach (glitz_surface_t *surface) glitz_drawable_destroy (surface->attached); surface->attached = NULL; + surface->buffer = GLITZ_GL_FRONT; + surface->x = 0; + surface->y = 0; REGION_EMPTY (&surface->drawable_damage); REGION_INIT (&surface->drawable_damage, &surface->box); @@ -535,18 +548,42 @@ glitz_bool_t glitz_surface_push_current (glitz_surface_t *surface, glitz_constraint_t constraint) { - if (surface->attached) { - surface->attached->backend->push_current (surface->attached, surface, - constraint); - if (constraint == GLITZ_DRAWABLE_CURRENT) { - _glitz_surface_update_state (surface); - _glitz_surface_sync_drawable (surface); - } - } else { - surface->drawable->backend->push_current (surface->drawable, NULL, - constraint); - if (constraint == GLITZ_DRAWABLE_CURRENT) - return 0; + if (surface->attached) + { + surface->attached->backend->push_current (surface->attached, + surface, + constraint); + if (constraint == GLITZ_DRAWABLE_CURRENT) + { + if (surface->attached->backend->feature_mask & + GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) + glitz_framebuffer_unbind (&surface->attached->backend->gl); + + _glitz_surface_update_state (surface); + _glitz_surface_sync_drawable (surface); + } + } + else + { + surface->drawable->backend->push_current (surface->drawable, + surface, + constraint); + if (constraint == GLITZ_DRAWABLE_CURRENT) + { + if (surface->drawable->backend->feature_mask & + GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) + { + if (glitz_framebuffer_complete (&surface->attached->backend->gl, + &surface->framebuffer, + &surface->texture)) + { + _glitz_surface_update_state (surface); + return 1; + } + } + + return 0; + } } return 1; @@ -873,3 +910,9 @@ glitz_surface_set_clip_region (glitz_surface_t *surface, } } slim_hidden_def(glitz_surface_set_clip_region); + +glitz_bool_t +glitz_surface_valid_target (glitz_surface_t *surface) +{ + return glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); +} diff --git a/src/glitz_util.c b/src/glitz_util.c index 969c2d3..8486a10 100644 --- a/src/glitz_util.c +++ b/src/glitz_util.c @@ -62,6 +62,7 @@ static glitz_extension_map gl_extensions[] = { { 0.0, "GL_EXT_blend_color", GLITZ_FEATURE_BLEND_COLOR_MASK }, { 0.0, "GL_ARB_imaging", GLITZ_FEATURE_BLEND_COLOR_MASK }, { 0.0, "GL_APPLE_packed_pixels", GLITZ_FEATURE_PACKED_PIXELS_MASK }, + { 0.0, "GL_EXT_framebuffer_object", GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK }, { 0.0, NULL, 0 } }; @@ -253,6 +254,27 @@ _glitz_gl_proc_address_lookup (glitz_backend_t *backend, backend->feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; } } + + if (backend->feature_mask & GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) { + backend->gl.gen_framebuffers = (glitz_gl_gen_framebuffers_t) + get_proc_address ("glGenFramebuffersEXT", closure); + backend->gl.delete_framebuffers = (glitz_gl_delete_framebuffers_t) + get_proc_address ("glDeleteFramebuffersEXT", closure); + backend->gl.bind_framebuffer = (glitz_gl_bind_framebuffer_t) + get_proc_address ("glBindFramebufferEXT", closure); + backend->gl.check_framebuffer_status = + (glitz_gl_check_framebuffer_status_t) + get_proc_address ("glCheckFramebufferStatusEXT", closure); + backend->gl.framebuffer_texture_2d = (glitz_gl_framebuffer_texture_2d_t) + get_proc_address ("glFramebufferTexture2DEXT", closure); + + if ((!backend->gl.gen_framebuffers) || + (!backend->gl.delete_framebuffers) || + (!backend->gl.bind_framebuffer) || + (!backend->gl.check_framebuffer_status) || + (!backend->gl.framebuffer_texture_2d)) + backend->feature_mask &= ~GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK; + } } void diff --git a/src/glitzint.h b/src/glitzint.h index 8c6cb22..f7d404f 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -170,6 +170,11 @@ typedef struct _glitz_gl_proc_address_list_t { glitz_gl_get_buffer_sub_data_t get_buffer_sub_data; glitz_gl_map_buffer_t map_buffer; glitz_gl_unmap_buffer_t unmap_buffer; + glitz_gl_gen_framebuffers_t gen_framebuffers; + glitz_gl_delete_framebuffers_t delete_framebuffers; + glitz_gl_bind_framebuffer_t bind_framebuffer; + glitz_gl_check_framebuffer_status_t check_framebuffer_status; + glitz_gl_framebuffer_texture_2d_t framebuffer_texture_2d; } glitz_gl_proc_address_list_t; typedef int glitz_surface_type_t; @@ -525,6 +530,10 @@ typedef struct _glitz_matrix { glitz_float_t m[16]; } glitz_matrix_t; +typedef struct _glitz_framebuffer { + glitz_gl_uint_t name; +} glitz_framebuffer_t; + #define GLITZ_DAMAGE_TEXTURE_MASK (1 << 0) #define GLITZ_DAMAGE_DRAWABLE_MASK (1 << 1) #define GLITZ_DAMAGE_SOLID_MASK (1 << 2) @@ -559,6 +568,7 @@ struct _glitz_surface { int *primcount; glitz_region_t texture_damage; glitz_region_t drawable_damage; + glitz_framebuffer_t framebuffer; }; #define GLITZ_GL_SURFACE(surface) \ @@ -808,6 +818,22 @@ glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, glitz_box_t *bounds, int damage); +extern void __internal_linkage +glitz_framebuffer_init (glitz_framebuffer_t *framebuffer); + +extern void __internal_linkage +glitz_framebuffer_fini (glitz_gl_proc_address_list_t *gl, + glitz_framebuffer_t *framebuffer); + +extern void __internal_linkage +glitz_framebuffer_unbind (glitz_gl_proc_address_list_t *gl); + +extern glitz_bool_t __internal_linkage +glitz_framebuffer_complete (glitz_gl_proc_address_list_t *gl, + glitz_framebuffer_t *framebuffer, + glitz_texture_t *texture); + + #define MAXSHORT SHRT_MAX #define MINSHORT SHRT_MIN |