From e98c2e0535b6baf1691cff53996ecfd02121899f Mon Sep 17 00:00:00 2001
From: Jonas Kulla <Nyocurio@gmail.com>
Date: Wed, 27 Jul 2016 11:59:08 +0200
Subject: [PATCH] Bitmap: Don't throw away cached surface in setPixel()

Instead, update the surface with the same change. For many
consecutive getPixel() -> setPixel() calls on the same bitmap,
this avoids calling glReadPixels at every iteration.
---
 src/bitmap.cpp | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/bitmap.cpp b/src/bitmap.cpp
index b2d1f3d..a677207 100644
--- a/src/bitmap.cpp
+++ b/src/bitmap.cpp
@@ -221,9 +221,9 @@ struct BitmapPrivate
 		surf = surfConv;
 	}
 
-	void onModified()
+	void onModified(bool freeSurface = true)
 	{
-		if (surface)
+		if (surface && freeSurface)
 		{
 			SDL_FreeSurface(surface);
 			surface = 0;
@@ -825,7 +825,16 @@ void Bitmap::setPixel(int x, int y, const Color &color)
 
 	p->addTaintedArea(IntRect(x, y, 1, 1));
 
-	p->onModified();
+	/* Setting just a single pixel is no reason to throw away the
+	 * whole cached surface; we can just apply the same change */
+
+	if (p->surface)
+	{
+		uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y);
+		surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]);
+	}
+
+	p->onModified(false);
 }
 
 void Bitmap::hueChange(int hue)