ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

s_blend.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00038 #include "main/glheader.h"
00039 #include "main/context.h"
00040 #include "main/colormac.h"
00041 #include "main/macros.h"
00042 
00043 #include "s_blend.h"
00044 #include "s_context.h"
00045 #include "s_span.h"
00046 
00047 
00048 #if defined(USE_MMX_ASM)
00049 #include "x86/mmx.h"
00050 #include "x86/common_x86_asm.h"
00051 #define _BLENDAPI _ASMAPI
00052 #else
00053 #define _BLENDAPI
00054 #endif
00055 
00056 
00063 #define DIV255(X)  (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16)
00064 
00065 
00066 
00072 static void _BLENDAPI
00073 blend_noop(GLcontext *ctx, GLuint n, const GLubyte mask[],
00074            GLvoid *src, const GLvoid *dst, GLenum chanType)
00075 {
00076    GLint bytes;
00077 
00078    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00079    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00080    ASSERT(ctx->Color.BlendSrcRGB == GL_ZERO);
00081    ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
00082    (void) ctx;
00083 
00084    /* just memcpy */
00085    if (chanType == GL_UNSIGNED_BYTE)
00086       bytes = 4 * n * sizeof(GLubyte);
00087    else if (chanType == GL_UNSIGNED_SHORT)
00088       bytes = 4 * n * sizeof(GLushort);
00089    else
00090       bytes = 4 * n * sizeof(GLfloat);
00091 
00092    _mesa_memcpy(src, dst, bytes);
00093 }
00094 
00095 
00100 static void _BLENDAPI
00101 blend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[],
00102               GLvoid *src, const GLvoid *dst, GLenum chanType)
00103 {
00104    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00105    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00106    ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
00107    ASSERT(ctx->Color.BlendDstRGB == GL_ZERO);
00108    (void) ctx;
00109    (void) n;
00110    (void) mask;
00111    (void) src;
00112    (void) dst;
00113 }
00114 
00115 
00120 static void _BLENDAPI
00121 blend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
00122                          GLvoid *src, const GLvoid *dst, GLenum chanType)
00123 {
00124    GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00125    const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00126    GLuint i;
00127 
00128    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00129    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00130    ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
00131    ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
00132    ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
00133    ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
00134    ASSERT(chanType == GL_UNSIGNED_BYTE);
00135 
00136    (void) ctx;
00137 
00138    for (i = 0; i < n; i++) {
00139       if (mask[i]) {
00140          const GLint t = rgba[i][ACOMP];  /* t is in [0, 255] */
00141          if (t == 0) {
00142             /* 0% alpha */
00143             COPY_4UBV(rgba[i], dest[i]);
00144          }
00145          else if (t != 255) {
00146         GLint divtemp;
00147             const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
00148             const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
00149             const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
00150             const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP]; 
00151             ASSERT(r <= 255);
00152             ASSERT(g <= 255);
00153             ASSERT(b <= 255);
00154             ASSERT(a <= 255);
00155             rgba[i][RCOMP] = (GLubyte) r;
00156             rgba[i][GCOMP] = (GLubyte) g;
00157             rgba[i][BCOMP] = (GLubyte) b;
00158             rgba[i][ACOMP] = (GLubyte) a;
00159          }
00160       }
00161    }
00162 }
00163 
00164 
00165 static void _BLENDAPI
00166 blend_transparency_ushort(GLcontext *ctx, GLuint n, const GLubyte mask[],
00167                           GLvoid *src, const GLvoid *dst, GLenum chanType)
00168 {
00169    GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00170    const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00171    GLuint i;
00172 
00173    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00174    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00175    ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
00176    ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
00177    ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
00178    ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
00179    ASSERT(chanType == GL_UNSIGNED_SHORT);
00180 
00181    (void) ctx;
00182 
00183    for (i = 0; i < n; i++) {
00184       if (mask[i]) {
00185          const GLint t = rgba[i][ACOMP];
00186          if (t == 0) {
00187             /* 0% alpha */
00188             COPY_4V(rgba[i], dest[i]);
00189          }
00190          else if (t != 65535) {
00191             const GLfloat tt = (GLfloat) t / 65535.0F;
00192             GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
00193             GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
00194             GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
00195             GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
00196             ASSIGN_4V(rgba[i], r, g, b, a);
00197          }
00198       }
00199    }
00200 }
00201 
00202 
00203 static void _BLENDAPI
00204 blend_transparency_float(GLcontext *ctx, GLuint n, const GLubyte mask[],
00205                          GLvoid *src, const GLvoid *dst, GLenum chanType)
00206 {
00207    GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
00208    const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
00209    GLuint i;
00210 
00211    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00212    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00213    ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
00214    ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
00215    ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
00216    ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
00217    ASSERT(chanType == GL_FLOAT);
00218 
00219    (void) ctx;
00220 
00221    for (i = 0; i < n; i++) {
00222       if (mask[i]) {
00223          const GLfloat t = rgba[i][ACOMP];  /* t in [0, 1] */
00224          if (t == 0.0F) {
00225             /* 0% alpha */
00226             COPY_4V(rgba[i], dest[i]);
00227          }
00228          else if (t != 1.0F) {
00229             GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP];
00230             GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP];
00231             GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP];
00232             GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP];
00233             ASSIGN_4V(rgba[i], r, g, b, a);
00234          }
00235       }
00236    }
00237 }
00238 
00239 
00240 
00245 static void _BLENDAPI
00246 blend_add(GLcontext *ctx, GLuint n, const GLubyte mask[],
00247           GLvoid *src, const GLvoid *dst, GLenum chanType)
00248 {
00249    GLuint i;
00250 
00251    ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
00252    ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
00253    ASSERT(ctx->Color.BlendSrcRGB == GL_ONE);
00254    ASSERT(ctx->Color.BlendDstRGB == GL_ONE);
00255    (void) ctx;
00256 
00257    if (chanType == GL_UNSIGNED_BYTE) {
00258       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00259       const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00260       for (i=0;i<n;i++) {
00261          if (mask[i]) {
00262             GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
00263             GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
00264             GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
00265             GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
00266             rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 );
00267             rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 );
00268             rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 );
00269             rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 );
00270          }
00271       }
00272    }
00273    else if (chanType == GL_UNSIGNED_SHORT) {
00274       GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00275       const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00276       for (i=0;i<n;i++) {
00277          if (mask[i]) {
00278             GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
00279             GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
00280             GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
00281             GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
00282             rgba[i][RCOMP] = (GLshort) MIN2( r, 255 );
00283             rgba[i][GCOMP] = (GLshort) MIN2( g, 255 );
00284             rgba[i][BCOMP] = (GLshort) MIN2( b, 255 );
00285             rgba[i][ACOMP] = (GLshort) MIN2( a, 255 );
00286          }
00287       }
00288    }
00289    else {
00290       GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
00291       const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
00292       ASSERT(chanType == GL_FLOAT);
00293       for (i=0;i<n;i++) {
00294          if (mask[i]) {
00295             /* don't RGB clamp to max */
00296             rgba[i][RCOMP] += dest[i][RCOMP];
00297             rgba[i][GCOMP] += dest[i][GCOMP];
00298             rgba[i][BCOMP] += dest[i][BCOMP];
00299             rgba[i][ACOMP] += dest[i][ACOMP];
00300          }
00301       }
00302    }
00303 }
00304 
00305 
00306 
00311 static void _BLENDAPI
00312 blend_min(GLcontext *ctx, GLuint n, const GLubyte mask[],
00313           GLvoid *src, const GLvoid *dst, GLenum chanType)
00314 {
00315    GLuint i;
00316    ASSERT(ctx->Color.BlendEquationRGB == GL_MIN);
00317    ASSERT(ctx->Color.BlendEquationA == GL_MIN);
00318    (void) ctx;
00319 
00320    if (chanType == GL_UNSIGNED_BYTE) {
00321       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00322       const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00323       for (i=0;i<n;i++) {
00324          if (mask[i]) {
00325             rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
00326             rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
00327             rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
00328             rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
00329          }
00330       }
00331    }
00332    else if (chanType == GL_UNSIGNED_SHORT) {
00333       GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00334       const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00335       for (i=0;i<n;i++) {
00336          if (mask[i]) {
00337             rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
00338             rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
00339             rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
00340             rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
00341          }
00342       }
00343    }
00344    else {
00345       GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
00346       const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
00347       ASSERT(chanType == GL_FLOAT);
00348       for (i=0;i<n;i++) {
00349          if (mask[i]) {
00350             rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
00351             rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
00352             rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
00353             rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
00354          }
00355       }
00356    }
00357 }
00358 
00359 
00364 static void _BLENDAPI
00365 blend_max(GLcontext *ctx, GLuint n, const GLubyte mask[],
00366           GLvoid *src, const GLvoid *dst, GLenum chanType)
00367 {
00368    GLuint i;
00369    ASSERT(ctx->Color.BlendEquationRGB == GL_MAX);
00370    ASSERT(ctx->Color.BlendEquationA == GL_MAX);
00371    (void) ctx;
00372 
00373    if (chanType == GL_UNSIGNED_BYTE) {
00374       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00375       const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00376       for (i=0;i<n;i++) {
00377          if (mask[i]) {
00378             rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
00379             rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
00380             rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
00381             rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
00382          }
00383       }
00384    }
00385    else if (chanType == GL_UNSIGNED_SHORT) {
00386       GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00387       const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00388       for (i=0;i<n;i++) {
00389          if (mask[i]) {
00390             rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
00391             rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
00392             rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
00393             rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
00394          }
00395       }
00396    }
00397    else {
00398       GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
00399       const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
00400       ASSERT(chanType == GL_FLOAT);
00401       for (i=0;i<n;i++) {
00402          if (mask[i]) {
00403             rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
00404             rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
00405             rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
00406             rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
00407          }
00408       }
00409    }
00410 }
00411 
00412 
00413 
00418 static void _BLENDAPI
00419 blend_modulate(GLcontext *ctx, GLuint n, const GLubyte mask[],
00420                GLvoid *src, const GLvoid *dst, GLenum chanType)
00421 {
00422    GLuint i;
00423    (void) ctx;
00424 
00425    if (chanType == GL_UNSIGNED_BYTE) {
00426       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00427       const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00428       for (i=0;i<n;i++) {
00429          if (mask[i]) {
00430         GLint divtemp;
00431             rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]);
00432             rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]);
00433             rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]);
00434             rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]);
00435          }
00436       }
00437    }
00438    else if (chanType == GL_UNSIGNED_SHORT) {
00439       GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00440       const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00441       for (i=0;i<n;i++) {
00442          if (mask[i]) {
00443             rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
00444             rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
00445             rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
00446             rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
00447          }
00448       }
00449    }
00450    else {
00451       GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
00452       const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
00453       ASSERT(chanType == GL_FLOAT);
00454       for (i=0;i<n;i++) {
00455          if (mask[i]) {
00456             rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
00457             rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
00458             rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
00459             rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
00460          }
00461       }
00462    }
00463 }
00464 
00465 
00473 static void
00474 blend_general_float(GLcontext *ctx, GLuint n, const GLubyte mask[],
00475                     GLfloat rgba[][4], GLfloat dest[][4],
00476                     GLenum chanType)
00477 {
00478    GLuint i;
00479 
00480    for (i = 0; i < n; i++) {
00481       if (mask[i]) {
00482          /* Incoming/source Color */
00483          const GLfloat Rs = rgba[i][RCOMP];
00484          const GLfloat Gs = rgba[i][GCOMP];
00485          const GLfloat Bs = rgba[i][BCOMP];
00486          const GLfloat As = rgba[i][ACOMP];
00487 
00488          /* Frame buffer/dest color */
00489          const GLfloat Rd = dest[i][RCOMP];
00490          const GLfloat Gd = dest[i][GCOMP];
00491          const GLfloat Bd = dest[i][BCOMP];
00492          const GLfloat Ad = dest[i][ACOMP];
00493 
00494          GLfloat sR, sG, sB, sA;  /* Source factor */
00495          GLfloat dR, dG, dB, dA;  /* Dest factor */
00496          GLfloat r, g, b, a;      /* result color */
00497 
00498          /* XXX for the case of constant blend terms we could init
00499           * the sX and dX variables just once before the loop.
00500           */
00501 
00502          /* Source RGB factor */
00503          switch (ctx->Color.BlendSrcRGB) {
00504             case GL_ZERO:
00505                sR = sG = sB = 0.0F;
00506                break;
00507             case GL_ONE:
00508                sR = sG = sB = 1.0F;
00509                break;
00510             case GL_DST_COLOR:
00511                sR = Rd;
00512                sG = Gd;
00513                sB = Bd;
00514                break;
00515             case GL_ONE_MINUS_DST_COLOR:
00516                sR = 1.0F - Rd;
00517                sG = 1.0F - Gd;
00518                sB = 1.0F - Bd;
00519                break;
00520             case GL_SRC_ALPHA:
00521                sR = sG = sB = As;
00522                break;
00523             case GL_ONE_MINUS_SRC_ALPHA:
00524                sR = sG = sB = 1.0F - As;
00525                break;
00526             case GL_DST_ALPHA:
00527                sR = sG = sB = Ad;
00528                break;
00529             case GL_ONE_MINUS_DST_ALPHA:
00530                sR = sG = sB = 1.0F - Ad;
00531                break;
00532             case GL_SRC_ALPHA_SATURATE:
00533                if (As < 1.0F - Ad) {
00534                   sR = sG = sB = As;
00535                }
00536                else {
00537                   sR = sG = sB = 1.0F - Ad;
00538                }
00539                break;
00540             case GL_CONSTANT_COLOR:
00541                sR = ctx->Color.BlendColor[0];
00542                sG = ctx->Color.BlendColor[1];
00543                sB = ctx->Color.BlendColor[2];
00544                break;
00545             case GL_ONE_MINUS_CONSTANT_COLOR:
00546                sR = 1.0F - ctx->Color.BlendColor[0];
00547                sG = 1.0F - ctx->Color.BlendColor[1];
00548                sB = 1.0F - ctx->Color.BlendColor[2];
00549                break;
00550             case GL_CONSTANT_ALPHA:
00551                sR = sG = sB = ctx->Color.BlendColor[3];
00552                break;
00553             case GL_ONE_MINUS_CONSTANT_ALPHA:
00554                sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
00555                break;
00556             case GL_SRC_COLOR:
00557                sR = Rs;
00558                sG = Gs;
00559                sB = Bs;
00560                break;
00561             case GL_ONE_MINUS_SRC_COLOR:
00562                sR = 1.0F - Rs;
00563                sG = 1.0F - Gs;
00564                sB = 1.0F - Bs;
00565                break;
00566             default:
00567                /* this should never happen */
00568                _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
00569                return;
00570          }
00571 
00572          /* Source Alpha factor */
00573          switch (ctx->Color.BlendSrcA) {
00574             case GL_ZERO:
00575                sA = 0.0F;
00576                break;
00577             case GL_ONE:
00578                sA = 1.0F;
00579                break;
00580             case GL_DST_COLOR:
00581                sA = Ad;
00582                break;
00583             case GL_ONE_MINUS_DST_COLOR:
00584                sA = 1.0F - Ad;
00585                break;
00586             case GL_SRC_ALPHA:
00587                sA = As;
00588                break;
00589             case GL_ONE_MINUS_SRC_ALPHA:
00590                sA = 1.0F - As;
00591                break;
00592             case GL_DST_ALPHA:
00593                sA = Ad;
00594                break;
00595             case GL_ONE_MINUS_DST_ALPHA:
00596                sA = 1.0F - Ad;
00597                break;
00598             case GL_SRC_ALPHA_SATURATE:
00599                sA = 1.0;
00600                break;
00601             case GL_CONSTANT_COLOR:
00602                sA = ctx->Color.BlendColor[3];
00603                break;
00604             case GL_ONE_MINUS_CONSTANT_COLOR:
00605                sA = 1.0F - ctx->Color.BlendColor[3];
00606                break;
00607             case GL_CONSTANT_ALPHA:
00608                sA = ctx->Color.BlendColor[3];
00609                break;
00610             case GL_ONE_MINUS_CONSTANT_ALPHA:
00611                sA = 1.0F - ctx->Color.BlendColor[3];
00612                break;
00613             case GL_SRC_COLOR:
00614                sA = As;
00615                break;
00616             case GL_ONE_MINUS_SRC_COLOR:
00617                sA = 1.0F - As;
00618                break;
00619             default:
00620                /* this should never happen */
00621                sA = 0.0F;
00622                _mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
00623                return;
00624          }
00625 
00626          /* Dest RGB factor */
00627          switch (ctx->Color.BlendDstRGB) {
00628             case GL_ZERO:
00629                dR = dG = dB = 0.0F;
00630                break;
00631             case GL_ONE:
00632                dR = dG = dB = 1.0F;
00633                break;
00634             case GL_SRC_COLOR:
00635                dR = Rs;
00636                dG = Gs;
00637                dB = Bs;
00638                break;
00639             case GL_ONE_MINUS_SRC_COLOR:
00640                dR = 1.0F - Rs;
00641                dG = 1.0F - Gs;
00642                dB = 1.0F - Bs;
00643                break;
00644             case GL_SRC_ALPHA:
00645                dR = dG = dB = As;
00646                break;
00647             case GL_ONE_MINUS_SRC_ALPHA:
00648                dR = dG = dB = 1.0F - As;
00649                break;
00650             case GL_DST_ALPHA:
00651                dR = dG = dB = Ad;
00652                break;
00653             case GL_ONE_MINUS_DST_ALPHA:
00654                dR = dG = dB = 1.0F - Ad;
00655                break;
00656             case GL_CONSTANT_COLOR:
00657                dR = ctx->Color.BlendColor[0];
00658                dG = ctx->Color.BlendColor[1];
00659                dB = ctx->Color.BlendColor[2];
00660                break;
00661             case GL_ONE_MINUS_CONSTANT_COLOR:
00662                dR = 1.0F - ctx->Color.BlendColor[0];
00663                dG = 1.0F - ctx->Color.BlendColor[1];
00664                dB = 1.0F - ctx->Color.BlendColor[2];
00665                break;
00666             case GL_CONSTANT_ALPHA:
00667                dR = dG = dB = ctx->Color.BlendColor[3];
00668                break;
00669             case GL_ONE_MINUS_CONSTANT_ALPHA:
00670                dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
00671                break;
00672             case GL_DST_COLOR:
00673                dR = Rd;
00674                dG = Gd;
00675                dB = Bd;
00676                break;
00677             case GL_ONE_MINUS_DST_COLOR:
00678                dR = 1.0F - Rd;
00679                dG = 1.0F - Gd;
00680                dB = 1.0F - Bd;
00681                break;
00682             default:
00683                /* this should never happen */
00684                dR = dG = dB = 0.0F;
00685                _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
00686                return;
00687          }
00688 
00689          /* Dest Alpha factor */
00690          switch (ctx->Color.BlendDstA) {
00691             case GL_ZERO:
00692                dA = 0.0F;
00693                break;
00694             case GL_ONE:
00695                dA = 1.0F;
00696                break;
00697             case GL_SRC_COLOR:
00698                dA = As;
00699                break;
00700             case GL_ONE_MINUS_SRC_COLOR:
00701                dA = 1.0F - As;
00702                break;
00703             case GL_SRC_ALPHA:
00704                dA = As;
00705                break;
00706             case GL_ONE_MINUS_SRC_ALPHA:
00707                dA = 1.0F - As;
00708                break;
00709             case GL_DST_ALPHA:
00710                dA = Ad;
00711                break;
00712             case GL_ONE_MINUS_DST_ALPHA:
00713                dA = 1.0F - Ad;
00714                break;
00715             case GL_CONSTANT_COLOR:
00716                dA = ctx->Color.BlendColor[3];
00717                break;
00718             case GL_ONE_MINUS_CONSTANT_COLOR:
00719                dA = 1.0F - ctx->Color.BlendColor[3];
00720                break;
00721             case GL_CONSTANT_ALPHA:
00722                dA = ctx->Color.BlendColor[3];
00723                break;
00724             case GL_ONE_MINUS_CONSTANT_ALPHA:
00725                dA = 1.0F - ctx->Color.BlendColor[3];
00726                break;
00727             case GL_DST_COLOR:
00728                dA = Ad;
00729                break;
00730             case GL_ONE_MINUS_DST_COLOR:
00731                dA = 1.0F - Ad;
00732                break;
00733             default:
00734                /* this should never happen */
00735                dA = 0.0F;
00736                _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
00737                return;
00738          }
00739 
00740          /* compute the blended RGB */
00741          switch (ctx->Color.BlendEquationRGB) {
00742          case GL_FUNC_ADD:
00743             r = Rs * sR + Rd * dR;
00744             g = Gs * sG + Gd * dG;
00745             b = Bs * sB + Bd * dB;
00746             a = As * sA + Ad * dA;
00747             break;
00748          case GL_FUNC_SUBTRACT:
00749             r = Rs * sR - Rd * dR;
00750             g = Gs * sG - Gd * dG;
00751             b = Bs * sB - Bd * dB;
00752             a = As * sA - Ad * dA;
00753             break;
00754          case GL_FUNC_REVERSE_SUBTRACT:
00755             r = Rd * dR - Rs * sR;
00756             g = Gd * dG - Gs * sG;
00757             b = Bd * dB - Bs * sB;
00758             a = Ad * dA - As * sA;
00759             break;
00760          case GL_MIN:
00761         r = MIN2( Rd, Rs );
00762         g = MIN2( Gd, Gs );
00763         b = MIN2( Bd, Bs );
00764             break;
00765          case GL_MAX:
00766         r = MAX2( Rd, Rs );
00767         g = MAX2( Gd, Gs );
00768         b = MAX2( Bd, Bs );
00769             break;
00770      default:
00771             /* should never get here */
00772             r = g = b = 0.0F;  /* silence uninitialized var warning */
00773             _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
00774             return;
00775          }
00776 
00777          /* compute the blended alpha */
00778          switch (ctx->Color.BlendEquationA) {
00779          case GL_FUNC_ADD:
00780             a = As * sA + Ad * dA;
00781             break;
00782          case GL_FUNC_SUBTRACT:
00783             a = As * sA - Ad * dA;
00784             break;
00785          case GL_FUNC_REVERSE_SUBTRACT:
00786             a = Ad * dA - As * sA;
00787             break;
00788          case GL_MIN:
00789         a = MIN2( Ad, As );
00790             break;
00791          case GL_MAX:
00792         a = MAX2( Ad, As );
00793             break;
00794          default:
00795             /* should never get here */
00796             a = 0.0F;  /* silence uninitialized var warning */
00797             _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
00798             return;
00799          }
00800 
00801          /* final clamping */
00802 #if 0
00803          rgba[i][RCOMP] = MAX2( r, 0.0F );
00804          rgba[i][GCOMP] = MAX2( g, 0.0F );
00805          rgba[i][BCOMP] = MAX2( b, 0.0F );
00806          rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F );
00807 #else
00808          ASSIGN_4V(rgba[i], r, g, b, a);
00809 #endif
00810       }
00811    }
00812 }
00813 
00814 
00818 static void
00819 blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[],
00820               void *src, const void *dst, GLenum chanType)
00821 {
00822    GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4];
00823 
00824    if (chanType == GL_UNSIGNED_BYTE) {
00825       GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
00826       const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
00827       GLuint i;
00828       /* convert ubytes to floats */
00829       for (i = 0; i < n; i++) {
00830          if (mask[i]) {
00831             rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
00832             rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
00833             rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
00834             rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
00835             destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
00836             destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
00837             destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
00838             destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
00839          }
00840       }
00841       /* do blend */
00842       blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
00843       /* convert back to ubytes */
00844       for (i = 0; i < n; i++) {
00845          if (mask[i]) {
00846             UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]);
00847             UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]);
00848             UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]);
00849             UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]);
00850          }
00851       }
00852    }
00853    else if (chanType == GL_UNSIGNED_SHORT) {
00854       GLushort (*rgba)[4] = (GLushort (*)[4]) src;
00855       const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
00856       GLuint i;
00857       /* convert ushorts to floats */
00858       for (i = 0; i < n; i++) {
00859          if (mask[i]) {
00860             rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
00861             rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
00862             rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
00863             rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
00864             destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
00865             destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
00866             destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
00867             destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
00868          }
00869       }
00870       /* do blend */
00871       blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
00872       /* convert back to ushorts */
00873       for (i = 0; i < n; i++) {
00874          if (mask[i]) {
00875             UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
00876             UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
00877             UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
00878             UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
00879          }
00880       }
00881    }
00882    else {
00883       blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src,
00884                           (GLfloat (*)[4]) dst, chanType);
00885    }
00886 }
00887 
00888 
00889 
00894 void
00895 _swrast_choose_blend_func(GLcontext *ctx, GLenum chanType)
00896 {
00897    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00898    const GLenum eq = ctx->Color.BlendEquationRGB;
00899    const GLenum srcRGB = ctx->Color.BlendSrcRGB;
00900    const GLenum dstRGB = ctx->Color.BlendDstRGB;
00901    const GLenum srcA = ctx->Color.BlendSrcA;
00902    const GLenum dstA = ctx->Color.BlendDstA;
00903 
00904    if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) {
00905       swrast->BlendFunc = blend_general;
00906    }
00907    else if (eq == GL_MIN) {
00908       /* Note: GL_MIN ignores the blending weight factors */
00909 #if defined(USE_MMX_ASM)
00910       if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
00911          swrast->BlendFunc = _mesa_mmx_blend_min;
00912       }
00913       else
00914 #endif
00915          swrast->BlendFunc = blend_min;
00916    }
00917    else if (eq == GL_MAX) {
00918       /* Note: GL_MAX ignores the blending weight factors */
00919 #if defined(USE_MMX_ASM)
00920       if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
00921          swrast->BlendFunc = _mesa_mmx_blend_max;
00922       }
00923       else
00924 #endif
00925          swrast->BlendFunc = blend_max;
00926    }
00927    else if (srcRGB != srcA || dstRGB != dstA) {
00928       swrast->BlendFunc = blend_general;
00929    }
00930    else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
00931             && dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
00932 #if defined(USE_MMX_ASM)
00933       if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
00934          swrast->BlendFunc = _mesa_mmx_blend_transparency;
00935       }
00936       else
00937 #endif
00938       {
00939          if (chanType == GL_UNSIGNED_BYTE)
00940             swrast->BlendFunc = blend_transparency_ubyte;
00941          else if (chanType == GL_UNSIGNED_SHORT)
00942             swrast->BlendFunc = blend_transparency_ushort;
00943          else
00944             swrast->BlendFunc = blend_transparency_float;
00945       }
00946    }
00947    else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
00948 #if defined(USE_MMX_ASM)
00949       if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
00950          swrast->BlendFunc = _mesa_mmx_blend_add;
00951       }
00952       else
00953 #endif
00954          swrast->BlendFunc = blend_add;
00955    }
00956    else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
00957          && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
00958         ||
00959         ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT)
00960          && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
00961 #if defined(USE_MMX_ASM)
00962       if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
00963          swrast->BlendFunc = _mesa_mmx_blend_modulate;
00964       }
00965       else
00966 #endif
00967          swrast->BlendFunc = blend_modulate;
00968    }
00969    else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
00970       swrast->BlendFunc = blend_noop;
00971    }
00972    else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
00973       swrast->BlendFunc = blend_replace;
00974    }
00975    else {
00976       swrast->BlendFunc = blend_general;
00977    }
00978 }
00979 
00980 
00981 
00987 void
00988 _swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, SWspan *span)
00989 {
00990    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00991    void *rbPixels;
00992 
00993    ASSERT(span->end <= MAX_WIDTH);
00994    ASSERT(span->arrayMask & SPAN_RGBA);
00995    ASSERT(rb->DataType == span->array->ChanType);
00996    ASSERT(!ctx->Color._LogicOpEnabled);
00997 
00998    rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
00999 
01000    swrast->BlendFunc(ctx, span->end, span->array->mask,
01001                      span->array->rgba, rbPixels, span->array->ChanType);
01002 }

Generated on Sat May 26 2012 04:19:30 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.