Skip to content

Commit

Permalink
Engine: in BitmapToVideoMemOpaque() cut out "HasAlpha" branch
Browse files Browse the repository at this point in the history
Handling alpha channel is meaningless in BitmapToVideoMemOpaque(), because the whole point of this function is to produce fully opaque texture.
Alpha + opaque combination had never been a case in practice.
  • Loading branch information
ivan-mogilko committed Oct 24, 2023
1 parent c20a5c5 commit ead7d59
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 48 deletions.
4 changes: 3 additions & 1 deletion Engine/gfx/ali3dogl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,10 @@ void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap
fixedTile.y = tile->y;
fixedTile.width = std::min(tile->width, tileWidth);
fixedTile.height = std::min(tile->height, tileHeight);

assert(!opaque || !has_alpha); // has_alpha is meaningless with opaque
if (opaque)
BitmapToVideoMemOpaque(bitmap, has_alpha, &fixedTile, memPtr, pitch);
BitmapToVideoMemOpaque(bitmap, &fixedTile, memPtr, pitch);
else
BitmapToVideoMem(bitmap, has_alpha, &fixedTile, memPtr, pitch, usingLinearFiltering);

Expand Down
61 changes: 18 additions & 43 deletions Engine/gfx/gfxdriverbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,7 @@ template <typename T> void get_pixel_if_not_transparent(const T *pixel, T *red,
template <typename T, bool HasAlpha, bool UsingLinearFiltering> void
VideoMemoryGraphicsDriver::BitmapToVideoMemImpl(
const Bitmap *bitmap, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch
)
uint8_t *dst_ptr, const int dst_pitch)
{
// tell the compiler these won't change mid loop execution
const int t_width = tile->width;
Expand Down Expand Up @@ -509,76 +508,52 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo
}


template <typename T, bool HasAlpha> void
template <typename T> void
VideoMemoryGraphicsDriver::BitmapToVideoMemOpaqueImpl(
const Bitmap *bitmap, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch
)
uint8_t *dst_ptr, const int dst_pitch)
{
const int t_width = tile->width;
const int t_height = tile->height;
const int t_x = tile->x;
const int t_y = tile->y;
if (HasAlpha) {
for (int y = 0; y < t_height; y++)
{
const uint8_t* scanline_at = bitmap->GetScanLine(y + t_y);
unsigned int* memPtrLong = (unsigned int*)dst_ptr;

for (int x = 0; x < t_width; x++)
{
auto srcData = (const T *)&scanline_at[(x + t_x) * sizeof(T)];
const T src_color = srcData[0];
memPtrLong[x] = VMEMCOLOR_RGBA(
algetr<T>(src_color), algetg<T>(src_color), algetb<T>(src_color), algeta<T>(src_color));
}
dst_ptr += dst_pitch;
}
}
else
for (int y = 0; y < t_height; y++)
{
for (int y = 0; y < t_height; y++)
{
const uint8_t* scanline_at = bitmap->GetScanLine(y + t_y);
unsigned int* memPtrLong = (unsigned int*)dst_ptr;
const uint8_t* scanline_at = bitmap->GetScanLine(y + t_y);
unsigned int* memPtrLong = (unsigned int*)dst_ptr;

for (int x = 0; x < t_width; x++)
{
auto srcData = (const T *)&scanline_at[(x + t_x) * sizeof(T)];
const T src_color = srcData[0];
memPtrLong[x] = VMEMCOLOR_RGBA(
algetr<T>(src_color), algetg<T>(src_color), algetb<T>(src_color), 0xFF);
}
dst_ptr += dst_pitch;
for (int x = 0; x < t_width; x++)
{
auto srcData = (const T *)&scanline_at[(x + t_x) * sizeof(T)];
const T src_color = srcData[0];
memPtrLong[x] = VMEMCOLOR_RGBA(
algetr<T>(src_color), algetg<T>(src_color), algetb<T>(src_color), 0xFF);
}
dst_ptr += dst_pitch;
}
}

void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch)
{
const int src_depth = bitmap->GetColorDepth();

switch (src_depth)
{
case 8:
BitmapToVideoMemOpaqueImpl<uint8_t, false>(bitmap, tile, dst_ptr, dst_pitch);
BitmapToVideoMemOpaqueImpl<uint8_t>(bitmap, tile, dst_ptr, dst_pitch);
break;
case 16:
BitmapToVideoMemOpaqueImpl<uint16_t, false>(bitmap, tile, dst_ptr, dst_pitch);
BitmapToVideoMemOpaqueImpl<uint16_t>(bitmap, tile, dst_ptr, dst_pitch);
break;
case 32:
if(has_alpha) {
BitmapToVideoMemOpaqueImpl<uint32_t, true>(bitmap, tile, dst_ptr, dst_pitch);
} else {
BitmapToVideoMemOpaqueImpl<uint32_t, false>(bitmap, tile, dst_ptr, dst_pitch);
}
BitmapToVideoMemOpaqueImpl<uint32_t>(bitmap, tile, dst_ptr, dst_pitch);
break;
default:
break;
}
}


} // namespace Engine
} // namespace Engine
} // namespace AGS
6 changes: 3 additions & 3 deletions Engine/gfx/gfxdriverbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ class VideoMemoryGraphicsDriver : public GraphicsDriverBase

// Prepares bitmap to be applied to the texture, copies pixels to the provided buffer
void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
uint8_t *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
// Same but optimized for opaque source bitmaps which ignore transparent "mask color"
void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
void BitmapToVideoMemOpaque(const Bitmap *bitmap, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch);

// Stage matrixes are used to let plugins with hardware acceleration know model matrix;
Expand Down Expand Up @@ -368,7 +368,7 @@ class VideoMemoryGraphicsDriver : public GraphicsDriverBase
uint8_t *dst_ptr, const int dst_pitch
);

template <typename T, bool HasAlpha> void
template <typename T> void
BitmapToVideoMemOpaqueImpl(
const Bitmap *bitmap, const TextureTile *tile,
uint8_t *dst_ptr, const int dst_pitch
Expand Down
3 changes: 2 additions & 1 deletion Engine/platform/windows/gfx/ali3dd3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,8 +1599,9 @@ void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap
bool usingLinearFiltering = _filter->NeedToColourEdgeLines();
uint8_t *memPtr = static_cast<uint8_t*>(lockedRegion.pBits);

assert(!opaque || !has_alpha); // has_alpha is meaningless with opaque
if (opaque)
BitmapToVideoMemOpaque(bitmap, has_alpha, tile, memPtr, lockedRegion.Pitch);
BitmapToVideoMemOpaque(bitmap, tile, memPtr, lockedRegion.Pitch);
else
BitmapToVideoMem(bitmap, has_alpha, tile, memPtr, lockedRegion.Pitch, usingLinearFiltering);

Expand Down

0 comments on commit ead7d59

Please sign in to comment.