Author: mir3x
Date: Mon Dec 12 22:36:25 2016
New Revision: 34701

URL: http://svn.gna.org/viewcvs/freeciv?rev=34701&view=rev
Log:
Qt client - update minimap pixmap in another thread

See patch #8043


Modified:
    branches/S2_6/client/gui-qt/canvas.cpp
    branches/S2_6/client/gui-qt/canvas.h
    branches/S2_6/client/gui-qt/mapview.cpp
    branches/S2_6/client/gui-qt/mapview.h

Modified: branches/S2_6/client/gui-qt/canvas.cpp
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/gui-qt/canvas.cpp?rev=34701&r1=34700&r2=34701&view=diff
==============================================================================
--- branches/S2_6/client/gui-qt/canvas.cpp      (original)
+++ branches/S2_6/client/gui-qt/canvas.cpp      Mon Dec 12 22:36:25 2016
@@ -99,6 +99,25 @@
 
   p.begin(dest);
   p.drawPixmap(dest_rect, *src, source_rect);
+  p.end();
+}
+
+/****************************************************************************
+  Copies an area from the source image to the destination image.
+****************************************************************************/
+void image_copy(QImage *dest, QImage *src, int src_x, int src_y,
+                 int dest_x, int dest_y, int width, int height)
+{
+  QRectF source_rect(src_x, src_y, width, height);
+  QRectF dest_rect(dest_x, dest_y, width, height);
+  QPainter p;
+
+  if (!width || !height) {
+    return;
+  }
+
+  p.begin(dest);
+  p.drawImage(dest_rect, *src, source_rect);
   p.end();
 }
 

Modified: branches/S2_6/client/gui-qt/canvas.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/gui-qt/canvas.h?rev=34701&r1=34700&r2=34701&view=diff
==============================================================================
--- branches/S2_6/client/gui-qt/canvas.h        (original)
+++ branches/S2_6/client/gui-qt/canvas.h        Mon Dec 12 22:36:25 2016
@@ -31,5 +31,7 @@
 struct canvas *qtg_canvas_create(int width, int height);
 void pixmap_copy(QPixmap *dest, QPixmap *src, int src_x, int src_y,
                  int dest_x, int dest_y, int width, int height);
+void image_copy(QImage *dest, QImage *src, int src_x, int src_y,
+                 int dest_x, int dest_y, int width, int height);
 QRect zealous_crop_rect(QImage &p);
 #endif /* FC__CANVAS_H */

Modified: branches/S2_6/client/gui-qt/mapview.cpp
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/gui-qt/mapview.cpp?rev=34701&r1=34700&r2=34701&view=diff
==============================================================================
--- branches/S2_6/client/gui-qt/mapview.cpp     (original)
+++ branches/S2_6/client/gui-qt/mapview.cpp     Mon Dec 12 22:36:25 2016
@@ -512,6 +512,8 @@
   rw->put_to_corner();
   pix = new QPixmap;
   scale_factor = 1.0;
+  connect(&thread, SIGNAL(rendered_image(QImage)),
+          this, SLOT(update_pixmap(QImage)));
 }
 
 /**************************************************************************
@@ -675,7 +677,7 @@
 /**************************************************************************
   Scales point from scaled overview coords to real overview coords.
 **************************************************************************/
