FractalZoomWidget.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef FRACTALZOOMWIDGET_H
  2. #define FRACTALZOOMWIDGET_H
  3. #include "EscapeTimeVisualWidget.h"
  4. #include "FractalWidgetUtils.h"
  5. #include "Bitmap.h"
  6. #include <QThreadPool>
  7. #include <QMutex>
  8. class FractalZoomWidget;
  9. Q_DECLARE_METATYPE(std::shared_ptr<ETVImage>)
  10. ///
  11. /// \brief represents a grid of images at a certain depth
  12. /// in the fractal.
  13. ///
  14. class SliceGrid
  15. {
  16. public:
  17. FractalZoomWidget& owner;
  18. int level;
  19. mnd::Real dpp;
  20. std::unordered_map<std::pair<GridIndex, GridIndex>, std::unique_ptr<GridElement>, IndexPairHash> cells;
  21. public:
  22. SliceGrid(FractalZoomWidget& owner, int level);
  23. std::pair<GridIndex, GridIndex> getCellIndices(mnd::Real x, mnd::Real y);
  24. std::pair<mnd::Real, mnd::Real> getPositions(GridIndex i, GridIndex j);
  25. GridElement* getCell(GridIndex i, GridIndex j);
  26. void setCell(GridIndex i, GridIndex j, std::unique_ptr<GridElement> tex);
  27. inline size_t countAllocatedCells(void) const { return cells.size(); }
  28. void clearCells(void);
  29. void clearUncleanCells(void);
  30. };
  31. class Calcer : public QObject
  32. {
  33. Q_OBJECT
  34. /// tuple contains level, i, j of the job
  35. std::unordered_map<std::tuple<int, GridIndex, GridIndex>, CalcJob*, IndexTripleHash> jobs;
  36. QMutex jobsMutex;
  37. QThreadPool* threadPool;
  38. FractalZoomWidget& owner;
  39. int currentLevel;
  40. volatile unsigned int calcState = 0;
  41. public:
  42. Calcer(FractalZoomWidget& owner);
  43. void clearAll(void);
  44. inline void changeState(void) { calcState++; }
  45. public slots:
  46. void calc(SliceGrid& grid, int level, GridIndex i, GridIndex j, int priority);
  47. void setCurrentLevel(int level);
  48. void notFinished(int level, GridIndex i, GridIndex j);
  49. void jobFailed(int level, GridIndex i, GridIndex j);
  50. void redirect(int level, GridIndex i, GridIndex j, Bitmap<float>* bmp);
  51. signals:
  52. void done(int level, GridIndex i, GridIndex j, Bitmap<float>* bmp);
  53. };
  54. class TextureUploader :
  55. public QThread
  56. {
  57. Q_OBJECT
  58. QOpenGLContext* context;
  59. EscapeTimeVisualWidget& owner;
  60. public:
  61. TextureUploader(EscapeTimeVisualWidget& shareWith, QObject* parent = nullptr);
  62. public slots:
  63. void upload(int level, GridIndex i, GridIndex j, Bitmap<float>* bmp);
  64. signals:
  65. void uploaded(int level, GridIndex i, GridIndex j, std::shared_ptr<ETVImage>);
  66. };
  67. class FractalZoomWidget :
  68. public EscapeTimeVisualWidget
  69. {
  70. Q_OBJECT
  71. // a grid should not be deleted once constructed.
  72. // to free up memory one can call SliceGrid::clearCells()
  73. std::unordered_map<int, SliceGrid> levels;
  74. mnd::MandelGenerator* generator;
  75. Calcer calcer;
  76. ETVImage* emptyImage;
  77. const bool useUploadThread = true;
  78. TextureUploader* uploader;
  79. QThread* uploadeThread;
  80. protected:
  81. mnd::MandelInfo mandelInfo;
  82. public:
  83. static const int chunkSize;
  84. FractalZoomWidget(QWidget* parent = nullptr);
  85. Q_PROPERTY(mnd::MandelViewport viewport READ getViewport WRITE setViewport)
  86. virtual void setViewport(const mnd::MandelViewport& viewport);
  87. virtual const mnd::MandelViewport& getViewport(void) const;
  88. int getLevel(const mnd::Real& dpp) const;
  89. mnd::Real getDpp(int level) const;
  90. SliceGrid& getGrid(int level);
  91. void clearCells(void);
  92. void garbageCollect(int level,
  93. const GridIndex& i, const GridIndex& j);
  94. GridElement* searchAbove(int level,
  95. const GridIndex& i, const GridIndex& j,
  96. int recursionLevel);
  97. GridElement* searchUnder(int level,
  98. const GridIndex& i, const GridIndex& j,
  99. int recursionLevel);
  100. const mnd::MandelInfo& getMandelInfo(void) const;
  101. mnd::MandelInfo& getMandelInfo(void);
  102. void setGenerator(mnd::MandelGenerator*);
  103. mnd::MandelGenerator* getGenerator(void) const;
  104. virtual void zoom(float factor);
  105. virtual void setSmoothColoring(bool smooth);
  106. virtual void setMaxIterations(int maxIterations);
  107. virtual void initializeGL(void) override;
  108. virtual void resizeGL(int w, int h) override;
  109. virtual void paintGL(void) override;
  110. protected slots:
  111. void cellReady(int level, GridIndex i, GridIndex j, Bitmap<float>* bmp);
  112. void cellReadyTex(int level, GridIndex i, GridIndex j, std::shared_ptr<ETVImage> img);
  113. };
  114. #endif // FRACTALZOOMWIDGET_H