[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