Public feed #890402

Threaded Screenshot PNG Creation

public text v1 · immutable
Raw Edit
·published 2008-02-03 18:43 UTC
rendered paste body
--- clientCommands.cxx.old	2008-02-03 18:10:02.000000000 +0000
+++ clientCommands.cxx.new	2008-02-03 18:38:20.000000000 +0000
@@ -20,6 +20,8 @@
 #  include <dirent.h>
 #endif
 
+#include <pthread.h>
+
 /* common implementation headers */
 #include "BZDBCache.h"
 #include "TextUtils.h"
@@ -39,6 +41,10 @@
 #include "HUDRenderer.h"
 #include "HUDui.h"
 
+pthread_mutex_t mutex;
+void *screenshot(void *);
+
+
 /** jump
  */
 static std::string cmdJump(const std::string&,
@@ -635,12 +641,31 @@
 static std::string cmdScreenshot(const std::string&,
 				 const CommandManager::ArgList& args, bool*)
 {
+  pthread_t thread;
+  static int first = 1;
+
+  if (first) {
+	pthread_mutex_init(&mutex, NULL);
+	first = 0;
+  }
+  int w = mainWindow->getWidth(), h = mainWindow->getHeight();
+  unsigned char *pixels = (unsigned char *) malloc(h * w * 3);
+  glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+  pthread_create(&thread, NULL, screenshot, (void *) pixels);
+
+  return ("");
+}
+
+  
+void *screenshot(void *sptr)
+{
+  unsigned char *pixels = (unsigned char *) sptr;
+
+  pthread_mutex_lock(&mutex);
+
   int snap = atoi(BZDB.get(std::string("lastScreenshot")).c_str());
   snap++;
 
-  if (args.size() != 0)
-    return "usage: screenshot";
-
   std::string filename = getScreenShotDirName();
   const std::string prefix = "bzfi";
   const std::string ext = ".png";
@@ -682,6 +707,8 @@
 
   BZDB.setInt(std::string("lastScreenshot"),snap);
 
+  pthread_mutex_unlock(&mutex);
+
   std::ostream* f = FILEMGR.createDataOutStream (filename.c_str(), true, true);
 
   if (f != NULL) {
@@ -689,16 +716,6 @@
     const unsigned long blength = h * w * 3 + h;    //size of b[] and br[]
     unsigned char* b = new unsigned char[blength];  //screen of pixels + column for filter type required by PNG - filtered data
 
-    // pause to prevent dt from accumulating until done screenshotting
-    LocalPlayer *myTank = LocalPlayer::getMyTank();
-    bool temp_paused = false;
-    if (myTank && !myTank->isPaused())
-	{
-    //  myTank->setDeadStop();
-	//  serverLink->sendPlayerUpdate(myTank);
-      temp_paused = true;
-    }
-
     //Prepare gamma table
     const bool gammaAdjust = BZDB.isSet("gamma");
     unsigned char gammaTable[256];
@@ -759,7 +776,7 @@
     for (i = h - 1; i >= 0; i--) {
       const unsigned long line = (h - (i + 1)) * (w * 3 + 1); //beginning of this line
       b[line] = 0;  //filter type byte at the beginning of each scanline (0 = no filter, 1 = sub filter)
-      glReadPixels(0, i, w, 1, GL_RGB, GL_UNSIGNED_BYTE, b + line + 1); //capture line
+      memcpy(b + line + 1, pixels + i * w * 3, w * 3);
       // apply gamma correction if necessary
       if (gammaAdjust) {
 	unsigned char *ptr = b + line + 1;
@@ -770,11 +787,6 @@
       }
     }
 
-    // let the user know we're paused while saving the file
-    if (temp_paused) {
-      drawFrame(0.0f);
-    }
-
     unsigned long zlength = blength + 15;	    //length of bz[], will be changed by zlib to the length of the compressed string contained therein
     unsigned char* bz = new unsigned char[zlength]; //just like b, but compressed; might get bigger, so give it room
     // compress b into bz
@@ -807,10 +819,12 @@
     crc = htonl(crc32(crc, b, (unsigned)strlen(reinterpret_cast<const char*>(b))));
     f->write((char*) &crc, 4);		       //(crc) write crc
 
-	// tEXt chunk containing gl renderer information
-	std::string renderer = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); renderer += ": ";
-	renderer += reinterpret_cast<const char*>(glGetString(GL_RENDERER)); renderer += " (OpenGL ";
-	renderer += reinterpret_cast<const char*>(glGetString(GL_VERSION)); renderer += ")";
+    // tEXt chunk containing gl renderer information
+    //std::string renderer = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); renderer += ": ";
+    //renderer += reinterpret_cast<const char*>(glGetString(GL_RENDERER)); renderer += " (OpenGL ";
+    //renderer += reinterpret_cast<const char*>(glGetString(GL_VERSION)); renderer += ")";
+    std::string renderer = "";
+
     temp = htonl(12 + (int)renderer.size()); //(length) tEXt is len("GL Renderer") + 1 + renderer.size()
     f->write((char*) &temp, 4);
     temp = htonl(PNGTAG("tEXt"));		   //(tag) tEXt
@@ -838,22 +852,9 @@
     delete [] bz;
     delete [] b;
     delete f;
-    char notify[128];
-    snprintf(notify, 128, "%s: %dx%d", filename.c_str(), w, h);
-    controlPanel->addMessage(notify);
-
-    // unpause to prevent dt from accumulating until done screenshotting
-    if (myTank && temp_paused)
-	{
-		// do a micro update to prevent DT overuns
-	//  myTank->update(0.001f);
-	//	myTank->setDeadStop();
-	//	serverLink->sendPlayerUpdate(myTank);
-    }
-    // update the display regardless of pausing
-    drawFrame(0.0f);
+
   }
-  return std::string();
+  return (void *) NULL;
 }