diff --git a/src/gl/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp
index fe523c79d..253d91f4b 100644
--- a/src/gl/textures/gl_hqresize.cpp
+++ b/src/gl/textures/gl_hqresize.cpp
@@ -46,6 +46,17 @@
 #include "gl/xbr/xbrz.h"
 #include "gl/xbr/xbrz_old.h"
 
+#ifdef __APPLE__
+#	include <AvailabilityMacros.h>
+#	if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#		define GZ_USE_LIBDISPATCH
+#	endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#endif // __APPLE__
+
+#ifdef GZ_USE_LIBDISPATCH
+#	include <dispatch/dispatch.h>
+#endif // GZ_USE_LIBDISPATCH
+
 CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
 {
 	if (self < 0 || self > 16)
@@ -76,6 +87,22 @@ CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1);
 CVAR (Flag, gl_texture_hqresize_sprites, gl_texture_hqresize_targets, 2);
 CVAR (Flag, gl_texture_hqresize_fonts, gl_texture_hqresize_targets, 4);
 
+#ifdef GZ_USE_LIBDISPATCH
+CVAR(Bool, gl_texture_hqresize_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
+
+CUSTOM_CVAR(Int, gl_texture_hqresize_mt_width, 16, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
+{
+	if (self < 2)    self = 2;
+	if (self > 1024) self = 1024;
+}
+
+CUSTOM_CVAR(Int, gl_texture_hqresize_mt_height, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
+{
+	if (self < 2)    self = 2;
+	if (self > 1024) self = 1024;
+}
+#endif // GZ_USE_LIBDISPATCH
+
 
 static void scale2x ( uint32* inputBuffer, uint32* outputBuffer, int inWidth, int inHeight )
 {
@@ -261,26 +288,38 @@ static unsigned char *xbrzHelper( void (*xbrzFunction) ( size_t, const uint32_t*
 	outHeight = N *inHeight;
 
 	unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
-	xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer), inWidth, inHeight, xbrz::ARGB, xbrz::ScalerCfg(), 0, std::numeric_limits<int>::max());
+	
+#ifdef GZ_USE_LIBDISPATCH
+	const int thresholdWidth  = gl_texture_hqresize_mt_width;
+	const int thresholdHeight = gl_texture_hqresize_mt_height;
+	
+	if (gl_texture_hqresize_multithread
+		&& inWidth  > thresholdWidth
+		&& inHeight > thresholdHeight)
+	{
+		const dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+		
+		dispatch_apply(inHeight / thresholdHeight + 1, queue, ^(size_t sliceY)
+		{
+			xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer),
+				inWidth, inHeight, xbrz::ARGB, xbrz::ScalerCfg(), sliceY * thresholdHeight, (sliceY + 1) * thresholdHeight);
+		});
+	}
+	else
+#endif // GZ_USE_LIBDISPATCH
+	{
+		xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer),
+			inWidth, inHeight, xbrz::ARGB, xbrz::ScalerCfg(), 0, std::numeric_limits<int>::max());
+	}
+
 	delete[] inputBuffer;
 	return newBuffer;
 }
 
-static unsigned char *xbrzoldHelper( void (*xbrzFunction) ( size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, const xbrz_old::ScalerCfg& cfg, int yFirst, int yLast ),
-							  const int N,
-							  unsigned char *inputBuffer,
-							  const int inWidth,
-							  const int inHeight,
-							  int &outWidth,
-							  int &outHeight )
+static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight, xbrz::ColorFormat colFmt, const xbrz::ScalerCfg& cfg, int yFirst, int yLast)
 {
-	outWidth = N * inWidth;
-	outHeight = N *inHeight;
-
-	unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
-	xbrzFunction(N, reinterpret_cast<uint32_t*>(inputBuffer), reinterpret_cast<uint32_t*>(newBuffer), inWidth, inHeight, xbrz_old::ScalerCfg(), 0, std::numeric_limits<int>::max());
-	delete[] inputBuffer;
-	return newBuffer;
+	static_assert(sizeof(xbrz::ScalerCfg) == sizeof(xbrz_old::ScalerCfg), "ScalerCfg classes have different layout");
+	xbrz_old::scale(factor, src, trg, srcWidth, srcHeight, reinterpret_cast<const xbrz_old::ScalerCfg&>(cfg), yFirst, yLast);
 }
 
 
@@ -372,7 +411,7 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
 		case 13:
 		case 14:
 		case 15:
-			return xbrzoldHelper(xbrz_old::scale, type - 11, inputBuffer, inWidth, inHeight, outWidth, outHeight );
+			return xbrzHelper(xbrzOldScale, type - 11, inputBuffer, inWidth, inHeight, outWidth, outHeight );
 			
 		}
 	}