ganttwidget.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. /*
  2. = StarPU-Top for StarPU =
  3. Copyright (C) 2011
  4. William Braik
  5. Yann Courtois
  6. Jean-Marie Couteyen
  7. Anthony Roy
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public
  10. License as published by the Free Software Foundation; either
  11. version 2.1 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with this library; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "ganttwidget.h"
  21. #include "mainwindow.h"
  22. #include "taskmanager.h"
  23. #include <math.h>
  24. #include <QtOpenGL>
  25. #include <QTimer>
  26. #include <sstream>
  27. const int MAX_CPU_NUM = 6;
  28. const int MAX_GPU_NUM = 3;
  29. const int MARGIN = 5;
  30. const int DEFAULT_TIME_TOTAL = 20000;
  31. const int HEIGHT_TIME_AXIS = 20;
  32. const int WIDTH_GLOBAL_PU = 50; // Width of the big CPU rect
  33. const int WIDTH_PROGRAM = 50;
  34. const int WIDTH_PU = 70;
  35. const int GRAD_NUM = 5; // Number of gradations between each label
  36. const int WIDTH_PRESENT_LINE = 1;
  37. const int SIGNIF_NUM = 100;
  38. const int FIRST_THRESHOLD = 25;
  39. const int SECOND_THRESHOLD = 75;
  40. const int SHIFT_LEFT_TIME_AXIS = 3;
  41. const int SHIFT_TOP_TIME_AXIS = 3;
  42. const QColor GANTT_BACKGROUND_COLOR = Qt::gray;
  43. const QFont::StyleHint GANTT_TEXT_FONT = QFont::Times;
  44. const QColor GANTT_TEXT_COLOR = Qt::white;
  45. const QColor GANTT_PU_COLOR = Qt::blue;
  46. const QColor GANTT_TIMELINE_COLOR = Qt::blue;
  47. const QColor GANTT_PRESENTLINE_COLOR = Qt::black;
  48. const QColor GANTT_IDLE_COLOR = Qt::red;
  49. const QColor GANTT_WORKING_COLOR = Qt::green;
  50. const QColor GANTT_PREV_COLOR = Qt::yellow;
  51. GanttWidget::GanttWidget(MainWindow *mainWindow, TaskManager *taskManager) :
  52. QGLWidget(QGLFormat(QGL::SampleBuffers), mainWindow)
  53. {
  54. _mainWindow = mainWindow;
  55. _taskManager = taskManager;
  56. setAutoFillBackground(false);
  57. _background = QBrush(GANTT_BACKGROUND_COLOR);
  58. _textPen = QPen(GANTT_TEXT_COLOR);
  59. _textFont.setPixelSize(50);
  60. _textFont.setStyleHint(GANTT_TEXT_FONT);
  61. _coordxPresentLine = 0;
  62. _numPUs = 0;
  63. _wasRunning = false;
  64. _timeTotal = DEFAULT_TIME_TOTAL;
  65. _timeBefore = _timeTotal * 0.66;
  66. _timeAfter = _timeTotal * 0.34;
  67. _lastValPrevLine = 66;
  68. _timePresent = 0;
  69. _timeToShow = 0;
  70. _numCPUs = 0;
  71. _numGPUs = 0;
  72. _heightPU = 0;
  73. _initCompleted = false;
  74. _PUsByDevice = 0;
  75. _PUsByPos = 0;
  76. // Start display update timer
  77. _timer = new QTimer(this);
  78. _timer->start(35);
  79. // Connect events
  80. QObject::connect(_mainWindow, SIGNAL(sessionOpened()),
  81. this, SLOT(connected()));
  82. QObject::connect(_mainWindow, SIGNAL(sessionClosed()),
  83. this, SLOT(disconnected()));
  84. QObject::connect(_mainWindow, SIGNAL(debugLocked()),
  85. this, SLOT(ganttLocked()));
  86. QObject::connect(_mainWindow, SIGNAL(debugStepped()),
  87. this, SLOT(ganttUnlocked()));
  88. QObject::connect(_timer, SIGNAL(timeout()),
  89. this, SLOT(update()));
  90. }
  91. GanttWidget::~GanttWidget()
  92. {
  93. delete _timer;
  94. delete _rectPUs;
  95. }
  96. void GanttWidget::defaultScreen(QPainter *painter)
  97. {
  98. painter->setPen(GANTT_TEXT_COLOR);
  99. drawPresentLine(painter);
  100. drawTime(painter);
  101. }
  102. // Called each time the window is resized
  103. void GanttWidget::resizeGL(int width, int height)
  104. {
  105. (void) width;
  106. (void) height;
  107. update();
  108. }
  109. void GanttWidget::paintEvent(QPaintEvent *event)
  110. {
  111. QPainter painter;
  112. painter.begin(this);
  113. painter.setRenderHint(QPainter::Antialiasing);
  114. paint(&painter, event);
  115. painter.end();
  116. }
  117. /* Draw CPU and GPU rects */
  118. void GanttWidget::drawPUs(QPainter *painter)
  119. {
  120. QFont f;
  121. QPen penRect;
  122. QPen penText;
  123. QPointF coordTxt;
  124. QString txt;
  125. QStaticText name;
  126. f.setFamily("utf8");
  127. f.setWeight(QFont::Bold);
  128. f.setPixelSize(12);
  129. painter->setFont(f);
  130. penRect.setColor(GANTT_PU_COLOR);
  131. penText.setColor(GANTT_TEXT_COLOR);
  132. painter->setPen(penRect);
  133. _rectPUs = new QRectF[_numCPUs + _numGPUs];
  134. int height_allowed = size().height() - HEIGHT_TIME_AXIS - MARGIN;
  135. // height of each processor unit rectangles
  136. int height = height_allowed / (_numCPUs + _numGPUs);
  137. _heightPU = height;
  138. int height_cpublock = height * _numCPUs;
  139. int height_gpublock = height * _numGPUs;
  140. /* The CPUs rect */
  141. if (_numCPUs > 0)
  142. {
  143. _rectCPUblock = QRectF(WIDTH_PROGRAM + MARGIN,
  144. HEIGHT_TIME_AXIS + MARGIN, WIDTH_GLOBAL_PU,
  145. height_cpublock - MARGIN);
  146. painter->drawRect(_rectCPUblock);
  147. painter->fillRect(_rectCPUblock, GANTT_PU_COLOR);
  148. painter->setPen(penText);
  149. coordTxt = QPointF(
  150. _rectCPUblock.center().rx() - (WIDTH_GLOBAL_PU / 2) + 3,
  151. _rectCPUblock.center().ry() - f.pixelSize());
  152. txt = QString("CPU(s)");
  153. name = QStaticText(txt);
  154. name.setPerformanceHint(QStaticText::AggressiveCaching);
  155. painter->drawStaticText(coordTxt, name);
  156. }
  157. f.setWeight(QFont::Light);
  158. f.setPixelSize(10);
  159. painter->setFont(f);
  160. painter->setPen(penRect);
  161. /* devices */
  162. for (int i = 0; i < _numCPUs + _numGPUs; i++)
  163. {
  164. painter->setPen(penRect);
  165. _rectPUs[i] = QRectF(WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN,
  166. HEIGHT_TIME_AXIS + MARGIN + i * height, WIDTH_PU,
  167. height - MARGIN);
  168. painter->drawRect(_rectPUs[i]);
  169. painter->fillRect(_rectPUs[i], Qt::blue);
  170. painter->setPen(penText);
  171. if (_heightPU >= f.pixelSize() * 2)
  172. {
  173. painter->drawText(_rectPUs[i], Qt::AlignVCenter, _PUsByPos[i].name);
  174. }
  175. }
  176. f.setFamily("utf8");
  177. f.setWeight(QFont::Bold);
  178. f.setPixelSize(12);
  179. painter->setFont(f);
  180. painter->setPen(penRect);
  181. /* The GPUs rect */
  182. if (_numGPUs > 0)
  183. {
  184. _rectGPUblock = QRectF(WIDTH_PROGRAM + MARGIN,
  185. HEIGHT_TIME_AXIS + MARGIN + height_cpublock, WIDTH_GLOBAL_PU,
  186. height_gpublock - MARGIN);
  187. painter->drawRect(_rectGPUblock);
  188. painter->fillRect(_rectGPUblock, Qt::blue);
  189. coordTxt = QPointF(
  190. _rectGPUblock.center().rx() - (WIDTH_GLOBAL_PU / 2) + 3,
  191. _rectGPUblock.center().ry() - f.pixelSize());
  192. txt = QString("GPU(s)");
  193. name = QStaticText(txt);
  194. name.setPerformanceHint(QStaticText::AggressiveCaching);
  195. painter->setPen(penText);
  196. painter->drawStaticText(coordTxt, name);
  197. }
  198. }
  199. /* calculate abscissa on the screen for a given time (in ms) if it's displayable
  200. return -1 if timestampMs is outside time displayable because of scale*/
  201. qreal GanttWidget::coordxForTime(qlonglong timestampMs)
  202. {
  203. qreal startx = (qreal) WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN
  204. + WIDTH_PU + MARGIN;
  205. qreal widthAllowed = (qreal) size().width() - startx;
  206. qreal scale = (qreal) widthAllowed / _timeTotal;
  207. qreal coordx = -1;
  208. if (timestampMs >= 0)
  209. {
  210. if ((timestampMs <= _timePresent) && (timestampMs >= (_timePresent
  211. - _timeBefore)))
  212. {
  213. coordx = (qreal) startx + (qreal)(
  214. (_timeBefore - (_timePresent - timestampMs)) * scale);
  215. }
  216. else if ((timestampMs > _timePresent) && timestampMs <= (_timeAfter
  217. + _timePresent))
  218. {
  219. coordx = (qreal) _coordxPresentLine + (qreal)(
  220. (timestampMs - _timePresent) * scale);
  221. }
  222. }
  223. return coordx;
  224. }
  225. void GanttWidget::drawTime(QPainter *painter)
  226. {
  227. QFont f;
  228. QPen penRect;
  229. QPen penText;
  230. penRect.setColor(GANTT_TIMELINE_COLOR);
  231. penText.setColor(GANTT_TEXT_COLOR);
  232. painter->setPen(penRect);
  233. f.setFamily("utf8");
  234. f.setWeight(QFont::DemiBold);
  235. f.setPixelSize(10);
  236. painter->setFont(f);
  237. _rectTime = QRectF(0, 0, size().width(), 20);
  238. painter->drawRect(_rectTime);
  239. painter->fillRect(_rectTime, Qt::blue);
  240. QString titre = QString("Time (ms)");
  241. QStaticText titreTxt = QStaticText(titre);
  242. titreTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  243. QPointF coordRect = QPointF(_rectTime.left() + SHIFT_LEFT_TIME_AXIS,
  244. _rectTime.center().ry() - f.pixelSize() + SHIFT_TOP_TIME_AXIS);
  245. painter->setPen(penText);
  246. painter->drawStaticText(coordRect, titreTxt);
  247. f.setWeight(QFont::Light);
  248. f.setPixelSize(10);
  249. painter->setFont(f);
  250. qreal ourStartx = WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN
  251. + WIDTH_PU + MARGIN;
  252. qreal widthAvailable = ((qreal)(size().width() - ourStartx));
  253. qreal scale = ((qreal)(_timeBefore + _timeAfter) / widthAvailable);
  254. qreal scale_time_px = (qreal) widthAvailable / (_timeBefore + _timeAfter);
  255. int timeInterval = computeTimeInterval(_timeTotal);
  256. qreal sizeInterval = ((qreal)(timeInterval * scale_time_px));
  257. qreal step_x = (qreal)(sizeInterval / GRAD_NUM);
  258. //we calculate the location of the next gradation in the future part
  259. qlonglong first = _timePresent - _timePresent % ((qlonglong) timeInterval);
  260. qlonglong cur_t = first;
  261. //gradations in the past
  262. while (cur_t > _timePresent - _timeBefore)
  263. {
  264. if (cur_t >= (qlonglong) 0)
  265. {
  266. qreal cur_x =
  267. ((qreal)((_timeBefore - (_timePresent - cur_t)) / scale)
  268. + ourStartx);
  269. QString buffer;
  270. buffer.append(QString("%1").arg(cur_t));
  271. QStaticText gradTxt = QStaticText(buffer);
  272. gradTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  273. //calculate the fading
  274. int fading = 3 * (cur_x - ourStartx);
  275. if (fading < 0)
  276. {
  277. fading = 0;
  278. }
  279. if (fading > 255)
  280. {
  281. fading = 255;
  282. }
  283. _textPen.setColor(QColor(255, 255, 255, fading));
  284. painter->setPen(_textPen);
  285. painter->drawLine(
  286. QLineF(cur_x, 0, cur_x, HEIGHT_TIME_AXIS - MARGIN));
  287. if (widthAvailable > 500)
  288. {
  289. painter->drawStaticText(
  290. QPointF(cur_x,
  291. HEIGHT_TIME_AXIS - MARGIN - f.pixelSize()),
  292. gradTxt);
  293. }
  294. for (int k = 1; k < GRAD_NUM; k++)
  295. { // k=1 ,because of spans
  296. painter->drawLine(
  297. QLineF(cur_x + step_x * k, 0, cur_x + step_x * k,
  298. HEIGHT_TIME_AXIS - MARGIN * 3));
  299. }
  300. }
  301. cur_t -= timeInterval;
  302. }
  303. //in the future
  304. cur_t = first + timeInterval;
  305. while (cur_t < _timePresent + _timeAfter)
  306. {
  307. qreal cur_x = ((qreal)((_timeBefore - (_timePresent - cur_t)) / scale)
  308. + ourStartx);
  309. QString buffer;
  310. buffer.append(QString("%1").arg(cur_t));
  311. QStaticText gradTxt = QStaticText(buffer);
  312. gradTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  313. //calculate the fading
  314. int fading = 3 * (size().width() - cur_x);
  315. if (fading > 255)
  316. {
  317. fading = 255;
  318. }
  319. _textPen.setColor(QColor(255, 255, 255, fading));
  320. painter->setPen(_textPen);
  321. painter->drawLine(QLineF(cur_x, 0, cur_x, HEIGHT_TIME_AXIS - MARGIN));
  322. if (widthAvailable > 500)
  323. {
  324. painter->drawStaticText(
  325. QPointF(cur_x, HEIGHT_TIME_AXIS - MARGIN - f.pixelSize()),
  326. gradTxt);
  327. }
  328. for (int k = 1; k < GRAD_NUM; k++)
  329. {
  330. painter->drawLine(
  331. QLineF(cur_x + step_x * k, 0, cur_x + step_x * k,
  332. HEIGHT_TIME_AXIS - MARGIN * 3));
  333. }
  334. cur_t += timeInterval;
  335. }
  336. _textPen.setColor(QColor(255, 255, 255));
  337. painter->setPen(_textPen);
  338. }
  339. //calculate un lapse of time to get at least 20 gradations if 1000 <= timeTotal
  340. //and <=24 * 10^X
  341. int GanttWidget::computeTimeInterval(int timeTotal)
  342. {
  343. int coef = 1;
  344. while (timeTotal >= SIGNIF_NUM)
  345. {
  346. timeTotal = timeTotal / 10;
  347. coef *= 10;
  348. }
  349. //we have a number between 1 and 99
  350. if (timeTotal < FIRST_THRESHOLD)
  351. {
  352. return coef;
  353. }
  354. else if (timeTotal < SECOND_THRESHOLD)
  355. {
  356. return coef * 5;
  357. }
  358. else
  359. {
  360. return coef * 10;
  361. }
  362. }
  363. void GanttWidget::drawProgram(QPainter *painter)
  364. {
  365. QFont f;
  366. QPen penRect;
  367. QPen penText;
  368. penRect.setColor(GANTT_PU_COLOR);
  369. penText.setColor(GANTT_TEXT_COLOR);
  370. f.setFamily("utf8");
  371. f.setWeight(QFont::Black);
  372. f.setPixelSize(10);
  373. painter->setFont(f);
  374. painter->setPen(penRect);
  375. _rectProg = QRectF(0, HEIGHT_TIME_AXIS + MARGIN, WIDTH_PROGRAM,
  376. size().height() - HEIGHT_TIME_AXIS - MARGIN * 2);
  377. painter->drawRect(_rectProg);
  378. painter->fillRect(_rectProg, Qt::blue);
  379. QPointF coordTxt = QPointF(
  380. _rectProg.center().rx() - (WIDTH_PROGRAM / 2) + 3,
  381. _rectProg.center().ry() - f.pixelSize());
  382. QString txt = QString("Program");
  383. QStaticText name = QStaticText(txt);
  384. name.setPerformanceHint(QStaticText::AggressiveCaching);
  385. painter->setPen(penText);
  386. painter->drawStaticText(coordTxt, name);
  387. }
  388. void GanttWidget::drawPresentLine(QPainter *painter)
  389. {
  390. QPen pen;
  391. pen.setColor(GANTT_PRESENTLINE_COLOR);
  392. painter->setPen(pen);
  393. qreal widthAllowed = (qreal)(
  394. size().width() - WIDTH_PROGRAM - MARGIN - WIDTH_GLOBAL_PU - MARGIN
  395. - WIDTH_PU - MARGIN);
  396. int timeTotal = _timeBefore + _timeAfter;
  397. int x, y, w, h;
  398. x = WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN + WIDTH_PU + MARGIN;
  399. y = (HEIGHT_TIME_AXIS + MARGIN);
  400. w = WIDTH_PRESENT_LINE;
  401. h = size().height() - (HEIGHT_TIME_AXIS + MARGIN);
  402. qreal scale = (qreal)(widthAllowed / timeTotal);
  403. qreal gap_x = (qreal)(scale * _timeBefore);
  404. _linePresent = QRectF(x + gap_x, y, w, h);
  405. _coordxPresentLine = (qreal)(x + gap_x);
  406. painter->drawRect(_linePresent);
  407. painter->fillRect(_linePresent, Qt::black);
  408. }
  409. /* Draw whole gantt diagram depending on time showing line present location.
  410. Useful to draw the diagram after the complete execution. */
  411. void GanttWidget::drawFromTime(QPainter *painter, qlonglong timestamp)
  412. {
  413. Q_ASSERT_X(timestamp >= 0, "GanttWidget::drawFromTime",
  414. "Negative timestamp !");
  415. /* program rect */
  416. drawProgram(painter);
  417. _timePresent = timestamp;
  418. /* time line */
  419. drawTime(painter);
  420. drawPUs(painter);
  421. /* Tasks */
  422. drawIdlePU(painter);
  423. qlonglong borneBefore = _timePresent - _timeBefore;
  424. if (borneBefore < 0)
  425. {
  426. borneBefore = 0;
  427. }
  428. _tasks = _taskManager->tasks(borneBefore, _timePresent);
  429. foreach(starpu_top_task t, _tasks)
  430. {
  431. drawWorkPU(painter,t);
  432. }
  433. }
  434. /* draw idle time for each processor */
  435. void GanttWidget::drawIdlePU(QPainter *painter)
  436. {
  437. int starty = HEIGHT_TIME_AXIS + MARGIN;
  438. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  439. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  440. int timeTotal = _timeBefore + _timeAfter;
  441. qreal posBlockx = 0;
  442. qreal placeTime = 0;
  443. bool isStartx = false;
  444. qreal scale = (qreal) widthAllowed / timeTotal;
  445. QRectF rectIdle;
  446. qlonglong timestampS = 0;
  447. if (_timePresent >= _timeBefore)
  448. {
  449. timestampS = _timePresent - _timeBefore;
  450. }
  451. /* drawIdlePu */
  452. for (qlonglong j = timestampS; j < _timePresent; j++)
  453. {
  454. if (!isStartx)
  455. {
  456. isStartx = true;
  457. posBlockx = coordxForTime(j);
  458. }
  459. placeTime++;
  460. }
  461. QFont f;
  462. QPen pen;
  463. f.setFamily("utf8");
  464. f.setWeight(QFont::DemiBold);
  465. f.setPixelSize(10);
  466. painter->setFont(f);
  467. pen.setColor(GANTT_IDLE_COLOR.lighter(110));
  468. painter->setPen(pen);
  469. for (int i = 0; i < _numPUs; i++)
  470. {
  471. rectIdle = QRectF(posBlockx, starty + (_heightPU) * i,
  472. placeTime * scale, (_heightPU - MARGIN));
  473. painter->drawRect(rectIdle);
  474. painter->fillRect(rectIdle, GANTT_IDLE_COLOR);
  475. }
  476. }
  477. /* draw forecasted working time for each processor */
  478. void GanttWidget::drawPrevWorkPU(QPainter *painter, starpu_top_task t)
  479. {
  480. int starty = HEIGHT_TIME_AXIS + MARGIN;
  481. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  482. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  483. qreal posBlockx = 0;
  484. qreal placeTime = 0;
  485. bool isStartx = false;
  486. qreal scale = (qreal) widthAllowed / _timeTotal;
  487. QRectF rectForecast;
  488. //either the beginning is in the Future Part
  489. //( timeAfter ) or either in the Past Part (timeBefore)
  490. qlonglong timestampS = (t.timestampStart - _timePresent);
  491. if (timestampS > 0)
  492. {
  493. // the beginning is in the Future part (displayable here)
  494. timestampS = t.timestampStart;
  495. }
  496. else
  497. {
  498. // the beginning is in the Past part (not displayable here)
  499. timestampS = _timePresent;
  500. // +1 just to be sure we don't draw over the line of Present
  501. posBlockx = _coordxPresentLine + WIDTH_PRESENT_LINE + 1;
  502. isStartx = true;
  503. placeTime -= WIDTH_PRESENT_LINE + 1;
  504. }
  505. qlonglong timestampE = (t.timestampEnd - _timePresent);
  506. if (timestampE > 0)
  507. {
  508. if (timestampE <= _timeAfter)
  509. {
  510. timestampE = t.timestampEnd; // the end is displayable
  511. }
  512. else
  513. {
  514. // the end is not displayable because it's in the future
  515. // more than timePresent + timeAfter
  516. timestampE = _timePresent + _timeAfter;
  517. }
  518. }
  519. else
  520. {
  521. // the end is not displayable because it's in the past
  522. timestampE = _timePresent;
  523. posBlockx = _coordxPresentLine + WIDTH_PRESENT_LINE + 1;
  524. isStartx = true;
  525. placeTime -= WIDTH_PRESENT_LINE + 1;
  526. }
  527. /* Future */
  528. for (qlonglong i = timestampS; i <= timestampE; i++)
  529. {
  530. if (!isStartx)
  531. {
  532. isStartx = true;
  533. posBlockx = coordxForTime(i);
  534. }
  535. placeTime++;
  536. }
  537. int pos = _PUsByDevice[t.deviceId].id;
  538. QFont f;
  539. QPen pen;
  540. pen.setColor(GANTT_TEXT_COLOR);
  541. painter->setPen(pen);
  542. f.setFamily("utf8");
  543. f.setWeight(QFont::DemiBold);
  544. f.setPixelSize(10);
  545. painter->setFont(f);
  546. QLinearGradient gradient(posBlockx,
  547. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2,
  548. posBlockx + placeTime * scale,
  549. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2);
  550. QColor prevColor = GANTT_PREV_COLOR;
  551. gradient.setColorAt(0.2, prevColor.lighter(110));
  552. gradient.setColorAt(0.3, Qt::yellow);
  553. gradient.setColorAt(0.80, prevColor.darker(270));
  554. QBrush brush(gradient);
  555. pen.setBrush(brush);
  556. painter->setPen(pen);
  557. rectForecast = QRectF(posBlockx, starty + (_heightPU) * pos,
  558. placeTime * scale, (_heightPU - MARGIN));
  559. painter->drawRect(rectForecast);
  560. painter->fillRect(rectForecast, brush);
  561. }
  562. /* Draw working time for each processor. Working PUs.
  563. We don't mind about task values because the taskmanager gives us only the tasks
  564. between timeBefore and timePresent so
  565. we haven't to test if they are displayable or not. We just have to calculate
  566. which part of time is displayable.
  567. The task t has its begin or its end between time Before and timePresent */
  568. void GanttWidget::drawWorkPU(QPainter *painter, starpu_top_task t)
  569. {
  570. int starty = HEIGHT_TIME_AXIS + MARGIN;
  571. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  572. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  573. qreal posBlockx = 0;
  574. qreal placeTime = 0;
  575. bool isStartx = false;
  576. qreal scale = (qreal) widthAllowed / _timeTotal;
  577. QRectF rectWorking;
  578. qlonglong timestampS = (_timePresent - t.timestampStart);
  579. qlonglong timestampE = -1;
  580. if (timestampS > _timeBefore)
  581. {
  582. // Begin time of task t is not displayable
  583. timestampS = _timePresent - _timeBefore;
  584. }
  585. else
  586. {
  587. timestampS = t.timestampStart; // Begin time of task t is displayable
  588. }
  589. if (t.timestampEnd == -1)
  590. {
  591. for (qlonglong i = timestampS; i <= _timePresent; i++)
  592. {
  593. if (!isStartx)
  594. {
  595. isStartx = true;
  596. posBlockx = coordxForTime(i);
  597. }
  598. placeTime++;
  599. }
  600. }
  601. else
  602. {
  603. timestampE = t.timestampEnd;
  604. if (timestampE > _timePresent)
  605. {
  606. timestampE = _timePresent;
  607. }
  608. for (qlonglong i = timestampS; i <= timestampE; i++)
  609. {
  610. if (!isStartx)
  611. {
  612. isStartx = true;
  613. posBlockx = coordxForTime(i);
  614. }
  615. placeTime++;
  616. }
  617. }
  618. int pos = _PUsByDevice[t.deviceId].id;
  619. QFont f;
  620. QPen pen;
  621. f.setFamily("utf8");
  622. f.setWeight(QFont::DemiBold);
  623. f.setPixelSize(10);
  624. painter->setFont(f);
  625. rectWorking = QRectF(posBlockx, starty + (_heightPU) * pos,
  626. placeTime * scale, (_heightPU - MARGIN));
  627. painter->drawRect(rectWorking);
  628. QLinearGradient gradient(posBlockx,
  629. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2,
  630. posBlockx + placeTime * scale,
  631. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2);
  632. QColor workingColor = GANTT_WORKING_COLOR;
  633. gradient.setColorAt(0.2, workingColor.lighter(110));
  634. gradient.setColorAt(0.3, Qt::green);
  635. gradient.setColorAt(0.8, workingColor.darker(270));
  636. gradient.setSpread(QGradient::PadSpread);
  637. QBrush brush(gradient);
  638. pen.setBrush(brush);
  639. painter->setPen(pen);
  640. painter->fillRect(rectWorking, brush);
  641. }
  642. void GanttWidget::updateZoom(double value)
  643. {
  644. qDebug() << "VALEUR === " << value;
  645. // if(!(value == 0.0))
  646. // {
  647. _timeTotal = value;
  648. updatePrevLine( _lastValPrevLine);
  649. //}
  650. }
  651. void GanttWidget::updatePrevLine(double value)
  652. {
  653. _timeBefore = _timeTotal * (value / 100);
  654. _timeAfter = _timeTotal * ((100 - value) / 100);
  655. _lastValPrevLine = value;
  656. if (!(_timer->isActive()))
  657. {
  658. update();
  659. }
  660. }
  661. void GanttWidget::updateTimeView(int time)
  662. {
  663. qlonglong newTimeToShow = time;
  664. if (!(_timer->isActive()))
  665. {
  666. _timeToShow = newTimeToShow;
  667. update();
  668. }
  669. }
  670. void GanttWidget::connected()
  671. {
  672. _wasRunning = false;
  673. _initCompleted = false;
  674. _timePresent = 0;
  675. if (!(_timer->isActive()))
  676. {
  677. _timer->start(35);
  678. }
  679. }
  680. void GanttWidget::disconnected()
  681. {
  682. _wasRunning = true;
  683. if (_timer->isActive())
  684. {
  685. _timer->stop();
  686. }
  687. }
  688. void GanttWidget::ganttLocked()
  689. {
  690. update(); // a last drawing update before to freeze the drawing
  691. if (_timer->isActive())
  692. {
  693. _timer->stop(); // freeze the drawing
  694. }
  695. }
  696. void GanttWidget::ganttUnlocked()
  697. {
  698. if (!(_timer->isActive()))
  699. {
  700. _timer->start(35); // start the timer again
  701. }
  702. }
  703. void GanttWidget::countPUs()
  704. {
  705. int length;
  706. _numCPUs = 0;
  707. _numGPUs = 0;
  708. length = _mainWindow->serverDevices()->length();
  709. _numPUs = length;
  710. delete _PUsByDevice;
  711. delete _PUsByPos;
  712. _PUsByDevice = new starpu_top_device[length];
  713. _PUsByPos = new starpu_top_device[length];
  714. int pos = 0;
  715. /* CPUs */
  716. foreach(starpu_top_device sD,*_mainWindow->serverDevices())
  717. {
  718. if(sD.type == 0)
  719. {
  720. _PUsByDevice[sD.id].name = sD.name;
  721. _PUsByDevice[sD.id].type = sD.type;
  722. _PUsByDevice[sD.id].id = pos; // actual location
  723. _PUsByPos[pos].id = sD.id; // the reak id
  724. _PUsByPos[pos].name = sD.name;
  725. _PUsByPos[pos].type = sD.type;
  726. _numCPUs++;
  727. pos++;
  728. }
  729. }
  730. /* GPUs */
  731. foreach (starpu_top_device sD , *_mainWindow->serverDevices())
  732. {
  733. if(sD.type == 1 || sD.type == 2)
  734. {
  735. _PUsByDevice[sD.id].name = sD.name;
  736. _PUsByDevice[sD.id].type = sD.type;
  737. _PUsByDevice[sD.id].id = pos; // actually location
  738. _PUsByPos[pos].id = sD.id; // the real id
  739. _PUsByPos[pos].name = sD.name;
  740. _PUsByPos[pos].type = sD.type;
  741. pos++;
  742. _numGPUs++;
  743. }
  744. }
  745. }
  746. void GanttWidget::paint(QPainter *painter, QPaintEvent *event)
  747. {
  748. painter->fillRect(event->rect(), _background);
  749. painter->setPen(_textPen);
  750. if (_mainWindow->isReady())
  751. {
  752. if (!_initCompleted)
  753. { // do not call countPUs more than once per execution
  754. countPUs();
  755. _initCompleted = true;
  756. }
  757. drawProgram(painter);
  758. drawPUs(painter);
  759. if (_mainWindow->isRunning())
  760. {
  761. _timePresent = _mainWindow->effectiveRunningTime();
  762. _timeToShow = _timePresent; // saved the time of end
  763. drawTime(painter);
  764. drawPresentLine(painter);
  765. drawIdlePU(painter);
  766. /* Past part */
  767. qlonglong borneBefore = _timePresent - _timeBefore;
  768. if (borneBefore < 0)
  769. {
  770. borneBefore = 0;
  771. }
  772. _tasks = _taskManager->tasks(borneBefore, _timePresent);
  773. foreach (starpu_top_task t, _tasks)
  774. {
  775. drawWorkPU(painter,t);
  776. }
  777. /* Future past */
  778. qlonglong borneAfter = _timePresent + _timeAfter;
  779. _tasks = _taskManager->prevTasks(_timePresent, borneAfter);
  780. foreach (starpu_top_task t, _tasks)
  781. {
  782. drawPrevWorkPU(painter,t);
  783. }
  784. }
  785. else if (!_wasRunning)
  786. {
  787. defaultScreen(painter);
  788. }
  789. }
  790. else
  791. {
  792. if (_wasRunning)
  793. {
  794. // display wanted part of execution (only if it's finished)
  795. drawFromTime(painter,_timeToShow);
  796. }
  797. }
  798. }