Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/x11/standalone/glxbackend.cpp
Show First 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | 108 | GlxBackend::GlxBackend(Display *display) | |||
---|---|---|---|---|---|
110 | , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) | 110 | , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) | ||
111 | , window(None) | 111 | , window(None) | ||
112 | , fbconfig(nullptr) | 112 | , fbconfig(nullptr) | ||
113 | , glxWindow(None) | 113 | , glxWindow(None) | ||
114 | , ctx(nullptr) | 114 | , ctx(nullptr) | ||
115 | , m_bufferAge(0) | 115 | , m_bufferAge(0) | ||
116 | , m_x11Display(display) | 116 | , m_x11Display(display) | ||
117 | { | 117 | { | ||
118 | // Ensures calls to glXSwapBuffers will always block until the next | | |||
119 | // retrace when using the proprietary NVIDIA driver. This must be | | |||
120 | // set before libGL.so is loaded. | | |||
121 | setenv("__GL_MaxFramesAllowed", "1", true); | | |||
122 | | ||||
123 | // Force initialization of GLX integration in the Qt's xcb backend | 118 | // Force initialization of GLX integration in the Qt's xcb backend | ||
124 | // to make it call XESetWireToEvent callbacks, which is required | 119 | // to make it call XESetWireToEvent callbacks, which is required | ||
125 | // by Mesa when using DRI2. | 120 | // by Mesa when using DRI2. | ||
126 | QOpenGLContext::supportsThreadedOpenGL(); | 121 | QOpenGLContext::supportsThreadedOpenGL(); | ||
127 | } | 122 | } | ||
128 | 123 | | |||
129 | GlxBackend::~GlxBackend() | 124 | GlxBackend::~GlxBackend() | ||
130 | { | 125 | { | ||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Line(s) | 168 | { | |||
224 | 219 | | |||
225 | if (hasExtension(QByteArrayLiteral("GLX_EXT_buffer_age"))) { | 220 | if (hasExtension(QByteArrayLiteral("GLX_EXT_buffer_age"))) { | ||
226 | const QByteArray useBufferAge = qgetenv("KWIN_USE_BUFFER_AGE"); | 221 | const QByteArray useBufferAge = qgetenv("KWIN_USE_BUFFER_AGE"); | ||
227 | 222 | | |||
228 | if (useBufferAge != "0") | 223 | if (useBufferAge != "0") | ||
229 | setSupportsBufferAge(true); | 224 | setSupportsBufferAge(true); | ||
230 | } | 225 | } | ||
231 | 226 | | |||
232 | setBlocksForRetrace(true); | | |||
233 | | ||||
234 | if (m_haveEXTSwapControl) { | 227 | if (m_haveEXTSwapControl) { | ||
235 | glXSwapIntervalEXT(display(), glxWindow, 1); | 228 | glXSwapIntervalEXT(display(), glxWindow, 1); | ||
236 | } else if (m_haveMESASwapControl) { | 229 | } else if (m_haveMESASwapControl) { | ||
237 | glXSwapIntervalMESA(1); | 230 | glXSwapIntervalMESA(1); | ||
238 | } else { | 231 | } else { | ||
239 | qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glSwapInterval is not supported"; | 232 | qCWarning(KWIN_X11STANDALONE) << "NO VSYNC! glSwapInterval is not supported"; | ||
240 | } | 233 | } | ||
241 | 234 | | |||
▲ Show 20 Lines • Show All 479 Lines • ▼ Show 20 Line(s) | |||||
721 | { | 714 | { | ||
722 | return new GlxTexture(texture, this); | 715 | return new GlxTexture(texture, this); | ||
723 | } | 716 | } | ||
724 | 717 | | |||
725 | QRegion GlxBackend::prepareRenderingFrame() | 718 | QRegion GlxBackend::prepareRenderingFrame() | ||
726 | { | 719 | { | ||
727 | QRegion repaint; | 720 | QRegion repaint; | ||
728 | 721 | | |||
729 | present(); | | |||
730 | | ||||
731 | if (supportsBufferAge()) | 722 | if (supportsBufferAge()) | ||
732 | repaint = accumulatedDamageHistory(m_bufferAge); | 723 | repaint = accumulatedDamageHistory(m_bufferAge); | ||
733 | 724 | | |||
734 | startRenderTimer(); | 725 | startRenderTimer(); | ||
735 | glXWaitX(); | | |||
736 | 726 | | |||
737 | return repaint; | 727 | return repaint; | ||
738 | } | 728 | } | ||
739 | 729 | | |||
740 | void GlxBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) | 730 | void GlxBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) | ||
741 | { | 731 | { | ||
742 | if (damagedRegion.isEmpty()) { | 732 | if (damagedRegion.isEmpty()) { | ||
743 | setLastDamage(QRegion()); | 733 | setLastDamage(QRegion()); | ||
744 | 734 | | |||
745 | // If the damaged region of a window is fully occluded, the only | 735 | // If the damaged region of a window is fully occluded, the only | ||
746 | // rendering done, if any, will have been to repair a reused back | 736 | // rendering done, if any, will have been to repair a reused back | ||
747 | // buffer, making it identical to the front buffer. | 737 | // buffer, making it identical to the front buffer. | ||
748 | // | 738 | // | ||
749 | // In this case we won't post the back buffer. Instead we'll just | 739 | // In this case we won't post the back buffer. Instead we'll just | ||
750 | // set the buffer age to 1, so the repaired regions won't be | 740 | // set the buffer age to 1, so the repaired regions won't be | ||
751 | // rendered again in the next frame. | 741 | // rendered again in the next frame. | ||
752 | if (!renderedRegion.isEmpty()) | 742 | if (!renderedRegion.isEmpty()) | ||
753 | glFlush(); | 743 | glFlush(); | ||
754 | 744 | | |||
755 | m_bufferAge = 1; | 745 | m_bufferAge = 1; | ||
756 | return; | 746 | return; | ||
757 | } | 747 | } | ||
758 | 748 | | |||
759 | setLastDamage(renderedRegion); | 749 | setLastDamage(renderedRegion); | ||
760 | | ||||
761 | if (!blocksForRetrace()) { | | |||
762 | // This also sets lastDamage to empty which prevents the frame from | | |||
763 | // being posted again when prepareRenderingFrame() is called. | | |||
764 | present(); | 750 | present(); | ||
765 | } else { | | |||
766 | // Make sure that the GPU begins processing the command stream | | |||
767 | // now and not the next time prepareRenderingFrame() is called. | | |||
768 | glFlush(); | | |||
769 | } | | |||
770 | 751 | | |||
771 | if (overlayWindow()->window()) // show the window only after the first pass, | 752 | if (overlayWindow()->window()) // show the window only after the first pass, | ||
772 | overlayWindow()->show(); // since that pass may take long | 753 | overlayWindow()->show(); // since that pass may take long | ||
773 | 754 | | |||
774 | // Save the damaged region to history | 755 | // Save the damaged region to history | ||
775 | if (supportsBufferAge()) | 756 | if (supportsBufferAge()) | ||
776 | addToDamageHistory(damagedRegion); | 757 | addToDamageHistory(damagedRegion); | ||
777 | } | 758 | } | ||
▲ Show 20 Lines • Show All 114 Lines • Show Last 20 Lines |