This commit is contained in:
vladimir%pobox.com 2005-08-20 05:23:22 +00:00
Родитель ea2799380f
Коммит afb71d6ee3
67 изменённых файлов: 18614 добавлений и 0 удалений

2
gfx/cairo/glitz/AUTHORS Normal file
Просмотреть файл

@ -0,0 +1,2 @@
David Reveman <davidr@novell.com>
Peter Nilsson <c99pnn@cs.umu.se>

22
gfx/cairo/glitz/COPYING Normal file
Просмотреть файл

@ -0,0 +1,22 @@
Copyright © 2004 David Reveman, Peter Nilsson
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 names of
David Reveman and Peter Nilsson not be used in advertising or
publicity pertaining to distribution of the software without
specific, written prior permission. David Reveman and Peter Nilsson
makes no representations about the suitability of this software for
any purpose. It is provided "as is" without express or implied warranty.
DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
PETER NILSSON 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.

21
gfx/cairo/glitz/README Normal file
Просмотреть файл

@ -0,0 +1,21 @@
glitz - OpenGL image compositing library
Glitz is an OpenGL image compositing library. Glitz provides
Porter/Duff compositing of images and implicit mask generation for
geometric primitives including trapezoids, triangles, and rectangles.
The semantics of glitz are designed to precisely match the
specification of the X Render extension. Glitz does not only implement
X Render features like component alpha and image transformations, but
also support for additional features like convolution filters and color
gradients, which are not currently part of the X Render specification.
The performance and capabilities of glitz are much dependent on
graphics hardware. Glitz does not in any way handle software
fall-backs when graphics hardware is insufficient. However, glitz
will report if any requested operation cannot be carried out by
graphics hardware, hence making a higher level software layer
responsible for appropriate actions.
David Reveman
davidr@novell.com

Просмотреть файл

@ -0,0 +1,90 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# mozilla.org
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Vladimir Vukicevic <vladimir@pobox.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = glitz
LIBRARY_NAME = mozglitz
LIBXUL_LIBRARY = 1
REQUIRES = $(NULL)
CSRCS = \
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_context.c \
$(NULL)
EXPORTS = glitz.h
DIRS = $(NULL)
ifdef MOZ_X11
DIRS += glx
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
DIRS += wgl
endif
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
LOCAL_INCLUDES += -I$(srcdir)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,73 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_AGL_H_INCLUDED
#define GLITZ_AGL_H_INCLUDED
#include <glitz.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#include <Carbon/Carbon.h>
/* glitz_agl_info.c */
void
glitz_agl_init (void);
void
glitz_agl_fini (void);
/* glitz_agl_format.c */
glitz_drawable_format_t *
glitz_agl_find_drawable_format (unsigned long mask,
const glitz_drawable_format_t *templ,
int count);
/* glitz_agl_drawable.c */
glitz_drawable_t *
glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format,
WindowRef window,
unsigned int width,
unsigned int height);
glitz_drawable_t *
glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif /* GLITZ_AGL_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,26 @@
.\"
.\"
.de TQ
.br
.ns
.TP
\\$1
..
.TH GLITZ-AGL 3 "Version 1.0"
.SH NAME
GLITZ-AGL \- AGL interface to glitz
.SH SYNOPSIS
.nf
.B #include <glitz-agl.h>
.fi
.SH DESCRIPTION
AGL interface to glitz.
.SH AUTHOR
David Reveman
.SH "SEE ALSO"
.BR GLITZ (3)

Просмотреть файл

@ -0,0 +1,472 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address;
static CFBundleRef
_glitz_agl_get_bundle (const char *name)
{
CFBundleRef bundle = 0;
FSRefParam ref_param;
unsigned char framework_name[256];
framework_name[0] = strlen (name);
strcpy (&framework_name[1], name);
memset (&ref_param, 0, sizeof (ref_param));
if (FindFolder (kSystemDomain,
kFrameworksFolderType,
kDontCreateFolder,
&ref_param.ioVRefNum,
&ref_param.ioDirID) == noErr) {
FSRef ref;
memset (&ref, 0, sizeof (ref));
ref_param.ioNamePtr = framework_name;
ref_param.newRef = &ref;
if (PBMakeFSRefSync (&ref_param) == noErr) {
CFURLRef url;
url = CFURLCreateFromFSRef (kCFAllocatorDefault, &ref);
if (url) {
bundle = CFBundleCreate (kCFAllocatorDefault, url);
CFRelease (url);
if (!CFBundleLoadExecutable (bundle)) {
CFRelease (bundle);
return (CFBundleRef) 0;
}
}
}
}
return bundle;
}
static void
_glitz_agl_release_bundle (CFBundleRef bundle)
{
if (bundle) {
CFBundleUnloadExecutable (bundle);
CFRelease (bundle);
}
}
static glitz_function_pointer_t
_glitz_agl_get_proc_address (const char *name, void *closure)
{
glitz_function_pointer_t address = NULL;
CFBundleRef bundle = (CFBundleRef) closure;
CFStringRef str;
if (bundle) {
str = CFStringCreateWithCString (kCFAllocatorDefault, name,
kCFStringEncodingMacRoman);
address = CFBundleGetFunctionPointerForName (bundle, str);
CFRelease (str);
}
return address;
}
static glitz_context_t *
_glitz_agl_create_context (void *abstract_drawable,
glitz_drawable_format_t *format)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
glitz_agl_thread_info_t *thread_info = drawable->thread_info;
glitz_agl_context_t *context;
context = malloc (sizeof (glitz_agl_context_t));
if (!context)
return NULL;
context->context =
aglCreateContext (thread_info->pixel_formats[format->id],
thread_info->root_context);
_glitz_context_init (&context->base, &drawable->base);
context->pbuffer = 0;
return (glitz_context_t *) context;
}
static void
_glitz_agl_context_destroy (void *abstract_context)
{
glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context;
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *)
context->base.drawable;
if (drawable->thread_info->cctx == &context->base)
{
aglSetCurrentContext (NULL);
drawable->thread_info->cctx = NULL;
}
aglDestroyContext (context->context);
_glitz_context_fini (&context->base);
free (context);
}
static void
_glitz_agl_copy_context (void *abstract_src,
void *abstract_dst,
unsigned long mask)
{
glitz_agl_context_t *src = (glitz_agl_context_t *) abstract_src;
glitz_agl_context_t *dst = (glitz_agl_context_t *) abstract_dst;
aglCopyContext (src->context, dst->context, mask);
}
static void
_glitz_agl_make_current (void *abstract_context,
void *abstract_drawable)
{
glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context;
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
int update = 0;
if (aglGetCurrentContext () != context->context)
{
update = 1;
}
else
{
if (drawable->pbuffer)
{
AGLPbuffer pbuffer;
GLuint unused;
aglGetPBuffer (context->context, &pbuffer,
&unused, &unused, &unused);
if (pbuffer != drawable->pbuffer)
update = 1;
}
else if (drawable->drawable)
{
if (aglGetDrawable (context->context) != drawable->drawable)
update = 1;
}
}
if (update)
{
if (drawable->thread_info->cctx)
{
glitz_context_t *ctx = drawable->thread_info->cctx;
if (ctx->lose_current)
ctx->lose_current (ctx->closure);
}
if (drawable->pbuffer) {
aglSetPBuffer (context->context, drawable->pbuffer, 0, 0,
aglGetVirtualScreen (context->context));
context->pbuffer = 1;
}
else
{
if (context->pbuffer) {
aglSetDrawable (context->context, NULL);
context->pbuffer = 0;
}
aglSetDrawable (context->context, drawable->drawable);
}
aglSetCurrentContext (context->context);
}
drawable->thread_info->cctx = &context->base;
}
static glitz_function_pointer_t
_glitz_agl_context_get_proc_address (void *abstract_context,
const char *name)
{
glitz_agl_context_t *context = (glitz_agl_context_t *) abstract_context;
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *)
context->base.drawable;
glitz_function_pointer_t func;
CFBundleRef bundle;
_glitz_agl_make_current (context, drawable);
bundle = _glitz_agl_get_bundle ("OpenGL.framework");
func = _glitz_agl_get_proc_address (name, (void *) bundle);
_glitz_agl_release_bundle (bundle);
return func;
}
glitz_agl_context_t *
glitz_agl_context_get (glitz_agl_thread_info_t *thread_info,
glitz_drawable_format_t *format)
{
glitz_agl_context_t *context;
glitz_agl_context_t **contexts = thread_info->contexts;
int index, n_contexts = thread_info->n_contexts;
for (; n_contexts; n_contexts--, contexts++)
if ((*contexts)->id == format->id)
return *contexts;
index = thread_info->n_contexts++;
thread_info->contexts =
realloc (thread_info->contexts,
sizeof (glitz_agl_context_t *) * thread_info->n_contexts);
if (!thread_info->contexts)
return NULL;
context = malloc (sizeof (glitz_agl_context_t));
if (!context)
return NULL;
thread_info->contexts[index] = context;
context->context =
aglCreateContext (thread_info->pixel_formats[format->id],
thread_info->root_context);
if (!context->context) {
free (context);
return NULL;
}
context->id = format->id;
context->pbuffer = 0;
if (!thread_info->root_context)
thread_info->root_context = context->context;
memcpy (&context->backend.gl,
&_glitz_agl_gl_proc_address,
sizeof (glitz_gl_proc_address_list_t));
context->backend.create_pbuffer = glitz_agl_create_pbuffer;
context->backend.destroy = glitz_agl_destroy;
context->backend.push_current = glitz_agl_push_current;
context->backend.pop_current = glitz_agl_pop_current;
context->backend.swap_buffers = glitz_agl_swap_buffers;
context->backend.create_context = _glitz_agl_create_context;
context->backend.destroy_context = _glitz_agl_context_destroy;
context->backend.copy_context = _glitz_agl_copy_context;
context->backend.make_current = _glitz_agl_make_current;
context->backend.get_proc_address = _glitz_agl_context_get_proc_address;
context->backend.drawable_formats = thread_info->formats;
context->backend.n_drawable_formats = thread_info->n_formats;
context->backend.texture_formats = NULL;
context->backend.formats = NULL;
context->backend.n_formats = 0;
context->backend.program_map = &thread_info->program_map;
context->backend.feature_mask = 0;
context->initialized = 0;
return context;
}
void
glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info,
glitz_agl_context_t *context)
{
if (context->backend.formats)
free (context->backend.formats);
if (context->backend.texture_formats)
free (context->backend.texture_formats);
aglDestroyContext (context->context);
free (context);
}
static void
_glitz_agl_context_initialize (glitz_agl_thread_info_t *thread_info,
glitz_agl_context_t *context)
{
CFBundleRef bundle;
bundle = _glitz_agl_get_bundle ("OpenGL.framework");
glitz_backend_init (&context->backend,
_glitz_agl_get_proc_address,
(void *) bundle);
_glitz_agl_release_bundle (bundle);
context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
context->max_viewport_dims);
glitz_initiate_state (&_glitz_agl_gl_proc_address);
context->initialized = 1;
}
static void
_glitz_agl_context_make_current (glitz_agl_drawable_t *drawable,
glitz_bool_t finish)
{
if (finish)
glFinish ();
if (drawable->thread_info->cctx)
{
glitz_context_t *ctx = drawable->thread_info->cctx;
if (ctx->lose_current)
ctx->lose_current (ctx->closure);
drawable->thread_info->cctx = NULL;
}
if (drawable->pbuffer) {
aglSetPBuffer (drawable->context->context, drawable->pbuffer, 0, 0,
aglGetVirtualScreen (drawable->context->context));
drawable->context->pbuffer = 1;
} else {
if (drawable->context->pbuffer) {
aglSetDrawable (drawable->context->context, NULL);
drawable->context->pbuffer = 0;
}
aglSetDrawable (drawable->context->context, drawable->drawable);
}
aglSetCurrentContext (drawable->context->context);
drawable->base.update_all = 1;
if (!drawable->context->initialized)
_glitz_agl_context_initialize (drawable->thread_info, drawable->context);
}
static void
_glitz_agl_context_update (glitz_agl_drawable_t *drawable,
glitz_constraint_t constraint)
{
AGLContext context;
switch (constraint) {
case GLITZ_NONE:
break;
case GLITZ_ANY_CONTEXT_CURRENT:
context = aglGetCurrentContext ();
if (context == (AGLContext) 0)
_glitz_agl_context_make_current (drawable, 0);
break;
case GLITZ_CONTEXT_CURRENT:
context = aglGetCurrentContext ();
if (context != drawable->context->context)
_glitz_agl_context_make_current (drawable, (context)? 1: 0);
break;
case GLITZ_DRAWABLE_CURRENT:
context = aglGetCurrentContext ();
if (context != drawable->context->context) {
_glitz_agl_context_make_current (drawable, (context)? 1: 0);
} else {
if (drawable->pbuffer) {
AGLPbuffer pbuffer;
GLuint unused;
aglGetPBuffer (drawable->context->context, &pbuffer,
&unused, &unused, &unused);
if (pbuffer != drawable->pbuffer)
_glitz_agl_context_make_current (drawable, (context)? 1: 0);
} else if (drawable->drawable) {
if (aglGetDrawable (drawable->context->context) != drawable->drawable)
_glitz_agl_context_make_current (drawable, (context)? 1: 0);
}
}
break;
}
}
void
glitz_agl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
glitz_agl_context_info_t *context_info;
int index;
index = drawable->thread_info->context_stack_size++;
context_info = &drawable->thread_info->context_stack[index];
context_info->drawable = drawable;
context_info->surface = surface;
context_info->constraint = constraint;
_glitz_agl_context_update (context_info->drawable, constraint);
}
glitz_surface_t *
glitz_agl_pop_current (void *abstract_drawable)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
glitz_agl_context_info_t *context_info = NULL;
int index;
drawable->thread_info->context_stack_size--;
index = drawable->thread_info->context_stack_size - 1;
context_info = &drawable->thread_info->context_stack[index];
if (context_info->drawable)
_glitz_agl_context_update (context_info->drawable,
context_info->constraint);
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
return context_info->surface;
return NULL;
}

Просмотреть файл

@ -0,0 +1,219 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
static glitz_agl_drawable_t *
_glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info,
glitz_agl_context_t *context,
glitz_drawable_format_t *format,
AGLDrawable agl_drawable,
AGLPbuffer agl_pbuffer,
unsigned int width,
unsigned int height)
{
glitz_agl_drawable_t *drawable;
if (width <= 0 || height <= 0)
return NULL;
drawable = (glitz_agl_drawable_t *) malloc (sizeof (glitz_agl_drawable_t));
if (drawable == NULL)
return NULL;
drawable->base.ref_count = 1;
drawable->thread_info = thread_info;
drawable->context = context;
drawable->drawable = agl_drawable;
drawable->pbuffer = agl_pbuffer;
drawable->base.format = format;
drawable->base.backend = &context->backend;
glitz_drawable_update_size (&drawable->base, width, height);
if (!context->initialized) {
glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_agl_pop_current (drawable);
}
if (width > context->max_viewport_dims[0] ||
height > context->max_viewport_dims[1]) {
free (drawable);
return NULL;
}
thread_info->drawables++;
return drawable;
}
static glitz_drawable_t *
_glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_agl_drawable_t *drawable;
glitz_agl_context_t *context;
AGLPbuffer pbuffer;
if (!format->types.pbuffer)
return NULL;
context = glitz_agl_context_get (thread_info, format);
if (!context)
return NULL;
pbuffer = glitz_agl_pbuffer_create (thread_info, (int) width, (int) height);
if (!pbuffer)
return NULL;
drawable = _glitz_agl_create_drawable (thread_info, context, format,
(AGLDrawable) 0, pbuffer,
width, height);
if (!drawable) {
glitz_agl_pbuffer_destroy (pbuffer);
return NULL;
}
return &drawable->base;
}
glitz_drawable_t *
glitz_agl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_agl_drawable_t *templ = (glitz_agl_drawable_t *) abstract_templ;
return _glitz_agl_create_pbuffer_drawable (templ->thread_info, format,
width, height);
}
glitz_drawable_t *
glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format,
WindowRef window,
unsigned int width,
unsigned int height)
{
glitz_agl_drawable_t *drawable;
glitz_agl_thread_info_t *thread_info;
glitz_agl_context_t *context;
AGLDrawable agl_drawable;
agl_drawable = (AGLDrawable) GetWindowPort (window);
if (!agl_drawable)
return NULL;
thread_info = glitz_agl_thread_info_get ();
if (!thread_info)
return NULL;
context = glitz_agl_context_get (thread_info, format);
if (!context)
return NULL;
drawable = _glitz_agl_create_drawable (thread_info, context, format,
agl_drawable, (AGLPbuffer) 0,
width, height);
if (!drawable)
return NULL;
return &drawable->base;
}
slim_hidden_def(glitz_agl_create_drawable_for_window);
glitz_drawable_t *
glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_agl_thread_info_t *thread_info;
thread_info = glitz_agl_thread_info_get ();
if (!thread_info)
return NULL;
return _glitz_agl_create_pbuffer_drawable (thread_info, format,
width, height);
}
slim_hidden_def(glitz_agl_create_pbuffer_drawable);
void
glitz_agl_destroy (void *abstract_drawable)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
drawable->thread_info->drawables--;
if (drawable->thread_info->drawables == 0) {
/*
* Last drawable? We have to destroy all fragment programs as this may
* be our last chance to have a context current.
*/
glitz_agl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_program_map_fini (&drawable->base.backend->gl,
&drawable->thread_info->program_map);
glitz_agl_pop_current (abstract_drawable);
}
if (drawable->drawable || drawable->pbuffer) {
AGLContext context = aglGetCurrentContext ();
if (context == drawable->context->context) {
if (drawable->pbuffer) {
AGLPbuffer pbuffer;
GLuint unused;
aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused);
if (pbuffer == drawable->pbuffer)
aglSetCurrentContext (NULL);
} else {
if (aglGetDrawable (context) == drawable->drawable)
aglSetCurrentContext (NULL);
}
}
if (drawable->pbuffer)
glitz_agl_pbuffer_destroy (drawable->pbuffer);
}
free (drawable);
}
void
glitz_agl_swap_buffers (void *abstract_drawable)
{
glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable;
glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT);
aglSwapBuffers (drawable->context->context);
glitz_agl_pop_current (abstract_drawable);
}

Просмотреть файл

@ -0,0 +1,92 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
static glitz_extension_map agl_extensions[] = {
{ 0.0, "GL_APPLE_pixel_buffer", GLITZ_AGL_FEATURE_PBUFFER_MASK },
{ 0.0, "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK },
{ 0.0, "GL_ARB_texture_rectangle",
GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, "GL_EXT_texture_rectangle",
GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, "GL_NV_texture_rectangle", GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, NULL, 0 }
};
glitz_status_t
glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info)
{
GLint attrib[] = {
AGL_RGBA,
AGL_NO_RECOVERY,
AGL_NONE
};
AGLPixelFormat pf;
AGLContext context;
thread_info->agl_feature_mask = 0;
pf = aglChoosePixelFormat (NULL, 0, attrib);
context = aglCreateContext (pf, NULL);
if (context) {
const char *gl_extensions_string;
aglSetCurrentContext (context);
gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS);
thread_info->agl_feature_mask =
glitz_extensions_query (0.0,
gl_extensions_string,
agl_extensions);
if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) {
const char *vendor;
vendor = glGetString (GL_VENDOR);
if (vendor) {
/* NVIDIA's driver seem to support multisample with pbuffers */
if (!strncmp ("NVIDIA", vendor, 6))
thread_info->agl_feature_mask |=
GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
}
}
aglSetCurrentContext (NULL);
aglDestroyContext (context);
}
aglDestroyPixelFormat (pf);
return GLITZ_STATUS_SUCCESS;
}

Просмотреть файл

@ -0,0 +1,333 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
#include <stdlib.h>
#include <string.h>
static GLint _attribs[] = {
AGL_RGBA,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_NONE
};
static GLint _db_attribs[] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_NONE
};
static GLint _stencil_attribs[] = {
AGL_RGBA,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_DEPTH_SIZE, 8,
AGL_STENCIL_SIZE, 8,
AGL_NONE
};
static GLint _db_stencil_attribs[] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_NONE
};
static GLint _ms2_attribs[] = {
AGL_RGBA,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 2,
AGL_NONE
};
static GLint _db_ms2_attribs[] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 2,
AGL_NONE
};
static GLint _ms4_attribs[] = {
AGL_RGBA,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 4,
AGL_NONE
};
static GLint _db_ms4_attribs[] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 4,
AGL_NONE
};
static GLint _ms6_attribs[] = {
AGL_RGBA,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 6,
AGL_NONE
};
static GLint _db_ms6_attribs[] = {
AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_ALPHA_SIZE, 16,
AGL_RED_SIZE, 16,
AGL_STENCIL_SIZE, 8,
AGL_SAMPLE_BUFFERS_ARB, 1,
AGL_SAMPLES_ARB, 6,
AGL_NONE
};
static GLint *_attribs_list[] = {
_attribs,
_db_attribs,
_stencil_attribs,
_db_stencil_attribs,
_ms2_attribs,
_db_ms2_attribs,
_ms4_attribs,
_db_ms4_attribs,
_ms6_attribs,
_db_ms6_attribs
};
static int
_glitz_agl_format_compare (const void *elem1,
const void *elem2)
{
int i, score[2];
glitz_drawable_format_t *format[2];
format[0] = (glitz_drawable_format_t *) elem1;
format[1] = (glitz_drawable_format_t *) elem2;
i = score[0] = score[1] = 0;
for (; i < 2; i++) {
if (format[i]->color.red_size) {
if (format[i]->color.red_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.green_size) {
if (format[i]->color.green_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.alpha_size) {
if (format[i]->color.alpha_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->stencil_size)
score[i] += 5;
if (format[i]->depth_size)
score[i] += 5;
if (format[i]->doublebuffer)
score[i] += 10;
if (format[i]->types.window)
score[i] += 10;
if (format[i]->types.pbuffer)
score[i] += 10;
if (format[i]->samples > 1)
score[i] -= (20 - format[i]->samples);
}
return score[1] - score[0];
}
static void
_glitz_add_format (glitz_agl_thread_info_t *thread_info,
glitz_drawable_format_t *format,
AGLPixelFormat pixel_format)
{
if (!glitz_drawable_format_find (thread_info->formats,
thread_info->n_formats,
GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK,
format, 0)) {
int n = thread_info->n_formats;
thread_info->formats =
realloc (thread_info->formats,
sizeof (glitz_drawable_format_t) * (n + 1));
thread_info->pixel_formats =
realloc (thread_info->pixel_formats,
sizeof (AGLPixelFormat) * (n + 1));
if (thread_info->formats && thread_info->pixel_formats) {
thread_info->formats[n] = *format;
thread_info->formats[n].id = n;
thread_info->pixel_formats[n] = pixel_format;
thread_info->n_formats++;
}
}
}
void
glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info)
{
glitz_drawable_format_t format;
AGLPixelFormat pixel_format, *new_pfs;
int n_attribs_list, i;
format.types.window = 1;
format.id = 0;
n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *);
for (i = 0; i < n_attribs_list; i++) {
GLint value;
pixel_format = aglChoosePixelFormat (NULL, 0, _attribs_list[i]);
/* Stereo is not supported yet */
if (!(aglDescribePixelFormat (pixel_format, AGL_STEREO, &value)) ||
value) {
aglDestroyPixelFormat (pixel_format);
continue;
}
aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value);
format.doublebuffer = (value)? 1: 0;
aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value);
format.color.red_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value);
format.color.green_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value);
format.color.blue_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value);
format.color.alpha_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value);
format.depth_size = (unsigned short) value;
aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value);
format.stencil_size = (unsigned short) value;
if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) {
aglDescribePixelFormat (pixel_format, AGL_SAMPLE_BUFFERS_ARB, &value);
if (value) {
aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value);
format.samples = (unsigned short) (value > 1)? value: 1;
} else
format.samples = 1;
} else
format.samples = 1;
if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) {
if (format.color.red_size && format.color.green_size &&
format.color.blue_size && format.color.alpha_size &&
format.doublebuffer == 0 && format.stencil_size == 0 &&
format.depth_size == 0) {
if (thread_info->agl_feature_mask &
GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK)
format.types.pbuffer = 1;
else if (format.samples == 1)
format.types.pbuffer = 1;
else
format.types.pbuffer = 0;
} else
format.types.pbuffer = 0;
} else
format.types.pbuffer = 0;
if (format.color.red_size ||
format.color.green_size ||
format.color.blue_size ||
format.color.alpha_size)
_glitz_add_format (thread_info, &format, pixel_format);
}
if (!thread_info->n_formats)
return;
qsort (thread_info->formats, thread_info->n_formats,
sizeof (glitz_drawable_format_t), _glitz_agl_format_compare);
/*
* Update AGLPixelFormat list so that it matches the sorted format list.
*/
new_pfs = malloc (sizeof (AGLPixelFormat) * thread_info->n_formats);
if (!new_pfs) {
thread_info->n_formats = 0;
return;
}
for (i = 0; i < thread_info->n_formats; i++) {
new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].id];
thread_info->formats[i].id = i;
}
free (thread_info->pixel_formats);
thread_info->pixel_formats = new_pfs;
}
glitz_drawable_format_t *
glitz_agl_find_drawable_format (unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get ();
return glitz_drawable_format_find (thread_info->formats,
thread_info->n_formats,
mask, templ, count);
}
slim_hidden_def(glitz_agl_find_drawable_format);

Просмотреть файл

@ -0,0 +1,269 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
#include <OpenGL/glext.h>
glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = {
/* core */
(glitz_gl_enable_t) glEnable,
(glitz_gl_disable_t) glDisable,
(glitz_gl_get_error_t) glGetError,
(glitz_gl_get_string_t) glGetString,
(glitz_gl_enable_client_state_t) glEnableClientState,
(glitz_gl_disable_client_state_t) glDisableClientState,
(glitz_gl_vertex_pointer_t) glVertexPointer,
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
(glitz_gl_draw_arrays_t) glDrawArrays,
(glitz_gl_tex_env_f_t) glTexEnvf,
(glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_gen_i_t) glTexGeni,
(glitz_gl_tex_gen_fv_t) glTexGenfv,
(glitz_gl_color_4us_t) glColor4us,
(glitz_gl_color_4f_t) glColor4f,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
(glitz_gl_clear_color_t) glClearColor,
(glitz_gl_clear_stencil_t) glClearStencil,
(glitz_gl_stencil_func_t) glStencilFunc,
(glitz_gl_stencil_op_t) glStencilOp,
(glitz_gl_push_attrib_t) glPushAttrib,
(glitz_gl_pop_attrib_t) glPopAttrib,
(glitz_gl_matrix_mode_t) glMatrixMode,
(glitz_gl_push_matrix_t) glPushMatrix,
(glitz_gl_pop_matrix_t) glPopMatrix,
(glitz_gl_load_identity_t) glLoadIdentity,
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
(glitz_gl_depth_range_t) glDepthRange,
(glitz_gl_viewport_t) glViewport,
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
(glitz_gl_bitmap_t) glBitmap,
(glitz_gl_read_buffer_t) glReadBuffer,
(glitz_gl_draw_buffer_t) glDrawBuffer,
(glitz_gl_copy_pixels_t) glCopyPixels,
(glitz_gl_flush_t) glFlush,
(glitz_gl_finish_t) glFinish,
(glitz_gl_pixel_store_i_t) glPixelStorei,
(glitz_gl_ortho_t) glOrtho,
(glitz_gl_scale_f_t) glScalef,
(glitz_gl_translate_f_t) glTranslatef,
(glitz_gl_hint_t) glHint,
(glitz_gl_depth_mask_t) glDepthMask,
(glitz_gl_polygon_mode_t) glPolygonMode,
(glitz_gl_shade_model_t) glShadeModel,
(glitz_gl_color_mask_t) glColorMask,
(glitz_gl_read_pixels_t) glReadPixels,
(glitz_gl_get_tex_image_t) glGetTexImage,
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
(glitz_gl_gen_textures_t) glGenTextures,
(glitz_gl_delete_textures_t) glDeleteTextures,
(glitz_gl_bind_texture_t) glBindTexture,
(glitz_gl_tex_image_2d_t) glTexImage2D,
(glitz_gl_tex_parameter_i_t) glTexParameteri,
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
(glitz_gl_get_integer_v_t) glGetIntegerv,
/* extensions */
(glitz_gl_blend_color_t) 0,
(glitz_gl_active_texture_t) 0,
(glitz_gl_client_active_texture_t) 0,
(glitz_gl_multi_draw_arrays_t) 0,
(glitz_gl_gen_programs_t) 0,
(glitz_gl_delete_programs_t) 0,
(glitz_gl_program_string_t) 0,
(glitz_gl_bind_program_t) 0,
(glitz_gl_program_local_param_4fv_t) 0,
(glitz_gl_get_program_iv_t) 0,
(glitz_gl_gen_buffers_t) 0,
(glitz_gl_delete_buffers_t) 0,
(glitz_gl_bind_buffer_t) 0,
(glitz_gl_buffer_data_t) 0,
(glitz_gl_buffer_sub_data_t) 0,
(glitz_gl_get_buffer_sub_data_t) 0,
(glitz_gl_map_buffer_t) 0,
(glitz_gl_unmap_buffer_t) 0
};
static void
glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info);
static void
glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info);
#ifdef PTHREADS
#include <pthread.h>
#include <stdlib.h>
/* thread safe */
static int tsd_initialized = 0;
static pthread_key_t info_tsd;
static void
glitz_agl_thread_info_destroy (glitz_agl_thread_info_t *thread_info)
{
pthread_setspecific (info_tsd, NULL);
if (thread_info) {
glitz_agl_thread_info_fini (thread_info);
free (thread_info);
}
}
static void
_tsd_destroy (void *p)
{
if (p) {
glitz_agl_thread_info_fini ((glitz_agl_thread_info_t *) p);
free (p);
}
}
glitz_agl_thread_info_t *
glitz_agl_thread_info_get (void)
{
glitz_agl_thread_info_t *thread_info;
void *p;
if (!tsd_initialized) {
pthread_key_create (&info_tsd, _tsd_destroy);
tsd_initialized = 1;
}
p = pthread_getspecific (info_tsd);
if (p == NULL) {
thread_info = malloc (sizeof (glitz_agl_thread_info_t));
glitz_agl_thread_info_init (thread_info);
pthread_setspecific (info_tsd, thread_info);
} else
thread_info = (glitz_agl_thread_info_t *) p;
return thread_info;
}
#else
/* not thread safe */
static glitz_agl_thread_info_t _thread_info = {
0,
NULL,
NULL,
0,
NULL,
0,
{ 0 },
0,
NULL,
0,
NULL,
{ 0 }
};
static void
glitz_agl_thread_info_destroy (glitz_agl_thread_info_t *thread_info)
{
if (thread_info)
glitz_agl_thread_info_fini (thread_info);
}
glitz_agl_thread_info_t *
glitz_agl_thread_info_get (void)
{
if (_thread_info.context_stack_size == 0)
glitz_agl_thread_info_init (&_thread_info);
return &_thread_info;
}
#endif
static void
glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info)
{
thread_info->formats = NULL;
thread_info->pixel_formats = (AGLPixelFormat *) 0;
thread_info->n_formats = 0;
thread_info->contexts = NULL;
thread_info->n_contexts = 0;
thread_info->context_stack_size = 1;
thread_info->context_stack->surface = NULL;
thread_info->context_stack->constraint = GLITZ_NONE;
thread_info->root_context = NULL;
thread_info->agl_feature_mask = 0;
thread_info->cctx = NULL;
glitz_program_map_init (&thread_info->program_map);
if (!glitz_agl_query_extensions (thread_info))
glitz_agl_query_formats (thread_info);
}
static void
glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info)
{
int i;
for (i = 0; i < thread_info->n_contexts; i++)
glitz_agl_context_destroy (thread_info, thread_info->contexts[i]);
for (i = 0; i < thread_info->n_formats; i++)
aglDestroyPixelFormat (thread_info->pixel_formats[i]);
if (thread_info->formats)
free (thread_info->formats);
if (thread_info->pixel_formats)
free (thread_info->pixel_formats);
}
void
glitz_agl_init (void)
{
glitz_agl_thread_info_get ();
}
slim_hidden_def(glitz_agl_init);
void
glitz_agl_fini (void)
{
glitz_agl_thread_info_t *info = glitz_agl_thread_info_get ();
glitz_agl_thread_info_destroy (info);
}
slim_hidden_def(glitz_agl_fini);

Просмотреть файл

@ -0,0 +1,58 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_aglint.h"
AGLPbuffer
glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info,
int width,
int height)
{
AGLPbuffer pbuffer;
glitz_gl_enum_t target;
if (!POWER_OF_TWO (width) || !POWER_OF_TWO (height)) {
if (thread_info->agl_feature_mask &
GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK)
target = GLITZ_GL_TEXTURE_RECTANGLE;
else
return (AGLPbuffer) 0;
} else
target = GLITZ_GL_TEXTURE_2D;
aglCreatePBuffer (width, height, target, GLITZ_GL_RGBA, 0, &pbuffer);
return pbuffer;
}
void
glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer)
{
aglDestroyPBuffer (pbuffer);
}

Просмотреть файл

@ -0,0 +1,142 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_GLXINT_H_INCLUDED
#define GLITZ_GLXINT_H_INCLUDED
#include "glitz.h"
#include "glitzint.h"
#include "glitz-agl.h"
#include <OpenGL/gl.h>
#include <Carbon/Carbon.h>
#include <AGL/agl.h>
#define GLITZ_AGL_FEATURE_PBUFFER_MASK (1L << 0)
#define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 1)
#define GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 2)
#define GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 3)
typedef struct _glitz_agl_drawable glitz_agl_drawable_t;
typedef struct _glitz_agl_context_info_t {
glitz_agl_drawable_t *drawable;
glitz_surface_t *surface;
glitz_constraint_t constraint;
} glitz_agl_context_info_t;
typedef struct _glitz_agl_context_t {
glitz_context_t base;
AGLContext context;
glitz_format_id_t id;
AGLPixelFormat pixel_format;
glitz_bool_t pbuffer;
glitz_backend_t backend;
glitz_gl_int_t max_viewport_dims[2];
glitz_gl_int_t max_texture_2d_size;
glitz_gl_int_t max_texture_rect_size;
glitz_bool_t initialized;
} glitz_agl_context_t;
typedef struct _glitz_agl_thread_info_t {
int drawables;
glitz_drawable_format_t *formats;
AGLPixelFormat *pixel_formats;
int n_formats;
glitz_agl_context_t **contexts;
int n_contexts;
glitz_agl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE];
int context_stack_size;
AGLContext root_context;
unsigned long agl_feature_mask;
glitz_context_t *cctx;
glitz_program_map_t program_map;
} glitz_agl_thread_info_t;
struct _glitz_agl_drawable {
glitz_drawable_t base;
glitz_agl_thread_info_t *thread_info;
glitz_agl_context_t *context;
AGLDrawable drawable;
AGLPbuffer pbuffer;
WindowRef window;
};
extern glitz_status_t __internal_linkage
glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info);
extern glitz_agl_thread_info_t __internal_linkage *
glitz_agl_thread_info_get (void);
extern glitz_agl_context_t __internal_linkage *
glitz_agl_context_get (glitz_agl_thread_info_t *thread_info,
glitz_drawable_format_t *format);
extern void __internal_linkage
glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info,
glitz_agl_context_t *context);
extern void __internal_linkage
glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info);
extern AGLPbuffer __internal_linkage
glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info,
int width,
int height);
extern void __internal_linkage
glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer);
extern glitz_drawable_t __internal_linkage *
glitz_agl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
extern void __internal_linkage
glitz_agl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint);
extern glitz_surface_t __internal_linkage *
glitz_agl_pop_current (void *abstract_drawable);
extern void __internal_linkage
glitz_agl_destroy (void *abstract_drawable);
extern void __internal_linkage
glitz_agl_swap_buffers (void *abstract_drawable);
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(glitz_agl_init)
slim_hidden_proto(glitz_agl_fini)
slim_hidden_proto(glitz_agl_find_drawable_format)
slim_hidden_proto(glitz_agl_create_drawable_for_window)
slim_hidden_proto(glitz_agl_create_pbuffer_drawable)
#endif /* GLITZ_GLXINT_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,78 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_EGL_H_INCLUDED
#define GLITZ_EGL_H_INCLUDED
#include <GL/gl.h>
#include <GLES/egl.h>
#include <glitz.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/* glitz_egl_info.c */
void
glitz_egl_init (const char *gl_library);
void
glitz_egl_fini (void);
/* glitz_egl_config.c */
glitz_drawable_format_t *
glitz_egl_find_config (EGLDisplay egl_display,
EGLScreenMESA egl_screen,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count);
/* glitz_egl_surface.c */
glitz_drawable_t *
glitz_egl_create_surface (EGLDisplay egl_display,
EGLScreenMESA egl_screen,
glitz_drawable_format_t *format,
EGLSurface egl_surface,
unsigned int width,
unsigned int height);
glitz_drawable_t *
glitz_egl_create_pbuffer_surface (EGLDisplay egl_display,
EGLScreenMESA egl_screen,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif /* GLITZ_EGL_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,27 @@
.\"
.\"
.de TQ
.br
.ns
.TP
\\$1
..
.TH GLITZ-EGL 3 "Version 1.0"
.SH NAME
GLITZ-EGL \- EGL interface to glitz
.SH SYNOPSIS
.nf
.B #include <glitz-egl.h>
.fi
.SH DESCRIPTION
EGL interface to glitz.
.SH AUTHOR
David Reveman
Jon Smirl
.SH "SEE ALSO"
.BR GLITZ (3)

Просмотреть файл

@ -0,0 +1,221 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
#include <stdlib.h>
#include <string.h>
static int
_glitz_egl_format_compare (const void *elem1,
const void *elem2)
{
int i, score[2];
glitz_drawable_format_t *format[2];
format[0] = (glitz_drawable_format_t *) elem1;
format[1] = (glitz_drawable_format_t *) elem2;
i = score[0] = score[1] = 0;
for (; i < 2; i++) {
if (format[i]->color.red_size) {
if (format[i]->color.red_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.green_size) {
if (format[i]->color.green_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.alpha_size) {
if (format[i]->color.alpha_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->stencil_size)
score[i] += 5;
if (format[i]->depth_size)
score[i] += 5;
if (format[i]->doublebuffer)
score[i] += 10;
if (format[i]->types.window)
score[i] += 10;
if (format[i]->types.pbuffer)
score[i] += 10;
if (format[i]->samples > 1)
score[i] -= (20 - format[i]->samples);
}
return score[1] - score[0];
}
static void
_glitz_add_format (glitz_egl_screen_info_t *screen_info,
glitz_drawable_format_t *format,
EGLConfig egl_id)
{
if (!glitz_drawable_format_find (screen_info->formats,
screen_info->n_formats,
GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK,
format, 0)) {
int n = screen_info->n_formats;
screen_info->formats =
realloc (screen_info->formats,
sizeof (glitz_drawable_format_t) * (n + 1));
screen_info->egl_config_ids =
realloc (screen_info->egl_config_ids, sizeof (EGLConfig) * (n + 1));
if (screen_info->formats && screen_info->egl_config_ids) {
screen_info->formats[n] = *format;
screen_info->formats[n].id = n;
screen_info->egl_config_ids[n] = egl_id;
screen_info->n_formats++;
}
}
}
static glitz_status_t
_glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info)
{
EGLDisplay egl_display;
glitz_drawable_format_t format;
EGLConfig *egl_configs;
int i, num_configs;
EGLConfig egl_id;
egl_display = screen_info->display_info->egl_display;
eglGetConfigs(egl_display, NULL, 0, &num_configs);
egl_configs = malloc(sizeof(*egl_configs) * num_configs);
eglGetConfigs(egl_display, egl_configs, num_configs, &num_configs);
for (i = 0; i < num_configs; i++) {
int value;
eglGetConfigAttrib(egl_display, egl_configs[i],
EGL_SURFACE_TYPE, &value);
if (!((value & EGL_WINDOW_BIT) || (value & EGL_PBUFFER_BIT)))
continue;
format.types.window = (value & EGL_WINDOW_BIT)? 1: 0;
format.types.pbuffer = (value & EGL_PBUFFER_BIT)? 1: 0;
format.id = 0;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_CONFIG_ID, &value);
egl_id = (EGLConfig) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_RED_SIZE, &value);
format.color.red_size = (unsigned short) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_GREEN_SIZE, &value);
format.color.green_size = (unsigned short) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_BLUE_SIZE, &value);
format.color.blue_size = (unsigned short) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_ALPHA_SIZE, &value);
format.color.alpha_size = (unsigned short) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_DEPTH_SIZE, &value);
format.depth_size = (unsigned short) value;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_STENCIL_SIZE, &value);
format.stencil_size = (unsigned short) value;
format.doublebuffer = 1;
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLE_BUFFERS, &value);
if (value) {
eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLES, &value);
format.samples = (unsigned short) (value > 1)? value: 1;
if (format.samples > 1)
format.types.pbuffer = 0;
} else
format.samples = 1;
_glitz_add_format (screen_info, &format, egl_id);
}
free(egl_configs);
return GLITZ_STATUS_SUCCESS;
}
void
glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info)
{
EGLConfig *egl_new_ids;
int i;
_glitz_egl_query_configs (screen_info);
if (!screen_info->n_formats)
return;
qsort (screen_info->formats, screen_info->n_formats,
sizeof (glitz_drawable_format_t), _glitz_egl_format_compare);
/*
* Update XID list so that it matches the sorted format list.
*/
egl_new_ids = malloc (sizeof (EGLConfig) * screen_info->n_formats);
if (!egl_new_ids) {
screen_info->n_formats = 0;
return;
}
for (i = 0; i < screen_info->n_formats; i++) {
egl_new_ids[i] = screen_info->egl_config_ids[screen_info->formats[i].id];
screen_info->formats[i].id = i;
}
free (screen_info->egl_config_ids);
screen_info->egl_config_ids = egl_new_ids;
}
glitz_drawable_format_t *
glitz_egl_find_config (EGLDisplay egl_display,
EGLScreenMESA egl_screen,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
glitz_egl_screen_info_t *screen_info =
glitz_egl_screen_info_get (egl_display, egl_screen);
return glitz_drawable_format_find (screen_info->formats,
screen_info->n_formats,
mask, templ, count);
}
slim_hidden_def(glitz_egl_find_config);

Просмотреть файл

@ -0,0 +1,357 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
#include <stdlib.h>
extern glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address;
static void
_glitz_egl_context_create (glitz_egl_screen_info_t *screen_info,
EGLConfig egl_config,
EGLContext egl_share_list,
glitz_egl_context_t *context)
{
context->id = egl_config;
context->egl_context = eglCreateContext (screen_info->display_info->egl_display,
egl_config, egl_share_list, NULL);
}
static glitz_context_t *
_glitz_egl_create_context (void *abstract_drawable,
glitz_drawable_format_t *format)
{
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
glitz_egl_screen_info_t *screen_info = drawable->screen_info;
int format_id = screen_info->egl_config_ids[format->id];
glitz_egl_context_t *context;
context = malloc (sizeof (glitz_egl_context_t));
if (!context)
return NULL;
_glitz_context_init (&context->base, &drawable->base);
_glitz_egl_context_create (screen_info,
format_id,
screen_info->egl_root_context,
context);
return (glitz_context_t *) context;
}
static void
_glitz_egl_context_destroy (void *abstract_context)
{
glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
context->base.drawable;
if (drawable->screen_info->display_info->thread_info->cctx == &context->base)
{
eglMakeCurrent (drawable->screen_info->display_info->egl_display,
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
drawable->screen_info->display_info->thread_info->cctx = NULL;
}
eglDestroyContext (drawable->screen_info->display_info->egl_display,
context->egl_context);
_glitz_context_fini (&context->base);
free (context);
}
static void
_glitz_egl_copy_context (void *abstract_src,
void *abstract_dst,
unsigned long mask)
{
glitz_egl_context_t *src = (glitz_egl_context_t *) abstract_src;
glitz_egl_context_t *dst = (glitz_egl_context_t *) abstract_dst;
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
src->base.drawable;
eglCopyContextMESA (drawable->screen_info->display_info->egl_display,
src->egl_context, dst->egl_context, mask);
}
static void
_glitz_egl_make_current (void *abstract_context,
void *abstract_drawable)
{
glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
glitz_egl_display_info_t *display_info = drawable->screen_info->display_info;
if ((eglGetCurrentContext () != context->egl_context) ||
(eglGetCurrentSurface ( 0 ) != drawable->egl_surface))
eglMakeCurrent (display_info->egl_display, drawable->egl_surface,
drawable->egl_surface, context->egl_context);
display_info->thread_info->cctx = &context->base;
}
static glitz_function_pointer_t
_glitz_egl_context_get_proc_address (void *abstract_context,
const char *name)
{
glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
context->base.drawable;
_glitz_egl_make_current (context, drawable);
return glitz_egl_get_proc_address (name, drawable->screen_info);
}
glitz_egl_context_t *
glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
glitz_drawable_format_t *format)
{
glitz_egl_context_t *context;
glitz_egl_context_t **contexts = screen_info->contexts;
int index, n_contexts = screen_info->n_contexts;
EGLConfig egl_config_id;
for (; n_contexts; n_contexts--, contexts++)
if ((*contexts)->id == screen_info->egl_config_ids[format->id])
return *contexts;
index = screen_info->n_contexts++;
screen_info->contexts =
realloc (screen_info->contexts,
sizeof (glitz_egl_context_t *) * screen_info->n_contexts);
if (!screen_info->contexts)
return NULL;
context = malloc (sizeof (glitz_egl_context_t));
if (!context)
return NULL;
screen_info->contexts[index] = context;
egl_config_id = screen_info->egl_config_ids[format->id];
_glitz_egl_context_create (screen_info,
egl_config_id,
screen_info->egl_root_context,
context);
if (!screen_info->egl_root_context)
screen_info->egl_root_context = context->egl_context;
memcpy (&context->backend.gl,
&_glitz_egl_gl_proc_address,
sizeof (glitz_gl_proc_address_list_t));
context->backend.create_pbuffer = glitz_egl_create_pbuffer;
context->backend.destroy = glitz_egl_destroy;
context->backend.push_current = glitz_egl_push_current;
context->backend.pop_current = glitz_egl_pop_current;
context->backend.swap_buffers = glitz_egl_swap_buffers;
context->backend.create_context = _glitz_egl_create_context;
context->backend.destroy_context = _glitz_egl_context_destroy;
context->backend.copy_context = _glitz_egl_copy_context;
context->backend.make_current = _glitz_egl_make_current;
context->backend.get_proc_address = _glitz_egl_context_get_proc_address;
context->backend.drawable_formats = screen_info->formats;
context->backend.n_drawable_formats = screen_info->n_formats;
context->backend.texture_formats = NULL;
context->backend.formats = NULL;
context->backend.n_formats = 0;
context->backend.program_map = &screen_info->program_map;
context->backend.feature_mask = 0;
context->initialized = 0;
return context;
}
void
glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info,
glitz_egl_context_t *context)
{
if (context->backend.formats)
free (context->backend.formats);
if (context->backend.texture_formats)
free (context->backend.texture_formats);
eglDestroyContext (screen_info->display_info->egl_display,
context->egl_context);
free (context);
}
static void
_glitz_egl_context_initialize (glitz_egl_screen_info_t *screen_info,
glitz_egl_context_t *context)
{
const char *version;
glitz_backend_init (&context->backend,
glitz_egl_get_proc_address,
(void *) screen_info);
context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
context->max_viewport_dims);
glitz_initiate_state (&_glitz_egl_gl_proc_address);
version = (const char *) context->backend.gl.get_string (GLITZ_GL_VERSION);
if (version)
{
/* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures when
using nvidia's binary driver. Seems like a driver issue, but I'm not
sure yet. Turning of NPOT GL_TEXTURE_2D textures until this have been
solved. */
if (strstr (version, "NVIDIA 61.11") ||
strstr (version, "NVIDIA 66.29"))
{
context->backend.feature_mask &=
~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK;
}
}
context->initialized = 1;
}
static void
_glitz_egl_context_make_current (glitz_egl_surface_t *drawable,
glitz_bool_t finish)
{
glitz_egl_display_info_t *display_info = drawable->screen_info->display_info;
if (finish)
glFinish ();
if (display_info->thread_info->cctx)
{
glitz_context_t *ctx = display_info->thread_info->cctx;
if (ctx->lose_current)
ctx->lose_current (ctx->closure);
display_info->thread_info->cctx = NULL;
}
eglMakeCurrent (display_info->egl_display,
drawable->egl_surface, drawable->egl_surface,
drawable->context->egl_context);
drawable->base.update_all = 1;
if (!drawable->context->initialized)
_glitz_egl_context_initialize (drawable->screen_info, drawable->context);
}
static void
_glitz_egl_context_update (glitz_egl_surface_t *drawable,
glitz_constraint_t constraint)
{
EGLContext egl_context;
switch (constraint) {
case GLITZ_NONE:
break;
case GLITZ_ANY_CONTEXT_CURRENT: {
glitz_egl_display_info_t *dinfo = drawable->screen_info->display_info;
if (dinfo->thread_info->cctx)
{
_glitz_egl_context_make_current (drawable, 0);
}
else
{
egl_context = eglGetCurrentContext ();
if (egl_context == (EGLContext) 0)
_glitz_egl_context_make_current (drawable, 0);
}
} break;
case GLITZ_CONTEXT_CURRENT:
egl_context = eglGetCurrentContext ();
if (egl_context != drawable->context->egl_context)
_glitz_egl_context_make_current (drawable, (egl_context)? 1: 0);
break;
case GLITZ_DRAWABLE_CURRENT:
egl_context = eglGetCurrentContext ();
if ((egl_context != drawable->context->egl_context) ||
(eglGetCurrentSurface ( 0 ) != drawable->egl_surface))
_glitz_egl_context_make_current (drawable, (egl_context)? 1: 0);
break;
}
}
void
glitz_egl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint)
{
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
glitz_egl_context_info_t *context_info;
int index;
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
context_info->drawable = drawable;
context_info->surface = surface;
context_info->constraint = constraint;
_glitz_egl_context_update (context_info->drawable, constraint);
}
glitz_surface_t *
glitz_egl_pop_current (void *abstract_drawable)
{
glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
glitz_egl_context_info_t *context_info = NULL;
int index;
drawable->screen_info->context_stack_size--;
index = drawable->screen_info->context_stack_size - 1;
context_info = &drawable->screen_info->context_stack[index];
if (context_info->drawable)
_glitz_egl_context_update (context_info->drawable,
context_info->constraint);
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
return context_info->surface;
return NULL;
}

Просмотреть файл

@ -0,0 +1,74 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
#if 0
static glitz_extension_map egl_extensions[] = {
{ 0.0, "EGL_SGIX_fbconfig", GLITZ_EGL_FEATURE_FBCONFIG_MASK },
{ 0.0, "EGL_SGIX_pbuffer", GLITZ_EGL_FEATURE_PBUFFER_MASK },
{ 0.0, "EGL_SGI_make_current_read",
GLITZ_EGL_FEATURE_MAKE_CURRENT_READ_MASK },
{ 0.0, "EGL_ARB_multisample", GLITZ_EGL_FEATURE_MULTISAMPLE_MASK },
{ 0.0, NULL, 0 }
};
#endif
void
glitz_egl_query_extensions (glitz_egl_screen_info_t *screen_info,
glitz_gl_float_t egl_version)
{
#if 0
const char *egl_extensions_string;
egl_extensions_string =
eglQueryExtensionsString (screen_info->display_info->display,
screen_info->screen);
screen_info->egl_feature_mask =
glitz_extensions_query (egl_version,
egl_extensions_string,
egl_extensions);
if (screen_info->egl_feature_mask & GLITZ_EGL_FEATURE_MULTISAMPLE_MASK) {
const char *vendor;
vendor = eglGetClientString (screen_info->display_info->display,
EGL_VENDOR);
if (vendor) {
/* NVIDIA's driver seem to support multisample with pbuffers */
if (!strncmp ("NVIDIA", vendor, 6))
screen_info->egl_feature_mask |=
GLITZ_EGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
}
}
#endif
}

Просмотреть файл

@ -0,0 +1,432 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
#include <pthread.h>
#include <string.h>
#include <dlfcn.h>
glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address = {
/* core */
(glitz_gl_enable_t) glEnable,
(glitz_gl_disable_t) glDisable,
(glitz_gl_get_error_t) glGetError,
(glitz_gl_get_string_t) glGetString,
(glitz_gl_enable_client_state_t) glEnableClientState,
(glitz_gl_disable_client_state_t) glDisableClientState,
(glitz_gl_vertex_pointer_t) glVertexPointer,
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
(glitz_gl_draw_arrays_t) glDrawArrays,
(glitz_gl_tex_env_f_t) glTexEnvf,
(glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_gen_i_t) glTexGeni,
(glitz_gl_tex_gen_fv_t) glTexGenfv,
(glitz_gl_color_4us_t) glColor4us,
(glitz_gl_color_4f_t) glColor4f,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
(glitz_gl_clear_color_t) glClearColor,
(glitz_gl_clear_stencil_t) glClearStencil,
(glitz_gl_stencil_func_t) glStencilFunc,
(glitz_gl_stencil_op_t) glStencilOp,
(glitz_gl_push_attrib_t) glPushAttrib,
(glitz_gl_pop_attrib_t) glPopAttrib,
(glitz_gl_matrix_mode_t) glMatrixMode,
(glitz_gl_push_matrix_t) glPushMatrix,
(glitz_gl_pop_matrix_t) glPopMatrix,
(glitz_gl_load_identity_t) glLoadIdentity,
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
(glitz_gl_depth_range_t) glDepthRange,
(glitz_gl_viewport_t) glViewport,
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
(glitz_gl_bitmap_t) glBitmap,
(glitz_gl_read_buffer_t) glReadBuffer,
(glitz_gl_draw_buffer_t) glDrawBuffer,
(glitz_gl_copy_pixels_t) glCopyPixels,
(glitz_gl_flush_t) glFlush,
(glitz_gl_finish_t) glFinish,
(glitz_gl_pixel_store_i_t) glPixelStorei,
(glitz_gl_ortho_t) glOrtho,
(glitz_gl_scale_f_t) glScalef,
(glitz_gl_translate_f_t) glTranslatef,
(glitz_gl_hint_t) glHint,
(glitz_gl_depth_mask_t) glDepthMask,
(glitz_gl_polygon_mode_t) glPolygonMode,
(glitz_gl_shade_model_t) glShadeModel,
(glitz_gl_color_mask_t) glColorMask,
(glitz_gl_read_pixels_t) glReadPixels,
(glitz_gl_get_tex_image_t) glGetTexImage,
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
(glitz_gl_gen_textures_t) glGenTextures,
(glitz_gl_delete_textures_t) glDeleteTextures,
(glitz_gl_bind_texture_t) glBindTexture,
(glitz_gl_tex_image_2d_t) glTexImage2D,
(glitz_gl_tex_parameter_i_t) glTexParameteri,
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
(glitz_gl_get_integer_v_t) glGetIntegerv,
/* extensions */
(glitz_gl_blend_color_t) 0,
(glitz_gl_active_texture_t) 0,
(glitz_gl_client_active_texture_t) 0,
(glitz_gl_multi_draw_arrays_t) 0,
(glitz_gl_gen_programs_t) 0,
(glitz_gl_delete_programs_t) 0,
(glitz_gl_program_string_t) 0,
(glitz_gl_bind_program_t) 0,
(glitz_gl_program_local_param_4fv_t) 0,
(glitz_gl_get_program_iv_t) 0,
(glitz_gl_gen_buffers_t) 0,
(glitz_gl_delete_buffers_t) 0,
(glitz_gl_bind_buffer_t) 0,
(glitz_gl_buffer_data_t) 0,
(glitz_gl_buffer_sub_data_t) 0,
(glitz_gl_get_buffer_sub_data_t) 0,
(glitz_gl_map_buffer_t) 0,
(glitz_gl_unmap_buffer_t) 0
};
glitz_function_pointer_t
glitz_egl_get_proc_address (const char *name,
void *closure)
{
glitz_egl_screen_info_t *screen_info = (glitz_egl_screen_info_t *) closure;
glitz_egl_thread_info_t *info = screen_info->display_info->thread_info;
glitz_function_pointer_t address = NULL;
if (screen_info->egl_feature_mask & GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK)
address = eglGetProcAddress ((char *) name);
if (!address) {
if (!info->dlhand)
info->dlhand = dlopen (info->gl_library, RTLD_LAZY);
if (info->dlhand) {
dlerror ();
address = (glitz_function_pointer_t) dlsym (info->dlhand, name);
if (dlerror () != NULL)
address = NULL;
}
}
return address;
}
static void
_glitz_egl_display_destroy (glitz_egl_display_info_t *display_info);
static void
_glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info);
static void
_glitz_egl_thread_info_fini (glitz_egl_thread_info_t *thread_info)
{
int i;
for (i = 0; i < thread_info->n_displays; i++)
_glitz_egl_display_destroy (thread_info->displays[i]);
free (thread_info->displays);
thread_info->displays = NULL;
thread_info->n_displays = 0;
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
if (thread_info->dlhand) {
dlclose (thread_info->dlhand);
thread_info->dlhand = NULL;
}
thread_info->cctx = NULL;
}
#ifdef PTHREADS
/* thread safe */
static int tsd_initialized = 0;
static pthread_key_t info_tsd;
static void
_glitz_egl_thread_info_init (glitz_egl_thread_info_t *thread_info)
{
thread_info->displays = NULL;
thread_info->n_displays = 0;
thread_info->gl_library = NULL;
thread_info->dlhand = NULL;
thread_info->cctx = NULL;
}
static void
_glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info)
{
pthread_setspecific (info_tsd, NULL);
if (thread_info) {
_glitz_egl_thread_info_fini (thread_info);
free (thread_info);
}
}
static void
_tsd_destroy (void *p)
{
if (p) {
_glitz_egl_thread_info_fini ((glitz_egl_thread_info_t *) p);
free (p);
}
}
static glitz_egl_thread_info_t *
_glitz_egl_thread_info_get (const char *gl_library)
{
glitz_egl_thread_info_t *thread_info;
void *p;
if (!tsd_initialized) {
pthread_key_create (&info_tsd, _tsd_destroy);
tsd_initialized = 1;
}
p = pthread_getspecific (info_tsd);
if (p == NULL) {
thread_info = malloc (sizeof (glitz_egl_thread_info_t));
_glitz_egl_thread_info_init (thread_info);
pthread_setspecific (info_tsd, thread_info);
} else
thread_info = (glitz_egl_thread_info_t *) p;
if (gl_library) {
int len = strlen (gl_library);
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
thread_info->gl_library = malloc (len + 1);
if (thread_info->gl_library) {
memcpy (thread_info->gl_library, gl_library, len);
thread_info->gl_library[len] = '\0';
}
}
return thread_info;
}
#else
/* not thread safe */
static glitz_egl_thread_info_t thread_info = {
NULL,
0,
NULL,
NULL
};
static void
_glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info)
{
if (thread_info)
_glitz_egl_thread_info_fini (thread_info);
}
static glitz_egl_thread_info_t *
_glitz_egl_thread_info_get (const char *gl_library)
{
if (gl_library) {
int len = strlen (gl_library);
if (thread_info.gl_library) {
free (thread_info.gl_library);
thread_info.gl_library = NULL;
}
thread_info.gl_library = malloc (len + 1);
if (thread_info.gl_library) {
memcpy (thread_info.gl_library, gl_library, len);
thread_info.gl_library[len] = '\0';
}
}
return &thread_info;
}
#endif
static glitz_egl_display_info_t *
_glitz_egl_display_info_get (EGLDisplay egl_display)
{
glitz_egl_display_info_t *display_info;
glitz_egl_thread_info_t *thread_info = _glitz_egl_thread_info_get (NULL);
glitz_egl_display_info_t **displays = thread_info->displays;
int index, n_displays = thread_info->n_displays;
for (; n_displays; n_displays--, displays++)
if ((*displays)->egl_display == egl_display)
return *displays;
index = thread_info->n_displays++;
thread_info->displays =
realloc (thread_info->displays,
sizeof (glitz_egl_display_info_t *) * thread_info->n_displays);
display_info = malloc (sizeof (glitz_egl_display_info_t));
thread_info->displays[index] = display_info;
display_info->thread_info = thread_info;
display_info->egl_display = egl_display;
display_info->screens = NULL;
display_info->n_screens = 0;
return display_info;
}
static void
_glitz_egl_display_destroy (glitz_egl_display_info_t *display_info)
{
int i;
for (i = 0; i < display_info->n_screens; i++)
_glitz_egl_screen_destroy (display_info->screens[i]);
if (display_info->screens)
free (display_info->screens);
free (display_info);
}
glitz_egl_screen_info_t *
glitz_egl_screen_info_get (EGLDisplay display,
EGLScreenMESA screen)
{
glitz_egl_screen_info_t *screen_info;
glitz_egl_display_info_t *display_info =
_glitz_egl_display_info_get (display);
glitz_egl_screen_info_t **screens = display_info->screens;
int index, n_screens = display_info->n_screens;
#if 0
int error_base, event_base;
#endif
for (; n_screens; n_screens--, screens++)
if ((*screens)->screen == screen)
return *screens;
index = display_info->n_screens++;
display_info->screens =
realloc (display_info->screens,
sizeof (glitz_egl_screen_info_t *) * display_info->n_screens);
screen_info = malloc (sizeof (glitz_egl_screen_info_t));
display_info->screens[index] = screen_info;
screen_info->display_info = display_info;
screen_info->screen = screen;
screen_info->drawables = 0;
screen_info->formats = NULL;
screen_info->egl_config_ids = NULL;
screen_info->n_formats = 0;
screen_info->contexts = NULL;
screen_info->n_contexts = 0;
glitz_program_map_init (&screen_info->program_map);
screen_info->egl_root_context = (EGLContext) 0;
screen_info->egl_feature_mask = 0;
#if 0
if (eglQueryExtension (display, &error_base, &event_base)) {
int major, minor;
if (eglQueryVersion (display, &major, &minor)) {
screen_info->egl_version = major + minor / 10.0f;
if (major > 1 || (major > 0 || minor >= 2)) {
glitz_egl_query_extensions (screen_info, screen_info->egl_version);
_glitz_egl_proc_address_lookup (screen_info);
glitz_egl_query_formats (screen_info);
}
}
}
#endif
glitz_egl_query_extensions (screen_info, screen_info->egl_version);
glitz_egl_query_configs (screen_info);
screen_info->context_stack_size = 1;
screen_info->context_stack->drawable = NULL;
screen_info->context_stack->surface = NULL;
screen_info->context_stack->constraint = GLITZ_NONE;
return screen_info;
}
static void
_glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info)
{
EGLDisplay egl_display = screen_info->display_info->egl_display;
int i;
if (screen_info->egl_root_context)
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
for (i = 0; i < screen_info->n_contexts; i++)
glitz_egl_context_destroy (screen_info, screen_info->contexts[i]);
free (screen_info->contexts);
free (screen_info->formats);
free (screen_info->egl_config_ids);
free (screen_info);
}
void
glitz_egl_init (const char *gl_library)
{
_glitz_egl_thread_info_get (gl_library);
}
slim_hidden_def(glitz_egl_init);
void
glitz_egl_fini (void)
{
glitz_egl_thread_info_t *info = _glitz_egl_thread_info_get (NULL);
_glitz_egl_thread_info_destroy (info);
}
slim_hidden_def(glitz_egl_fini);

Просмотреть файл

@ -0,0 +1,67 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
EGLSurface
glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info,
EGLConfig egl_config,
int width,
int height)
{
if (egl_config) {
int attributes[9];
attributes[0] = EGL_WIDTH;
attributes[1] = width;
attributes[2] = EGL_HEIGHT;
attributes[3] = height;
#if 0
attributes[4] = EGL_LARGEST_PBUFFER;
attributes[5] = 0;
attributes[6] = EGL_PRESERVED_CONTENTS;
attributes[7] = 1;
attributes[8] = 0;
#endif
return
eglCreatePbufferSurface(screen_info->display_info->egl_display,
egl_config, attributes);
} else
return (EGLSurface) 0;
}
void
glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info,
EGLSurface egl_pbuffer)
{
eglDestroySurface(screen_info->display_info->egl_display,
egl_pbuffer);
}

Просмотреть файл

@ -0,0 +1,203 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_eglint.h"
static glitz_egl_surface_t *
_glitz_egl_create_surface (glitz_egl_screen_info_t *screen_info,
glitz_egl_context_t *context,
glitz_drawable_format_t *format,
EGLSurface egl_surface,
int width,
int height)
{
glitz_egl_surface_t *surface;
if (width <= 0 || height <= 0)
return NULL;
surface = (glitz_egl_surface_t *) malloc (sizeof (glitz_egl_surface_t));
if (surface == NULL)
return NULL;
surface->base.ref_count = 1;
surface->screen_info = screen_info;
surface->context = context;
surface->egl_surface = egl_surface;
surface->base.format = format;
surface->base.backend = &context->backend;
glitz_drawable_update_size (&surface->base, width, height);
if (!context->initialized) {
glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT);
glitz_egl_pop_current (surface);
}
if (width > context->max_viewport_dims[0] ||
height > context->max_viewport_dims[1]) {
free (surface);
return NULL;
}
screen_info->drawables++;
return surface;
}
static glitz_drawable_t *
_glitz_egl_create_pbuffer_surface (glitz_egl_screen_info_t *screen_info,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_egl_surface_t *surface;
glitz_egl_context_t *context;
EGLSurface egl_pbuffer;
if (!format->types.pbuffer)
return NULL;
context = glitz_egl_context_get (screen_info, format);
if (!context)
return NULL;
egl_pbuffer = glitz_egl_pbuffer_create (screen_info, context->egl_config,
(int) width, (int) height);
if (!egl_pbuffer)
return NULL;
surface = _glitz_egl_create_surface (screen_info, context, format,
egl_pbuffer,
width, height);
if (!surface) {
glitz_egl_pbuffer_destroy (screen_info, egl_pbuffer);
return NULL;
}
return &surface->base;
}
glitz_drawable_t *
glitz_egl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_egl_surface_t *templ = (glitz_egl_surface_t *) abstract_templ;
return _glitz_egl_create_pbuffer_surface (templ->screen_info, format,
width, height);
}
glitz_drawable_t *
glitz_egl_create_surface (EGLDisplay egl_display,
EGLScreenMESA egl_screen,
glitz_drawable_format_t *format,
EGLSurface egl_surface,
unsigned int width,
unsigned int height)
{
glitz_egl_surface_t *surface;
glitz_egl_screen_info_t *screen_info;
glitz_egl_context_t *context;
screen_info = glitz_egl_screen_info_get (egl_display, egl_screen);
if (!screen_info)
return NULL;
context = glitz_egl_context_get (screen_info, format);
if (!context)
return NULL;
surface = _glitz_egl_create_surface (screen_info, context, format,
egl_surface,
width, height);
if (!surface)
return NULL;
return &surface->base;
}
slim_hidden_def(glitz_egl_create_surface);
glitz_drawable_t *
glitz_egl_create_pbuffer_surface (EGLDisplay display,
EGLScreenMESA screen,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_egl_screen_info_t *screen_info;
screen_info = glitz_egl_screen_info_get (display, screen);
if (!screen_info)
return NULL;
return _glitz_egl_create_pbuffer_surface (screen_info, format,
width, height);
}
slim_hidden_def(glitz_egl_create_pbuffer_surface);
void
glitz_egl_destroy (void *abstract_drawable)
{
EGLint value;
glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable;
surface->screen_info->drawables--;
if (surface->screen_info->drawables == 0) {
/*
* Last drawable? We have to destroy all fragment programs as this may
* be our last chance to have a context current.
*/
glitz_egl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_program_map_fini (&surface->base.backend->gl,
&surface->screen_info->program_map);
glitz_egl_pop_current (abstract_drawable);
}
if (eglGetCurrentSurface ( 0 ) == surface->egl_surface)
eglMakeCurrent (surface->screen_info->display_info->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglQuerySurface (surface->screen_info->display_info->egl_display, surface->egl_surface,
EGL_SURFACE_TYPE, &value);
if (value == EGL_PBUFFER_BIT)
glitz_egl_pbuffer_destroy (surface->screen_info, surface->egl_surface);
free (surface);
}
void
glitz_egl_swap_buffers (void *abstract_drawable)
{
glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable;
eglSwapBuffers (surface->screen_info->display_info->egl_display,
surface->egl_surface);
}

Просмотреть файл

Просмотреть файл

@ -0,0 +1,171 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_EGLINT_H_INCLUDED
#define GLITZ_EGLINT_H_INCLUDED
#include "glitz.h"
#include "glitzint.h"
#include "glitz-egl.h"
#include "glitz_eglext.h"
#define GLITZ_EGL_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2)
#define GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3)
#define GLITZ_EGL_FEATURE_MULTISAMPLE_MASK (1L << 4)
#define GLITZ_EGL_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5)
typedef struct _glitz_egl_surface glitz_egl_surface_t;
typedef struct _glitz_egl_screen_info_t glitz_egl_screen_info_t;
typedef struct _glitz_egl_display_info_t glitz_egl_display_info_t;
typedef struct _glitz_egl_thread_info_t {
glitz_egl_display_info_t **displays;
int n_displays;
char *gl_library;
void *dlhand;
glitz_context_t *cctx;
} glitz_egl_thread_info_t;
struct _glitz_egl_display_info_t {
glitz_egl_thread_info_t *thread_info;
EGLDisplay egl_display;
glitz_egl_screen_info_t **screens;
int n_screens;
};
typedef struct _glitz_egl_context_info_t {
glitz_egl_surface_t *drawable;
glitz_surface_t *surface;
glitz_constraint_t constraint;
} glitz_egl_context_info_t;
typedef struct _glitz_egl_context_t {
glitz_context_t base;
EGLContext egl_context;
glitz_format_id_t id;
EGLConfig egl_config;
glitz_backend_t backend;
glitz_gl_int_t max_viewport_dims[2];
glitz_gl_int_t max_texture_2d_size;
glitz_gl_int_t max_texture_rect_size;
glitz_bool_t initialized;
} glitz_egl_context_t;
struct _glitz_egl_screen_info_t {
glitz_egl_display_info_t *display_info;
int screen;
int drawables;
glitz_drawable_format_t *formats;
EGLConfig *egl_config_ids;
int n_formats;
glitz_egl_context_t **contexts;
int n_contexts;
glitz_egl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE];
int context_stack_size;
EGLContext egl_root_context;
unsigned long egl_feature_mask;
glitz_gl_float_t egl_version;
glitz_program_map_t program_map;
};
struct _glitz_egl_surface {
glitz_drawable_t base;
glitz_egl_screen_info_t *screen_info;
glitz_egl_context_t *context;
EGLSurface egl_surface;
};
extern void __internal_linkage
glitz_egl_query_extensions (glitz_egl_screen_info_t *screen_info,
glitz_gl_float_t egl_version);
extern glitz_egl_screen_info_t __internal_linkage *
glitz_egl_screen_info_get (EGLDisplay egl_display,
EGLScreenMESA egl_screen);
extern glitz_function_pointer_t __internal_linkage
glitz_egl_get_proc_address (const char *name,
void *closure);
extern glitz_egl_context_t __internal_linkage *
glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
glitz_drawable_format_t *format);
extern void __internal_linkage
glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info,
glitz_egl_context_t *context);
extern void __internal_linkage
glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info);
extern EGLSurface __internal_linkage
glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info,
EGLConfig egl_config,
int width,
int height);
extern void __internal_linkage
glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info,
EGLSurface egl_pbuffer);
extern glitz_drawable_t __internal_linkage *
glitz_egl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
extern void __internal_linkage
glitz_egl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint);
extern glitz_surface_t __internal_linkage *
glitz_egl_pop_current (void *abstract_drawable);
void
glitz_egl_make_current (void *abstract_drawable,
glitz_constraint_t constraint);
extern glitz_status_t __internal_linkage
glitz_egl_make_current_read (void *abstract_surface);
extern void __internal_linkage
glitz_egl_destroy (void *abstract_drawable);
extern void __internal_linkage
glitz_egl_swap_buffers (void *abstract_drawable);
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(glitz_egl_init)
slim_hidden_proto(glitz_egl_fini)
slim_hidden_proto(glitz_egl_find_config)
slim_hidden_proto(glitz_egl_create_surface)
slim_hidden_proto(glitz_egl_create_pbuffer_surface)
#endif /* GLITZ_EGLINT_H_INCLUDED */

640
gfx/cairo/glitz/src/glitz.c Normal file
Просмотреть файл

@ -0,0 +1,640 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
static glitz_gl_uint_t _texture_units[] = {
GLITZ_GL_TEXTURE0,
GLITZ_GL_TEXTURE1,
GLITZ_GL_TEXTURE2
};
typedef struct _glitz_texture_unit_t {
glitz_texture_t *texture;
glitz_gl_uint_t unit;
glitz_bool_t transform;
} glitz_texture_unit_t;
void
glitz_composite (glitz_operator_t op,
glitz_surface_t *src,
glitz_surface_t *mask,
glitz_surface_t *dst,
int x_src,
int y_src,
int x_mask,
int y_mask,
int x_dst,
int y_dst,
int width,
int height)
{
glitz_composite_op_t comp_op;
int i, texture_nr = -1;
glitz_texture_t *stexture, *mtexture;
glitz_texture_unit_t textures[3];
glitz_box_t bounds;
glitz_bool_t no_border_clamp;
unsigned long flags;
GLITZ_GL_SURFACE (dst);
bounds.x1 = MAX (x_dst, 0);
bounds.y1 = MAX (y_dst, 0);
bounds.x2 = x_dst + width;
bounds.y2 = y_dst + height;
if (bounds.x2 > dst->box.x2)
bounds.x2 = dst->box.x2;
if (bounds.y2 > dst->box.y2)
bounds.y2 = dst->box.y2;
if (bounds.x1 >= bounds.x2 || bounds.y1 >= bounds.y2)
return;
if (dst->geometry.buffer && (!dst->geometry.count))
return;
glitz_composite_op_init (&comp_op, op, src, mask, dst);
if (comp_op.type == GLITZ_COMBINE_TYPE_NA)
{
glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
return;
}
src = comp_op.src;
mask = comp_op.mask;
if (src)
{
stexture = glitz_surface_get_texture (src, 0);
if (!stexture)
return;
} else
stexture = NULL;
if (mask)
{
mtexture = glitz_surface_get_texture (mask, 0);
if (!mtexture)
return;
} else
mtexture = NULL;
if (!glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT))
{
glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
glitz_surface_pop_current (dst);
return;
}
no_border_clamp = !(dst->drawable->backend->feature_mask &
GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK);
if (mtexture)
{
textures[0].texture = mtexture;
textures[0].unit = _texture_units[0];
textures[0].transform = 0;
texture_nr = 0;
glitz_texture_bind (gl, mtexture);
flags = mask->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK;
if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK)
{
flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK;
if (dst->geometry.u.v.mask.size == 2)
flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK;
}
glitz_texture_set_tex_gen (gl,
mtexture,
&dst->geometry,
x_dst - x_mask,
y_dst - y_mask,
flags,
&dst->geometry.u.v.mask);
if (mask->transform)
{
textures[0].transform = 1;
gl->matrix_mode (GLITZ_GL_TEXTURE);
gl->load_matrix_f (SURFACE_EYE_COORDS (mask)?
mask->transform->m: mask->transform->t);
gl->matrix_mode (GLITZ_GL_MODELVIEW);
if (SURFACE_LINEAR_TRANSFORM_FILTER (mask))
glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR);
else
glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST);
}
else
{
if ((dst->geometry.attributes &
GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) &&
SURFACE_LINEAR_TRANSFORM_FILTER (mask))
glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR);
else
glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST);
}
if (SURFACE_REPEAT (mask))
{
if (SURFACE_MIRRORED (mask))
glitz_texture_ensure_wrap (gl, mtexture,
GLITZ_GL_MIRRORED_REPEAT);
else
glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT);
}
else
{
if (no_border_clamp || SURFACE_PAD (mask))
glitz_texture_ensure_wrap (gl, mtexture,
GLITZ_GL_CLAMP_TO_EDGE);
else
glitz_texture_ensure_wrap (gl, mtexture,
GLITZ_GL_CLAMP_TO_BORDER);
}
}
if (stexture)
{
int last_texture_nr = comp_op.combine->texture_units - 1;
while (texture_nr < last_texture_nr)
{
textures[++texture_nr].texture = stexture;
textures[texture_nr].unit = _texture_units[texture_nr];
textures[texture_nr].transform = 0;
if (texture_nr > 0)
{
gl->active_texture (textures[texture_nr].unit);
gl->client_active_texture (textures[texture_nr].unit);
}
glitz_texture_bind (gl, stexture);
}
flags = src->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK;
if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK)
{
flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK;
if (dst->geometry.u.v.src.size == 2)
flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK;
}
glitz_texture_set_tex_gen (gl,
stexture,
&dst->geometry,
x_dst - x_src,
y_dst - y_src,
flags,
&dst->geometry.u.v.src);
if (src->transform)
{
textures[texture_nr].transform = 1;
gl->matrix_mode (GLITZ_GL_TEXTURE);
gl->load_matrix_f (SURFACE_EYE_COORDS (src)?
src->transform->m: src->transform->t);
gl->matrix_mode (GLITZ_GL_MODELVIEW);
if (SURFACE_LINEAR_TRANSFORM_FILTER (src))
glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR);
else
glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST);
}
else
{
if ((dst->geometry.attributes &
GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) &&
SURFACE_LINEAR_TRANSFORM_FILTER (src))
glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR);
else
glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST);
}
if (SURFACE_REPEAT (src))
{
if (SURFACE_MIRRORED (src))
glitz_texture_ensure_wrap (gl, stexture,
GLITZ_GL_MIRRORED_REPEAT);
else
glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT);
}
else
{
if (no_border_clamp || SURFACE_PAD (src))
glitz_texture_ensure_wrap (gl, stexture,
GLITZ_GL_CLAMP_TO_EDGE);
else
glitz_texture_ensure_wrap (gl, stexture,
GLITZ_GL_CLAMP_TO_BORDER);
}
}
glitz_geometry_enable (gl, dst, &bounds);
if (comp_op.per_component)
{
static unsigned short alpha_map[4][4] = {
{ 0, 0, 0, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 0, 0 },
{ 1, 0, 0, 0 }
};
static int damage[4] = {
GLITZ_DAMAGE_TEXTURE_MASK | GLITZ_DAMAGE_SOLID_MASK,
0,
0,
0
};
glitz_color_t alpha = comp_op.alpha_mask;
int component = 4;
int cmask = 1;
while (component--)
{
comp_op.alpha_mask.red = alpha_map[component][0] * alpha.red;
comp_op.alpha_mask.green = alpha_map[component][1] * alpha.green;
comp_op.alpha_mask.blue = alpha_map[component][2] * alpha.blue;
comp_op.alpha_mask.alpha = alpha_map[component][3] * alpha.alpha;
gl->color_mask ((cmask & 1) ,
(cmask & 2) >> 1,
(cmask & 4) >> 2,
(cmask & 8) >> 3);
glitz_composite_enable (&comp_op);
glitz_geometry_draw_arrays (gl, dst,
dst->geometry.type, &bounds,
damage[component]);
cmask <<= 1;
}
gl->color_mask (1, 1, 1, 1);
}
else
{
glitz_composite_enable (&comp_op);
glitz_geometry_draw_arrays (gl, dst, dst->geometry.type, &bounds,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
glitz_composite_disable (&comp_op);
glitz_geometry_disable (dst);
for (i = texture_nr; i >= 0; i--)
{
glitz_texture_unbind (gl, textures[i].texture);
if (textures[i].transform)
{
gl->matrix_mode (GLITZ_GL_TEXTURE);
gl->load_identity ();
gl->matrix_mode (GLITZ_GL_MODELVIEW);
}
if (i > 0)
{
gl->client_active_texture (textures[i - 1].unit);
gl->active_texture (textures[i - 1].unit);
}
}
glitz_surface_pop_current (dst);
}
void
glitz_copy_area (glitz_surface_t *src,
glitz_surface_t *dst,
int x_src,
int y_src,
int width,
int height,
int x_dst,
int y_dst)
{
glitz_status_t status;
glitz_box_t bounds;
int src_width = src->box.x2;
int src_height = src->box.y2;
GLITZ_GL_SURFACE (dst);
if (x_src < 0)
{
bounds.x1 = x_dst - x_src;
width += x_src;
}
else
{
bounds.x1 = x_dst;
src_width -= x_src;
}
if (y_src < 0)
{
bounds.y1 = y_dst - y_src;
height += y_src;
}
else
{
bounds.y1 = y_dst;
src_height -= y_src;
}
if (width > src_width)
bounds.x2 = bounds.x1 + src_width;
else
bounds.x2 = bounds.x1 + width;
if (height > src_height)
bounds.y2 = bounds.y1 + src_height;
else
bounds.y2 = bounds.y1 + height;
if (bounds.x1 < 0)
bounds.x1 = 0;
if (bounds.y1 < 0)
bounds.y1 = 0;
if (bounds.x2 > dst->box.x2)
bounds.x2 = dst->box.x2;
if (bounds.y2 > dst->box.y2)
bounds.y2 = dst->box.y2;
if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
return;
status = GLITZ_STATUS_NOT_SUPPORTED;
if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT))
{
int target_height = SURFACE_DRAWABLE_HEIGHT (dst);
int source_height = SURFACE_DRAWABLE_HEIGHT (src);
if (src == dst || (dst->attached && src->attached == dst->attached))
{
glitz_box_t box, *clip = dst->clip;
int n_clip = dst->n_clip;
if (REGION_NOTEMPTY (&src->drawable_damage))
{
glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT);
glitz_surface_pop_current (src);
}
gl->read_buffer (src->buffer);
gl->draw_buffer (dst->buffer);
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
x_src += src->x;
y_src += src->y;
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds.x1 > box.x1)
box.x1 = bounds.x1;
if (bounds.y1 > box.y1)
box.y1 = bounds.y1;
if (bounds.x2 < box.x2)
box.x2 = bounds.x2;
if (bounds.y2 < box.y2)
box.y2 = bounds.y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
glitz_set_raster_pos (gl,
dst->x + box.x1,
target_height - (dst->y + box.y2));
gl->scissor (dst->x + box.x1,
target_height - (dst->y + box.y2),
box.x2 - box.x1,
box.y2 - box.y1);
gl->copy_pixels (x_src + (box.x1 - x_dst),
source_height -
(y_src + (box.y2 - y_dst)),
box.x2 - box.x1, box.y2 - box.y1,
GLITZ_GL_COLOR);
glitz_surface_damage (dst, &box,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
clip++;
}
}
else
{
glitz_texture_t *texture;
texture = glitz_surface_get_texture (src, 0);
if (texture)
{
glitz_texture_bind (gl, texture);
glitz_texture_set_tex_gen (gl, texture, NULL,
x_dst - x_src,
y_dst - y_src,
GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK,
NULL);
gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
gl->color_4us (0x0, 0x0, 0x0, 0xffff);
glitz_texture_ensure_wrap (gl, texture,
GLITZ_GL_CLAMP_TO_EDGE);
glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST);
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
if (dst->n_clip > 1)
{
glitz_float_t *data;
void *ptr;
int vertices = 0;
glitz_box_t box, *clip = dst->clip;
int n_clip = dst->n_clip;
ptr = malloc (n_clip * 8 * sizeof (glitz_float_t));
if (!ptr) {
glitz_surface_pop_current (dst);
glitz_surface_status_add (dst,
GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
data = (glitz_float_t *) ptr;
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds.x1 > box.x1)
box.x1 = bounds.x1;
if (bounds.y1 > box.y1)
box.y1 = bounds.y1;
if (bounds.x2 < box.x2)
box.x2 = bounds.x2;
if (bounds.y2 < box.y2)
box.y2 = bounds.y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
*data++ = (glitz_float_t) box.x1;
*data++ = (glitz_float_t) box.y1;
*data++ = (glitz_float_t) box.x2;
*data++ = (glitz_float_t) box.y1;
*data++ = (glitz_float_t) box.x2;
*data++ = (glitz_float_t) box.y2;
*data++ = (glitz_float_t) box.x1;
*data++ = (glitz_float_t) box.y2;
vertices += 4;
glitz_surface_damage (dst, &box,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
clip++;
}
if (vertices)
{
gl->scissor (bounds.x1 + dst->x,
(target_height - dst->y) - bounds.y2,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr);
gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices);
}
free (ptr);
}
else
{
glitz_geometry_enable_none (gl, dst, &bounds);
glitz_geometry_draw_arrays (gl, dst,
GLITZ_GEOMETRY_TYPE_NONE,
&bounds,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
glitz_texture_unbind (gl, texture);
}
}
status = GLITZ_STATUS_SUCCESS;
}
glitz_surface_pop_current (dst);
if (status && src->attached)
{
if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT))
{
glitz_texture_t *texture;
gl->read_buffer (src->buffer);
texture = glitz_surface_get_texture (dst, 1);
if (texture)
{
glitz_box_t box, *clip = dst->clip;
int n_clip = dst->n_clip;
gl->disable (GLITZ_GL_SCISSOR_TEST);
glitz_texture_bind (gl, texture);
x_src += src->x;
y_src += src->y;
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds.x1 > box.x1)
box.x1 = bounds.x1;
if (bounds.y1 > box.y1)
box.y1 = bounds.y1;
if (bounds.x2 < box.x2)
box.x2 = bounds.x2;
if (bounds.y2 < box.y2)
box.y2 = bounds.y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
glitz_texture_copy_drawable (gl,
texture,
src->attached,
x_src + (box.x1 - x_dst),
y_src + (box.y1 - y_dst),
box.x2 - box.x1,
box.y2 - box.y1,
box.x1,
box.y1);
glitz_surface_damage (dst, &box,
GLITZ_DAMAGE_DRAWABLE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
clip++;
}
glitz_texture_unbind (gl, texture);
gl->enable (GLITZ_GL_SCISSOR_TEST);
status = GLITZ_STATUS_SUCCESS;
}
}
glitz_surface_pop_current (src);
}
if (status)
glitz_surface_status_add (dst, glitz_status_to_status_mask (status));
}

Просмотреть файл

@ -0,0 +1,121 @@
EXPORTS
_glitz_context_fini @1
_glitz_context_init @2
_texture_formats @3 DATA
glitz_add_trapezoids @4
glitz_add_traps @5
glitz_backend_init @6
glitz_buffer_bind @7
glitz_buffer_create_for_data @8
glitz_buffer_destroy @9
glitz_buffer_get_data @10
glitz_buffer_map @11
glitz_buffer_reference @12
glitz_buffer_set_data @13
glitz_buffer_unbind @14
glitz_buffer_unmap @15
glitz_clamp_value @16
glitz_composite @17
glitz_composite_disable @18
glitz_composite_enable @19
glitz_composite_op_init @20
glitz_context_bind_texture @21
glitz_context_copy @22
glitz_context_create @23
glitz_context_destroy @24
glitz_context_get_proc_address @25
glitz_context_make_current @26
glitz_context_reference @27
glitz_context_set_user_data @28
glitz_copy_area @29
glitz_create_pbuffer_drawable @30
glitz_create_surface_formats @31
glitz_drawable_destroy @32
glitz_drawable_finish @33
glitz_drawable_flush @34
glitz_drawable_format_find @35
glitz_drawable_get_features @36
glitz_drawable_get_format @37
glitz_drawable_get_height @38
glitz_drawable_get_width @39
glitz_drawable_reference @40
glitz_drawable_swap_buffers @41
glitz_drawable_update_size @42
glitz_extensions_query @43
glitz_filter_enable @44
glitz_filter_get_fragment_program @45
glitz_filter_set_params @46
glitz_filter_set_type @47
glitz_find_format @48
glitz_find_similar_drawable_format @49
glitz_find_standard_format @50
glitz_framebuffer_complete @51
glitz_framebuffer_fini @52
glitz_framebuffer_init @53
glitz_framebuffer_unbind @54
glitz_geometry_disable @55
glitz_geometry_draw_arrays @56
glitz_geometry_enable @57
glitz_geometry_enable_none @58
glitz_get_fragment_program @59
glitz_get_pixels @60
glitz_initiate_state @61
glitz_multi_array_add @62
glitz_multi_array_create @63
glitz_multi_array_destroy @64
glitz_multi_array_reference @65
glitz_multi_array_reset @66
glitz_pixel_buffer_create @67
glitz_program_map_fini @68
glitz_program_map_init @69
glitz_region_union @70
glitz_set_array @71
glitz_set_geometry @72
glitz_set_multi_array @73
glitz_set_operator @74
glitz_set_pixels @75
glitz_set_raster_pos @76
glitz_set_rectangle @77
glitz_set_rectangles @78
glitz_status_pop_from_mask @79
glitz_status_string @80
glitz_status_to_status_mask @81
glitz_surface_attach @82
glitz_surface_create @83
glitz_surface_damage @84
glitz_surface_destroy @85
glitz_surface_detach @86
glitz_surface_flush @87
glitz_surface_get_attached_drawable @88
glitz_surface_get_drawable @89
glitz_surface_get_format @90
glitz_surface_get_height @91
glitz_surface_get_status @92
glitz_surface_get_texture @93
glitz_surface_get_width @94
glitz_surface_pop_current @95
glitz_surface_push_current @96
glitz_surface_reference @97
glitz_surface_set_clip_region @98
glitz_surface_set_component_alpha @99
glitz_surface_set_dither @100
glitz_surface_set_fill @101
glitz_surface_set_filter @102
glitz_surface_set_transform @103
glitz_surface_status_add @104
glitz_surface_sync_drawable @105
glitz_surface_sync_solid @106
glitz_surface_translate_point @107
glitz_surface_valid_target @108
glitz_texture_allocate @109
glitz_texture_bind @110
glitz_texture_copy_drawable @111
glitz_texture_ensure_filter @112
glitz_texture_ensure_wrap @113
glitz_texture_fini @114
glitz_texture_init @115
glitz_texture_set_tex_gen @116
glitz_texture_size_check @117
glitz_texture_unbind @118
glitz_uint_to_power_of_two @119
glitz_vertex_buffer_create @120

697
gfx/cairo/glitz/src/glitz.h Normal file
Просмотреть файл

@ -0,0 +1,697 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_H_INCLUDED
#define GLITZ_H_INCLUDED
#if defined(__SVR4) && defined(__sun)
# include <sys/int_types.h>
#else
# if defined(__OpenBSD__)
# include <inttypes.h>
# else
# include <stdint.h>
# endif
#endif
#define GLITZ_MAJOR 0
#define GLITZ_MINOR 4
#define GLITZ_REVISION 4
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
typedef int glitz_bool_t;
typedef short glitz_short_t;
typedef int glitz_int_t;
typedef float glitz_float_t;
typedef double glitz_double_t;
typedef int glitz_fixed16_16_t;
typedef struct _glitz_rectangle_t {
short x, y;
unsigned short width, height;
} glitz_rectangle_t;
typedef struct _glitz_box_t {
short x1, y1, x2, y2;
} glitz_box_t;
typedef struct _glitz_point_fixed_t {
glitz_fixed16_16_t x;
glitz_fixed16_16_t y;
} glitz_point_fixed_t;
typedef struct _glitz_line_fixed_t {
glitz_point_fixed_t p1;
glitz_point_fixed_t p2;
} glitz_line_fixed_t;
typedef struct _glitz_trapezoid_t {
glitz_fixed16_16_t top, bottom;
glitz_line_fixed_t left, right;
} glitz_trapezoid_t;
typedef struct _glitz_span_fixed_t {
glitz_fixed16_16_t left, right, y;
} glitz_span_fixed_t;
typedef struct _glitz_trap_t {
glitz_span_fixed_t top, bottom;
} glitz_trap_t;
typedef struct _glitz_transform_t {
glitz_fixed16_16_t matrix[3][3];
} glitz_transform_t;
typedef struct {
unsigned short red;
unsigned short green;
unsigned short blue;
unsigned short alpha;
} glitz_color_t;
typedef enum {
GLITZ_FILTER_NEAREST,
GLITZ_FILTER_BILINEAR,
GLITZ_FILTER_CONVOLUTION,
GLITZ_FILTER_GAUSSIAN,
GLITZ_FILTER_LINEAR_GRADIENT,
GLITZ_FILTER_RADIAL_GRADIENT
} glitz_filter_t;
typedef enum {
GLITZ_OPERATOR_CLEAR,
GLITZ_OPERATOR_SRC,
GLITZ_OPERATOR_DST,
GLITZ_OPERATOR_OVER,
GLITZ_OPERATOR_OVER_REVERSE,
GLITZ_OPERATOR_IN,
GLITZ_OPERATOR_IN_REVERSE,
GLITZ_OPERATOR_OUT,
GLITZ_OPERATOR_OUT_REVERSE,
GLITZ_OPERATOR_ATOP,
GLITZ_OPERATOR_ATOP_REVERSE,
GLITZ_OPERATOR_XOR,
GLITZ_OPERATOR_ADD
} glitz_operator_t;
#define GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 0)
#define GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK (1L << 1)
#define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 2)
#define GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK (1L << 3)
#define GLITZ_FEATURE_MULTISAMPLE_MASK (1L << 4)
#define GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK (1L << 5)
#define GLITZ_FEATURE_MULTITEXTURE_MASK (1L << 6)
#define GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK (1L << 7)
#define GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK (1L << 8)
#define GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK (1L << 9)
#define GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK (1L << 10)
#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 11)
#define GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK (1L << 12)
#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,
GLITZ_STANDARD_RGB24,
GLITZ_STANDARD_A8,
GLITZ_STANDARD_A1
} glitz_format_name_t;
#define GLITZ_FORMAT_ID_MASK (1L << 0)
#define GLITZ_FORMAT_RED_SIZE_MASK (1L << 1)
#define GLITZ_FORMAT_GREEN_SIZE_MASK (1L << 2)
#define GLITZ_FORMAT_BLUE_SIZE_MASK (1L << 3)
#define GLITZ_FORMAT_ALPHA_SIZE_MASK (1L << 4)
typedef unsigned long glitz_format_id_t;
typedef struct _glitz_color_format_t {
unsigned short red_size;
unsigned short green_size;
unsigned short blue_size;
unsigned short alpha_size;
} glitz_color_format_t;
/* glitz_status.c */
typedef enum {
GLITZ_STATUS_SUCCESS = 0,
GLITZ_STATUS_NO_MEMORY,
GLITZ_STATUS_BAD_COORDINATE,
GLITZ_STATUS_NOT_SUPPORTED,
GLITZ_STATUS_CONTENT_DESTROYED
} glitz_status_t;
const char *
glitz_status_string (glitz_status_t status);
/* glitz_drawable.c */
typedef struct _glitz_drawable glitz_drawable_t;
typedef enum {
GLITZ_DRAWABLE_BUFFER_FRONT_COLOR,
GLITZ_DRAWABLE_BUFFER_BACK_COLOR
} glitz_drawable_buffer_t;
#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 5)
#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 6)
#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 7)
#define GLITZ_FORMAT_SAMPLES_MASK (1L << 8)
#define GLITZ_FORMAT_WINDOW_MASK (1L << 9)
#define GLITZ_FORMAT_PBUFFER_MASK (1L << 10)
typedef struct _glitz_drawable_types_t {
glitz_bool_t window;
glitz_bool_t pbuffer;
} glitz_drawable_types_t;
typedef struct _glitz_drawable_format_t {
glitz_format_id_t id;
glitz_color_format_t color;
unsigned short depth_size;
unsigned short stencil_size;
unsigned short samples;
glitz_bool_t doublebuffer;
glitz_drawable_types_t types;
} glitz_drawable_format_t;
glitz_drawable_format_t *
glitz_find_similar_drawable_format (glitz_drawable_t *other,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count);
glitz_drawable_t *
glitz_create_pbuffer_drawable (glitz_drawable_t *other,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
void
glitz_drawable_destroy (glitz_drawable_t *drawable);
void
glitz_drawable_reference (glitz_drawable_t *drawable);
void
glitz_drawable_update_size (glitz_drawable_t *drawable,
unsigned int width,
unsigned int height);
unsigned int
glitz_drawable_get_width (glitz_drawable_t *drawable);
unsigned int
glitz_drawable_get_height (glitz_drawable_t *drawable);
void
glitz_drawable_swap_buffers (glitz_drawable_t *drawable);
void
glitz_drawable_flush (glitz_drawable_t *drawable);
void
glitz_drawable_finish (glitz_drawable_t *drawable);
unsigned long
glitz_drawable_get_features (glitz_drawable_t *drawable);
glitz_drawable_format_t *
glitz_drawable_get_format (glitz_drawable_t *drawable);
/* glitz_format.c */
#define GLITZ_FORMAT_TYPE_MASK (1L << 5)
typedef enum {
GLITZ_FORMAT_TYPE_COLOR
} glitz_format_type_t;
typedef struct _glitz_format_t {
glitz_format_id_t id;
glitz_format_type_t type;
glitz_color_format_t color;
} glitz_format_t;
glitz_format_t *
glitz_find_standard_format (glitz_drawable_t *drawable,
glitz_format_name_t format_name);
glitz_format_t *
glitz_find_format (glitz_drawable_t *drawable,
unsigned long mask,
const glitz_format_t *templ,
int count);
/* glitz_surface.c */
typedef struct _glitz_surface glitz_surface_t;
#define GLITZ_SURFACE_UNNORMALIZED_MASK (1L << 0)
typedef struct _glitz_surface_attributes_t {
glitz_bool_t unnormalized;
} glitz_surface_attributes_t;
glitz_surface_t *
glitz_surface_create (glitz_drawable_t *drawable,
glitz_format_t *format,
unsigned int width,
unsigned int height,
unsigned long mask,
glitz_surface_attributes_t *attributes);
void
glitz_surface_destroy (glitz_surface_t *surface);
void
glitz_surface_reference (glitz_surface_t *surface);
void
glitz_surface_attach (glitz_surface_t *surface,
glitz_drawable_t *drawable,
glitz_drawable_buffer_t buffer,
int x,
int y);
void
glitz_surface_detach (glitz_surface_t *surface);
void
glitz_surface_flush (glitz_surface_t *surface);
glitz_drawable_t *
glitz_surface_get_drawable (glitz_surface_t *surface);
glitz_drawable_t *
glitz_surface_get_attached_drawable (glitz_surface_t *surface);
void
glitz_surface_set_transform (glitz_surface_t *surface,
glitz_transform_t *transform);
typedef enum {
GLITZ_FILL_TRANSPARENT,
GLITZ_FILL_NEAREST,
GLITZ_FILL_REPEAT,
GLITZ_FILL_REFLECT
} glitz_fill_t;
void
glitz_surface_set_fill (glitz_surface_t *surface,
glitz_fill_t fill);
void
glitz_surface_set_component_alpha (glitz_surface_t *surface,
glitz_bool_t component_alpha);
void
glitz_surface_set_filter (glitz_surface_t *surface,
glitz_filter_t filter,
glitz_fixed16_16_t *params,
int n_params);
void
glitz_surface_set_dither (glitz_surface_t *surface,
glitz_bool_t dither);
unsigned int
glitz_surface_get_width (glitz_surface_t *surface);
unsigned int
glitz_surface_get_height (glitz_surface_t *surface);
glitz_status_t
glitz_surface_get_status (glitz_surface_t *surface);
glitz_format_t *
glitz_surface_get_format (glitz_surface_t *surface);
void
glitz_surface_translate_point (glitz_surface_t *surface,
glitz_point_fixed_t *src,
glitz_point_fixed_t *dst);
void
glitz_surface_set_clip_region (glitz_surface_t *surface,
int x_origin,
int y_origin,
glitz_box_t *box,
int n_box);
glitz_bool_t
glitz_surface_valid_target (glitz_surface_t *surface);
/* glitz_context.c */
typedef struct _glitz_context glitz_context_t;
glitz_context_t *
glitz_context_create (glitz_drawable_t *drawable,
glitz_drawable_format_t *format);
void
glitz_context_destroy (glitz_context_t *context);
void
glitz_context_reference (glitz_context_t *context);
void
glitz_context_copy (glitz_context_t *src,
glitz_context_t *dst,
unsigned long mask);
typedef void (*glitz_lose_current_function_t) (void *closure);
void
glitz_context_set_user_data (glitz_context_t *context,
void *closure,
glitz_lose_current_function_t lose_current);
typedef void (*glitz_function_pointer_t) (void);
glitz_function_pointer_t
glitz_context_get_proc_address (glitz_context_t *context,
const char *name);
void
glitz_context_make_current (glitz_context_t *context);
void
glitz_context_bind_texture (glitz_context_t *context,
glitz_surface_t *surface);
/* glitz_rect.c */
void
glitz_set_rectangle (glitz_surface_t *dst,
const glitz_color_t *color,
int x,
int y,
unsigned int width,
unsigned int height);
void
glitz_set_rectangles (glitz_surface_t *dst,
const glitz_color_t *color,
const glitz_rectangle_t *rects,
int n_rects);
/* glitz_buffer.c */
typedef struct _glitz_buffer glitz_buffer_t;
typedef enum {
GLITZ_BUFFER_HINT_STREAM_DRAW,
GLITZ_BUFFER_HINT_STREAM_READ,
GLITZ_BUFFER_HINT_STREAM_COPY,
GLITZ_BUFFER_HINT_STATIC_DRAW,
GLITZ_BUFFER_HINT_STATIC_READ,
GLITZ_BUFFER_HINT_STATIC_COPY,
GLITZ_BUFFER_HINT_DYNAMIC_DRAW,
GLITZ_BUFFER_HINT_DYNAMIC_READ,
GLITZ_BUFFER_HINT_DYNAMIC_COPY
} glitz_buffer_hint_t;
typedef enum {
GLITZ_BUFFER_ACCESS_READ_ONLY,
GLITZ_BUFFER_ACCESS_WRITE_ONLY,
GLITZ_BUFFER_ACCESS_READ_WRITE
} glitz_buffer_access_t;
glitz_buffer_t *
glitz_vertex_buffer_create (glitz_drawable_t *drawable,
void *data,
unsigned int size,
glitz_buffer_hint_t hint);
glitz_buffer_t *
glitz_pixel_buffer_create (glitz_drawable_t *drawable,
void *data,
unsigned int size,
glitz_buffer_hint_t hint);
glitz_buffer_t *
glitz_buffer_create_for_data (void *data);
void
glitz_buffer_destroy (glitz_buffer_t *buffer);
void
glitz_buffer_reference (glitz_buffer_t *buffer);
void
glitz_buffer_set_data (glitz_buffer_t *buffer,
int offset,
unsigned int size,
const void *data);
void
glitz_buffer_get_data (glitz_buffer_t *buffer,
int offset,
unsigned int size,
void *data);
void *
glitz_buffer_map (glitz_buffer_t *buffer,
glitz_buffer_access_t access);
glitz_status_t
glitz_buffer_unmap (glitz_buffer_t *buffer);
/* glitz_pixel.c */
typedef enum {
GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
} glitz_pixel_scanline_order_t;
typedef struct _glitz_pixel_masks {
int bpp;
unsigned long alpha_mask;
unsigned long red_mask;
unsigned long green_mask;
unsigned long blue_mask;
} glitz_pixel_masks_t;
typedef struct _glitz_pixel_format {
glitz_pixel_masks_t masks;
int xoffset;
int skip_lines;
int bytes_per_line;
glitz_pixel_scanline_order_t scanline_order;
} glitz_pixel_format_t;
void
glitz_set_pixels (glitz_surface_t *dst,
int x_dst,
int y_dst,
int width,
int height,
glitz_pixel_format_t *format,
glitz_buffer_t *buffer);
void
glitz_get_pixels (glitz_surface_t *src,
int x_src,
int y_src,
int width,
int height,
glitz_pixel_format_t *format,
glitz_buffer_t *buffer);
/* glitz_geometry.c */
typedef enum {
GLITZ_PRIMITIVE_POINTS,
GLITZ_PRIMITIVE_LINES,
GLITZ_PRIMITIVE_LINE_STRIP,
GLITZ_PRIMITIVE_LINE_LOOP,
GLITZ_PRIMITIVE_TRIANGLES,
GLITZ_PRIMITIVE_TRIANGLE_STRIP,
GLITZ_PRIMITIVE_TRIANGLE_FAN,
GLITZ_PRIMITIVE_QUADS,
GLITZ_PRIMITIVE_QUAD_STRIP,
GLITZ_PRIMITIVE_POLYGON
} glitz_primitive_t;
typedef enum {
GLITZ_DATA_TYPE_SHORT,
GLITZ_DATA_TYPE_INT,
GLITZ_DATA_TYPE_FLOAT,
GLITZ_DATA_TYPE_DOUBLE
} glitz_data_type_t;
typedef enum {
GLITZ_COORDINATE_SIZE_X,
GLITZ_COORDINATE_SIZE_XY
} glitz_coordinate_size_t;
typedef struct _glitz_coordinate_attribute {
glitz_data_type_t type;
glitz_coordinate_size_t size;
int offset;
} glitz_coordinate_attribute_t;
#define GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK (1L << 0)
#define GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK (1L << 1)
typedef struct _glitz_vertex_format {
glitz_primitive_t primitive;
glitz_data_type_t type;
unsigned int bytes_per_vertex;
unsigned long attributes;
glitz_coordinate_attribute_t src;
glitz_coordinate_attribute_t mask;
} glitz_vertex_format_t;
typedef struct _glitz_bitmap_format {
glitz_pixel_scanline_order_t scanline_order;
unsigned int bytes_per_line;
int pad;
} glitz_bitmap_format_t;
typedef enum {
GLITZ_GEOMETRY_TYPE_NONE,
GLITZ_GEOMETRY_TYPE_VERTEX,
GLITZ_GEOMETRY_TYPE_BITMAP
} glitz_geometry_type_t;
typedef union _glitz_geometry_format {
glitz_vertex_format_t vertex;
glitz_bitmap_format_t bitmap;
} glitz_geometry_format_t;
void
glitz_set_geometry (glitz_surface_t *dst,
glitz_geometry_type_t type,
glitz_geometry_format_t *format,
glitz_buffer_t *buffer);
void
glitz_set_array (glitz_surface_t *dst,
int first,
int size,
unsigned int count,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off);
typedef struct _glitz_multi_array glitz_multi_array_t;
glitz_multi_array_t *
glitz_multi_array_create (unsigned int size);
void
glitz_multi_array_destroy (glitz_multi_array_t *array);
void
glitz_multi_array_reference (glitz_multi_array_t *array);
void
glitz_multi_array_add (glitz_multi_array_t *array,
int first,
int size,
unsigned int count,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off);
void
glitz_multi_array_reset (glitz_multi_array_t *array);
void
glitz_set_multi_array (glitz_surface_t *dst,
glitz_multi_array_t *array,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off);
/* glitz_trap.c */
int
glitz_add_trapezoids (glitz_buffer_t *buffer,
int offset,
unsigned int size,
glitz_data_type_t type,
glitz_surface_t *mask,
glitz_trapezoid_t *traps,
int n_traps,
int *n_added);
int
glitz_add_traps (glitz_buffer_t *buffer,
int offset,
unsigned int size,
glitz_data_type_t type,
glitz_surface_t *mask,
glitz_trap_t *traps,
int n_traps,
int *n_added);
/* glitz.c */
void
glitz_composite (glitz_operator_t op,
glitz_surface_t *src,
glitz_surface_t *mask,
glitz_surface_t *dst,
int x_src,
int y_src,
int x_mask,
int y_mask,
int x_dst,
int y_dst,
int width,
int height);
void
glitz_copy_area (glitz_surface_t *src,
glitz_surface_t *dst,
int x_src,
int y_src,
int width,
int height,
int x_dst,
int y_dst);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif /* GLITZ_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,364 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
static glitz_status_t
_glitz_buffer_init (glitz_buffer_t *buffer,
glitz_drawable_t *drawable,
void *data,
unsigned int size,
glitz_buffer_hint_t hint)
{
glitz_gl_enum_t usage;
buffer->ref_count = 1;
buffer->name = 0;
if (drawable)
{
GLITZ_GL_DRAWABLE (drawable);
switch (hint) {
case GLITZ_BUFFER_HINT_STREAM_DRAW:
usage = GLITZ_GL_STREAM_DRAW;
break;
case GLITZ_BUFFER_HINT_STREAM_READ:
usage = GLITZ_GL_STREAM_READ;
break;
case GLITZ_BUFFER_HINT_STREAM_COPY:
usage = GLITZ_GL_STREAM_COPY;
break;
case GLITZ_BUFFER_HINT_STATIC_DRAW:
usage = GLITZ_GL_STATIC_DRAW;
break;
case GLITZ_BUFFER_HINT_STATIC_READ:
usage = GLITZ_GL_STATIC_READ;
break;
case GLITZ_BUFFER_HINT_STATIC_COPY:
usage = GLITZ_GL_STATIC_COPY;
break;
case GLITZ_BUFFER_HINT_DYNAMIC_DRAW:
usage = GLITZ_GL_DYNAMIC_DRAW;
break;
case GLITZ_BUFFER_HINT_DYNAMIC_READ:
usage = GLITZ_GL_DYNAMIC_READ;
break;
default:
usage = GLITZ_GL_DYNAMIC_COPY;
break;
}
buffer->owns_data = 1;
buffer->drawable = drawable;
glitz_drawable_reference (drawable);
drawable->backend->push_current (drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
gl->gen_buffers (1, &buffer->name);
if (buffer->name) {
gl->bind_buffer (buffer->target, buffer->name);
gl->buffer_data (buffer->target, size, data, usage);
gl->bind_buffer (buffer->target, 0);
}
drawable->backend->pop_current (drawable);
}
else
{
buffer->drawable = NULL;
usage = GLITZ_GL_DYNAMIC_COPY;
}
if (size > 0 && buffer->name == 0)
{
buffer->data = malloc (size);
if (buffer->data == NULL)
return GLITZ_STATUS_NO_MEMORY;
if (data)
memcpy (buffer->data, data, size);
buffer->owns_data = 1;
}
else
{
buffer->owns_data = 0;
buffer->data = data;
}
return GLITZ_STATUS_SUCCESS;
}
glitz_buffer_t *
glitz_vertex_buffer_create (glitz_drawable_t *drawable,
void *data,
unsigned int size,
glitz_buffer_hint_t hint)
{
glitz_buffer_t *buffer;
glitz_status_t status;
if (size == 0)
return NULL;
buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
if (buffer == NULL)
return NULL;
buffer->target = GLITZ_GL_ARRAY_BUFFER;
if (drawable->backend->feature_mask &
GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)
status = _glitz_buffer_init (buffer, drawable, data, size, hint);
else
status = _glitz_buffer_init (buffer, NULL, data, size, hint);
if (status != GLITZ_STATUS_SUCCESS) {
free (buffer);
return NULL;
}
return buffer;
}
glitz_buffer_t *
glitz_pixel_buffer_create (glitz_drawable_t *drawable,
void *data,
unsigned int size,
glitz_buffer_hint_t hint)
{
glitz_buffer_t *buffer;
glitz_status_t status;
if (size == 0)
return NULL;
buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
if (buffer == NULL)
return NULL;
switch (hint) {
case GLITZ_BUFFER_HINT_STREAM_READ:
case GLITZ_BUFFER_HINT_STATIC_READ:
case GLITZ_BUFFER_HINT_DYNAMIC_READ:
buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER;
break;
default:
buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
break;
}
if (drawable->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
status = _glitz_buffer_init (buffer, drawable, data, size, hint);
else
status = _glitz_buffer_init (buffer, NULL, data, size, hint);
if (status != GLITZ_STATUS_SUCCESS) {
free (buffer);
return NULL;
}
return buffer;
}
glitz_buffer_t *
glitz_buffer_create_for_data (void *data)
{
glitz_buffer_t *buffer;
buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
if (buffer == NULL)
return NULL;
if (_glitz_buffer_init (buffer, NULL, data, 0, 0)) {
free (buffer);
return NULL;
}
return buffer;
}
void
glitz_buffer_destroy (glitz_buffer_t *buffer)
{
if (!buffer)
return;
buffer->ref_count--;
if (buffer->ref_count)
return;
if (buffer->drawable) {
buffer->drawable->backend->push_current (buffer->drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
buffer->drawable->backend->gl.delete_buffers (1, &buffer->name);
buffer->drawable->backend->pop_current (buffer->drawable);
glitz_drawable_destroy (buffer->drawable);
} else if (buffer->owns_data)
free (buffer->data);
free (buffer);
}
void
glitz_buffer_reference (glitz_buffer_t *buffer)
{
if (!buffer)
return;
buffer->ref_count++;
}
void
glitz_buffer_set_data (glitz_buffer_t *buffer,
int offset,
unsigned int size,
const void *data)
{
if (buffer->drawable) {
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
gl->bind_buffer (buffer->target, buffer->name);
gl->buffer_sub_data (buffer->target, offset, size, data);
gl->bind_buffer (buffer->target, 0);
buffer->drawable->backend->pop_current (buffer->drawable);
} else if (buffer->data)
memcpy ((char *) buffer->data + offset, data, size);
}
slim_hidden_def(glitz_buffer_set_data);
void
glitz_buffer_get_data (glitz_buffer_t *buffer,
int offset,
unsigned int size,
void *data)
{
if (buffer->drawable) {
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
gl->bind_buffer (buffer->target, buffer->name);
gl->get_buffer_sub_data (buffer->target, offset, size, data);
gl->bind_buffer (buffer->target, 0);
buffer->drawable->backend->pop_current (buffer->drawable);
} else if (buffer->data)
memcpy (data, (char *) buffer->data + offset, size);
}
slim_hidden_def(glitz_buffer_get_data);
void *
glitz_buffer_map (glitz_buffer_t *buffer,
glitz_buffer_access_t access)
{
void *pointer = NULL;
if (buffer->drawable) {
glitz_gl_enum_t buffer_access;
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
switch (access) {
case GLITZ_BUFFER_ACCESS_READ_ONLY:
buffer_access = GLITZ_GL_READ_ONLY;
break;
case GLITZ_BUFFER_ACCESS_WRITE_ONLY:
buffer_access = GLITZ_GL_WRITE_ONLY;
break;
default:
buffer_access = GLITZ_GL_READ_WRITE;
break;
}
gl->bind_buffer (buffer->target, buffer->name);
pointer = gl->map_buffer (buffer->target, buffer_access);
gl->bind_buffer (buffer->target, 0);
buffer->drawable->backend->pop_current (buffer->drawable);
}
if (pointer == NULL)
pointer = buffer->data;
return pointer;
}
glitz_status_t
glitz_buffer_unmap (glitz_buffer_t *buffer)
{
glitz_status_t status = GLITZ_STATUS_SUCCESS;
if (buffer->drawable) {
GLITZ_GL_DRAWABLE (buffer->drawable);
buffer->drawable->backend->push_current (buffer->drawable, NULL,
GLITZ_ANY_CONTEXT_CURRENT);
gl->bind_buffer (buffer->target, buffer->name);
if (gl->unmap_buffer (buffer->target) == GLITZ_GL_FALSE)
status = GLITZ_STATUS_CONTENT_DESTROYED;
gl->bind_buffer (buffer->target, 0);
buffer->drawable->backend->pop_current (buffer->drawable);
}
return status;
}
void *
glitz_buffer_bind (glitz_buffer_t *buffer,
glitz_gl_enum_t target)
{
if (buffer->drawable) {
buffer->drawable->backend->gl.bind_buffer (target, buffer->name);
buffer->target = target;
return NULL;
}
return buffer->data;
}
void
glitz_buffer_unbind (glitz_buffer_t *buffer)
{
if (buffer->drawable)
buffer->drawable->backend->gl.bind_buffer (buffer->target, 0);
}

Просмотреть файл

@ -0,0 +1,621 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
static void
_glitz_combine_argb_argb (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
op->gl->active_texture (GLITZ_GL_TEXTURE0);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
op->gl->active_texture (GLITZ_GL_TEXTURE1);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_COMBINE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
GLITZ_GL_MODULATE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
GLITZ_GL_TEXTURE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
GLITZ_GL_PREVIOUS);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
GLITZ_GL_SRC_ALPHA);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA,
GLITZ_GL_MODULATE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA,
GLITZ_GL_TEXTURE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA,
GLITZ_GL_PREVIOUS);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
GLITZ_GL_SRC_ALPHA);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA,
GLITZ_GL_SRC_ALPHA);
}
static void
_glitz_combine_argb_argbc (glitz_composite_op_t *op)
{
if (op->count == 0) {
glitz_set_operator (op->gl, op->render_op);
op->gl->active_texture (GLITZ_GL_TEXTURE0);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_COMBINE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
GLITZ_GL_INTERPOLATE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
GLITZ_GL_TEXTURE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE2_RGB,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND2_RGB,
GLITZ_GL_SRC_ALPHA);
/* we don't care about the alpha channel, so lets do something (simple?) */
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA,
GLITZ_GL_REPLACE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
GLITZ_GL_SRC_ALPHA);
op->gl->active_texture (GLITZ_GL_TEXTURE1);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_COMBINE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
GLITZ_GL_DOT3_RGBA);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
GLITZ_GL_PREVIOUS);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->active_texture (GLITZ_GL_TEXTURE2);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_MODULATE);
}
if (op->alpha_mask.red) {
op->gl->color_4f (1.0f, 0.5f, 0.5f, 0.5f);
} else if (op->alpha_mask.green) {
op->gl->color_4f (0.5f, 1.0f, 0.5f, 0.5f);
} else if (op->alpha_mask.blue) {
op->gl->color_4f (0.5f, 0.5f, 1.0f, 0.5f);
} else {
op->gl->active_texture (GLITZ_GL_TEXTURE0);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
op->gl->active_texture (GLITZ_GL_TEXTURE1);
glitz_texture_unbind (op->gl, &op->src->texture);
op->gl->active_texture (GLITZ_GL_TEXTURE2);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_MODULATE);
}
}
static void
_glitz_combine_argb_argbf (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
glitz_filter_enable (op->mask, op);
op->gl->color_4us (op->alpha_mask.red,
op->alpha_mask.green,
op->alpha_mask.blue,
op->alpha_mask.alpha);
}
static void
_glitz_combine_argb_solid (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
if (op->alpha_mask.alpha != 0xffff) {
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_MODULATE);
op->gl->color_4us (op->alpha_mask.alpha,
op->alpha_mask.alpha,
op->alpha_mask.alpha,
op->alpha_mask.alpha);
} else {
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
}
}
static void
_glitz_combine_argb_solidc (glitz_composite_op_t *op)
{
unsigned short alpha;
if (op->count == 0)
glitz_set_operator (op->gl, op->render_op);
if (op->alpha_mask.red)
alpha = op->alpha_mask.red;
else if (op->alpha_mask.green)
alpha = op->alpha_mask.green;
else if (op->alpha_mask.blue)
alpha = op->alpha_mask.blue;
else
alpha = op->alpha_mask.alpha;
if (alpha != 0xffff) {
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_MODULATE);
op->gl->color_4us (alpha, alpha, alpha, alpha);
} else {
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
}
}
static void
_glitz_combine_argbf_solid (glitz_composite_op_t *op)
{
if (op->count == 0) {
glitz_set_operator (op->gl, op->render_op);
glitz_filter_enable (op->src, op);
}
op->gl->color_4us (0x0, 0x0, 0x0, op->alpha_mask.alpha);
}
static void
_glitz_combine_argbf_argbc (glitz_composite_op_t *op)
{
if (op->count == 0) {
glitz_set_operator (op->gl, op->render_op);
glitz_filter_enable (op->src, op);
}
op->gl->color_4us (op->alpha_mask.red,
op->alpha_mask.green,
op->alpha_mask.blue,
op->alpha_mask.alpha);
}
static void
_glitz_combine_argbf_solidc (glitz_composite_op_t *op)
{
unsigned short alpha;
if (op->count == 0) {
glitz_set_operator (op->gl, op->render_op);
glitz_filter_enable (op->src, op);
}
if (op->alpha_mask.red)
alpha = op->alpha_mask.red;
else if (op->alpha_mask.green)
alpha = op->alpha_mask.green;
else if (op->alpha_mask.blue)
alpha = op->alpha_mask.blue;
else
alpha = op->alpha_mask.alpha;
op->gl->color_4us (0x0, 0x0, 0x0, alpha);
}
static void
_glitz_combine_solid_solid (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha),
SHORT_MULT (op->solid->green, op->alpha_mask.alpha),
SHORT_MULT (op->solid->blue, op->alpha_mask.alpha),
SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha));
}
static void
_glitz_combine_solid_argb (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_COMBINE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
GLITZ_GL_MODULATE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
GLITZ_GL_TEXTURE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
GLITZ_GL_SRC_ALPHA);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
GLITZ_GL_SRC_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA,
GLITZ_GL_MODULATE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA,
GLITZ_GL_TEXTURE);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA,
GLITZ_GL_PRIMARY_COLOR);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
GLITZ_GL_SRC_ALPHA);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA,
GLITZ_GL_SRC_ALPHA);
op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha),
SHORT_MULT (op->solid->green, op->alpha_mask.alpha),
SHORT_MULT (op->solid->blue, op->alpha_mask.alpha),
SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha));
}
/* This only works with the OVER operator. */
static void
_glitz_combine_solid_argbc (glitz_composite_op_t *op)
{
glitz_color_t solid;
solid.red = SHORT_MULT (op->solid->red, op->alpha_mask.alpha);
solid.green = SHORT_MULT (op->solid->green, op->alpha_mask.alpha);
solid.blue = SHORT_MULT (op->solid->blue, op->alpha_mask.alpha);
solid.alpha = SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha);
op->gl->enable (GLITZ_GL_BLEND);
op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR);
if (solid.alpha > 0)
op->gl->blend_color ((glitz_gl_clampf_t) solid.red / solid.alpha,
(glitz_gl_clampf_t) solid.green / solid.alpha,
(glitz_gl_clampf_t) solid.blue / solid.alpha,
1.0f);
else
op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f);
op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_MODULATE);
op->gl->color_4us (solid.alpha,
solid.alpha,
solid.alpha,
solid.alpha);
}
static void
_glitz_combine_solid_argbf (glitz_composite_op_t *op)
{
glitz_set_operator (op->gl, op->render_op);
glitz_filter_enable (op->mask, op);
op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha),
SHORT_MULT (op->solid->green, op->alpha_mask.alpha),
SHORT_MULT (op->solid->blue, op->alpha_mask.alpha),
SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha));
}
/* This only works with the OVER operator. */
static void
_glitz_combine_solid_solidc (glitz_composite_op_t *op)
{
op->gl->enable (GLITZ_GL_BLEND);
op->gl->blend_func (GLITZ_GL_CONSTANT_COLOR, GLITZ_GL_ONE_MINUS_SRC_COLOR);
if (op->solid->alpha > 0)
op->gl->blend_color ((glitz_gl_clampf_t) op->solid->red / op->solid->alpha,
(glitz_gl_clampf_t)
op->solid->green / op->solid->alpha,
(glitz_gl_clampf_t)
op->solid->blue / op->solid->alpha,
1.0f);
else
op->gl->blend_color (1.0f, 1.0f, 1.0f, 1.0f);
op->gl->color_4us (SHORT_MULT (op->alpha_mask.red, op->solid->alpha),
SHORT_MULT (op->alpha_mask.green, op->solid->alpha),
SHORT_MULT (op->alpha_mask.blue, op->solid->alpha),
SHORT_MULT (op->alpha_mask.alpha, op->solid->alpha));
}
static glitz_combine_t
_glitz_combine_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = {
{
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }
}, {
{ GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 },
{ GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 }
}, {
{ GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 },
{ GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 },
{ GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 }
}, {
{ GLITZ_COMBINE_TYPE_ARGBF, _glitz_combine_argbf_solid, 1, 1 },
{ GLITZ_COMBINE_TYPE_ARGBF_ARGB, _glitz_combine_argbf_solid, 2, 1 },
{ GLITZ_COMBINE_TYPE_ARGBF_ARGBC, _glitz_combine_argbf_argbc, 2, 1 },
{ GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 },
{ GLITZ_COMBINE_TYPE_ARGBF_SOLID, _glitz_combine_argbf_solid, 1, 1 },
{ GLITZ_COMBINE_TYPE_ARGBF_SOLIDC, _glitz_combine_argbf_solidc, 1, 1 }
}, {
{ GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 },
{ GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 }
}, {
{ GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 },
{ GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 },
{ GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 }
}
};
#define SURFACE_WRAP(surface, feature_mask) \
(SURFACE_REPEAT (surface)? \
(TEXTURE_REPEATABLE (&(surface)->texture) && \
( \
(!SURFACE_MIRRORED (surface)) || \
((feature_mask) & GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) \
) \
) \
: \
((SURFACE_PAD (surface))? \
(TEXTURE_PADABLE (&(surface)->texture)) \
: \
( \
(!SURFACE_PROJECTIVE_TRANSFORM (surface)) || \
((feature_mask) & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) \
) \
) \
)
static glitz_surface_type_t
_glitz_get_surface_type (glitz_surface_t *surface,
unsigned long feature_mask)
{
if (surface == NULL)
return GLITZ_SURFACE_TYPE_NULL;
if (SURFACE_SOLID (surface) &&
(SURFACE_REPEAT (surface) || SURFACE_PAD (surface))) {
if (SURFACE_COMPONENT_ALPHA (surface))
return GLITZ_SURFACE_TYPE_SOLIDC;
else
return GLITZ_SURFACE_TYPE_SOLID;
}
if (SURFACE_WRAP (surface, feature_mask)) {
if (SURFACE_FRAGMENT_FILTER (surface)) {
if (SURFACE_COMPONENT_ALPHA (surface))
return GLITZ_SURFACE_TYPE_NA;
if (feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)
return GLITZ_SURFACE_TYPE_ARGBF;
} else if (SURFACE_COMPONENT_ALPHA (surface)) {
return GLITZ_SURFACE_TYPE_ARGBC;
} else
return GLITZ_SURFACE_TYPE_ARGB;
}
return GLITZ_SURFACE_TYPE_NA;
}
static glitz_color_t _default_alpha_mask = {
0xffff, 0xffff, 0xffff, 0xffff
};
void
glitz_composite_op_init (glitz_composite_op_t *op,
glitz_operator_t render_op,
glitz_surface_t *src,
glitz_surface_t *mask,
glitz_surface_t *dst)
{
glitz_surface_type_t src_type;
glitz_surface_type_t mask_type;
glitz_combine_t *combine;
unsigned long feature_mask;
op->render_op = render_op;
op->type = GLITZ_COMBINE_TYPE_NA;
op->combine = NULL;
op->alpha_mask = _default_alpha_mask;
op->src = src;
op->mask = mask;
op->dst = dst;
op->count = 0;
op->solid = NULL;
op->per_component = 0;
op->fp = 0;
if (dst->attached)
{
op->gl = &dst->attached->backend->gl;
feature_mask = dst->attached->backend->feature_mask;
}
else
{
op->gl = &dst->drawable->backend->gl;
feature_mask = dst->drawable->backend->feature_mask;
}
src_type = _glitz_get_surface_type (src, feature_mask);
if (src_type < 1)
return;
mask_type = _glitz_get_surface_type (mask, feature_mask);
if (mask_type < 0)
return;
if (src_type == GLITZ_SURFACE_TYPE_SOLIDC)
src_type = GLITZ_SURFACE_TYPE_SOLID;
/* We can't do solid IN argbc OP dest, unless OP is OVER.
But we can do argb IN argbc OP dest, so lets just not use the
source as a solid color if this is the case. I need to figure out
a better way to handle special cases like this. */
if (src_type == GLITZ_SURFACE_TYPE_SOLID &&
(mask_type == GLITZ_SURFACE_TYPE_SOLIDC ||
mask_type == GLITZ_SURFACE_TYPE_ARGBC) &&
render_op != GLITZ_OPERATOR_OVER)
src_type = GLITZ_SURFACE_TYPE_ARGB;
combine = &_glitz_combine_map[src_type][mask_type];
if (!combine->type)
return;
if (dst->geometry.type == GLITZ_GEOMETRY_TYPE_BITMAP)
{
/* We can't do anything but solid colors with bitmaps yet. */
if (src_type != GLITZ_SURFACE_TYPE_SOLID ||
(mask_type != GLITZ_SURFACE_TYPE_NULL &&
mask_type != GLITZ_SURFACE_TYPE_SOLID))
return;
}
if (src_type == GLITZ_SURFACE_TYPE_SOLID) {
if (SURFACE_SOLID_DAMAGE (src)) {
glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
glitz_surface_sync_solid (src);
glitz_surface_pop_current (dst);
}
op->solid = &src->solid;
op->src = NULL;
}
if (mask_type == GLITZ_SURFACE_TYPE_SOLID) {
if (SURFACE_SOLID_DAMAGE (mask)) {
glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
glitz_surface_sync_solid (mask);
glitz_surface_pop_current (dst);
}
op->alpha_mask = mask->solid;
op->mask = NULL;
op->combine = combine;
} else if (mask_type == GLITZ_SURFACE_TYPE_SOLIDC) {
if (SURFACE_SOLID_DAMAGE (mask)) {
glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
glitz_surface_sync_solid (mask);
glitz_surface_pop_current (dst);
}
op->alpha_mask = mask->solid;
op->mask = NULL;
if (op->src) {
op->per_component = 4;
op->combine = combine;
} else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
op->combine = combine;
} else if (mask_type != GLITZ_SURFACE_TYPE_NULL) {
if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) {
if (op->src) {
/* we can't do component alpha with alpha only surfaces */
if (op->src->format->color.red_size) {
op->per_component = 4;
if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
op->combine = combine;
}
} else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
op->combine = combine;
} else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
op->combine = combine;
} else
op->combine = combine;
if (!(feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) {
if (op->src && op->mask)
op->combine = NULL;
}
if (op->per_component &&
(!(feature_mask & GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK)))
op->combine = NULL;
if (op->combine == combine) {
op->type = combine->type;
if (combine->source_shader) {
if (combine->source_shader == 1)
op->fp = glitz_filter_get_fragment_program (src, op);
else
op->fp = glitz_filter_get_fragment_program (mask, op);
if (op->fp == 0)
op->type = GLITZ_COMBINE_TYPE_NA;
}
}
}
void
glitz_composite_enable (glitz_composite_op_t *op)
{
op->combine->enable (op);
op->count++;
}
void
glitz_composite_disable (glitz_composite_op_t *op)
{
if (op->fp) {
op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0);
op->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM);
}
}

Просмотреть файл

@ -0,0 +1,127 @@
/*
* 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_context_init (glitz_context_t *context,
glitz_drawable_t *drawable)
{
glitz_drawable_reference (drawable);
context->ref_count = 1;
context->drawable = drawable;
context->closure = NULL;
context->lose_current = NULL;
}
void
_glitz_context_fini (glitz_context_t *context)
{
glitz_drawable_destroy (context->drawable);
}
glitz_context_t *
glitz_context_create (glitz_drawable_t *drawable,
glitz_drawable_format_t *format)
{
return drawable->backend->create_context (drawable, format);
}
slim_hidden_def(glitz_context_create);
void
glitz_context_destroy (glitz_context_t *context)
{
if (!context)
return;
context->ref_count--;
if (context->ref_count)
return;
context->drawable->backend->destroy_context (context);
}
slim_hidden_def(glitz_context_destroy);
void
glitz_context_reference (glitz_context_t *context)
{
if (!context)
return;
context->ref_count++;
}
slim_hidden_def(glitz_context_reference);
void
glitz_context_copy (glitz_context_t *src,
glitz_context_t *dst,
unsigned long mask)
{
src->drawable->backend->copy_context (src, dst, mask);
}
slim_hidden_def(glitz_context_copy);
void
glitz_context_set_user_data (glitz_context_t *context,
void *closure,
glitz_lose_current_function_t lose_current)
{
context->closure = closure;
context->lose_current = lose_current;
}
slim_hidden_def(glitz_context_set_user_data);
glitz_function_pointer_t
glitz_context_get_proc_address (glitz_context_t *context,
const char *name)
{
return context->drawable->backend->get_proc_address (context, name);
}
slim_hidden_def(glitz_context_get_proc_address);
void
glitz_context_make_current (glitz_context_t *context)
{
context->drawable->backend->make_current (context, context->drawable);
}
slim_hidden_def(glitz_context_make_current);
void
glitz_context_bind_texture (glitz_context_t *context,
glitz_surface_t *surface)
{
glitz_gl_proc_address_list_t *gl = &context->drawable->backend->gl;
if (!surface->texture.name)
gl->gen_textures (1, &surface->texture.name);
gl->bind_texture (surface->texture.target, surface->texture.name);
}
slim_hidden_def(glitz_context_bind_texture);

Просмотреть файл

@ -0,0 +1,147 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
glitz_drawable_format_t *
glitz_find_similar_drawable_format (glitz_drawable_t *other,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
return glitz_drawable_format_find (other->backend->drawable_formats,
other->backend->n_drawable_formats,
mask, templ, count);
}
slim_hidden_def(glitz_find_similar_drawable_format);
glitz_drawable_t *
glitz_create_pbuffer_drawable (glitz_drawable_t *other,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
if (!format->types.pbuffer)
return NULL;
return other->backend->create_pbuffer (other, format, width, height);
}
slim_hidden_def(glitz_create_pbuffer_drawable);
void
glitz_drawable_destroy (glitz_drawable_t *drawable)
{
if (!drawable)
return;
drawable->ref_count--;
if (drawable->ref_count)
return;
drawable->backend->destroy (drawable);
}
void
glitz_drawable_reference (glitz_drawable_t *drawable)
{
if (!drawable)
return;
drawable->ref_count++;
}
void
glitz_drawable_update_size (glitz_drawable_t *drawable,
unsigned int width,
unsigned int height)
{
drawable->width = (int) width;
drawable->height = (int) height;
drawable->viewport.x = -32767;
drawable->viewport.y = -32767;
drawable->viewport.width = 65535;
drawable->viewport.height = 65535;
drawable->update_all = 1;
}
unsigned int
glitz_drawable_get_width (glitz_drawable_t *drawable)
{
return (unsigned int) drawable->width;
}
slim_hidden_def(glitz_drawable_get_width);
unsigned int
glitz_drawable_get_height (glitz_drawable_t *drawable)
{
return (unsigned int) drawable->height;
}
slim_hidden_def(glitz_drawable_get_height);
void
glitz_drawable_swap_buffers (glitz_drawable_t *drawable)
{
if (drawable->format->doublebuffer)
drawable->backend->swap_buffers (drawable);
}
slim_hidden_def(glitz_drawable_swap_buffers);
void
glitz_drawable_flush (glitz_drawable_t *drawable)
{
drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT);
drawable->backend->gl.flush ();
drawable->backend->pop_current (drawable);
}
slim_hidden_def(glitz_drawable_flush);
void
glitz_drawable_finish (glitz_drawable_t *drawable)
{
drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT);
drawable->backend->gl.finish ();
drawable->backend->pop_current (drawable);
}
slim_hidden_def(glitz_drawable_finish);
unsigned long
glitz_drawable_get_features (glitz_drawable_t *drawable)
{
return drawable->backend->feature_mask;
}
slim_hidden_def(glitz_drawable_get_features);
glitz_drawable_format_t *
glitz_drawable_get_format (glitz_drawable_t *drawable)
{
return drawable->format;
}
slim_hidden_def(glitz_drawable_get_format);

Просмотреть файл

@ -0,0 +1,425 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
struct _glitz_filter_params_t {
int fp_type;
int id;
glitz_vec4_t *vectors;
int n_vectors;
};
static glitz_status_t
_glitz_filter_params_ensure (glitz_surface_t *surface,
int vectors)
{
int size;
size = sizeof (glitz_filter_params_t) + vectors * sizeof (glitz_vec4_t);
if (!surface->filter_params ||
surface->filter_params->n_vectors != vectors)
{
if (surface->filter_params)
free (surface->filter_params);
surface->filter_params = malloc (size);
if (surface->filter_params == NULL)
return GLITZ_STATUS_NO_MEMORY;
surface->filter_params->fp_type = 0;
surface->filter_params->id = 0;
surface->filter_params->vectors =
(glitz_vec4_t *) (surface->filter_params + 1);
surface->filter_params->n_vectors = vectors;
}
return GLITZ_STATUS_SUCCESS;
}
static void
_glitz_filter_params_set (glitz_float_t *value,
const glitz_float_t default_value,
glitz_fixed16_16_t **params,
int *n_params)
{
if (*n_params > 0) {
*value = FIXED_TO_FLOAT (**params);
(*params)++;
(*n_params)--;
} else
*value = default_value;
}
static int
_glitz_color_stop_compare (const void *elem1, const void *elem2)
{
return
(((glitz_vec4_t *) elem1)->v[2] == ((glitz_vec4_t *) elem2)->v[2]) ?
/* equal offsets, sort on id */
((((glitz_vec4_t *) elem1)->v[3] <
((glitz_vec4_t *) elem2)->v[3]) ? -1 : 1) :
/* sort on offset */
((((glitz_vec4_t *) elem1)->v[2] <
((glitz_vec4_t *) elem2)->v[2]) ? -1 : 1);
}
glitz_status_t
glitz_filter_set_params (glitz_surface_t *surface,
glitz_filter_t filter,
glitz_fixed16_16_t *params,
int n_params)
{
glitz_vec4_t *vecs;
int i, size = 0;
switch (filter) {
case GLITZ_FILTER_CONVOLUTION: {
glitz_float_t dm, dn;
int cx, cy, m, n, j;
_glitz_filter_params_set (&dm, 3.0f, &params, &n_params);
_glitz_filter_params_set (&dn, 3.0f, &params, &n_params);
m = dm;
n = dn;
size = m * n;
if (_glitz_filter_params_ensure (surface, size))
return GLITZ_STATUS_NO_MEMORY;
vecs = surface->filter_params->vectors;
surface->filter_params->id = 0;
/* center point is rounded down in case dimensions are not even */
cx = m / 2;
cy = n / 2;
for (i = 0; i < m; i++) {
glitz_vec4_t *vec;
glitz_float_t weight;
for (j = 0; j < n; j++) {
_glitz_filter_params_set (&weight, 0.0f, &params, &n_params);
if (weight != 0.0f) {
vec = &vecs[surface->filter_params->id++];
vec->v[0] = (i - cx) * surface->texture.texcoord_width_unit;
vec->v[1] = (cy - j) * surface->texture.texcoord_height_unit;
vec->v[2] = weight;
vec->v[3] = 0.0f;
}
}
}
} break;
case GLITZ_FILTER_GAUSSIAN: {
glitz_float_t radius, sigma, alpha, scale, xy_scale, sum;
int half_size, x, y;
_glitz_filter_params_set (&radius, 1.0f, &params, &n_params);
glitz_clamp_value (&radius, 0.0f, 1024.0f);
_glitz_filter_params_set (&sigma, radius / 2.0f, &params, &n_params);
glitz_clamp_value (&sigma, 0.0f, 1024.0f);
_glitz_filter_params_set (&alpha, radius, &params, &n_params);
glitz_clamp_value (&alpha, 0.0f, 1024.0f);
scale = 1.0f / (2.0f * GLITZ_PI * sigma * sigma);
half_size = alpha + 0.5f;
if (half_size == 0)
half_size = 1;
size = half_size * 2 + 1;
xy_scale = 2.0f * radius / size;
if (_glitz_filter_params_ensure (surface, size * size))
return GLITZ_STATUS_NO_MEMORY;
vecs = surface->filter_params->vectors;
surface->filter_params->id = 0;
sum = 0.0f;
for (x = 0; x < size; x++) {
glitz_vec4_t *vec;
glitz_float_t fx, fy, amp;
fx = xy_scale * (x - half_size);
for (y = 0; y < size; y++) {
fy = xy_scale * (y - half_size);
amp = scale * exp ((-1.0f * (fx * fx + fy * fy)) /
(2.0f * sigma * sigma));
if (amp > 0.0f) {
vec = &vecs[surface->filter_params->id++];
vec->v[0] = fx * surface->texture.texcoord_width_unit;
vec->v[1] = fy * surface->texture.texcoord_height_unit;
vec->v[2] = amp;
vec->v[3] = 0.0f;
sum += amp;
}
}
}
/* normalize */
if (sum != 0.0f)
sum = 1.0f / sum;
for (i = 0; i < surface->filter_params->id; i++)
vecs[i].v[2] *= sum;
} break;
case GLITZ_FILTER_LINEAR_GRADIENT:
case GLITZ_FILTER_RADIAL_GRADIENT:
if (n_params <= 4) {
if (surface->box.x2 == 1)
size = surface->box.y2;
else if (surface->box.y2 == 1)
size = surface->box.x2;
} else
size = (n_params - 2) / 3;
if (size < 2)
size = 2;
if (_glitz_filter_params_ensure (surface, size + 1))
return GLITZ_STATUS_NO_MEMORY;
vecs = surface->filter_params->vectors;
if (filter == GLITZ_FILTER_LINEAR_GRADIENT) {
glitz_float_t length, angle, dh, dv;
glitz_float_t start_x, start_y, stop_x, stop_y;
_glitz_filter_params_set (&start_x, 0.0f, &params, &n_params);
_glitz_filter_params_set (&start_y, 0.0f, &params, &n_params);
_glitz_filter_params_set (&stop_x, 1.0f, &params, &n_params);
_glitz_filter_params_set (&stop_y, 0.0f, &params, &n_params);
dh = stop_x - start_x;
dv = stop_y - start_y;
length = sqrtf (dh * dh + dv * dv);
angle = -atan2f (dv, dh);
vecs->v[2] = cosf (angle);
vecs->v[3] = -sinf (angle);
vecs->v[0] = vecs->v[2] * start_x;
vecs->v[0] += vecs->v[3] * start_y;
vecs->v[1] = (length)? 1.0f / length: 2147483647.0f;
} else {
glitz_float_t r0, r1;
_glitz_filter_params_set (&vecs->v[0], 0.5f, &params, &n_params);
_glitz_filter_params_set (&vecs->v[1], 0.5f, &params, &n_params);
_glitz_filter_params_set (&r0, 0.0f, &params, &n_params);
_glitz_filter_params_set (&r1, 0.5f, &params, &n_params);
glitz_clamp_value (&r0, 0.0f, r1);
vecs->v[2] = r0;
if (r1 != r0)
vecs->v[3] = 1.0f / (r1 - r0);
else
vecs->v[3] = 2147483647.0f;
}
vecs++;
surface->filter_params->id = size;
for (i = 0; i < size; i++) {
glitz_float_t x_default, y_default, o_default;
o_default = i / (glitz_float_t) (size - 1);
x_default = (surface->box.x2 * i) / (glitz_float_t) size;
y_default = (surface->box.y2 * i) / (glitz_float_t) size;
_glitz_filter_params_set (&vecs[i].v[2], o_default, &params, &n_params);
_glitz_filter_params_set (&vecs[i].v[0], x_default, &params, &n_params);
_glitz_filter_params_set (&vecs[i].v[1], y_default, &params, &n_params);
glitz_clamp_value (&vecs[i].v[2], 0.0f, 1.0f);
glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->box.x2 - 1.0f);
glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->box.y2 - 1.0f);
vecs[i].v[0] += 0.5f;
vecs[i].v[1] += 0.5f;
vecs[i].v[0] += surface->texture.box.x1;
vecs[i].v[1] = surface->texture.box.y2 - vecs[i].v[1];
vecs[i].v[0] *= surface->texture.texcoord_width_unit;
vecs[i].v[1] *= surface->texture.texcoord_height_unit;
vecs[i].v[3] = i;
}
/* sort color stops in ascending order */
qsort (vecs, surface->filter_params->id, sizeof (glitz_vec4_t),
_glitz_color_stop_compare);
for (i = 0; i < size; i++) {
glitz_float_t diff;
if ((i + 1) == size)
diff = 1.0f - vecs[i].v[2];
else
diff = vecs[i + 1].v[2] - vecs[i].v[2];
if (diff != 0.0f)
vecs[i].v[3] = 1.0f / diff;
else
vecs[i].v[3] = 2147483647.0f; /* should be FLT_MAX, but this will do */
}
break;
case GLITZ_FILTER_BILINEAR:
case GLITZ_FILTER_NEAREST:
if (surface->filter_params)
free (surface->filter_params);
surface->filter_params = NULL;
break;
}
glitz_filter_set_type (surface, filter);
return GLITZ_STATUS_SUCCESS;
}
glitz_gl_uint_t
glitz_filter_get_fragment_program (glitz_surface_t *surface,
glitz_composite_op_t *op)
{
return glitz_get_fragment_program (op,
surface->filter_params->fp_type,
surface->filter_params->id);
}
void
glitz_filter_set_type (glitz_surface_t *surface,
glitz_filter_t filter)
{
switch (filter) {
case GLITZ_FILTER_CONVOLUTION:
case GLITZ_FILTER_GAUSSIAN:
surface->filter_params->fp_type = GLITZ_FP_CONVOLUTION;
break;
case GLITZ_FILTER_LINEAR_GRADIENT:
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
if (SURFACE_MIRRORED (surface))
surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_REFLECT;
else
surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_REPEAT;
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_NEAREST;
} else
surface->filter_params->fp_type = GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT;
break;
case GLITZ_FILTER_RADIAL_GRADIENT:
if (surface->flags & GLITZ_SURFACE_FLAG_REPEAT_MASK) {
if (SURFACE_MIRRORED (surface))
surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_REFLECT;
else
surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_REPEAT;
} else if (surface->flags & GLITZ_SURFACE_FLAG_PAD_MASK) {
surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_NEAREST;
} else
surface->filter_params->fp_type = GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT;
break;
case GLITZ_FILTER_BILINEAR:
case GLITZ_FILTER_NEAREST:
break;
}
}
void
glitz_filter_enable (glitz_surface_t *surface,
glitz_composite_op_t *op)
{
glitz_gl_proc_address_list_t *gl = op->gl;
int i;
gl->enable (GLITZ_GL_FRAGMENT_PROGRAM);
gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, op->fp);
switch (surface->filter) {
case GLITZ_FILTER_GAUSSIAN:
case GLITZ_FILTER_CONVOLUTION:
for (i = 0; i < surface->filter_params->id; i++)
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i,
surface->filter_params->vectors[i].v);
break;
case GLITZ_FILTER_LINEAR_GRADIENT:
case GLITZ_FILTER_RADIAL_GRADIENT: {
int j, fp_type = surface->filter_params->fp_type;
glitz_vec4_t *vec;
vec = surface->filter_params->vectors;
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 0, vec->v);
vec++;
if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT ||
fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) {
glitz_vec4_t v;
v.v[0] = v.v[1] = -1.0f;
v.v[2] = 0.0f;
v.v[3] = (vec->v[3])? 1.0f / vec->v[3]: 1.0f;
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, 1, v.v);
j = 2;
} else
j = 1;
for (i = 0; i < surface->filter_params->id; i++, vec++)
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i + j, vec->v);
if (fp_type == GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT ||
fp_type == GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT) {
glitz_vec4_t v;
v.v[0] = v.v[1] = -1.0f;
v.v[2] = v.v[3] = 1.0f;
gl->program_local_param_4fv (GLITZ_GL_FRAGMENT_PROGRAM, i + j, v.v);
}
} break;
case GLITZ_FILTER_BILINEAR:
case GLITZ_FILTER_NEAREST:
break;
}
}

Просмотреть файл

@ -0,0 +1,285 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#include <stdlib.h>
struct _texture_format {
glitz_gl_int_t texture_format;
glitz_format_t format;
} _texture_formats[] = {
{ GLITZ_GL_ALPHA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 4 } } },
{ GLITZ_GL_ALPHA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 8 } } },
{ GLITZ_GL_ALPHA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 12 } } },
{ GLITZ_GL_ALPHA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 16 } } },
{ GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 3, 3, 2, 0 } } },
{ GLITZ_GL_RGB4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 0 } } },
{ GLITZ_GL_RGB5, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 6, 5, 0 } } },
{ GLITZ_GL_RGB8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 0 } } },
{ GLITZ_GL_RGB10, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 0 } } },
{ GLITZ_GL_RGB12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 0 } } },
{ GLITZ_GL_RGB16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 0 } } },
{ GLITZ_GL_RGBA2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 2, 2, 2, 2 } } },
{ GLITZ_GL_RGB5_A1, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 5, 5, 1 } } },
{ GLITZ_GL_RGBA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 4 } } },
{ GLITZ_GL_RGBA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 8 } } },
{ GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 2 } } },
{ GLITZ_GL_RGBA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } },
{ GLITZ_GL_RGBA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } }
};
static void
_glitz_add_texture_format (glitz_format_t **formats,
glitz_gl_int_t **texture_formats,
int *n_formats,
glitz_gl_int_t texture_format,
glitz_format_t *format)
{
*formats = realloc (*formats, sizeof (glitz_format_t) * (*n_formats + 1));
*texture_formats = realloc (*texture_formats,
sizeof (glitz_gl_enum_t) * (*n_formats + 1));
if (*formats && *texture_formats) {
(*texture_formats)[*n_formats] = texture_format;
(*formats)[*n_formats] = *format;
(*formats)[*n_formats].id = *n_formats;
(*n_formats)++;
} else
*n_formats = 0;
}
void
glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
glitz_format_t **formats,
glitz_gl_int_t **texture_formats,
int *n_formats)
{
glitz_gl_int_t value;
int i, n_texture_formats;
n_texture_formats =
sizeof (_texture_formats) / sizeof (struct _texture_format);
for (i = 0; i < n_texture_formats; i++) {
gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0,
_texture_formats[i].texture_format, 1, 1, 0,
GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
switch (_texture_formats[i].format.type) {
case GLITZ_FORMAT_TYPE_COLOR:
if (_texture_formats[i].format.color.red_size) {
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
GLITZ_GL_TEXTURE_RED_SIZE, &value);
if (value != _texture_formats[i].format.color.red_size)
continue;
}
if (_texture_formats[i].format.color.green_size) {
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
GLITZ_GL_TEXTURE_GREEN_SIZE, &value);
if (value != _texture_formats[i].format.color.green_size)
continue;
}
if (_texture_formats[i].format.color.blue_size) {
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
GLITZ_GL_TEXTURE_BLUE_SIZE, &value);
if (value != _texture_formats[i].format.color.blue_size)
continue;
}
if (_texture_formats[i].format.color.alpha_size) {
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
GLITZ_GL_TEXTURE_ALPHA_SIZE, &value);
if (value != _texture_formats[i].format.color.alpha_size)
continue;
}
break;
default:
continue;
}
_glitz_add_texture_format (formats,
texture_formats,
n_formats,
_texture_formats[i].texture_format,
&_texture_formats[i].format);
}
}
glitz_drawable_format_t *
glitz_drawable_format_find (glitz_drawable_format_t *formats,
int n_formats,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
for (; n_formats; n_formats--, formats++) {
if (mask & GLITZ_FORMAT_ID_MASK)
if (templ->id != formats->id)
continue;
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
if (templ->color.red_size != formats->color.red_size)
continue;
if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
if (templ->color.green_size != formats->color.green_size)
continue;
if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
if (templ->color.blue_size != formats->color.blue_size)
continue;
if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
if (templ->color.alpha_size != formats->color.alpha_size)
continue;
if (mask & GLITZ_FORMAT_DEPTH_SIZE_MASK)
if (templ->depth_size != formats->depth_size)
continue;
if (mask & GLITZ_FORMAT_STENCIL_SIZE_MASK)
if (templ->stencil_size != formats->stencil_size)
continue;
if (mask & GLITZ_FORMAT_DOUBLEBUFFER_MASK)
if (templ->doublebuffer != formats->doublebuffer)
continue;
if (mask & GLITZ_FORMAT_SAMPLES_MASK)
if (templ->samples != formats->samples)
continue;
if (mask & GLITZ_FORMAT_WINDOW_MASK)
if (templ->types.window != formats->types.window)
continue;
if (mask & GLITZ_FORMAT_PBUFFER_MASK)
if (templ->types.pbuffer != formats->types.pbuffer)
continue;
if (count-- == 0)
return formats;
}
return NULL;
}
static glitz_format_t *
_glitz_format_find (glitz_format_t *formats,
int n_formats,
unsigned long mask,
const glitz_format_t *templ,
int count)
{
for (; n_formats; n_formats--, formats++) {
if (mask & GLITZ_FORMAT_ID_MASK)
if (templ->id != formats->id)
continue;
if (mask & GLITZ_FORMAT_TYPE_MASK)
if (templ->type != formats->type)
continue;
if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
if (templ->color.red_size != formats->color.red_size)
continue;
if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
if (templ->color.green_size != formats->color.green_size)
continue;
if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
if (templ->color.blue_size != formats->color.blue_size)
continue;
if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
if (templ->color.alpha_size != formats->color.alpha_size)
continue;
if (count-- == 0)
return formats;
}
return NULL;
}
glitz_format_t *
glitz_find_format (glitz_drawable_t *drawable,
unsigned long mask,
const glitz_format_t *templ,
int count)
{
return _glitz_format_find (drawable->backend->formats,
drawable->backend->n_formats,
mask, templ, count);
}
glitz_format_t *
glitz_find_standard_format (glitz_drawable_t *drawable,
glitz_format_name_t format_name)
{
glitz_format_t templ;
unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK |
GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK |
GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK;
templ.type = GLITZ_FORMAT_TYPE_COLOR;
switch (format_name) {
case GLITZ_STANDARD_ARGB32:
templ.color.red_size = 8;
templ.color.green_size = 8;
templ.color.blue_size = 8;
templ.color.alpha_size = 8;
break;
case GLITZ_STANDARD_RGB24:
templ.color.red_size = 8;
templ.color.green_size = 8;
templ.color.blue_size = 8;
templ.color.alpha_size = 0;
break;
case GLITZ_STANDARD_A8:
templ.color.red_size = 0;
templ.color.green_size = 0;
templ.color.blue_size = 0;
templ.color.alpha_size = 8;
break;
case GLITZ_STANDARD_A1:
templ.color.red_size = 0;
templ.color.green_size = 0;
templ.color.blue_size = 0;
templ.color.alpha_size = 1;
break;
}
return glitz_find_format (drawable, mask, &templ, 0);
}

Просмотреть файл

@ -0,0 +1,76 @@
/*
* 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)
{
if (framebuffer->name)
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);
}

Просмотреть файл

@ -0,0 +1,681 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
static glitz_gl_enum_t
_glitz_data_type (glitz_data_type_t type)
{
switch (type) {
case GLITZ_DATA_TYPE_SHORT:
return GLITZ_GL_SHORT;
case GLITZ_DATA_TYPE_INT:
return GLITZ_GL_INT;
case GLITZ_DATA_TYPE_DOUBLE:
return GLITZ_GL_DOUBLE;
default:
return GLITZ_GL_FLOAT;
}
}
void
glitz_set_geometry (glitz_surface_t *dst,
glitz_geometry_type_t type,
glitz_geometry_format_t *format,
glitz_buffer_t *buffer)
{
switch (type) {
case GLITZ_GEOMETRY_TYPE_VERTEX:
{
glitz_buffer_reference (buffer);
if (dst->geometry.buffer)
glitz_buffer_destroy (dst->geometry.buffer);
dst->geometry.buffer = buffer;
dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX;
switch (format->vertex.primitive) {
case GLITZ_PRIMITIVE_POINTS:
dst->geometry.u.v.prim = GLITZ_GL_POINTS;
break;
case GLITZ_PRIMITIVE_LINES:
dst->geometry.u.v.prim = GLITZ_GL_LINES;
break;
case GLITZ_PRIMITIVE_LINE_STRIP:
dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP;
break;
case GLITZ_PRIMITIVE_LINE_LOOP:
dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP;
break;
case GLITZ_PRIMITIVE_TRIANGLES:
dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES;
break;
case GLITZ_PRIMITIVE_TRIANGLE_STRIP:
dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP;
break;
case GLITZ_PRIMITIVE_TRIANGLE_FAN:
dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN;
break;
case GLITZ_PRIMITIVE_QUADS:
dst->geometry.u.v.prim = GLITZ_GL_QUADS;
break;
case GLITZ_PRIMITIVE_QUAD_STRIP:
dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP;
break;
default:
dst->geometry.u.v.prim = GLITZ_GL_POLYGON;
break;
}
dst->geometry.u.v.type = _glitz_data_type (format->vertex.type);
dst->geometry.stride = format->vertex.bytes_per_vertex;
dst->geometry.attributes = format->vertex.attributes;
if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK)
{
dst->geometry.u.v.src.type =
_glitz_data_type (format->vertex.src.type);
dst->geometry.u.v.src.offset = format->vertex.src.offset;
if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY)
dst->geometry.u.v.src.size = 2;
else
dst->geometry.u.v.src.size = 1;
}
if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK)
{
dst->geometry.u.v.mask.type =
_glitz_data_type (format->vertex.mask.type);
dst->geometry.u.v.mask.offset = format->vertex.mask.offset;
if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY)
dst->geometry.u.v.mask.size = 2;
else
dst->geometry.u.v.mask.size = 1;
}
} break;
case GLITZ_GEOMETRY_TYPE_BITMAP:
glitz_buffer_reference (buffer);
if (dst->geometry.buffer)
glitz_buffer_destroy (dst->geometry.buffer);
dst->geometry.buffer = buffer;
dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP;
if (format->bitmap.scanline_order ==
GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
dst->geometry.u.b.top_down = 1;
else
dst->geometry.u.b.top_down = 0;
switch (format->bitmap.pad) {
case 2:
dst->geometry.u.b.pad = 2;
break;
case 4:
dst->geometry.u.b.pad = 4;
break;
case 8:
dst->geometry.u.b.pad = 8;
break;
default:
dst->geometry.u.b.pad = 1;
break;
}
dst->geometry.stride = format->bitmap.bytes_per_line;
dst->geometry.attributes = 0;
break;
default:
dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE;
if (dst->geometry.buffer)
glitz_buffer_destroy (dst->geometry.buffer);
dst->geometry.buffer = NULL;
dst->geometry.attributes = 0;
break;
}
}
slim_hidden_def(glitz_set_geometry);
void
glitz_set_array (glitz_surface_t *dst,
int first,
int size,
unsigned int count,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off)
{
if (dst->geometry.array)
{
glitz_multi_array_destroy (dst->geometry.array);
dst->geometry.array = NULL;
}
dst->geometry.first = first;
dst->geometry.size = size;
dst->geometry.count = count;
dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off);
dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off);
}
slim_hidden_def(glitz_set_array);
glitz_multi_array_t *
glitz_multi_array_create (unsigned int size)
{
glitz_multi_array_t *array;
int alloc_size;
if (!size)
return NULL;
alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) +
sizeof (int) +
sizeof (unsigned int) +
sizeof (glitz_vec2_t) +
sizeof (int)) * (size);
array = (glitz_multi_array_t *) malloc (alloc_size);
if (array == NULL)
return NULL;
array->ref_count = 1;
array->size = size;
array->first = (int *) (array + 1);
array->sizes = (int *) (array->first + size);
array->count = (int *) (array->sizes + size);
array->off = (glitz_vec2_t *) (array->count + size);
array->span = (int *) (array->off + size);
array->n_arrays = 0;
return array;
}
slim_hidden_def(glitz_multi_array_create);
void
glitz_multi_array_destroy (glitz_multi_array_t *array)
{
if (!array)
return;
array->ref_count--;
if (array->ref_count)
return;
free (array);
}
void
glitz_multi_array_reference (glitz_multi_array_t *array)
{
if (array == NULL)
return;
array->ref_count++;
}
void
glitz_multi_array_add (glitz_multi_array_t *array,
int first,
int size,
unsigned int count,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off)
{
int i;
if (array->size == array->n_arrays)
return;
i = array->n_arrays++;
array->first[i] = first;
array->sizes[i] = size;
array->count[i] = count;
array->span[i] = 0;
if (i == 0 || x_off || y_off)
{
array->off[i].v[0] = FIXED_TO_FLOAT (x_off);
array->off[i].v[1] = FIXED_TO_FLOAT (y_off);
array->current_span = &array->span[i];
}
(*array->current_span)++;
}
slim_hidden_def(glitz_multi_array_add);
void
glitz_multi_array_reset (glitz_multi_array_t *array)
{
array->n_arrays = 0;
}
slim_hidden_def(glitz_multi_array_reset);
void
glitz_set_multi_array (glitz_surface_t *dst,
glitz_multi_array_t *array,
glitz_fixed16_16_t x_off,
glitz_fixed16_16_t y_off)
{
glitz_multi_array_reference (array);
if (dst->geometry.array)
glitz_multi_array_destroy (dst->geometry.array);
dst->geometry.array = array;
dst->geometry.count = array->n_arrays;
dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off);
dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off);
}
slim_hidden_def(glitz_set_multi_array);
void
glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_box_t *box)
{
dst->geometry.data[0] = (glitz_float_t) box->x1;
dst->geometry.data[1] = (glitz_float_t) box->y1;
dst->geometry.data[2] = (glitz_float_t) box->x2;
dst->geometry.data[3] = (glitz_float_t) box->y1;
dst->geometry.data[4] = (glitz_float_t) box->x2;
dst->geometry.data[5] = (glitz_float_t) box->y2;
dst->geometry.data[6] = (glitz_float_t) box->x1;
dst->geometry.data[7] = (glitz_float_t) box->y2;
gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data);
}
void
glitz_geometry_enable (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_box_t *box)
{
switch (dst->geometry.type) {
case GLITZ_GEOMETRY_TYPE_VERTEX:
gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride,
glitz_buffer_bind (dst->geometry.buffer,
GLITZ_GL_ARRAY_BUFFER));
break;
case GLITZ_GEOMETRY_TYPE_BITMAP:
dst->geometry.u.b.base =
glitz_buffer_bind (dst->geometry.buffer,
GLITZ_GL_PIXEL_UNPACK_BUFFER);
gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0);
gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0);
#if BITMAP_BIT_ORDER == MSBFirst
gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE);
#else
gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE);
#endif
break;
case GLITZ_GEOMETRY_TYPE_NONE:
glitz_geometry_enable_none (gl, dst, box);
}
}
void
glitz_geometry_disable (glitz_surface_t *dst)
{
if (dst->geometry.buffer)
glitz_buffer_unbind (dst->geometry.buffer);
}
static void
_glitz_draw_rectangle (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_box_t *bounds,
int damage)
{
glitz_box_t *clip = dst->clip;
int n_clip = dst->n_clip;
glitz_box_t box;
int target_height = SURFACE_DRAWABLE_HEIGHT (dst);
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds->x1 > box.x1)
box.x1 = bounds->x1;
if (bounds->y1 > box.y1)
box.y1 = bounds->y1;
if (bounds->x2 < box.x2)
box.x2 = bounds->x2;
if (bounds->y2 < box.y2)
box.y2 = bounds->y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
gl->scissor (box.x1 + dst->x,
target_height - dst->y - box.y2,
box.x2 - box.x1, box.y2 - box.y1);
gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
if (damage)
glitz_surface_damage (dst, &box, damage);
}
clip++;
}
}
#define MULTI_DRAW_ARRAYS(surface) \
((surface)->drawable->backend->feature_mask & \
GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK)
static void
_glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_box_t *bounds,
int damage)
{
glitz_multi_array_t *array = dst->geometry.array;
glitz_box_t *clip = dst->clip;
int i, n_clip = dst->n_clip;
glitz_box_t box;
int target_height = SURFACE_DRAWABLE_HEIGHT (dst);
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds->x1 > box.x1)
box.x1 = bounds->x1;
if (bounds->y1 > box.y1)
box.y1 = bounds->y1;
if (bounds->x2 < box.x2)
box.x2 = bounds->x2;
if (bounds->y2 < box.y2)
box.y2 = bounds->y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
gl->scissor (box.x1 + dst->x,
target_height - dst->y - box.y2,
box.x2 - box.x1, box.y2 - box.y1);
gl->push_matrix ();
if (dst->geometry.off.v[0] || dst->geometry.off.v[1])
gl->translate_f (dst->geometry.off.v[0],
dst->geometry.off.v[1], 0.0f);
if (array)
{
for (i = 0; i < array->n_arrays;)
{
gl->translate_f (array->off[i].v[0],
array->off[i].v[1], 0.0f);
if (MULTI_DRAW_ARRAYS (dst))
{
gl->multi_draw_arrays (dst->geometry.u.v.prim,
&array->first[i],
&array->count[i],
array->span[i]);
i += array->span[i];
}
else
{
do {
if (array->count[i])
gl->draw_arrays (dst->geometry.u.v.prim,
array->first[i],
array->count[i]);
} while (array->span[++i] == 0);
}
}
} else
gl->draw_arrays (dst->geometry.u.v.prim,
dst->geometry.first,
dst->geometry.count);
gl->pop_matrix ();
if (damage)
glitz_surface_damage (dst, &box, damage);
}
clip++;
}
}
#define N_STACK_BITMAP 128
#define BITMAP_PAD 4
#define BITMAP_STRIDE(x, w, a) \
(((((x) & 3) + (w) + (((a) << 3) - 1)) / ((a) << 3)) * (a))
#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \
(_w) = (size); \
(_h) = (count); \
(_b_off) = (first) >> 3; \
if ((_p_off) != ((first) & 3)) \
{ \
(_p_off) = (first) & 3; \
gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \
} \
if ((dst)->geometry.u.b.top_down) \
{ \
dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \
if ((dst)->geometry.stride) \
src_stride = (dst)->geometry.stride; \
else \
src_stride = BITMAP_STRIDE ((first), _w, \
(dst)->geometry.u.b.pad); \
min_stride = MIN (src_stride, dst_stride); \
base = (dst)->geometry.u.b.base + (_b_off); \
y = (_h); \
while (y--) \
memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \
base + y * src_stride, \
min_stride); \
(_b_off) = 0; \
}
/* TODO: clipping could be done without glScissor, that might be
faster. Other then solid colors can be used if bitmap fits into a
stipple pattern. Maybe we should add a repeat parameter to
glitz_bitmap_format_t as 2, 4, 8, 16 and 32 sized bitmaps can be tiled.
*/
static void
_glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_box_t *bounds,
int damage)
{
glitz_multi_array_t *array = dst->geometry.array;
glitz_box_t *clip = dst->clip;
int n, i, n_clip = dst->n_clip;
int x, y, w, h, min_stride, dst_stride, src_stride;
glitz_gl_ubyte_t *heap_bitmap = NULL;
glitz_gl_ubyte_t stack_bitmap[N_STACK_BITMAP];
glitz_gl_ubyte_t *base, *bitmap = dst->geometry.u.b.base;
int byte_offset, pixel_offset = 0;
glitz_float_t x_off, y_off;
glitz_box_t box;
int target_height = SURFACE_DRAWABLE_HEIGHT (dst);
if (dst->geometry.u.b.top_down)
{
int max_size = 0;
if (array)
{
int size;
for (i = 0, n = array->n_arrays; n--; i++)
{
x = array->first[i];
w = array->sizes[i];
size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i];
if (size > max_size)
max_size = size;
}
}
else
{
x = dst->geometry.first;
w = dst->geometry.size;
max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count;
}
if (max_size > N_STACK_BITMAP)
{
heap_bitmap = malloc (max_size);
if (!heap_bitmap)
{
glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
bitmap = heap_bitmap;
} else
bitmap = stack_bitmap;
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD);
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
}
else
{
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad);
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH,
dst->geometry.stride * 8);
}
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (bounds->x1 > box.x1)
box.x1 = bounds->x1;
if (bounds->y1 > box.y1)
box.y1 = bounds->y1;
if (bounds->x2 < box.x2)
box.x2 = bounds->x2;
if (bounds->y2 < box.y2)
box.y2 = bounds->y2;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
gl->scissor (box.x1 + dst->x,
target_height - dst->y - box.y2,
box.x2 - box.x1, box.y2 - box.y1);
x_off = dst->x + dst->geometry.off.v[0];
y_off = dst->y + dst->geometry.off.v[1];
if (array)
{
x_off += array->off->v[0];
y_off += array->off->v[1];
glitz_set_raster_pos (gl, x_off, target_height - y_off);
for (i = 0, n = array->n_arrays; n--; i++)
{
if (n)
{
x_off = array->off[i + 1].v[0];
y_off = array->off[i + 1].v[1];
}
BITMAP_SETUP (dst,
array->first[i],
array->sizes[i],
array->count[i],
w, h, byte_offset, pixel_offset);
gl->bitmap (w, h,
0.0f, (glitz_gl_float_t) array->count[i],
x_off, -y_off,
bitmap + byte_offset);
}
}
else
{
glitz_set_raster_pos (gl, x_off, target_height - y_off);
BITMAP_SETUP (dst,
dst->geometry.first,
dst->geometry.size,
dst->geometry.count,
w, h, byte_offset, pixel_offset);
gl->bitmap (w, h,
0.0f, (glitz_gl_float_t) dst->geometry.count,
0.0f, 0.0f,
bitmap + byte_offset);
}
if (damage)
glitz_surface_damage (dst, &box, damage);
}
clip++;
}
if (heap_bitmap)
free (heap_bitmap);
}
void
glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl,
glitz_surface_t *dst,
glitz_geometry_type_t type,
glitz_box_t *bounds,
int damage)
{
switch (type) {
case GLITZ_GEOMETRY_TYPE_VERTEX:
_glitz_draw_vertex_arrays (gl, dst, bounds, damage);
break;
case GLITZ_GEOMETRY_TYPE_BITMAP:
_glitz_draw_bitmap_arrays (gl, dst, bounds, damage);
break;
case GLITZ_GEOMETRY_TYPE_NONE:
_glitz_draw_rectangle (gl, dst, bounds, damage);
break;
}
}

Просмотреть файл

@ -0,0 +1,533 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Authors: David Reveman <davidr@novell.com>
* Peter Nilsson <c99pnn@cs.umu.se>
*/
#ifndef GLITZ_GL_H_INCLUDED
#define GLITZ_GL_H_INCLUDED
#include <stddef.h>
#ifdef _WIN32
#define GLITZ_GL_API_ATTRIBUTE __stdcall
#else
#define GLITZ_GL_API_ATTRIBUTE
#endif
typedef unsigned int glitz_gl_enum_t;
typedef unsigned char glitz_gl_boolean_t;
typedef void glitz_gl_void_t;
typedef int glitz_gl_int_t;
typedef unsigned int glitz_gl_uint_t;
typedef int glitz_gl_sizei_t;
typedef double glitz_gl_double_t;
typedef float glitz_gl_float_t;
typedef unsigned short glitz_gl_ushort_t;
typedef short glitz_gl_short_t;
typedef unsigned int glitz_gl_bitfield_t;
typedef double glitz_gl_clampd_t;
typedef float glitz_gl_clampf_t;
typedef unsigned char glitz_gl_ubyte_t;
typedef ptrdiff_t glitz_gl_intptr_t;
typedef ptrdiff_t glitz_gl_sizeiptr_t;
#define GLITZ_GL_FALSE 0x0
#define GLITZ_GL_TRUE 0x1
#define GLITZ_GL_NO_ERROR 0x0
#define GLITZ_GL_INVALID_OPERATION 0x0502
#define GLITZ_GL_VERSION 0x1F02
#define GLITZ_GL_EXTENSIONS 0x1F03
#define GLITZ_GL_UNSIGNED_BYTE 0x1401
#define GLITZ_GL_UNSIGNED_BYTE_3_3_2 0x8032
#define GLITZ_GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
#define GLITZ_GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GLITZ_GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
#define GLITZ_GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GLITZ_GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
#define GLITZ_GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GLITZ_GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
#define GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#define GLITZ_GL_UNSIGNED_INT_10_10_10_2 0x8036
#define GLITZ_GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#define GLITZ_GL_MODELVIEW 0x1700
#define GLITZ_GL_PROJECTION 0x1701
#define GLITZ_GL_SHORT 0x1402
#define GLITZ_GL_INT 0x1404
#define GLITZ_GL_FLOAT 0x1406
#define GLITZ_GL_DOUBLE 0x140A
#define GLITZ_GL_POINTS 0x0000
#define GLITZ_GL_LINES 0x0001
#define GLITZ_GL_LINE_LOOP 0x0002
#define GLITZ_GL_LINE_STRIP 0x0003
#define GLITZ_GL_TRIANGLES 0x0004
#define GLITZ_GL_TRIANGLE_STRIP 0x0005
#define GLITZ_GL_TRIANGLE_FAN 0x0006
#define GLITZ_GL_QUADS 0x0007
#define GLITZ_GL_QUAD_STRIP 0x0008
#define GLITZ_GL_POLYGON 0x0009
#define GLITZ_GL_VERTEX_ARRAY 0x8074
#define GLITZ_GL_TEXTURE_COORD_ARRAY 0x8078
#define GLITZ_GL_FILL 0x1B02
#define GLITZ_GL_FRONT 0x0404
#define GLITZ_GL_BACK 0x0405
#define GLITZ_GL_CULL_FACE 0x0B44
#define GLITZ_GL_POINT_SMOOTH 0x0B10
#define GLITZ_GL_LINE_SMOOTH 0x0B20
#define GLITZ_GL_POLYGON_SMOOTH 0x0B41
#define GLITZ_GL_SCISSOR_TEST 0x0C11
#define GLITZ_GL_MAX_TEXTURE_SIZE 0x0D33
#define GLITZ_GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GLITZ_GL_TEXTURE_WIDTH 0x1000
#define GLITZ_GL_TEXTURE_HEIGHT 0x1001
#define GLITZ_GL_TEXTURE_ENV 0x2300
#define GLITZ_GL_TEXTURE_ENV_MODE 0x2200
#define GLITZ_GL_TEXTURE_2D 0x0DE1
#define GLITZ_GL_PROXY_TEXTURE_2D 0x8064
#define GLITZ_GL_TEXTURE_WRAP_S 0x2802
#define GLITZ_GL_TEXTURE_WRAP_T 0x2803
#define GLITZ_GL_TEXTURE_MAG_FILTER 0x2800
#define GLITZ_GL_TEXTURE_MIN_FILTER 0x2801
#define GLITZ_GL_TEXTURE_ENV_COLOR 0x2201
#define GLITZ_GL_TEXTURE_GEN_S 0x0C60
#define GLITZ_GL_TEXTURE_GEN_T 0x0C61
#define GLITZ_GL_TEXTURE_GEN_MODE 0x2500
#define GLITZ_GL_EYE_LINEAR 0x2400
#define GLITZ_GL_EYE_PLANE 0x2502
#define GLITZ_GL_S 0x2000
#define GLITZ_GL_T 0x2001
#define GLITZ_GL_MODULATE 0x2100
#define GLITZ_GL_NEAREST 0x2600
#define GLITZ_GL_LINEAR 0x2601
#define GLITZ_GL_REPEAT 0x2901
#define GLITZ_GL_CLAMP_TO_EDGE 0x812F
#define GLITZ_GL_CLAMP_TO_BORDER 0x812D
#define GLITZ_GL_TEXTURE_RED_SIZE 0x805C
#define GLITZ_GL_TEXTURE_GREEN_SIZE 0x805D
#define GLITZ_GL_TEXTURE_BLUE_SIZE 0x805E
#define GLITZ_GL_TEXTURE_ALPHA_SIZE 0x805F
#define GLITZ_GL_TEXTURE 0x1702
#define GLITZ_GL_SRC_COLOR 0x0300
#define GLITZ_GL_COMBINE 0x8570
#define GLITZ_GL_COMBINE_RGB 0x8571
#define GLITZ_GL_COMBINE_ALPHA 0x8572
#define GLITZ_GL_SOURCE0_RGB 0x8580
#define GLITZ_GL_SOURCE1_RGB 0x8581
#define GLITZ_GL_SOURCE2_RGB 0x8582
#define GLITZ_GL_SOURCE0_ALPHA 0x8588
#define GLITZ_GL_SOURCE1_ALPHA 0x8589
#define GLITZ_GL_SOURCE2_ALPHA 0x858A
#define GLITZ_GL_OPERAND0_RGB 0x8590
#define GLITZ_GL_OPERAND1_RGB 0x8591
#define GLITZ_GL_OPERAND2_RGB 0x8592
#define GLITZ_GL_OPERAND0_ALPHA 0x8598
#define GLITZ_GL_OPERAND1_ALPHA 0x8599
#define GLITZ_GL_OPERAND2_ALPHA 0x859A
#define GLITZ_GL_RGB_SCALE 0x8573
#define GLITZ_GL_ADD_SIGNED 0x8574
#define GLITZ_GL_INTERPOLATE 0x8575
#define GLITZ_GL_SUBTRACT 0x84E7
#define GLITZ_GL_CONSTANT 0x8576
#define GLITZ_GL_PRIMARY_COLOR 0x8577
#define GLITZ_GL_PREVIOUS 0x8578
#define GLITZ_GL_DOT3_RGB 0x86AE
#define GLITZ_GL_DOT3_RGBA 0x86AF
#define GLITZ_GL_STENCIL_TEST 0x0B90
#define GLITZ_GL_KEEP 0x1E00
#define GLITZ_GL_REPLACE 0x1E01
#define GLITZ_GL_INCR 0x1E02
#define GLITZ_GL_DECR 0x1E03
#define GLITZ_GL_LESS 0x0201
#define GLITZ_GL_EQUAL 0x0202
#define GLITZ_GL_LEQUAL 0x0203
#define GLITZ_GL_ALWAYS 0x0207
#define GLITZ_GL_DEPTH_TEST 0x0B71
#define GLITZ_GL_STENCIL_BUFFER_BIT 0x00000400
#define GLITZ_GL_VIEWPORT_BIT 0x00000800
#define GLITZ_GL_TRANSFORM_BIT 0x00001000
#define GLITZ_GL_COLOR_BUFFER_BIT 0x00004000
#define GLITZ_GL_ALPHA 0x1906
#define GLITZ_GL_RGB 0x1907
#define GLITZ_GL_LUMINANCE 0x1909
#define GLITZ_GL_COLOR 0x1800
#define GLITZ_GL_DITHER 0x0BD0
#define GLITZ_GL_RGBA 0x1908
#define GLITZ_GL_BGR 0x80E0
#define GLITZ_GL_BGRA 0x80E1
#define GLITZ_GL_ALPHA4 0x803B
#define GLITZ_GL_ALPHA8 0x803C
#define GLITZ_GL_ALPHA12 0x803D
#define GLITZ_GL_ALPHA16 0x803E
#define GLITZ_GL_R3_G3_B2 0x2A10
#define GLITZ_GL_RGB4 0x804F
#define GLITZ_GL_RGB5 0x8050
#define GLITZ_GL_RGB8 0x8051
#define GLITZ_GL_RGB10 0x8052
#define GLITZ_GL_RGB12 0x8053
#define GLITZ_GL_RGB16 0x8054
#define GLITZ_GL_RGBA2 0x8055
#define GLITZ_GL_RGBA4 0x8056
#define GLITZ_GL_RGB5_A1 0x8057
#define GLITZ_GL_RGBA8 0x8058
#define GLITZ_GL_RGB10_A2 0x8059
#define GLITZ_GL_RGBA12 0x805A
#define GLITZ_GL_RGBA16 0x805B
#define GLITZ_GL_FRONT_AND_BACK 0x0408
#define GLITZ_GL_FLAT 0x1D00
#define GLITZ_GL_SMOOTH 0x1D01
#define GLITZ_GL_BLEND 0x0BE2
#define GLITZ_GL_ZERO 0x0000
#define GLITZ_GL_ONE 0x0001
#define GLITZ_GL_ONE_MINUS_SRC_COLOR 0x0301
#define GLITZ_GL_SRC_ALPHA 0x0302
#define GLITZ_GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GLITZ_GL_DST_ALPHA 0x0304
#define GLITZ_GL_ONE_MINUS_DST_ALPHA 0x0305
#define GLITZ_GL_SRC_ALPHA_SATURATE 0x0308
#define GLITZ_GL_CONSTANT_COLOR 0x8001
#define GLITZ_GL_PACK_ALIGNMENT 0x0D05
#define GLITZ_GL_PACK_LSB_FIRST 0x0D01
#define GLITZ_GL_PACK_ROW_LENGTH 0x0D02
#define GLITZ_GL_PACK_SKIP_PIXELS 0x0D04
#define GLITZ_GL_PACK_SKIP_ROWS 0x0D03
#define GLITZ_GL_UNPACK_ALIGNMENT 0x0CF5
#define GLITZ_GL_UNPACK_LSB_FIRST 0x0CF1
#define GLITZ_GL_UNPACK_ROW_LENGTH 0x0CF2
#define GLITZ_GL_UNPACK_SKIP_PIXELS 0x0CF4
#define GLITZ_GL_UNPACK_SKIP_ROWS 0x0CF3
#define GLITZ_GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
#define GLITZ_GL_FASTEST 0x1101
#define GLITZ_GL_NICEST 0x1102
#define GLITZ_GL_COMPILE 0x1300
#define GLITZ_GL_TEXTURE_RECTANGLE 0x84F5
#define GLITZ_GL_PROXY_TEXTURE_RECTANGLE 0x84F7
#define GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
#define GLITZ_GL_MIRRORED_REPEAT 0x8370
#define GLITZ_GL_TEXTURE0 0x84C0
#define GLITZ_GL_TEXTURE1 0x84C1
#define GLITZ_GL_TEXTURE2 0x84C2
#define GLITZ_GL_ACTIVE_TEXTURE 0x84E0
#define GLITZ_GL_MAX_TEXTURE_UNITS 0x84E2
#define GLITZ_GL_MULTISAMPLE 0x809D
#define GLITZ_GL_MULTISAMPLE_FILTER_HINT 0x8534
#define GLITZ_GL_FRAGMENT_PROGRAM 0x8804
#define GLITZ_GL_PROGRAM_STRING 0x8628
#define GLITZ_GL_PROGRAM_FORMAT_ASCII 0x8875
#define GLITZ_GL_PROGRAM_ERROR_POSITION 0x864B
#define GLITZ_GL_MAX_PROGRAM_LOCAL_PARAMETERS 0x88B4
#define GLITZ_GL_PROGRAM_INSTRUCTIONS 0x88A0
#define GLITZ_GL_MAX_PROGRAM_INSTRUCTIONS 0x88A1
#define GLITZ_GL_PROGRAM_NATIVE_INSTRUCTIONS 0x88A2
#define GLITZ_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS 0x88A3
#define GLITZ_GL_PROGRAM_PARAMETERS 0x88A8
#define GLITZ_GL_MAX_PROGRAM_PARAMETERS 0x88A9
#define GLITZ_GL_PROGRAM_NATIVE_PARAMETERS 0x88AA
#define GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS 0x88AB
#define GLITZ_GL_PROGRAM_UNDER_NATIVE_LIMITS 0x88B6
#define GLITZ_GL_PROGRAM_ALU_INSTRUCTIONS 0x8805
#define GLITZ_GL_PROGRAM_TEX_INSTRUCTIONS 0x8806
#define GLITZ_GL_PROGRAM_TEX_INDIRECTIONS 0x8807
#define GLITZ_GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS 0x8808
#define GLITZ_GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS 0x8809
#define GLITZ_GL_PROGRAM_NATIVE_TEX_INDIRECTIONS 0x880A
#define GLITZ_GL_MAX_PROGRAM_ALU_INSTRUCTIONS 0x880B
#define GLITZ_GL_MAX_PROGRAM_TEX_INSTRUCTIONS 0x880C
#define GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS 0x880D
#define GLITZ_GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS 0x880E
#define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS 0x880F
#define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS 0x8810
#define GLITZ_GL_ARRAY_BUFFER 0x8892
#define GLITZ_GL_PIXEL_PACK_BUFFER 0x88EB
#define GLITZ_GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GLITZ_GL_STREAM_DRAW 0x88E0
#define GLITZ_GL_STREAM_READ 0x88E1
#define GLITZ_GL_STREAM_COPY 0x88E2
#define GLITZ_GL_STATIC_DRAW 0x88E4
#define GLITZ_GL_STATIC_READ 0x88E5
#define GLITZ_GL_STATIC_COPY 0x88E6
#define GLITZ_GL_DYNAMIC_DRAW 0x88E8
#define GLITZ_GL_DYNAMIC_READ 0x88E9
#define GLITZ_GL_DYNAMIC_COPY 0x88EA
#define GLITZ_GL_READ_ONLY 0x88B8
#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_API_ATTRIBUTE * glitz_gl_enable_t)
(glitz_gl_enum_t cap);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_disable_t)
(glitz_gl_enum_t cap);
typedef glitz_gl_enum_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_error_t)
(glitz_gl_void_t);
typedef glitz_gl_ubyte_t *(GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_string_t)
(glitz_gl_enum_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_enable_client_state_t)
(glitz_gl_enum_t cap);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_disable_client_state_t)
(glitz_gl_enum_t cap);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_vertex_pointer_t)
(glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride,
const glitz_gl_void_t *ptr);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_coord_pointer_t)
(glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride,
const glitz_gl_void_t *ptr);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_draw_arrays_t)
(glitz_gl_enum_t mode, glitz_gl_int_t first, glitz_gl_sizei_t count);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_multi_draw_arrays_t)
(glitz_gl_enum_t mode, glitz_gl_int_t *first, glitz_gl_sizei_t *count,
glitz_gl_sizei_t primcount);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_env_f_t)
(glitz_gl_enum_t target, glitz_gl_enum_t pname, glitz_gl_float_t param);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_env_fv_t)
(glitz_gl_enum_t target, glitz_gl_enum_t pname,
const glitz_gl_float_t *params);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_gen_i_t)
(glitz_gl_enum_t coord, glitz_gl_enum_t pname, glitz_gl_int_t param);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_gen_fv_t)
(glitz_gl_enum_t coord, glitz_gl_enum_t pname,
const glitz_gl_float_t *params);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_scissor_t)
(glitz_gl_int_t x, glitz_gl_int_t y,
glitz_gl_sizei_t width, glitz_gl_sizei_t height);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_color_4us_t)
(glitz_gl_ushort_t red, glitz_gl_ushort_t green, glitz_gl_ushort_t blue,
glitz_gl_ushort_t alpha);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_color_4f_t)
(glitz_gl_float_t red, glitz_gl_float_t green, glitz_gl_float_t blue,
glitz_gl_float_t alpha);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_blend_func_t)
(glitz_gl_enum_t sfactor, glitz_gl_enum_t dfactor);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_blend_color_t)
(glitz_gl_clampf_t red, glitz_gl_clampf_t green, glitz_gl_clampf_t blue,
glitz_gl_clampf_t alpha);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_clear_t)
(glitz_gl_bitfield_t mask);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_clear_color_t)
(glitz_gl_clampf_t red, glitz_gl_clampf_t green,
glitz_gl_clampf_t blue, glitz_gl_clampf_t alpha);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_clear_stencil_t)
(glitz_gl_int_t s);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_stencil_func_t)
(glitz_gl_enum_t func, glitz_gl_int_t ref, glitz_gl_uint_t mask);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_stencil_op_t)
(glitz_gl_enum_t fail, glitz_gl_enum_t zfail, glitz_gl_enum_t zpass);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_push_attrib_t)
(glitz_gl_bitfield_t mask);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_pop_attrib_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_matrix_mode_t)
(glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_push_matrix_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_pop_matrix_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_load_identity_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_load_matrix_f_t)
(const glitz_gl_float_t *m);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_depth_range_t)
(glitz_gl_clampd_t near_val, glitz_gl_clampd_t far_val);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_viewport_t)
(glitz_gl_int_t x, glitz_gl_int_t y,
glitz_gl_sizei_t width, glitz_gl_sizei_t height);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_raster_pos_2f_t)
(glitz_gl_float_t x, glitz_gl_float_t y);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_bitmap_t)
(glitz_gl_sizei_t width, glitz_gl_sizei_t height,
glitz_gl_float_t xorig, glitz_gl_float_t yorig,
glitz_gl_float_t xmove, glitz_gl_float_t ymove,
const glitz_gl_ubyte_t *bitmap);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_read_buffer_t)
(glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_draw_buffer_t)
(glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_copy_pixels_t)
(glitz_gl_int_t x, glitz_gl_int_t y,
glitz_gl_sizei_t width, glitz_gl_sizei_t height,
glitz_gl_enum_t type);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_flush_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_finish_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_pixel_store_i_t)
(glitz_gl_enum_t pname, glitz_gl_int_t param);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_ortho_t)
(glitz_gl_double_t left, glitz_gl_double_t right,
glitz_gl_double_t bottom, glitz_gl_double_t top,
glitz_gl_double_t near_val, glitz_gl_double_t far_val);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_scale_f_t)
(glitz_gl_float_t x, glitz_gl_float_t y, glitz_gl_float_t z);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_translate_f_t)
(glitz_gl_float_t x, glitz_gl_float_t y, glitz_gl_float_t z);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_hint_t)
(glitz_gl_enum_t target, glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_depth_mask_t)
(glitz_gl_boolean_t flag);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_polygon_mode_t)
(glitz_gl_enum_t face, glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_shade_model_t)
(glitz_gl_enum_t mode);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_color_mask_t)
(glitz_gl_boolean_t red,
glitz_gl_boolean_t green,
glitz_gl_boolean_t blue,
glitz_gl_boolean_t alpha);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_read_pixels_t)
(glitz_gl_int_t x, glitz_gl_int_t y,
glitz_gl_sizei_t width, glitz_gl_sizei_t height,
glitz_gl_enum_t format, glitz_gl_enum_t type,
glitz_gl_void_t *pixels);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_tex_image_t)
(glitz_gl_enum_t target, glitz_gl_int_t level,
glitz_gl_enum_t format, glitz_gl_enum_t type,
glitz_gl_void_t *pixels);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_sub_image_2d_t)
(glitz_gl_enum_t target, glitz_gl_int_t level,
glitz_gl_int_t xoffset, glitz_gl_int_t yoffset,
glitz_gl_sizei_t width, glitz_gl_sizei_t height,
glitz_gl_enum_t format, glitz_gl_enum_t type,
const glitz_gl_void_t *pixels);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_gen_textures_t)
(glitz_gl_sizei_t n, glitz_gl_uint_t *textures);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_delete_textures_t)
(glitz_gl_sizei_t n, const glitz_gl_uint_t *textures);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_bind_texture_t)
(glitz_gl_enum_t target, glitz_gl_uint_t texture);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_image_2d_t)
(glitz_gl_enum_t target, glitz_gl_int_t level,
glitz_gl_int_t internal_format,
glitz_gl_sizei_t width, glitz_gl_sizei_t height,
glitz_gl_int_t border, glitz_gl_enum_t format, glitz_gl_enum_t type,
const glitz_gl_void_t *pixels);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_tex_parameter_i_t)
(glitz_gl_enum_t target, glitz_gl_enum_t pname, glitz_gl_int_t param);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_tex_level_parameter_iv_t)
(glitz_gl_enum_t target, glitz_gl_int_t level,
glitz_gl_enum_t pname, glitz_gl_int_t *param);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_copy_tex_sub_image_2d_t)
(glitz_gl_enum_t target, glitz_gl_int_t level,
glitz_gl_int_t xoffset, glitz_gl_int_t yoffset,
glitz_gl_int_t x, glitz_gl_int_t y,
glitz_gl_sizei_t width, glitz_gl_sizei_t height);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_integer_v_t)
(glitz_gl_enum_t pname, glitz_gl_int_t *params);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_pointer_v_t)
(glitz_gl_enum_t pname, glitz_gl_void_t **params);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_active_texture_t)
(glitz_gl_enum_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_client_active_texture_t)
(glitz_gl_enum_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_gen_programs_t)
(glitz_gl_sizei_t, glitz_gl_uint_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_delete_programs_t)
(glitz_gl_sizei_t, const glitz_gl_uint_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_program_string_t)
(glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_sizei_t,
const glitz_gl_void_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_bind_program_t)
(glitz_gl_enum_t, glitz_gl_uint_t);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_program_local_param_4fv_t)
(glitz_gl_enum_t, glitz_gl_uint_t, const glitz_gl_float_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_program_iv_t)
(glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_int_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_gen_buffers_t)
(glitz_gl_sizei_t, glitz_gl_uint_t *buffers);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_delete_buffers_t)
(glitz_gl_sizei_t, const glitz_gl_uint_t *buffers);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_bind_buffer_t)
(glitz_gl_enum_t, glitz_gl_uint_t buffer);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_buffer_data_t)
(glitz_gl_enum_t, glitz_gl_sizeiptr_t, const glitz_gl_void_t *,
glitz_gl_enum_t);
typedef glitz_gl_void_t *(GLITZ_GL_API_ATTRIBUTE * glitz_gl_buffer_sub_data_t)
(glitz_gl_enum_t, glitz_gl_intptr_t, glitz_gl_sizeiptr_t,
const glitz_gl_void_t *);
typedef glitz_gl_void_t *(GLITZ_GL_API_ATTRIBUTE * glitz_gl_get_buffer_sub_data_t)
(glitz_gl_enum_t, glitz_gl_intptr_t, glitz_gl_sizeiptr_t,
glitz_gl_void_t *);
typedef glitz_gl_void_t *(GLITZ_GL_API_ATTRIBUTE * glitz_gl_map_buffer_t)
(glitz_gl_enum_t, glitz_gl_enum_t);
typedef glitz_gl_boolean_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_unmap_buffer_t)
(glitz_gl_enum_t);
typedef void (GLITZ_GL_API_ATTRIBUTE * glitz_gl_gen_framebuffers_t)
(glitz_gl_sizei_t, glitz_gl_uint_t *);
typedef void (GLITZ_GL_API_ATTRIBUTE * glitz_gl_delete_framebuffers_t)
(glitz_gl_sizei_t, const glitz_gl_uint_t *);
typedef glitz_gl_void_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_bind_framebuffer_t)
(glitz_gl_enum_t, glitz_gl_uint_t);
typedef glitz_gl_enum_t (GLITZ_GL_API_ATTRIBUTE * glitz_gl_check_framebuffer_status_t)
(glitz_gl_enum_t);
typedef void (GLITZ_GL_API_ATTRIBUTE * 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 */

Просмотреть файл

@ -0,0 +1,90 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Authors: David Reveman <davidr@novell.com>
* Peter Nilsson <c99pnn@cs.umu.se>
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitzint.h"
void
glitz_set_operator (glitz_gl_proc_address_list_t *gl, glitz_operator_t op) {
switch (op) {
case GLITZ_OPERATOR_CLEAR:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ZERO);
break;
case GLITZ_OPERATOR_SRC:
gl->disable (GLITZ_GL_BLEND);
break;
case GLITZ_OPERATOR_DST:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE);
break;
case GLITZ_OPERATOR_OVER:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE_MINUS_SRC_ALPHA);
break;
case GLITZ_OPERATOR_OVER_REVERSE:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ONE);
break;
case GLITZ_OPERATOR_IN:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ZERO);
break;
case GLITZ_OPERATOR_IN_REVERSE:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_SRC_ALPHA);
break;
case GLITZ_OPERATOR_OUT:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_ZERO);
break;
case GLITZ_OPERATOR_OUT_REVERSE:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE_MINUS_SRC_ALPHA);
break;
case GLITZ_OPERATOR_ATOP:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_DST_ALPHA, GLITZ_GL_ONE_MINUS_SRC_ALPHA);
break;
case GLITZ_OPERATOR_ATOP_REVERSE:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA, GLITZ_GL_SRC_ALPHA);
break;
case GLITZ_OPERATOR_XOR:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE_MINUS_DST_ALPHA,
GLITZ_GL_ONE_MINUS_SRC_ALPHA);
break;
case GLITZ_OPERATOR_ADD:
gl->enable (GLITZ_GL_BLEND);
gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE);
break;
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,618 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#include <stdio.h>
#define EXPAND_NONE ""
#define EXPAND_2D "2D"
#define EXPAND_RECT "RECT"
#define EXPAND_NA "NA"
#define EXPAND_X_IN_SOLID_OP \
{ "", "", "MUL result.color, color, fragment.color.a;" }
#define EXPAND_SOLID_IN_X_OP \
{ "", "", "MUL result.color, fragment.color, color.a;" }
#define EXPAND_SRC_DECL "TEMP src;"
#define EXPAND_SRC_2D_IN_OP \
{ "TXP src, fragment.texcoord[1], texture[1], 2D;", \
"DP4 color.a, color, fragment.color;", \
"MUL result.color, src, color.a;" }
#define EXPAND_SRC_RECT_IN_OP \
{ "TXP src, fragment.texcoord[1], texture[1], RECT;", \
"DP4 color.a, color, fragment.color;", \
"MUL result.color, src, color.a;" }
#define EXPAND_MASK_DECL "TEMP mask;"
#define EXPAND_MASK_2D_IN_OP \
{ "TXP mask, fragment.texcoord[0], texture[0], 2D;", \
"DP4 mask.a, mask, fragment.color;", \
"MUL result.color, color, mask.a;" }
#define EXPAND_MASK_RECT_IN_OP \
{ "TXP mask, fragment.texcoord[0], texture[0], RECT;", \
"DP4 mask.a, mask, fragment.color;", \
"MUL result.color, color, mask.a;" }
#define EXPAND_IN_NA \
{ "NA", "NA", "NA" }
typedef struct _glitz_program_expand_t glitz_program_expand_t;
typedef struct _glitz_inop {
char *fetch;
char *dot_product;
char *mult;
} glitz_in_op_t;
static const struct _glitz_program_expand_t {
char *texture;
char *declarations;
glitz_in_op_t in;
} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST][2] = {
{
/* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */
{
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA },
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }
},
/* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */
{
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA },
{ EXPAND_2D, EXPAND_NONE, EXPAND_SOLID_IN_X_OP }
},
/* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */
{
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA },
{ EXPAND_RECT, EXPAND_NONE, EXPAND_SOLID_IN_X_OP }
}
}, {
/* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */
{
{ EXPAND_2D, EXPAND_NONE, EXPAND_X_IN_SOLID_OP },
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }
},
/* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */
{
{ EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
{ EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP }
},
/* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */
{
{ EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP },
{ EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP }
}
}, {
/* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */
{
{ EXPAND_RECT, EXPAND_NONE, EXPAND_X_IN_SOLID_OP },
{ EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }
},
/* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */
{
{ EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
{ EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP }
},
/* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */
{
{ EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP },
{ EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_RECT_IN_OP }
}
}
};
/*
* general convolution filter.
*/
static const char *_convolution_header[] = {
"PARAM p[%d] = { program.local[0..%d] };",
"ATTRIB pos = fragment.texcoord[%s];",
"TEMP color, in, coord, position;",
/* extra declarations */
"%s"
/* perspective divide */
"RCP position.w, pos.w;",
"MUL position, pos, position.w;", NULL
};
static const char *_convolution_sample_first[] = {
"MOV coord, 0.0;",
"ADD coord.x, position.x, p[0].x;",
"ADD coord.y, position.y, p[0].y;",
"TEX in, coord, texture[%s], %s;",
"MUL color, in, p[0].z;", NULL
};
static const char *_convolution_sample[] = {
"ADD coord.x, position.x, p[%d].x;",
"ADD coord.y, position.y, p[%d].y;",
"TEX in, coord, texture[%s], %s;",
"MAD color, in, p[%d].z, color;", NULL
};
/*
* gradient filters.
*/
static const char *_gradient_header[] = {
"PARAM gradient = program.local[0];",
"PARAM stops[%d] = { program.local[1..%d] };",
"ATTRIB pos = fragment.texcoord[%s];",
"TEMP color, second_color, stop0, stop1, position;",
/* extra declarations */
"%s",
/* perspective divide */
"RCP position.w, pos.w;",
"MUL position, pos, position.w;", NULL
};
/*
* linear gradient filter.
*
* gradient.x = start offset
* gradient.y = 1 / length
* gradient.z = cos (angle)
* gradient.w = -sin (angle)
*/
static const char *_linear_gradient_calculations[] = {
"MUL position.x, gradient.z, position.x;",
"MAD position.x, gradient.w, position.y, position.x;",
"SUB position.z, position.x, gradient.x;",
"MUL position.z, position.z, gradient.y;", NULL
};
/*
* radial gradient filter.
*
* gradient.x = center point X coordinate
* gradient.y = center point Y coordinate
* gradient.z = radius0
* gradient.w = 1 / (radius1 - radius0)
*/
static const char *_radial_gradient_calculations[] = {
"SUB position, position, gradient;",
"MUL position.x, position.x, position.x;",
"MAD position.x, position.y, position.y, position.x;",
"RSQ position.y, position.x;",
"RCP position.x, position.y;",
"MUL position.x, position.x, position.x;",
"MUL position.x, position.x, position.y;",
"SUB position.x, position.x, gradient.z;",
"MUL position.z, position.x, gradient.w;", NULL
};
static const char *_gradient_fill_repeat[] = {
"FRC position.z, position.z;", NULL
};
static const char *_gradient_fill_reflect[] = {
"FLR position.w, position.z;",
"MUL position.w, position.w, 0.5;",
"FLR position.w, position.w;",
"MUL position.y, position.w, 2.0;",
"FLR position.x, position.z;",
"SUB position.y, position.x, position.y;",
"FRC position.x, position.z;",
"SUB position.x, position.x, position.y;",
"ABS position.z, position.x;", NULL
};
static const char *_gradient_init_stops[] = {
"MOV stop0, stops[0];",
"MOV stop1, stops[%d];", NULL
};
static const char *_gradient_lower_stop[] = {
"SLT position.x, stops[%d].z, position.z;",
"CMP stop0, -position.x, stops[%d], stop0;", NULL
};
static const char *_gradient_higher_stop[] = {
"SLT position.x, position.z, stops[%d].z;",
"CMP stop1, -position.x, stops[%d], stop1;", NULL
};
static const char *_gradient_fetch_and_interpolate[] = {
"TEX color, stop0, texture[%s], %s;",
"TEX second_color, stop1, texture[%s], %s;",
/* normalize gradient offset to color stop span */
"SUB position.z, position.z, stop0.z;",
"MUL_SAT position.z, position.z, stop0.w;",
/* linear interpolation */
"LRP color, position.z, second_color, color;", NULL
};
static struct _glitz_program_query {
glitz_gl_enum_t query;
glitz_gl_enum_t max_query;
glitz_gl_int_t min;
} _program_limits[] = {
{ GLITZ_GL_PROGRAM_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_INSTRUCTIONS, 1 },
{ GLITZ_GL_PROGRAM_NATIVE_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS, 1 },
{ GLITZ_GL_PROGRAM_PARAMETERS,
GLITZ_GL_MAX_PROGRAM_PARAMETERS, 1 },
{ GLITZ_GL_PROGRAM_NATIVE_PARAMETERS,
GLITZ_GL_MAX_PROGRAM_NATIVE_PARAMETERS, 1 },
{ GLITZ_GL_PROGRAM_ALU_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_ALU_INSTRUCTIONS, 0 },
{ GLITZ_GL_PROGRAM_TEX_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_TEX_INSTRUCTIONS, 1 },
{ GLITZ_GL_PROGRAM_TEX_INDIRECTIONS,
GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS, 0 },
{ GLITZ_GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS, 0 },
{ GLITZ_GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS,
GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS, 0 },
{ GLITZ_GL_PROGRAM_NATIVE_TEX_INDIRECTIONS,
GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS, 0 },
};
static glitz_bool_t
_glitz_program_under_limits (glitz_gl_proc_address_list_t *gl)
{
int i, n_limits;
n_limits = sizeof (_program_limits) / (sizeof (struct _glitz_program_query));
for (i = 0; i < n_limits; i++) {
glitz_gl_int_t value, max;
gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM,
_program_limits[i].query, &value);
gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM,
_program_limits[i].max_query, &max);
if (value < _program_limits[i].min)
return 0;
if (value >= max)
return 0;
}
return 1;
}
static glitz_gl_int_t
_glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
char *program_string,
int n_parameters)
{
glitz_gl_int_t error, pid = -1;
glitz_gl_uint_t program;
/* clear error flags */
while (gl->get_error () != GLITZ_GL_NO_ERROR);
gl->gen_programs (1, &program);
gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, program);
gl->program_string (GLITZ_GL_FRAGMENT_PROGRAM,
GLITZ_GL_PROGRAM_FORMAT_ASCII,
strlen (program_string),
program_string);
if (gl->get_error () == GLITZ_GL_NO_ERROR) {
gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error);
if (error == -1) {
glitz_gl_int_t value;
gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM,
GLITZ_GL_PROGRAM_UNDER_NATIVE_LIMITS,
&value);
if (value == GLITZ_GL_TRUE) {
gl->get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM,
GLITZ_GL_MAX_PROGRAM_LOCAL_PARAMETERS,
&value);
if (value >= n_parameters) {
if (_glitz_program_under_limits (gl))
pid = program;
}
}
}
}
if (pid == -1) {
gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0);
gl->delete_programs (1, &program);
}
return pid;
}
static void
_string_array_to_char_array (char *dst, const char *src[])
{
int i, n;
for (i = 0; src[i]; i++) {
n = strlen (src[i]);
memcpy (dst, src[i], n);
dst += n;
}
*dst = '\0';
}
/* these should be more than enough */
#define CONVOLUTION_BASE_SIZE 2048
#define CONVOLUTION_SAMPLE_SIZE 256
#define GRADIENT_BASE_SIZE 2048
#define GRADIENT_STOP_SIZE 256
static glitz_gl_uint_t
_glitz_create_fragment_program (glitz_composite_op_t *op,
int fp_type,
int id,
const glitz_program_expand_t *expand)
{
char buffer[1024], *program = NULL, *tex, *p = NULL;
char *texture_type, *extra_declarations;
const glitz_in_op_t *in;
glitz_gl_uint_t fp;
int i;
switch (op->type) {
case GLITZ_COMBINE_TYPE_ARGBF:
case GLITZ_COMBINE_TYPE_ARGBF_SOLID:
case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC:
i = 0;
tex = "0";
break;
case GLITZ_COMBINE_TYPE_ARGB_ARGBF:
case GLITZ_COMBINE_TYPE_SOLID_ARGBF:
i = 1;
tex = "0";
break;
case GLITZ_COMBINE_TYPE_ARGBF_ARGB:
case GLITZ_COMBINE_TYPE_ARGBF_ARGBC:
i = 0;
tex = "1";
break;
default:
return 0;
}
texture_type = expand[i].texture;
extra_declarations = expand[i].declarations;
in = &expand[i].in;
switch (fp_type) {
case GLITZ_FP_CONVOLUTION:
program = malloc (CONVOLUTION_BASE_SIZE + CONVOLUTION_SAMPLE_SIZE * id);
if (program == NULL)
return 0;
p = program;
p += sprintf (p, "!!ARBfp1.0");
_string_array_to_char_array (buffer, _convolution_header);
p += sprintf (p, buffer, id, id - 1, tex, extra_declarations);
_string_array_to_char_array (buffer, _convolution_sample_first);
p += sprintf (p, buffer, tex, texture_type);
_string_array_to_char_array (buffer, _convolution_sample);
for (i = 1; i < id; i++)
p += sprintf (p, buffer, i, i, tex, texture_type, i);
break;
case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
case GLITZ_FP_RADIAL_GRADIENT_TRANSPARENT:
id += 2;
/* fall-through */
case GLITZ_FP_LINEAR_GRADIENT_NEAREST:
case GLITZ_FP_LINEAR_GRADIENT_REPEAT:
case GLITZ_FP_LINEAR_GRADIENT_REFLECT:
case GLITZ_FP_RADIAL_GRADIENT_NEAREST:
case GLITZ_FP_RADIAL_GRADIENT_REPEAT:
case GLITZ_FP_RADIAL_GRADIENT_REFLECT:
program = malloc (GRADIENT_BASE_SIZE + GRADIENT_STOP_SIZE * id);
if (program == NULL)
return 0;
p = program;
p += sprintf (p, "!!ARBfp1.0");
_string_array_to_char_array (buffer, _gradient_header);
p += sprintf (p, buffer, id, id, tex, extra_declarations);
switch (fp_type) {
case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
case GLITZ_FP_LINEAR_GRADIENT_NEAREST:
case GLITZ_FP_LINEAR_GRADIENT_REPEAT:
case GLITZ_FP_LINEAR_GRADIENT_REFLECT:
_string_array_to_char_array (buffer, _linear_gradient_calculations);
break;
default:
_string_array_to_char_array (buffer, _radial_gradient_calculations);
break;
}
p += sprintf (p, buffer);
switch (fp_type) {
case GLITZ_FP_LINEAR_GRADIENT_REPEAT:
case GLITZ_FP_RADIAL_GRADIENT_REPEAT:
_string_array_to_char_array (buffer, _gradient_fill_repeat);
p += sprintf (p, buffer);
break;
case GLITZ_FP_LINEAR_GRADIENT_REFLECT:
case GLITZ_FP_RADIAL_GRADIENT_REFLECT:
_string_array_to_char_array (buffer, _gradient_fill_reflect);
p += sprintf (p, buffer);
break;
default:
break;
}
_string_array_to_char_array (buffer, _gradient_init_stops);
p += sprintf (p, buffer, id - 1);
_string_array_to_char_array (buffer, _gradient_lower_stop);
for (i = 1; i < (id - 1); i++)
p += sprintf (p, buffer, i, i);
_string_array_to_char_array (buffer, _gradient_higher_stop);
for (i = 1; i < (id - 1); i++)
p += sprintf (p, buffer, id - i - 1, id - i - 1);
_string_array_to_char_array (buffer, _gradient_fetch_and_interpolate);
p += sprintf (p, buffer, tex, texture_type, tex, texture_type);
id++;
break;
default:
return 0;
}
if (program == NULL)
return 0;
p += sprintf (p, "%s", in->fetch);
if (op->per_component)
p += sprintf (p, "%s", in->dot_product);
p += sprintf (p, "%s", in->mult);
sprintf (p, "END");
fp = _glitz_compile_arb_fragment_program (op->gl, program, id);
free (program);
return fp;
}
void
glitz_program_map_init (glitz_program_map_t *map)
{
memset (map, 0, sizeof (glitz_program_map_t));
}
void
glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
glitz_program_map_t *map)
{
glitz_gl_uint_t program;
int i, j, k, x, y;
for (i = 0; i < GLITZ_COMBINE_TYPES; i++) {
for (j = 0; j < GLITZ_FP_TYPES; j++) {
for (x = 0; x < GLITZ_TEXTURE_LAST; x++) {
for (y = 0; y < GLITZ_TEXTURE_LAST; y++) {
glitz_program_t *p = &map->filters[i][j].fp[x][y];
if (p->name) {
for (k = 0; k < p->size; k++)
if (p->name[k] > 0) {
program = p->name[k];
gl->delete_programs (1, &program);
}
free (p->name);
}
}
}
}
}
}
#define TEXTURE_INDEX(surface) \
((surface)? \
(((surface)->texture.target == GLITZ_GL_TEXTURE_2D)? \
GLITZ_TEXTURE_2D: \
GLITZ_TEXTURE_RECT \
) : \
GLITZ_TEXTURE_NONE \
)
glitz_gl_uint_t
glitz_get_fragment_program (glitz_composite_op_t *op,
int fp_type,
int id)
{
glitz_program_map_t *map;
glitz_program_t *program;
int t0 = TEXTURE_INDEX (op->src);
int t1 = TEXTURE_INDEX (op->mask);
map = op->dst->drawable->backend->program_map;
program = &map->filters[op->type][fp_type].fp[t0][t1];
if (program->size < id) {
int old_size;
program->name = realloc (program->name,
id * sizeof (glitz_gl_uint_t));
if (program->name == NULL) {
glitz_surface_status_add (op->dst, GLITZ_STATUS_NO_MEMORY_MASK);
return 0;
}
old_size = program->size;
program->size = id;
memset (program->name + old_size, 0,
(program->size - old_size) * sizeof (glitz_gl_uint_t));
}
if (program->name[id - 1] == 0) {
glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT);
program->name[id - 1] =
_glitz_create_fragment_program (op, fp_type, id,
_program_expand_map[t0][t1]);
glitz_surface_pop_current (op->dst);
}
if (program->name[id - 1] > 0)
return program->name[id - 1];
else
return 0;
}

Просмотреть файл

@ -0,0 +1,296 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#define STORE_16(dst, size, src) \
dst = ((size) ? \
((((((1L << (size)) - 1L) * (src)) / 0xffff) * 0xffff) / \
((1L << (size)) - 1L)) : \
dst)
static glitz_buffer_t *
_glitz_minimum_buffer (glitz_surface_t *surface,
const glitz_rectangle_t *rects,
int n_rects,
unsigned int *pixel)
{
glitz_buffer_t *buffer;
int i, size = 0;
unsigned int *data;
while (n_rects--)
{
i = rects->width * rects->height;
if (i > size)
size = i;
rects++;
}
if (size <= 1)
return glitz_buffer_create_for_data (pixel);
buffer = glitz_pixel_buffer_create (surface->drawable, NULL,
size * sizeof (unsigned int),
GLITZ_BUFFER_HINT_STATIC_DRAW);
if (!buffer)
return NULL;
data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
while (size--)
*data++ = *pixel;
glitz_buffer_unmap (buffer);
return buffer;
}
void
glitz_set_rectangles (glitz_surface_t *dst,
const glitz_color_t *color,
const glitz_rectangle_t *rects,
int n_rects)
{
GLITZ_GL_SURFACE (dst);
if (n_rects < 1)
return;
if (SURFACE_SOLID (dst))
{
glitz_color_t old = dst->solid;
glitz_box_t *clip = dst->clip;
int n_clip = dst->n_clip;
for (; n_clip; clip++, n_clip--)
{
if (clip->x1 > 0 ||
clip->y1 > 0 ||
clip->x2 < 1 ||
clip->y2 < 1)
continue;
for (; n_rects; rects++, n_rects--)
{
if (rects->x > 0 ||
rects->y > 0 ||
(rects->x + rects->width) < 1 ||
(rects->y + rects->height) < 1)
continue;
STORE_16 (dst->solid.red,
dst->format->color.red_size,
color->red);
STORE_16 (dst->solid.green,
dst->format->color.green_size,
color->green);
STORE_16 (dst->solid.blue,
dst->format->color.blue_size,
color->blue);
STORE_16 (dst->solid.alpha,
dst->format->color.alpha_size,
color->alpha);
if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
{
dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
glitz_surface_damage (dst, &dst->box,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_DRAWABLE_MASK);
}
else
{
if (dst->solid.red != old.red ||
dst->solid.green != old.green ||
dst->solid.blue != old.blue ||
dst->solid.alpha != old.alpha)
glitz_surface_damage (dst, &dst->box,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_DRAWABLE_MASK);
}
break;
}
break;
}
}
else
{
static glitz_pixel_format_t pf = {
{
32,
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff
},
0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
};
glitz_buffer_t *buffer = NULL;
glitz_box_t box;
glitz_bool_t drawable = 0;
if (n_rects == 1 && rects->width <= 1 && rects->height <= 1)
{
glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
}
else
{
drawable = glitz_surface_push_current (dst,
GLITZ_DRAWABLE_CURRENT);
}
if (drawable)
{
glitz_box_t *clip;
int n_clip;
int target_height = SURFACE_DRAWABLE_HEIGHT (dst);
gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff,
color->green / (glitz_gl_clampf_t) 0xffff,
color->blue / (glitz_gl_clampf_t) 0xffff,
color->alpha / (glitz_gl_clampf_t) 0xffff);
while (n_rects--)
{
clip = dst->clip;
n_clip = dst->n_clip;
while (n_clip--)
{
box.x1 = clip->x1 + dst->x_clip;
box.y1 = clip->y1 + dst->y_clip;
box.x2 = clip->x2 + dst->x_clip;
box.y2 = clip->y2 + dst->y_clip;
if (dst->box.x1 > box.x1)
box.x1 = dst->box.x1;
if (dst->box.y1 > box.y1)
box.y1 = dst->box.y1;
if (dst->box.x2 < box.x2)
box.x2 = dst->box.x2;
if (dst->box.y2 < box.y2)
box.y2 = dst->box.y2;
if (rects->x > box.x1)
box.x1 = rects->x;
if (rects->y > box.y1)
box.y1 = rects->y;
if (rects->x + rects->width < box.x2)
box.x2 = rects->x + rects->width;
if (rects->y + rects->height < box.y2)
box.y2 = rects->y + rects->height;
if (box.x1 < box.x2 && box.y1 < box.y2)
{
gl->scissor (box.x1,
target_height - dst->y - box.y2,
box.x2 - box.x1,
box.y2 - box.y1);
gl->clear (GLITZ_GL_COLOR_BUFFER_BIT);
glitz_surface_damage (dst, &box,
GLITZ_DAMAGE_TEXTURE_MASK |
GLITZ_DAMAGE_SOLID_MASK);
}
clip++;
}
rects++;
}
}
else
{
unsigned int pixel =
((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) |
((((unsigned int) color->red * 0xff) / 0xffff) << 16) |
((((unsigned int) color->green * 0xff) / 0xffff) << 8) |
((((unsigned int) color->blue * 0xff) / 0xffff));
int x1, y1, x2, y2;
buffer = _glitz_minimum_buffer (dst, rects, n_rects, &pixel);
if (!buffer)
{
glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
while (n_rects--)
{
x1 = rects->x;
y1 = rects->y;
x2 = x1 + rects->width;
y2 = y1 + rects->height;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
if (x2 > dst->box.x2)
x2 = dst->box.x2;
if (y2 > dst->box.y2)
y2 = dst->box.y2;
if (x1 < x2 && y1 < y2)
glitz_set_pixels (dst,
x1, y1,
x2 - x1, y2 - y1,
&pf, buffer);
rects++;
}
if (buffer)
glitz_buffer_destroy (buffer);
}
glitz_surface_pop_current (dst);
}
}
slim_hidden_def(glitz_set_rectangles);
void
glitz_set_rectangle (glitz_surface_t *dst,
const glitz_color_t *color,
int x,
int y,
unsigned int width,
unsigned int height)
{
glitz_rectangle_t rect;
rect.x = x;
rect.y = y;
rect.width = width;
rect.height = height;
glitz_set_rectangles (dst, color, &rect, 1);
}
slim_hidden_def(glitz_set_rectangle);

Просмотреть файл

@ -0,0 +1,166 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#define REGION_ALLOC_CHUNK 16
#define BOX_SUBSUMS_BOX(b1, b2) \
((b2)->x1 >= (b1)->x1 && \
(b2)->x2 <= (b1)->x2 && \
(b2)->y1 >= (b1)->y1 && \
(b2)->y2 <= (b1)->y2)
#define BOX_INTERSECTS_BOX(b1, b2) \
((b1)->x1 < (b2)->x2 && \
(b1)->x2 > (b2)->x1 && \
(b1)->y1 < (b2)->y2 && \
(b1)->y2 > (b2)->y1)
#define BOX_CLOSE_TO_BOX(b1, b2) \
((b1)->x1 < ((b2)->x2 + 1) && \
(b1)->x2 > ((b2)->x1 - 1) && \
(b1)->y1 < ((b2)->y2 + 1) && \
(b1)->y2 > ((b2)->y1 - 1))
#define BOX_NEXT_TO_BOX(b1, b2) \
((((b1)->x1 == (b2)->x2 || \
(b1)->x2 == (b2)->x1) && \
(b1)->y1 == (b2)->y1 && \
(b1)->y2 == (b2)->y2) || \
(((b1)->y1 == (b2)->y2 || \
(b1)->y2 == (b2)->y1) && \
(b1)->x1 == (b2)->x1 && \
(b1)->x2 == (b2)->x2))
#define MERGE_BOXES(d, b1, b2) \
{ \
(d)->x1 = MIN ((b1)->x1, (b2)->x1); \
(d)->y1 = MIN ((b1)->y1, (b2)->y1); \
(d)->x2 = MAX ((b1)->x2, (b2)->x2); \
(d)->y2 = MAX ((b1)->y2, (b2)->y2); \
}
/*
* No real union, boxes that intersect are just joined into bigger boxes.
* This is OK for our needs and it keeps the number of boxes down to a
* minimum and makes it faster.
*/
glitz_status_t
glitz_region_union (glitz_region_t *region,
glitz_box_t *ubox)
{
if (region->n_box == 0) {
region->extents = *ubox;
region->box = &region->extents;
region->n_box = 1;
return GLITZ_STATUS_SUCCESS;
}
if (BOX_CLOSE_TO_BOX (ubox, &region->extents)) {
glitz_box_t *box, *new_box, *dst_box;
int n_box;
box = region->box;
n_box = region->n_box;
while (n_box--) {
if (BOX_SUBSUMS_BOX (box, ubox))
return GLITZ_STATUS_SUCCESS;
box++;
}
box = region->box;
n_box = region->n_box;
new_box = ubox;
dst_box = NULL;
while (n_box--) {
if (BOX_INTERSECTS_BOX (box, new_box) ||
BOX_NEXT_TO_BOX (box, new_box)) {
if (dst_box) {
/*
* Remove box from region
*/
region->n_box--;
if (region->n_box == 1) {
MERGE_BOXES (&region->extents, box, new_box);
region->box = &region->extents;
return GLITZ_STATUS_SUCCESS;
} else {
MERGE_BOXES (dst_box, box, new_box);
if (n_box)
memmove (box, box + 1, n_box * sizeof (glitz_box_t));
}
continue;
} else {
dst_box = box;
MERGE_BOXES (dst_box, box, new_box);
new_box = dst_box;
}
}
box++;
}
if (dst_box) {
if (region->n_box > 1)
MERGE_BOXES (&region->extents, &region->extents, ubox);
return GLITZ_STATUS_SUCCESS;
}
}
/*
* Add box to region
*/
if (region->size < (region->n_box + 1)) {
region->size += REGION_ALLOC_CHUNK;
region->data = (void *) realloc (region->data,
sizeof (glitz_box_t) * region->size);
if (!region->data)
return GLITZ_STATUS_NO_MEMORY;
}
region->box = (glitz_box_t *) region->data;
region->box[region->n_box] = *ubox;
if (region->n_box == 1)
region->box[0] = region->extents;
region->n_box++;
MERGE_BOXES (&region->extents, &region->extents, ubox);
return GLITZ_STATUS_SUCCESS;
}

Просмотреть файл

@ -0,0 +1,90 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Authors: David Reveman <davidr@novell.com>
* Peter Nilsson <c99pnn@cs.umu.se>
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitzint.h"
unsigned long
glitz_status_to_status_mask (glitz_status_t status)
{
switch (status) {
case GLITZ_STATUS_NO_MEMORY:
return GLITZ_STATUS_NO_MEMORY_MASK;
case GLITZ_STATUS_BAD_COORDINATE:
return GLITZ_STATUS_BAD_COORDINATE_MASK;
case GLITZ_STATUS_NOT_SUPPORTED:
return GLITZ_STATUS_NOT_SUPPORTED_MASK;
case GLITZ_STATUS_CONTENT_DESTROYED:
return GLITZ_STATUS_CONTENT_DESTROYED_MASK;
case GLITZ_STATUS_SUCCESS:
break;
}
return 0;
}
glitz_status_t
glitz_status_pop_from_mask (unsigned long *mask)
{
if (*mask & GLITZ_STATUS_NO_MEMORY_MASK) {
*mask &= ~GLITZ_STATUS_NO_MEMORY_MASK;
return GLITZ_STATUS_NO_MEMORY;
} else if (*mask & GLITZ_STATUS_BAD_COORDINATE_MASK) {
*mask &= ~GLITZ_STATUS_BAD_COORDINATE_MASK;
return GLITZ_STATUS_BAD_COORDINATE;
} else if (*mask & GLITZ_STATUS_NOT_SUPPORTED_MASK) {
*mask &= ~GLITZ_STATUS_NOT_SUPPORTED_MASK;
return GLITZ_STATUS_NOT_SUPPORTED;
} else if (*mask & GLITZ_STATUS_CONTENT_DESTROYED_MASK) {
*mask &= ~GLITZ_STATUS_CONTENT_DESTROYED_MASK;
return GLITZ_STATUS_CONTENT_DESTROYED;
}
return GLITZ_STATUS_SUCCESS;
}
const char *
glitz_status_string (glitz_status_t status)
{
switch (status) {
case GLITZ_STATUS_SUCCESS:
return "success";
case GLITZ_STATUS_NO_MEMORY:
return "out of memory";
case GLITZ_STATUS_BAD_COORDINATE:
return "bad coordinate";
case GLITZ_STATUS_NOT_SUPPORTED:
return "not supported";
case GLITZ_STATUS_CONTENT_DESTROYED:
return "content destroyed";
}
return "<unknown error status>";
}

Просмотреть файл

@ -0,0 +1,927 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#include <stdlib.h>
#include <string.h>
glitz_surface_t *
glitz_surface_create (glitz_drawable_t *drawable,
glitz_format_t *format,
unsigned int width,
unsigned int height,
unsigned long mask,
glitz_surface_attributes_t *attributes)
{
glitz_surface_t *surface;
glitz_bool_t unnormalized = 0;
unsigned long feature_mask = drawable->backend->feature_mask;
if (!width || !height)
return NULL;
if (mask & GLITZ_SURFACE_UNNORMALIZED_MASK)
{
if (attributes->unnormalized)
{
if (!(feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK))
return NULL;
unnormalized = 1;
}
}
surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t));
if (surface == NULL)
return NULL;
surface->drawable = drawable;
glitz_drawable_reference (drawable);
surface->ref_count = 1;
surface->filter = GLITZ_FILTER_NEAREST;
surface->format = format;
surface->box.x2 = (short) width;
surface->box.y2 = (short) height;
surface->clip = &surface->box;
surface->n_clip = 1;
surface->buffer = GLITZ_GL_FRONT;
if (width == 1 && height == 1)
{
surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK;
surface->solid.alpha = 0xffff;
REGION_INIT (&surface->texture_damage, &surface->box);
REGION_INIT (&surface->drawable_damage, &surface->box);
}
else
{
REGION_INIT (&surface->texture_damage, NULL_BOX);
REGION_INIT (&surface->drawable_damage, NULL_BOX);
}
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)
{
glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT);
glitz_texture_size_check (&drawable->backend->gl, &surface->texture,
drawable->backend->max_texture_2d_size,
drawable->backend->max_texture_rect_size);
glitz_surface_pop_current (surface);
if (TEXTURE_INVALID_SIZE (&surface->texture))
{
glitz_surface_destroy (surface);
return NULL;
}
}
return surface;
}
void
glitz_surface_destroy (glitz_surface_t *surface)
{
if (!surface)
return;
surface->ref_count--;
if (surface->ref_count)
return;
if (surface->texture.name) {
glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT);
glitz_framebuffer_fini (&surface->drawable->backend->gl,
&surface->framebuffer);
glitz_texture_fini (&surface->drawable->backend->gl, &surface->texture);
glitz_surface_pop_current (surface);
}
REGION_UNINIT (&surface->texture_damage);
REGION_UNINIT (&surface->drawable_damage);
if (surface->geometry.buffer)
glitz_buffer_destroy (surface->geometry.buffer);
if (surface->geometry.array)
glitz_multi_array_destroy (surface->geometry.array);
if (surface->transform)
free (surface->transform);
if (surface->filter_params)
free (surface->filter_params);
if (surface->attached)
glitz_drawable_destroy (surface->attached);
glitz_drawable_destroy (surface->drawable);
free (surface);
}
void
glitz_surface_reference (glitz_surface_t *surface)
{
if (surface == NULL)
return;
surface->ref_count++;
}
static void
_glitz_surface_sync_texture (glitz_surface_t *surface)
{
if (REGION_NOTEMPTY (&surface->texture_damage))
{
glitz_box_t *box;
int n_box;
GLITZ_GL_SURFACE (surface);
if (!(TEXTURE_ALLOCATED (&surface->texture)))
glitz_texture_allocate (gl, &surface->texture);
if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface)))
{
glitz_gl_float_t color[4];
if (TEXTURE_ALLOCATED (&surface->texture))
{
color[0] = surface->solid.red / 65535.0f;
color[1] = surface->solid.green / 65535.0f;
color[2] = surface->solid.blue / 65535.0f;
color[3] = surface->solid.alpha / 65535.0f;
glitz_texture_bind (gl, &surface->texture);
gl->tex_sub_image_2d (surface->texture.target, 0,
surface->texture.box.x1,
surface->texture.box.y1,
1, 1, GLITZ_GL_RGBA,
GLITZ_GL_FLOAT, color);
glitz_texture_unbind (gl, &surface->texture);
}
REGION_EMPTY (&surface->texture_damage);
return;
}
glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
gl->read_buffer (surface->buffer);
gl->disable (GLITZ_GL_SCISSOR_TEST);
glitz_texture_bind (gl, &surface->texture);
box = REGION_RECTS (&surface->texture_damage);
n_box = REGION_NUM_RECTS (&surface->texture_damage);
while (n_box--)
{
glitz_texture_copy_drawable (gl,
&surface->texture,
surface->attached,
box->x1 + surface->x,
box->y1 + surface->y,
box->x2 - box->x1,
box->y2 - box->y1,
box->x1,
box->y1);
box++;
}
REGION_EMPTY (&surface->texture_damage);
glitz_texture_unbind (gl, &surface->texture);
gl->enable (GLITZ_GL_SCISSOR_TEST);
glitz_surface_pop_current (surface);
}
}
void
glitz_surface_sync_drawable (glitz_surface_t *surface)
{
if (REGION_NOTEMPTY (&surface->drawable_damage))
{
glitz_texture_t *texture;
glitz_box_t *box, *ext;
int n_box;
GLITZ_GL_SURFACE (surface);
texture = glitz_surface_get_texture (surface, 0);
if (!texture)
return;
box = REGION_RECTS (&surface->drawable_damage);
ext = REGION_EXTENTS (&surface->drawable_damage);
n_box = REGION_NUM_RECTS (&surface->drawable_damage);
glitz_texture_bind (gl, texture);
glitz_texture_set_tex_gen (gl, texture, NULL,
0, 0,
GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK,
NULL);
gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
gl->color_4us (0x0, 0x0, 0x0, 0xffff);
glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE);
glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST);
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
gl->scissor (surface->x + ext->x1,
surface->attached->height - surface->y - ext->y2,
ext->x2 - ext->x1,
ext->y2 - ext->y1);
if (n_box > 1)
{
glitz_float_t *data;
void *ptr;
int vertices;
ptr = malloc (n_box * 8 * sizeof (glitz_float_t));
if (!ptr) {
glitz_surface_status_add (surface,
GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
data = (glitz_float_t *) ptr;
vertices = n_box << 2;
while (n_box--)
{
*data++ = (glitz_float_t) box->x1;
*data++ = (glitz_float_t) box->y1;
*data++ = (glitz_float_t) box->x2;
*data++ = (glitz_float_t) box->y1;
*data++ = (glitz_float_t) box->x2;
*data++ = (glitz_float_t) box->y2;
*data++ = (glitz_float_t) box->x1;
*data++ = (glitz_float_t) box->y2;
box++;
}
gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr);
gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices);
free (ptr);
}
else
{
glitz_geometry_enable_none (gl, surface, ext);
gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
}
glitz_texture_unbind (gl, texture);
REGION_EMPTY (&surface->drawable_damage);
}
}
void
glitz_surface_sync_solid (glitz_surface_t *surface)
{
if (SURFACE_SOLID_DAMAGE (surface))
{
glitz_gl_float_t *c, color[64];
glitz_texture_t *texture;
GLITZ_GL_SURFACE (surface);
texture = glitz_surface_get_texture (surface, 0);
c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4];
if (texture)
{
glitz_texture_bind (gl, texture);
gl->get_tex_image (texture->target, 0,
GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color);
glitz_texture_unbind (gl, texture);
}
else
{
c[0] = c[1] = c[2] = 0.0f;
c[3] = 1.0f;
}
surface->solid.red = c[0] * 65535.0f;
surface->solid.green = c[1] * 65535.0f;
surface->solid.blue = c[2] * 65535.0f;
surface->solid.alpha = c[3] * 65535.0f;
surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
}
}
glitz_texture_t *
glitz_surface_get_texture (glitz_surface_t *surface,
glitz_bool_t allocate)
{
GLITZ_GL_SURFACE (surface);
if (REGION_NOTEMPTY (&surface->texture_damage))
{
_glitz_surface_sync_texture (surface);
}
else if (allocate)
{
if (!(TEXTURE_ALLOCATED (&surface->texture)))
glitz_texture_allocate (gl, &surface->texture);
}
if (TEXTURE_ALLOCATED (&surface->texture))
return &surface->texture;
return NULL;
}
void
glitz_surface_damage (glitz_surface_t *surface,
glitz_box_t *box,
int what)
{
if (box)
{
if (what & GLITZ_DAMAGE_DRAWABLE_MASK)
REGION_UNION (&surface->drawable_damage, box);
if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK))
REGION_UNION (&surface->texture_damage, box);
}
else
{
if (what & GLITZ_DAMAGE_DRAWABLE_MASK)
{
REGION_EMPTY (&surface->drawable_damage);
REGION_INIT (&surface->drawable_damage, &surface->box);
}
if (surface->attached && (what & GLITZ_DAMAGE_TEXTURE_MASK))
{
REGION_EMPTY (&surface->texture_damage);
REGION_INIT (&surface->texture_damage, &surface->box);
}
}
if (what & GLITZ_DAMAGE_SOLID_MASK)
surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
}
void
glitz_surface_status_add (glitz_surface_t *surface,
int flags)
{
surface->status_mask |= flags;
}
static void
_glitz_surface_update_state (glitz_surface_t *surface)
{
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;
}
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,
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,
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, -height, 0.0f);
drawable->viewport.x = surface->x;
drawable->viewport.y = surface->y;
drawable->viewport.width = surface->box.x2;
drawable->viewport.height = surface->box.y2;
drawable->update_all = 0;
}
gl->draw_buffer (surface->buffer);
if (SURFACE_DITHER (surface))
gl->enable (GLITZ_GL_DITHER);
else
gl->disable (GLITZ_GL_DITHER);
}
void
glitz_surface_attach (glitz_surface_t *surface,
glitz_drawable_t *drawable,
glitz_drawable_buffer_t buffer,
int x,
int y)
{
glitz_drawable_reference (drawable);
if (surface->attached)
glitz_drawable_destroy (surface->attached);
surface->attached = drawable;
surface->x = x;
surface->y = y;
switch (buffer) {
case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR:
surface->buffer = GLITZ_GL_FRONT;
break;
case GLITZ_DRAWABLE_BUFFER_BACK_COLOR:
surface->buffer = GLITZ_GL_BACK;
break;
}
if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface))
REGION_EMPTY (&surface->texture_damage);
}
void
glitz_surface_detach (glitz_surface_t *surface)
{
if (!surface->attached)
return;
if (REGION_NOTEMPTY (&surface->texture_damage))
{
glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
_glitz_surface_sync_texture (surface);
glitz_surface_pop_current (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);
}
glitz_drawable_t *
glitz_surface_get_drawable (glitz_surface_t *surface)
{
return surface->drawable;
}
slim_hidden_def(glitz_surface_get_drawable);
glitz_drawable_t *
glitz_surface_get_attached_drawable (glitz_surface_t *surface)
{
return surface->attached;
}
slim_hidden_def(glitz_surface_get_attached_drawable);
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)
{
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->drawable->backend->gl,
&surface->framebuffer,
&surface->texture))
{
_glitz_surface_update_state (surface);
return 1;
}
}
return 0;
}
}
return 1;
}
void
glitz_surface_pop_current (glitz_surface_t *surface)
{
glitz_surface_t *other;
if (surface->attached) {
other = surface->attached->backend->pop_current (surface->attached);
} else {
if (surface->framebuffer.name)
glitz_framebuffer_unbind (&surface->drawable->backend->gl);
other = surface->drawable->backend->pop_current (surface->drawable);
}
if (other) {
if ((!other->attached) &&
(other->drawable->backend->feature_mask &
GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK))
{
glitz_framebuffer_complete (&other->drawable->backend->gl,
&other->framebuffer,
&other->texture);
}
_glitz_surface_update_state (other);
}
}
void
glitz_surface_set_transform (glitz_surface_t *surface,
glitz_transform_t *transform)
{
static glitz_transform_t identity = {
{
{ FIXED1, 0x00000, 0x00000 },
{ 0x00000, FIXED1, 0x00000 },
{ 0x00000, 0x00000, FIXED1 }
}
};
if (transform &&
memcmp (transform, &identity, sizeof (glitz_transform_t)) == 0)
transform = NULL;
if (transform) {
glitz_gl_float_t height, *m, *t;
if (!surface->transform) {
surface->transform = malloc (sizeof (glitz_matrix_t));
if (surface->transform == NULL) {
glitz_surface_status_add (surface, GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
}
m = surface->transform->m;
t = surface->transform->t;
m[0] = FIXED_TO_FLOAT (transform->matrix[0][0]);
m[4] = FIXED_TO_FLOAT (transform->matrix[0][1]);
m[8] = 0.0f;
m[12] = FIXED_TO_FLOAT (transform->matrix[0][2]);
m[1] = FIXED_TO_FLOAT (transform->matrix[1][0]);
m[5] = FIXED_TO_FLOAT (transform->matrix[1][1]);
m[9] = 0.0f;
m[13] = FIXED_TO_FLOAT (transform->matrix[1][2]);
m[2] = 0.0f;
m[6] = 0.0f;
m[10] = 1.0f;
m[14] = 0.0f;
m[3] = FIXED_TO_FLOAT (transform->matrix[2][0]);
m[7] = FIXED_TO_FLOAT (transform->matrix[2][1]);
m[11] = 0.0f;
m[15] = FIXED_TO_FLOAT (transform->matrix[2][2]);
/* Projective transformation matrix conversion to normalized
texture coordinates seems to be working fine. However, it would be
good if someone could verify that this is actually a correct way for
doing this.
We need to do this:
scale (IDENTITY, 0, -1)
translate (IDENTITY, 0, -texture_height)
multiply (TEXTURE_MATRIX, IDENTITY, MATRIX)
scale (TEXTURE_MATRIX, 0, -1)
translate (TEXTURE_MATRIX, 0, -texture_height)
the following code does it pretty efficiently. */
height = surface->texture.texcoord_height_unit *
(surface->texture.box.y2 - surface->texture.box.y1);
t[0] = m[0];
t[4] = m[4];
t[8] = 0.0f;
t[12] = surface->texture.texcoord_width_unit * m[12];
t[3] = m[3] / surface->texture.texcoord_width_unit;
t[7] = m[7] / surface->texture.texcoord_height_unit;
t[11] = 0.0f;
t[15] = m[15];
t[1] = height * t[3] - m[1];
t[5] = height * t[7] - m[5];
t[9] = 0.0f;
t[13] = height * t[15] - surface->texture.texcoord_height_unit * m[13];
t[2] = 0.0f;
t[6] = 0.0f;
t[10] = 1.0f;
t[14] = 0.0f;
/* scale y = -1 */
t[4] = -t[4];
t[5] = -t[5];
t[7] = -t[7];
/* translate y = -texture_height */
t[12] -= t[4] * height;
t[13] -= t[5] * height;
t[15] -= t[7] * height;
/* Translate coordinates into texture. This only makes a difference when
GL_ARB_texture_border_clamp is missing as box.x1 and box.y1 are
otherwise always zero. This breaks projective transformations so
those wont work without GL_ARB_texture_border_clamp. */
t[12] += surface->texture.texcoord_width_unit * surface->texture.box.x1;
t[13] += surface->texture.texcoord_height_unit * surface->texture.box.y1;
surface->flags |= GLITZ_SURFACE_FLAG_TRANSFORM_MASK;
if (m[3] != 0.0f || m[7] != 0.0f || (m[15] != 1.0f && m[15] != -1.0f))
surface->flags |= GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK;
} else {
if (surface->transform)
free (surface->transform);
surface->transform = NULL;
surface->flags &= ~GLITZ_SURFACE_FLAG_TRANSFORM_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK;
}
}
slim_hidden_def(glitz_surface_set_transform);
void
glitz_surface_set_fill (glitz_surface_t *surface,
glitz_fill_t fill)
{
switch (fill) {
case GLITZ_FILL_TRANSPARENT:
surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK;
break;
case GLITZ_FILL_NEAREST:
surface->flags &= ~GLITZ_SURFACE_FLAG_REPEAT_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_PAD_MASK;
break;
case GLITZ_FILL_REPEAT:
surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_MIRRORED_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK;
break;
case GLITZ_FILL_REFLECT:
surface->flags |= GLITZ_SURFACE_FLAG_REPEAT_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_MIRRORED_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_PAD_MASK;
break;
}
glitz_filter_set_type (surface, surface->filter);
}
slim_hidden_def(glitz_surface_set_fill);
void
glitz_surface_set_component_alpha (glitz_surface_t *surface,
glitz_bool_t component_alpha)
{
if (component_alpha && surface->format->color.red_size)
surface->flags |= GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK;
else
surface->flags &= ~GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK;
}
slim_hidden_def(glitz_surface_set_component_alpha);
void
glitz_surface_set_filter (glitz_surface_t *surface,
glitz_filter_t filter,
glitz_fixed16_16_t *params,
int n_params)
{
glitz_status_t status;
status = glitz_filter_set_params (surface, filter, params, n_params);
if (status) {
glitz_surface_status_add (surface, glitz_status_to_status_mask (status));
} else {
switch (filter) {
case GLITZ_FILTER_NEAREST:
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
break;
case GLITZ_FILTER_BILINEAR:
surface->flags &= ~GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
break;
case GLITZ_FILTER_CONVOLUTION:
case GLITZ_FILTER_GAUSSIAN:
surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
break;
case GLITZ_FILTER_LINEAR_GRADIENT:
case GLITZ_FILTER_RADIAL_GRADIENT:
surface->flags |= GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK;
surface->flags &= ~GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK;
surface->flags |= GLITZ_SURFACE_FLAG_EYE_COORDS_MASK;
break;
}
surface->filter = filter;
}
}
slim_hidden_def(glitz_surface_set_filter);
void
glitz_surface_set_dither (glitz_surface_t *surface,
glitz_bool_t dither)
{
if (dither)
surface->flags |= GLITZ_SURFACE_FLAG_DITHER_MASK;
else
surface->flags &= ~GLITZ_SURFACE_FLAG_DITHER_MASK;
}
slim_hidden_def(glitz_surface_set_dither);
void
glitz_surface_flush (glitz_surface_t *surface)
{
if (surface->attached && REGION_NOTEMPTY (&surface->drawable_damage)) {
glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
glitz_surface_pop_current (surface);
}
}
slim_hidden_def(glitz_surface_flush);
unsigned int
glitz_surface_get_width (glitz_surface_t *surface)
{
return (unsigned int) surface->box.x2;
}
slim_hidden_def(glitz_surface_get_width);
unsigned int
glitz_surface_get_height (glitz_surface_t *surface)
{
return (unsigned int) surface->box.y2;
}
slim_hidden_def(glitz_surface_get_height);
glitz_status_t
glitz_surface_get_status (glitz_surface_t *surface)
{
return glitz_status_pop_from_mask (&surface->status_mask);
}
slim_hidden_def(glitz_surface_get_status);
glitz_format_t *
glitz_surface_get_format (glitz_surface_t *surface)
{
return surface->format;
}
slim_hidden_def(glitz_surface_get_format);
void
glitz_surface_translate_point (glitz_surface_t *surface,
glitz_point_fixed_t *src,
glitz_point_fixed_t *dst)
{
if (surface->texture.target == GLITZ_GL_TEXTURE_2D)
{
dst->x = (INT_TO_FIXED (surface->texture.box.x1) + src->x) /
surface->texture.width;
dst->y = (INT_TO_FIXED (surface->texture.box.y2) - src->y) /
surface->texture.height;
}
else
{
dst->x = INT_TO_FIXED (surface->texture.box.x1) + src->x;
dst->y = INT_TO_FIXED (surface->texture.box.y2) - src->y;
}
}
slim_hidden_def(glitz_surface_translate_point);
void
glitz_surface_set_clip_region (glitz_surface_t *surface,
int x_origin,
int y_origin,
glitz_box_t *box,
int n_box)
{
if (n_box)
{
surface->clip = box;
surface->n_clip = n_box;
surface->x_clip = x_origin;
surface->y_clip = y_origin;
}
else
{
surface->clip = &surface->box;
surface->n_clip = 1;
surface->x_clip = surface->y_clip = 0;
}
}
slim_hidden_def(glitz_surface_set_clip_region);
glitz_bool_t
glitz_surface_valid_target (glitz_surface_t *surface)
{
glitz_bool_t valid;
valid = glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
glitz_surface_pop_current (surface);
return valid;
}

Просмотреть файл

@ -0,0 +1,347 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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_texture_init (glitz_texture_t *texture,
int width,
int height,
glitz_gl_int_t texture_format,
unsigned long feature_mask,
glitz_bool_t unnormalized)
{
texture->filter = 0;
texture->wrap = 0;
texture->format = texture_format;
texture->name = 0;
if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)
{
texture->box.x1 = texture->box.y1 = 0;
texture->box.x2 = texture->width = width;
texture->box.y2 = texture->height = height;
texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
GLITZ_TEXTURE_FLAG_PADABLE_MASK;
}
else
{
texture->box.x1 = texture->box.y1 = 1;
texture->box.x2 = width + 1;
texture->box.y2 = height + 1;
texture->width = width + 2;
texture->height = height + 2;
texture->flags = 0;
}
if (!unnormalized &&
((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) ||
(POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height))))
{
texture->target = GLITZ_GL_TEXTURE_2D;
}
else
{
texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK;
if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)
{
texture->target = GLITZ_GL_TEXTURE_RECTANGLE;
}
else
{
texture->target = GLITZ_GL_TEXTURE_2D;
texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK;
if (!POWER_OF_TWO (texture->width))
texture->width = glitz_uint_to_power_of_two (texture->width);
if (!POWER_OF_TWO (texture->height))
texture->height = glitz_uint_to_power_of_two (texture->height);
}
}
if (texture->target == GLITZ_GL_TEXTURE_2D)
{
texture->texcoord_width_unit = 1.0f / texture->width;
texture->texcoord_height_unit = 1.0f / texture->height;
}
else
{
texture->texcoord_width_unit = 1.0f;
texture->texcoord_height_unit = 1.0f;
}
}
void
glitz_texture_size_check (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture,
glitz_gl_int_t max_2d,
glitz_gl_int_t max_rect) {
glitz_gl_enum_t proxy_target;
glitz_gl_int_t value, max;
if (texture->target == GLITZ_GL_TEXTURE_2D) {
max = max_2d;
proxy_target = GLITZ_GL_PROXY_TEXTURE_2D;
} else {
max = max_rect;
proxy_target = GLITZ_GL_PROXY_TEXTURE_RECTANGLE;
}
if (texture->width > max || texture->height > max) {
texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK;
return;
}
gl->tex_image_2d (proxy_target, 0,
texture->format, texture->width, texture->height,
0, GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
gl->get_tex_level_parameter_iv (proxy_target, 0,
GLITZ_GL_TEXTURE_WIDTH, &value);
if (value != texture->width) {
texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK;
return;
}
gl->get_tex_level_parameter_iv (proxy_target, 0,
GLITZ_GL_TEXTURE_HEIGHT, &value);
if (value != texture->height)
texture->flags |= GLITZ_TEXTURE_FLAG_INVALID_SIZE_MASK;
}
void
glitz_texture_allocate (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture)
{
char *data = NULL;
if (!texture->name)
gl->gen_textures (1, &texture->name);
texture->flags |= GLITZ_TEXTURE_FLAG_ALLOCATED_MASK;
glitz_texture_bind (gl, texture);
if (texture->box.x2 != texture->width ||
texture->box.y2 != texture->height) {
data = malloc (texture->width * texture->height);
if (data)
memset (data, 0, texture->width * texture->height);
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0);
gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0);
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1);
}
gl->tex_image_2d (texture->target, 0, texture->format,
texture->width, texture->height, 0,
GLITZ_GL_ALPHA, GLITZ_GL_UNSIGNED_BYTE, data);
gl->tex_parameter_i (texture->target,
GLITZ_GL_TEXTURE_MAG_FILTER,
GLITZ_GL_NEAREST);
gl->tex_parameter_i (texture->target,
GLITZ_GL_TEXTURE_MIN_FILTER,
GLITZ_GL_NEAREST);
texture->filter = GLITZ_GL_NEAREST;
glitz_texture_unbind (gl, texture);
if (data)
free (data);
}
void
glitz_texture_fini (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture)
{
if (texture->name)
gl->delete_textures (1, &texture->name);
}
void
glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture,
glitz_gl_enum_t filter)
{
if (!texture->name)
return;
if (texture->filter != filter) {
gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_MAG_FILTER, filter);
gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_MIN_FILTER, filter);
texture->filter = filter;
}
}
void
glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture,
glitz_gl_enum_t wrap)
{
if (!texture->name)
return;
if (texture->wrap != wrap) {
gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_WRAP_S, wrap);
gl->tex_parameter_i (texture->target, GLITZ_GL_TEXTURE_WRAP_T, wrap);
texture->wrap = wrap;
}
}
void
glitz_texture_bind (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture)
{
gl->disable (GLITZ_GL_TEXTURE_RECTANGLE);
gl->disable (GLITZ_GL_TEXTURE_2D);
if (!texture->name)
return;
gl->enable (texture->target);
gl->bind_texture (texture->target, texture->name);
}
void
glitz_texture_unbind (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture)
{
gl->bind_texture (texture->target, 0);
gl->disable (texture->target);
}
void
glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture,
glitz_drawable_t *drawable,
int x_drawable,
int y_drawable,
int width,
int height,
int x_texture,
int y_texture)
{
gl->copy_tex_sub_image_2d (texture->target, 0,
texture->box.x1 + x_texture,
texture->box.y2 - y_texture - height,
x_drawable,
drawable->height - y_drawable - height,
width, height);
}
void
glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture,
glitz_geometry_t *geometry,
int x_src,
int y_src,
unsigned long flags,
glitz_int_coordinate_t *coord)
{
glitz_vec4_t plane;
if (flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK)
{
plane.v[1] = plane.v[2] = 0.0f;
if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
{
plane.v[0] = 1.0f;
plane.v[3] = -x_src;
}
else
{
plane.v[0] = texture->texcoord_width_unit;
if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
plane.v[3] = -(x_src) * texture->texcoord_width_unit;
else
plane.v[3] = -(x_src - texture->box.x1) *
texture->texcoord_width_unit;
}
gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE,
GLITZ_GL_EYE_LINEAR);
gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v);
gl->enable (GLITZ_GL_TEXTURE_GEN_S);
}
else
gl->disable (GLITZ_GL_TEXTURE_GEN_S);
if (flags & GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK)
{
plane.v[0] = plane.v[2] = 0.0f;
if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
{
plane.v[1] = 1.0f;
plane.v[3] = -y_src;
}
else
{
plane.v[1] = -texture->texcoord_height_unit;
if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) *
texture->texcoord_height_unit;
else
plane.v[3] = (y_src + texture->box.y2) *
texture->texcoord_height_unit;
}
gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE,
GLITZ_GL_EYE_LINEAR);
gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v);
gl->enable (GLITZ_GL_TEXTURE_GEN_T);
}
else
gl->disable (GLITZ_GL_TEXTURE_GEN_T);
if (!(flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK))
{
unsigned char *ptr;
gl->enable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY);
ptr = glitz_buffer_bind (geometry->buffer, GLITZ_GL_ARRAY_BUFFER);
ptr += coord->offset;
gl->tex_coord_pointer (coord->size,
coord->type,
geometry->stride,
(void *) ptr);
} else
gl->disable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY);
}

Просмотреть файл

@ -0,0 +1,446 @@
/*
* 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"
/* whether 't' is a well defined not obviously empty trapezoid */
#define TRAPEZOID_VALID(t) ((t)->left.p1.y != (t)->left.p2.y && \
(t)->right.p1.y != (t)->right.p2.y && \
(int) ((t)->bottom - (t)->top) > 0)
/* whether 't' is a well defined not obviously empty trap */
#define TRAP_VALID(t) ((int) ((t)->bottom.y - (t)->top.y) > 0)
typedef struct _glitz_edge {
glitz_float_t dx, dy;
glitz_float_t x0, y0;
glitz_float_t kx, ky;
glitz_float_t tx, bx;
glitz_float_t hypx;
int hyp;
} glitz_edge_t;
#define EDGE_INIT(e, p1x, p1y, p2x, p2y) \
(e)->hyp = 1; \
(e)->dx = (p2x) - (p1x); \
(e)->dy = (p2y) - (p1y); \
if ((e)->dy) \
(e)->kx = (e)->dx / (e)->dy; \
else \
(e)->kx = 0; \
(e)->x0 = (p1x) - (e)->kx * (p1y); \
if ((e)->dx) \
(e)->ky = (e)->dy / (e)->dx; \
else \
(e)->ky = 0; \
(e)->y0 = (p1y) - (e)->ky * (p1x)
#define EDGE_X(e, _y) (((e)->kx * (_y)) + (e)->x0)
#define EDGE_Y(e, _x) (((e)->ky * (_x)) + (e)->y0)
#define EDGE_INTERSECT_BOX(upper_x, lower_y, left_y, right_y, \
box_x1, box_x2, box_y1, box_y2, \
max_x, max_y, \
_x1, _y1, _x2, _y2) \
if (upper_x < (box_x1)) \
{ \
(_x1) = 0.0f; \
(_y1) = (left_y) - (box_y1); \
} \
else if ((upper_x) > (box_x2)) \
{ \
(_x1) = (max_x); \
(_y1) = (right_y) - (box_y1); \
} \
else \
{ \
(_x1) = (upper_x) - (box_x1); \
(_y1) = 0.0f; \
} \
if ((lower_x) < (box_x1)) \
{ \
(_x2) = 0.0f; \
(_y2) = (left_y) - (box_y1); \
} \
else if ((lower_x) > (box_x2)) \
{ \
(_x2) = (max_x); \
(_y2) = (right_y) - (box_y1); \
} \
else \
{ \
(_x2) = (lower_x) - (box_x1); \
(_y2) = (max_y); \
}
#define AREA_ABOVE_LEFT(x1, y1, x2, y2, bottom) \
((x1) * (y1) + \
(((x1) + (x2)) / 2.0f) * ((y2) - (y1)) + \
(x2) * ((bottom) - (y2)))
/*
Given a single pixel position this function calculates
trapezoid pixel coverage.
*/
static glitz_float_t
_glitz_pixel_area (glitz_float_t pixel_x,
glitz_float_t pixel_y,
glitz_float_t top,
glitz_float_t bottom,
glitz_edge_t *left,
glitz_edge_t *right)
{
glitz_float_t area;
glitz_float_t upper_x, lower_x;
glitz_float_t left_y, right_y;
glitz_float_t pixel_x_1 = pixel_x + 1.0f;
glitz_float_t pixel_y_1 = pixel_y + 1.0f;
glitz_float_t x1, x2, y1, y2;
if (bottom >= pixel_y_1)
bottom = 1.0f;
else
bottom = bottom - pixel_y;
if (top <= pixel_y)
top = 0.0f;
else
top = top - pixel_y;
if (right->ky)
{
upper_x = EDGE_X (right, pixel_y);
lower_x = EDGE_X (right, pixel_y_1);
left_y = EDGE_Y (right, pixel_x);
right_y = EDGE_Y (right, pixel_x_1);
EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y,
pixel_x, pixel_x_1, pixel_y, pixel_y_1,
1.0f, 1.0f, x1, y1, x2, y2);
if (bottom <= y1)
{
if (left_y > right_y)
area = bottom;
else
area = 0.0f;
}
else
{
if (bottom < y2)
{
x2 -= right->kx * (y2 - bottom);
y2 = bottom;
}
area = AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom);
}
if (top <= y1)
{
if (left_y > right_y)
area -= top;
}
else
{
if (top < y2)
{
x2 -= right->kx * (y2 - top);
y2 = top;
}
area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, top);
}
}
else
{
/* Vertical Edge */
if (right->x0 < pixel_x_1)
area = (right->x0 - pixel_x) * (bottom - top);
else
area = bottom - top;
}
if (left->kx)
{
upper_x = EDGE_X (left, pixel_y);
lower_x = EDGE_X (left, pixel_y_1);
left_y = EDGE_Y (left, pixel_x);
right_y = EDGE_Y (left, pixel_x_1);
EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y,
pixel_x, pixel_x_1, pixel_y, pixel_y_1,
1.0f, 1.0f, x1, y1, x2, y2);
if (bottom <= y1)
{
if (left_y > right_y)
area -= bottom;
}
else
{
if (bottom < y2)
{
x2 -= left->kx * (y2 - bottom);
y2 = bottom;
}
area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom);
}
if (top <= y1)
{
if (left_y > right_y)
area += top;
}
else
{
if (top < y2)
{
x2 -= left->kx * (y2 - top);
y2 = top;
}
area += AREA_ABOVE_LEFT (x1, y1, x2, y2, top);
}
}
else
{
/* Vertical Edge */
if (left->x0 > pixel_x)
area -= (left->x0 - pixel_x) * (bottom - top);
}
return area;
}
#define TRAPINIT(trap, _top, _bottom, _left, _right) \
if (!TRAPEZOID_VALID (trap)) \
continue; \
\
(_top) = FIXED_TO_FLOAT ((trap)->top); \
(_bottom) = FIXED_TO_FLOAT ((trap)->bottom); \
\
(_left)->tx = FIXED_TO_FLOAT ((trap)->left.p1.x); \
(_left)->bx = FIXED_TO_FLOAT ((trap)->left.p1.y); \
\
(_right)->tx = FIXED_TO_FLOAT ((trap)->right.p1.x); \
(_right)->bx = FIXED_TO_FLOAT ((trap)->right.p1.y); \
\
EDGE_INIT (_left, \
(_left)->tx, (_left)->bx, \
FIXED_TO_FLOAT ((trap)->left.p2.x), \
FIXED_TO_FLOAT ((trap)->left.p2.y)); \
\
EDGE_INIT (_right, \
(_right)->tx, (_right)->bx, \
FIXED_TO_FLOAT ((trap)->right.p2.x), \
FIXED_TO_FLOAT ((trap)->right.p2.y)); \
\
if ((_left)->dx) \
{ \
(_left)->tx = EDGE_X (_left, _top); \
(_left)->bx = EDGE_X (_left, _bottom); \
} else \
(_left)->tx = (_left)->bx = (_left)->x0; \
\
if ((_right)->dx) \
{ \
(_right)->tx = EDGE_X (_right, _top); \
(_right)->bx = EDGE_X (_right, _bottom); \
} else \
(_right)->tx = (_right)->bx = (_right)->x0
#define TRAP glitz_trapezoid_t
#define UNIT glitz_short_t
#define TRAPS _glitz_add_trapezoids_short
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_int_t
#define TRAPS _glitz_add_trapezoids_int
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_float_t
#define TRAPS _glitz_add_trapezoids_float
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_double_t
#define TRAPS _glitz_add_trapezoids_double
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#undef TRAP
#undef TRAPINIT
#define TRAPINIT(trap, _top, _bottom, _left, _right) \
if (!TRAP_VALID (trap)) \
continue; \
\
(_top) = FIXED_TO_FLOAT ((trap)->top.y); \
(_bottom) = FIXED_TO_FLOAT ((trap)->bottom.y); \
\
(_left)->tx = FIXED_TO_FLOAT ((trap)->top.left); \
(_left)->bx = FIXED_TO_FLOAT ((trap)->bottom.left); \
\
(_right)->tx = FIXED_TO_FLOAT ((trap)->top.right); \
(_right)->bx = FIXED_TO_FLOAT ((trap)->bottom.right); \
\
EDGE_INIT (_left, \
(_left)->tx, _top, \
(_left)->bx, _bottom); \
\
EDGE_INIT (_right, \
(_right)->tx, _top, \
(_right)->bx, _bottom)
#define TRAP glitz_trap_t
#define UNIT glitz_short_t
#define TRAPS _glitz_add_traps_short
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_int_t
#define TRAPS _glitz_add_traps_int
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_float_t
#define TRAPS _glitz_add_traps_float
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#define UNIT glitz_double_t
#define TRAPS _glitz_add_traps_double
#include "glitz_trapimp.h"
#undef TRAPS
#undef UNIT
#undef TRAP
#undef TRAPINIT
int
glitz_add_trapezoids (glitz_buffer_t *buffer,
int offset,
unsigned int size,
glitz_data_type_t type,
glitz_surface_t *mask,
glitz_trapezoid_t *traps,
int n_traps,
int *n_added)
{
int count, n = n_traps;
uint8_t *ptr;
*n_added = 0;
ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
return 0;
ptr += offset;
switch (type) {
case GLITZ_DATA_TYPE_SHORT:
count = _glitz_add_trapezoids_short (ptr, size, mask, traps, &n_traps);
break;
case GLITZ_DATA_TYPE_INT:
count = _glitz_add_trapezoids_int (ptr, size, mask, traps, &n_traps);
break;
case GLITZ_DATA_TYPE_DOUBLE:
count = _glitz_add_trapezoids_double (ptr, size, mask,
traps, &n_traps);
break;
default:
count = _glitz_add_trapezoids_float (ptr, size, mask, traps, &n_traps);
break;
}
if (glitz_buffer_unmap (buffer))
return 0;
*n_added = n - n_traps;
return count;
}
int
glitz_add_traps (glitz_buffer_t *buffer,
int offset,
unsigned int size,
glitz_data_type_t type,
glitz_surface_t *mask,
glitz_trap_t *traps,
int n_traps,
int *n_added)
{
int count, n = n_traps;
uint8_t *ptr;
*n_added = 0;
ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
return 0;
ptr += offset;
switch (type) {
case GLITZ_DATA_TYPE_SHORT:
count = _glitz_add_traps_short (ptr, size, mask, traps, &n_traps);
break;
case GLITZ_DATA_TYPE_INT:
count = _glitz_add_traps_int (ptr, size, mask, traps, &n_traps);
break;
case GLITZ_DATA_TYPE_DOUBLE:
count = _glitz_add_traps_double (ptr, size, mask, traps, &n_traps);
break;
default:
count = _glitz_add_traps_float (ptr, size, mask, traps, &n_traps);
break;
}
if (glitz_buffer_unmap (buffer))
return 0;
*n_added = n - n_traps;
return count;
}

Просмотреть файл

@ -0,0 +1,749 @@
/*
* 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>
*/
/*
Define the following before including this file:
TRAPS name of function for adding trapezoids
UNIT type of underlying vertex unit
TRAP type of underlying trapezoid structure
TRAPINIT initialization code for underlying trapezoid structure
*/
#define BYTES_PER_VERTEX (2 * sizeof (UNIT) + sizeof (glitz_float_t))
#define BYTES_PER_QUAD (4 * BYTES_PER_VERTEX)
#define VSKIP (BYTES_PER_VERTEX / sizeof (UNIT))
#define TSKIP (BYTES_PER_VERTEX / sizeof (glitz_float_t))
#define ADD_VERTEX(vptr, tptr, texcoord, _x, _y) \
(vptr)[0] = (UNIT) (_x); \
(vptr)[1] = (UNIT) (_y); \
(tptr)[0] = (texcoord); \
(vptr) += VSKIP; \
(tptr) += TSKIP
#define ADD_QUAD(vptr, tptr, offset, size, \
t00, t01, t10, t11, x1, y1, x2, y2) \
if ((offset) == (size)) \
return (toff); \
(offset) += BYTES_PER_QUAD; \
ADD_VERTEX (vptr, tptr, t00, x1, y1); \
ADD_VERTEX (vptr, tptr, t01, x2, y1); \
ADD_VERTEX (vptr, tptr, t10, x2, y2); \
ADD_VERTEX (vptr, tptr, t11, x1, y2)
#define ADD_PIXEL(vptr, tptr, offset, size, tmp0, tbase, tsize, \
x1, y1, x2, y2, alpha) \
(tmp0) = (tbase) + (alpha - 0.5f) * (tsize); \
ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp0, tmp0, \
x1, y1, x2, y2)
#define CALC_SPAN(tmp0, tmp1, tbase, tsize, edge, end) \
(tmp0) = (edge) - (end); \
(tmp0) = (tbase) - (tmp0) * (tsize); \
(tmp1) = (tbase) + (end) * (tsize)
#define ADD_LEFT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \
x1, y1, x2, y2, end) \
CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \
ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp1, tmp0, \
x1, y1, x2, y2)
#define ADD_RIGHT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \
x1, y1, x2, y2, end) \
CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \
ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp0, tmp0, tmp1, \
x1, y1, x2, y2)
#define ADD_TOP_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \
x1, y1, x2, y2, end) \
CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \
ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp1, tmp1, \
x1, y1, x2, y2)
#define ADD_BOTTOM_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \
x1, y1, x2, y2, end) \
CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \
ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp1, tmp0, tmp0, \
x1, y1, x2, y2)
#define CALC_EDGE(tl, tr, bl, br, x1, x2, tsize, edge, tx, bx) \
if ((edge)->hyp) \
{ \
(edge)->hypx = (edge)->dy / \
sqrtf ((edge)->dx * (edge)->dx + (edge)->dy * (edge)->dy); \
(edge)->hyp = 0; \
} \
(tl) = (((tx) - (x1)) * (edge)->hypx) * tsize; \
(tr) = (((tx) - (x2)) * (edge)->hypx) * tsize; \
(bl) = (((bx) - (x1)) * (edge)->hypx) * tsize; \
(br) = (((bx) - (x2)) * (edge)->hypx) * tsize
#define CALC_LEFT_EDGE(tl, tr, bl, br, x1, x2, tbase, tsize, edge, tx, bx) \
CALC_EDGE (tl, tr, bl, br, x1, x2, tsize, edge, tx, bx); \
(tl) = (tbase) - (tl); \
(tr) = (tbase) - (tr); \
(bl) = (tbase) - (bl); \
(br) = (tbase) - (br)
#define CALC_RIGHT_EDGE(tl, tr, bl, br, x1, x2, tbase, tsize, edge, tx, bx) \
CALC_EDGE (tl, tr, bl, br, x1, x2, tsize, edge, tx, bx); \
(tl) = (tbase) + (tl); \
(tr) = (tbase) + (tr); \
(bl) = (tbase) + (bl); \
(br) = (tbase) + (br)
#define ADD_LEFT_EDGE(vptr, tptr, offset, size, \
tmp0, tmp1, tmp2, tmp3, tbase, tsize, \
edge, x1, y1, x2, y2, tx, bx) \
CALC_LEFT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \
tbase, tsize, edge, tx, bx); \
ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \
x1, y1, x2, y2)
#define ADD_RIGHT_EDGE(vptr, tptr, offset, size, \
tmp0, tmp1, tmp2, tmp3, tbase, tsize, \
edge, x1, y1, x2, y2, tx, bx) \
CALC_RIGHT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \
tbase, tsize, edge, tx, bx); \
ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \
x1, y1, x2, y2)
/*
An implicit mask surface for a single anti-aliased edge that
intersect a rectangle in any direction, can be represented
accurately and consistently with a set of one-dimensional texture
coordinates in a fixed size texture. By using linear texture
filtering this allows us to render perfectly anti-aliased
geometry on a wide range of hardware.
Each trapezoid needs to be slit up into a set of rectangles along
with appropriate horizontal texture coordinates for the specified
mask surface. In general the mask is a 2x1 surface with pixel
0,0 "clear black" and pixel 1,0 "solid white". It could also be a
Nx1 surface containing a pre-computed gamma curve with resolution
N for gamma corrected anti-aliasing.
This function generates geometry data in the following format:
primitive : QUADS
type : SHORT|INT|FLOAT|DOUBLE
stride : 2 * sizeof (type) + sizeof (FLOAT)
attributes : MASK_COORD
mask.type : FLOAT
mask.size : COORDINATE_SIZE_X
mask.offset : 2 * sizeof (type)
Trapezoid:
top { l, r, y }
bottom { l, r, y }
Bounds:
x1 = floor (MIN (top.l, bottom.l))
x2 = ceil (MAX (top.r, bottom.r))
y1 = floor (top.y)
y2 = ceil (bottom.y)
W = x2 - x1;
H = y2 - y1;
TH = 1 if TOP rectangle exist, else 0
BH = 1 if BOTTOM rectangle exist, else 0
TOP rectangle exists if: floor (top.y) != top.y
BOTTOM rectangle exists if: ceil (bottom.y) != bottom.y &&
bottom.y > ceil (top.y)
MIDDLE rectangle exists if: (H - TH - BH) > 0
W
+----------------------------------------------------+
| |
| TOP +---------------------------+ | TH
| / | |
+---------------/-----------------------------+------+
| / | |
| MIDDLE / | |
| / | |
| / | |
| / | | H - TH - BH
| / | |
| / | |
| / | |
| / | |
+-----/---------------------------------------+------+
| / | |
| +-----------------------------------------+ | BH
| BOTTOM |
+----------------------------------------------------+
*/
static unsigned int
TRAPS (void *ptr,
unsigned int size,
glitz_surface_t *mask,
TRAP *traps,
int *n_traps)
{
unsigned int toff = 0, offset = 0;
UNIT *vptr = (UNIT *) ptr;
glitz_float_t *tptr = (glitz_float_t *) (vptr + 2);
glitz_edge_t left, right;
glitz_float_t top, bottom;
glitz_float_t tbase, tsize;
glitz_float_t l, r, lspan, rspan;
glitz_float_t tmp0, tmp1, tmp2, tmp3, tmpx, tmpy;
glitz_float_t x1, x2, lx, rx;
glitz_float_t y, y0, y1, y2, y3;
glitz_float_t y1lx, y2lx, y1rx, y2rx;
glitz_float_t area;
size -= size % BYTES_PER_QUAD;
tsize = (glitz_float_t) (mask->texture.box.x2 - mask->texture.box.x1);
tbase = (glitz_float_t) mask->texture.box.x1 + (tsize / 2.0f);
tsize = (tsize - 1.0f) * mask->texture.texcoord_width_unit;
tbase *= mask->texture.texcoord_width_unit;
for (; *n_traps; (*n_traps)--, traps++)
{
TRAPINIT (traps, top, bottom, &left, &right);
/*
Top left X greater than top right X or bottom left X greater
than bottom right X. To me, this seems like an invalid trapezoid.
Cairo's current caps generation code, creates a lot of these. The
following adjustments makes them render almost correct.
*/
if (left.tx > right.tx)
{
if (floorf (left.tx) > floorf (right.tx))
left.tx = right.tx = floorf (left.tx);
}
if (left.bx > right.bx)
{
if (floorf (left.bx) > floorf (right.bx))
left.bx = right.bx = floorf (left.bx);
}
x1 = floorf (MIN (left.tx, left.bx));
x2 = ceilf (MAX (right.tx, right.bx));
/*
TOP rectangle
W
+---------+---------+------------------+---------+--------+
| | | | | |
| lE | +------+------------------|------+ | rE |
| |/ | | \| | 1
| /| lEtE | tE | tErE |\ |
| +-+---------+------------------+---------+-+ |
+-----+---+---------+------------------+---------+--------+
The following set sub-rectangles might need to be generated
to render the top span of the trapezoid correctly.
lE = Left Edge
tE = Top Edge
rE = Right Edge
lEtE = Left/Top Edge intersection
tErE = Top/Right Edge intersection
*/
y1 = ceilf (top);
if (y1 != top)
{
y0 = floorf (top);
lx = x1;
rx = x2;
y1lx = EDGE_X (&left, y1);
y1rx = EDGE_X (&right, y1);
if (bottom > y1)
{
l = MAX (left.tx, y1lx);
r = MIN (right.tx, y1rx);
}
else
{
l = MAX (left.tx, left.bx);
r = MIN (right.tx, right.bx);
}
lspan = ceilf (l);
rspan = floorf (r);
l = floorf (l);
if (l > rspan)
l = rspan;
r = ceilf (r);
if (r < lspan)
r = lspan;
/* Left Edge */
if (l > x1)
{
lx = EDGE_X (&left, y0);
if (left.dx > 0.0f)
{
tmpx = y1lx + (left.tx - lx);
lx = left.tx;
}
else
{
if (bottom < y1)
{
lx += (left.bx - y1lx);
tmpx = left.bx;
}
else
tmpx = y1lx;
}
ADD_LEFT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &left,
x1, y0, l, y1,
lx, tmpx);
lx = l;
}
/* Right Edge */
if (r < x2)
{
rx = EDGE_X (&right, y0);
if (right.dx < 0.0f)
{
tmpx = y1rx - (rx - right.tx);
rx = right.tx;
}
else
{
if (bottom < y1)
{
rx -= (y1rx - right.bx);
tmpx = right.bx;
}
else
tmpx = y1rx;
}
ADD_RIGHT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &right,
r, y0, x2, y1,
rx, tmpx);
rx = r;
}
/* Left/Top Edge intersection */
if (lx < l)
{
area = _glitz_pixel_area (l++, y0,
top, bottom,
&left, &right);
ADD_LEFT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
lx, y0, l, y1,
area);
}
/* Top Edge */
while (l < r)
{
if (l < lspan || l >= rspan)
{
area = _glitz_pixel_area (l, y0,
top, bottom,
&left, &right);
tmpx = l++;
ADD_PIXEL (vptr, tptr, offset, size,
tmp0,
tbase, tsize,
tmpx, y0, l, y1,
area);
}
else
{
area = MIN (bottom, y1) - top;
ADD_TOP_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
lspan, y0, rspan, y1,
area);
l = rspan;
}
}
/* Top/Right Edge intersection */
if (rx > r)
{
area = _glitz_pixel_area (r, y0,
top, bottom,
&left, &right);
ADD_RIGHT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
r, y0, rx, y1,
area);
}
}
else
{
y1lx = EDGE_X (&left, y1);
y1rx = EDGE_X (&right, y1);
}
/*
BOTTOM rectangle
W
+--+------+---------+------------------+---------+----+----+
| \ | | | | / |
| \ | | | |/ |
| \| | | /| | 1
| |\ lEbE | bE | bErE / | |
| lE | +------+------------------|----+ | rE |
| | | | | |
+---------+---------+------------------+---------+---------+
The following set sub-rectangles might need to be generated
to render the bottom span of the trapezoid correctly.
lE = Left Edge
bE = Top Edge
rE = Right Edge
lEbE = Left/Bottom Edge intersection
bErE = Bottom/Right Edge intersection
*/
y2 = floorf (bottom);
if (y2 != bottom && y2 >= y1)
{
y3 = ceilf (bottom);
lx = x1;
rx = x2;
if (y2 > y1)
{
y2lx = EDGE_X (&left, y2);
y2rx = EDGE_X (&right, y2);
}
else
{
y2lx = y1lx;
y2rx = y1rx;
}
l = MAX (left.bx, y2lx);
r = MIN (right.bx, y2rx);
lspan = ceilf (l);
rspan = floorf (r);
l = floorf (l);
if (l > rspan)
l = rspan;
r = ceilf (r);
if (r < lspan)
r = lspan;
/* Left Edge */
if (l > x1)
{
lx = EDGE_X (&left, y3);
if (y2lx > left.bx)
{
tmpx = y2lx + (left.bx - lx);
lx = left.bx;
} else
tmpx = y2lx;
ADD_LEFT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &left,
x1, y2, l, y3,
tmpx, lx);
lx = l;
}
/* Right Edge */
if (r < x2)
{
rx = EDGE_X (&right, y3);
if (y2rx < right.bx)
{
tmpx = y2rx - (rx - right.bx);
rx = right.bx;
} else
tmpx = y2rx;
ADD_RIGHT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &right,
r, y2, x2, y3,
tmpx, rx);
rx = r;
}
/* Left/Bottom Edge intersection */
if (lx < l)
{
area = _glitz_pixel_area (l++, y2,
top, bottom,
&left, &right);
ADD_LEFT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
lx, y2, l, y3,
area);
}
/* Bottom Edge */
while (l < r)
{
if (l < lspan || l >= rspan)
{
area = _glitz_pixel_area (l, y2,
top, bottom,
&left, &right);
tmpx = l++;
ADD_PIXEL (vptr, tptr, offset, size,
tmp0,
tbase, tsize,
tmpx, y2, l, y3,
area);
}
else
{
area = bottom - y2;
ADD_BOTTOM_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
lspan, y2, rspan, y3,
area);
l = rspan;
}
}
/* Bottom/Right Edge intersection */
if (rx > r)
{
area = _glitz_pixel_area (r, y2,
top, bottom,
&left, &right);
ADD_RIGHT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
r, y2, rx, y3,
area);
}
}
else
{
y2lx = EDGE_X (&left, y2);
y2rx = EDGE_X (&right, y2);
}
/*
MIDDLE rectangle
W
+---+---------------------------------+--------+------+
| \ | / |
| \ | / |
| \ lE | / rE | H - TH - BH
| \ | / |
| \ | / |
+---------+---------------------------+--+------------+
The following set sub-rectangles might need to be generated
to render the middle span of the trapezoid correctly.
lE = Left Edge
rE = Right Edge
If floor (MIN (rE)) < ceil (MAX (lE)) a number of left and right
edges needs to be generated as pixels intersected by both edges
needs to be calculated separately in a middle span.
*/
if (y1 < y2)
{
left.tx = y1lx;
right.tx = y1rx;
do {
if (left.tx > y2rx)
{
rx = lx = ceilf (left.tx);
if (right.dx)
y = floorf (EDGE_Y (&right, rx));
else
y = y2;
}
else
{
rx = lx = floorf (MIN (right.tx, y2rx));
if (left.dx)
y = floorf (EDGE_Y (&left, rx));
else
y = y2;
}
if (y == y1)
y = y1 + 1.0f;
if (y > y1 && y < y2)
{
left.bx = EDGE_X (&left, y);
right.bx = EDGE_X (&right, y);
}
else
{
y = y2;
left.bx = y2lx;
right.bx = y2rx;
}
if (lx > right.tx)
lx = floorf (right.tx);
if (lx > right.bx)
lx = floorf (right.bx);
if (rx < left.tx)
rx = ceilf (left.tx);
if (rx < left.bx)
rx = ceilf (left.bx);
/* Left Edge */
if (lx > x1)
{
if (left.dx)
{
ADD_LEFT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &left,
x1, y1, lx, y,
left.tx, left.bx);
}
else
{
area = lx - left.x0;
ADD_LEFT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
x1, y1, lx, y,
area);
}
}
/* Middle Span */
while (lx < rx)
{
tmpy = y1;
tmpx = lx++;
while (tmpy < y)
{
y0 = tmpy++;
area = _glitz_pixel_area (tmpx, y0,
y0, y2,
&left, &right);
ADD_PIXEL (vptr, tptr, offset, size,
tmp0,
tbase, tsize,
tmpx, y0, lx, tmpy,
area);
}
}
/* Right Edge */
if (rx < x2)
{
if (right.dx)
{
ADD_RIGHT_EDGE (vptr, tptr, offset, size,
tmp0, tmp1, tmp2, tmp3,
tbase, tsize, &right,
rx, y1, x2, y,
right.tx, right.bx);
}
else
{
area = right.x0 - rx;
ADD_RIGHT_SPAN (vptr, tptr, offset, size,
tmp0, tmp1,
tbase, tsize,
rx, y1, x2, y,
area);
}
}
left.tx = left.bx;
right.tx = right.bx;
y1 = y;
} while (y < y2);
}
toff = offset;
}
return toff;
}
#undef ADD_RIGHT_EDGE
#undef ADD_LEFT_EDGE
#undef CALC_RIGHT_EDGE
#undef CALC_LEFT_EDGE
#undef CALC_EDGE
#undef ADD_BOTTOM_SPAN
#undef ADD_TOP_SPAN
#undef ADD_RIGHT_SPAN
#undef ADD_LEFT_SPAN
#undef CALC_SPAN
#undef ADD_PIXEL
#undef ADD_QUAD
#undef ADD_VERTEX
#undef TSKIP
#undef VSKIP
#undef BYTES_PER_QUAD
#undef BYTES_PER_VERTEX

Просмотреть файл

@ -0,0 +1,367 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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"
#include <stdlib.h>
#include <string.h>
static glitz_extension_map gl_extensions[] = {
{ 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, "GL_EXT_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, "GL_NV_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
{ 0.0, "GL_ARB_texture_non_power_of_two",
GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK },
{ 0.0, "GL_ARB_texture_mirrored_repeat",
GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK },
{ 0.0, "GL_ARB_texture_border_clamp",
GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK },
{ 0.0, "GL_ARB_texture_env_combine",
GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK },
{ 0.0, "GL_EXT_texture_env_combine",
GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK },
{ 0.0, "GL_ARB_texture_env_dot3", GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK },
{ 0.0, "GL_ARB_multisample", GLITZ_FEATURE_MULTISAMPLE_MASK },
{ 0.0, "GL_NV_multisample_filter_hint",
GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK },
{ 0.0, "GL_ARB_multitexture", GLITZ_FEATURE_MULTITEXTURE_MASK },
{ 0.0, "GL_EXT_multi_draw_arrays", GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK },
{ 0.0, "GL_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK },
{ 0.0, "GL_ARB_vertex_buffer_object",
GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK },
{ 0.0, "GL_ARB_pixel_buffer_object",
GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
{ 0.0, "GL_EXT_pixel_buffer_object",
GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
{ 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 }
};
static glitz_bool_t
_glitz_extension_check (const char *extensions,
const char *ext_name)
{
char *end;
char *p = (char *) extensions;
int ext_name_len = strlen (ext_name);
if (! p)
return 0;
end = p + strlen (p);
while (p < end) {
int n = strcspn (p, " ");
if ((ext_name_len == n) && (strncmp (ext_name, p, n) == 0)) {
return 1;
}
p += (n + 1);
}
return 0;
}
unsigned long
glitz_extensions_query (glitz_gl_float_t version,
const char *extensions_string,
glitz_extension_map *extensions_map)
{
unsigned long mask = 0;
int i;
for (i = 0; extensions_map[i].name; i++)
if (((extensions_map[i].version > 1.0) &&
(version >= extensions_map[i].version)) ||
_glitz_extension_check (extensions_string, extensions_map[i].name))
mask |= extensions_map[i].mask;
return mask;
}
static glitz_status_t
_glitz_query_gl_extensions (glitz_gl_proc_address_list_t *gl,
glitz_gl_float_t *gl_version,
unsigned long *feature_mask)
{
const char *gl_extensions_string;
*gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION));
if (*gl_version < 1.2f)
return GLITZ_STATUS_NOT_SUPPORTED;
gl_extensions_string = (const char *) gl->get_string (GLITZ_GL_EXTENSIONS);
*feature_mask = glitz_extensions_query (*gl_version,
gl_extensions_string,
gl_extensions);
if ((*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) &&
(*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) {
glitz_gl_int_t max_texture_units;
gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units);
if (max_texture_units >= 3)
*feature_mask |= GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK;
}
return GLITZ_STATUS_SUCCESS;
}
static void
_glitz_gl_proc_address_lookup (glitz_backend_t *backend,
glitz_get_proc_address_proc_t get_proc_address,
void *closure)
{
if (backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) {
if (backend->gl_version >= 1.4f) {
backend->gl.blend_color = (glitz_gl_blend_color_t)
get_proc_address ("glBlendColor", closure);
} else {
backend->gl.blend_color = (glitz_gl_blend_color_t)
get_proc_address ("glBlendColorEXT", closure);
}
if (!backend->gl.blend_color)
backend->feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK;
}
if (backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) {
if (backend->gl_version >= 1.3f) {
backend->gl.active_texture = (glitz_gl_active_texture_t)
get_proc_address ("glActiveTexture", closure);
backend->gl.client_active_texture = (glitz_gl_client_active_texture_t)
get_proc_address ("glClientActiveTexture", closure);
} else {
backend->gl.active_texture = (glitz_gl_active_texture_t)
get_proc_address ("glActiveTextureARB", closure);
backend->gl.client_active_texture = (glitz_gl_client_active_texture_t)
get_proc_address ("glClientActiveTextureARB", closure);
}
if ((!backend->gl.active_texture) ||
(!backend->gl.client_active_texture)) {
backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK;
backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK;
}
}
if (backend->feature_mask & GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) {
backend->gl.multi_draw_arrays = (glitz_gl_multi_draw_arrays_t)
get_proc_address ("glMultiDrawArraysEXT", closure);
if (!backend->gl.multi_draw_arrays)
backend->feature_mask &= ~GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK;
}
if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) {
backend->gl.gen_programs = (glitz_gl_gen_programs_t)
get_proc_address ("glGenProgramsARB", closure);
backend->gl.delete_programs = (glitz_gl_delete_programs_t)
get_proc_address ("glDeleteProgramsARB", closure);
backend->gl.program_string = (glitz_gl_program_string_t)
get_proc_address ("glProgramStringARB", closure);
backend->gl.bind_program = (glitz_gl_bind_program_t)
get_proc_address ("glBindProgramARB", closure);
backend->gl.program_local_param_4fv = (glitz_gl_program_local_param_4fv_t)
get_proc_address ("glProgramLocalParameter4fvARB", closure);
backend->gl.get_program_iv = (glitz_gl_get_program_iv_t)
get_proc_address ("glGetProgramivARB", closure);
if ((!backend->gl.gen_programs) ||
(!backend->gl.delete_programs) ||
(!backend->gl.program_string) ||
(!backend->gl.bind_program) ||
(!backend->gl.program_local_param_4fv))
backend->feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK;
}
if ((backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) ||
(backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) {
if (backend->gl_version >= 1.5f) {
backend->gl.gen_buffers = (glitz_gl_gen_buffers_t)
get_proc_address ("glGenBuffers", closure);
backend->gl.delete_buffers = (glitz_gl_delete_buffers_t)
get_proc_address ("glDeleteBuffers", closure);
backend->gl.bind_buffer = (glitz_gl_bind_buffer_t)
get_proc_address ("glBindBuffer", closure);
backend->gl.buffer_data = (glitz_gl_buffer_data_t)
get_proc_address ("glBufferData", closure);
backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t)
get_proc_address ("glBufferSubData", closure);
backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t)
get_proc_address ("glGetBufferSubData", closure);
backend->gl.map_buffer = (glitz_gl_map_buffer_t)
get_proc_address ("glMapBuffer", closure);
backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t)
get_proc_address ("glUnmapBuffer", closure);
} else {
backend->gl.gen_buffers = (glitz_gl_gen_buffers_t)
get_proc_address ("glGenBuffersARB", closure);
backend->gl.delete_buffers = (glitz_gl_delete_buffers_t)
get_proc_address ("glDeleteBuffersARB", closure);
backend->gl.bind_buffer = (glitz_gl_bind_buffer_t)
get_proc_address ("glBindBufferARB", closure);
backend->gl.buffer_data = (glitz_gl_buffer_data_t)
get_proc_address ("glBufferDataARB", closure);
backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t)
get_proc_address ("glBufferSubDataARB", closure);
backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t)
get_proc_address ("glGetBufferSubDataARB", closure);
backend->gl.map_buffer = (glitz_gl_map_buffer_t)
get_proc_address ("glMapBufferARB", closure);
backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t)
get_proc_address ("glUnmapBufferARB", closure);
}
if ((!backend->gl.gen_buffers) ||
(!backend->gl.delete_buffers) ||
(!backend->gl.bind_buffer) ||
(!backend->gl.buffer_data) ||
(!backend->gl.buffer_sub_data) ||
(!backend->gl.get_buffer_sub_data) ||
(!backend->gl.map_buffer) ||
(!backend->gl.unmap_buffer)) {
backend->feature_mask &= ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK;
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
glitz_backend_init (glitz_backend_t *backend,
glitz_get_proc_address_proc_t get_proc_address,
void *closure)
{
if (!_glitz_query_gl_extensions (&backend->gl,
&backend->gl_version,
&backend->feature_mask)) {
_glitz_gl_proc_address_lookup (backend, get_proc_address, closure);
glitz_create_surface_formats (&backend->gl,
&backend->formats,
&backend->texture_formats,
&backend->n_formats);
}
backend->gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE,
&backend->max_texture_2d_size);
if (backend->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)
backend->gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE,
&backend->max_texture_rect_size);
else
backend->max_texture_rect_size = 0;
}
unsigned int
glitz_uint_to_power_of_two (unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return (x + 1);
}
void
glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl,
glitz_float_t x,
glitz_float_t y)
{
gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT);
gl->matrix_mode (GLITZ_GL_PROJECTION);
gl->push_matrix ();
gl->load_identity ();
gl->matrix_mode (GLITZ_GL_MODELVIEW);
gl->push_matrix ();
gl->load_identity ();
gl->depth_range (0, 1);
gl->viewport (-1, -1, 2, 2);
gl->raster_pos_2f (0, 0);
gl->bitmap (0, 0, 1, 1, x, y, NULL);
gl->pop_matrix ();
gl->matrix_mode (GLITZ_GL_PROJECTION);
gl->pop_matrix ();
gl->pop_attrib ();
}
void
glitz_clamp_value (glitz_float_t *value,
glitz_float_t min, glitz_float_t max)
{
if (*value < min)
*value = min;
else if (*value > max)
*value = max;
}
void
glitz_initiate_state (glitz_gl_proc_address_list_t *gl)
{
gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST);
gl->disable (GLITZ_GL_CULL_FACE);
gl->depth_mask (GLITZ_GL_FALSE);
gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL);
gl->disable (GLITZ_GL_POLYGON_SMOOTH);
gl->disable (GLITZ_GL_LINE_SMOOTH);
gl->disable (GLITZ_GL_POINT_SMOOTH);
gl->shade_model (GLITZ_GL_FLAT);
gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE);
gl->enable (GLITZ_GL_SCISSOR_TEST);
gl->disable (GLITZ_GL_STENCIL_TEST);
gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY);
gl->disable (GLITZ_GL_DEPTH_TEST);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,71 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# mozilla.org
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Vladimir Vukicevic <vladimir@pobox.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = glitzglx
LIBRARY_NAME = mozglitzglx
LIBXUL_LIBRARY = 1
REQUIRES = glitz
CSRCS = \
glitz_glx_drawable.c \
glitz_glx_format.c \
glitz_glx_info.c \
glitz_glx_extension.c \
glitz_glx_context.c \
glitz_glx_pbuffer.c \
$(NULL)
EXPORTS = glitz-glx.h
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/..
EXTRA_DSO_LIBS = mozglitz
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS += -L$(DIST)/bin $(EXTRA_DSO_LIBS)

Просмотреть файл

@ -0,0 +1,89 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_GLX_H_INCLUDED
#define GLITZ_GLX_H_INCLUDED
#include <glitz.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/* glitz_glx_info.c */
void
glitz_glx_init (const char *gl_library);
void
glitz_glx_fini (void);
/* glitz_glx_format.c */
glitz_drawable_format_t *
glitz_glx_find_drawable_format (Display *display,
int screen,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count);
glitz_drawable_format_t *
glitz_glx_find_drawable_format_for_visual (Display *display,
int screen,
VisualID visual_id);
XVisualInfo *
glitz_glx_get_visual_info_from_format (Display *display,
int screen,
glitz_drawable_format_t *format);
/* glitz_glx_drawable.c */
glitz_drawable_t *
glitz_glx_create_drawable_for_window (Display *display,
int screen,
glitz_drawable_format_t *format,
Window window,
unsigned int width,
unsigned int height);
glitz_drawable_t *
glitz_glx_create_pbuffer_drawable (Display *display,
int screen,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif /* GLITZ_GLX_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,436 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
#include <stdlib.h>
extern glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address;
static void
_glitz_glx_context_create (glitz_glx_screen_info_t *screen_info,
XID visualid,
GLXContext share_list,
glitz_glx_context_t *context)
{
int vis_info_count, i;
XVisualInfo *vis_infos;
vis_infos = XGetVisualInfo (screen_info->display_info->display,
0, NULL, &vis_info_count);
for (i = 0; i < vis_info_count; i++) {
if (vis_infos[i].visual->visualid == visualid)
break;
}
context->context = glXCreateContext (screen_info->display_info->display,
&vis_infos[i], share_list,
GLITZ_GL_TRUE);
context->id = visualid;
context->fbconfig = (GLXFBConfig) 0;
XFree (vis_infos);
}
static void
_glitz_glx_context_create_using_fbconfig (glitz_glx_screen_info_t *screen_info,
XID fbconfigid,
GLXContext share_list,
glitz_glx_context_t *context)
{
GLXFBConfig *fbconfigs;
int i, n_fbconfigs;
XVisualInfo *vinfo = NULL;
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
fbconfigs = glx->get_fbconfigs (screen_info->display_info->display,
screen_info->screen, &n_fbconfigs);
for (i = 0; i < n_fbconfigs; i++) {
int value;
glx->get_fbconfig_attrib (screen_info->display_info->display, fbconfigs[i],
GLX_FBCONFIG_ID, &value);
if (value == (int) fbconfigid)
break;
}
if (i < n_fbconfigs)
vinfo = glx->get_visual_from_fbconfig (screen_info->display_info->display,
fbconfigs[i]);
context->id = fbconfigid;
if (vinfo) {
context->context = glXCreateContext (screen_info->display_info->display,
vinfo, share_list, GLITZ_GL_TRUE);
XFree (vinfo);
} else if (glx->create_new_context)
context->context =
glx->create_new_context (screen_info->display_info->display,
fbconfigs[i], GLX_RGBA_TYPE, share_list,
GLITZ_GL_TRUE);
if (context->context)
context->fbconfig = fbconfigs[i];
else
context->fbconfig = (GLXFBConfig) 0;
if (fbconfigs)
XFree (fbconfigs);
}
static glitz_context_t *
_glitz_glx_create_context (void *abstract_drawable,
glitz_drawable_format_t *format)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
glitz_glx_screen_info_t *screen_info = drawable->screen_info;
int format_id = screen_info->format_ids[format->id];
glitz_glx_context_t *context;
context = malloc (sizeof (glitz_glx_context_t));
if (!context)
return NULL;
_glitz_context_init (&context->base, &drawable->base);
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
_glitz_glx_context_create_using_fbconfig (screen_info,
format_id,
screen_info->root_context,
context);
else
_glitz_glx_context_create (screen_info,
format_id,
screen_info->root_context,
context);
return (glitz_context_t *) context;
}
static void
_glitz_glx_context_destroy (void *abstract_context)
{
glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context;
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
context->base.drawable;
if (drawable->screen_info->display_info->thread_info->cctx == &context->base)
{
glXMakeCurrent (drawable->screen_info->display_info->display,
None, NULL);
drawable->screen_info->display_info->thread_info->cctx = NULL;
}
glXDestroyContext (drawable->screen_info->display_info->display,
context->context);
_glitz_context_fini (&context->base);
free (context);
}
static void
_glitz_glx_copy_context (void *abstract_src,
void *abstract_dst,
unsigned long mask)
{
glitz_glx_context_t *src = (glitz_glx_context_t *) abstract_src;
glitz_glx_context_t *dst = (glitz_glx_context_t *) abstract_dst;
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
src->base.drawable;
glXCopyContext (drawable->screen_info->display_info->display,
src->context, dst->context, mask);
}
static void
_glitz_glx_make_current (void *abstract_context,
void *abstract_drawable)
{
glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context;
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
glitz_glx_display_info_t *display_info = drawable->screen_info->display_info;
if ((glXGetCurrentContext () != context->context) ||
(glXGetCurrentDrawable () != drawable->drawable))
{
if (display_info->thread_info->cctx)
{
glitz_context_t *ctx = display_info->thread_info->cctx;
if (ctx->lose_current)
ctx->lose_current (ctx->closure);
}
glXMakeCurrent (display_info->display, drawable->drawable,
context->context);
}
display_info->thread_info->cctx = &context->base;
}
static glitz_function_pointer_t
_glitz_glx_context_get_proc_address (void *abstract_context,
const char *name)
{
glitz_glx_context_t *context = (glitz_glx_context_t *) abstract_context;
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *)
context->base.drawable;
_glitz_glx_make_current (context, drawable);
return glitz_glx_get_proc_address (name, drawable->screen_info);
}
glitz_glx_context_t *
glitz_glx_context_get (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format)
{
glitz_glx_context_t *context;
glitz_glx_context_t **contexts = screen_info->contexts;
int index, n_contexts = screen_info->n_contexts;
XID format_id;
for (; n_contexts; n_contexts--, contexts++)
if ((*contexts)->id == screen_info->format_ids[format->id])
return *contexts;
index = screen_info->n_contexts++;
screen_info->contexts =
realloc (screen_info->contexts,
sizeof (glitz_glx_context_t *) * screen_info->n_contexts);
if (!screen_info->contexts)
return NULL;
context = malloc (sizeof (glitz_glx_context_t));
if (!context)
return NULL;
screen_info->contexts[index] = context;
format_id = screen_info->format_ids[format->id];
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
_glitz_glx_context_create_using_fbconfig (screen_info,
format_id,
screen_info->root_context,
context);
else
_glitz_glx_context_create (screen_info,
format_id,
screen_info->root_context,
context);
if (!screen_info->root_context)
screen_info->root_context = context->context;
memcpy (&context->backend.gl,
&_glitz_glx_gl_proc_address,
sizeof (glitz_gl_proc_address_list_t));
context->backend.create_pbuffer = glitz_glx_create_pbuffer;
context->backend.destroy = glitz_glx_destroy;
context->backend.push_current = glitz_glx_push_current;
context->backend.pop_current = glitz_glx_pop_current;
context->backend.swap_buffers = glitz_glx_swap_buffers;
context->backend.create_context = _glitz_glx_create_context;
context->backend.destroy_context = _glitz_glx_context_destroy;
context->backend.copy_context = _glitz_glx_copy_context;
context->backend.make_current = _glitz_glx_make_current;
context->backend.get_proc_address = _glitz_glx_context_get_proc_address;
context->backend.drawable_formats = screen_info->formats;
context->backend.n_drawable_formats = screen_info->n_formats;
context->backend.texture_formats = NULL;
context->backend.formats = NULL;
context->backend.n_formats = 0;
context->backend.program_map = &screen_info->program_map;
context->backend.feature_mask = 0;
context->initialized = 0;
return context;
}
void
glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info,
glitz_glx_context_t *context)
{
if (context->backend.formats)
free (context->backend.formats);
if (context->backend.texture_formats)
free (context->backend.texture_formats);
glXDestroyContext (screen_info->display_info->display,
context->context);
free (context);
}
static void
_glitz_glx_context_initialize (glitz_glx_screen_info_t *screen_info,
glitz_glx_context_t *context)
{
const char *version;
glitz_backend_init (&context->backend,
glitz_glx_get_proc_address,
(void *) screen_info);
context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
context->max_viewport_dims);
glitz_initiate_state (&_glitz_glx_gl_proc_address);
version = (const char *) context->backend.gl.get_string (GLITZ_GL_VERSION);
if (version)
{
/* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures when
using nvidia's binary driver. Seems like a driver issue, but I'm not
sure yet. Turning of NPOT GL_TEXTURE_2D textures until this have been
solved. */
if (strstr (version, "NVIDIA 61.11") ||
strstr (version, "NVIDIA 66.29"))
{
context->backend.feature_mask &=
~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK;
}
}
context->initialized = 1;
}
static void
_glitz_glx_context_make_current (glitz_glx_drawable_t *drawable,
glitz_bool_t finish)
{
glitz_glx_display_info_t *display_info = drawable->screen_info->display_info;
if (finish)
glFinish ();
if (display_info->thread_info->cctx)
{
glitz_context_t *ctx = display_info->thread_info->cctx;
if (ctx->lose_current)
ctx->lose_current (ctx->closure);
display_info->thread_info->cctx = NULL;
}
glXMakeCurrent (display_info->display,
drawable->drawable,
drawable->context->context);
drawable->base.update_all = 1;
if (!drawable->context->initialized)
_glitz_glx_context_initialize (drawable->screen_info, drawable->context);
}
static void
_glitz_glx_context_update (glitz_glx_drawable_t *drawable,
glitz_constraint_t constraint)
{
glitz_glx_display_info_t *dinfo = drawable->screen_info->display_info;
GLXContext context = NULL;
switch (constraint) {
case GLITZ_NONE:
break;
case GLITZ_ANY_CONTEXT_CURRENT:
if (!dinfo->thread_info->cctx)
context = glXGetCurrentContext ();
if (context == (GLXContext) 0)
_glitz_glx_context_make_current (drawable, 0);
break;
case GLITZ_CONTEXT_CURRENT:
if (!dinfo->thread_info->cctx)
context = glXGetCurrentContext ();
if (context != drawable->context->context)
_glitz_glx_context_make_current (drawable, (context)? 1: 0);
break;
case GLITZ_DRAWABLE_CURRENT:
if (!dinfo->thread_info->cctx)
context = glXGetCurrentContext ();
if ((context != drawable->context->context) ||
(glXGetCurrentDrawable () != drawable->drawable))
_glitz_glx_context_make_current (drawable, (context)? 1: 0);
break;
}
}
void
glitz_glx_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
glitz_glx_context_info_t *context_info;
int index;
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
context_info->drawable = drawable;
context_info->surface = surface;
context_info->constraint = constraint;
_glitz_glx_context_update (context_info->drawable, constraint);
}
glitz_surface_t *
glitz_glx_pop_current (void *abstract_drawable)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
glitz_glx_context_info_t *context_info = NULL;
int index;
drawable->screen_info->context_stack_size--;
index = drawable->screen_info->context_stack_size - 1;
context_info = &drawable->screen_info->context_stack[index];
if (context_info->drawable)
_glitz_glx_context_update (context_info->drawable,
context_info->constraint);
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
return context_info->surface;
return NULL;
}

Просмотреть файл

@ -0,0 +1,202 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
static glitz_glx_drawable_t *
_glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info,
glitz_glx_context_t *context,
glitz_drawable_format_t *format,
GLXDrawable glx_drawable,
GLXPbuffer glx_pbuffer,
int width,
int height)
{
glitz_glx_drawable_t *drawable;
if (width <= 0 || height <= 0)
return NULL;
drawable = (glitz_glx_drawable_t *) malloc (sizeof (glitz_glx_drawable_t));
if (drawable == NULL)
return NULL;
drawable->base.ref_count = 1;
drawable->screen_info = screen_info;
drawable->context = context;
drawable->drawable = glx_drawable;
drawable->pbuffer = glx_pbuffer;
drawable->base.format = format;
drawable->base.backend = &context->backend;
glitz_drawable_update_size (&drawable->base, width, height);
if (!context->initialized) {
glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_glx_pop_current (drawable);
}
if (width > context->max_viewport_dims[0] ||
height > context->max_viewport_dims[1]) {
free (drawable);
return NULL;
}
screen_info->drawables++;
return drawable;
}
static glitz_drawable_t *
_glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_glx_drawable_t *drawable;
glitz_glx_context_t *context;
GLXPbuffer pbuffer;
if (!format->types.pbuffer)
return NULL;
context = glitz_glx_context_get (screen_info, format);
if (!context)
return NULL;
pbuffer = glitz_glx_pbuffer_create (screen_info, context->fbconfig,
(int) width, (int) height);
if (!pbuffer)
return NULL;
drawable = _glitz_glx_create_drawable (screen_info, context, format,
pbuffer, pbuffer,
width, height);
if (!drawable) {
glitz_glx_pbuffer_destroy (screen_info, pbuffer);
return NULL;
}
return &drawable->base;
}
glitz_drawable_t *
glitz_glx_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_glx_drawable_t *templ = (glitz_glx_drawable_t *) abstract_templ;
return _glitz_glx_create_pbuffer_drawable (templ->screen_info, format,
width, height);
}
glitz_drawable_t *
glitz_glx_create_drawable_for_window (Display *display,
int screen,
glitz_drawable_format_t *format,
Window window,
unsigned int width,
unsigned int height)
{
glitz_glx_drawable_t *drawable;
glitz_glx_screen_info_t *screen_info;
glitz_glx_context_t *context;
screen_info = glitz_glx_screen_info_get (display, screen);
if (!screen_info)
return NULL;
context = glitz_glx_context_get (screen_info, format);
if (!context)
return NULL;
drawable = _glitz_glx_create_drawable (screen_info, context, format,
window, (GLXPbuffer) 0,
width, height);
if (!drawable)
return NULL;
return &drawable->base;
}
slim_hidden_def(glitz_glx_create_drawable_for_window);
glitz_drawable_t *
glitz_glx_create_pbuffer_drawable (Display *display,
int screen,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_glx_screen_info_t *screen_info;
screen_info = glitz_glx_screen_info_get (display, screen);
if (!screen_info)
return NULL;
return _glitz_glx_create_pbuffer_drawable (screen_info, format,
width, height);
}
slim_hidden_def(glitz_glx_create_pbuffer_drawable);
void
glitz_glx_destroy (void *abstract_drawable)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
drawable->screen_info->drawables--;
if (drawable->screen_info->drawables == 0) {
/*
* Last drawable? We have to destroy all fragment programs as this may
* be our last chance to have a context current.
*/
glitz_glx_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_program_map_fini (&drawable->base.backend->gl,
&drawable->screen_info->program_map);
glitz_glx_pop_current (abstract_drawable);
}
if (glXGetCurrentDrawable () == drawable->drawable)
glXMakeCurrent (drawable->screen_info->display_info->display, None, NULL);
if (drawable->pbuffer)
glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer);
free (drawable);
}
void
glitz_glx_swap_buffers (void *abstract_drawable)
{
glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable;
glXSwapBuffers (drawable->screen_info->display_info->display,
drawable->drawable);
}

Просмотреть файл

@ -0,0 +1,70 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
static glitz_extension_map glx_extensions[] = {
{ 0.0, "GLX_SGIX_fbconfig", GLITZ_GLX_FEATURE_FBCONFIG_MASK },
{ 0.0, "GLX_SGIX_pbuffer", GLITZ_GLX_FEATURE_PBUFFER_MASK },
{ 0.0, "GLX_SGI_make_current_read",
GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK },
{ 0.0, "GLX_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK },
{ 0.0, NULL, 0 }
};
void
glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info,
glitz_gl_float_t glx_version)
{
const char *glx_extensions_string;
glx_extensions_string =
glXQueryExtensionsString (screen_info->display_info->display,
screen_info->screen);
screen_info->glx_feature_mask =
glitz_extensions_query (glx_version,
glx_extensions_string,
glx_extensions);
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) {
const char *vendor;
vendor = glXGetClientString (screen_info->display_info->display,
GLX_VENDOR);
if (vendor) {
/* NVIDIA's driver seem to support multisample with pbuffers */
if (!strncmp ("NVIDIA", vendor, 6))
screen_info->glx_feature_mask |=
GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK;
}
}
}

Просмотреть файл

@ -0,0 +1,423 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
#include <stdlib.h>
#include <string.h>
static int
_glitz_glx_format_compare (const void *elem1,
const void *elem2)
{
int i, score[2];
glitz_drawable_format_t *format[2];
format[0] = (glitz_drawable_format_t *) elem1;
format[1] = (glitz_drawable_format_t *) elem2;
i = score[0] = score[1] = 0;
for (; i < 2; i++) {
if (format[i]->color.red_size) {
if (format[i]->color.red_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.green_size) {
if (format[i]->color.green_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.alpha_size) {
if (format[i]->color.alpha_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->stencil_size)
score[i] += 5;
if (format[i]->depth_size)
score[i] += 5;
if (format[i]->doublebuffer)
score[i] += 10;
if (format[i]->types.window)
score[i] += 10;
if (format[i]->types.pbuffer)
score[i] += 10;
if (format[i]->samples > 1)
score[i] -= (20 - format[i]->samples);
}
return score[1] - score[0];
}
static void
_glitz_add_format (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format,
XID id)
{
int n = screen_info->n_formats;
screen_info->formats =
realloc (screen_info->formats,
sizeof (glitz_drawable_format_t) * (n + 1));
screen_info->format_ids =
realloc (screen_info->format_ids, sizeof (XID) * (n + 1));
if (screen_info->formats && screen_info->format_ids) {
screen_info->formats[n] = *format;
screen_info->formats[n].id = n;
screen_info->format_ids[n] = id;
screen_info->n_formats++;
}
}
static void
_glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
{
Display *display;
glitz_drawable_format_t format;
XVisualInfo visual_templ;
XVisualInfo *visuals;
int i, num_visuals;
display = screen_info->display_info->display;
visual_templ.screen = screen_info->screen;
visuals = XGetVisualInfo (display, VisualScreenMask,
&visual_templ, &num_visuals);
/* No pbuffers without fbconfigs */
format.types.window = 1;
format.types.pbuffer = 0;
format.id = 0;
for (i = 0; i < num_visuals; i++) {
int value;
if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) ||
(value == 0))
continue;
glXGetConfig (display, &visuals[i], GLX_RGBA, &value);
if (value == 0)
continue;
/* Stereo is not supported yet */
glXGetConfig (display, &visuals[i], GLX_STEREO, &value);
if (value != 0)
continue;
glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value);
format.color.red_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value);
format.color.green_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value);
format.color.blue_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value);
format.color.alpha_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value);
format.depth_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value);
format.stencil_size = (unsigned short) value;
glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value);
format.doublebuffer = (value) ? 1: 0;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) {
glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &value);
if (value) {
glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value);
format.samples = (unsigned short) (value > 1)? value: 1;
} else
format.samples = 1;
} else
format.samples = 1;
_glitz_add_format (screen_info, &format, visuals[i].visualid);
}
if (visuals)
XFree (visuals);
}
static glitz_status_t
_glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info)
{
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
Display *display;
glitz_drawable_format_t format;
GLXFBConfig *fbconfigs;
int i, num_configs;
XID id;
display = screen_info->display_info->display;
fbconfigs = glx->get_fbconfigs (display, screen_info->screen, &num_configs);
if (!fbconfigs) {
/* fbconfigs are not supported, falling back to visuals */
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK;
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
return GLITZ_STATUS_NOT_SUPPORTED;
}
for (i = 0; i < num_configs; i++) {
int value;
if ((glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_RENDER_TYPE, &value) != 0) ||
(!(value & GLX_RGBA_BIT)))
continue;
/* Stereo is not supported yet */
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value);
if (value != 0)
continue;
glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_DRAWABLE_TYPE, &value);
if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT)))
continue;
format.types.window = (value & GLX_WINDOW_BIT)? 1: 0;
format.types.pbuffer = (value & GLX_PBUFFER_BIT)? 1: 0;
format.id = 0;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID, &value);
id = (XID) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value);
format.color.red_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE, &value);
format.color.green_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE, &value);
format.color.blue_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE, &value);
format.color.alpha_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE, &value);
format.depth_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE, &value);
format.stencil_size = (unsigned short) value;
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER, &value);
format.doublebuffer = (value)? 1: 0;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) {
glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_SAMPLE_BUFFERS_ARB, &value);
if (value) {
glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_SAMPLES_ARB, &value);
format.samples = (unsigned short) (value > 1)? value: 1;
if (format.samples > 1) {
if (!(screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK))
format.types.pbuffer = 0;
}
} else
format.samples = 1;
} else
format.samples = 1;
_glitz_add_format (screen_info, &format, id);
}
if (fbconfigs)
XFree (fbconfigs);
return GLITZ_STATUS_SUCCESS;
}
void
glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
{
glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED;
XID *new_ids;
int i;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
status = _glitz_glx_query_formats_using_fbconfigs (screen_info);
if (status)
_glitz_glx_query_formats (screen_info);
if (!screen_info->n_formats)
return;
qsort (screen_info->formats, screen_info->n_formats,
sizeof (glitz_drawable_format_t), _glitz_glx_format_compare);
/*
* Update XID list so that it matches the sorted format list.
*/
new_ids = malloc (sizeof (XID) * screen_info->n_formats);
if (!new_ids) {
screen_info->n_formats = 0;
return;
}
for (i = 0; i < screen_info->n_formats; i++) {
new_ids[i] = screen_info->format_ids[screen_info->formats[i].id];
screen_info->formats[i].id = i;
}
free (screen_info->format_ids);
screen_info->format_ids = new_ids;
}
glitz_drawable_format_t *
glitz_glx_find_drawable_format (Display *display,
int screen,
unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
glitz_glx_screen_info_t *screen_info =
glitz_glx_screen_info_get (display, screen);
return glitz_drawable_format_find (screen_info->formats,
screen_info->n_formats,
mask, templ, count);
}
slim_hidden_def(glitz_glx_find_drawable_format);
glitz_drawable_format_t *
glitz_glx_find_drawable_format_for_visual (Display *display,
int screen,
VisualID visual_id)
{
glitz_drawable_format_t *format = NULL;
glitz_glx_screen_info_t *screen_info;
int i;
screen_info = glitz_glx_screen_info_get (display, screen);
if (!screen_info)
return NULL;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
{
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
GLXFBConfig *fbconfigs;
int fid, n_fbconfigs;
fid = -1;
fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs);
for (i = 0; i < n_fbconfigs; i++)
{
XVisualInfo *visinfo;
visinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]);
if (visinfo && visinfo->visualid == visual_id)
{
int value;
glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_FBCONFIG_ID, &value);
for (fid = 0; fid < screen_info->n_formats; fid++)
{
if (screen_info->format_ids[fid] == value)
{
format = screen_info->formats + fid;
break;
}
}
if (format)
break;
}
}
if (fbconfigs)
XFree (fbconfigs);
}
else
{
for (i = 0; i < screen_info->n_formats; i++)
{
if (visual_id == screen_info->format_ids[i])
{
format = screen_info->formats + i;
break;
}
}
}
return format;
}
slim_hidden_def(glitz_glx_find_drawable_format_for_visual);
XVisualInfo *
glitz_glx_get_visual_info_from_format (Display *display,
int screen,
glitz_drawable_format_t *format)
{
XVisualInfo *vinfo = NULL;
glitz_glx_screen_info_t *screen_info =
glitz_glx_screen_info_get (display, screen);
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) {
GLXFBConfig *fbconfigs;
int i, n_fbconfigs;
int fbconfigid = screen_info->format_ids[format->id];
fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs);
for (i = 0; i < n_fbconfigs; i++) {
int value;
glx->get_fbconfig_attrib (display, fbconfigs[i],
GLX_FBCONFIG_ID, &value);
if (value == fbconfigid)
break;
}
if (i < n_fbconfigs)
vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]);
if (fbconfigs)
XFree (fbconfigs);
} else {
XVisualInfo templ;
int n_items;
templ.visualid = screen_info->format_ids[format->id];
vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items);
}
return vinfo;
}
slim_hidden_def(glitz_glx_get_visual_info_from_format);

Просмотреть файл

@ -0,0 +1,544 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
#include <string.h>
#include <dlfcn.h>
glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = {
/* core */
(glitz_gl_enable_t) glEnable,
(glitz_gl_disable_t) glDisable,
(glitz_gl_get_error_t) glGetError,
(glitz_gl_get_string_t) glGetString,
(glitz_gl_enable_client_state_t) glEnableClientState,
(glitz_gl_disable_client_state_t) glDisableClientState,
(glitz_gl_vertex_pointer_t) glVertexPointer,
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
(glitz_gl_draw_arrays_t) glDrawArrays,
(glitz_gl_tex_env_f_t) glTexEnvf,
(glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_gen_i_t) glTexGeni,
(glitz_gl_tex_gen_fv_t) glTexGenfv,
(glitz_gl_color_4us_t) glColor4us,
(glitz_gl_color_4f_t) glColor4f,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
(glitz_gl_clear_color_t) glClearColor,
(glitz_gl_clear_stencil_t) glClearStencil,
(glitz_gl_stencil_func_t) glStencilFunc,
(glitz_gl_stencil_op_t) glStencilOp,
(glitz_gl_push_attrib_t) glPushAttrib,
(glitz_gl_pop_attrib_t) glPopAttrib,
(glitz_gl_matrix_mode_t) glMatrixMode,
(glitz_gl_push_matrix_t) glPushMatrix,
(glitz_gl_pop_matrix_t) glPopMatrix,
(glitz_gl_load_identity_t) glLoadIdentity,
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
(glitz_gl_depth_range_t) glDepthRange,
(glitz_gl_viewport_t) glViewport,
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
(glitz_gl_bitmap_t) glBitmap,
(glitz_gl_read_buffer_t) glReadBuffer,
(glitz_gl_draw_buffer_t) glDrawBuffer,
(glitz_gl_copy_pixels_t) glCopyPixels,
(glitz_gl_flush_t) glFlush,
(glitz_gl_finish_t) glFinish,
(glitz_gl_pixel_store_i_t) glPixelStorei,
(glitz_gl_ortho_t) glOrtho,
(glitz_gl_scale_f_t) glScalef,
(glitz_gl_translate_f_t) glTranslatef,
(glitz_gl_hint_t) glHint,
(glitz_gl_depth_mask_t) glDepthMask,
(glitz_gl_polygon_mode_t) glPolygonMode,
(glitz_gl_shade_model_t) glShadeModel,
(glitz_gl_color_mask_t) glColorMask,
(glitz_gl_read_pixels_t) glReadPixels,
(glitz_gl_get_tex_image_t) glGetTexImage,
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
(glitz_gl_gen_textures_t) glGenTextures,
(glitz_gl_delete_textures_t) glDeleteTextures,
(glitz_gl_bind_texture_t) glBindTexture,
(glitz_gl_tex_image_2d_t) glTexImage2D,
(glitz_gl_tex_parameter_i_t) glTexParameteri,
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
(glitz_gl_get_integer_v_t) glGetIntegerv,
/* extensions */
(glitz_gl_blend_color_t) 0,
(glitz_gl_active_texture_t) 0,
(glitz_gl_client_active_texture_t) 0,
(glitz_gl_multi_draw_arrays_t) 0,
(glitz_gl_gen_programs_t) 0,
(glitz_gl_delete_programs_t) 0,
(glitz_gl_program_string_t) 0,
(glitz_gl_bind_program_t) 0,
(glitz_gl_program_local_param_4fv_t) 0,
(glitz_gl_get_program_iv_t) 0,
(glitz_gl_gen_buffers_t) 0,
(glitz_gl_delete_buffers_t) 0,
(glitz_gl_bind_buffer_t) 0,
(glitz_gl_buffer_data_t) 0,
(glitz_gl_buffer_sub_data_t) 0,
(glitz_gl_get_buffer_sub_data_t) 0,
(glitz_gl_map_buffer_t) 0,
(glitz_gl_unmap_buffer_t) 0
};
glitz_function_pointer_t
glitz_glx_get_proc_address (const char *name,
void *closure)
{
glitz_glx_screen_info_t *screen_info = (glitz_glx_screen_info_t *) closure;
glitz_glx_thread_info_t *info = screen_info->display_info->thread_info;
glitz_function_pointer_t address = NULL;
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK)
address = screen_info->glx.get_proc_address ((glitz_gl_ubyte_t *) name);
if (!address) {
if (!info->dlhand)
info->dlhand = dlopen (info->gl_library, RTLD_LAZY);
if (info->dlhand) {
dlerror ();
address = (glitz_function_pointer_t) dlsym (info->dlhand, name);
if (dlerror () != NULL)
address = NULL;
}
}
return address;
}
static void
_glitz_glx_proc_address_lookup (glitz_glx_screen_info_t *screen_info)
{
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) {
if (screen_info->glx_version >= 1.3f) {
screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t)
glitz_glx_get_proc_address ("glXGetFBConfigs", (void *) screen_info);
screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t)
glitz_glx_get_proc_address ("glXGetFBConfigAttrib",
(void *) screen_info);
screen_info->glx.get_visual_from_fbconfig =
(glitz_glx_get_visual_from_fbconfig_t)
glitz_glx_get_proc_address ("glXGetVisualFromFBConfig",
(void *) screen_info);
screen_info->glx.create_new_context = (glitz_glx_create_new_context_t)
glitz_glx_get_proc_address ("glXCreateNewContext",
(void *) screen_info);
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) {
screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t)
glitz_glx_get_proc_address ("glXCreatePbuffer",
(void *) screen_info);
screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t)
glitz_glx_get_proc_address ("glXDestroyPbuffer",
(void *) screen_info);
screen_info->glx.query_drawable = (glitz_glx_query_drawable_t)
glitz_glx_get_proc_address ("glXQueryDrawable",
(void *) screen_info);
}
} else {
screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t)
glitz_glx_get_proc_address ("glXGetFBConfigsSGIX",
(void *) screen_info);
screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t)
glitz_glx_get_proc_address ("glXGetFBConfigAttribSGIX",
(void *) screen_info);
screen_info->glx.get_visual_from_fbconfig =
(glitz_glx_get_visual_from_fbconfig_t)
glitz_glx_get_proc_address ("glXGetVisualFromFBConfigSGIX",
(void *) screen_info);
screen_info->glx.create_new_context = (glitz_glx_create_new_context_t)
glitz_glx_get_proc_address ("glXCreateContextWithConfigSGIX",
(void *) screen_info);
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) {
screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t)
glitz_glx_get_proc_address ("glXCreateGLXPbufferSGIX",
(void *) screen_info);
screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t)
glitz_glx_get_proc_address ("glXDestroyGLXPbufferSGIX",
(void *) screen_info);
screen_info->glx.query_drawable = (glitz_glx_query_drawable_t)
glitz_glx_get_proc_address ("glXQueryGLXPbufferSGIX",
(void *) screen_info);
}
}
if ((!screen_info->glx.create_pbuffer) ||
(!screen_info->glx.destroy_pbuffer) ||
(!screen_info->glx.query_drawable))
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
if ((!screen_info->glx.get_fbconfigs) ||
(!screen_info->glx.get_fbconfig_attrib) ||
(!screen_info->glx.get_visual_from_fbconfig) ||
(!screen_info->glx.create_new_context)) {
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK;
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
}
} else
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
if (screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK) {
if (screen_info->glx_version >= 1.3f) {
screen_info->glx.make_context_current =
(glitz_glx_make_context_current_t)
glitz_glx_get_proc_address ("glXMakeContextCurrent",
(void *) screen_info);
} else {
screen_info->glx.make_context_current =
(glitz_glx_make_context_current_t)
glitz_glx_get_proc_address ("glXMakeCurrentReadSGI",
(void *) screen_info);
}
if (!screen_info->glx.make_context_current)
screen_info->glx_feature_mask &=
~GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK;
}
if (screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) {
if (screen_info->glx_version >= 1.4f) {
screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t)
glitz_glx_get_proc_address ("glXGetProcAddress", (void *) screen_info);
} else {
screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t)
glitz_glx_get_proc_address ("glXGetProcAddressARB",
(void *) screen_info);
}
if (!screen_info->glx.get_proc_address)
screen_info->glx_feature_mask &=
~GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK;
}
}
static void
_glitz_glx_display_destroy (glitz_glx_display_info_t *display_info);
static void
_glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info);
static void
_glitz_glx_thread_info_fini (glitz_glx_thread_info_t *thread_info)
{
int i;
for (i = 0; i < thread_info->n_displays; i++)
_glitz_glx_display_destroy (thread_info->displays[i]);
free (thread_info->displays);
thread_info->displays = NULL;
thread_info->n_displays = 0;
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
if (thread_info->dlhand) {
dlclose (thread_info->dlhand);
thread_info->dlhand = NULL;
}
thread_info->cctx = NULL;
}
#ifdef XTHREADS
#include <X11/Xthreads.h>
#include <stdlib.h>
/* thread safe */
static int tsd_initialized = 0;
static xthread_key_t info_tsd;
static void
_glitz_glx_thread_info_init (glitz_glx_thread_info_t *thread_info)
{
thread_info->displays = NULL;
thread_info->n_displays = 0;
thread_info->gl_library = NULL;
thread_info->dlhand = NULL;
thread_info->cctx = NULL;
}
static void
_glitz_glx_thread_info_destroy (glitz_glx_thread_info_t *thread_info)
{
xthread_set_specific (info_tsd, NULL);
if (thread_info) {
_glitz_glx_thread_info_fini (thread_info);
free (thread_info);
}
}
static void
_tsd_destroy (void *p)
{
if (p) {
_glitz_glx_thread_info_fini ((glitz_glx_thread_info_t *) p);
free (p);
}
}
static glitz_glx_thread_info_t *
_glitz_glx_thread_info_get (const char *gl_library)
{
glitz_glx_thread_info_t *thread_info;
void *p;
if (!tsd_initialized) {
xthread_key_create (&info_tsd, _tsd_destroy);
tsd_initialized = 1;
}
xthread_get_specific (info_tsd, &p);
if (p == NULL) {
thread_info = malloc (sizeof (glitz_glx_thread_info_t));
_glitz_glx_thread_info_init (thread_info);
xthread_set_specific (info_tsd, thread_info);
} else
thread_info = (glitz_glx_thread_info_t *) p;
if (gl_library) {
int len = strlen (gl_library);
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
thread_info->gl_library = malloc (len + 1);
if (thread_info->gl_library) {
memcpy (thread_info->gl_library, gl_library, len);
thread_info->gl_library[len] = '\0';
}
}
return thread_info;
}
#else
/* not thread safe */
static glitz_glx_thread_info_t thread_info = {
NULL,
0,
NULL,
NULL
};
static void
_glitz_glx_thread_info_destroy (glitz_glx_thread_info_t *thread_info)
{
if (thread_info)
_glitz_glx_thread_info_fini (thread_info);
}
static glitz_glx_thread_info_t *
_glitz_glx_thread_info_get (const char *gl_library)
{
if (gl_library) {
int len = strlen (gl_library);
if (thread_info.gl_library) {
free (thread_info.gl_library);
thread_info.gl_library = NULL;
}
thread_info.gl_library = malloc (len + 1);
if (thread_info.gl_library) {
memcpy (thread_info.gl_library, gl_library, len);
thread_info.gl_library[len] = '\0';
}
}
return &thread_info;
}
#endif
static glitz_glx_display_info_t *
_glitz_glx_display_info_get (Display *display)
{
glitz_glx_display_info_t *display_info;
glitz_glx_thread_info_t *thread_info = _glitz_glx_thread_info_get (NULL);
glitz_glx_display_info_t **displays = thread_info->displays;
int index, n_displays = thread_info->n_displays;
for (; n_displays; n_displays--, displays++)
if ((*displays)->display == display)
return *displays;
index = thread_info->n_displays++;
thread_info->displays =
realloc (thread_info->displays,
sizeof (glitz_glx_display_info_t *) * thread_info->n_displays);
display_info = malloc (sizeof (glitz_glx_display_info_t));
thread_info->displays[index] = display_info;
display_info->thread_info = thread_info;
display_info->display = display;
display_info->screens = NULL;
display_info->n_screens = 0;
return display_info;
}
static void
_glitz_glx_display_destroy (glitz_glx_display_info_t *display_info)
{
int i;
for (i = 0; i < display_info->n_screens; i++)
_glitz_glx_screen_destroy (display_info->screens[i]);
if (display_info->screens)
free (display_info->screens);
free (display_info);
}
glitz_glx_screen_info_t *
glitz_glx_screen_info_get (Display *display,
int screen)
{
glitz_glx_screen_info_t *screen_info;
glitz_glx_display_info_t *display_info =
_glitz_glx_display_info_get (display);
glitz_glx_screen_info_t **screens = display_info->screens;
int error_base, event_base, index, n_screens = display_info->n_screens;
for (; n_screens; n_screens--, screens++)
if ((*screens)->screen == screen)
return *screens;
index = display_info->n_screens++;
display_info->screens =
realloc (display_info->screens,
sizeof (glitz_glx_screen_info_t *) * display_info->n_screens);
screen_info = malloc (sizeof (glitz_glx_screen_info_t));
display_info->screens[index] = screen_info;
screen_info->display_info = display_info;
screen_info->screen = screen;
screen_info->drawables = 0;
screen_info->formats = NULL;
screen_info->format_ids = NULL;
screen_info->n_formats = 0;
screen_info->contexts = NULL;
screen_info->n_contexts = 0;
memset (&screen_info->glx, 0, sizeof (glitz_glx_static_proc_address_list_t));
glitz_program_map_init (&screen_info->program_map);
screen_info->root_context = (GLXContext) 0;
screen_info->glx_feature_mask = 0;
if (glXQueryExtension (display, &error_base, &event_base)) {
int major, minor;
if (glXQueryVersion (display, &major, &minor)) {
screen_info->glx_version = major + minor / 10.0f;
if (major > 1 || (major > 0 || minor >= 2)) {
glitz_glx_query_extensions (screen_info, screen_info->glx_version);
_glitz_glx_proc_address_lookup (screen_info);
glitz_glx_query_formats (screen_info);
}
}
}
screen_info->context_stack_size = 1;
screen_info->context_stack->drawable = NULL;
screen_info->context_stack->surface = NULL;
screen_info->context_stack->constraint = GLITZ_NONE;
return screen_info;
}
static void
_glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info)
{
Display *display = screen_info->display_info->display;
int i;
if (screen_info->root_context)
glXMakeCurrent (display, None, NULL);
for (i = 0; i < screen_info->n_contexts; i++)
glitz_glx_context_destroy (screen_info, screen_info->contexts[i]);
if (screen_info->contexts)
free (screen_info->contexts);
if (screen_info->formats)
free (screen_info->formats);
if (screen_info->format_ids)
free (screen_info->format_ids);
free (screen_info);
}
void
glitz_glx_init (const char *gl_library)
{
_glitz_glx_thread_info_get (gl_library);
}
slim_hidden_def(glitz_glx_init);
void
glitz_glx_fini (void)
{
glitz_glx_thread_info_t *info = _glitz_glx_thread_info_get (NULL);
_glitz_glx_thread_info_destroy (info);
}
slim_hidden_def(glitz_glx_fini);

Просмотреть файл

@ -0,0 +1,67 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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 "glitz_glxint.h"
GLXPbuffer
glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info,
GLXFBConfig fbconfig,
int width,
int height)
{
if (fbconfig) {
int attributes[9];
attributes[0] = GLX_PBUFFER_WIDTH;
attributes[1] = width;
attributes[2] = GLX_PBUFFER_HEIGHT;
attributes[3] = height;
attributes[4] = GLX_LARGEST_PBUFFER;
attributes[5] = 0;
attributes[6] = GLX_PRESERVED_CONTENTS;
attributes[7] = 1;
attributes[8] = 0;
return
screen_info->glx.create_pbuffer (screen_info->display_info->display,
fbconfig, attributes);
} else
return (GLXPbuffer) 0;
}
void
glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info,
GLXPbuffer pbuffer)
{
screen_info->glx.destroy_pbuffer (screen_info->display_info->display,
pbuffer);
}

Просмотреть файл

@ -0,0 +1,128 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Authors: David Reveman <davidr@novell.com>
* Peter Nilsson <c99pnn@cs.umu.se>
*/
#ifndef GLITZ_GLXEXT_H_INCLUDED
#define GLITZ_GLXEXT_H_INCLUDED
#ifndef GLX_VERSION_1_3
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_RGBA_BIT 0x00000001
#define GLX_COLOR_INDEX_BIT 0x00000002
#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
#define GLX_AUX_BUFFERS_BIT 0x00000010
#define GLX_DEPTH_BUFFER_BIT 0x00000020
#define GLX_STENCIL_BUFFER_BIT 0x00000040
#define GLX_ACCUM_BUFFER_BIT 0x00000080
#define GLX_CONFIG_CAVEAT 0x20
#define GLX_X_VISUAL_TYPE 0x22
#define GLX_TRANSPARENT_TYPE 0x23
#define GLX_TRANSPARENT_INDEX_VALUE 0x24
#define GLX_TRANSPARENT_RED_VALUE 0x25
#define GLX_TRANSPARENT_GREEN_VALUE 0x26
#define GLX_TRANSPARENT_BLUE_VALUE 0x27
#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
#define GLX_DONT_CARE 0xFFFFFFFF
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_PSEUDO_COLOR 0x8004
#define GLX_STATIC_COLOR 0x8005
#define GLX_GRAY_SCALE 0x8006
#define GLX_STATIC_GRAY 0x8007
#define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009
#define GLX_VISUAL_ID 0x800B
#define GLX_SCREEN 0x800C
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_X_RENDERABLE 0x8012
#define GLX_FBCONFIG_ID 0x8013
#define GLX_RGBA_TYPE 0x8014
#define GLX_COLOR_INDEX_TYPE 0x8015
#define GLX_MAX_PBUFFER_WIDTH 0x8016
#define GLX_MAX_PBUFFER_HEIGHT 0x8017
#define GLX_MAX_PBUFFER_PIXELS 0x8018
#define GLX_PRESERVED_CONTENTS 0x801B
#define GLX_LARGEST_PBUFFER 0x801C
#define GLX_WIDTH 0x801D
#define GLX_HEIGHT 0x801E
#define GLX_EVENT_MASK 0x801F
#define GLX_DAMAGED 0x8020
#define GLX_SAVED 0x8021
#define GLX_WINDOW 0x8022
#define GLX_PBUFFER 0x8023
#define GLX_PBUFFER_HEIGHT 0x8040
#define GLX_PBUFFER_WIDTH 0x8041
typedef struct __GLXFBConfigRec *GLXFBConfig;
typedef XID GLXFBConfigID;
typedef XID GLXContextID;
typedef XID GLXWindow;
typedef XID GLXPbuffer;
#endif
typedef glitz_function_pointer_t (* glitz_glx_get_proc_address_t)
(const glitz_gl_ubyte_t *);
typedef GLXFBConfig *(* glitz_glx_get_fbconfigs_t)
(Display *display, int screen, int *n_elements);
typedef int (* glitz_glx_get_fbconfig_attrib_t)
(Display *display, GLXFBConfig config, int attribute, int *value);
typedef XVisualInfo *(* glitz_glx_get_visual_from_fbconfig_t)
(Display *display, GLXFBConfig config);
typedef GLXPbuffer (* glitz_glx_create_pbuffer_t)
(Display *display, GLXFBConfig config, const int *attrib_list);
typedef void (* glitz_glx_destroy_pbuffer_t)
(Display *display, GLXPbuffer pbuffer);
typedef void (* glitz_glx_query_drawable_t)
(Display *display, GLXDrawable drawable,
int attribute, unsigned int *value);
typedef Bool (* glitz_glx_make_context_current_t)
(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef GLXContext (* glitz_glx_create_new_context_t)
(Display *display, GLXFBConfig config, int render_type,
GLXContext share_list, Bool direct);
#ifndef GLX_ARB_multisample
#define GLX_SAMPLE_BUFFERS_ARB 0x186a0
#define GLX_SAMPLES_ARB 0x186a1
#endif
typedef Bool *(* glitz_glx_bind_tex_image_t)
(Display *display, GLXPbuffer pbuffer, int buffer);
typedef Bool (* glitz_glx_release_tex_image_t)
(Display *display, GLXPbuffer pbuffer, int buffer);
#endif /* GLITZ_GLXEXT_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,192 @@
/*
* Copyright © 2004 David Reveman
*
* 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
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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>
*/
#ifndef GLITZ_GLXINT_H_INCLUDED
#define GLITZ_GLXINT_H_INCLUDED
#include "glitz.h"
#include "glitzint.h"
#include "glitz-glx.h"
#include <GL/gl.h>
#include <GL/glx.h>
#include "glitz_glxext.h"
#define GLITZ_GLX_FEATURE_FBCONFIG_MASK (1L << 0)
#define GLITZ_GLX_FEATURE_PBUFFER_MASK (1L << 1)
#define GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2)
#define GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3)
#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 4)
#define GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5)
typedef struct _glitz_glx_drawable glitz_glx_drawable_t;
typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t;
typedef struct _glitz_glx_display_info_t glitz_glx_display_info_t;
typedef struct _glitz_glx_static_proc_address_list_t {
glitz_glx_get_proc_address_t get_proc_address;
glitz_glx_get_fbconfigs_t get_fbconfigs;
glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib;
glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig;
glitz_glx_create_pbuffer_t create_pbuffer;
glitz_glx_destroy_pbuffer_t destroy_pbuffer;
glitz_glx_query_drawable_t query_drawable;
glitz_glx_make_context_current_t make_context_current;
glitz_glx_create_new_context_t create_new_context;
} glitz_glx_static_proc_address_list_t;
typedef struct _glitz_glx_thread_info_t {
glitz_glx_display_info_t **displays;
int n_displays;
char *gl_library;
void *dlhand;
glitz_context_t *cctx;
} glitz_glx_thread_info_t;
struct _glitz_glx_display_info_t {
glitz_glx_thread_info_t *thread_info;
Display *display;
glitz_glx_screen_info_t **screens;
int n_screens;
};
typedef struct _glitz_glx_context_info_t {
glitz_glx_drawable_t *drawable;
glitz_surface_t *surface;
glitz_constraint_t constraint;
} glitz_glx_context_info_t;
typedef struct _glitz_glx_context_t {
glitz_context_t base;
GLXContext context;
glitz_format_id_t id;
GLXFBConfig fbconfig;
glitz_backend_t backend;
glitz_gl_int_t max_viewport_dims[2];
glitz_gl_int_t max_texture_2d_size;
glitz_gl_int_t max_texture_rect_size;
glitz_bool_t initialized;
} glitz_glx_context_t;
struct _glitz_glx_screen_info_t {
glitz_glx_display_info_t *display_info;
int screen;
int drawables;
glitz_drawable_format_t *formats;
XID *format_ids;
int n_formats;
glitz_glx_context_t **contexts;
int n_contexts;
glitz_glx_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE];
int context_stack_size;
GLXContext root_context;
unsigned long glx_feature_mask;
glitz_gl_float_t glx_version;
glitz_glx_static_proc_address_list_t glx;
glitz_program_map_t program_map;
};
struct _glitz_glx_drawable {
glitz_drawable_t base;
glitz_glx_screen_info_t *screen_info;
glitz_glx_context_t *context;
GLXDrawable drawable;
GLXDrawable pbuffer;
};
extern void __internal_linkage
glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info,
glitz_gl_float_t glx_version);
extern glitz_glx_screen_info_t __internal_linkage *
glitz_glx_screen_info_get (Display *display,
int screen);
extern glitz_function_pointer_t __internal_linkage
glitz_glx_get_proc_address (const char *name,
void *closure);
extern glitz_glx_context_t __internal_linkage *
glitz_glx_context_get (glitz_glx_screen_info_t *screen_info,
glitz_drawable_format_t *format);
extern void __internal_linkage
glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info,
glitz_glx_context_t *context);
extern void __internal_linkage
glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info);
extern GLXPbuffer __internal_linkage
glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info,
GLXFBConfig fbconfig,
int width,
int height);
extern void __internal_linkage
glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info,
GLXPbuffer pbuffer);
extern glitz_drawable_t __internal_linkage *
glitz_glx_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
extern void __internal_linkage
glitz_glx_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint);
extern glitz_surface_t __internal_linkage *
glitz_glx_pop_current (void *abstract_drawable);
void
glitz_glx_make_current (void *abstract_drawable,
glitz_constraint_t constraint);
extern glitz_status_t __internal_linkage
glitz_glx_make_current_read (void *abstract_surface);
extern void __internal_linkage
glitz_glx_destroy (void *abstract_drawable);
extern void __internal_linkage
glitz_glx_swap_buffers (void *abstract_drawable);
/* Avoid unnecessary PLT entries. */
slim_hidden_proto(glitz_glx_init)
slim_hidden_proto(glitz_glx_fini)
slim_hidden_proto(glitz_glx_find_drawable_format)
slim_hidden_proto(glitz_glx_find_drawable_format_for_visual)
slim_hidden_proto(glitz_glx_get_visual_info_from_format)
slim_hidden_proto(glitz_glx_create_drawable_for_window)
slim_hidden_proto(glitz_glx_create_pbuffer_drawable)
#endif /* GLITZ_GLXINT_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,58 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# mozilla.org
# Portions created by the Initial Developer are Copyright (C) 2005
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Vladimir Vukicevic <vladimir@pobox.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = glitzwgl
LIBRARY_NAME = mozglitzwgl
LIBXUL_LIBRARY = 1
REQUIRES = glitz
CSRCS = \
$(NULL)
EXPORTS = glitz-wgl.h
FORCE_USE_PIC = 1
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,84 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Based on glx code by David Reveman and Peter Nilsson
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifndef GLITZ_WGL_H_INCLUDED
#define GLITZ_WGL_H_INCLUDED
#include <glitz.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#include <windows.h>
/* glitz_wgl_info.c */
typedef struct _glitz_wgl_thread_starter_arg_t {
int (*user_thread_function) (void *);
void *user_thread_function_arg;
} glitz_wgl_thread_starter_arg_t;
int
glitz_wgl_thread_starter (const glitz_wgl_thread_starter_arg_t *arg);
void
glitz_wgl_init (const char *gl_library);
void
glitz_wgl_fini (void);
/* glitz_wgl_format.c */
glitz_drawable_format_t *
glitz_wgl_find_drawable_format (unsigned long mask,
const glitz_drawable_format_t *templ,
int count);
/* glitz_wgl_drawable.c */
glitz_drawable_t *
glitz_wgl_create_drawable_for_window (glitz_drawable_format_t *format,
HWND window,
unsigned int width,
unsigned int height);
glitz_drawable_t *
glitz_wgl_create_pbuffer_drawable (glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif /* GLITZ_WGL_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,307 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
#include <stdlib.h>
#include <stdio.h>
extern glitz_gl_proc_address_list_t _glitz_wgl_gl_proc_address;
static void
_glitz_wgl_context_create (glitz_wgl_screen_info_t *screen_info,
HDC dc,
int format_id,
glitz_wgl_context_t *context)
{
PIXELFORMATDESCRIPTOR dummy_pfd;
dummy_pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
dummy_pfd.nVersion = 1;
SetPixelFormat (dc, format_id, &dummy_pfd);
context->context = wglCreateContext (dc);
context->pixel_format = format_id;
}
static glitz_context_t *
_glitz_wgl_create_context (void *abstract_drawable,
glitz_drawable_format_t *format)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
glitz_wgl_screen_info_t *screen_info = drawable->screen_info;
int format_id = screen_info->format_ids[format->id];
glitz_wgl_context_t *context;
context = malloc (sizeof (glitz_wgl_context_t));
if (!context)
return NULL;
_glitz_context_init (&context->base, &drawable->base);
_glitz_wgl_context_create (screen_info,
drawable->dc,
format_id,
context);
wglShareLists (screen_info->root_context, context->context);
return (glitz_context_t *) context;
}
static void
_glitz_wgl_destroy_context (void *abstract_context)
{
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
wglDeleteContext (context->context);
_glitz_context_fini (&context->base);
free (context);
}
static void
_glitz_wgl_copy_context (void *abstract_src,
void *abstract_dst,
unsigned long mask)
{
glitz_wgl_context_t *src = (glitz_wgl_context_t *) abstract_src;
glitz_wgl_context_t *dst = (glitz_wgl_context_t *) abstract_dst;
wglCopyContext (src->context, dst->context, mask);
}
static void
_glitz_wgl_make_current (void *abstract_context,
void *abstract_drawable)
{
glitz_wgl_context_t *context = (glitz_wgl_context_t *) abstract_context;
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
if (wglGetCurrentContext() != context->context ||
wglGetCurrentDC() != drawable->dc)
{
wglMakeCurrent (drawable->dc, context->context);
}
}
glitz_wgl_context_t *
glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
HDC dc,
glitz_drawable_format_t *format)
{
glitz_wgl_context_t *context;
glitz_wgl_context_t **contexts = screen_info->contexts;
int index, n_contexts = screen_info->n_contexts;
int format_id;
for (; n_contexts; n_contexts--, contexts++)
if ((*contexts)->pixel_format == screen_info->format_ids[format->id]) {
return *contexts;
}
index = screen_info->n_contexts++;
screen_info->contexts =
realloc (screen_info->contexts,
sizeof (glitz_wgl_context_t *) * screen_info->n_contexts);
context = malloc (sizeof (glitz_wgl_context_t));
screen_info->contexts[index] = context;
format_id = screen_info->format_ids[format->id];
_glitz_wgl_context_create (screen_info,
dc,
format_id,
context);
wglShareLists (screen_info->root_context, context->context);
#if 0
/* Not needed as the root_context is created already when the
* singleton screen_info is set up.
*/
if (!screen_info->root_context)
screen_info->root_context = context->context;
#endif
memcpy (&context->backend.gl,
&_glitz_wgl_gl_proc_address,
sizeof (glitz_gl_proc_address_list_t));
context->backend.create_pbuffer = glitz_wgl_create_pbuffer;
context->backend.destroy = glitz_wgl_destroy;
context->backend.push_current = glitz_wgl_push_current;
context->backend.pop_current = glitz_wgl_pop_current;
context->backend.swap_buffers = glitz_wgl_swap_buffers;
context->backend.create_context = _glitz_wgl_create_context;
context->backend.destroy_context = _glitz_wgl_destroy_context;
context->backend.copy_context = _glitz_wgl_copy_context;
context->backend.make_current = _glitz_wgl_make_current;
context->backend.drawable_formats = screen_info->formats;
context->backend.n_drawable_formats = screen_info->n_formats;
context->backend.texture_formats = NULL;
context->backend.formats = NULL;
context->backend.n_formats = 0;
context->backend.program_map = &screen_info->program_map;
context->backend.feature_mask = 0;
context->initialized = 0;
return context;
}
void
glitz_wgl_context_destroy (glitz_wgl_screen_info_t *screen_info,
glitz_wgl_context_t *context)
{
if (context->backend.formats)
free (context->backend.formats);
if (context->backend.texture_formats)
free (context->backend.texture_formats);
wglDeleteContext (context->context);
free (context);
}
static void
_glitz_wgl_context_initialize (glitz_wgl_screen_info_t *screen_info,
glitz_wgl_context_t *context)
{
glitz_backend_init (&context->backend,
glitz_wgl_get_proc_address,
(void *) screen_info);
context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
context->max_viewport_dims);
glitz_initiate_state (&_glitz_wgl_gl_proc_address);
context->initialized = 1;
}
static void
_glitz_wgl_context_make_current (glitz_wgl_drawable_t *drawable,
glitz_bool_t flush)
{
if (flush)
{
glFlush ();
}
wglMakeCurrent (drawable->dc, drawable->context->context);
if (!drawable->context->initialized)
_glitz_wgl_context_initialize (drawable->screen_info, drawable->context);
}
static void
_glitz_wgl_context_update (glitz_wgl_drawable_t *drawable,
glitz_constraint_t constraint)
{
HGLRC context;
switch (constraint) {
case GLITZ_NONE:
break;
case GLITZ_ANY_CONTEXT_CURRENT:
context = wglGetCurrentContext ();
if (context == NULL)
_glitz_wgl_context_make_current (drawable, 0);
break;
case GLITZ_CONTEXT_CURRENT:
context = wglGetCurrentContext ();
if (context != drawable->context->context)
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
break;
case GLITZ_DRAWABLE_CURRENT:
context = wglGetCurrentContext ();
if ((context != drawable->context->context) ||
(wglGetCurrentDC () != drawable->dc))
_glitz_wgl_context_make_current (drawable, (context)? 1: 0);
break;
}
}
void
glitz_wgl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
glitz_wgl_context_info_t *context_info;
int index;
index = drawable->screen_info->context_stack_size++;
context_info = &drawable->screen_info->context_stack[index];
context_info->drawable = drawable;
context_info->surface = surface;
context_info->constraint = constraint;
_glitz_wgl_context_update (context_info->drawable, constraint);
}
glitz_surface_t *
glitz_wgl_pop_current (void *abstract_drawable)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
glitz_wgl_context_info_t *context_info = NULL;
int index;
drawable->screen_info->context_stack_size--;
index = drawable->screen_info->context_stack_size - 1;
context_info = &drawable->screen_info->context_stack[index];
if (context_info->drawable)
_glitz_wgl_context_update (context_info->drawable,
context_info->constraint);
if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
return context_info->surface;
return NULL;
}

Просмотреть файл

@ -0,0 +1,222 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
#include <stdio.h>
glitz_status_t
glitz_wgl_make_current_read (void *abstract_surface)
{
return GLITZ_STATUS_NOT_SUPPORTED;
}
static glitz_wgl_drawable_t *
_glitz_wgl_create_drawable (glitz_wgl_screen_info_t *screen_info,
glitz_wgl_context_t *context,
glitz_drawable_format_t *format,
HWND window,
HDC dc,
HPBUFFERARB pbuffer,
int width,
int height)
{
glitz_wgl_drawable_t *drawable;
if (width <= 0 || height <= 0)
return NULL;
drawable = (glitz_wgl_drawable_t *) malloc (sizeof (glitz_wgl_drawable_t));
if (drawable == NULL)
return NULL;
drawable->base.ref_count = 1;
drawable->screen_info = screen_info;
drawable->context = context;
drawable->window = window;
drawable->dc = dc;
drawable->pbuffer = pbuffer;
drawable->base.format = format;
drawable->base.backend = &context->backend;
glitz_drawable_update_size (&drawable->base, width, height);
if (!context->initialized) {
glitz_wgl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_wgl_pop_current (drawable);
}
if (width > context->max_viewport_dims[0] ||
height > context->max_viewport_dims[1]) {
free (drawable);
return NULL;
}
screen_info->drawables++;
return drawable;
}
static glitz_drawable_t *
_glitz_wgl_create_pbuffer_drawable (glitz_wgl_screen_info_t *screen_info,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_wgl_drawable_t *drawable;
glitz_wgl_context_t *context;
HPBUFFERARB pbuffer;
HDC dc;
if (!format->types.pbuffer)
return NULL;
pbuffer = glitz_wgl_pbuffer_create (screen_info, screen_info->format_ids[format->id],
width, height,
&dc);
if (!pbuffer)
return NULL;
context = glitz_wgl_context_get (screen_info, dc, format);
if (!context) {
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
return NULL;
}
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
NULL, dc, pbuffer,
width, height);
if (!drawable) {
glitz_wgl_pbuffer_destroy (screen_info, pbuffer, dc);
glitz_wgl_context_destroy (screen_info, context);
return NULL;
}
return &drawable->base;
}
glitz_drawable_t *
glitz_wgl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_wgl_drawable_t *templ = (glitz_wgl_drawable_t *) abstract_templ;
return _glitz_wgl_create_pbuffer_drawable (templ->screen_info, format,
width, height);
}
glitz_drawable_t *
glitz_wgl_create_drawable_for_window (glitz_drawable_format_t *format,
HWND window,
unsigned int width,
unsigned int height)
{
glitz_wgl_drawable_t *drawable;
glitz_wgl_screen_info_t *screen_info;
glitz_wgl_context_t *context;
HDC dc;
screen_info = glitz_wgl_screen_info_get ();
if (!screen_info)
return NULL;
dc = GetDC (window);
context = glitz_wgl_context_get (screen_info, dc, format);
if (!context) {
ReleaseDC (window, dc);
return NULL;
}
drawable = _glitz_wgl_create_drawable (screen_info, context, format,
window, dc, NULL,
width, height);
if (!drawable)
return NULL;
return &drawable->base;
}
glitz_drawable_t *
glitz_wgl_create_pbuffer_drawable (glitz_drawable_format_t *format,
unsigned int width,
unsigned int height)
{
glitz_wgl_screen_info_t *screen_info;
screen_info = glitz_wgl_screen_info_get ();
if (!screen_info)
return NULL;
return _glitz_wgl_create_pbuffer_drawable (screen_info, format,
width, height);
}
void
glitz_wgl_destroy (void *abstract_drawable)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
drawable->screen_info->drawables--;
if (drawable->screen_info->drawables == 0) {
/*
* Last drawable? We have to destroy all fragment programs as this may
* be our last chance to have a context current.
*/
glitz_wgl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
glitz_program_map_fini (&drawable->base.backend->gl,
&drawable->screen_info->program_map);
glitz_wgl_pop_current (abstract_drawable);
}
if (wglGetCurrentDC () == drawable->dc)
{
wglMakeCurrent (NULL, NULL);
}
if (drawable->pbuffer)
glitz_wgl_pbuffer_destroy (drawable->screen_info, drawable->pbuffer, drawable->dc);
free (drawable);
}
void
glitz_wgl_swap_buffers (void *abstract_drawable)
{
glitz_wgl_drawable_t *drawable = (glitz_wgl_drawable_t *) abstract_drawable;
SwapBuffers (drawable->dc);
}

Просмотреть файл

@ -0,0 +1,82 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
#include <stdio.h>
#include <ctype.h>
static glitz_extension_map wgl_extensions[] = {
{ 0.0, "WGL_ARB_pixel_format", GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK },
{ 0.0, "WGL_ARB_pbuffer", GLITZ_WGL_FEATURE_PBUFFER_MASK },
{ 0.0, "WGL_ARB_make_current_read",
GLITZ_WGL_FEATURE_MAKE_CURRENT_READ_MASK },
{ 0.0, "WGL_ARB_multisample", GLITZ_WGL_FEATURE_MULTISAMPLE_MASK },
{ 0.0, NULL, 0 }
};
void
glitz_wgl_query_extensions (glitz_wgl_screen_info_t *screen_info,
glitz_gl_float_t wgl_version)
{
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
const char *wgl_extensions_string;
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress ("wglGetExtensionsStringARB");
if (wglGetExtensionsStringARB == NULL)
return;
wgl_extensions_string = (*wglGetExtensionsStringARB) (screen_info->root_dc);
screen_info->wgl_feature_mask =
glitz_extensions_query (wgl_version,
wgl_extensions_string,
wgl_extensions);
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
const char *renderer;
renderer = glGetString (GL_RENDERER);
if (renderer) {
/* nVIDIA's driver seem to support multisample with pbuffers (?) */
if (!strncmp ("GeForce", renderer, 7) ||
!strncmp ("Quadro", renderer, 6))
screen_info->wgl_feature_mask |=
GLITZ_WGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
}
}
}

Просмотреть файл

@ -0,0 +1,347 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static int
_glitz_wgl_format_compare (const void *elem1,
const void *elem2)
{
int i, score[2];
glitz_drawable_format_t *format[2];
format[0] = (glitz_drawable_format_t *) elem1;
format[1] = (glitz_drawable_format_t *) elem2;
i = score[0] = score[1] = 0;
for (; i < 2; i++) {
if (format[i]->color.red_size) {
if (format[i]->color.red_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.green_size) {
if (format[i]->color.green_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->color.alpha_size) {
if (format[i]->color.alpha_size == 8)
score[i] += 5;
score[i] += 10;
}
if (format[i]->stencil_size)
score[i] += 5;
if (format[i]->depth_size)
score[i] += 5;
if (format[i]->doublebuffer)
score[i] += 10;
if (format[i]->types.window)
score[i] += 10;
if (format[i]->types.pbuffer)
score[i] += 10;
if (format[i]->samples > 1)
score[i] -= (20 - format[i]->samples);
}
return score[1] - score[0];
}
static void
_glitz_add_format (glitz_wgl_screen_info_t *screen_info,
glitz_drawable_format_t *format,
int id)
{
if (!glitz_drawable_format_find (screen_info->formats,
screen_info->n_formats,
GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK,
format, 0)) {
int n = screen_info->n_formats;
screen_info->formats =
realloc (screen_info->formats,
sizeof (glitz_drawable_format_t) * (n + 1));
screen_info->format_ids =
realloc (screen_info->format_ids, sizeof (int) * (n + 1));
if (screen_info->formats && screen_info->format_ids) {
screen_info->formats[n] = *format;
screen_info->formats[n].id = n;
screen_info->format_ids[n] = id;
screen_info->n_formats++;
}
}
}
static glitz_bool_t
_glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
{
glitz_drawable_format_t format;
int i, num_pixel_formats;
PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
num_pixel_formats =
DescribePixelFormat (screen_info->root_dc, 1,
sizeof (PIXELFORMATDESCRIPTOR), &pfd);
if (!num_pixel_formats)
return 0;
for (i = 1; i <= num_pixel_formats; i++) {
format.id = 0;
if (!DescribePixelFormat (screen_info->root_dc, i,
sizeof (PIXELFORMATDESCRIPTOR), &pfd))
{
continue;
}
if (!((pfd.dwFlags & PFD_DRAW_TO_WINDOW) &&
(pfd.dwFlags & PFD_SUPPORT_OPENGL)))
continue;
if (pfd.iPixelType != PFD_TYPE_RGBA)
continue;
if (pfd.dwFlags & (PFD_NEED_PALETTE |
PFD_NEED_SYSTEM_PALETTE |
PFD_STEREO))
continue;
#ifndef USE_MESA
/* Can't use the Windows software implementation as glitz
* unconditionally requires OpenGL 1.2, and it's only 1.1.
*/
if (pfd.dwFlags & PFD_GENERIC_FORMAT)
continue;
#endif
format.types.window = 1;
format.types.pbuffer = 0;
format.color.red_size = pfd.cRedBits;
format.color.green_size = pfd.cGreenBits;
format.color.blue_size = pfd.cBlueBits;
format.color.alpha_size = pfd.cAlphaBits;
format.depth_size = pfd.cDepthBits;
format.stencil_size = pfd.cStencilBits;
format.doublebuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0;
format.samples = 1;
_glitz_add_format (screen_info, &format, i);
}
return 0;
}
static glitz_status_t
_glitz_wgl_query_formats_using_pixel_format (glitz_wgl_screen_info_t *screen_info)
{
glitz_drawable_format_t format;
int i, num_pixel_formats;
int question, answer;
glitz_wgl_static_proc_address_list_t *wgl = &screen_info->wgl;
question = WGL_NUMBER_PIXEL_FORMATS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, 0, 0, 1,
&question, &num_pixel_formats)) {
/* wglGetPixelFormatAttribivARB didn't work, fall back to
* DescribePixelFormat.
*/
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK;
return GLITZ_STATUS_NOT_SUPPORTED;
}
for (i = 1; i <= num_pixel_formats; i++) {
format.id = 0;
question = WGL_SUPPORT_OPENGL_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer) ||
!answer)
continue;
question = WGL_PIXEL_TYPE_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer) ||
answer != WGL_TYPE_RGBA_ARB)
continue;
/* Stereo is not supported yet */
question = WGL_STEREO_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer) ||
answer != 0)
continue;
question = WGL_DRAW_TO_WINDOW_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.types.window = (answer) ? 1 : 0;
question = WGL_DRAW_TO_PBUFFER_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.types.pbuffer = (answer) ? 1 : 0;
if (!(format.types.window || format.types.pbuffer))
continue;
question = WGL_RED_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.color.red_size = (unsigned short) answer;
question = WGL_GREEN_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.color.green_size = (unsigned short) answer;
question = WGL_BLUE_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.color.blue_size = (unsigned short) answer;
question = WGL_ALPHA_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.color.alpha_size = (unsigned short) answer;
question = WGL_DEPTH_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.depth_size = (unsigned short) answer;
question = WGL_STENCIL_BITS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.stencil_size = (unsigned short) answer;
question = WGL_DOUBLE_BUFFER_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.doublebuffer = (answer) ? 1: 0;
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_MULTISAMPLE_MASK) {
question = WGL_SAMPLE_BUFFERS_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
if (answer) {
question = WGL_SAMPLES_ARB;
if (!wgl->get_pixel_format_attrib_iv (screen_info->root_dc, i, 0, 1,
&question, &answer))
continue;
format.samples = (unsigned short) answer;
} else {
format.samples = 1;
}
} else {
format.samples = 1;
}
_glitz_add_format (screen_info, &format, i);
}
return GLITZ_STATUS_SUCCESS;
}
void
glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info)
{
glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED;
int *new_ids, i;
if (screen_info->wgl_feature_mask & GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK)
status = _glitz_wgl_query_formats_using_pixel_format (screen_info);
if (status)
_glitz_wgl_query_formats (screen_info);
if (!screen_info->n_formats)
return;
qsort (screen_info->formats, screen_info->n_formats,
sizeof (glitz_drawable_format_t), _glitz_wgl_format_compare);
new_ids = malloc (sizeof (*new_ids) * screen_info->n_formats);
for (i = 0; i < screen_info->n_formats; i++) {
new_ids[i] = screen_info->format_ids[screen_info->formats[i].id];
screen_info->formats[i].id = i;
}
free (screen_info->format_ids);
screen_info->format_ids = new_ids;
}
glitz_drawable_format_t *
glitz_wgl_find_drawable_format (unsigned long mask,
const glitz_drawable_format_t *templ,
int count)
{
glitz_wgl_screen_info_t *screen_info =
glitz_wgl_screen_info_get ();
return glitz_drawable_format_find (screen_info->formats,
screen_info->n_formats,
mask, templ, count);
}

Просмотреть файл

@ -0,0 +1,499 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <assert.h>
void
glitz_wgl_print_win32_error_string (int error_code)
{
char *msg = NULL;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error_code, 0,
(LPTSTR) &msg, 0, NULL);
if (msg != NULL)
fprintf (stderr, "%s", msg);
else
fprintf (stderr, "Unknown error code %d", error_code);
LocalFree (msg);
}
void
glitz_wgl_win32_api_failed (const char *api)
{
fprintf (stderr, "%s failed: ", api);
glitz_wgl_print_win32_error_string (GetLastError ());
fprintf (stderr, "\n");
}
glitz_gl_proc_address_list_t _glitz_wgl_gl_proc_address = {
/* core */
(glitz_gl_enable_t) glEnable,
(glitz_gl_disable_t) glDisable,
(glitz_gl_get_error_t) glGetError,
(glitz_gl_get_string_t) glGetString,
(glitz_gl_enable_client_state_t) glEnableClientState,
(glitz_gl_disable_client_state_t) glDisableClientState,
(glitz_gl_vertex_pointer_t) glVertexPointer,
(glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
(glitz_gl_draw_arrays_t) glDrawArrays,
(glitz_gl_tex_env_f_t) glTexEnvf,
(glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_gen_i_t) glTexGeni,
(glitz_gl_tex_gen_fv_t) glTexGenfv,
(glitz_gl_color_4us_t) glColor4us,
(glitz_gl_color_4f_t) glColor4f,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
(glitz_gl_clear_color_t) glClearColor,
(glitz_gl_clear_stencil_t) glClearStencil,
(glitz_gl_stencil_func_t) glStencilFunc,
(glitz_gl_stencil_op_t) glStencilOp,
(glitz_gl_push_attrib_t) glPushAttrib,
(glitz_gl_pop_attrib_t) glPopAttrib,
(glitz_gl_matrix_mode_t) glMatrixMode,
(glitz_gl_push_matrix_t) glPushMatrix,
(glitz_gl_pop_matrix_t) glPopMatrix,
(glitz_gl_load_identity_t) glLoadIdentity,
(glitz_gl_load_matrix_f_t) glLoadMatrixf,
(glitz_gl_depth_range_t) glDepthRange,
(glitz_gl_viewport_t) glViewport,
(glitz_gl_raster_pos_2f_t) glRasterPos2f,
(glitz_gl_bitmap_t) glBitmap,
(glitz_gl_read_buffer_t) glReadBuffer,
(glitz_gl_draw_buffer_t) glDrawBuffer,
(glitz_gl_copy_pixels_t) glCopyPixels,
(glitz_gl_flush_t) glFlush,
(glitz_gl_finish_t) glFinish,
(glitz_gl_pixel_store_i_t) glPixelStorei,
(glitz_gl_ortho_t) glOrtho,
(glitz_gl_scale_f_t) glScalef,
(glitz_gl_translate_f_t) glTranslatef,
(glitz_gl_hint_t) glHint,
(glitz_gl_depth_mask_t) glDepthMask,
(glitz_gl_polygon_mode_t) glPolygonMode,
(glitz_gl_shade_model_t) glShadeModel,
(glitz_gl_color_mask_t) glColorMask,
(glitz_gl_read_pixels_t) glReadPixels,
(glitz_gl_get_tex_image_t) glGetTexImage,
(glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
(glitz_gl_gen_textures_t) glGenTextures,
(glitz_gl_delete_textures_t) glDeleteTextures,
(glitz_gl_bind_texture_t) glBindTexture,
(glitz_gl_tex_image_2d_t) glTexImage2D,
(glitz_gl_tex_parameter_i_t) glTexParameteri,
(glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
(glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
(glitz_gl_get_integer_v_t) glGetIntegerv,
/* extensions */
(glitz_gl_blend_color_t) 0,
(glitz_gl_active_texture_t) 0,
(glitz_gl_client_active_texture_t) 0,
(glitz_gl_multi_draw_arrays_t) 0,
(glitz_gl_gen_programs_t) 0,
(glitz_gl_delete_programs_t) 0,
(glitz_gl_program_string_t) 0,
(glitz_gl_bind_program_t) 0,
(glitz_gl_program_local_param_4fv_t) 0,
(glitz_gl_get_program_iv_t) 0,
(glitz_gl_gen_buffers_t) 0,
(glitz_gl_delete_buffers_t) 0,
(glitz_gl_bind_buffer_t) 0,
(glitz_gl_buffer_data_t) 0,
(glitz_gl_buffer_sub_data_t) 0,
(glitz_gl_get_buffer_sub_data_t) 0,
(glitz_gl_map_buffer_t) 0,
(glitz_gl_unmap_buffer_t) 0
};
glitz_function_pointer_t
glitz_wgl_get_proc_address (const char *name,
void *closure)
{
glitz_wgl_screen_info_t *screen_info = (glitz_wgl_screen_info_t *) closure;
glitz_wgl_thread_info_t *info = screen_info->thread_info;
glitz_function_pointer_t address = (glitz_function_pointer_t) wglGetProcAddress (name);
if (!address && info->gl_library) {
/* Not sure whether this has any use at all... */
if (!info->dlhand)
info->dlhand = LoadLibrary (info->gl_library);
if (info->dlhand) {
address = (glitz_function_pointer_t) GetProcAddress (info->dlhand, name);
}
}
return address;
}
static void
_glitz_wgl_proc_address_lookup (glitz_wgl_screen_info_t *screen_info)
{
screen_info->wgl.get_pixel_format_attrib_iv =
(glitz_wgl_get_pixel_format_attrib_iv_t)
glitz_wgl_get_proc_address ("wglGetPixelFormatAttribivARB", screen_info);
screen_info->wgl.choose_pixel_format = (glitz_wgl_choose_pixel_format_t)
glitz_wgl_get_proc_address ("wglChoosePixelFormatARB", screen_info);
screen_info->wgl.create_pbuffer = (glitz_wgl_create_pbuffer_t)
glitz_wgl_get_proc_address ("wglCreatePbufferARB", screen_info);
screen_info->wgl.get_pbuffer_dc = (glitz_wgl_get_pbuffer_dc_t)
glitz_wgl_get_proc_address ("wglGetPbufferDCARB", screen_info);
screen_info->wgl.release_pbuffer_dc = (glitz_wgl_release_pbuffer_dc_t)
glitz_wgl_get_proc_address ("wglReleasePbufferDCARB", screen_info);
screen_info->wgl.destroy_pbuffer = (glitz_wgl_destroy_pbuffer_t)
glitz_wgl_get_proc_address ("wglDestroyPbufferARB", screen_info);
screen_info->wgl.query_pbuffer = (glitz_wgl_query_pbuffer_t)
glitz_wgl_get_proc_address ("wglQueryPbufferARB", screen_info);
screen_info->wgl.make_context_current = (glitz_wgl_make_context_current_t)
glitz_wgl_get_proc_address ("wglMakeContextCurrentARB", screen_info);
if ((!screen_info->wgl.create_pbuffer) ||
(!screen_info->wgl.destroy_pbuffer) ||
(!screen_info->wgl.query_pbuffer))
screen_info->wgl_feature_mask &= ~GLITZ_WGL_FEATURE_PBUFFER_MASK;
}
static void
_glitz_wgl_screen_destroy (glitz_wgl_screen_info_t *screen_info);
static void
_glitz_wgl_thread_info_init (glitz_wgl_thread_info_t *thread_info)
{
thread_info->screen = NULL;
thread_info->gl_library = NULL;
thread_info->dlhand = NULL;
}
static void
_glitz_wgl_thread_info_fini (glitz_wgl_thread_info_t *thread_info)
{
_glitz_wgl_screen_destroy (thread_info->screen);
thread_info->screen = NULL;
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
if (thread_info->dlhand) {
FreeLibrary (thread_info->dlhand);
thread_info->dlhand = NULL;
}
}
static int tsd_initialized = 0;
static DWORD info_tsd;
static void
_glitz_wgl_thread_info_destroy (glitz_wgl_thread_info_t *thread_info)
{
TlsSetValue (info_tsd, NULL);
if (thread_info) {
_glitz_wgl_thread_info_fini (thread_info);
free (thread_info);
}
}
static glitz_wgl_thread_info_t *
_glitz_wgl_thread_info_get_inner (void)
{
glitz_wgl_thread_info_t *thread_info;
void *p;
if (!tsd_initialized) {
info_tsd = TlsAlloc ();
tsd_initialized = 1;
}
p = TlsGetValue (info_tsd);
if (p == NULL) {
thread_info = malloc (sizeof (glitz_wgl_thread_info_t));
_glitz_wgl_thread_info_init (thread_info);
TlsSetValue (info_tsd, thread_info);
} else
thread_info = (glitz_wgl_thread_info_t *) p;
return thread_info;
}
static glitz_wgl_thread_info_t *
_glitz_wgl_thread_info_get (const char *gl_library)
{
glitz_wgl_thread_info_t *thread_info = _glitz_wgl_thread_info_get_inner ();
if (gl_library) {
int len = strlen (gl_library);
if (thread_info->gl_library) {
free (thread_info->gl_library);
thread_info->gl_library = NULL;
}
thread_info->gl_library = malloc (len + 1);
if (thread_info->gl_library) {
memcpy (thread_info->gl_library, gl_library, len);
thread_info->gl_library[len] = '\0';
}
}
return thread_info;
}
int
glitz_wgl_thread_starter (const glitz_wgl_thread_starter_arg_t *arg)
{
glitz_wgl_thread_info_t *thread_info;
int retval;
retval = (*arg->user_thread_function) (arg->user_thread_function_arg);
if (tsd_initialized) {
thread_info = (glitz_wgl_thread_info_t *) TlsGetValue (info_tsd);
_glitz_wgl_thread_info_fini (thread_info);
free (thread_info);
}
return retval;
}
static void
_glitz_wgl_create_root_context (glitz_wgl_screen_info_t *screen_info)
{
WNDCLASSEX wcl;
ATOM klass;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA,
32,
0, 0, 0,
0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
0,
0,
0,
PFD_MAIN_PLANE,
0,
0,
0,
0
};
int pixel_format;
wcl.cbSize = sizeof (wcl);
wcl.style = 0;
wcl.lpfnWndProc = DefWindowProc;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hInstance = GetModuleHandle (NULL);
wcl.hIcon = NULL;
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
wcl.hbrBackground = NULL;
wcl.lpszMenuName = NULL;
wcl.lpszClassName = "glitz-wgl-root-window-class";
wcl.hIconSm = NULL;
klass = RegisterClassEx (&wcl);
if (!klass) {
exit (1);
}
screen_info->root_window =
CreateWindowEx (0, (LPCTSTR) (DWORD) klass, "glitz-wgl-root-window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100,
GetDesktopWindow (),
NULL, GetModuleHandle (NULL), NULL);
screen_info->root_dc = GetDC (screen_info->root_window);
pixel_format = ChoosePixelFormat (screen_info->root_dc, &pfd);
if (pixel_format != 0) {
SetPixelFormat (screen_info->root_dc, pixel_format, &pfd);
screen_info->root_context = wglCreateContext (screen_info->root_dc);
wglMakeCurrent (screen_info->root_dc, screen_info->root_context);
} else {
screen_info->root_context = NULL;
}
}
glitz_wgl_screen_info_t *
glitz_wgl_screen_info_get (void)
{
static glitz_wgl_screen_info_t *screen_info = NULL;
const char *gl_version;
if (screen_info != NULL)
return screen_info;
screen_info = malloc (sizeof (glitz_wgl_screen_info_t));
screen_info->drawables = 0;
screen_info->formats = NULL;
screen_info->format_ids = NULL;
screen_info->n_formats = 0;
screen_info->contexts = NULL;
screen_info->n_contexts = 0;
memset (&screen_info->wgl, 0, sizeof (glitz_wgl_static_proc_address_list_t));
glitz_program_map_init (&screen_info->program_map);
_glitz_wgl_create_root_context (screen_info);
gl_version = glGetString (GL_VERSION);
screen_info->wgl_version = 1;
/* Can't use atof(), as GL_VERSION might always use a decimal period,
* but atof() looks for the locale-specific decimal separator.
*/
if (gl_version != NULL && gl_version[0]) {
int whole_part;
int n;
if (sscanf (gl_version, "%d%n", &whole_part, &n) == 1 &&
(gl_version[n] == '.' ||
gl_version[n] == ',')) {
double fraction = 0.1;
screen_info->wgl_version = whole_part;
while (isdigit (gl_version[n+1])) {
screen_info->wgl_version += (gl_version[n+1] - '0') * fraction;
fraction /= 10;
n++;
}
}
}
screen_info->wgl_feature_mask = 0;
screen_info->thread_info = _glitz_wgl_thread_info_get_inner ();
screen_info->thread_info->screen = screen_info;
_glitz_wgl_thread_info_get (NULL);
glitz_wgl_query_extensions (screen_info, screen_info->wgl_version);
_glitz_wgl_proc_address_lookup (screen_info);
glitz_wgl_query_formats (screen_info);
screen_info->context_stack_size = 1;
screen_info->context_stack->drawable = NULL;
screen_info->context_stack->surface = NULL;
screen_info->context_stack->constraint = GLITZ_NONE;
return screen_info;
}
static void
_glitz_wgl_screen_destroy (glitz_wgl_screen_info_t *screen_info)
{
int i;
if (screen_info->root_context) {
wglMakeCurrent (NULL, NULL);
}
for (i = 0; i < screen_info->n_contexts; i++)
glitz_wgl_context_destroy (screen_info, screen_info->contexts[i]);
if (screen_info->contexts)
free (screen_info->contexts);
if (screen_info->formats)
free (screen_info->formats);
if (screen_info->format_ids)
free (screen_info->format_ids);
if (screen_info->root_context) {
wglDeleteContext (screen_info->root_context);
}
if (screen_info->root_dc) {
DeleteDC (screen_info->root_dc);
}
if (screen_info->root_window) {
DestroyWindow (screen_info->root_window);
}
free (screen_info);
}
void
glitz_wgl_init (const char *gl_library)
{
_glitz_wgl_thread_info_get (gl_library);
}
void
glitz_wgl_fini (void)
{
glitz_wgl_thread_info_t *info = _glitz_wgl_thread_info_get (NULL);
_glitz_wgl_thread_info_destroy (info);
}

Просмотреть файл

@ -0,0 +1,71 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif
#include "glitz_wglint.h"
HPBUFFERARB
glitz_wgl_pbuffer_create (glitz_wgl_screen_info_t *screen_info,
int pixel_format,
unsigned int width,
unsigned int height,
HDC *dcp)
{
if (pixel_format) {
HPBUFFERARB retval;
int pbuffer_attr[3], i = 0;
pbuffer_attr[i++] = WGL_PBUFFER_LARGEST_ARB;
pbuffer_attr[i++] = 0;
pbuffer_attr[i++] = 0;
retval =
screen_info->wgl.create_pbuffer (screen_info->root_dc, pixel_format,
width, height, pbuffer_attr);
if (retval != NULL) {
*dcp = screen_info->wgl.get_pbuffer_dc (retval);
return retval;
}
}
*dcp = NULL;
return NULL;
}
void
glitz_wgl_pbuffer_destroy (glitz_wgl_screen_info_t *screen_info,
HPBUFFERARB pbuffer,
HDC dc)
{
screen_info->wgl.release_pbuffer_dc (pbuffer, dc);
screen_info->wgl.destroy_pbuffer (pbuffer);
}

Просмотреть файл

@ -0,0 +1,151 @@
/*
* Copyright © 2004 David Reveman, Peter Nilsson
*
* 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 names of
* David Reveman and Peter Nilsson not be used in advertising or
* publicity pertaining to distribution of the software without
* specific, written prior permission. David Reveman and Peter Nilsson
* makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
* PETER NILSSON 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.
*
* Based on glx code by David Reveman and Peter Nilsson
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifndef GLITZ_WGLEXT_H_INCLUDED
#define GLITZ_WGLEXT_H_INCLUDED
/* WGL_ARB_pixel_format */
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
typedef BOOL (WINAPI * glitz_wgl_get_pixel_format_attrib_iv_t)
(HDC hDC,
int iPixelFormat,
int iLayerPlane,
unsigned int nAttributes,
const int *piAttributes,
int *piValues);
typedef BOOL (WINAPI * glitz_wgl_choose_pixel_format_t)
(HDC hDC,
const int *piAttribIList,
const float *pfAttribFList,
unsigned int nMaxFormats,
int *piFormats,
unsigned int *nNumFormats);
/* WGL_ARB_make_current_read */
typedef HDC (WINAPI * glitz_wgl_get_current_read_dc_t) (VOID);
typedef BOOL (WINAPI * glitz_wgl_make_context_current_t)
(HDC hDrawDC,
HDC hReadDC,
HGLRC hglrc);
/* WGL_ARB_multisample */
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
/* WGL_ARB_pbuffer */
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
DECLARE_HANDLE(HPBUFFERARB);
typedef HPBUFFERARB (WINAPI * glitz_wgl_create_pbuffer_t)
(HDC hDC,
int iPixelFormat,
int iWidth,
int iHeight,
const int *piAttribList);
typedef HDC (WINAPI * glitz_wgl_get_pbuffer_dc_t)
(HPBUFFERARB hPbuffer);
typedef int (WINAPI * glitz_wgl_release_pbuffer_dc_t)
(HPBUFFERARB hPbuffer,
HDC hDC);
typedef BOOL (WINAPI * glitz_wgl_destroy_pbuffer_t)
(HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * glitz_wgl_query_pbuffer_t)
(HPBUFFERARB hPbuffer,
int iAttribute,
int *piValue);
#endif /* GLITZ_WGLEXT_H_INCLUDED */

Просмотреть файл

@ -0,0 +1,196 @@
/*
* Copyright © 2004 David Reveman
*
* 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 names of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN 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.
*
* Based on glx code by David Reveman
*
* Contributors:
* Tor Lillqvist <tml@iki.fi>
* Vladimir Vukicevic <vladimir@pobox.com>
*
*/
#ifndef GLITZ_WGLINT_H_INCLUDED
#define GLITZ_WGLINT_H_INCLUDED
#include <windows.h> /* To let it define MAX/MINSHORT first */
#undef MAXSHORT
#undef MINSHORT
#include "glitzint.h"
#include "glitz-wgl.h"
#include <GL/gl.h>
#ifdef USE_MESA
#define ChoosePixelFormat wglChoosePixelFormat
#define DescribePixelFormat wglDescribePixelFormat
#define GetPixelFormat wglGetPixelFormat
#define SetPixelFormat wglSetPixelFormat
#define SwapBuffers wglSwapBuffers
#endif
#include "glitz_wglext.h"
#define GLITZ_WGL_FEATURE_PIXEL_FORMAT_MASK (1L << 0)
#define GLITZ_WGL_FEATURE_PBUFFER_MASK (1L << 1)
#define GLITZ_WGL_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2)
/* wglGetProcAddress is always present */
#define GLITZ_WGL_FEATURE_MULTISAMPLE_MASK (1L << 4)
#define GLITZ_WGL_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5)
typedef struct _glitz_wgl_drawable glitz_wgl_drawable_t;
typedef struct _glitz_wgl_screen_info_t glitz_wgl_screen_info_t;
typedef struct _glitz_wgl_static_proc_address_list_t {
glitz_wgl_get_pixel_format_attrib_iv_t get_pixel_format_attrib_iv;
glitz_wgl_choose_pixel_format_t choose_pixel_format;
glitz_wgl_create_pbuffer_t create_pbuffer;
glitz_wgl_get_pbuffer_dc_t get_pbuffer_dc;
glitz_wgl_release_pbuffer_dc_t release_pbuffer_dc;
glitz_wgl_destroy_pbuffer_t destroy_pbuffer;
glitz_wgl_query_pbuffer_t query_pbuffer;
glitz_wgl_make_context_current_t make_context_current;
} glitz_wgl_static_proc_address_list_t;
typedef struct _glitz_wgl_thread_info_t {
glitz_wgl_screen_info_t *screen;
char *gl_library;
HMODULE dlhand;
} glitz_wgl_thread_info_t;
typedef struct _glitz_wgl_context_info_t {
glitz_wgl_drawable_t *drawable;
glitz_surface_t *surface;
glitz_constraint_t constraint;
} glitz_wgl_context_info_t;
typedef struct _glitz_wgl_context_t {
glitz_context_t base;
HGLRC context;
glitz_format_id_t id;
int pixel_format;
glitz_backend_t backend;
glitz_gl_int_t max_viewport_dims[2];
glitz_bool_t initialized;
} glitz_wgl_context_t;
struct _glitz_wgl_screen_info_t {
glitz_wgl_thread_info_t *thread_info;
int drawables;
glitz_drawable_format_t *formats;
int *format_ids;
int n_formats;
glitz_wgl_context_t **contexts;
int n_contexts;
glitz_wgl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE];
int context_stack_size;
/* root_context is used only for sharing a single display-list space
* amont the Glitz rendering contexts. Nothing is ever actually
* rendered into it. The related root_dc and root_window are kept
* around only for proper destruction.
*/
HGLRC root_context;
HDC root_dc;
HWND root_window;
unsigned long wgl_feature_mask;
glitz_gl_float_t wgl_version;
glitz_wgl_static_proc_address_list_t wgl;
glitz_program_map_t program_map;
};
struct _glitz_wgl_drawable {
glitz_drawable_t base;
glitz_wgl_screen_info_t *screen_info;
glitz_wgl_context_t *context;
HWND window;
HDC dc;
HPBUFFERARB pbuffer;
};
extern void __internal_linkage
glitz_wgl_query_extensions (glitz_wgl_screen_info_t *screen_info,
glitz_gl_float_t wgl_version);
extern glitz_wgl_screen_info_t *__internal_linkage
glitz_wgl_screen_info_get (void);
extern glitz_function_pointer_t __internal_linkage
glitz_wgl_get_proc_address (const char *name,
void *closure);
extern glitz_wgl_context_t *__internal_linkage
glitz_wgl_context_get (glitz_wgl_screen_info_t *screen_info,
HDC dc,
glitz_drawable_format_t *format);
extern void __internal_linkage
glitz_wgl_context_destroy (glitz_wgl_screen_info_t *screen_info,
glitz_wgl_context_t *context);
extern void __internal_linkage
glitz_wgl_query_formats (glitz_wgl_screen_info_t *screen_info);
extern HPBUFFERARB __internal_linkage
glitz_wgl_pbuffer_create (glitz_wgl_screen_info_t *screen_info,
int pixel_format,
unsigned int width,
unsigned int height,
HDC *dcp);
extern void __internal_linkage
glitz_wgl_pbuffer_destroy (glitz_wgl_screen_info_t *screen_info,
HPBUFFERARB pbuffer,
HDC dc);
extern glitz_drawable_t *__internal_linkage
glitz_wgl_create_pbuffer (void *abstract_templ,
glitz_drawable_format_t *format,
unsigned int width,
unsigned int height);
extern void __internal_linkage
glitz_wgl_push_current (void *abstract_drawable,
glitz_surface_t *surface,
glitz_constraint_t constraint);
extern glitz_surface_t *__internal_linkage
glitz_wgl_pop_current (void *abstract_drawable);
extern glitz_status_t __internal_linkage
glitz_wgl_make_current_read (void *abstract_surface);
extern void __internal_linkage
glitz_wgl_destroy (void *abstract_drawable);
extern void __internal_linkage
glitz_wgl_swap_buffers (void *abstract_drawable);
extern void __internal_linkage
glitz_wgl_print_win32_error_string (int error_code);
extern void __internal_linkage
glitz_wgl_win32_api_failed (const char *api);
#endif /* GLITZ_WGLINT_H_INCLUDED */