Codechange: address CodeQL issue "Multiplication result converted to larger type" (#10306)

Most are very unlikely to ever be triggered in our codebase; two
stand out: linkgraph and money cheat. Those, potentially, could
wrap earlier than expected.
This commit is contained in:
Patric Stout 2023-01-02 21:30:02 +01:00 committed by GitHub
parent fcbe390353
commit 1fb101eabb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 74 additions and 66 deletions

View File

@ -478,9 +478,9 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
}
int Blitter_32bppAnim::BufferSize(int width, int height)
size_t Blitter_32bppAnim::BufferSize(uint width, uint height)
{
return width * height * (sizeof(uint32) + sizeof(uint16));
return (sizeof(uint32) + sizeof(uint16)) * width * height;
}
void Blitter_32bppAnim::PaletteAnimate(const Palette &palette)

View File

@ -43,7 +43,7 @@ public:
void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;

View File

@ -140,9 +140,9 @@ void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &widt
}
}
int Blitter_32bppBase::BufferSize(int width, int height)
size_t Blitter_32bppBase::BufferSize(uint width, uint height)
{
return width * height * sizeof(uint32);
return sizeof(uint32) * width * height;
}
void Blitter_32bppBase::PaletteAnimate(const Palette &palette)

View File

@ -27,7 +27,7 @@ public:
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
int GetBytesPerPixel() override { return 4; }

View File

@ -31,9 +31,10 @@ void Blitter_40bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
if (_screen_disable_anim) {
Blitter_32bppOptimized::SetPixel(video, x, y, colour);
} else {
*((Colour *)video + x + y * _screen.pitch) = _black_colour;
size_t y_offset = static_cast<size_t>(y) * _screen.pitch;
*((Colour *)video + x + y_offset) = _black_colour;
VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * _screen.pitch] = colour;
VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y_offset] = colour;
}
}
@ -500,9 +501,9 @@ void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt
Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y);
}
int Blitter_40bppAnim::BufferSize(int width, int height)
size_t Blitter_40bppAnim::BufferSize(uint width, uint height)
{
return width * height * (sizeof(uint32) + sizeof(uint8));
return (sizeof(uint32) + sizeof(uint8)) * width * height;
}
Blitter::PaletteAnimation Blitter_40bppAnim::UsePaletteAnimation()

View File

@ -29,7 +29,7 @@ public:
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
bool NeedsAnimationBuffer() override;

View File

@ -144,9 +144,9 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width
}
}
int Blitter_8bppBase::BufferSize(int width, int height)
size_t Blitter_8bppBase::BufferSize(uint width, uint height)
{
return width * height;
return static_cast<size_t>(width) * height;
}
void Blitter_8bppBase::PaletteAnimate(const Palette &palette)

View File

@ -25,7 +25,7 @@ public:
void CopyToBuffer(const void *video, void *dst, int width, int height) override;
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override;
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override;
int BufferSize(int width, int height) override;
size_t BufferSize(uint width, uint height) override;
void PaletteAnimate(const Palette &palette) override;
Blitter::PaletteAnimation UsePaletteAnimation() override;
int GetBytesPerPixel() override { return 1; }

View File

@ -170,7 +170,7 @@ public:
* @param height The height of the buffer-to-be.
* @return The size needed for the buffer.
*/
virtual int BufferSize(int width, int height) = 0;
virtual size_t BufferSize(uint width, uint height) = 0;
/**
* Called when the 8bpp palette is changed; you should redraw all pixels on the screen that

View File

@ -27,7 +27,7 @@ public:
void CopyToBuffer(const void *video, void *dst, int width, int height) override {};
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};
void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override {};
int BufferSize(int width, int height) override { return 0; };
size_t BufferSize(uint width, uint height) override { return 0; };
void PaletteAnimate(const Palette &palette) override { };
Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; };

View File

@ -390,7 +390,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
{
assert(info != nullptr && data != nullptr);
data->bitmap = CallocT<byte>(info->width * info->height * ((info->bpp == 24) ? 3 : 1));
data->bitmap = CallocT<byte>(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
/* Load image */
SetStreamOffset(buffer, info->offset);

View File

