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