зеркало из https://github.com/mozilla/pjs.git
cairo landing: adding glitz
This commit is contained in:
Родитель
ea2799380f
Коммит
afb71d6ee3
|
@ -0,0 +1,2 @@
|
|||
David Reveman <davidr@novell.com>
|
||||
Peter Nilsson <c99pnn@cs.umu.se>
|
|
@ -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.
|
|
@ -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 */
|
|
@ -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
|
|
@ -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, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&dn, 3.0f, ¶ms, &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, ¶ms, &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, ¶ms, &n_params);
|
||||
glitz_clamp_value (&radius, 0.0f, 1024.0f);
|
||||
|
||||
_glitz_filter_params_set (&sigma, radius / 2.0f, ¶ms, &n_params);
|
||||
glitz_clamp_value (&sigma, 0.0f, 1024.0f);
|
||||
|
||||
_glitz_filter_params_set (&alpha, radius, ¶ms, &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, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&start_y, 0.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&stop_x, 1.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&stop_y, 0.0f, ¶ms, &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, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&vecs->v[1], 0.5f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&r0, 0.0f, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&r1, 0.5f, ¶ms, &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, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&vecs[i].v[0], x_default, ¶ms, &n_params);
|
||||
_glitz_filter_params_set (&vecs[i].v[1], y_default, ¶ms, &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 = ®ion->extents;
|
||||
region->n_box = 1;
|
||||
|
||||
return GLITZ_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (BOX_CLOSE_TO_BOX (ubox, ®ion->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 (®ion->extents, box, new_box);
|
||||
region->box = ®ion->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 (®ion->extents, ®ion->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 (®ion->extents, ®ion->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 */
|
Загрузка…
Ссылка в новой задаче