-void minimap_view::unscale_point(int &x, int &y)
+void unscale_point(double scale_factor, int &x, int &y)
 {
   int ax, bx;
   int dx, dy;
@@ -700,25 +702,70 @@
 }
 
 /**************************************************************************
-  Updates minimap's pixmap
-**************************************************************************/
-void minimap_view::update_image()
-{
-  QPixmap *tpix;
-  QPixmap gpix;
-  QPixmap bigger_pix(gui_options.overview.width * 2,
-                     gui_options.overview.height * 2);
+  Slot for updating pixmap from thread's image
+**************************************************************************/
+void minimap_view::update_pixmap(const QImage &image)
+{
+  *pix = QPixmap::fromImage(image);
+  update();
+}
+
+/**************************************************************************
+  Minimap thread's contructor
+**************************************************************************/
+minimap_thread::minimap_thread(QObject *parent) : QThread(parent)
+{
+  restart = false;
+}
+
+/**************************************************************************
+  Minimap thread's desctructor
+**************************************************************************/
+minimap_thread::~minimap_thread()
+{
+  mutex.lock();
+  condition.wakeOne();
+  mutex.unlock();
+
+  wait();
+}
+
+/**************************************************************************
+  Starts thread
+**************************************************************************/
+void minimap_thread::render(double scale_factor, int width, int height)
+{
+  QMutexLocker locker(&mutex);
+  mini_width = width;
+  mini_height = height;
+  scale = scale_factor;
+
+  if (!isRunning()) {
+    start(LowPriority);
+  } else {
+    restart = true;
+    condition.wakeOne();
+  }
+}
+
+/**************************************************************************
+  Updates minimap's iamge in thread
+**************************************************************************/
+void minimap_thread::run()
+{
+  QImage tpix;
+  QImage gpix;
+  QImage bigger_pix(gui_options.overview.width * 2,
+                    gui_options.overview.height * 2, QImage::Format_RGB32);
   int delta_x, delta_y;
   int x, y, ix, iy;
   float wf, hf;
   QPixmap *src, *dst;
-
-  if (isHidden() == true ){
-    return; 
-  }
+  QImage image(QSize(mini_width, mini_height), QImage::Format_RGB32);
+
   if (gui_options.overview.map != NULL) {
-    if (scale_factor > 1) {
-      /* move minimap now, 
+    if (scale > 1) {
+      /* move minimap now,
          scale later and draw without looking for origin */
       src = &gui_options.overview.map->map_pixmap;
       dst = &gui_options.overview.window->map_pixmap;
@@ -730,29 +777,48 @@
       pixmap_copy(dst, src, 0, y, ix, 0, x, iy);
       pixmap_copy(dst, src, x, 0, 0, iy, ix, y);
       pixmap_copy(dst, src, x, y, 0, 0, ix, iy);
-      tpix = &gui_options.overview.window->map_pixmap;
-      wf = static_cast <float>(gui_options.overview.width) / scale_factor;
-      hf = static_cast <float>(gui_options.overview.height) / scale_factor;
+      tpix = gui_options.overview.window->map_pixmap.toImage();
+      wf = static_cast <float>(gui_options.overview.width) / scale;
+      hf = static_cast <float>(gui_options.overview.height) / scale;
       x = 0;
       y = 0;
-      unscale_point(x, y);
-      /* qt 4.8 is going to copy pixmap badly if coords x+size, y+size 
+      unscale_point(scale, x, y);
+      /* qt 4.8 is going to copy pixmap badly if coords x+size, y+size
          will go over image so we create extra black bigger image */
       bigger_pix.fill(Qt::black);
       delta_x = gui_options.overview.width / 2;
       delta_y = gui_options.overview.height / 2;
-      pixmap_copy(&bigger_pix, tpix, 0, 0, delta_x, delta_y,
-                  gui_options.overview.width, gui_options.overview.height);
+      image_copy(&bigger_pix, &tpix, 0, 0, delta_x, delta_y,
+                 gui_options.overview.width, gui_options.overview.height);
       gpix = bigger_pix.copy(delta_x + x, delta_y + y, wf, hf);
-      *pix = gpix.scaled(width(), height(),
-                         Qt::IgnoreAspectRatio, Qt::FastTransformation);
+      image = gpix.scaled(mini_width, mini_height,
+                          Qt::IgnoreAspectRatio, Qt::FastTransformation);
     } else {
-      tpix = &gui_options.overview.map->map_pixmap;
-      *pix = tpix->scaled(width(), height(),
+      tpix = gui_options.overview.map->map_pixmap.toImage();
+      image = tpix.scaled(mini_width, mini_height,
                           Qt::IgnoreAspectRatio, Qt::FastTransformation);
     }
   }
-  update();
+  if (!restart) {
+    emit rendered_image(image);
+  }
+  mutex.lock();
+  if (!restart) {
+    condition.wait(&mutex);
+  }
+  restart = false;
+  mutex.unlock();
+}
+
+/**************************************************************************
+  Updates minimap's pixmap
+**************************************************************************/
+void minimap_view::update_image()
+{
+  if (isHidden() == true ) {
+    return;
+  }
+  thread.render(scale_factor, width(), height());
 }
 
 /**************************************************************************
@@ -856,7 +922,7 @@
     fx = qRound(fx / w_ratio);
     fy = qRound(fy / h_ratio);
     if (scale_factor > 1) {
-      unscale_point(fx, fy);
+      unscale_point(scale_factor, fx, fy);
     }
     fx = qMax(fx, 1);
     fy = qMax(fy, 1);

Modified: branches/S2_6/client/gui-qt/mapview.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/gui-qt/mapview.h?rev=34701&r1=34700&r2=34701&view=diff
==============================================================================
--- branches/S2_6/client/gui-qt/mapview.h       (original)
+++ branches/S2_6/client/gui-qt/mapview.h       Mon Dec 12 22:36:25 2016
@@ -32,10 +32,13 @@
 // Qt
 #include <QHBoxLayout>
 #include <QLabel>
+#include <QMutex>
 #include <QObject>
 #include <QPushButton>
 #include <QQueue>
+#include <QThread>
 #include <QTimer>
+#include <QWaitCondition>
 #include <QVariant>
 #include <QWidget>
 
@@ -45,6 +48,7 @@
 class minimap_view;
 
 bool is_point_in_area(int x, int y, int px, int py, int pxe, int pye);
+void unscale_point(double scale_factor, int &x, int &y);
 void draw_calculated_trade_routes(QPainter *painter);
 
 /**************************************************************************
@@ -187,6 +191,30 @@
 };
 
 /**************************************************************************
+  Thread helper for drawing minimap
+**************************************************************************/
+class minimap_thread : public QThread
+{
+  Q_OBJECT
+public:
+  minimap_thread(QObject *parent = 0);
+  ~minimap_thread();
+  void render(double scale_factor, int width, int height);
+
+signals:
+  void rendered_image(const QImage &image);
+protected:
+  void run() Q_DECL_OVERRIDE;
+
+private:
+  int mini_width, mini_height;
+  bool restart;
+  double scale;
+  QMutex mutex;
+  QWaitCondition condition;
+};
+
+/**************************************************************************
   QLabel used for displaying overview (minimap)
 **************************************************************************/
 class minimap_view: public fcwidget
@@ -211,6 +239,7 @@
   void showEvent(QShowEvent *event);
 
 private slots:
+  void update_pixmap(const QImage &image);
   void zoom_in();
   void zoom_out();
 
@@ -218,9 +247,9 @@
   void draw_viewport(QPainter *painter);
   void scale(double factor);
   void scale_point(int &x, int &y);
-  void unscale_point(int &x, int &y);
   double scale_factor;
   float w_ratio, h_ratio;
+  minimap_thread thread;
   QBrush background;
   QPixmap *pix;
   QPoint cursor;


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to