benchmark inicial per a determinar modes de baix rendiment

ajustats escenaris maxims i minims per als diferents modes automatics
This commit is contained in:
2026-03-11 20:30:32 +01:00
parent 09303537a4
commit ea27a771ab
4 changed files with 112 additions and 13 deletions

View File

@@ -283,6 +283,9 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
app_logo_.reset();
}
// Benchmark de rendimiento (determina max_auto_scenario_ para modos automáticos)
runPerformanceBenchmark();
// Precalentar caché: shapes PNG (evitar I/O en primera activación de PNG_SHAPE)
{
unsigned char* tmp = nullptr; size_t tmp_size = 0;
@@ -1289,7 +1292,7 @@ void Engine::executeDemoAction(bool is_lite) {
if (is_lite) {
// DEMO LITE: Verificar condiciones para salto a Logo Mode
if (static_cast<int>(scene_manager_->getBallCount()) >= LOGO_MODE_MIN_BALLS &&
if (static_cast<int>(scene_manager_->getBallCount()) >= BALL_COUNT_SCENARIOS[LOGO_MIN_SCENARIO_IDX] &&
theme_manager_->getCurrentThemeIndex() == 5) { // MONOCHROME
// 10% probabilidad de saltar a Logo Mode
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE) {
@@ -1299,7 +1302,7 @@ void Engine::executeDemoAction(bool is_lite) {
}
} else {
// DEMO COMPLETO: Verificar condiciones para salto a Logo Mode
if (static_cast<int>(scene_manager_->getBallCount()) >= LOGO_MODE_MIN_BALLS) {
if (static_cast<int>(scene_manager_->getBallCount()) >= BALL_COUNT_SCENARIOS[LOGO_MIN_SCENARIO_IDX]) {
// 15% probabilidad de saltar a Logo Mode
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO) {
state_manager_->enterLogoMode(true, current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
@@ -1413,12 +1416,12 @@ void Engine::executeDemoAction(bool is_lite) {
return;
}
// Cambiar escenario (10%) - EXCLUIR índices 0, 6, 7 (1, 50K, 100K pelotas)
// Cambiar escenario (10%) - rango dinámico según benchmark de rendimiento
accumulated_weight += DEMO_WEIGHT_SCENARIO;
if (random_value < accumulated_weight) {
// Escenarios válidos: índices 1, 2, 3, 4, 5 (10, 100, 500, 1000, 10000 pelotas)
int valid_scenarios[] = {1, 2, 3, 4, 5};
int new_scenario = valid_scenarios[rand() % 5];
int auto_max = std::min(max_auto_scenario_, DEMO_AUTO_MAX_SCENARIO);
int range = auto_max - DEMO_AUTO_MIN_SCENARIO + 1;
int new_scenario = DEMO_AUTO_MIN_SCENARIO + (rand() % range);
scene_manager_->changeScenario(new_scenario, current_mode_);
// Si estamos en modo SHAPE, regenerar la figura con nuevo número de pelotas
@@ -1573,9 +1576,10 @@ void Engine::executeRandomizeOnDemoStart(bool is_lite) {
// changeScenario() creará las pelotas y luego llamará a generateShape()
}
// 2. Escenario (excluir índices 0, 6, 7) - AHORA con current_mode_ ya establecido correctamente
int valid_scenarios[] = {1, 2, 3, 4, 5};
int new_scenario = valid_scenarios[rand() % 5];
// 2. Escenario - rango dinámico según benchmark de rendimiento
int auto_max = std::min(max_auto_scenario_, DEMO_AUTO_MAX_SCENARIO);
int range = auto_max - DEMO_AUTO_MIN_SCENARIO + 1;
int new_scenario = DEMO_AUTO_MIN_SCENARIO + (rand() % range);
scene_manager_->changeScenario(new_scenario, current_mode_);
// Si estamos en modo SHAPE, generar la figura y activar atracción
@@ -1621,16 +1625,80 @@ void Engine::executeToggleGravityOnOff() {
}
}
// ============================================================================
// BENCHMARK DE RENDIMIENTO
// ============================================================================
void Engine::runPerformanceBenchmark() {
int num_displays = 0;
SDL_DisplayID* displays = SDL_GetDisplays(&num_displays);
float monitor_hz = 60.0f;
if (displays && num_displays > 0) {
const auto* dm = SDL_GetCurrentDisplayMode(displays[0]);
if (dm && dm->refresh_rate > 0) monitor_hz = dm->refresh_rate;
SDL_free(displays);
}
// Ocultar ventana y desactivar V-sync para medición limpia
SDL_HideWindow(window_);
SDL_SetRenderVSync(renderer_, 0);
const int BENCH_DURATION_MS = 600;
const int WARMUP_FRAMES = 5;
auto restore = [&]() {
SDL_SetRenderVSync(renderer_, vsync_enabled_ ? 1 : 0);
SDL_ShowWindow(window_);
scene_manager_->changeScenario(0, current_mode_);
last_frame_time_ = 0;
};
// Probar de más pesado a más ligero
for (int idx = DEMO_AUTO_MAX_SCENARIO; idx >= DEMO_AUTO_MIN_SCENARIO; --idx) {
scene_manager_->changeScenario(idx, current_mode_);
// Warmup: estabilizar física y pipeline GPU
last_frame_time_ = 0;
for (int w = 0; w < WARMUP_FRAMES; ++w) {
calculateDeltaTime();
SDL_Event e; while (SDL_PollEvent(&e)) {}
update();
render();
}
// Medición
int frame_count = 0;
Uint64 start = SDL_GetTicks();
while (SDL_GetTicks() - start < static_cast<Uint64>(BENCH_DURATION_MS)) {
calculateDeltaTime();
SDL_Event e;
while (SDL_PollEvent(&e)) { /* descartar */ }
update();
render();
++frame_count;
}
float measured_fps = static_cast<float>(frame_count) / (BENCH_DURATION_MS / 1000.0f);
if (measured_fps >= monitor_hz) {
max_auto_scenario_ = idx;
restore();
return;
}
}
// Fallback: escenario mínimo
max_auto_scenario_ = DEMO_AUTO_MIN_SCENARIO;
restore();
}
// ============================================================================
// CALLBACKS PARA STATEMANAGER - LOGO MODE
// ============================================================================
// Callback para StateManager - Configuración visual al entrar a LOGO MODE
void Engine::executeEnterLogoMode(size_t ball_count) {
// Verificar mínimo de pelotas
if (static_cast<int>(ball_count) < LOGO_MODE_MIN_BALLS) {
// Ajustar a 5000 pelotas automáticamente
scene_manager_->changeScenario(5, current_mode_); // Escenario 5000 pelotas (índice 5 en BALL_COUNT_SCENARIOS)
// Verificar mínimo de pelotas (LOGO_MIN_SCENARIO_IDX = índice 4 → 1000 bolas)
if (scene_manager_->getCurrentScenario() < LOGO_MIN_SCENARIO_IDX) {
scene_manager_->changeScenario(LOGO_MIN_SCENARIO_IDX, current_mode_);
}
// Guardar estado previo (para restaurar al salir)