[Scummvm-cvs-logs] SF.net SVN: scummvm:[54942] scummvm/trunk/backends/platform/psp

bluddy at users.sourceforge.net bluddy at users.sourceforge.net
Fri Dec 17 11:58:35 CET 2010


Revision: 54942
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54942&view=rev
Author:   bluddy
Date:     2010-12-17 10:58:34 +0000 (Fri, 17 Dec 2010)

Log Message:
-----------
PSP: fixed bug exhibited in Gob engine with blacked out video frames

The problem was that I was allowing changes to the palette (in this case) even before the separate display thread, which is synchronized to vsync, was done drawing. This caused the palette to change mid-render.

The fix is a semaphore synchronizing the threads.

Modified Paths:
--------------
    scummvm/trunk/backends/platform/psp/display_manager.cpp
    scummvm/trunk/backends/platform/psp/display_manager.h
    scummvm/trunk/backends/platform/psp/osys_psp.cpp

Modified: scummvm/trunk/backends/platform/psp/display_manager.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/display_manager.cpp	2010-12-17 07:44:59 UTC (rev 54941)
+++ scummvm/trunk/backends/platform/psp/display_manager.cpp	2010-12-17 10:58:34 UTC (rev 54942)
@@ -149,6 +149,17 @@
 	sceKernelSleepThreadCB();	// sleep until we get a callback
 }
 
+// Sleep on the render mutex if the rendering thread hasn't finished its work
+//
+void MasterGuRenderer::sleepUntilRenderFinished() {
+	if (!isRenderFinished()) {
+		_renderSema.take();   // sleep on the semaphore
+		_renderSema.give();
+		PSP_DEBUG_PRINT("slept on the rendering semaphore\n");
+	}
+}
+
+
 // This callback is called when the render is finished. It swaps the buffers
 int MasterGuRenderer::guCallback(int, int, void *__this) {
 
@@ -160,6 +171,7 @@
 
 	_this->_renderFinished = true;	// Only this thread can set the variable to true
 
+	_this->_renderSema.give(); 		// Release render semaphore
 	return 0;
 }
 
@@ -214,7 +226,11 @@
 inline void MasterGuRenderer::guPreRender() {
 	DEBUG_ENTER_FUNC();
 
+#ifdef USE_DISPLAY_CALLBACK
+	_renderSema.take(); 		// Take the semaphore to prevent writes
+								// to the palette/screen before we're done
 	_renderFinished = false;	// set to synchronize with callback thread
+#endif
 
 #ifdef ENABLE_RENDER_MEASURE
 	_lastRenderTime = g_system->getMillis();
@@ -374,6 +390,12 @@
 
 }
 
+void DisplayManager::waitUntilRenderFinished() {
+#ifdef USE_DISPLAY_CALLBACK
+	_masterGuRenderer.sleepUntilRenderFinished();
+#endif /* USE_DISPLAY_CALLBACK */
+}
+
 // return true if we really rendered or no dirty. False otherwise
 bool DisplayManager::renderAll() {
 	DEBUG_ENTER_FUNC();

Modified: scummvm/trunk/backends/platform/psp/display_manager.h
===================================================================
--- scummvm/trunk/backends/platform/psp/display_manager.h	2010-12-17 07:44:59 UTC (rev 54941)
+++ scummvm/trunk/backends/platform/psp/display_manager.h	2010-12-17 10:58:34 UTC (rev 54942)
@@ -75,12 +75,14 @@
  */
 class MasterGuRenderer : public PspThreadable {
 public:
-	MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), _callbackId(-1) {}
+	MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), 
+		_renderSema(1, 1), _callbackId(-1) {}
 	void guInit();
 	void guPreRender();
 	void guPostRender();
 	void guShutDown();
 	bool isRenderFinished() { return _renderFinished; }
+	void sleepUntilRenderFinished();
 	void setupCallbackThread();
 private:
 	virtual void threadFunction();			// for the display callback thread
@@ -89,6 +91,7 @@
 	void guProgramDisplayBufferSizes();
 	static int guCallback(int, int, void *__this);	// for the display callback
 	bool _renderFinished;					// for sync with render callback
+	PspSemaphore _renderSema;				// semaphore for syncing
 	int _callbackId;						// to keep track of render callback
 };
 
@@ -114,6 +117,7 @@
 
 	void init();
 	bool renderAll();	// return true if rendered or nothing dirty. False otherwise
+	void waitUntilRenderFinished();
 	bool setGraphicsMode(int mode);
 	bool setGraphicsMode(const char *name);
 	int getGraphicsMode() const { return _graphicsMode; }

Modified: scummvm/trunk/backends/platform/psp/osys_psp.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/osys_psp.cpp	2010-12-17 07:44:59 UTC (rev 54941)
+++ scummvm/trunk/backends/platform/psp/osys_psp.cpp	2010-12-17 10:58:34 UTC (rev 54942)
@@ -131,12 +131,14 @@
 
 bool OSystem_PSP::setGraphicsMode(int mode) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	return _displayManager.setGraphicsMode(mode);
 }
 
 bool OSystem_PSP::setGraphicsMode(const char *name) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	return _displayManager.setGraphicsMode(name);
 }
@@ -160,6 +162,7 @@
 
 void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_displayManager.setSizeAndPixelFormat(width, height, format);
 
@@ -179,6 +182,7 @@
 
 void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_screen.setPartialPalette(colors, start, num);
 	_cursor.setScreenPalette(colors, start, num);
@@ -187,6 +191,7 @@
 
 void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_cursor.setCursorPalette(colors, start, num);
 	_cursor.enableCursorPalette(true);
@@ -201,12 +206,14 @@
 
 void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_screen.copyFromRect(buf, pitch, x, y, w, h);
 }
 
 Graphics::Surface *OSystem_PSP::lockScreen() {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	return _screen.lockAndGetForEditing();
 }
@@ -225,6 +232,7 @@
 
 void OSystem_PSP::setShakePos(int shakeOffset) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_screen.setShakePos(shakeOffset);
 }
@@ -247,6 +255,7 @@
 
 void OSystem_PSP::clearOverlay() {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_overlay.clearBuffer();
 }
@@ -258,6 +267,7 @@
 
 void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_overlay.copyFromRect(buf, pitch, x, y, w, h);
 }
@@ -288,12 +298,14 @@
 
 void OSystem_PSP::warpMouse(int x, int y) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 	_cursor.setXY(x, y);
 }
 
 void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
 	DEBUG_ENTER_FUNC();
+	_displayManager.waitUntilRenderFinished();
 	_pendingUpdate = false;
 
 	PSP_DEBUG_PRINT("pbuf[%p], w[%u], h[%u], hotspot:X[%d], Y[%d], keycolor[%d], scale[%d], pformat[%p]\n", buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list