1 /**************************************************************************
2 * This file is part of the Fraqtive program
3 * Copyright (C) 2004-2012 Michał Męciński
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 **************************************************************************/
18 
19 #ifndef FRACTALGENERATOR_H
20 #define FRACTALGENERATOR_H
21 
22 #include <QEvent>
23 #include <QMutex>
24 #include <QObject>
25 #include <QWaitCondition>
26 
27 #include "abstractjobprovider.h"
28 #include "datastructures.h"
29 #include "generatorcore.h"
30 
31 class FractalData;
32 
33 class FractalGenerator : public QObject, public AbstractJobProvider
34 {
35     Q_OBJECT
36 public:
37     enum UpdateStatus
38     {
39         NoUpdate,
40         InitialUpdate,
41         PartialUpdate,
42         FullUpdate,
43         ClearUpdate
44     };
45 
46     static const QEvent::Type UpdateEvent = static_cast<QEvent::Type>( QEvent::User + 1 );
47 
48 public:
49     FractalGenerator( QObject* parent );
50     ~FractalGenerator();
51 
52 public:
53     void setPreviewMode( bool preview );
54     void setPriority( int priority );
55     void setReceiver( QObject* receiver );
56 
57     void setEnabled( bool enabled );
58 
59     void setParameters( const FractalType& type, const Position& position );
60     void setFractalType( const FractalType& type );
61     void setPosition( const Position& position );
62 
63     void setGeneratorSettings( const GeneratorSettings& settings );
64 
65     void setResolution( const QSize& resolution );
resolution()66     QSize resolution() const { return m_resolution; }
67 
68     int maximumIterations() const;
69 
70     UpdateStatus updateData( FractalData* data );
71 
72 public: // AbstractJobProvider implementation
73     int priority() const;
74 
75     void executeJob();
76 
77 private:
78     void calculateRegion( const QRect& region );
79 
80     void reset();
81 
82     void handleState();
83 
84     void createFunctor();
85 
86     void splitRegions();
87 
88     void calculateInput( GeneratorCore::Input* input, const QRect& region );
89     void calculateOutput( GeneratorCore::Output* output, const QRect& region );
90 
91     void addJobs();
92     void cancelJobs();
93     void finishJob();
94 
95     void appendValidRegion( const QRect& region );
96 
97     void postUpdate( UpdateStatus update );
98 
99 private:
100     bool m_preview;
101     int m_priority;
102     QObject* m_receiver;
103 
104     QMutex m_mutex;
105 
106     bool m_enabled;
107 
108     FractalType m_type;
109     Position m_position;
110     GeneratorSettings m_settings;
111 
112     QSize m_resolution;
113     QSize m_bufferSize;
114 
115     GeneratorCore::Functor* m_functor;
116 #if defined( HAVE_SSE2 )
117     GeneratorCore::FunctorSSE2* m_functorSSE2;
118 #endif
119 
120     double* m_buffer;
121 
122     QList<QRect> m_regions;
123 
124     int m_activeJobs;
125     QWaitCondition m_allJobsDone;
126 
127     bool m_pending;
128 
129     FractalType m_pendingType;
130     Position m_pendingPosition;
131     GeneratorSettings m_pendingSettings;
132 
133     QSize m_pendingResolution;
134     QSize m_pendingBufferSize;
135 
136     UpdateStatus m_update;
137     QList<QRect> m_validRegions;
138 
139     double* m_previewBuffer;
140 };
141 
142 #endif
143