diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-02-20 19:01:45 +0100 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2021-02-20 21:14:44 +0100 |
commit | f3c192c63d77de641c84fd2d808e11418b9c15fd (patch) | |
tree | 1a3fbb4a4ad96fc37a255d13cfd8c5425579a2fc /src/video/cocoa | |
parent | 61275df7dafaca3a8c6c6d726ad399dd055263e3 (diff) | |
download | openttd-f3c192c63d77de641c84fd2d808e11418b9c15fd.tar.xz |
Codechange: [OSX] Only keep a total dirty rect for drawing.
When drawing an 8bpp screen buffer, palette resolving was done for each
dirty rectangle. In areas with high activity, this would mean a pixel might
have been resolved multiple times. Also, if too many individual updates
were queued, the whole screen would be refreshed, even if unnecessary.
All other drivers only keep one overall dirty rect, so do it here as well.
Diffstat (limited to 'src/video/cocoa')
-rw-r--r-- | src/video/cocoa/cocoa_v.h | 4 | ||||
-rw-r--r-- | src/video/cocoa/cocoa_v.mm | 66 |
2 files changed, 26 insertions, 44 deletions
diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 7e4d8c9fd..f9f678157 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -32,10 +32,8 @@ private: void *pixel_buffer; ///< used for direct pixel access void *window_buffer; ///< Colour translation from palette to screen - static const int MAX_DIRTY_RECTS = 100; + Rect dirty_rect; ///< Region of the screen that needs redrawing. - Rect dirty_rects[MAX_DIRTY_RECTS]; ///< dirty rectangles - uint num_dirty_rects; ///< Number of dirty rectangles uint32 palette[256]; ///< Colour Palette public: diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 91cfe42ae..c84fd1a98 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -26,7 +26,7 @@ #include "../../openttd.h" #include "../../debug.h" -#include "../../core/geometry_type.hpp" +#include "../../core/geometry_func.hpp" #include "../../core/math_func.hpp" #include "cocoa_v.h" #include "cocoa_wnd.h" @@ -125,7 +125,7 @@ VideoDriver_Cocoa::VideoDriver_Cocoa() this->color_space = nullptr; this->cgcontext = nullptr; - this->num_dirty_rects = lengthof(this->dirty_rects); + this->dirty_rect = {}; } /** Stop Cocoa video driver. */ @@ -192,13 +192,8 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm) */ void VideoDriver_Cocoa::MakeDirty(int left, int top, int width, int height) { - if (this->num_dirty_rects < lengthof(this->dirty_rects)) { - dirty_rects[this->num_dirty_rects].left = left; - dirty_rects[this->num_dirty_rects].top = top; - dirty_rects[this->num_dirty_rects].right = left + width; - dirty_rects[this->num_dirty_rects].bottom = top + height; - } - this->num_dirty_rects++; + Rect r = {left, top, left + width, top + height}; + this->dirty_rect = BoundingRect(this->dirty_rect, r); } /** @@ -473,40 +468,29 @@ void VideoDriver_Cocoa::Paint() PerformanceMeasurer framerate(PFE_VIDEO); /* Check if we need to do anything */ - if (this->num_dirty_rects == 0 || [ this->window isMiniaturized ]) return; - - if (this->num_dirty_rects >= lengthof(this->dirty_rects)) { - this->num_dirty_rects = 1; - this->dirty_rects[0].left = 0; - this->dirty_rects[0].top = 0; - this->dirty_rects[0].right = this->window_width; - this->dirty_rects[0].bottom = this->window_height; - } + if (IsEmptyRect(this->dirty_rect) || [ this->window isMiniaturized ]) return; - /* Build the region of dirty rectangles */ - for (uint i = 0; i < this->num_dirty_rects; i++) { - /* We only need to blit in indexed mode since in 32bpp mode the game draws directly to the image. */ - if (this->buffer_depth == 8) { - BlitIndexedToView32( - this->dirty_rects[i].left, - this->dirty_rects[i].top, - this->dirty_rects[i].right, - this->dirty_rects[i].bottom - ); - } + /* We only need to blit in indexed mode since in 32bpp mode the game draws directly to the image. */ + if (this->buffer_depth == 8) { + BlitIndexedToView32( + this->dirty_rect.left, + this->dirty_rect.top, + this->dirty_rect.right, + this->dirty_rect.bottom + ); + } - NSRect dirtyrect; - dirtyrect.origin.x = this->dirty_rects[i].left; - dirtyrect.origin.y = this->window_height - this->dirty_rects[i].bottom; - dirtyrect.size.width = this->dirty_rects[i].right - this->dirty_rects[i].left; - dirtyrect.size.height = this->dirty_rects[i].bottom - this->dirty_rects[i].top; + NSRect dirtyrect; + dirtyrect.origin.x = this->dirty_rect.left; + dirtyrect.origin.y = this->window_height - this->dirty_rect.bottom; + dirtyrect.size.width = this->dirty_rect.right - this->dirty_rect.left; + dirtyrect.size.height = this->dirty_rect.bottom - this->dirty_rect.top; - /* Normally drawRect will be automatically called by Mac OS X during next update cycle, - * and then blitting will occur. */ - [ this->cocoaview setNeedsDisplayInRect:[ this->cocoaview getVirtualRect:dirtyrect ] ]; - } + /* Normally drawRect will be automatically called by Mac OS X during next update cycle, + * and then blitting will occur. */ + [ this->cocoaview setNeedsDisplayInRect:[ this->cocoaview getVirtualRect:dirtyrect ] ]; - this->num_dirty_rects = 0; + this->dirty_rect = {}; } /** Update the palette. */ @@ -522,7 +506,7 @@ void VideoDriver_Cocoa::UpdatePalette(uint first_color, uint num_colors) this->palette[i] = clr; } - this->num_dirty_rects = lengthof(this->dirty_rects); + this->MakeDirty(0, 0, _screen.width, _screen.height); } /** Clear buffer to opaque black. */ @@ -580,8 +564,8 @@ void VideoDriver_Cocoa::AllocateBackingStore() } /* Redraw screen */ - this->num_dirty_rects = lengthof(this->dirty_rects); this->GameSizeChanged(); + this->MakeDirty(0, 0, _screen.width, _screen.height); } /** Check if palette updates need to be performed. */ |