Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 342044 Details for
Bug 461684
kde-base/kwin: backport patch to remove tearing on Intel systems
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
The actual patch - tearing-fix.patch
tearing-fix.patch (text/plain), 23.55 KB, created by
Mike Lothian
on 2013-03-14 19:00:14 UTC
(
hide
)
Description:
The actual patch - tearing-fix.patch
Filename:
MIME Type:
Creator:
Mike Lothian
Created:
2013-03-14 19:00:14 UTC
Size:
23.55 KB
patch
obsolete
>commit 6072b4feb8c90024aa24b2e9cb8a21ab2140412c >Author: Thomas Lübking <thomas.luebking@gmail.com> >Date: Mon Feb 18 23:17:46 2013 +0100 > > support a permanent glSwapBuffer > > either by > - forcing fullrepaints unconditionally > - turning a repaint to a full one beyond a threshhold > - completing the the backbuffer from the frontbuffer after the paint > > BUG: 307965 > FIXED-IN: 4.10 > REVIEW: 107198 > >diff --git a/kwin/composite.cpp b/kwin/composite.cpp >index 5702ec0..1e77b5c 100644 >--- a/kwin/composite.cpp >+++ b/kwin/composite.cpp >@@ -501,8 +501,6 @@ void Compositor::timerEvent(QTimerEvent *te) > QObject::timerEvent(te); > } > >-static int s_pendingFlushes = 0; >- > void Compositor::performCompositing() > { > if (!isOverlayWindowVisible()) >@@ -543,15 +541,7 @@ void Compositor::performCompositing() > win->getDamageRegionReply(); > } > >- bool pending = !repaints_region.isEmpty() || windowRepaintsPending(); >- if (pending) >- s_pendingFlushes = 3; >- else if (m_scene->hasPendingFlush()) >- --s_pendingFlushes; >- else >- s_pendingFlushes = 0; >- if (s_pendingFlushes < 1) { >- s_pendingFlushes = 0; >+ if (repaints_region.isEmpty() && !windowRepaintsPending()) { > m_scene->idle(); > // Note: It would seem here we should undo suspended unredirect, but when scenes need > // it for some reason, e.g. transformations or translucency, the next pass that does not >diff --git a/kwin/eglonxbackend.cpp b/kwin/eglonxbackend.cpp >index dcb70d8..a34685a 100644 >--- a/kwin/eglonxbackend.cpp >+++ b/kwin/eglonxbackend.cpp >@@ -194,12 +194,13 @@ bool EglOnXBackend::initBufferConfigs() > > void EglOnXBackend::present() > { >- if (lastMask() & Scene::PAINT_SCREEN_REGION && surfaceHasSubPost && eglPostSubBufferNV) { >+ const bool swap = (options->glPreferBufferSwap() && options->glPreferBufferSwap() != Options::ExtendDamage) || >+ !(lastMask() & Scene::PAINT_SCREEN_REGION && surfaceHasSubPost && eglPostSubBufferNV); >+ if (swap) { >+ eglSwapBuffers(dpy, surface); >+ } else { > const QRect damageRect = lastDamage().boundingRect(); >- > eglPostSubBufferNV(dpy, surface, damageRect.left(), displayHeight() - damageRect.bottom() - 1, damageRect.width(), damageRect.height()); >- } else { >- eglSwapBuffers(dpy, surface); > } > > eglWaitGL(); >diff --git a/kwin/glxbackend.cpp b/kwin/glxbackend.cpp >index be11497..17d01e7 100644 >--- a/kwin/glxbackend.cpp >+++ b/kwin/glxbackend.cpp >@@ -115,7 +115,7 @@ void GlxBackend::init() > // However mesa/dri will return a range error (6) because deactivating the > // swapinterval (as of today) seems completely unsupported > setHasWaitSync(true); >- setSwapInterval(0); >+ setSwapInterval(1); > } > else > qWarning() << "NO VSYNC! glXWaitVideoSync(1,0,&uint) isn't 0 but" << glXWaitVideoSync(1, 0, &sync); >@@ -473,77 +473,80 @@ void GlxBackend::waitSync() > > void GlxBackend::present() > { >+ QRegion displayRegion(0, 0, displayWidth(), displayHeight()); >+ const bool fullRepaint = (lastDamage() == displayRegion); >+ > if (isDoubleBuffer()) { >- if (lastMask() & Scene::PAINT_SCREEN_REGION) { >- waitSync(); >- if (glXCopySubBuffer) { >- foreach (const QRect & r, lastDamage().rects()) { >- // convert to OpenGL coordinates >- int y = displayHeight() - r.y() - r.height(); >- glXCopySubBuffer(display(), glxbuffer, r.x(), y, r.width(), r.height()); >- } >- } else { >- // if a shader is bound or the texture unit is enabled, copy pixels results in a black screen >- // therefore unbind the shader and restore after copying the pixels >- GLint shader = 0; >- if (ShaderManager::instance()->isShaderBound()) { >- glGetIntegerv(GL_CURRENT_PROGRAM, &shader); >- glUseProgram(0); >- } >- bool reenableTexUnit = false; >- if (glIsEnabled(GL_TEXTURE_2D)) { >- glDisable(GL_TEXTURE_2D); >- reenableTexUnit = true; >- } >- // no idea why glScissor() is used, but Compiz has it and it doesn't seem to hurt >- glEnable(GL_SCISSOR_TEST); >- glDrawBuffer(GL_FRONT); >- int xpos = 0; >- int ypos = 0; >- foreach (const QRect & r, lastDamage().rects()) { >- // convert to OpenGL coordinates >- int y = displayHeight() - r.y() - r.height(); >- // Move raster position relatively using glBitmap() rather >- // than using glRasterPos2f() - the latter causes drawing >- // artefacts at the bottom screen edge with some gfx cards >-// glRasterPos2f( r.x(), r.y() + r.height()); >- glBitmap(0, 0, 0, 0, r.x() - xpos, y - ypos, NULL); >- xpos = r.x(); >- ypos = y; >- glScissor(r.x(), y, r.width(), r.height()); >- glCopyPixels(r.x(), y, r.width(), r.height(), GL_COLOR); >- } >- glBitmap(0, 0, 0, 0, -xpos, -ypos, NULL); // move position back to 0,0 >- glDrawBuffer(GL_BACK); >- glDisable(GL_SCISSOR_TEST); >- if (reenableTexUnit) { >- glEnable(GL_TEXTURE_2D); >- } >- // rebind previously bound shader >- if (ShaderManager::instance()->isShaderBound()) { >- glUseProgram(shader); >- } >- } >- } else { >+ >+ if (fullRepaint) { > if (haveSwapInterval) { >- setSwapInterval(options->isGlVSync() ? 1 : 0); > glXSwapBuffers(display(), glxbuffer); >- setSwapInterval(0); >- startRenderTimer(); // this is important so we don't assume to be loosing frames in the compositor timing calculation >+ startRenderTimer(); > } else { >- waitSync(); >+ waitSync(); // calls startRenderTimer(); > glXSwapBuffers(display(), glxbuffer); > } >+ } else if (glXCopySubBuffer) { >+ waitSync(); >+ foreach (const QRect & r, lastDamage().rects()) { >+ // convert to OpenGL coordinates >+ int y = displayHeight() - r.y() - r.height(); >+ glXCopySubBuffer(display(), glxbuffer, r.x(), y, r.width(), r.height()); >+ } >+ } else { // Copy Pixels >+ // if a shader is bound or the texture unit is enabled, copy pixels results in a black screen >+ // therefore unbind the shader and restore after copying the pixels >+ GLint shader = 0; >+ if (ShaderManager::instance()->isShaderBound()) { >+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader); >+ glUseProgram(0); >+ } >+ bool reenableTexUnit = false; >+ if (glIsEnabled(GL_TEXTURE_2D)) { >+ glDisable(GL_TEXTURE_2D); >+ reenableTexUnit = true; >+ } >+ // no idea why glScissor() is used, but Compiz has it and it doesn't seem to hurt >+ glEnable(GL_SCISSOR_TEST); >+ glDrawBuffer(GL_FRONT); >+ waitSync(); >+ int xpos = 0; >+ int ypos = 0; >+ foreach (const QRect & r, lastDamage().rects()) { >+ // convert to OpenGL coordinates >+ int y = displayHeight() - r.y() - r.height(); >+ // Move raster position relatively using glBitmap() rather >+ // than using glRasterPos2f() - the latter causes drawing >+ // artefacts at the bottom screen edge with some gfx cards >+// glRasterPos2f( r.x(), r.y() + r.height()); >+ glBitmap(0, 0, 0, 0, r.x() - xpos, y - ypos, NULL); >+ xpos = r.x(); >+ ypos = y; >+ glScissor(r.x(), y, r.width(), r.height()); >+ glCopyPixels(r.x(), y, r.width(), r.height(), GL_COLOR); >+ } >+ glBitmap(0, 0, 0, 0, -xpos, -ypos, NULL); // move position back to 0,0 >+ glDrawBuffer(GL_BACK); >+ glDisable(GL_SCISSOR_TEST); >+ if (reenableTexUnit) { >+ glEnable(GL_TEXTURE_2D); >+ } >+ // rebind previously bound shader >+ if (ShaderManager::instance()->isShaderBound()) { >+ glUseProgram(shader); >+ } > } >+ > glXWaitGL(); > } else { > glXWaitGL(); >- if (lastMask() & Scene::PAINT_SCREEN_REGION) >+ if (!fullRepaint) > foreach (const QRect & r, lastDamage().rects()) > XCopyArea(display(), buffer, rootWindow(), gcroot, r.x(), r.y(), r.width(), r.height(), r.x(), r.y()); > else > XCopyArea(display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0); > } >+ setLastDamage(QRegion()); > XFlush(display()); > } > >diff --git a/kwin/options.cpp b/kwin/options.cpp >index c0150a2..46a9396 100644 >--- a/kwin/options.cpp >+++ b/kwin/options.cpp >@@ -161,6 +161,7 @@ Options::Options(QObject *parent) > , m_glStrictBinding(Options::defaultGlStrictBinding()) > , m_glStrictBindingFollowsDriver(Options::defaultGlStrictBindingFollowsDriver()) > , m_glLegacy(Options::defaultGlLegacy()) >+ , m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap()) > , OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick()) > , CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1()) > , CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2()) >@@ -768,6 +769,24 @@ void Options::setGlLegacy(bool glLegacy) > emit glLegacyChanged(); > } > >+void Options::setGlPreferBufferSwap(char glPreferBufferSwap) >+{ >+ if (glPreferBufferSwap == 'a') { >+ // buffer cpying is very fast with the nvidia blob >+ // but due to restrictions in DRI2 *incredibly* slow for all MESA drivers >+ // see http://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5 >+ if (GLPlatform::instance()->driver() == Driver_NVidia) >+ glPreferBufferSwap = CopyFrontBuffer; >+ else >+ glPreferBufferSwap = ExtendDamage; >+ } >+ if (m_glPreferBufferSwap == (GlSwapStrategy)glPreferBufferSwap) { >+ return; >+ } >+ m_glPreferBufferSwap = (GlSwapStrategy)glPreferBufferSwap; >+ emit glPreferBufferSwapChanged(); >+} >+ > void Options::reparseConfiguration() > { > KGlobal::config()->reparseConfiguration(); >@@ -957,6 +976,16 @@ void Options::reloadCompositingSettings(bool force) > } > setGlLegacy(config.readEntry("GLLegacy", Options::defaultGlLegacy())); > >+ char c = 0; >+ if (isGlVSync()) { // buffer swap enforcement makes little sense without >+ const QString s = config.readEntry("GLPreferBufferSwap", QString(Options::defaultGlPreferBufferSwap())); >+ if (!s.isEmpty()) >+ c = s.at(0).toAscii(); >+ if (c != 'a' && c != 'c' && c != 'p' && c != 'e') >+ c = 0; >+ } >+ setGlPreferBufferSwap(c); >+ > setColorCorrected(config.readEntry("GLColorCorrection", Options::defaultColorCorrected())); > > m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false); >diff --git a/kwin/options.h b/kwin/options.h >index c76dbae..e816d4a 100644 >--- a/kwin/options.h >+++ b/kwin/options.h >@@ -42,6 +42,7 @@ class Options : public QObject, public KDecorationOptions > { > Q_OBJECT > Q_ENUMS(FocusPolicy) >+ Q_ENUMS(GlSwapStrategy) > Q_ENUMS(MouseCommand) > Q_ENUMS(MouseWheelCommand) > >@@ -187,6 +188,7 @@ class Options : public QObject, public KDecorationOptions > * Whether legacy OpenGL should be used or OpenGL (ES) 2 > **/ > Q_PROPERTY(bool glLegacy READ isGlLegacy WRITE setGlLegacy NOTIFY glLegacyChanged) >+ Q_PROPERTY(char glPreferBufferSwap READ glPreferBufferSwap WRITE setGlPreferBufferSwap NOTIFY glPreferBufferSwapChanged) > public: > > explicit Options(QObject *parent = NULL); >@@ -549,6 +551,11 @@ public: > return m_glLegacy; > } > >+ enum GlSwapStrategy { NoSwapEncourage = 0, CopyFrontBuffer = 'c', PaintFullScreen = 'p', ExtendDamage = 'e', AutoSwapStrategy = 'a' }; >+ GlSwapStrategy glPreferBufferSwap() const { >+ return m_glPreferBufferSwap; >+ } >+ > // setters > void setFocusPolicy(FocusPolicy focusPolicy); > void setNextFocusPrefersMouse(bool nextFocusPrefersMouse); >@@ -610,6 +617,7 @@ public: > void setGlStrictBinding(bool glStrictBinding); > void setGlStrictBindingFollowsDriver(bool glStrictBindingFollowsDriver); > void setGlLegacy(bool glLegacy); >+ void setGlPreferBufferSwap(char glPreferBufferSwap); > > // default values > static WindowOperation defaultOperationTitlebarDblClick() { >@@ -717,6 +725,9 @@ public: > static bool defaultGlLegacy() { > return false; > } >+ static GlSwapStrategy defaultGlPreferBufferSwap() { >+ return AutoSwapStrategy; >+ } > static int defaultAnimationSpeed() { > return 3; > } >@@ -797,6 +808,7 @@ Q_SIGNALS: > void glStrictBindingChanged(); > void glStrictBindingFollowsDriverChanged(); > void glLegacyChanged(); >+ void glPreferBufferSwapChanged(); > > public Q_SLOTS: > void setColorCorrected(bool colorCorrected = false); >@@ -847,6 +859,7 @@ private: > bool m_glStrictBinding; > bool m_glStrictBindingFollowsDriver; > bool m_glLegacy; >+ GlSwapStrategy m_glPreferBufferSwap; > > WindowOperation OpTitlebarDblClick; > >diff --git a/kwin/scene.cpp b/kwin/scene.cpp >index 685254b..939f000 100644 >--- a/kwin/scene.cpp >+++ b/kwin/scene.cpp >@@ -103,8 +103,9 @@ Scene::~Scene() > // returns mask and possibly modified region > void Scene::paintScreen(int* mask, QRegion* region) > { >- *mask = (*region == QRegion(0, 0, displayWidth(), displayHeight())) >- ? 0 : PAINT_SCREEN_REGION; >+ const QRegion displayRegion(0, 0, displayWidth(), displayHeight()); >+ *mask = (*region == displayRegion) ? 0 : PAINT_SCREEN_REGION; >+ > updateTimeDiff(); > // preparation step > static_cast<EffectsHandlerImpl*>(effects)->startPaint(); >@@ -124,10 +125,10 @@ void Scene::paintScreen(int* mask, QRegion* region) > *region = infiniteRegion(); > } else if (*mask & PAINT_SCREEN_REGION) { > // make sure not to go outside visible screen >- *region &= QRegion(0, 0, displayWidth(), displayHeight()); >+ *region &= displayRegion; > } else { > // whole screen, not transformed, force region to be full >- *region = QRegion(0, 0, displayWidth(), displayHeight()); >+ *region = displayRegion; > } > painted_region = *region; > if (*mask & PAINT_SCREEN_BACKGROUND_FIRST) { >@@ -141,7 +142,7 @@ void Scene::paintScreen(int* mask, QRegion* region) > effects->postPaintScreen(); > *region |= painted_region; > // make sure not to go outside of the screen area >- *region &= QRegion(0, 0, displayWidth(), displayHeight()); >+ *region &= displayRegion; > // make sure all clipping is restored > Q_ASSERT(!PaintClipper::clip()); > } >@@ -236,6 +237,7 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) > QList< QPair< Window*, Phase2Data > > phase2data; > > QRegion dirtyArea = region; >+ bool opaqueFullscreen(false); > for (int i = 0; // do prePaintWindow bottom to top > i < stacking_order.count(); > ++i) { >@@ -254,10 +256,12 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) > topw->resetRepaints(); > > // Clip out the decoration for opaque windows; the decoration is drawn in the second pass >+ opaqueFullscreen = false; // TODO: do we care about unmanged windows here (maybe input windows?) > if (w->isOpaque()) { > Client *c = NULL; > if (topw->isClient()) { > c = static_cast<Client*>(topw); >+ opaqueFullscreen = c->isFullScreen(); > } > // the window is fully opaque > if (c && c->decorationHasAlpha()) { >@@ -297,13 +301,24 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) > w->suspendUnredirect(data.mask & PAINT_WINDOW_TRANSLUCENT); > } > >- // This is the occlusion culling pass >+ const QRegion displayRegion(0, 0, displayWidth(), displayHeight()); >+ >+ bool fullRepaint(dirtyArea == displayRegion); // spare some expensive region operations >+ if (!fullRepaint) { >+ extendPaintRegion(dirtyArea, opaqueFullscreen); >+ fullRepaint = (dirtyArea == displayRegion); >+ } >+ > QRegion allclips, upperTranslucentDamage; >+ // This is the occlusion culling pass > for (int i = phase2data.count() - 1; i >= 0; --i) { > QPair< Window*, Phase2Data > *entry = &phase2data[i]; > Phase2Data *data = &entry->second; > >- data->region |= upperTranslucentDamage; >+ if (fullRepaint) >+ data->region = displayRegion; >+ else >+ data->region |= upperTranslucentDamage; > > // subtract the parts which will possibly been drawn as part of > // a higher opaque window >@@ -315,8 +330,9 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) > // clip away the opaque regions for all windows below this one > allclips |= data->clip; > // extend the translucent damage for windows below this by remaining (translucent) regions >- upperTranslucentDamage |= data->region - data->clip; >- } else { >+ if (!fullRepaint) >+ upperTranslucentDamage |= data->region - data->clip; >+ } else if (!fullRepaint) { > upperTranslucentDamage |= data->region; > } > } >@@ -338,7 +354,10 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region) > > paintWindow(data->window, data->mask, data->region, data->quads); > } >- painted_region |= paintedArea; >+ if (fullRepaint) >+ painted_region = displayRegion; >+ else >+ painted_region |= paintedArea; > } > > void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quads) >@@ -452,6 +471,12 @@ void Scene::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, Windo > w->sceneWindow()->performPaint(mask, region, data); > } > >+void Scene::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) >+{ >+ Q_UNUSED(region); >+ Q_UNUSED(opaqueFullscreen); >+} >+ > bool Scene::waitSyncAvailable() const > { > return false; >diff --git a/kwin/scene.h b/kwin/scene.h >index f06d150..5d49c40 100644 >--- a/kwin/scene.h >+++ b/kwin/scene.h >@@ -125,6 +125,9 @@ protected: > virtual void paintWindow(Window* w, int mask, QRegion region, WindowQuadList quads); > // called after all effects had their drawWindow() called > virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); >+ // let the scene decide whether it's better to paint more of the screen, eg. in order to allow a buffer swap >+ // the default is NOOP >+ virtual void extendPaintRegion(QRegion ®ion, bool opaqueFullscreen); > // compute time since the last repaint > void updateTimeDiff(); > // saved data for 2nd pass of optimized screen painting >diff --git a/kwin/scene_opengl.cpp b/kwin/scene_opengl.cpp >index 3185c9e..a9c5d84 100644 >--- a/kwin/scene_opengl.cpp >+++ b/kwin/scene_opengl.cpp >@@ -98,7 +98,8 @@ void OpenGLBackend::setFailed(const QString &reason) > > void OpenGLBackend::idle() > { >- present(); >+ if (hasPendingFlush()) >+ present(); > } > > /************************************************ >@@ -269,7 +270,52 @@ int SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) > #ifdef CHECK_GL_ERROR > checkGLError("Paint1"); > #endif >+ >+ const QRegion displayRegion(0, 0, displayWidth(), displayHeight()); > paintScreen(&mask, &damage); // call generic implementation >+#ifndef KWIN_HAVE_OPENGLES >+ // copy dirty parts from front to backbuffer >+ if (options->glPreferBufferSwap() == Options::CopyFrontBuffer && damage != displayRegion) { >+ GLint shader = 0; >+ if (ShaderManager::instance()->isShaderBound()) { >+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader); >+ glUseProgram(0); >+ } >+ bool reenableTexUnit = false; >+ if (glIsEnabled(GL_TEXTURE_2D)) { >+ glDisable(GL_TEXTURE_2D); >+ reenableTexUnit = true; >+ } >+ // no idea why glScissor() is used, but Compiz has it and it doesn't seem to hurt >+ glEnable(GL_SCISSOR_TEST); >+ glReadBuffer(GL_FRONT); >+ >+ int xpos = 0; >+ int ypos = 0; >+ const QRegion dirty = displayRegion - damage; >+ foreach (const QRect &r, dirty.rects()) { >+ // convert to OpenGL coordinates >+ int y = displayHeight() - r.y() - r.height(); >+ glBitmap(0, 0, 0, 0, r.x() - xpos, y - ypos, NULL); // not glRasterPos2f, see glxbackend.cpp >+ xpos = r.x(); >+ ypos = y; >+ glScissor(r.x(), y, r.width(), r.height()); >+ glCopyPixels(r.x(), y, r.width(), r.height(), GL_COLOR); >+ } >+ >+ glBitmap(0, 0, 0, 0, -xpos, -ypos, NULL); // move position back to 0,0 >+ glReadBuffer(GL_BACK); >+ glDisable(GL_SCISSOR_TEST); >+ if (reenableTexUnit) { >+ glEnable(GL_TEXTURE_2D); >+ } >+ // rebind previously bound shader >+ if (ShaderManager::instance()->isShaderBound()) { >+ glUseProgram(shader); >+ } >+ damage = displayRegion; >+ } >+#endif > #ifdef CHECK_GL_ERROR > checkGLError("Paint2"); > #endif >@@ -328,6 +374,35 @@ void SceneOpenGL::paintBackground(QRegion region) > doPaintBackground(verts); > } > >+void SceneOpenGL::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen) >+{ >+#ifndef KWIN_HAVE_OPENGLES >+ if (options->glPreferBufferSwap() == Options::ExtendDamage) { // only Extend "large" repaints >+ const QRegion displayRegion(0, 0, displayWidth(), displayHeight()); >+ uint damagedPixels = 0; >+ const uint fullRepaintLimit = (opaqueFullscreen?0.49f:0.748f)*displayWidth()*displayHeight(); >+ // 16:9 is 75% of 4:3 and 2.55:1 is 49.01% of 5:4 >+ // (5:4 is the most square format and 2.55:1 is Cinemascope55 - the widest ever shot >+ // movie aspect - two times ;-) It's a Fox format, though, so maybe we want to restrict >+ // to 2.20:1 - Panavision - which has actually been used for interesting movies ...) >+ // would be 57% of 5/4 >+ foreach (const QRect &r, region.rects()) { >+// damagedPixels += r.width() * r.height(); // combined window damage test >+ damagedPixels = r.width() * r.height(); // experimental single window damage testing >+ if (damagedPixels > fullRepaintLimit) { >+ region = displayRegion; >+ return; >+ } >+ } >+ } else if (options->glPreferBufferSwap() == Options::PaintFullScreen) { // forced full rePaint >+ region = QRegion(0, 0, displayWidth(), displayHeight()); >+ } >+#else >+ Q_UNUSED(region); >+ Q_UNUSED(opaqueFullscreen); >+#endif >+} >+ > void SceneOpenGL::windowAdded(Toplevel* c) > { > assert(!windows.contains(c)); >diff --git a/kwin/scene_opengl.h b/kwin/scene_opengl.h >index 7971c83..cd3dd86 100644 >--- a/kwin/scene_opengl.h >+++ b/kwin/scene_opengl.h >@@ -68,6 +68,7 @@ public: > protected: > SceneOpenGL(Workspace* ws, OpenGLBackend *backend); > virtual void paintBackground(QRegion region); >+ virtual void extendPaintRegion(QRegion ®ion, bool opaqueFullscreen); > QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const; > > virtual void doPaintBackground(const QVector<float> &vertices) = 0;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 461684
:
342042
| 342044