[Scummvm-git-logs] scummvm master -> 2a9d29f067a8e5f292514ab0c10d055c286178de

sev- sev at scummvm.org
Tue Sep 13 22:15:39 CEST 2016


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
521ba2cb8a OSYSTEM: Introduce a method allowing to draw a background activity icon
4d68b93aba CLOUD: Switch to the new OSD API
05bc82b622 SDL: Switch the surface renderer to use small surfaces for OSD drawing
9cbaad6140 SDL: Switch the OpenGL renderer to use small textures to draw the OSD
0802bbd8ee OSYSTEM: Remove the API allowing to draw to the OSD surface directly
2a9d29f067 Merge pull request #824 from bgK/osd


Commit: 521ba2cb8ac6cbe4240ad4da7ad44d13449e3943
    https://github.com/scummvm/scummvm/commit/521ba2cb8ac6cbe4240ad4da7ad44d13449e3943
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-09-13T20:25:13+02:00

Commit Message:
OSYSTEM: Introduce a method allowing to draw a background activity icon

Changed paths:
    backends/graphics/graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    common/system.h



diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 921dfca..271a482 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -87,6 +87,7 @@ public:
 	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {}
 	virtual void clearOSD() {}
 	virtual Graphics::PixelFormat getOSDFormat() { return Graphics::PixelFormat(); }
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) {}
 
 
 	// Graphics::PaletteManager interface
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index e1bdf15..13db277 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -253,6 +253,10 @@ Graphics::PixelFormat ModularBackend::getOSDFormat() {
 	return _graphicsManager->getOSDFormat();
 }
 
+void ModularBackend::displayActivityIconOnOSD(const Graphics::Surface *icon) {
+	_graphicsManager->displayActivityIconOnOSD(icon);
+}
+
 void ModularBackend::quit() {
 	exit(0);
 }
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 9cde279..886f91c 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -130,6 +130,7 @@ public:
 	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h);
 	virtual void clearOSD();
 	virtual Graphics::PixelFormat getOSDFormat();
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
 
 	//@}
 
