s_blend.c revision 77df88727cb0a423dd5cb41498c2302d9df4fce7
177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul/* $Id: s_blend.c,v 1.24 2002/08/07 00:45:07 brianp Exp $ */
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
559235bd5da794557613463bc942de0c634d2d961Brian Paul * Version:  4.1
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "glheader.h"
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "context.h"
316b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul#include "colormac.h"
32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "macros.h"
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alphabuf.h"
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_blend.h"
36cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
40cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#if defined(USE_MMX_ASM)
41cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/mmx.h"
42cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "X86/common_x86_asm.h"
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI _ASMAPI
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define _BLENDAPI
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
48cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
5059235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ZERO, GL_ONE)
5159235bd5da794557613463bc942de0c634d2d961Brian Paul */
5259235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
5359235bd5da794557613463bc942de0c634d2d961Brian Paulblend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
5459235bd5da794557613463bc942de0c634d2d961Brian Paul            GLchan rgba[][4], CONST GLchan dest[][4] )
5559235bd5da794557613463bc942de0c634d2d961Brian Paul{
5612a1024d9d003afe1212cc48af04dac81c034299Karl Schultz   GLuint i;
5759235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
5859235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendSrcRGB==GL_ZERO);
5959235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
6059235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
6159235bd5da794557613463bc942de0c634d2d961Brian Paul
6259235bd5da794557613463bc942de0c634d2d961Brian Paul   for (i = 0; i < n; i++) {
6359235bd5da794557613463bc942de0c634d2d961Brian Paul      if (mask[i]) {
646b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         COPY_CHAN4( rgba[i], dest[i] );
6559235bd5da794557613463bc942de0c634d2d961Brian Paul      }
6659235bd5da794557613463bc942de0c634d2d961Brian Paul   }
6759235bd5da794557613463bc942de0c634d2d961Brian Paul}
6859235bd5da794557613463bc942de0c634d2d961Brian Paul
6959235bd5da794557613463bc942de0c634d2d961Brian Paul
7059235bd5da794557613463bc942de0c634d2d961Brian Paul/*
7159235bd5da794557613463bc942de0c634d2d961Brian Paul * Special case for glBlendFunc(GL_ONE, GL_ZERO)
7259235bd5da794557613463bc942de0c634d2d961Brian Paul */
7359235bd5da794557613463bc942de0c634d2d961Brian Paulstatic void _BLENDAPI
7459235bd5da794557613463bc942de0c634d2d961Brian Paulblend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
7559235bd5da794557613463bc942de0c634d2d961Brian Paul               GLchan rgba[][4], CONST GLchan dest[][4] )
7659235bd5da794557613463bc942de0c634d2d961Brian Paul{
7759235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
7859235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
7959235bd5da794557613463bc942de0c634d2d961Brian Paul   ASSERT(ctx->Color.BlendDstRGB==GL_ZERO);
8059235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) ctx;
8159235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) n;
8259235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) mask;
8359235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) rgba;
8459235bd5da794557613463bc942de0c634d2d961Brian Paul   (void) dest;
8559235bd5da794557613463bc942de0c634d2d961Brian Paul}
8659235bd5da794557613463bc942de0c634d2d961Brian Paul
8759235bd5da794557613463bc942de0c634d2d961Brian Paul
8859235bd5da794557613463bc942de0c634d2d961Brian Paul/*
89e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Common transparency blending mode.
90e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                    GLchan rgba[][4], CONST GLchan dest[][4] )
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
98e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
99e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
103e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         const GLint t = rgba[i][ACOMP];  /* t in [0, CHAN_MAX] */
104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (t == 0) {
105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 0% alpha */
106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = dest[i][RCOMP];
107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = dest[i][GCOMP];
108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = dest[i][BCOMP];
109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = dest[i][ACOMP];
110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (t == CHAN_MAX) {
112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* 100% alpha, no-op */
113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if 0
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is pretty close, but Glean complains */
117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s + 1) >> 8;
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8;
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8;
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#elif 0
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This is slower but satisfies Glean */
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint s = CHAN_MAX - t;
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255;
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255;
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255;
128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255;
129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#if CHAN_BITS == 8
131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* This satisfies Glean and should be reasonably fast */
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* Contributed by Nathan Hand */
13317b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul#if 0
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define DIV255(X)  (((X) << 8) + (X) + 256) >> 16
13517b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul#else
13617b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul	    GLint temp;
13717b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul#define DIV255(X)  (temp = (X), ((temp << 8) + temp + 256) >> 16)
13817b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul#endif
13917b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
14017b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
14117b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
14217b7cc4caeeb8f3daaf417d417e7e3a9a5d639d1Brian Paul            const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
1436b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul
144e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DIV255
14501915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#elif CHAN_BITS == 16
14601915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
147b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLint r = (GLint) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
148b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLint g = (GLint) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
149b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLint b = (GLint) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
150b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLint a = (GLint) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
15101915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul#else /* CHAN_BITS == 32 */
15201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul            const GLfloat tt = (GLfloat) t / CHAN_MAXF;
153b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP];
154b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP];
155b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP];
156b63e8556fa9655bdfcc69fa04663e854f7fb2fbdBrian Paul            const GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP];
157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(r <= CHAN_MAX);
160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(g <= CHAN_MAX);
161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(b <= CHAN_MAX);
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            ASSERT(a <= CHAN_MAX);
163e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][RCOMP] = (GLchan) r;
164e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][GCOMP] = (GLchan) g;
165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][BCOMP] = (GLchan) b;
166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            rgba[i][ACOMP] = (GLchan) a;
167e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
168e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
169e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
171e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
175e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Add src and dest.
176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
177e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
179e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
181e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
182e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
184e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
185e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
186e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
187e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
188e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
1896b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul#if CHAN_TYPE == GL_FLOAT
1906b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         GLfloat r = rgba[i][RCOMP] + dest[i][RCOMP];
1916b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         GLfloat g = rgba[i][GCOMP] + dest[i][GCOMP];
1926b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         GLfloat b = rgba[i][BCOMP] + dest[i][BCOMP];
1936b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         GLfloat a = rgba[i][ACOMP] + dest[i][ACOMP];
1946b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAXF );
1956b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAXF );
1966b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAXF );
1976b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul         rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAXF );
1986b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul#else
199e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
200e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
201e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
203e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
204e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
205e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
206e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
2076b50a004ffb885dd86dd611979348bdf69b1151cBrian Paul#endif
208e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
209e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
210e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
211e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
213e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
214e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
215e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend min function  (for GL_EXT_blend_minmax)
216e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
219e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
220e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
224e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
233e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Blend max function  (for GL_EXT_blend_minmax)
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell           GLchan rgba[][4], CONST GLchan dest[][4] )
243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
258e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Modulate:  result = src * dest
262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
263e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                GLchan rgba[][4], CONST GLchan dest[][4] )
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   (void) ctx;
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
272f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#if CHAN_TYPE == GL_FLOAT
273f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
274f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
275f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
276f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul         rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
277d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul#elif CHAN_TYPE == GL_UNSIGNED_SHORT
278d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
279d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
280d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
281d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
282d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         rgba[i][RCOMP] = (GLchan) r;
283d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         rgba[i][GCOMP] = (GLchan) g;
284d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         rgba[i][BCOMP] = (GLchan) b;
285d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         rgba[i][ACOMP] = (GLchan) a;
286f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#else
287d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 255) >> 8;
288d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 255) >> 8;
289d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 255) >> 8;
290d5c94ef40d9dfef9ad4ecaa56218150f903014e3Brian Paul         GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 255) >> 8;
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) r;
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) g;
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) b;
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) a;
295f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#endif
296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * General case blend pixels.
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  n - number of pixels
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *         mask - the usual write mask
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * In/Out:  rgba - the incoming and modified pixels
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Input:  dest - the pixels from the dest color buffer
308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void _BLENDAPI
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellblend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               GLchan rgba[][4], CONST GLchan dest[][4] )
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat rscale = 1.0F / CHAN_MAXF;
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat gscale = 1.0F / CHAN_MAXF;
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat bscale = 1.0F / CHAN_MAXF;
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat ascale = 1.0F / CHAN_MAXF;
317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint i;
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (i=0;i<n;i++) {
320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (mask[i]) {
321e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#if CHAN_TYPE == GL_FLOAT
322e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         GLfloat Rs, Gs, Bs, As;  /* Source colors */
323e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         GLfloat Rd, Gd, Bd, Ad;  /* Dest colors */
324e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#else
325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rs, Gs, Bs, As;  /* Source colors */
326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLint Rd, Gd, Bd, Ad;  /* Dest colors */
327e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#endif
328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat sR, sG, sB, sA;  /* Source scaling */
329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dR, dG, dB, dA;  /* Dest scaling */
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat r, g, b, a;
331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Color */
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rs = rgba[i][RCOMP];
334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gs = rgba[i][GCOMP];
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bs = rgba[i][BCOMP];
336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         As = rgba[i][ACOMP];
337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Frame buffer color */
339e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Rd = dest[i][RCOMP];
340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Gd = dest[i][GCOMP];
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Bd = dest[i][BCOMP];
342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         Ad = dest[i][ACOMP];
343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source RGB factor */
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcRGB) {
346e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 0.0F;
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F;
351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
353e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rd * rscale;
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gd * gscale;
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bd * bscale;
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
358e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rd * rscale;
359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gd * gscale;
360e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bd * bscale;
361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
362e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) As * ascale;
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = (GLfloat) Ad * ascale;
370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (As < CHAN_MAX - Ad) {
376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = (GLfloat) As * ascale;
377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = ctx->Color.BlendColor[0];
384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = ctx->Color.BlendColor[1];
385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = ctx->Color.BlendColor[2];
386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - ctx->Color.BlendColor[0];
389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - ctx->Color.BlendColor[1];
390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - ctx->Color.BlendColor[2];
391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
393e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = ctx->Color.BlendColor[3];
394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
395e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = (GLfloat) Rs * rscale;
400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = (GLfloat) Gs * gscale;
401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = (GLfloat) Bs * bscale;
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sR = 1.0F - (GLfloat) Rs * rscale;
405e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sG = 1.0F - (GLfloat) Gs * gscale;
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sB = 1.0F - (GLfloat) Bs * bscale;
407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
41008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
41159235bd5da794557613463bc942de0c634d2d961Brian Paul               return;
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Source Alpha factor */
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendSrcA) {
416e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F;
421e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR:
423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) Ad * ascale;
424e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR:
426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
427e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
428e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
431e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
432e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
433e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
435e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA =(GLfloat) Ad * ascale;
436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) Ad * ascale;
439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA_SATURATE:
441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0;
442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = ctx->Color.BlendColor[3];
451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
453e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - ctx->Color.BlendColor[3];
454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR: /* GL_NV_blend_square */
456e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = (GLfloat) As * ascale;
457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 1.0F - (GLfloat) As * ascale;
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               sA = 0.0F;
46408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend source A factor in do_blend");
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest RGB factor */
468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstRGB) {
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F;
474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rs * rscale;
477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gs * gscale;
478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bs * bscale;
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rs * rscale;
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gs * gscale;
483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bs * bscale;
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) As * ascale;
487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
489e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = (GLfloat) Ad * ascale;
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = ctx->Color.BlendColor[0];
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = ctx->Color.BlendColor[1];
500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = ctx->Color.BlendColor[2];
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - ctx->Color.BlendColor[0];
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - ctx->Color.BlendColor[1];
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - ctx->Color.BlendColor[2];
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = ctx->Color.BlendColor[3];
509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = (GLfloat) Rd * rscale;
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = (GLfloat) Gd * gscale;
516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = (GLfloat) Bd * bscale;
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = 1.0F - (GLfloat) Rd * rscale;
520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dG = 1.0F - (GLfloat) Gd * gscale;
521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dB = 1.0F - (GLfloat) Bd * bscale;
522e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
523e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
524e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
525e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dR = dG = dB = 0.0F;
52608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Dest Alpha factor */
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         switch (ctx->Color.BlendDstA) {
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ZERO:
532e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE:
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F;
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
537e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_COLOR:
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_COLOR:
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) As * ascale;
542e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_SRC_ALPHA:
544e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) As * ascale;
545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_SRC_ALPHA:
547e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
548e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
549e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_ALPHA:
550e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
551e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
552e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_ALPHA:
553e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
554e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
555e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_COLOR:
556e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
557e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
558e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_COLOR:
559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
561e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_CONSTANT_ALPHA:
562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = ctx->Color.BlendColor[3];
563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_CONSTANT_ALPHA:
565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - ctx->Color.BlendColor[3];
566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_DST_COLOR: /* GL_NV_blend_square */
568e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = (GLfloat) Ad * ascale;
569e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
570e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
571e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 1.0F - (GLfloat) Ad * ascale;
572e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               break;
573e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            default:
574e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* this should never happen */
575e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dA = 0.0F;
57608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul               _mesa_problem(ctx, "Bad blend dest A factor in do_blend");
57759235bd5da794557613463bc942de0c634d2d961Brian Paul               return;
578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Due to round-off problems we have to clamp against zero. */
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Optimization: we don't have to do this for all src & dst factors */
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dA < 0.0F)  dA = 0.0F;
583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dR < 0.0F)  dR = 0.0F;
584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dG < 0.0F)  dG = 0.0F;
585e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (dB < 0.0F)  dB = 0.0F;
586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sA < 0.0F)  sA = 0.0F;
587e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sR < 0.0F)  sR = 0.0F;
588e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sG < 0.0F)  sG = 0.0F;
589e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (sB < 0.0F)  sB = 0.0F;
590e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
591e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sR <= 1.0 );
592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sG <= 1.0 );
593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sB <= 1.0 );
594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( sA <= 1.0 );
595e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dR <= 1.0 );
596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dG <= 1.0 );
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dB <= 1.0 );
598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         ASSERT( dA <= 1.0 );
599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* compute blended color */
601e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#if CHAN_TYPE == GL_FLOAT
602e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
603e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            r = Rs * sR + Rd * dR;
604e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            g = Gs * sG + Gd * dG;
605e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            b = Bs * sB + Bd * dB;
606e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            a = As * sA + Ad * dA;
607e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         }
608e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
609e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            r = Rs * sR - Rd * dR;
610e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            g = Gs * sG - Gd * dG;
611e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            b = Bs * sB - Bd * dB;
612e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            a = As * sA - Ad * dA;
613e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         }
614e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
615e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            r = Rd * dR - Rs * sR;
616e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            g = Gd * dG - Gs * sG;
617e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            b = Bd * dB - Bs * sB;
618e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            a = Ad * dA - As * sA;
619e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         }
620e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         else {
621e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            /* should never get here */
622e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            r = g = b = a = 0.0F;  /* silence uninitialized var warning */
623e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
624e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         }
625e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul
626e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         /* final clamping */
627e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         rgba[i][RCOMP] = CLAMP( r, 0.0F, CHAN_MAXF );
628e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         rgba[i][GCOMP] = CLAMP( g, 0.0F, CHAN_MAXF );
629e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         rgba[i][BCOMP] = CLAMP( b, 0.0F, CHAN_MAXF );
630e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul         rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
631e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#else
632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
633e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR + Rd * dR + 0.5F;
634e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG + Gd * dG + 0.5F;
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB + Bd * dB + 0.5F;
636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA + Ad * dA + 0.5F;
637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rs * sR - Rd * dR + 0.5F;
640e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gs * sG - Gd * dG + 0.5F;
641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bs * sB - Bd * dB + 0.5F;
642e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = As * sA - Ad * dA + 0.5F;
643e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
644e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = Rd * dR - Rs * sR + 0.5F;
646e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            g = Gd * dG - Gs * sG + 0.5F;
647e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            b = Bd * dB - Bs * sB + 0.5F;
648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            a = Ad * dA - As * sA + 0.5F;
649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
650e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
651e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* should never get here */
652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            r = g = b = a = 0.0F;  /* silence uninitialized var warning */
65308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
655e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* final clamping */
657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF );
658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF );
659e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF );
660e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );
661e201bef913bbb869e9c4012fcfff2406e9d55393Brian Paul#endif
662e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
663e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
664e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
668e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
670e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
671e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Analyze current blending parameters to pick fastest blending function.
672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Result: the ctx->Color.BlendFunc pointer is updated.
673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
674cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwellvoid _swrast_choose_blend_func( GLcontext *ctx )
675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum eq = ctx->Color.BlendEquation;
677e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcRGB = ctx->Color.BlendSrcRGB;
678e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstRGB = ctx->Color.BlendDstRGB;
679e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum srcA = ctx->Color.BlendSrcA;
680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLenum dstA = ctx->Color.BlendDstA;
681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (srcRGB != srcA || dstRGB != dstA) {
683cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
685e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
6869add9a21d8c51ee4238169265541fa9a40f0a8b0Brian Paul            && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
6879add9a21d8c51ee4238169265541fa9a40f0a8b0Brian Paul#if defined(USE_MMX_ASM)
688cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      if ( cpu_has_mmx ) {
68959235bd5da794557613463bc942de0c634d2d961Brian Paul         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
690cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      }
691cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      else
692cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#endif
693cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	 SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
694e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
695e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
6960c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca#if defined(USE_MMX_ASM)
6970c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca      if ( cpu_has_mmx ) {
6980c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add;
6990c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca      }
7000c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca      else
7010c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca#endif
7020c527ab0546eb1de9ee10cc31bc386a40e6b3f98José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
703e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
704e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
705cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
706cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ||
707cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	    ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
708cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell	     && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
709533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca#if defined(USE_MMX_ASM)
710533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca      if ( cpu_has_mmx ) {
711533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate;
712533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca      }
713533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca      else
714533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca#endif
715533e88824af9f60a926e7b70ddd40ad1386be686José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
716e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
717e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MIN_EXT) {
7183fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca#if defined(USE_MMX_ASM)
7193fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      if ( cpu_has_mmx ) {
7203fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min;
7213fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      }
7223fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      else
7233fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca#endif
7243fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
726e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (eq==GL_MAX_EXT) {
7273fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca#if defined(USE_MMX_ASM)
7283fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      if ( cpu_has_mmx ) {
7293fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max;
7303fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      }
7313fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca      else
7323fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca#endif
7333fe2bb8933c15a7091838fd982dbad402fe6ad43José Fonseca         SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
734e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
73559235bd5da794557613463bc942de0c634d2d961Brian Paul   else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
73659235bd5da794557613463bc942de0c634d2d961Brian Paul      SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
73759235bd5da794557613463bc942de0c634d2d961Brian Paul   }
73859235bd5da794557613463bc942de0c634d2d961Brian Paul   else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
73959235bd5da794557613463bc942de0c634d2d961Brian Paul      SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace;
74059235bd5da794557613463bc942de0c634d2d961Brian Paul   }
741e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
742cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
743e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
744e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
745e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
746e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
747e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
748e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
749e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Apply the blending operator to a span of pixels.
750733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * We can handle horizontal runs of pixels (spans) or arrays of x/y
751733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul * pixel coordinates.
752e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
753e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
754733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
755733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                  GLchan rgba[][4] )
756e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
757733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
758733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   GLchan framebuffer[MAX_WIDTH][4];
759e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
760c02861778493ca65508e4dbbc2b907751811c845Brian Paul   ASSERT(span->end <= MAX_WIDTH);
761733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
762733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   ASSERT(!ctx->Color.ColorLogicOpEnabled);
763e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
764e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Read span of current frame buffer pixels */
765733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   if (span->arrayMask & SPAN_XY) {
766733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* array of x/y pixel coords */
767733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      (*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
76877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                        span->array->x, span->array->y,
76977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                        framebuffer, span->array->mask );
770733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      if (swrast->_RasterMask & ALPHABUF_BIT) {
77177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         _mesa_read_alpha_pixels( ctx, span->end,
77277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                  span->array->x, span->array->y,
77377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul                                  framebuffer, span->array->mask );
774733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      }
775733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
776733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   else {
777733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* horizontal run of pixels */
778733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      _mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
779733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul                            span->x, span->y, framebuffer );
780733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
781e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
78277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, rgba,
783733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul				   (const GLchan (*)[4]) framebuffer );
784e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
785