diff options
-rw-r--r-- | src/video/sdl2_v.cpp | 79 | ||||
-rw-r--r-- | src/video/sdl2_v.h | 1 |
2 files changed, 32 insertions, 48 deletions
diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 61edea6e0..28ce0f880 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -73,7 +73,7 @@ void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height) _num_dirty_rects++; } -static void UpdatePalette(bool init = false) +static void UpdatePalette() { SDL_Color pal[256]; @@ -86,8 +86,19 @@ static void UpdatePalette(bool init = false) SDL_SetPaletteColors(_sdl_palette, pal, _local_palette.first_dirty, _local_palette.count_dirty); SDL_SetSurfacePalette(_sdl_surface, _sdl_palette); +} - if (_sdl_surface != _sdl_real_surface && init) { +static void MakePalette() +{ + if (_sdl_palette == nullptr) { + _sdl_palette = SDL_AllocPalette(256); + if (_sdl_palette == nullptr) usererror("SDL2: Couldn't allocate palette: %s", SDL_GetError()); + } + + _local_palette = _cur_palette; + UpdatePalette(); + + if (_sdl_surface != _sdl_real_surface) { /* When using a shadow surface, also set our palette on the real screen. This lets SDL * allocate as many colors (or approximations) as * possible, instead of using only the default SDL @@ -110,33 +121,22 @@ static void UpdatePalette(bool init = false) */ SDL_SetSurfacePalette(_sdl_real_surface, _sdl_palette); } - - if (_sdl_surface != _sdl_real_surface && !init) { - /* We're not using real hardware palette, but are letting SDL - * approximate the palette during shadow -> screen copy. To - * change the palette, we need to recopy the entire screen. - * - * Note that this operation can slow down the rendering - * considerably, especially since changing the shadow - * palette will need the next blit to re-detect the - * best mapping of shadow palette colors to real palette - * colors from scratch. - */ - SDL_BlitSurface(_sdl_surface, nullptr, _sdl_real_surface, nullptr); - SDL_UpdateWindowSurface(_sdl_window); - } } -static void InitPalette() +void VideoDriver_SDL::CheckPaletteAnim() { - _cur_palette.first_dirty = 0; - _cur_palette.count_dirty = 256; + if (_cur_palette.count_dirty == 0) return; + _local_palette = _cur_palette; - UpdatePalette(true); + this->MakeDirty(0, 0, _screen.width, _screen.height); } -static void CheckPaletteAnim() +static void DrawSurfaceToScreen() { + PerformanceMeasurer framerate(PFE_VIDEO); + + if (_num_dirty_rects == 0) return; + if (_cur_palette.count_dirty != 0) { Blitter *blitter = BlitterFactory::GetCurrentBlitter(); @@ -157,18 +157,8 @@ static void CheckPaletteAnim() } _cur_palette.count_dirty = 0; } -} - -static void DrawSurfaceToScreen() -{ - PerformanceMeasurer framerate(PFE_VIDEO); - int n = _num_dirty_rects; - if (n == 0) return; - - _num_dirty_rects = 0; - - if (n > MAX_DIRTY_RECTS) { + if (_num_dirty_rects > MAX_DIRTY_RECTS) { if (_sdl_surface != _sdl_real_surface) { SDL_BlitSurface(_sdl_surface, nullptr, _sdl_real_surface, nullptr); } @@ -176,13 +166,15 @@ static void DrawSurfaceToScreen() SDL_UpdateWindowSurface(_sdl_window); } else { if (_sdl_surface != _sdl_real_surface) { - for (int i = 0; i < n; i++) { + for (int i = 0; i < _num_dirty_rects; i++) { SDL_BlitSurface(_sdl_surface, &_dirty_rects[i], _sdl_real_surface, &_dirty_rects[i]); } } - SDL_UpdateWindowSurfaceRects(_sdl_window, _dirty_rects, n); + SDL_UpdateWindowSurfaceRects(_sdl_window, _dirty_rects, _num_dirty_rects); } + + _num_dirty_rects = 0; } static void DrawSurfaceToScreenThread() @@ -195,7 +187,6 @@ static void DrawSurfaceToScreenThread() _draw_signal->wait(*_draw_mutex); while (_draw_continue) { - CheckPaletteAnim(); /* Then just draw and wait till we stop */ DrawSurfaceToScreen(); _draw_signal->wait(lock); @@ -362,14 +353,6 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize) _sdl_surface = _sdl_real_surface; } - if (_sdl_palette == nullptr) { - _sdl_palette = SDL_AllocPalette(256); - if (_sdl_palette == nullptr) { - DEBUG(driver, 0, "SDL_AllocPalette() failed: %s", SDL_GetError()); - return false; - } - } - /* Delay drawing for this cycle; the next cycle will redraw the whole screen */ _num_dirty_rects = 0; @@ -378,6 +361,8 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize) _screen.pitch = _sdl_surface->pitch / (bpp / 8); _screen.dst_ptr = _sdl_surface->pixels; + MakePalette(); + /* When in full screen, we will always have the mouse cursor * within the window, even though SDL does not give us the * appropriate event to know this. */ @@ -385,7 +370,6 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize) BlitterFactory::GetCurrentBlitter()->PostResize(); - InitPalette(); GameSizeChanged(); return true; } @@ -813,7 +797,7 @@ void VideoDriver_SDL::LoopOnce() if (_draw_mutex != nullptr) draw_lock.lock(); UpdateWindows(); - _local_palette = _cur_palette; + this->CheckPaletteAnim(); } else { /* Release the thread while sleeping */ if (_draw_mutex != nullptr) { @@ -837,7 +821,6 @@ void VideoDriver_SDL::LoopOnce() _draw_signal->notify_one(); } else { /* Oh, we didn't have threads, then just draw unthreaded */ - CheckPaletteAnim(); DrawSurfaceToScreen(); } } @@ -848,7 +831,7 @@ void VideoDriver_SDL::MainLoop() last_cur_ticks = cur_ticks; next_tick = cur_ticks + MILLISECONDS_PER_TICK; - CheckPaletteAnim(); + this->CheckPaletteAnim(); if (_draw_threaded) { /* Initialise the mutex first, because that's the thing we *need* diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index a72325674..d1c4d957c 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -50,6 +50,7 @@ private: void MainLoopCleanup(); bool CreateMainSurface(uint w, uint h, bool resize); bool CreateMainWindow(uint w, uint h); + void CheckPaletteAnim(); #ifdef __EMSCRIPTEN__ /* Convert a constant pointer back to a non-constant pointer to a member function. */ |