summaryrefslogtreecommitdiff
path: root/src/video/cocoa
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-02-20 19:01:45 +0100
committerMichael Lutz <michi@icosahedron.de>2021-02-20 21:14:44 +0100
commitf3c192c63d77de641c84fd2d808e11418b9c15fd (patch)
tree1a3fbb4a4ad96fc37a255d13cfd8c5425579a2fc /src/video/cocoa
parent61275df7dafaca3a8c6c6d726ad399dd055263e3 (diff)
downloadopenttd-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.h4
-rw-r--r--src/video/cocoa/cocoa_v.mm66
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. */