@ -56,7 +56,7 @@ static int32 _money_cheat_amount = 10000000;
*/
static int32 ClickMoneyCheat(int32 p1, int32 p2)
{
Command<CMD_MONEY_CHEAT>::Post(p2 * _money_cheat_amount);
Command<CMD_MONEY_CHEAT>::Post(Money(_money_cheat_amount) * p2);
return _money_cheat_amount;
}

View File

@ -240,7 +240,7 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
SpriteLoader::Sprite sprite;
sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
sprite.AllocateData(ZOOM_LVL_NORMAL, static_cast<size_t>(width) * height);
sprite.type = ST_FONT;
sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL);
sprite.width = width;

View File

@ -1222,9 +1222,10 @@ std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo
const SpriteID real_sprite = GB(spriteId, 0, SPRITE_WIDTH);
const Sprite *sprite = GetSprite(real_sprite, ST_NORMAL);
Dimension dim = GetSpriteSize(real_sprite, nullptr, zoom);
std::unique_ptr<uint32[]> result(new uint32[dim.width * dim.height]);
size_t dim_size = static_cast<size_t>(dim.width) * dim.height;
std::unique_ptr<uint32[]> result(new uint32[dim_size]);
/* Set buffer to fully transparent. */
MemSetT(result.get(), 0, dim.width * dim.height);
MemSetT(result.get(), 0, dim_size);
/* Prepare new DrawPixelInfo - Normally this would be the screen but we want to draw to another buffer here.
* Normally, pitch would be scaled screen width, but in our case our "screen" is only the sprite width wide. */
@ -1237,11 +1238,13 @@ std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo
dpi.height = dim.height;
dpi.zoom = zoom;
dim_size = static_cast<size_t>(dim.width) * dim.height;
/* If the current blitter is a paletted blitter, we have to render to an extra buffer and resolve the palette later. */
std::unique_ptr<byte[]> pal_buffer{};
if (blitter->GetScreenDepth() == 8) {
pal_buffer.reset(new byte[dim.width * dim.height]);
MemSetT(pal_buffer.get(), 0, dim.width * dim.height);
pal_buffer.reset(new byte[dim_size]);
MemSetT(pal_buffer.get(), 0, dim_size);
dpi.dst_ptr = pal_buffer.get();
}
@ -1255,7 +1258,7 @@ std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo
/* Resolve palette. */
uint32 *dst = result.get();
const byte *src = pal_buffer.get();
for (size_t i = 0; i < dim.height * dim.width; ++i) {
for (size_t i = 0; i < dim_size; ++i) {
*dst++ = _cur_palette.palette[*src++].data;
}
}
@ -1506,7 +1509,7 @@ void GetBroadestDigit(uint *front, uint *next, FontSize size)
void ScreenSizeChanged()
{
_dirty_bytes_per_line = CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH);
_dirty_blocks = ReallocT<byte>(_dirty_blocks, _dirty_bytes_per_line * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
_dirty_blocks = ReallocT<byte>(_dirty_blocks, static_cast<size_t>(_dirty_bytes_per_line) * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
/* check the dirty rect */
if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;

View File

@ -141,7 +141,7 @@ int GroundVehicle<T, Type>::GetAcceleration() const
}
/* Air drag; the air drag coefficient is in an arbitrary NewGRF-unit,
* so we need some magic conversion factor. */
resistance += (area * this->gcache.cached_air_drag * speed * speed) / 1000;
resistance += static_cast<int64>(area) * this->gcache.cached_air_drag * speed * speed / 1000;
resistance += this->GetSlopeResistance();

View File

@ -188,7 +188,7 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map)
}
if (map != nullptr) {
*map = MallocT<byte>(width * height);
*map = MallocT<byte>(static_cast<size_t>(width) * height);
ReadHeightmapPNGImageData(*map, png_ptr, info_ptr);
}
@ -303,7 +303,7 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map)
return false;
}
*map = MallocT<byte>(info.width * info.height);
*map = MallocT<byte>(static_cast<size_t>(info.width) * info.height);
ReadHeightmapBMPImageData(*map, &info, &data);
}

View File

