[Mesa-dev] [PATCH 10/29] mesa: Use bitmask/ffs to iterate enabled lights

Ian Romanick idr at freedesktop.org
Wed May 25 16:11:19 UTC 2016


On 05/23/2016 11:42 PM, Mathias.Froehlich at gmx.net wrote:
> From: Mathias Fröhlich <mathias.froehlich at web.de>
> 
> Replaces loops that iterate all lights and test
> which of them is enabled by a loop only iterating over
> the bits set in the enabled bitmask.
> 
> Signed-off-by: Mathias Fröhlich <Mathias.Froehlich at web.de>
> ---
>  src/mesa/main/light.c   | 55 ++++++++++++++++++++++++++++++++++++++-----------
>  src/mesa/main/rastpos.c |  9 +++++---
>  2 files changed, 49 insertions(+), 15 deletions(-)
> 
> diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
> index a52efdb..b28ea7e 100644
> --- a/src/mesa/main/light.c
> +++ b/src/mesa/main/light.c
> @@ -612,7 +612,6 @@ _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname,
>  void
>  _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
>  {
> -   struct gl_light *light, *list = &ctx->Light.EnabledList;
>     GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
>  
>     if (MESA_VERBOSE & VERBOSE_MATERIAL) 
> @@ -623,14 +622,22 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
>  
>     /* update material ambience */
>     if (bitmask & MAT_BIT_FRONT_AMBIENT) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;

The next patch makes i const, and I think this one should too.

> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>           SCALE_3V( light->_MatAmbient[0], light->Ambient, 
>  		   mat[MAT_ATTRIB_FRONT_AMBIENT]);
>        }
>     }
>  
>     if (bitmask & MAT_BIT_BACK_AMBIENT) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;
> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>           SCALE_3V( light->_MatAmbient[1], light->Ambient, 
>  		   mat[MAT_ATTRIB_BACK_AMBIENT]);
>        }
> @@ -651,14 +658,22 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
>  
>     /* update material diffuse values */
>     if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;
> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>  	 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, 
>  		   mat[MAT_ATTRIB_FRONT_DIFFUSE] );
>        }
>     }
>  
>     if (bitmask & MAT_BIT_BACK_DIFFUSE) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;
> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>  	 SCALE_3V( light->_MatDiffuse[1], light->Diffuse, 
>  		   mat[MAT_ATTRIB_BACK_DIFFUSE] );
>        }
> @@ -666,14 +681,22 @@ _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
>  
>     /* update material specular values */
>     if (bitmask & MAT_BIT_FRONT_SPECULAR) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;
> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>  	 SCALE_3V( light->_MatSpecular[0], light->Specular, 
>  		   mat[MAT_ATTRIB_FRONT_SPECULAR]);
>        }
>     }
>  
>     if (bitmask & MAT_BIT_BACK_SPECULAR) {
> -      foreach (light, list) {
> +      GLbitfield mask = ctx->Light._EnabledLights;
> +      while (mask) {
> +         int i = ffs(mask) - 1;
> +         struct gl_light *light = &ctx->Light.Light[i];
> +         mask ^= (1u << i);
>  	 SCALE_3V( light->_MatSpecular[1], light->Specular,
>  		   mat[MAT_ATTRIB_BACK_SPECULAR]);
>        }
> @@ -863,14 +886,18 @@ _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
>  void
>  _mesa_update_lighting( struct gl_context *ctx )
>  {
> -   GLbitfield flags = 0;
> -   struct gl_light *light;
> +   GLbitfield flags = 0, mask;

Each variable should be declared on its own line.  Also, we can mix code
and data now, so you can declare mask at the assignment.

>     ctx->Light._NeedEyeCoords = GL_FALSE;
>  
>     if (!ctx->Light.Enabled)
>        return;
>  
> -   foreach(light, &ctx->Light.EnabledList) {
> +   mask = ctx->Light._EnabledLights;
> +   while (mask) {
> +      int i = ffs(mask) - 1;
> +      struct gl_light *light = &ctx->Light.Light[i];
> +      mask ^= (1u << i);
> +
>        flags |= light->_Flags;
>     }
>  
> @@ -926,7 +953,7 @@ _mesa_update_lighting( struct gl_context *ctx )
>  static void
>  compute_light_positions( struct gl_context *ctx )
>  {
> -   struct gl_light *light;
> +   GLbitfield mask;
>     static const GLfloat eye_z[3] = { 0, 0, 1 };
>  
>     if (!ctx->Light.Enabled)
> @@ -939,7 +966,11 @@ compute_light_positions( struct gl_context *ctx )
>        TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
>     }
>  
> -   foreach (light, &ctx->Light.EnabledList) {
> +   mask = ctx->Light._EnabledLights;
> +   while (mask) {
> +      int i = ffs(mask) - 1;
> +      struct gl_light *light = &ctx->Light.Light[i];
> +      mask ^= (1u << i);
>  
>        if (ctx->_NeedEyeCoords) {
>           /* _Position is in eye coordinate space */
> diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
> index b468219..6ab439e 100644
> --- a/src/mesa/main/rastpos.c
> +++ b/src/mesa/main/rastpos.c
> @@ -37,7 +37,6 @@
>  #include "state.h"
>  #include "main/dispatch.h"
>  #include "main/viewport.h"
> -#include "util/simple_list.h"
>  
>  
>  
> @@ -125,7 +124,7 @@ shade_rastpos(struct gl_context *ctx,
>                GLfloat Rspec[4])
>  {
>     /*const*/ GLfloat (*base)[3] = ctx->Light._BaseColor;
> -   const struct gl_light *light;
> +   GLbitfield mask;
>     GLfloat diffuseColor[4], specularColor[4];  /* for RGB mode only */
>  
>     COPY_3V(diffuseColor, base[0]);
> @@ -133,11 +132,15 @@ shade_rastpos(struct gl_context *ctx,
>        ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3], 0.0F, 1.0F );
>     ASSIGN_4V(specularColor, 0.0, 0.0, 0.0, 1.0);
>  
> -   foreach (light, &ctx->Light.EnabledList) {
> +   mask = ctx->Light._EnabledLights;
> +   while (mask) {
> +      int i = ffs(mask) - 1;
> +      struct gl_light *light = &ctx->Light.Light[i];
>        GLfloat attenuation = 1.0;
>        GLfloat VP[3]; /* vector from vertex to light pos */
>        GLfloat n_dot_VP;
>        GLfloat diffuseContrib[3], specularContrib[3];
> +      mask ^= (1u << i);
>  
>        if (!(light->_Flags & LIGHT_POSITIONAL)) {
>           /* light at infinity */
> 



More information about the mesa-dev mailing list