FractalZoomWidget.h 4.2 KB

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