@ -204,7 +204,7 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 trave
BaseEdge &first = this->edges[this->index];
edge.capacity = capacity;
edge.usage = usage;
edge.travel_time_sum = travel_time * capacity;
edge.travel_time_sum = static_cast<uint64>(travel_time) * capacity;
edge.next_edge = first.next_edge;
first.next_edge = to;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
@ -275,18 +275,18 @@ void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, Edge
if (mode & EUM_INCREASE) {
if (this->edge.travel_time_sum == 0) {
this->edge.travel_time_sum = (this->edge.capacity + capacity) * travel_time;
this->edge.travel_time_sum = static_cast<uint64>(this->edge.capacity + capacity) * travel_time;
} else if (travel_time == 0) {
this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity;
} else {
this->edge.travel_time_sum += travel_time * capacity;
this->edge.travel_time_sum += static_cast<uint64>(travel_time) * capacity;
}
this->edge.capacity += capacity;
this->edge.usage += usage;
} else if (mode & EUM_REFRESH) {
if (this->edge.travel_time_sum == 0) {
this->edge.capacity = std::max(this->edge.capacity, capacity);
this->edge.travel_time_sum = travel_time * this->edge.capacity;
this->edge.travel_time_sum = static_cast<uint64>(travel_time) * this->edge.capacity;
} else if (capacity > this->edge.capacity) {
this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity;
this->edge.capacity = capacity;

View File

@ -108,7 +108,7 @@ void NetworkReInitChatBoxSize()
{
_chatmsg_box.y = 3 * FONT_HEIGHT_NORMAL;
_chatmsg_box.height = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + ScaleGUITrad(NETWORK_CHAT_LINE_SPACING)) + ScaleGUITrad(4);
_chatmessage_backup = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
_chatmessage_backup = ReallocT(_chatmessage_backup, static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel());
}
/** Initialize all buffers of the chat visualisation. */
@ -214,7 +214,7 @@ void NetworkDrawChatMessage()
}
if (width <= 0 || height <= 0) return;
assert(blitter->BufferSize(width, height) <= (int)(_chatmsg_box.width * _chatmsg_box.height * blitter->GetBytesPerPixel()));
assert(blitter->BufferSize(width, height) <= static_cast<size_t>(_chatmsg_box.width) * _chatmsg_box.height * blitter->GetBytesPerPixel());
/* Make a copy of the screen as it is before painting (for undraw) */
blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height);

View File

