1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org> |
6 | Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org> |
7 | |
8 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2 of the License, or |
11 | (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | *********************************************************************/ |
21 | |
22 | #ifndef KWIN_SCENE_OPENGL_H |
23 | #define KWIN_SCENE_OPENGL_H |
24 | |
25 | #include "scene.h" |
26 | #include "shadow.h" |
27 | |
28 | #include "kwinglutils.h" |
29 | #include "kwingltexture_p.h" |
30 | |
31 | namespace KWin |
32 | { |
33 | class ColorCorrection; |
34 | class LanczosFilter; |
35 | class OpenGLBackend; |
36 | class OpenGLPaintRedirector; |
37 | |
38 | class SceneOpenGL |
39 | : public Scene |
40 | { |
41 | Q_OBJECT |
42 | public: |
43 | class EffectFrame; |
44 | class Texture; |
45 | class TexturePrivate; |
46 | class Window; |
47 | virtual ~SceneOpenGL(); |
48 | virtual bool initFailed() const; |
49 | virtual bool hasPendingFlush() const; |
50 | virtual qint64 paint(QRegion damage, ToplevelList windows); |
51 | virtual void windowAdded(Toplevel*); |
52 | virtual void windowDeleted(Deleted*); |
53 | virtual void screenGeometryChanged(const QSize &size); |
54 | virtual OverlayWindow *overlayWindow(); |
55 | virtual bool blocksForRetrace() const; |
56 | virtual bool syncsToVBlank() const; |
57 | |
58 | void idle(); |
59 | |
60 | bool debug() const { return m_debug; } |
61 | |
62 | /** |
63 | * @brief Factory method to create a backend specific texture. |
64 | * |
65 | * @return :SceneOpenGL::Texture* |
66 | **/ |
67 | Texture *createTexture(); |
68 | Texture *createTexture(const QPixmap& pix, GLenum target = GL_TEXTURE_2D); |
69 | |
70 | #ifndef KWIN_HAVE_OPENGLES |
71 | /** |
72 | * Copy a region of pixels from the current read to the current draw buffer |
73 | */ |
74 | static void copyPixels(const QRegion ®ion); |
75 | #endif |
76 | |
77 | static SceneOpenGL *createScene(); |
78 | |
79 | protected: |
80 | SceneOpenGL(Workspace* ws, OpenGLBackend *backend); |
81 | virtual void paintBackground(QRegion region); |
82 | virtual void extendPaintRegion(QRegion ®ion, bool opaqueFullscreen); |
83 | QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const; |
84 | virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data); |
85 | |
86 | void handleGraphicsReset(GLenum status); |
87 | |
88 | virtual void doPaintBackground(const QVector<float> &vertices) = 0; |
89 | virtual SceneOpenGL::Window *createWindow(Toplevel *t) = 0; |
90 | |
91 | Q_SIGNALS: |
92 | void resetCompositing(); |
93 | |
94 | public Q_SLOTS: |
95 | virtual void windowOpacityChanged(KWin::Toplevel* c); |
96 | virtual void windowGeometryShapeChanged(KWin::Toplevel* c); |
97 | virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted); |
98 | protected: |
99 | bool init_ok; |
100 | private: |
101 | bool viewportLimitsMatched(const QSize &size) const; |
102 | private: |
103 | QHash< Toplevel*, Window* > windows; |
104 | bool m_debug; |
105 | OpenGLBackend *m_backend; |
106 | }; |
107 | |
108 | class SceneOpenGL2 : public SceneOpenGL |
109 | { |
110 | Q_OBJECT |
111 | public: |
112 | explicit SceneOpenGL2(OpenGLBackend *backend); |
113 | virtual ~SceneOpenGL2(); |
114 | virtual CompositingType compositingType() const { |
115 | return OpenGL2Compositing; |
116 | } |
117 | |
118 | static bool supported(OpenGLBackend *backend); |
119 | |
120 | ColorCorrection *colorCorrection(); |
121 | |
122 | protected: |
123 | virtual void paintGenericScreen(int mask, ScreenPaintData data); |
124 | virtual void doPaintBackground(const QVector< float >& vertices); |
125 | virtual SceneOpenGL::Window *createWindow(Toplevel *t); |
126 | virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); |
127 | virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data); |
128 | |
129 | private Q_SLOTS: |
130 | void slotColorCorrectedChanged(bool recreateShaders = true); |
131 | void resetLanczosFilter(); |
132 | |
133 | private: |
134 | void performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); |
135 | |
136 | private: |
137 | LanczosFilter *m_lanczosFilter; |
138 | QScopedPointer<ColorCorrection> m_colorCorrection; |
139 | GLuint vao; |
140 | }; |
141 | |
142 | #ifdef KWIN_HAVE_OPENGL_1 |
143 | class SceneOpenGL1 : public SceneOpenGL |
144 | { |
145 | public: |
146 | explicit SceneOpenGL1(OpenGLBackend *backend); |
147 | virtual ~SceneOpenGL1(); |
148 | virtual void screenGeometryChanged(const QSize &size); |
149 | virtual qint64 paint(QRegion damage, ToplevelList windows); |
150 | virtual CompositingType compositingType() const { |
151 | return OpenGL1Compositing; |
152 | } |
153 | |
154 | static bool supported(OpenGLBackend *backend); |
155 | |
156 | protected: |
157 | virtual void paintGenericScreen(int mask, ScreenPaintData data); |
158 | virtual void doPaintBackground(const QVector< float >& vertices); |
159 | virtual SceneOpenGL::Window *createWindow(Toplevel *t); |
160 | |
161 | private: |
162 | void setupModelViewProjectionMatrix(); |
163 | bool m_resetModelViewProjectionMatrix; |
164 | }; |
165 | #endif |
166 | |
167 | class SceneOpenGL::TexturePrivate |
168 | : public GLTexturePrivate |
169 | { |
170 | public: |
171 | virtual ~TexturePrivate(); |
172 | |
173 | virtual void findTarget() = 0; |
174 | virtual bool loadTexture(const Pixmap& pix, const QSize& size, int depth) = 0; |
175 | virtual OpenGLBackend *backend() = 0; |
176 | virtual bool update(const QRegion &damage); |
177 | |
178 | protected: |
179 | TexturePrivate(); |
180 | |
181 | private: |
182 | Q_DISABLE_COPY(TexturePrivate) |
183 | }; |
184 | |
185 | class SceneOpenGL::Texture |
186 | : public GLTexture |
187 | { |
188 | public: |
189 | Texture(OpenGLBackend *backend); |
190 | Texture(OpenGLBackend *backend, const QPixmap& pix, GLenum target = GL_TEXTURE_2D); |
191 | virtual ~Texture(); |
192 | |
193 | Texture & operator = (const Texture& tex); |
194 | |
195 | using GLTexture::load; |
196 | virtual bool load(const QImage& image, GLenum target = GL_TEXTURE_2D); |
197 | virtual bool load(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D); |
198 | virtual void discard(); |
199 | bool update(const QRegion &damage); |
200 | |
201 | protected: |
202 | void findTarget(); |
203 | virtual bool load(const Pixmap& pix, const QSize& size, int depth, |
204 | QRegion region); |
205 | virtual bool load(const Pixmap& pix, const QSize& size, int depth); |
206 | |
207 | Texture(TexturePrivate& dd); |
208 | |
209 | private: |
210 | Q_DECLARE_PRIVATE(Texture) |
211 | |
212 | friend class OpenGLWindowPixmap; |
213 | }; |
214 | |
215 | class SceneOpenGL::Window |
216 | : public Scene::Window |
217 | { |
218 | public: |
219 | virtual ~Window(); |
220 | bool beginRenderWindow(int mask, const QRegion ®ion, WindowPaintData &data); |
221 | virtual void performPaint(int mask, QRegion region, WindowPaintData data) = 0; |
222 | void endRenderWindow(); |
223 | bool bindTexture(); |
224 | void setScene(SceneOpenGL *scene) { |
225 | m_scene = scene; |
226 | } |
227 | |
228 | protected: |
229 | virtual WindowPixmap* createWindowPixmap(); |
230 | Window(Toplevel* c); |
231 | enum TextureType { |
232 | Content, |
233 | DecorationLeftRight, |
234 | DecorationTopBottom, |
235 | Shadow |
236 | }; |
237 | |
238 | QMatrix4x4 transformation(int mask, const WindowPaintData &data) const; |
239 | bool getDecorationTextures(GLTexture **textures) const; |
240 | void paintDecoration(GLTexture *texture, TextureType type, const QRegion ®ion, const WindowPaintData &data, const WindowQuadList &quads); |
241 | void paintShadow(const QRegion ®ion, const WindowPaintData &data); |
242 | void renderQuads(int, const QRegion& region, const WindowQuadList& quads, GLTexture* tex, bool normalized); |
243 | /** |
244 | * @brief Prepare the OpenGL rendering state before the texture with @p type will be rendered. |
245 | * |
246 | * @param type The type of the Texture which will be rendered |
247 | * @param opacity The opacity value to use for this rendering |
248 | * @param brightness The brightness value to use for this rendering |
249 | * @param saturation The saturation value to use for this rendering |
250 | * @param screen The index of the screen to use for this rendering |
251 | **/ |
252 | virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen) = 0; |
253 | /** |
254 | * @brief Restores the OpenGL rendering state after the texture with @p type has been rendered. |
255 | * |
256 | * @param type The type of the Texture which has been rendered |
257 | * @param opacity The opacity value used for the rendering |
258 | * @param brightness The brightness value used for this rendering |
259 | * @param saturation The saturation value used for this rendering |
260 | * @param screen The index of the screen to use for this rendering |
261 | **/ |
262 | virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation) = 0; |
263 | |
264 | /** |
265 | * @brief Returns the texture for the given @p type. |
266 | * |
267 | * @param type The Texture Type for which the texture should be retrieved |
268 | * @return :GLTexture* the texture |
269 | **/ |
270 | GLTexture *textureForType(TextureType type); |
271 | |
272 | void paintDecorations(const WindowPaintData &data, const QRegion ®ion); |
273 | |
274 | protected: |
275 | SceneOpenGL *m_scene; |
276 | bool m_hardwareClipping; |
277 | |
278 | private: |
279 | OpenGLPaintRedirector *paintRedirector() const; |
280 | }; |
281 | |
282 | class SceneOpenGL2Window : public SceneOpenGL::Window |
283 | { |
284 | public: |
285 | enum Leaf { ShadowLeaf = 0, LeftRightLeaf, TopBottomLeaf, ContentLeaf, PreviousContentLeaf, LeafCount }; |
286 | |
287 | struct LeafNode |
288 | { |
289 | LeafNode() |
290 | : texture(0), |
291 | firstVertex(0), |
292 | vertexCount(0), |
293 | opacity(1.0), |
294 | hasAlpha(false), |
295 | coordinateType(UnnormalizedCoordinates) |
296 | { |
297 | } |
298 | |
299 | GLTexture *texture; |
300 | int firstVertex; |
301 | int vertexCount; |
302 | float opacity; |
303 | bool hasAlpha; |
304 | TextureCoordinateType coordinateType; |
305 | }; |
306 | |
307 | explicit SceneOpenGL2Window(Toplevel *c); |
308 | virtual ~SceneOpenGL2Window(); |
309 | |
310 | protected: |
311 | QVector4D modulate(float opacity, float brightness) const; |
312 | void setBlendEnabled(bool enabled); |
313 | void setupLeafNodes(LeafNode *nodes, const WindowQuadList *quads, const WindowPaintData &data); |
314 | virtual void performPaint(int mask, QRegion region, WindowPaintData data); |
315 | virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen); |
316 | virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation); |
317 | |
318 | private: |
319 | /** |
320 | * Whether prepareStates enabled blending and restore states should disable again. |
321 | **/ |
322 | bool m_blendingEnabled; |
323 | }; |
324 | |
325 | #ifdef KWIN_HAVE_OPENGL_1 |
326 | class SceneOpenGL1Window : public SceneOpenGL::Window |
327 | { |
328 | public: |
329 | explicit SceneOpenGL1Window(Toplevel *c); |
330 | virtual ~SceneOpenGL1Window(); |
331 | |
332 | protected: |
333 | virtual void performPaint(int mask, QRegion region, WindowPaintData data); |
334 | virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen); |
335 | virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation); |
336 | private: |
337 | void paintContent(SceneOpenGL::Texture* content, const QRegion& region, int mask, qreal opacity, |
338 | const WindowPaintData& data, const WindowQuadList &contentQuads, bool normalized); |
339 | }; |
340 | #endif |
341 | |
342 | class OpenGLWindowPixmap : public WindowPixmap |
343 | { |
344 | public: |
345 | explicit OpenGLWindowPixmap(Scene::Window *window, SceneOpenGL *scene); |
346 | virtual ~OpenGLWindowPixmap(); |
347 | SceneOpenGL::Texture *texture() const; |
348 | bool bind(); |
349 | private: |
350 | SceneOpenGL *m_scene; |
351 | QScopedPointer<SceneOpenGL::Texture> m_texture; |
352 | }; |
353 | |
354 | class SceneOpenGL::EffectFrame |
355 | : public Scene::EffectFrame |
356 | { |
357 | public: |
358 | EffectFrame(EffectFrameImpl* frame, SceneOpenGL *scene); |
359 | virtual ~EffectFrame(); |
360 | |
361 | virtual void free(); |
362 | virtual void freeIconFrame(); |
363 | virtual void freeTextFrame(); |
364 | virtual void freeSelection(); |
365 | |
366 | virtual void render(QRegion region, double opacity, double frameOpacity); |
367 | |
368 | virtual void crossFadeIcon(); |
369 | virtual void crossFadeText(); |
370 | |
371 | static void cleanup(); |
372 | |
373 | private: |
374 | void updateTexture(); |
375 | void updateTextTexture(); |
376 | |
377 | Texture* m_texture; |
378 | Texture* m_textTexture; |
379 | Texture* m_oldTextTexture; |
380 | QPixmap* m_textPixmap; // need to keep the pixmap around to workaround some driver problems |
381 | Texture* m_iconTexture; |
382 | Texture* m_oldIconTexture; |
383 | Texture* m_selectionTexture; |
384 | GLVertexBuffer* m_unstyledVBO; |
385 | SceneOpenGL *m_scene; |
386 | |
387 | static GLTexture* m_unstyledTexture; |
388 | static QPixmap* m_unstyledPixmap; // need to keep the pixmap around to workaround some driver problems |
389 | static void updateUnstyledTexture(); // Update OpenGL unstyled frame texture |
390 | }; |
391 | |
392 | /** |
393 | * @short OpenGL implementation of Shadow. |
394 | * |
395 | * This class extends Shadow by the Elements required for OpenGL rendering. |
396 | * @author Martin Gräßlin <mgraesslin@kde.org> |
397 | **/ |
398 | class SceneOpenGLShadow |
399 | : public Shadow |
400 | { |
401 | public: |
402 | explicit SceneOpenGLShadow(Toplevel *toplevel); |
403 | virtual ~SceneOpenGLShadow(); |
404 | |
405 | GLTexture *shadowTexture() { |
406 | return m_texture; |
407 | } |
408 | protected: |
409 | virtual void buildQuads(); |
410 | virtual bool prepareBackend(); |
411 | private: |
412 | GLTexture *m_texture; |
413 | }; |
414 | |
415 | /** |
416 | * @short Profiler to detect whether we have triple buffering |
417 | * The strategy is to start setBlocksForRetrace(false) but assume blocking and have the system prove that assumption wrong |
418 | **/ |
419 | class SwapProfiler |
420 | { |
421 | public: |
422 | SwapProfiler(); |
423 | void init(); |
424 | void begin(); |
425 | /** |
426 | * @return char being 'd' for double, 't' for triple (or more - but non-blocking) buffering and |
427 | * 0 (NOT '0') otherwise, so you can act on "if (char result = SwapProfiler::end()) { fooBar(); } |
428 | **/ |
429 | char end(); |
430 | private: |
431 | QElapsedTimer m_timer; |
432 | qint64 m_time; |
433 | int m_counter; |
434 | }; |
435 | |
436 | /** |
437 | * @brief The OpenGLBackend creates and holds the OpenGL context and is responsible for Texture from Pixmap. |
438 | * |
439 | * The OpenGLBackend is an abstract base class used by the SceneOpenGL to abstract away the differences |
440 | * between various OpenGL windowing systems such as GLX and EGL. |
441 | * |
442 | * A concrete implementation has to create and release the OpenGL context in a way so that the |
443 | * SceneOpenGL does not have to care about it. |
444 | * |
445 | * In addition a major task for this class is to generate the SceneOpenGL::TexturePrivate which is |
446 | * able to perform the texture from pixmap operation in the given backend. |
447 | * |
448 | * @author Martin Gräßlin <mgraesslin@kde.org> |
449 | **/ |
450 | class OpenGLBackend |
451 | { |
452 | public: |
453 | OpenGLBackend(); |
454 | virtual ~OpenGLBackend(); |
455 | /** |
456 | * @return Time passes since start of rendering current frame. |
457 | * @see startRenderTimer |
458 | **/ |
459 | qint64 renderTime() { |
460 | return m_renderTimer.nsecsElapsed(); |
461 | } |
462 | virtual void screenGeometryChanged(const QSize &size) = 0; |
463 | virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) = 0; |
464 | |
465 | /** |
466 | * @brief Backend specific code to prepare the rendering of a frame including flushing the |
467 | * previously rendered frame to the screen if the backend works this way. |
468 | * |
469 | * @return A region that if not empty will be repainted in addition to the damaged region |
470 | **/ |
471 | virtual QRegion prepareRenderingFrame() = 0; |
472 | |
473 | /** |
474 | * @brief Backend specific code to handle the end of rendering a frame. |
475 | * |
476 | * @param renderedRegion The possibly larger region that has been rendered |
477 | * @param damagedRegion The damaged region that should be posted |
478 | **/ |
479 | virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) = 0; |
480 | |
481 | /** |
482 | * @brief Compositor is going into idle mode, flushes any pending paints. |
483 | **/ |
484 | void idle(); |
485 | |
486 | /** |
487 | * @return bool Whether the scene needs to flush a frame. |
488 | **/ |
489 | bool hasPendingFlush() const { |
490 | return !m_lastDamage.isEmpty(); |
491 | } |
492 | |
493 | /** |
494 | * @brief Returns the OverlayWindow used by the backend. |
495 | * |
496 | * A backend does not have to use an OverlayWindow, this is mostly for the X world. |
497 | * In case the backend does not use an OverlayWindow it is allowed to return @c null. |
498 | * It's the task of the caller to check whether it is @c null. |
499 | * |
500 | * @return :OverlayWindow* |
501 | **/ |
502 | OverlayWindow *overlayWindow() { |
503 | return m_overlayWindow; |
504 | } |
505 | /** |
506 | * @brief Whether the creation of the Backend failed. |
507 | * |
508 | * The SceneOpenGL should test whether the Backend got constructed correctly. If this method |
509 | * returns @c true, the SceneOpenGL should not try to start the rendering. |
510 | * |
511 | * @return bool @c true if the creation of the Backend failed, @c false otherwise. |
512 | **/ |
513 | bool isFailed() const { |
514 | return m_failed; |
515 | } |
516 | /** |
517 | * @brief Whether the Backend provides VSync. |
518 | * |
519 | * Currently only the GLX backend can provide VSync. |
520 | * |
521 | * @return bool @c true if VSync support is available, @c false otherwise |
522 | **/ |
523 | bool syncsToVBlank() const { |
524 | return m_syncsToVBlank; |
525 | } |
526 | /** |
527 | * @brief Whether VSync blocks execution until the screen is in the retrace |
528 | * |
529 | * Case for waitVideoSync and non triple buffering buffer swaps |
530 | * |
531 | **/ |
532 | bool blocksForRetrace() const { |
533 | return m_blocksForRetrace; |
534 | } |
535 | /** |
536 | * @brief Whether the backend uses direct rendering. |
537 | * |
538 | * Some OpenGLScene modes require direct rendering. E.g. the OpenGL 2 should not be used |
539 | * if direct rendering is not supported by the Scene. |
540 | * |
541 | * @return bool @c true if the GL context is direct, @c false if indirect |
542 | **/ |
543 | bool isDirectRendering() const { |
544 | return m_directRendering; |
545 | } |
546 | |
547 | bool supportsBufferAge() const { |
548 | return m_haveBufferAge; |
549 | } |
550 | |
551 | /** |
552 | * Returns the damage that has accumulated since a buffer of the given age was presented. |
553 | */ |
554 | QRegion accumulatedDamageHistory(int bufferAge) const; |
555 | |
556 | /** |
557 | * Saves the given region to damage history. |
558 | */ |
559 | void addToDamageHistory(const QRegion ®ion); |
560 | |
561 | protected: |
562 | /** |
563 | * @brief Backend specific flushing of frame to screen. |
564 | **/ |
565 | virtual void present() = 0; |
566 | /** |
567 | * @brief Sets the backend initialization to failed. |
568 | * |
569 | * This method should be called by the concrete subclass in case the initialization failed. |
570 | * The given @p reason is logged as a warning. |
571 | * |
572 | * @param reason The reason why the initialization failed. |
573 | **/ |
574 | void setFailed(const QString &reason); |
575 | /** |
576 | * @brief Sets whether the backend provides VSync. |
577 | * |
578 | * Should be called by the concrete subclass once it is determined whether VSync is supported. |
579 | * If the subclass does not call this method, the backend defaults to @c false. |
580 | * @param enabled @c true if VSync support available, @c false otherwise. |
581 | **/ |
582 | void setSyncsToVBlank(bool enabled) { |
583 | m_syncsToVBlank = enabled; |
584 | } |
585 | /** |
586 | * @brief Sets whether the VSync iplementation blocks |
587 | * |
588 | * Should be called by the concrete subclass once it is determined how VSync works. |
589 | * If the subclass does not call this method, the backend defaults to @c false. |
590 | * @param enabled @c true if VSync blocks, @c false otherwise. |
591 | **/ |
592 | void setBlocksForRetrace(bool enabled) { |
593 | m_blocksForRetrace = enabled; |
594 | } |
595 | /** |
596 | * @brief Sets whether the OpenGL context is direct. |
597 | * |
598 | * Should be called by the concrete subclass once it is determined whether the OpenGL context is |
599 | * direct or indirect. |
600 | * If the subclass does not call this method, the backend defaults to @c false. |
601 | * |
602 | * @param direct @c true if the OpenGL context is direct, @c false if indirect |
603 | **/ |
604 | void setIsDirectRendering(bool direct) { |
605 | m_directRendering = direct; |
606 | } |
607 | |
608 | void setSupportsBufferAge(bool value) { |
609 | m_haveBufferAge = value; |
610 | } |
611 | |
612 | /** |
613 | * @return const QRegion& Damage of previously rendered frame |
614 | **/ |
615 | const QRegion &lastDamage() const { |
616 | return m_lastDamage; |
617 | } |
618 | void setLastDamage(const QRegion &damage) { |
619 | m_lastDamage = damage; |
620 | } |
621 | /** |
622 | * @brief Starts the timer for how long it takes to render the frame. |
623 | * |
624 | * @see renderTime |
625 | **/ |
626 | void startRenderTimer() { |
627 | m_renderTimer.start(); |
628 | } |
629 | |
630 | SwapProfiler m_swapProfiler; |
631 | |
632 | private: |
633 | /** |
634 | * @brief The OverlayWindow used by this Backend. |
635 | **/ |
636 | OverlayWindow *m_overlayWindow; |
637 | /** |
638 | * @brief Whether VSync is available and used, defaults to @c false. |
639 | **/ |
640 | bool m_syncsToVBlank; |
641 | /** |
642 | * @brief Whether present() will block execution until the next vertical retrace @c false. |
643 | **/ |
644 | bool m_blocksForRetrace; |
645 | /** |
646 | * @brief Whether direct rendering is used, defaults to @c false. |
647 | **/ |
648 | bool m_directRendering; |
649 | /** |
650 | * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age. |
651 | */ |
652 | bool m_haveBufferAge; |
653 | /** |
654 | * @brief Whether the initialization failed, of course default to @c false. |
655 | **/ |
656 | bool m_failed; |
657 | /** |
658 | * @brief Damaged region of previously rendered frame. |
659 | **/ |
660 | QRegion m_lastDamage; |
661 | /** |
662 | * @brief The damage history for the past 10 frames. |
663 | */ |
664 | QList<QRegion> m_damageHistory; |
665 | /** |
666 | * @brief Timer to measure how long a frame renders. |
667 | **/ |
668 | QElapsedTimer m_renderTimer; |
669 | }; |
670 | |
671 | inline bool SceneOpenGL::hasPendingFlush() const |
672 | { |
673 | return m_backend->hasPendingFlush(); |
674 | } |
675 | |
676 | inline SceneOpenGL::Texture* OpenGLWindowPixmap::texture() const |
677 | { |
678 | return m_texture.data(); |
679 | } |
680 | |
681 | } // namespace |
682 | |
683 | #endif |
684 | |