diff --git a/common/system.h b/common/system.h
index eb9a39b..b07a5ff 100644
--- a/common/system.h
+++ b/common/system.h
@@ -1102,6 +1102,25 @@ public:
 	virtual void displayMessageOnOSD(const char *msg) = 0;
 
 	/**
+	 * Display an icon indicating background activity
+	 *
+	 * The icon is displayed in an 'on screen display'. It is visible above
+	 * the regular screen content or near it.
+	 *
+	 * The caller keeps ownership of the icon. It is acceptable to free
+	 * the surface just after the call.
+	 *
+	 * There is no preferred pixel format for the icon. The backend should
+	 * convert its copy of the icon to an appropriate format.
+	 *
+	 * The caller must call this method again with a null pointer
+	 * as a parameter to indicate the icon should no longer be displayed.
+	 *
+	 * @param icon the icon to display on screen
+	 */
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) = 0;
+
+	/**
 	* Blit a bitmap to the 'on screen display'.
 	*
 	* If the current pixel format has one byte per pixel, the graphics data


Commit: 4d68b93abacf78dae480a52e242a0644896e5101
    https://github.com/scummvm/scummvm/commit/4d68b93abacf78dae480a52e242a0644896e5101
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-09-13T20:29:09+02:00

Commit Message:
CLOUD: Switch to the new OSD API

Changed paths:
    backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
    backends/cloud/googledrive/googledrivestorage.cpp
    backends/networking/curl/cloudicon.cpp
    backends/networking/curl/cloudicon.h



diff --git a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
index 3c31ddb..0b90ec6 100644
--- a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
+++ b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
@@ -27,6 +27,7 @@
 #include "backends/networking/curl/curljsonrequest.h"
 #include "backends/networking/curl/networkreadstream.h"
 #include "common/json.h"
+#include "common/debug.h"
 
 namespace Cloud {
 namespace Dropbox {
diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp
index f4a6fba..ec4c844 100644
--- a/backends/cloud/googledrive/googledrivestorage.cpp
+++ b/backends/cloud/googledrive/googledrivestorage.cpp
@@ -33,6 +33,7 @@
 #include "common/config-manager.h"
 #include "common/debug.h"
 #include "common/json.h"
+#include "common/debug.h"
 #include <curl/curl.h>
 
 #ifdef ENABLE_RELEASE
diff --git a/backends/networking/curl/cloudicon.cpp b/backends/networking/curl/cloudicon.cpp
index 3ae6fd2..9aa08af 100644
--- a/backends/networking/curl/cloudicon.cpp
+++ b/backends/networking/curl/cloudicon.cpp
@@ -39,7 +39,11 @@ CloudIcon::CloudIcon():
 	initIcons();
 }
 
-CloudIcon::~CloudIcon() {}
+CloudIcon::~CloudIcon() {
+	_icon.free();
+	_disabledIcon.free();
+	_alphaIcon.free();
+}
 
 bool CloudIcon::draw() {
 	bool stop = false;
@@ -48,7 +52,6 @@ bool CloudIcon::draw() {
 	if (CloudMan.isWorking() || _disabledFrames > 0) {
 		if (g_system) {
 			if (!_wasVisible) {
-				g_system->clearOSD();
 				_wasVisible = true;
 			}
 			--_disabledFrames;
@@ -81,13 +84,11 @@ bool CloudIcon::draw() {
 	}
 
 	if (g_system) {
-		Graphics::TransparentSurface *surface = &_icon;
-		makeAlphaIcon((_showingDisabled ? _disabledIcon : _icon), _currentAlpha);
-		if (_alphaIcon.getPixels())
-			surface = &_alphaIcon;
-		if (surface && surface->getPixels()) {
-			int x = g_system->getOverlayWidth() - surface->w - 10, y = 10;
-			g_system->copyRectToOSD(surface->getPixels(), surface->pitch, x, y, surface->w, surface->h);
+		if (!stop) {
+			makeAlphaIcon((_showingDisabled ? _disabledIcon : _icon), _currentAlpha);
+			g_system->displayActivityIconOnOSD(&_alphaIcon);
+		} else {
+			g_system->displayActivityIconOnOSD(nullptr);
 		}
 	}
 
@@ -112,36 +113,17 @@ void CloudIcon::initIcons() {
 	_iconsInited = true;
 }
 
-void CloudIcon::loadIcon(Graphics::TransparentSurface &icon, byte *data, uint32 size) {
+void CloudIcon::loadIcon(Graphics::Surface &icon, byte *data, uint32 size) {
 	Image::PNGDecoder decoder;
 	Common::MemoryReadStream stream(data, size);
 	if (!decoder.loadStream(stream))
 		error("CloudIcon::loadIcon: error decoding PNG");
 
-	Graphics::TransparentSurface *s = new Graphics::TransparentSurface(*decoder.getSurface(), true);
-	if (s) {
-		Graphics::PixelFormat f = g_system->getOSDFormat();
-		if (f != s->format) {
-			// Graphics::TransparentSurface::convertTo(f) errors out if the format is not 2Bpp or 4Bpp.
-			// We don't need to error out as we can recover from it. So check the format before calling convertTo(f);
-			Graphics::TransparentSurface *s2 = nullptr;
-			if (f.bytesPerPixel == 2 || f.bytesPerPixel == 4)
-				s2 = s->convertTo(f);
-			if (s2)
-				icon.copyFrom(*s2);
-			else
-				warning("CloudIcon::loadIcon: failed converting TransparentSurface");
-			delete s2;
-		} else {
-			icon.copyFrom(*s);
-		}
-		delete s;
-	} else {
-		warning("CloudIcon::loadIcon: failed reading TransparentSurface from PNGDecoder");
-	}
+	const Graphics::Surface *s = decoder.getSurface();
+	return icon.copyFrom(*s);
 }
 
-void CloudIcon::makeAlphaIcon(Graphics::TransparentSurface &icon, float alpha) {
+void CloudIcon::makeAlphaIcon(Graphics::Surface &icon, float alpha) {
 	_alphaIcon.copyFrom(icon);
 
 	byte *pixels = (byte *)_alphaIcon.getPixels();
diff --git a/backends/networking/curl/cloudicon.h b/backends/networking/curl/cloudicon.h
index 316cb67..d6ea60b 100644
--- a/backends/networking/curl/cloudicon.h
+++ b/backends/networking/curl/cloudicon.h
@@ -23,7 +23,7 @@
 #ifndef BACKENDS_NETWORKING_CURL_CLOUDICON_H
 #define BACKENDS_NETWORKING_CURL_CLOUDICON_H
 
-#include "graphics/transparent_surface.h"
+#include "graphics/surface.h"
 
 namespace Networking {
 
@@ -31,14 +31,14 @@ class CloudIcon {
 	static const float ALPHA_STEP, ALPHA_MAX, ALPHA_MIN;
 
 	bool _wasVisible, _iconsInited, _showingDisabled;
-	Graphics::TransparentSurface _icon, _disabledIcon, _alphaIcon;
+	Graphics::Surface _icon, _disabledIcon, _alphaIcon;
 	float _currentAlpha;
 	bool _alphaRising;
 	int _disabledFrames;
 
 	void initIcons();
-	void loadIcon(Graphics::TransparentSurface &icon, byte *data, uint32 size);
-	void makeAlphaIcon(Graphics::TransparentSurface &icon, float alpha);
+	void loadIcon(Graphics::Surface &icon, byte *data, uint32 size);
+	void makeAlphaIcon(Graphics::Surface &icon, float alpha);
 
 public:
 	CloudIcon();


Commit: 05bc82b6225f79ad42e6259be8e227aed6e7c0dc
    https://github.com/scummvm/scummvm/commit/05bc82b6225f79ad42e6259be8e227aed6e7c0dc
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-09-13T20:33:42+02:00

Commit Message:
SDL: Switch the surface renderer to use small surfaces for OSD drawing

Changed paths:
    backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
    backends/graphics/gph/gph-graphics.cpp
    backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h



diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
index 0938be2..9e75dd1 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
@@ -257,38 +257,6 @@ void DINGUXSdlGraphicsManager::internUpdateScreen() {
 		_forceFull = true;
 	}
 
-#ifdef USE_OSD
-	// OSD visible (i.e. non-transparent)?
-	if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT) {
-		// Updated alpha value
-		const int diff = SDL_GetTicks() - _osdMessageFadeStartTime;
-		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
-				// Back to full transparency
-				_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
-			} else {
-				// Do a linear fade out...
-				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
-				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
-			}
-			_forceFull = true;
-		}
-
-		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
-			removeOSDMessage();
-		} else {
-			if (_osdMessageSurface && _osdSurface) {
-				SDL_Rect dstRect;
-				dstRect.x = (_osdSurface->w - _osdMessageSurface->w) / 2;
-				dstRect.y = (_osdSurface->h - _osdMessageSurface->h) / 2;
-				dstRect.w = _osdMessageSurface->w;
-				dstRect.h = _osdMessageSurface->h;
-				blitOSDMessage(dstRect);
-			}
-		}
-	}
-#endif
-
 	if (!_overlayVisible) {
 		origSurf = _screen;
 		srcSurf = _tmpscreen;
@@ -310,6 +278,10 @@ void DINGUXSdlGraphicsManager::internUpdateScreen() {
 	if (_mouseNeedsRedraw)
 		undrawMouse();
 
+#ifdef USE_OSD
+	updateOSD();
+#endif
+
 	// Force a full redraw if requested
 	if (_forceFull) {
 		_numDirtyRects = 1;
@@ -417,8 +389,7 @@ void DINGUXSdlGraphicsManager::internUpdateScreen() {
 		drawMouse();
 
 #ifdef USE_OSD
-		if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT)
-			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		drawOSD();
 #endif
 		// Finally, blit all our changes to the screen
 		SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp
index bd0f246..a195121 100644
--- a/backends/graphics/gph/gph-graphics.cpp
+++ b/backends/graphics/gph/gph-graphics.cpp
@@ -277,38 +277,6 @@ void GPHGraphicsManager::internUpdateScreen() {
 		_forceFull = true;
 	}
 
-#ifdef USE_OSD
-	// OSD visible (i.e. non-transparent)?
-	if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT) {
-		// Updated alpha value
-		const int diff = SDL_GetTicks() - _osdMessageFadeStartTime;
-		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
-				// Back to full transparency
-				_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
-			} else {
-				// Do a linear fade out...
-				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
-				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
-			}
-			_forceFull = true;
-		}
-
-		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
-			removeOSDMessage();
-		} else {
-			if (_osdMessageSurface && _osdSurface) {
-				SDL_Rect dstRect;
-				dstRect.x = (_osdSurface->w - _osdMessageSurface->w) / 2;
-				dstRect.y = (_osdSurface->h - _osdMessageSurface->h) / 2;
-				dstRect.w = _osdMessageSurface->w;
-				dstRect.h = _osdMessageSurface->h;
-				blitOSDMessage(dstRect);
-			}
-		}
-	}
-#endif
-
 	if (!_overlayVisible) {
 		origSurf = _screen;
 		srcSurf = _tmpscreen;
@@ -331,6 +299,10 @@ void GPHGraphicsManager::internUpdateScreen() {
 	if (_mouseNeedsRedraw)
 		undrawMouse();
 
+#ifdef USE_OSD
+	updateOSD();
+#endif
+
 	// Force a full redraw if requested
 	if (_forceFull) {
 		_numDirtyRects = 1;
@@ -440,9 +412,9 @@ void GPHGraphicsManager::internUpdateScreen() {
 		drawMouse();
 
 #ifdef USE_OSD
-		if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT)
-			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		drawOSD();
 #endif
+
 		// Finally, blit all our changes to the screen
 		SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
 	}
diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
index a69cba2..6a920e9 100644
--- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
+++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
@@ -290,38 +290,6 @@ void LinuxmotoSdlGraphicsManager::internUpdateScreen() {
 		_forceFull = true;
 	}
 
-#ifdef USE_OSD
-	// OSD visible (i.e. non-transparent)?
-	if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT) {
-		// Updated alpha value
-		const int diff = SDL_GetTicks() - _osdMessageFadeStartTime;
-		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
-				// Back to full transparency
-				_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
-			} else {
-				// Do a linear fade out...
-				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
-				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
-			}
-			_forceFull = true;
-		}
-
-		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
-			removeOSDMessage();
-		} else {
-			if (_osdMessageSurface && _osdSurface) {
-				SDL_Rect dstRect;
-				dstRect.x = (_osdSurface->w - _osdMessageSurface->w) / 2;
-				dstRect.y = (_osdSurface->h - _osdMessageSurface->h) / 2;
-				dstRect.w = _osdMessageSurface->w;
-				dstRect.h = _osdMessageSurface->h;
-				blitOSDMessage(dstRect);
-			}
-		}
-	}
-#endif
-
 	if (!_overlayVisible) {
 		origSurf = _screen;
 		srcSurf = _tmpscreen;
@@ -343,6 +311,10 @@ void LinuxmotoSdlGraphicsManager::internUpdateScreen() {
 	if (_mouseNeedsRedraw)
 		undrawMouse();
 
+#ifdef USE_OSD
+	updateOSD();
+#endif
+
 	// Force a full redraw if requested
 	if (_forceFull) {
 		_numDirtyRects = 1;
@@ -451,9 +423,9 @@ void LinuxmotoSdlGraphicsManager::internUpdateScreen() {
 		drawMouse();
 
 #ifdef USE_OSD
-		if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT)
-			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		drawOSD();
 #endif
+
 		// Finally, blit all our changes to the screen
 		SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
 	}
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index f4a466d..cd89440 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -121,7 +121,8 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	:
 	SdlGraphicsManager(sdlEventSource, window),
 #ifdef USE_OSD
-	_osdSurface(0), _osdMessageSurface(nullptr), _osdMessageAlpha(SDL_ALPHA_TRANSPARENT), _osdMessageFadeStartTime(0),
+	_osdMessageSurface(nullptr), _osdMessageAlpha(SDL_ALPHA_TRANSPARENT), _osdMessageFadeStartTime(0),
+	_osdIconSurface(nullptr),
 #endif
 	_hwscreen(0),
 #if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -879,23 +880,6 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	if (_tmpscreen2 == NULL)
 		error("allocating _tmpscreen2 failed");
 
-#ifdef USE_OSD
-	_osdSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
-						_hwscreen->w,
-						_hwscreen->h,
-						32,
-						0xFF000000,
-						0x00FF0000,
-						0x0000FF00,
-						0x000000FF
-	);
-	if (_osdSurface == NULL)
-		error("allocating _osdSurface failed");
-
-	_osdFormat = getSurfaceFormat(_osdSurface);
-	SDL_SetColorKey(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kOSDColorKey);
-#endif
-
 #if !SDL_VERSION_ATLEAST(2, 0, 0)
 	// For SDL2 the output resolution might differ from the requested
 	// resolution. We handle resetting the keyboard emulation properly inside
@@ -945,15 +929,15 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
 	}
 
 #ifdef USE_OSD
-	if (_osdSurface) {
-		SDL_FreeSurface(_osdSurface);
-		_osdSurface = NULL;
-	}
-
 	if (_osdMessageSurface) {
 		SDL_FreeSurface(_osdMessageSurface);
 		_osdMessageSurface = NULL;
 	}
+
+	if (_osdIconSurface) {
+		SDL_FreeSurface(_osdIconSurface);
+		_osdIconSurface = NULL;
+	}
 #endif
 	DestroyScalers();
 
@@ -983,11 +967,6 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
 	SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL;
 	SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL;
 
-#ifdef USE_OSD
-	// Release the OSD surface
-	SDL_FreeSurface(_osdSurface); _osdSurface = NULL;
-#endif
-
 	// Setup the new GFX mode
 	if (!loadGFXMode()) {
 		unloadGFXMode();
@@ -1065,38 +1044,6 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 		_forceFull = true;
 	}
 
-#ifdef USE_OSD
-	// OSD visible (i.e. non-transparent)?
-	if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT) {
-		// Updated alpha value
-		const int diff = SDL_GetTicks() - _osdMessageFadeStartTime;
-		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
-				// Back to full transparency
-				_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
-			} else {
-				// Do a linear fade out...
-				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
-				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
-			}
-			_forceFull = true;
-		}
-
-		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
-			removeOSDMessage();
-		} else {
-			if (_osdMessageSurface && _osdSurface) {
-				SDL_Rect dstRect;
-				dstRect.x = (_osdSurface->w - _osdMessageSurface->w) / 2;
-				dstRect.y = (_osdSurface->h - _osdMessageSurface->h) / 2;
-				dstRect.w = _osdMessageSurface->w;
-				dstRect.h = _osdMessageSurface->h;
-				blitOSDMessage(dstRect);
-			}
-		}
-	}
-#endif
-
 	if (!_overlayVisible) {
 		origSurf = _screen;
 		srcSurf = _tmpscreen;
@@ -1119,6 +1066,10 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	if (_mouseNeedsRedraw)
 		undrawMouse();
 
+#ifdef USE_OSD
+	updateOSD();
+#endif
+
 	// Force a full redraw if requested
 	if (_forceFull) {
 		_numDirtyRects = 1;
@@ -1199,8 +1150,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 		drawMouse();
 
 #ifdef USE_OSD
-		if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT)
-			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		drawOSD();
 #endif
 
 #ifdef USE_SDL_DEBUG_FOCUSRECT
@@ -2169,14 +2119,14 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
 	}
 
 	// Clip the rect
-	if (width > _osdSurface->w)
-		width = _osdSurface->w;
-	if (height > _osdSurface->h)
-		height = _osdSurface->h;
+	if (width > _hwscreen->w)
+		width = _hwscreen->w;
+	if (height > _hwscreen->h)
+		height = _hwscreen->h;
 
 	_osdMessageSurface = SDL_CreateRGBSurface(
-		SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
-		width, height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
+		SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCALPHA,
+		width, height, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask
 	);
 
 	// Lock the surface
@@ -2209,138 +2159,120 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
 	// Init the OSD display parameters, and the fade out
 	_osdMessageAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
 	_osdMessageFadeStartTime = SDL_GetTicks() + kOSDFadeOutDelay;
+}
 
-	// Ensure a full redraw takes place next time the screen is updated
-	_forceFull = true;
+SDL_Rect SurfaceSdlGraphicsManager::getOSDMessageRect() const {
+	SDL_Rect rect;
+	rect.x = (_hwscreen->w - _osdMessageSurface->w) / 2;
+	rect.y = (_hwscreen->h - _osdMessageSurface->h) / 2;
+	rect.w = _osdMessageSurface->w;
+	rect.h = _osdMessageSurface->h;
+	return rect;
 }
 
-void SurfaceSdlGraphicsManager::copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {
+void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface *icon) {
 	assert(_transactionMode == kTransactionNone);
-	assert(buf);
 
 	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
 
-	// Lock the OSD surface for drawing
-	if (SDL_LockSurface(_osdSurface))
-		error("displayMessageOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
-
-	// Mark that area as "dirty"
-	addDirtyRect(x, y, w, h, true);
+	if (_osdIconSurface) {
+		SDL_FreeSurface(_osdIconSurface);
+		_osdIconSurface = nullptr;
+	}
+
+	if (icon) {
+		const Graphics::PixelFormat &iconFormat = icon->format;
+
+		_osdIconSurface = SDL_CreateRGBSurface(
+				SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCALPHA,
+				icon->w, icon->h, iconFormat.bytesPerPixel * 8,
+				((0xFF >> iconFormat.rLoss) << iconFormat.rShift),
+				((0xFF >> iconFormat.gLoss) << iconFormat.gShift),
+				((0xFF >> iconFormat.bLoss) << iconFormat.bShift),
+				((0xFF >> iconFormat.aLoss) << iconFormat.aShift)
+		);
+
+		// Lock the surface
+		if (SDL_LockSurface(_osdIconSurface))
+			error("displayActivityIconOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
+
+		byte *dst = (byte *) _osdIconSurface->pixels;
+		const byte *src = (const byte *) icon->getPixels();
+		for (uint y = 0; y < icon->h; y++) {
+			memcpy(dst, src, icon->w * iconFormat.bytesPerPixel);
+			src += icon->pitch;
+			dst += _osdIconSurface->pitch;
+		}
 
-#ifdef USE_RGB_COLOR
-	byte *dst = (byte *)_osdSurface->pixels + y * _osdSurface->pitch + x * _osdSurface->format->BytesPerPixel;
-	if (_videoMode.screenWidth == w && pitch == _osdSurface->pitch) {
-		memcpy(dst, buf, h*pitch);
-	} else {
-		const byte *src = (const byte *)buf;
-		do {
-			memcpy(dst, src, w * _osdSurface->format->BytesPerPixel);
-			src += pitch;
-			dst += _osdSurface->pitch;
-		} while (--h);
+		// Finished drawing, so unlock the OSD icon surface
+		SDL_UnlockSurface(_osdIconSurface);
 	}
-#else
-	byte *dst = (byte *)_osdSurface->pixels + y * _osdSurface->pitch + x;
-	if (_osdSurface->pitch == pitch && pitch == w) {
-		memcpy(dst, buf, h*w);
-	} else {
-		const byte *src = (const byte *)buf;
-		do {
-			memcpy(dst, src, w);
-			src += pitch;
-			dst += _osdSurface->pitch;
-		} while (--h);
-	}
-#endif
-
-	// Finished drawing, so unlock the OSD surface again
-	SDL_UnlockSurface(_osdSurface);
 }
 
-void SurfaceSdlGraphicsManager::clearOSD() {
-	assert(_transactionMode == kTransactionNone);
-
-	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
-
-	// Lock the OSD surface for drawing
-	if (SDL_LockSurface(_osdSurface))
-		error("displayMessageOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
-
-	// Clear everything with the "transparent" color, i.e. the colorkey
-	SDL_FillRect(_osdSurface, 0, kOSDColorKey);
-
-	// Finished drawing, so unlock the OSD surface again
-	SDL_UnlockSurface(_osdSurface);
-
-	// Remove OSD message as well
-	removeOSDMessage();
-
-	// Ensure a full redraw takes place next time the screen is updated
-	_forceFull = true;
+SDL_Rect SurfaceSdlGraphicsManager::getOSDIconRect() const {
+	SDL_Rect dstRect;
+	dstRect.x = _hwscreen->w - _osdIconSurface->w - 10;
+	dstRect.y = 10;
+	dstRect.w = _osdIconSurface->w;
+	dstRect.h = _osdIconSurface->h;
+	return dstRect;
 }
 
 void SurfaceSdlGraphicsManager::removeOSDMessage() {
-	// Lock the OSD surface for drawing
-	if (SDL_LockSurface(_osdSurface))
-		error("displayMessageOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
-
-	//remove previous message
+	// Remove the previous message
 	if (_osdMessageSurface) {
-		SDL_Rect osdRect;
-		osdRect.x = (_osdSurface->w - _osdMessageSurface->w) / 2;
-		osdRect.y = (_osdSurface->h - _osdMessageSurface->h) / 2;
-		osdRect.w = _osdMessageSurface->w;
-		osdRect.h = _osdMessageSurface->h;
-		SDL_FillRect(_osdSurface, &osdRect, kOSDColorKey);
 		SDL_FreeSurface(_osdMessageSurface);
 	}
 
 	_osdMessageSurface = NULL;
 	_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
+}
 
-	// Finished drawing, so unlock the OSD surface again
-	SDL_UnlockSurface(_osdSurface);
-}
-
-void SurfaceSdlGraphicsManager::blitOSDMessage(SDL_Rect dstRect) {
-	SDL_Surface *src = _osdMessageSurface;
-	SDL_Surface *dst = _osdSurface;
-	Graphics::PixelFormat srcFormat = getSurfaceFormat(src);
-	Graphics::PixelFormat dstFormat = _osdFormat;
-	for (int y = 0; y < dstRect.h; y++) {
-		const byte *srcRow = (const byte *)((const byte *)(src->pixels) + y * src->pitch); //src (x, y) == (0, 0)
-		byte *dstRow = (byte *)((byte *)(dst->pixels) + (dstRect.y + y) * dst->pitch + dstRect.x * dstFormat.bytesPerPixel);
-
-		for (int x = 0; x < dstRect.w; x++) {
-			uint32 srcColor;
-			if (dst->format->BytesPerPixel == 2)
-				srcColor = READ_UINT16(srcRow);
-			else if (dst->format->BytesPerPixel == 3)
-				srcColor = READ_UINT24(srcRow);
-			else
-				srcColor = READ_UINT32(srcRow);
-
-			srcRow += srcFormat.bytesPerPixel;
+void SurfaceSdlGraphicsManager::updateOSD() {
+	// OSD message visible (i.e. non-transparent)?
+	if (_osdMessageAlpha != SDL_ALPHA_TRANSPARENT) {
+		// Updated alpha value
+		const int diff = SDL_GetTicks() - _osdMessageFadeStartTime;
+		if (diff > 0) {
+			if (diff >= kOSDFadeOutDuration) {
+				// Back to full transparency
+				_osdMessageAlpha = SDL_ALPHA_TRANSPARENT;
+			} else {
+				// Do a linear fade out...
+				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
+			}
+			SDL_SetAlpha(_osdMessageSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdMessageAlpha);
+		}
 
-			// Convert that color to the new format
-			byte r, g, b, a;
-			srcFormat.colorToARGB(srcColor, a, r, g, b);
-			a = _osdMessageAlpha; //this is the important line, because apart from that this is plain surface copying
-			uint32 color = dstFormat.ARGBToColor(a, r, g, b);
+		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
+			removeOSDMessage();
+		}
+	}
 
-			if (dstFormat.bytesPerPixel == 2)
-				*((uint16 *)dstRow) = color;
-			else
-				*((uint32 *)dstRow) = color;
+	if (_osdMessageSurface) {
+		SDL_Rect dstRect = getOSDMessageRect();
+		addDirtyRect(dstRect.x, dstRect.y, dstRect.w, dstRect.h, true);
+	}
 
-			dstRow += dstFormat.bytesPerPixel;
-		}
+	if (_osdIconSurface) {
+		SDL_Rect dstRect = getOSDIconRect();
+		addDirtyRect(dstRect.x, dstRect.y, dstRect.w, dstRect.h, true);
 	}
 }
 
-Graphics::PixelFormat SurfaceSdlGraphicsManager::getOSDFormat() {
-	return _osdFormat;
+void SurfaceSdlGraphicsManager::drawOSD() {
+	if (_osdMessageSurface) {
+		SDL_Rect dstRect = getOSDMessageRect();
+		SDL_BlitSurface(_osdMessageSurface, 0, _hwscreen, &dstRect);
+	}
+
+	if (_osdIconSurface) {
+		SDL_Rect dstRect = getOSDIconRect();
+		SDL_BlitSurface(_osdIconSurface, 0, _hwscreen, &dstRect);
+	}
 }
+
 #endif
 
 bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
@@ -2402,26 +2334,24 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 			setGraphicsMode(newMode);
 		endGFXTransaction();
 #ifdef USE_OSD
-		if (_osdSurface) {
-			const char *newScalerName = 0;
-			const OSystem::GraphicsMode *g = getSupportedGraphicsModes();
-			while (g->name) {
-				if (g->id == _videoMode.mode) {
-					newScalerName = g->description;
-					break;
-				}
-				g++;
-			}
-			if (newScalerName) {
-				char buffer[128];
-				sprintf(buffer, "%s %s\n%d x %d -> %d x %d",
-					_("Active graphics filter:"),
-					newScalerName,
-					_videoMode.screenWidth, _videoMode.screenHeight,
-					_hwscreen->w, _hwscreen->h
-					);
-				displayMessageOnOSD(buffer);
+		const char *newScalerName = 0;
+		const OSystem::GraphicsMode *g = getSupportedGraphicsModes();
+		while (g->name) {
+			if (g->id == _videoMode.mode) {
+				newScalerName = g->description;
+				break;
 			}
+			g++;
+		}
+		if (newScalerName) {
+			char buffer[128];
+			sprintf(buffer, "%s %s\n%d x %d -> %d x %d",
+				_("Active graphics filter:"),
+				newScalerName,
+				_videoMode.screenWidth, _videoMode.screenHeight,
+				_hwscreen->w, _hwscreen->h
+				);
+			displayMessageOnOSD(buffer);
 		}
 #endif
 		internUpdateScreen();
@@ -2636,22 +2566,4 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
 }
 #endif // SDL_VERSION_ATLEAST(2, 0, 0)
 
-Graphics::PixelFormat SurfaceSdlGraphicsManager::getSurfaceFormat(SDL_Surface *surface) {
-	Graphics::PixelFormat format;
-	if (surface) {
-		format.bytesPerPixel = surface->format->BytesPerPixel;
-
-		format.rLoss = surface->format->Rloss;
-		format.gLoss = surface->format->Gloss;
-		format.bLoss = surface->format->Bloss;
-		format.aLoss = surface->format->Aloss;
-
-		format.rShift = surface->format->Rshift;
-		format.gShift = surface->format->Gshift;
-		format.bShift = surface->format->Bshift;
-		format.aShift = surface->format->Ashift;
-	}
-	return format;
-}
-
 #endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index d8f826a..82f4a33 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -145,9 +145,7 @@ public:
 
 #ifdef USE_OSD
 	virtual void displayMessageOnOSD(const char *msg);
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void clearOSD();
-	virtual Graphics::PixelFormat getOSDFormat();	
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
 #endif
 
 	// Override from Common::EventObserver
@@ -163,8 +161,6 @@ public:
 
 protected:
 #ifdef USE_OSD
-	/** Surface containing the OSD */
-	SDL_Surface *_osdSurface;
 	/** Surface containing the OSD message */
 	SDL_Surface *_osdMessageSurface;
 	/** Transparency level of the OSD message */
