1 /* $Id: blend.c,v 1.2 1999/08/19 15:48:01 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 #include "GL/xf86glx.h"
49 void gl_BlendFunc( GLcontext
*ctx
, GLenum sfactor
, GLenum dfactor
)
51 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glBlendFunc");
53 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
54 fprintf(stderr
, "glBlendFunc %s %s\n",
55 gl_lookup_enum_by_nr(sfactor
),
56 gl_lookup_enum_by_nr(dfactor
));
62 case GL_ONE_MINUS_DST_COLOR
:
64 case GL_ONE_MINUS_SRC_ALPHA
:
66 case GL_ONE_MINUS_DST_ALPHA
:
67 case GL_SRC_ALPHA_SATURATE
:
68 case GL_CONSTANT_COLOR
:
69 case GL_ONE_MINUS_CONSTANT_COLOR
:
70 case GL_CONSTANT_ALPHA
:
71 case GL_ONE_MINUS_CONSTANT_ALPHA
:
72 ctx
->Color
.BlendSrcRGB
= ctx
->Color
.BlendSrcA
= sfactor
;
75 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(sfactor)" );
83 case GL_ONE_MINUS_SRC_COLOR
:
85 case GL_ONE_MINUS_SRC_ALPHA
:
87 case GL_ONE_MINUS_DST_ALPHA
:
88 case GL_CONSTANT_COLOR
:
89 case GL_ONE_MINUS_CONSTANT_COLOR
:
90 case GL_CONSTANT_ALPHA
:
91 case GL_ONE_MINUS_CONSTANT_ALPHA
:
92 ctx
->Color
.BlendDstRGB
= ctx
->Color
.BlendDstA
= dfactor
;
95 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFunc(dfactor)" );
99 if (ctx
->Driver
.BlendFunc
) {
100 (*ctx
->Driver
.BlendFunc
)( ctx
, sfactor
, dfactor
);
103 ctx
->Color
.BlendFunc
= NULL
;
104 ctx
->NewState
|= NEW_RASTER_OPS
;
108 /* GL_INGR_blend_func_separate */
110 gl_BlendFuncSeparate( GLcontext
*ctx
, GLenum sfactorRGB
, GLenum dfactorRGB
,
111 GLenum sfactorA
, GLenum dfactorA
)
113 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glBlendFuncSeparate");
115 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
116 fprintf(stderr
, "glBlendFuncSeperate %s %s %s %s\n",
117 gl_lookup_enum_by_nr(sfactorRGB
),
118 gl_lookup_enum_by_nr(dfactorRGB
),
119 gl_lookup_enum_by_nr(sfactorA
),
120 gl_lookup_enum_by_nr(dfactorA
));
122 switch (sfactorRGB
) {
126 case GL_ONE_MINUS_DST_COLOR
:
128 case GL_ONE_MINUS_SRC_ALPHA
:
130 case GL_ONE_MINUS_DST_ALPHA
:
131 case GL_SRC_ALPHA_SATURATE
:
132 case GL_CONSTANT_COLOR
:
133 case GL_ONE_MINUS_CONSTANT_COLOR
:
134 case GL_CONSTANT_ALPHA
:
135 case GL_ONE_MINUS_CONSTANT_ALPHA
:
136 ctx
->Color
.BlendSrcRGB
= sfactorRGB
;
139 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorRGB)" );
143 switch (dfactorRGB
) {
147 case GL_ONE_MINUS_SRC_COLOR
:
149 case GL_ONE_MINUS_SRC_ALPHA
:
151 case GL_ONE_MINUS_DST_ALPHA
:
152 case GL_CONSTANT_COLOR
:
153 case GL_ONE_MINUS_CONSTANT_COLOR
:
154 case GL_CONSTANT_ALPHA
:
155 case GL_ONE_MINUS_CONSTANT_ALPHA
:
156 ctx
->Color
.BlendDstRGB
= dfactorRGB
;
159 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorRGB)" );
167 case GL_ONE_MINUS_DST_COLOR
:
169 case GL_ONE_MINUS_SRC_ALPHA
:
171 case GL_ONE_MINUS_DST_ALPHA
:
172 case GL_SRC_ALPHA_SATURATE
:
173 case GL_CONSTANT_COLOR
:
174 case GL_ONE_MINUS_CONSTANT_COLOR
:
175 case GL_CONSTANT_ALPHA
:
176 case GL_ONE_MINUS_CONSTANT_ALPHA
:
177 ctx
->Color
.BlendSrcA
= sfactorA
;
180 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(sfactorA)" );
188 case GL_ONE_MINUS_SRC_COLOR
:
190 case GL_ONE_MINUS_SRC_ALPHA
:
192 case GL_ONE_MINUS_DST_ALPHA
:
193 case GL_CONSTANT_COLOR
:
194 case GL_ONE_MINUS_CONSTANT_COLOR
:
195 case GL_CONSTANT_ALPHA
:
196 case GL_ONE_MINUS_CONSTANT_ALPHA
:
197 ctx
->Color
.BlendDstA
= dfactorA
;
200 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendFuncSeparate(dfactorA)" );
204 ctx
->Color
.BlendFunc
= NULL
;
205 ctx
->NewState
|= NEW_RASTER_OPS
;
210 /* This is really an extension function! */
211 void gl_BlendEquation( GLcontext
*ctx
, GLenum mode
)
213 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glBlendEquation");
215 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
216 fprintf(stderr
, "glBlendEquation %s\n",
217 gl_lookup_enum_by_nr(mode
));
224 case GL_FUNC_ADD_EXT
:
225 case GL_FUNC_SUBTRACT_EXT
:
226 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
227 ctx
->Color
.BlendEquation
= mode
;
230 gl_error( ctx
, GL_INVALID_ENUM
, "glBlendEquation" );
234 /* This is needed to support 1.1's RGB logic ops AND
235 * 1.0's blending logicops.
237 if (mode
==GL_LOGIC_OP
&& ctx
->Color
.BlendEnabled
) {
238 ctx
->Color
.ColorLogicOpEnabled
= GL_TRUE
;
241 ctx
->Color
.ColorLogicOpEnabled
= GL_FALSE
;
244 ctx
->Color
.BlendFunc
= NULL
;
245 ctx
->NewState
|= NEW_RASTER_OPS
;
250 void gl_BlendColor( GLcontext
*ctx
, GLclampf red
, GLclampf green
,
251 GLclampf blue
, GLclampf alpha
)
253 ctx
->Color
.BlendColor
[0] = CLAMP( red
, 0.0, 1.0 );
254 ctx
->Color
.BlendColor
[1] = CLAMP( green
, 0.0, 1.0 );
255 ctx
->Color
.BlendColor
[2] = CLAMP( blue
, 0.0, 1.0 );
256 ctx
->Color
.BlendColor
[3] = CLAMP( alpha
, 0.0, 1.0 );
262 * Common transparency blending mode.
264 static void blend_transparency( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
265 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
268 ASSERT(ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
);
269 ASSERT(ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
);
270 ASSERT(ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
);
275 GLint t
= rgba
[i
][ACOMP
]; /* t in [0,255] */
277 rgba
[i
][RCOMP
] = dest
[i
][RCOMP
];
278 rgba
[i
][GCOMP
] = dest
[i
][GCOMP
];
279 rgba
[i
][BCOMP
] = dest
[i
][BCOMP
];
280 rgba
[i
][ACOMP
] = dest
[i
][ACOMP
];
287 GLint r
= (rgba
[i
][RCOMP
] * t
+ dest
[i
][RCOMP
] * s
) >> 8;
288 GLint g
= (rgba
[i
][GCOMP
] * t
+ dest
[i
][GCOMP
] * s
) >> 8;
289 GLint b
= (rgba
[i
][BCOMP
] * t
+ dest
[i
][BCOMP
] * s
) >> 8;
290 GLint a
= (rgba
[i
][ACOMP
] * t
+ dest
[i
][ACOMP
] * s
) >> 8;
309 static void blend_add( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
310 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
313 ASSERT(ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
);
314 ASSERT(ctx
->Color
.BlendSrcRGB
==GL_ONE
);
315 ASSERT(ctx
->Color
.BlendDstRGB
==GL_ONE
);
320 GLint r
= rgba
[i
][RCOMP
] + dest
[i
][RCOMP
];
321 GLint g
= rgba
[i
][GCOMP
] + dest
[i
][GCOMP
];
322 GLint b
= rgba
[i
][BCOMP
] + dest
[i
][BCOMP
];
323 GLint a
= rgba
[i
][ACOMP
] + dest
[i
][ACOMP
];
324 rgba
[i
][RCOMP
] = MIN2( r
, 255 );
325 rgba
[i
][GCOMP
] = MIN2( g
, 255 );
326 rgba
[i
][BCOMP
] = MIN2( b
, 255 );
327 rgba
[i
][ACOMP
] = MIN2( a
, 255 );
335 * Blend min function (for GL_EXT_blend_minmax)
337 static void blend_min( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
338 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
341 ASSERT(ctx
->Color
.BlendEquation
==GL_MIN_EXT
);
346 rgba
[i
][RCOMP
] = MIN2( rgba
[i
][RCOMP
], dest
[i
][RCOMP
] );
347 rgba
[i
][GCOMP
] = MIN2( rgba
[i
][GCOMP
], dest
[i
][GCOMP
] );
348 rgba
[i
][BCOMP
] = MIN2( rgba
[i
][BCOMP
], dest
[i
][BCOMP
] );
349 rgba
[i
][ACOMP
] = MIN2( rgba
[i
][ACOMP
], dest
[i
][ACOMP
] );
357 * Blend max function (for GL_EXT_blend_minmax)
359 static void blend_max( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
360 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
363 ASSERT(ctx
->Color
.BlendEquation
==GL_MAX_EXT
);
368 rgba
[i
][RCOMP
] = MAX2( rgba
[i
][RCOMP
], dest
[i
][RCOMP
] );
369 rgba
[i
][GCOMP
] = MAX2( rgba
[i
][GCOMP
], dest
[i
][GCOMP
] );
370 rgba
[i
][BCOMP
] = MAX2( rgba
[i
][BCOMP
], dest
[i
][BCOMP
] );
371 rgba
[i
][ACOMP
] = MAX2( rgba
[i
][ACOMP
], dest
[i
][ACOMP
] );
379 * Modulate: result = src * dest
381 static void blend_modulate( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
382 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
389 GLint r
= (rgba
[i
][RCOMP
] * dest
[i
][RCOMP
]) >> 8;
390 GLint g
= (rgba
[i
][GCOMP
] * dest
[i
][GCOMP
]) >> 8;
391 GLint b
= (rgba
[i
][BCOMP
] * dest
[i
][BCOMP
]) >> 8;
392 GLint a
= (rgba
[i
][ACOMP
] * dest
[i
][ACOMP
]) >> 8;
404 * General case blend pixels.
405 * Input: n - number of pixels
406 * mask - the usual write mask
407 * In/Out: rgba - the incoming and modified pixels
408 * Input: dest - the pixels from the dest color buffer
410 static void blend_general( GLcontext
*ctx
, GLuint n
, const GLubyte mask
[],
411 GLubyte rgba
[][4], CONST GLubyte dest
[][4] )
413 GLfloat rscale
= 1.0F
/ 255.0F
;
414 GLfloat gscale
= 1.0F
/ 255.0F
;
415 GLfloat bscale
= 1.0F
/ 255.0F
;
416 GLfloat ascale
= 1.0F
/ 255.0F
;
421 GLint Rs
, Gs
, Bs
, As
; /* Source colors */
422 GLint Rd
, Gd
, Bd
, Ad
; /* Dest colors */
423 GLfloat sR
, sG
, sB
, sA
; /* Source scaling */
424 GLfloat dR
, dG
, dB
, dA
; /* Dest scaling */
433 /* Frame buffer color */
439 /* Source RGB factor */
440 switch (ctx
->Color
.BlendSrcRGB
) {
448 sR
= (GLfloat
) Rd
* rscale
;
449 sG
= (GLfloat
) Gd
* gscale
;
450 sB
= (GLfloat
) Bd
* bscale
;
452 case GL_ONE_MINUS_DST_COLOR
:
453 sR
= 1.0F
- (GLfloat
) Rd
* rscale
;
454 sG
= 1.0F
- (GLfloat
) Gd
* gscale
;
455 sB
= 1.0F
- (GLfloat
) Bd
* bscale
;
458 sR
= sG
= sB
= (GLfloat
) As
* ascale
;
460 case GL_ONE_MINUS_SRC_ALPHA
:
461 sR
= sG
= sB
= (GLfloat
) 1.0F
- (GLfloat
) As
* ascale
;
464 sR
= sG
= sB
= (GLfloat
) Ad
* ascale
;
466 case GL_ONE_MINUS_DST_ALPHA
:
467 sR
= sG
= sB
= 1.0F
- (GLfloat
) Ad
* ascale
;
469 case GL_SRC_ALPHA_SATURATE
:
470 if (As
< 1.0F
- (GLfloat
) Ad
* ascale
) {
471 sR
= sG
= sB
= (GLfloat
) As
* ascale
;
474 sR
= sG
= sB
= 1.0F
- (GLfloat
) Ad
* ascale
;
477 case GL_CONSTANT_COLOR
:
478 sR
= ctx
->Color
.BlendColor
[0];
479 sG
= ctx
->Color
.BlendColor
[1];
480 sB
= ctx
->Color
.BlendColor
[2];
482 case GL_ONE_MINUS_CONSTANT_COLOR
:
483 sR
= 1.0F
- ctx
->Color
.BlendColor
[0];
484 sG
= 1.0F
- ctx
->Color
.BlendColor
[1];
485 sB
= 1.0F
- ctx
->Color
.BlendColor
[2];
487 case GL_CONSTANT_ALPHA
:
488 sR
= sG
= sB
= ctx
->Color
.BlendColor
[3];
490 case GL_ONE_MINUS_CONSTANT_ALPHA
:
491 sR
= sG
= sB
= 1.0F
- ctx
->Color
.BlendColor
[3];
494 /* this should never happen */
495 gl_problem(ctx
, "Bad blend source RGB factor in do_blend");
499 /* Source Alpha factor */
500 switch (ctx
->Color
.BlendSrcA
) {
508 sA
= (GLfloat
) Ad
* ascale
;
510 case GL_ONE_MINUS_DST_COLOR
:
511 sA
= 1.0F
- (GLfloat
) Ad
* ascale
;
514 sA
= (GLfloat
) As
* ascale
;
516 case GL_ONE_MINUS_SRC_ALPHA
:
517 sA
= (GLfloat
) 1.0F
- (GLfloat
) As
* ascale
;
520 sA
=(GLfloat
) Ad
* ascale
;
522 case GL_ONE_MINUS_DST_ALPHA
:
523 sA
= 1.0F
- (GLfloat
) Ad
* ascale
;
525 case GL_SRC_ALPHA_SATURATE
:
528 case GL_CONSTANT_COLOR
:
529 sA
= ctx
->Color
.BlendColor
[3];
531 case GL_ONE_MINUS_CONSTANT_COLOR
:
532 sA
= 1.0F
- ctx
->Color
.BlendColor
[3];
534 case GL_CONSTANT_ALPHA
:
535 sA
= ctx
->Color
.BlendColor
[3];
537 case GL_ONE_MINUS_CONSTANT_ALPHA
:
538 sA
= 1.0F
- ctx
->Color
.BlendColor
[3];
541 /* this should never happen */
542 gl_problem(ctx
, "Bad blend source A factor in do_blend");
545 /* Dest RGB factor */
546 switch (ctx
->Color
.BlendDstRGB
) {
554 dR
= (GLfloat
) Rs
* rscale
;
555 dG
= (GLfloat
) Gs
* gscale
;
556 dB
= (GLfloat
) Bs
* bscale
;
558 case GL_ONE_MINUS_SRC_COLOR
:
559 dR
= 1.0F
- (GLfloat
) Rs
* rscale
;
560 dG
= 1.0F
- (GLfloat
) Gs
* gscale
;
561 dB
= 1.0F
- (GLfloat
) Bs
* bscale
;
564 dR
= dG
= dB
= (GLfloat
) As
* ascale
;
566 case GL_ONE_MINUS_SRC_ALPHA
:
567 dR
= dG
= dB
= (GLfloat
) 1.0F
- (GLfloat
) As
* ascale
;
570 dR
= dG
= dB
= (GLfloat
) Ad
* ascale
;
572 case GL_ONE_MINUS_DST_ALPHA
:
573 dR
= dG
= dB
= 1.0F
- (GLfloat
) Ad
* ascale
;
575 case GL_CONSTANT_COLOR
:
576 dR
= ctx
->Color
.BlendColor
[0];
577 dG
= ctx
->Color
.BlendColor
[1];
578 dB
= ctx
->Color
.BlendColor
[2];
580 case GL_ONE_MINUS_CONSTANT_COLOR
:
581 dR
= 1.0F
- ctx
->Color
.BlendColor
[0];
582 dG
= 1.0F
- ctx
->Color
.BlendColor
[1];
583 dB
= 1.0F
- ctx
->Color
.BlendColor
[2];
585 case GL_CONSTANT_ALPHA
:
586 dR
= dG
= dB
= ctx
->Color
.BlendColor
[3];
588 case GL_ONE_MINUS_CONSTANT_ALPHA
:
589 dR
= dG
= dB
= 1.0F
- ctx
->Color
.BlendColor
[3] * ascale
;
592 /* this should never happen */
593 gl_problem(ctx
, "Bad blend dest RGB factor in do_blend");
596 /* Dest Alpha factor */
597 switch (ctx
->Color
.BlendDstA
) {
605 dA
= (GLfloat
) As
* ascale
;
607 case GL_ONE_MINUS_SRC_COLOR
:
608 dA
= 1.0F
- (GLfloat
) As
* ascale
;
611 dA
= (GLfloat
) As
* ascale
;
613 case GL_ONE_MINUS_SRC_ALPHA
:
614 dA
= (GLfloat
) 1.0F
- (GLfloat
) As
* ascale
;
617 dA
= (GLfloat
) Ad
* ascale
;
619 case GL_ONE_MINUS_DST_ALPHA
:
620 dA
= 1.0F
- (GLfloat
) Ad
* ascale
;
622 case GL_CONSTANT_COLOR
:
623 dA
= ctx
->Color
.BlendColor
[3];
625 case GL_ONE_MINUS_CONSTANT_COLOR
:
626 dA
= 1.0F
- ctx
->Color
.BlendColor
[3];
628 case GL_CONSTANT_ALPHA
:
629 dA
= ctx
->Color
.BlendColor
[3];
631 case GL_ONE_MINUS_CONSTANT_ALPHA
:
632 dA
= 1.0F
- ctx
->Color
.BlendColor
[3] * ascale
;
635 /* this should never happen */
636 gl_problem(ctx
, "Bad blend dest A factor in do_blend");
640 /* Due to round-off problems we have to clamp against zero. */
641 /* Optimization: we don't have to do this for all src & dst factors */
642 if (dA
< 0.0F
) dA
= 0.0F
;
643 if (dR
< 0.0F
) dR
= 0.0F
;
644 if (dG
< 0.0F
) dG
= 0.0F
;
645 if (dB
< 0.0F
) dB
= 0.0F
;
646 if (sA
< 0.0F
) sA
= 0.0F
;
647 if (sR
< 0.0F
) sR
= 0.0F
;
648 if (sG
< 0.0F
) sG
= 0.0F
;
649 if (sB
< 0.0F
) sB
= 0.0F
;
660 /* compute blended color */
661 if (ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
662 r
= Rs
* sR
+ Rd
* dR
;
663 g
= Gs
* sG
+ Gd
* dG
;
664 b
= Bs
* sB
+ Bd
* dB
;
665 a
= As
* sA
+ Ad
* dA
;
667 else if (ctx
->Color
.BlendEquation
==GL_FUNC_SUBTRACT_EXT
) {
668 r
= Rs
* sR
- Rd
* dR
;
669 g
= Gs
* sG
- Gd
* dG
;
670 b
= Bs
* sB
- Bd
* dB
;
671 a
= As
* sA
- Ad
* dA
;
673 else if (ctx
->Color
.BlendEquation
==GL_FUNC_REVERSE_SUBTRACT_EXT
) {
674 r
= Rd
* dR
- Rs
* sR
;
675 g
= Gd
* dG
- Gs
* sG
;
676 b
= Bd
* dB
- Bs
* sB
;
677 a
= Ad
* dA
- As
* sA
;
681 rgba
[i
][RCOMP
] = (GLint
) CLAMP( r
, 0.0F
, 255.0F
);
682 rgba
[i
][GCOMP
] = (GLint
) CLAMP( g
, 0.0F
, 255.0F
);
683 rgba
[i
][BCOMP
] = (GLint
) CLAMP( b
, 0.0F
, 255.0F
);
684 rgba
[i
][ACOMP
] = (GLint
) CLAMP( a
, 0.0F
, 255.0F
);
691 #if defined(USE_MMX_ASM)
693 #include "X86/common_x86asm.h"
698 * Analyze current blending parameters to pick fastest blending function.
699 * Result: the ctx->Color.BlendFunc pointer is updated.
701 static void set_blend_function( GLcontext
*ctx
)
703 const GLenum eq
= ctx
->Color
.BlendEquation
;
704 const GLenum srcRGB
= ctx
->Color
.BlendSrcRGB
;
705 const GLenum dstRGB
= ctx
->Color
.BlendDstRGB
;
706 const GLenum srcA
= ctx
->Color
.BlendSrcA
;
707 const GLenum dstA
= ctx
->Color
.BlendDstA
;
709 #if defined(USE_MMX_ASM)
710 /* Hmm. A table here would have 12^4 == way too many entries.
711 * Provide a hook for MMX instead.
713 if (gl_x86_cpu_features
& GL_CPU_MMX
) {
714 gl_mmx_set_blend_function (ctx
);
717 if (srcRGB
!= srcA
|| dstRGB
!= dstA
) {
718 ctx
->Color
.BlendFunc
= blend_general
;
720 else if (eq
==GL_FUNC_ADD_EXT
&& srcRGB
==GL_SRC_ALPHA
721 && dstRGB
==GL_ONE_MINUS_SRC_ALPHA
) {
722 ctx
->Color
.BlendFunc
= blend_transparency
;
724 else if (eq
==GL_FUNC_ADD_EXT
&& srcRGB
==GL_ONE
&& dstRGB
==GL_ONE
) {
725 ctx
->Color
.BlendFunc
= blend_add
;
727 else if (((eq
==GL_FUNC_ADD_EXT
|| eq
==GL_FUNC_REVERSE_SUBTRACT_EXT
)
728 && (srcRGB
==GL_ZERO
&& dstRGB
==GL_SRC_COLOR
))
730 ((eq
==GL_FUNC_ADD_EXT
|| eq
==GL_FUNC_SUBTRACT_EXT
)
731 && (srcRGB
==GL_DST_COLOR
&& dstRGB
==GL_ZERO
))) {
732 ctx
->Color
.BlendFunc
= blend_modulate
;
734 else if (eq
==GL_MIN_EXT
) {
735 ctx
->Color
.BlendFunc
= blend_min
;
737 else if (eq
==GL_MAX_EXT
) {
738 ctx
->Color
.BlendFunc
= blend_max
;
741 ctx
->Color
.BlendFunc
= blend_general
;
748 * Apply the blending operator to a span of pixels.
749 * Input: n - number of pixels in span
750 * x, y - location of leftmost pixel in span in window coords.
751 * mask - boolean mask indicating which pixels to blend.
752 * In/Out: rgba - pixel values
754 void gl_blend_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
755 GLubyte rgba
[][4], const GLubyte mask
[] )
757 GLubyte dest
[MAX_WIDTH
][4];
759 /* Check if device driver can do the work */
760 if (ctx
->Color
.BlendEquation
==GL_LOGIC_OP
&& !ctx
->Color
.SWLogicOpEnabled
) {
764 /* Read span of current frame buffer pixels */
765 gl_read_rgba_span( ctx
, n
, x
, y
, dest
);
767 if (!ctx
->Color
.BlendFunc
)
768 set_blend_function(ctx
);
770 (*ctx
->Color
.BlendFunc
)( ctx
, n
, mask
, rgba
, (const GLubyte (*)[4])dest
);
778 * Apply the blending operator to an array of pixels.
779 * Input: n - number of pixels in span
780 * x, y - array of pixel locations
781 * mask - boolean mask indicating which pixels to blend.
782 * In/Out: rgba - pixel values
784 void gl_blend_pixels( GLcontext
*ctx
,
785 GLuint n
, const GLint x
[], const GLint y
[],
786 GLubyte rgba
[][4], const GLubyte mask
[] )
788 GLubyte dest
[PB_SIZE
][4];
790 /* Check if device driver can do the work */
791 if (ctx
->Color
.BlendEquation
==GL_LOGIC_OP
&& !ctx
->Color
.SWLogicOpEnabled
) {
795 /* Read pixels from current color buffer */
796 (*ctx
->Driver
.ReadRGBAPixels
)( ctx
, n
, x
, y
, dest
, mask
);
797 if (ctx
->RasterMask
& ALPHABUF_BIT
) {
798 gl_read_alpha_pixels( ctx
, n
, x
, y
, dest
, mask
);
801 if (!ctx
->Color
.BlendFunc
)
802 set_blend_function(ctx
);
804 (*ctx
->Color
.BlendFunc
)( ctx
, n
, mask
, rgba
, (const GLubyte (*)[4])dest
);