Skip to content

Commit

Permalink
Optimize I_MapRGB
Browse files Browse the repository at this point in the history
Replaced the `I_MapRGB()` function with a preprocessor macro to manually assemble 32-bit pixel values. This approach avoids the overhead of the `SDL_MapRGB()` function call, resulting in situational performance improvements when working with non-palettized, fixed pixel formats.

The macro handles:
- Shifting R, G, B components according to the format's `Rshift`, `Gshift`, `Bshift`.
- Adjusting for bit loss using `Rloss`, `Gloss`, `Bloss`.
- Applying the alpha mask (`Amask`) for consistency.

This change is safe under the assumption of a fixed 32-bit pixel format (e.g., ARGB8888).
  • Loading branch information
pvictress committed Jan 17, 2025
1 parent d23da3e commit 5313f76
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/i_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static int vid_window_title_short = 1;
#ifndef CRISPY_TRUECOLOR
static SDL_Surface *screenbuffer = NULL;
#endif
static SDL_Surface *argbbuffer = NULL;
SDL_Surface *argbbuffer = NULL;
static SDL_Texture *texture = NULL;
static SDL_Texture *texture_upscaled = NULL;

Expand Down Expand Up @@ -2291,9 +2291,12 @@ void I_BindVideoVariables(void)
M_BindIntVariable("mouse_grab", &mouse_grab);
}

// [PN] Original human-readable mapping function from Crispy Doom
/*
#ifdef CRISPY_TRUECOLOR
const pixel_t I_MapRGB (const uint8_t r, const uint8_t g, const uint8_t b)
{
return SDL_MapRGB(argbbuffer->format, r, g, b);
}
#endif
*/
20 changes: 19 additions & 1 deletion src/i_video.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef __I_VIDEO__
#define __I_VIDEO__

#include "SDL.h"
#include "doomtype.h"
#include "i_truecolor.h"
#include "m_fixed.h"
Expand Down Expand Up @@ -97,7 +98,24 @@ void I_SetPalette (byte* palette);
int I_GetPaletteIndex(int r, int g, int b);
#else
void I_SetPalette (int palette);
extern const pixel_t I_MapRGB (const uint8_t r, const uint8_t g, const uint8_t b);

// [PN] We define a macro that manually assembles a 32-bit pixel from separate R/G/B values.
// It applies the format's shift and loss adjustments, then merges all components (and alpha mask) with bitwise OR.
// This avoids the overhead of the SDL_MapRGB() function call.
//
// Original human-readable mapping function from Crispy Doom is preserved as commented example in i_video.c file.
// extern inline const pixel_t I_MapRGB (const uint8_t r, const uint8_t g, const uint8_t b);

extern SDL_Surface *argbbuffer;

#define I_MapRGB(r, g, b) ( \
(pixel_t)( \
(((uint32_t)(r) >> argbbuffer->format->Rloss) << argbbuffer->format->Rshift) | \
(((uint32_t)(g) >> argbbuffer->format->Gloss) << argbbuffer->format->Gshift) | \
(((uint32_t)(b) >> argbbuffer->format->Bloss) << argbbuffer->format->Bshift) | \
(argbbuffer->format->Amask) \
) \
)
#endif
void I_FinishUpdate (void);

Expand Down

0 comments on commit 5313f76

Please sign in to comment.