@@ -175,14 +171,19 @@ protected:
 	enum {
 		kOSDFadeOutDelay = 2 * 1000,	/** < Delay before the OSD is faded out (in milliseconds) */
 		kOSDFadeOutDuration = 500,		/** < Duration of the OSD fade out (in milliseconds) */
-		kOSDColorKey = 1,				/** < Transparent color key */
 		kOSDInitialAlpha = 80			/** < Initial alpha level, in percent */
 	};
-	/** OSD pixel format */
-	Graphics::PixelFormat _osdFormat;
-
+	/** Screen rectangle where the OSD message is drawn */
+	SDL_Rect getOSDMessageRect() const;
+	/** Clear the currently displayed OSD message if any */
 	void removeOSDMessage();
-	void blitOSDMessage(SDL_Rect dstRect);
+	/** Surface containing the OSD background activity icon */
+	SDL_Surface *_osdIconSurface;
+	/** Screen rectangle where the OSD background activity icon is drawn */
+	SDL_Rect getOSDIconRect() const;
+
+	void updateOSD();
+	void drawOSD();
 #endif
 
 	/** Hardware screen */
@@ -368,8 +369,6 @@ protected:
 	Common::Rect _focusRect;
 #endif
 
-	static Graphics::PixelFormat getSurfaceFormat(SDL_Surface *surface);
-
 	virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false);
 
 	virtual void drawMouse();


