summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2005-02-10 01:03:00 +0000
committerDavid Reveman <davidr@novell.com>2005-02-10 01:03:00 +0000
commit39b5acfa12d126d255627059e36a9471d8473103 (patch)
treecea9e45c503187308c2fc330f5c8142fa162d83c /src
parent19a83a4372d737df43c87068409085a962d727bf (diff)
Add preliminary support for EXT_framebuffer_object
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am43
-rw-r--r--src/glitz.h4
-rw-r--r--src/glitz_framebuffer.c74
-rw-r--r--src/glitz_gl.h23
-rw-r--r--src/glitz_surface.c117
-rw-r--r--src/glitz_util.c22
-rw-r--r--src/glitzint.h26
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