[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