Ensure that sprite aligner click to pick sprites is thread safe
Use a mutex for list of sprite IDs found in (threaded) draw jobs
This commit is contained in:
@@ -1212,7 +1212,7 @@ static void GfxBlitter(const GfxBlitterCtx &ctx, const Sprite *sprite, int x, in
|
|||||||
if (topleft <= clicked && clicked <= bottomright) {
|
if (topleft <= clicked && clicked <= bottomright) {
|
||||||
uint offset = (((size_t)clicked - (size_t)topleft) / (blitter->GetScreenDepth() / 8)) % bp.pitch;
|
uint offset = (((size_t)clicked - (size_t)topleft) / (blitter->GetScreenDepth() / 8)) % bp.pitch;
|
||||||
if (offset < (uint)bp.width) {
|
if (offset < (uint)bp.width) {
|
||||||
include(_newgrf_debug_sprite_picker.sprites, sprite_id);
|
_newgrf_debug_sprite_picker.FoundSpriteDuringDrawing(sprite_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,9 +24,15 @@ enum NewGrfDebugSpritePickerMode {
|
|||||||
|
|
||||||
/** Spritepicker of SpriteAligner */
|
/** Spritepicker of SpriteAligner */
|
||||||
struct NewGrfDebugSpritePicker {
|
struct NewGrfDebugSpritePicker {
|
||||||
NewGrfDebugSpritePickerMode mode; ///< Current state
|
NewGrfDebugSpritePickerMode mode = SPM_NONE; ///< Current state
|
||||||
void *clicked_pixel; ///< Clicked pixel (pointer to blitter buffer)
|
void *clicked_pixel = nullptr; ///< Clicked pixel (pointer to blitter buffer)
|
||||||
std::vector<SpriteID> sprites; ///< Sprites found
|
std::vector<SpriteID> sprites; ///< Sprites found
|
||||||
|
|
||||||
|
void DrawingComplete();
|
||||||
|
void FoundSpriteDuringDrawing(SpriteID sprite);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<SpriteID> draw_found_sprites; ///< Sprites found (used from threaded drawing jobs, mutex must be held for all accesses)
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker;
|
extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker;
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "window_gui.h"
|
#include "window_gui.h"
|
||||||
#include "window_func.h"
|
#include "window_func.h"
|
||||||
#include "random_access_file_type.h"
|
#include "random_access_file_type.h"
|
||||||
@@ -51,11 +52,27 @@
|
|||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/** The sprite picker. */
|
/** The sprite picker. */
|
||||||
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, nullptr, std::vector<SpriteID>() };
|
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker;
|
||||||
|
|
||||||
|
static std::mutex _newgrf_debug_sprite_picker_draw_mutex;
|
||||||
|
|
||||||
|
void NewGrfDebugSpritePicker::DrawingComplete()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_newgrf_debug_sprite_picker_draw_mutex);
|
||||||
|
this->sprites.swap(this->draw_found_sprites);
|
||||||
|
this->draw_found_sprites.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewGrfDebugSpritePicker::FoundSpriteDuringDrawing(SpriteID sprite)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_newgrf_debug_sprite_picker_draw_mutex);
|
||||||
|
include(this->draw_found_sprites, sprite);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the feature index related to the window number.
|
* Get the feature index related to the window number.
|
||||||
|
@@ -3082,6 +3082,7 @@ void HandleMouseEvents()
|
|||||||
/* We are done with the last draw-frame, so we know what sprites we
|
/* We are done with the last draw-frame, so we know what sprites we
|
||||||
* clicked on. Reset the picker mode and invalidate the window. */
|
* clicked on. Reset the picker mode and invalidate the window. */
|
||||||
_newgrf_debug_sprite_picker.mode = SPM_NONE;
|
_newgrf_debug_sprite_picker.mode = SPM_NONE;
|
||||||
|
_newgrf_debug_sprite_picker.DrawingComplete();
|
||||||
InvalidateWindowData(WC_SPRITE_ALIGNER, 0, 1);
|
InvalidateWindowData(WC_SPRITE_ALIGNER, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user