@ -137,7 +137,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user
/* Setup the file header */
BitmapFileHeader bfh;
bfh.type = TO_LE16('MB');
bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + bytewidth * h);
bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + static_cast<size_t>(bytewidth) * h);
bfh.reserved = 0;
bfh.off_bits = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size);
@ -374,7 +374,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
maxlines = Clamp(65536 / w, 16, 128);
/* now generate the bitmap bits */
void *buff = CallocT<uint8>(w * maxlines * bpp); // by default generate 128 lines at a time.
void *buff = CallocT<uint8>(static_cast<size_t>(w) * maxlines * bpp); // by default generate 128 lines at a time.
y = 0;
do {
@ -481,7 +481,7 @@ static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *user
maxlines = Clamp(65536 / w, 16, 128);
/* now generate the bitmap bits */
uint8 *buff = CallocT<uint8>(w * maxlines); // by default generate 128 lines at a time.
uint8 *buff = CallocT<uint8>(static_cast<size_t>(w) * maxlines); // by default generate 128 lines at a time.
y = 0;
do {

View File

@ -236,7 +236,7 @@ static bool ResizeSpriteIn(SpriteLoader::Sprite *sprite, ZoomLevel src, ZoomLeve
sprite[tgt].y_offs = sprite[src].y_offs * scaled_1;
sprite[tgt].colours = sprite[src].colours;
sprite[tgt].AllocateData(tgt, sprite[tgt].width * sprite[tgt].height);
sprite[tgt].AllocateData(tgt, static_cast<size_t>(sprite[tgt].width) * sprite[tgt].height);
SpriteLoader::CommonPixel *dst = sprite[tgt].data;
for (int y = 0; y < sprite[tgt].height; y++) {
@ -259,7 +259,7 @@ static void ResizeSpriteOut(SpriteLoader::Sprite *sprite, ZoomLevel zoom)
sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom);
sprite[zoom].colours = sprite[ZOOM_LVL_NORMAL].colours;
sprite[zoom].AllocateData(zoom, sprite[zoom].height * sprite[zoom].width);
sprite[zoom].AllocateData(zoom, static_cast<size_t>(sprite[zoom].height) * sprite[zoom].width);
SpriteLoader::CommonPixel *dst = sprite[zoom].data;
const SpriteLoader::CommonPixel *src = sprite[zoom - 1].data;
@ -290,9 +290,10 @@ static bool PadSingleSprite(SpriteLoader::Sprite *sprite, ZoomLevel zoom, uint p
if (width > UINT16_MAX || height > UINT16_MAX) return false;
/* Copy source data and reallocate sprite memory. */
SpriteLoader::CommonPixel *src_data = MallocT<SpriteLoader::CommonPixel>(sprite->width * sprite->height);
MemCpyT(src_data, sprite->data, sprite->width * sprite->height);
sprite->AllocateData(zoom, width * height);
size_t sprite_size = static_cast<size_t>(sprite->width) * sprite->height;
SpriteLoader::CommonPixel *src_data = MallocT<SpriteLoader::CommonPixel>(sprite_size);
MemCpyT(src_data, sprite->data, sprite_size);
sprite->AllocateData(zoom, static_cast<size_t>(width) * height);
/* Copy with padding to destination. */
SpriteLoader::CommonPixel *src = src_data;

View File

@ -92,7 +92,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t f
if (num != 0) return WarnCorruptSprite(file, file_pos, __LINE__);
sprite->AllocateData(zoom_lvl, sprite->width * sprite->height);
sprite->AllocateData(zoom_lvl, static_cast<size_t>(sprite->width) * sprite->height);
/* Convert colour depth to pixel size. */
int bpp = 0;
@ -168,13 +168,14 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t f
} while (!last_item);
}
} else {
if (dest_size < sprite->width * sprite->height * bpp) {
int64 sprite_size = static_cast<int64>(sprite->width) * sprite->height * bpp;
if (dest_size < sprite_size) {
return WarnCorruptSprite(file, file_pos, __LINE__);
}
if (dest_size > sprite->width * sprite->height * bpp) {
if (dest_size > sprite_size) {
static byte warning_level = 0;
Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite->width * sprite->height * bpp, file.GetSimplifiedFilename(), file_pos);
Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite_size, file.GetSimplifiedFilename(), file_pos);
warning_level = 6;
}

View File

@ -1126,7 +1126,7 @@ void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const Station
!statspec->layouts[plat_len - 1][numtracks - 1].empty()) {
/* Custom layout defined, follow it. */
memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1].data(),
plat_len * numtracks);
static_cast<size_t>(plat_len) * numtracks);
return;
}
@ -1864,7 +1864,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, u
if (ret.Failed()) return ret;
/* Check if this number of road stops can be allocated. */
if (!RoadStop::CanAllocateItem(roadstop_area.w * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS);
if (!RoadStop::CanAllocateItem(static_cast<size_t>(roadstop_area.w) * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS);
ret = BuildStationPart(&st, flags, reuse, roadstop_area, STATIONNAMING_ROAD);
if (ret.Failed()) return ret;

View File

@ -326,7 +326,7 @@ static inline bool AllocHeightMap()
_height_map.size_y = MapSizeY();
/* Allocate memory block for height map row pointers */
size_t total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1);
size_t total_size = static_cast<size_t>(_height_map.size_x + 1) * (_height_map.size_y + 1);
_height_map.dim_x = _height_map.size_x + 1;
_height_map.h.resize(total_size);
@ -580,7 +580,7 @@ static void HeightMapCurves(uint level)
float factor = sqrt((float)_height_map.size_x / (float)_height_map.size_y);
uint sx = Clamp((int)(((1 << level) * factor) + 0.5), 1, 128);
uint sy = Clamp((int)(((1 << level) / factor) + 0.5), 1, 128);
byte *c = AllocaM(byte, sx * sy);
byte *c = AllocaM(byte, static_cast<size_t>(sx) * sy);
for (uint i = 0; i < sx * sy; i++) {
c[i] = Random() % lengthof(curve_maps);

View File

@ -204,7 +204,7 @@ static bool CreateMainSurface(uint w, uint h)
_screen.dst_ptr = _allegro_screen->line[0];
/* Initialise the screen so we don't blit garbage to the screen */
memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);
memset(_screen.dst_ptr, 0, static_cast<size_t>(_screen.height) * _screen.pitch);
/* Set the mouse at the place where we expect it */
poll_mouse();

View File

@ -139,7 +139,7 @@ const char *VideoDriver_Dedicated::Start(const StringList &parm)
this->UpdateAutoResolution();
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
_dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<byte>(_cur_resolution.width * _cur_resolution.height * (bpp / 8));
_dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<byte>(static_cast<size_t>(_cur_resolution.width) * _cur_resolution.height * (bpp / 8));
_screen.width = _screen.pitch = _cur_resolution.width;
_screen.height = _cur_resolution.height;

View File

@ -918,6 +918,7 @@ bool OpenGLBackend::Resize(int w, int h, bool force)
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
int pitch = Align(w, 4);
size_t line_pixel_count = static_cast<size_t>(pitch) * h;
_glViewport(0, 0, w, h);
@ -928,27 +929,27 @@ bool OpenGLBackend::Resize(int w, int h, bool force)
_glDeleteBuffers(1, &this->vid_pbo);
_glGenBuffers(1, &this->vid_pbo);
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
} else {
/* Re-allocate video buffer texture and backing store. */
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_DYNAMIC_DRAW);
_glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_DYNAMIC_DRAW);
}
if (bpp == 32) {
/* Initialize backing store alpha to opaque for 32bpp modes. */
Colour black(0, 0, 0);
if (_glClearBufferSubData != nullptr) {
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, pitch * h * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data);
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, line_pixel_count * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data);
} else {
ClearPixelBuffer<uint32>(pitch * h, black.data);
ClearPixelBuffer<uint32>(line_pixel_count, black.data);
}
} else if (bpp == 8) {
if (_glClearBufferSubData != nullptr) {
byte b = 0;
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b);
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b);
} else {
ClearPixelBuffer<byte>(pitch * h, 0);
ClearPixelBuffer<byte>(line_pixel_count, 0);
}
}
@ -972,18 +973,18 @@ bool OpenGLBackend::Resize(int w, int h, bool force)
_glDeleteBuffers(1, &this->anim_pbo);
_glGenBuffers(1, &this->anim_pbo);
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
_glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT);
} else {
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_DYNAMIC_DRAW);
_glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_DYNAMIC_DRAW);
}
/* Initialize buffer as 0 == no remap. */
if (_glClearBufferSubData != nullptr) {
byte b = 0;
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b);
_glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b);
} else {
ClearPixelBuffer<byte>(pitch * h, 0);
ClearPixelBuffer<byte>(line_pixel_count, 0);
}
_glBindTexture(GL_TEXTURE_2D, this->anim_texture);
@ -1191,7 +1192,7 @@ uint8 *OpenGLBackend::GetAnimBuffer()
this->anim_buffer = _glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
} else if (this->anim_buffer == nullptr) {
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo);
this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _screen.pitch * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, static_cast<GLsizeiptr>(_screen.pitch) * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
}
return (uint8 *)this->anim_buffer;
@ -1491,8 +1492,9 @@ void OpenGLSprite::Update(uint width, uint height, uint level, const SpriteLoade
if (this->tex[TEX_RGBA] != 0) {
/* Unpack pixel data */
Colour *rgba = buf_rgba.Allocate(width * height);
for (size_t i = 0; i < width * height; i++) {
size_t size = static_cast<size_t>(width) * height;
Colour *rgba = buf_rgba.Allocate(size);
for (size_t i = 0; i < size; i++) {
rgba[i].r = data[i].r;
rgba[i].g = data[i].g;
rgba[i].b = data[i].b;
@ -1505,7 +1507,7 @@ void OpenGLSprite::Update(uint width, uint height, uint level, const SpriteLoade
if (this->tex[TEX_REMAP] != 0) {
/* Unpack and align pixel data. */
int pitch = Align(width, 4);
size_t pitch = Align(width, 4);
uint8 *pal = buf_pal.Allocate(pitch * height);
const SpriteLoader::CommonPixel *row = data;