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 | |||||