Commit: 9cbaad61405f0a4c8b88eb4e6637b84a12633c1a
    https://github.com/scummvm/scummvm/commit/9cbaad61405f0a4c8b88eb4e6637b84a12633c1a
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-09-13T20:41:26+02:00

Commit Message:
SDL: Switch the OpenGL renderer to use small textures to draw the OSD

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 8861d36..3e2be6e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -57,7 +57,8 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
       _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false),
       _forceRedraw(false), _scissorOverride(3)
 #ifdef USE_OSD
-      , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
+      , _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
+      _osdIconChangeRequest(false), _osdIconSurface(nullptr)
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
@@ -69,7 +70,9 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
 	delete _overlay;
 	delete _cursor;
 #ifdef USE_OSD
-	delete _osd;
+	delete _osdMessageSurface;
+	delete _osdIconSurface;
+	_osdIconNextData.free();
 #endif
 #if !USE_FORCED_GLES
 	ShaderManager::destroy();
@@ -362,13 +365,27 @@ void OpenGLGraphicsManager::updateScreen() {
 		return;
 	}
 
+#ifdef USE_OSD
+	{
+		Common::StackLock lock(_osdMutex);
+
+		if (_osdMessageChangeRequest) {
+			osdMessageUpdateSurface();
+		}
+
+		if (_osdIconChangeRequest) {
+			osdIconUpdateSurface();
+		}
+	}
+#endif
+
 	// We only update the screen when there actually have been any changes.
 	if (   !_forceRedraw
 	    && !_gameScreen->isDirty()
 	    && !(_overlayVisible && _overlay->isDirty())
 	    && !(_cursorVisible && _cursor && _cursor->isDirty())
 #ifdef USE_OSD
-	    && _osdAlpha == 0
+	    && !_osdMessageSurface && !_osdIconSurface
 #endif
 	    ) {
 		return;
@@ -381,9 +398,6 @@ void OpenGLGraphicsManager::updateScreen() {
 		_cursor->updateGLTexture();
 	}
 	_overlay->updateGLTexture();
-#ifdef USE_OSD
-	_osd->updateGLTexture();
-#endif
 
 	// Clear the screen buffer.
 	if (_scissorOverride && !_overlayVisible) {
@@ -424,29 +438,45 @@ void OpenGLGraphicsManager::updateScreen() {
 
 #ifdef USE_OSD
 	// Fourth step: Draw the OSD.
-	if (_osdAlpha > 0) {
-		Common::StackLock lock(_osdMutex);
-
+	if (_osdMessageSurface) {
 		// Update alpha value.
-		const int diff = g_system->getMillis(false) - _osdFadeStartTime;
+		const int diff = g_system->getMillis(false) - _osdMessageFadeStartTime;
 		if (diff > 0) {
-			if (diff >= kOSDFadeOutDuration) {
+			if (diff >= kOSDMessageFadeOutDuration) {
 				// Back to full transparency.
-				_osdAlpha = 0;
+				_osdMessageAlpha = 0;
 			} else {
 				// Do a fade out.
-				_osdAlpha = kOSDInitialAlpha - diff * kOSDInitialAlpha / kOSDFadeOutDuration;
+				_osdMessageAlpha = kOSDMessageInitialAlpha - diff * kOSDMessageInitialAlpha / kOSDMessageFadeOutDuration;
 			}
 		}
 
 		// Set the OSD transparency.
-		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
+		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
+
+		int dstX = (_outputScreenWidth - _osdMessageSurface->getWidth()) / 2;
+		int dstY = (_outputScreenHeight - _osdMessageSurface->getHeight()) / 2;
 
 		// Draw the OSD texture.
-		g_context.getActivePipeline()->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
+		                                           dstX, dstY, _osdMessageSurface->getWidth(), _osdMessageSurface->getHeight());
 
 		// Reset color.
 		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
+
+		if (_osdMessageAlpha <= 0) {
+			delete _osdMessageSurface;
+			_osdMessageSurface = nullptr;
+		}
+	}
+
+	if (_osdIconSurface) {
+		int dstX = _outputScreenWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
+		int dstY = kOSDIconTopMargin;
+
+		// Draw the OSD icon texture.
+		g_context.getActivePipeline()->drawTexture(_osdIconSurface->getGLTexture(),
+		                                           dstX, dstY, _osdIconSurface->getWidth(), _osdIconSurface->getHeight());
 	}
 #endif
 
@@ -703,85 +733,130 @@ void OpenGLGraphicsManager::setCursorPalette(const byte *colors, uint start, uin
 void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) {
 #ifdef USE_OSD
 	// HACK: Actually no client code should use graphics functions from
-	// another thread. But the MT-32 emulator still does, thus we need to
-	// make sure this doesn't happen while a updateScreen call is done.
+	// another thread. But the MT-32 emulator and network synchronization still do,
+	// thus we need to make sure this doesn't happen while a updateScreen call is done.
 	Common::StackLock lock(_osdMutex);
 
-	// Slip up the lines.
+	_osdMessageChangeRequest = true;
+
+	_osdMessageNextData = msg;
+#endif
+}
+
+#ifdef USE_OSD
+void OpenGLGraphicsManager::osdMessageUpdateSurface() {
+	// Split up the lines.
 	Common::Array<Common::String> osdLines;
-	Common::StringTokenizer tokenizer(msg, "\n");
+	Common::StringTokenizer tokenizer(_osdMessageNextData, "\n");
 	while (!tokenizer.empty()) {
 		osdLines.push_back(tokenizer.nextToken());
 	}
 
 	// Do the actual drawing like the SDL backend.
 	const Graphics::Font *font = getFontOSD();
-	Graphics::Surface *dst = _osd->getSurface();
-	_osd->fill(0);
-	_osd->flagDirty();
 
 	// Determine a rect which would contain the message string (clipped to the
 	// screen dimensions).
 	const int vOffset = 6;
 	const int lineSpacing = 1;
 	const int lineHeight = font->getFontHeight() + 2 * lineSpacing;
-	int width = 0;
-	int height = lineHeight * osdLines.size() + 2 * vOffset;
+	uint width = 0;
+	uint height = lineHeight * osdLines.size() + 2 * vOffset;
 	for (uint i = 0; i < osdLines.size(); i++) {
-		width = MAX(width, font->getStringWidth(osdLines[i]) + 14);
+		width = MAX<uint>(width, font->getStringWidth(osdLines[i]) + 14);
 	}
 
 	// Clip the rect
-	width  = MIN<int>(width,  dst->w);
-	height = MIN<int>(height, dst->h);
+	width  = MIN<uint>(width,  _displayWidth);
+	height = MIN<uint>(height, _displayHeight);
+
+	delete _osdMessageSurface;
+	_osdMessageSurface = nullptr;
+
+	_osdMessageSurface = createSurface(_defaultFormatAlpha);
+	assert(_osdMessageSurface);
+	// We always filter the osd with GL_LINEAR. This assures it's
+	// readable in case it needs to be scaled and does not affect it
+	// otherwise.
+	_osdMessageSurface->enableLinearFiltering(true);
+
+	_osdMessageSurface->allocate(width, height);
 
-	int dstX = (dst->w - width) / 2;
-	int dstY = (dst->h - height) / 2;
+	Graphics::Surface *dst = _osdMessageSurface->getSurface();
 
 	// Draw a dark gray rect.
 	const uint32 color = dst->format.RGBToColor(40, 40, 40);
-	dst->fillRect(Common::Rect(dstX, dstY, dstX + width, dstY + height), color);
+	dst->fillRect(Common::Rect(0, 0, width, height), color);
 
-	// Render the message, centered, and in white
+	// Render the message in white
 	const uint32 white = dst->format.RGBToColor(255, 255, 255);
 	for (uint i = 0; i < osdLines.size(); ++i) {
 		font->drawString(dst, osdLines[i],
-		                 dstX, dstY + i * lineHeight + vOffset + lineSpacing, width,
+		                 0, i * lineHeight + vOffset + lineSpacing, width,
 		                 white, Graphics::kTextAlignCenter);
 	}
 
+	_osdMessageSurface->updateGLTexture();
+
 	// Init the OSD display parameters.
-	_osdAlpha = kOSDInitialAlpha;
-	_osdFadeStartTime = g_system->getMillis() + kOSDFadeOutDelay;
-#endif
-}
+	_osdMessageAlpha = kOSDMessageInitialAlpha;
+	_osdMessageFadeStartTime = g_system->getMillis() + kOSDMessageFadeOutDelay;
 
-void OpenGLGraphicsManager::copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {
-#ifdef USE_OSD
-	_osd->copyRectToTexture(x, y, w, h, buf, pitch);
-#endif
+	// Clear the text update request
+	_osdMessageNextData.clear();
+	_osdMessageChangeRequest = false;
 }
+#endif
 
-void OpenGLGraphicsManager::clearOSD() {
+void OpenGLGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface *icon) {
 #ifdef USE_OSD
 	// HACK: Actually no client code should use graphics functions from
-	// another thread. But the MT-32 emulator still does, thus we need to
-	// make sure this doesn't happen while a updateScreen call is done.
+	// another thread. But the MT-32 emulator and network synchronization still do,
+	// thus we need to make sure this doesn't happen while a updateScreen call is done.
+	// HACK: We can't make OpenGL calls outside of the main thread. This method
+	// stores a copy of the icon. The main thread will pick up the changed icon,
+	// and copy it to an OpenGL texture.
 	Common::StackLock lock(_osdMutex);
 
-	Graphics::Surface *dst = _osd->getSurface();
-	_osd->fill(0);
-	_osd->flagDirty();
+	_osdIconChangeRequest = true;
 
-	// Init the OSD display parameters.
-	_osdAlpha = kOSDInitialAlpha;
-	_osdFadeStartTime = g_system->getMillis() + kOSDFadeOutDelay;
+	_osdIconNextData.free();
+	_osdIconNextData.copyFrom(*icon);
 #endif
 }
 
-Graphics::PixelFormat OpenGLGraphicsManager::getOSDFormat() {
-	return _defaultFormatAlpha;
+#ifdef USE_OSD
+void OpenGLGraphicsManager::osdIconUpdateSurface() {
+	delete _osdIconSurface;
+	_osdIconSurface = nullptr;
+
+	if (_osdIconNextData.getPixels()) {
+		Graphics::Surface *converted = _osdIconNextData.convertTo(_defaultFormatAlpha);
+		_osdIconNextData.free();
+
+		_osdIconSurface = createSurface(_defaultFormatAlpha);
+		assert(_osdIconSurface);
+		// We always filter the osd with GL_LINEAR. This assures it's
+		// readable in case it needs to be scaled and does not affect it
+		// otherwise.
+		_osdIconSurface->enableLinearFiltering(true);
+
+		_osdIconSurface->allocate(converted->w, converted->h);
+
+		Graphics::Surface *dst = _osdIconSurface->getSurface();
+
+		// Copy the icon to the texture
+		dst->copyRectToSurface(*converted, 0, 0, Common::Rect(0, 0, converted->w, converted->h));
+
+		converted->free();
+		delete converted;
+
+		_osdIconSurface->updateGLTexture();
+	}
+
+	_osdIconChangeRequest = false;
 }
+#endif
 
 void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
 	assert(_gameScreen->hasPalette());
@@ -849,22 +924,6 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	_overlay->allocate(overlayWidth, overlayHeight);
 	_overlay->fill(0);
 
-#ifdef USE_OSD
-	if (!_osd || _osd->getFormat() != _defaultFormatAlpha) {
-		delete _osd;
-		_osd = nullptr;
-
-		_osd = createSurface(_defaultFormatAlpha);
-		assert(_osd);
-		// We always filter the osd with GL_LINEAR. This assures it's
-		// readable in case it needs to be scaled and does not affect it
-		// otherwise.
-		_osd->enableLinearFiltering(true);
-	}
-	_osd->allocate(_overlay->getWidth(), _overlay->getHeight());
-	_osd->fill(0);
-#endif
-
 	// Re-setup the scaling for the screen and cursor
 	recalculateDisplayArea();
 	recalculateCursorScaling();
@@ -949,8 +1008,12 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	}
 
 #ifdef USE_OSD
-	if (_osd) {
-		_osd->recreate();
+	if (_osdMessageSurface) {
+		_osdMessageSurface->recreate();
+	}
+
+	if (_osdIconSurface) {
+		_osdIconSurface->recreate();
 	}
 #endif
 }
@@ -969,8 +1032,12 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	}
 
 #ifdef USE_OSD
-	if (_osd) {
-		_osd->destroy();
+	if (_osdMessageSurface) {
+		_osdMessageSurface->destroy();
+	}
+
+	if (_osdIconSurface) {
+		_osdIconSurface->destroy();
 	}
 #endif
 
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 55d2c5c..366ad48 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -30,6 +30,8 @@
 #include "common/frac.h"
 #include "common/mutex.h"
 
+#include "graphics/surface.h"
+
 namespace Graphics {
 class Font;
 } // End of namespace Graphics
@@ -115,9 +117,7 @@ public:
 	virtual void setCursorPalette(const byte *colors, uint start, uint num);
 
 	virtual void displayMessageOnOSD(const char *msg);
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void clearOSD();
-	virtual Graphics::PixelFormat getOSDFormat();
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
 
 	// PaletteManager interface
 	virtual void setPalette(const byte *colors, uint start, uint num);
@@ -548,30 +548,79 @@ protected:
 
 private:
 	/**
-	 * The OSD's contents.
+	 * Request for the OSD icon surface to be updated.
 	 */
-	Surface *_osd;
+	bool _osdMessageChangeRequest;
 
 	/**
-	 * Current opacity level of the OSD.
+	 * The next OSD message.
+	 *
+	 * If this value is not empty, the OSD message will be set
+	 * to it on the next frame.
 	 */
-	uint8 _osdAlpha;
+	Common::String _osdMessageNextData;
 
 	/**
-	 * When fading the OSD has started.
+	 * Set the OSD message surface with the value of the next OSD message.
 	 */
-	uint32 _osdFadeStartTime;
+	void osdMessageUpdateSurface();
 
 	/**
-	 * Mutex to allow displayMessageOnOSD to be used from the audio thread.
+	 * The OSD message's contents.
 	 */
-	Common::Mutex _osdMutex;
+	Surface *_osdMessageSurface;
+
+	/**
+	 * Current opacity level of the OSD message.
+	 */
+	uint8 _osdMessageAlpha;
+
+	/**
+	 * When fading the OSD message has started.
+	 */
+	uint32 _osdMessageFadeStartTime;
+
+	enum {
+		kOSDMessageFadeOutDelay = 2 * 1000,
+		kOSDMessageFadeOutDuration = 500,
+		kOSDMessageInitialAlpha = 80
+	};
+
+	/**
+	 * Request for the OSD icon surface to be updated.
+	 */
+	bool _osdIconChangeRequest;
+
+	/**
+	 * The next OSD background activity icon.
+	 *
+	 * The OSD icon will be updated with this data on the next frame.
+	 * Can be an unallocated surface if the OSD icon should not be displayed.
+	 */
+	Graphics::Surface _osdIconNextData;
+
+	/**
+	 * Set the OSD icon surface with the value of the next OSD icon.
+	 */
+	void osdIconUpdateSurface();
+
+	/**
+	 * The OSD background activity icon's contents.
+	 */
+	Surface *_osdIconSurface;
 
 	enum {
-		kOSDFadeOutDelay = 2 * 1000,
-		kOSDFadeOutDuration = 500,
-		kOSDInitialAlpha = 80
+		kOSDIconTopMargin = 10,
+		kOSDIconRightMargin = 10
 	};
+
+	/**
+	 * Mutex for the OSD draw calls.
+	 *
+	 * Mutex to allow displayMessageOnOSD and displayActivityIconOnOSD
+	 * to be used from the audio and network threads.
+	 */
+	Common::Mutex _osdMutex;
 #endif
 };
 


Commit: 0802bbd8ee526552da751141ce03cce2a8e3ec30
    https://github.com/scummvm/scummvm/commit/0802bbd8ee526552da751141ce03cce2a8e3ec30
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2016-09-13T20:41:26+02:00

Commit Message:
OSYSTEM: Remove the API allowing to draw to the OSD surface directly

Changed paths:
    backends/base-backend.cpp
    backends/base-backend.h
    backends/graphics/graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    common/system.h



diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp
index dfb9e28..3e95c3e 100644
--- a/backends/base-backend.cpp
+++ b/backends/base-backend.cpp
@@ -39,20 +39,6 @@ void BaseBackend::displayMessageOnOSD(const char *msg) {
 	dialog.runModal();
 }
 
-void BaseBackend::copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {
-	warning("BaseBackend::copyRectToOSD not implemented"); //TODO
-}
-
-void BaseBackend::clearOSD() {
-	warning("BaseBackend::clearOSD not implemented"); //TODO
-	//what should I do? Remove all TimedMessageDialogs?
-}
-
-Graphics::PixelFormat BaseBackend::getOSDFormat() {
-	warning("BaseBackend::getOSDFormat not implemented");
-	return Graphics::PixelFormat();
-}
-
 void BaseBackend::initBackend() {
 	// Init Event manager
 #ifndef DISABLE_DEFAULT_EVENT_MANAGER
diff --git a/backends/base-backend.h b/backends/base-backend.h
index 2394eda..598f682 100644
--- a/backends/base-backend.h
+++ b/backends/base-backend.h
@@ -33,9 +33,6 @@ public:
 	virtual void initBackend();
 
 	virtual void displayMessageOnOSD(const char *msg);
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void clearOSD();
-	virtual Graphics::PixelFormat getOSDFormat();
 	virtual void fillScreen(uint32 col);
 };
 
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 271a482..db8b6a9 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -84,9 +84,6 @@ public:
 	virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0;
 
 	virtual void displayMessageOnOSD(const char *msg) {}
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {}
-	virtual void clearOSD() {}
-	virtual Graphics::PixelFormat getOSDFormat() { return Graphics::PixelFormat(); }
 	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) {}
 
 
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 13db277..1fef5c5 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -241,18 +241,6 @@ void ModularBackend::displayMessageOnOSD(const char *msg) {
 	_graphicsManager->displayMessageOnOSD(msg);
 }
 
-void ModularBackend::copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) {
-	_graphicsManager->copyRectToOSD(buf, pitch, x, y, w, h);
-}
-
-void ModularBackend::clearOSD() {
-	_graphicsManager->clearOSD();
-}
-
-Graphics::PixelFormat ModularBackend::getOSDFormat() {
-	return _graphicsManager->getOSDFormat();
-}
-
 void ModularBackend::displayActivityIconOnOSD(const Graphics::Surface *icon) {
 	_graphicsManager->displayActivityIconOnOSD(icon);
 }
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 886f91c..23f0e2d 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -127,9 +127,6 @@ public:
 
 	virtual void quit();
 	virtual void displayMessageOnOSD(const char *msg);
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void clearOSD();
-	virtual Graphics::PixelFormat getOSDFormat();
 	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
 
 	//@}
diff --git a/common/system.h b/common/system.h
index b07a5ff..cbaa30c 100644
--- a/common/system.h
+++ b/common/system.h
@@ -1121,45 +1121,6 @@ public:
 	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) = 0;
 
 	/**
-	* Blit a bitmap to the 'on screen display'.
-	*
-	* If the current pixel format has one byte per pixel, the graphics data
-	* uses 8 bits per pixel, using the palette specified via setPalette.
-	* If more than one byte per pixel is in use, the graphics data uses the
-	* pixel format returned by getScreenFormat.
-	*
-	* @param buf		the buffer containing the graphics data source
-	* @param pitch		the pitch of the buffer (number of bytes in a scanline)
-	* @param x			the x coordinate of the destination rectangle
-	* @param y			the y coordinate of the destination rectangle
-	* @param w			the width of the destination rectangle
-	* @param h			the height of the destination rectangle
-	*
-	* @note The specified destination rectangle must be completly contained
-	*       in the visible screen space, and must be non-empty. If not, a
-	*       backend may or may not perform clipping, trigger an assert or
-	*       silently corrupt memory.
-	*
-	* @see updateScreen
-	* @see getScreenFormat
-	* @see copyRectToScreen
-	*/
-
-	virtual void copyRectToOSD(const void *buf, int pitch, int x, int y, int w, int h) = 0;
-
-	/**
-	* Clears 'on screen display' from everything drawn on it.
-	*/
-
-	virtual void clearOSD() = 0;
-
-	/**
-	* Returns 'on screen display' pixel format.
-	*/
-
-	virtual Graphics::PixelFormat getOSDFormat() = 0;
-
-	/**
 	 * Return the SaveFileManager, used to store and load savestates
 	 * and other modifiable persistent game data. For more information,
 	 * refer to the SaveFileManager documentation.


Commit: 2a9d29f067a8e5f292514ab0c10d055c286178de
    https://github.com/scummvm/scummvm/commit/2a9d29f067a8e5f292514ab0c10d055c286178de
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-09-13T22:15:32+02:00

Commit Message:
Merge pull request #824 from bgK/osd

OSYSTEM: Allow drawing a background activity icon on the OSD

Changed paths:
    backends/base-backend.cpp
    backends/base-backend.h
    backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
    backends/cloud/googledrive/googledrivestorage.cpp
    backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
    backends/graphics/gph/gph-graphics.cpp
    backends/graphics/graphics.h
    backends/graphics/linuxmotosdl/linuxmotosdl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    backends/networking/curl/cloudicon.cpp
    backends/networking/curl/cloudicon.h
    common/system.h








More information about the Scummvm-git-logs mailing list