[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    Re: Review Request: Move decoration pixmap handling from Client to PaintRedirector
From:       Fredrik_Höglund <fredrik () kde ! org>
Date:       2012-09-30 8:54:50
Message-ID: 20120930085450.31260.48388 () vidsolbach ! de
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


> On Sept. 28, 2012, 7:58 p.m., Thomas L=C3=BCbking wrote:
> > Afaics atm. the patch makes resizing windows *much* slower, activate (t=
hus repaint) and init move seems en par at best, but the lag on repainting =
is notable (as in 20fps ./. 2fps - w/ all compositors, bespin, oxygen and P=
lastik QML)
> > =

> > I doubt the problem is that repainting decos is somewhere in the hot co=
mpositing loop, but that it's in the compositing & event handling thread.
> =

> Fredrik H=C3=B6glund wrote:
>     Triggering the repaint from the compositing path ensures that the dec=
orations are never repainted more than once / frame.
>
> =

> Martin Gr=C3=A4=C3=9Flin wrote:
>     I had not observered a regression in resizing, but did not test that =
condition completely (mostly only tested whether it works). I'll look into =
that one.
>     =

>     Part of the idea behind this change was to move the painting out of t=
he compositor to be able to move the compositor into a second thread. So fa=
r that had been a major issue as it crashed when using any QWidget based de=
coration.
> =

> Thomas L=C3=BCbking wrote:
>     It has the biggest impact on windows not supporting the XSYNC protoco=
l (had an mplayer window open, used that to test. then tried on an xterm to=
 rule out the client - actually kwrite resizes at pretty much the same spee=
d)
> =

> Thomas L=C3=BCbking wrote:
>     Can possibly be resolved by tacting unsynced resizes, what also -in a=
 way- resolves the nasty judder it currently has on resizes (regardless of =
the WM, may be nvidia issue) but a trivial patch requires HAVE_XSYNC define=
d (or we remove it everywhere but for the very relevant getters end end up =
with the sync counter just being None if XSYNC is not available.
>
> =

> Fredrik H=C3=B6glund wrote:
>     The problem is that the event filter in PaintRedirector now schedules=
 repaints in response to Paint events as soon as kwin returns to the event =
loop. And that can happen many times before we actually update the screen. =
I also note that we recreate the decoration pixmaps on every resize event, =
and not just before we paint the decoration.
>     =

>     But if the decorations need to be updated it needs to happen exactly =
once before we paint the screen. If we do that in Window::performPaint(), o=
r in performCompositing() or somewhere else probably doesn't matter from a =
performance point of view, because it still takes the same amount of time t=
o do it. But doing it in Window::performPaint() does have the advantage tha=
t the update is deferred if the window isn't going to be painted because it=
 is obscured or on another desktop.
> =

> Martin Gr=C3=A4=C3=9Flin wrote:
>     I'm going to rever this part of the change. Thought it's a good idea =
based on the assumption that Qt won't render at a higher framerate than KWi=
n.
>     =

>     I'm still hoping for a better solution as (especially with Oxygen) th=
e painting can be extremely costly (I did some tests where during animation=
s Oxygen needed > 30 msec to render the decorations (mostly spent in render=
ing the radial gradient)).
>     =

>     The new idea I have now is to move the call for ensurePixmapsPainted(=
) before the blocking call to vsync. So it would still be in the same event=
 cycle but at least we don't have to wait for it. Though that is still befo=
re the scene graph is constructed and before we decide whether it's paintGe=
nericScreen or paintSimpleScreen. So it would lose the advantages of Window=
::performPaint() you pointed out above.
>     =

>     Maybe the best solution is to wait for Nuno and Hugo to replace the g=
radial radient by a texture ;-)
> =

> Thomas L=C3=BCbking wrote:
>     update() collects paint events, but repain() repaints immediately.
>     Problem however is kwin which resizes as fast as possible (unless XSY=
NC kicks in)
>     -> i'd suggest to clock unsynced resizes anyway to also reduce load o=
n the client (30fps should be ok, but right now we cause it for every pixel=
 by pixel, ie, the faster the user resizes, the more we do - 200 resize eve=
nts / second is not much...)
>     =

>     Doing so does easily drop the repaint amount even under the 60fps rep=
aint tact and as mentioned resolves this issue.
>     =

>     Putting the deco repaint before the vsync block means that we have no=
 longer a reasonable idea about the time available for the event processing=
 (if there's a deco to paint: "none" ;-)
>     =

>     The final solution will likely be to render the deco off thread (into=
 a QImage or Pixmap w/ xlib t5hreadin enabled, or textures if we can use th=
reading on contexts) and ensure a buffer update whenever the deco is done (=
but oc. the faster the deco repaints, the better)
> =

> Fredrik H=C3=B6glund wrote:
>     There is no point in using threads if one of the threads is always wa=
iting for the other thread. The compositing thread can't start rendering un=
til the decoration thread has finished updating the decorations.
>     =

>     There are also certain thread safety issues with OpenGL on Linux at t=
he moment, so only one thread can make OpenGL calls. If the decorations are=
 not painted in the same thread that does the compositing, then we can't us=
e OpenGL in the decorations.
>     =

>     So I don't think offloading rendering to different threads is the rig=
ht thing to do right now.
>
> =

> Martin Gr=C3=A4=C3=9Flin wrote:
>     Also at the moment it just does not work (I tried it). QWidget needs =
to be in the main thread and at least KCommonDecoration is too strongly QWi=
dget based. If the complete compositor is in a background thread and the de=
coration painting is in the main thread it might work, but then we have the=
 problem that performPaint has to block till the deco is rendered, so nothi=
ng is won.
>     =

>     Still the long time solution is probably threads.
> =

> Thomas L=C3=BCbking wrote:
>     Why should the compositor wait for the deco rendering?
>     The deco renders as fast as it can and the compositor uses the textur=
e it currently has, in doubt stretched or limiting the resize FPS.
>     =

>     This ensures activating a window or resizing does not block general s=
cene rendering (ie, you resize window W @5fps, but videoplayer V keeps play=
ing @24fps)
>     =

>     Regarding rendering decos into textures/the scene (gets us clamping i=
ssues?) directly, how often does Qt fall back to the raster engine (eg. bec=
ause of text?)
>     Using "bespin demo -graphicssystem opengl" is much slower on repaints=
 (try crossfading tabs) than the raster or native variant and also there're=
 some graphical glitches (easy to spot with a tiled background structure, e=
ither the tile has a border, or drawTiledPixmap() has a clamping error)

If the compositor reuses and scales an old texture, it will be perceived as=
 a temporary visual glitch which is fixed in the next frame. I think this i=
s something we want to avoid.

When there is a race between the compositing thread and the decoration thre=
ad it also creates the problem of knowing if the textures were actually up-=
to-date at the time when we rendered them. If we rendered them too soon, we=
 have to repaint the screen again immediately.

Most GPU's also don't have multiple HW contexts, so all the rendering comma=
nds that have been queued up in a thread since the last glFlush() call are =
executed without preemption when the thread calls glFlush().

And of course with the current API all this is a moot point, because it's t=
he compositing code that creates the decoration textures.

When it comes to QPainter the problem is that in order to achieve good perf=
ormance with OpenGL it's important to minimize state changes and API overhe=
ad. The way you do that is you sort the objects so you can draw all the pri=
mitives that need the same shader and the same state at the same time. And =
preferably with a single call to glDrawArrays(). With QPainter you can't re=
ally do that, since it's an immediate mode API. That's why Nokia added the =
QML2 scene graph, which allows the objects in the scene to be sorted so the=
y can be rendered in the optimal order.


- Fredrik


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
http://git.reviewboard.kde.org/r/106620/#review19532
-----------------------------------------------------------


On Sept. 30, 2012, 8:30 a.m., Martin Gr=C3=A4=C3=9Flin wrote:
> =

> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> http://git.reviewboard.kde.org/r/106620/
> -----------------------------------------------------------
> =

> (Updated Sept. 30, 2012, 8:30 a.m.)
> =

> =

> Review request for kwin.
> =

> =

> Description
> -------
> =

> Move decoration pixmap handling from Client to PaintRedirector
> =

> The only task of the PaintRedirector is to redirect the painting of the
> window decorations into Pixmaps. So it should actually do this by also
> handling the four pixmaps for the decoration. This simplifies the code
> as all the logic concerning redirecting the painting is now grouped
> together.
> =

> Furthermore the PaintRedirector is now a child of the decoration widget,
> which means it gets automatically destroyed whenever the decoration is
> destroyed - the Client does not have to care about it.
> =

> Also the PaintRedirector gets only created if the Compositor is active as
> it is not needed in the non-compositing case.
> =

> REVIEW: 106620
> =

> =

> Diffs
> -----
> =

>   kwin/client.h 130a67ae58a614f58f1106bb723312c89519be31 =

>   kwin/client.cpp 07ffe031275d988507724e45881232865b30cd9f =

>   kwin/deleted.h b91f4e2f5ced7a12a41d99c8aef000a634e7a413 =

>   kwin/deleted.cpp e2e8b8c8c655d4a17fd94ef3472bdb62d8a1d67b =

>   kwin/paintredirector.h bb5d67c598fbea88bddfd9bbe36c9452709989d1 =

>   kwin/paintredirector.cpp 61282416bfe055ff5828edf44604c709d4a2e32d =

>   kwin/scene_opengl.cpp 164d463eaef2d1dcf1b5bd7b0f8e32dda1265b13 =

>   kwin/scene_xrender.cpp f0ac20b23a022419f9cd1354a8d597acc6fa2321 =

> =

> Diff: http://git.reviewboard.kde.org/r/106620/diff/
> =

> =

> Testing
> -------
> =

> Tested with OpenGL, XRender and no compositing
> =

> =

> Thanks,
> =

> Martin Gr=C3=A4=C3=9Flin
> =

>


[Attachment #5 (text/html)]

<html>
 <body>
  <div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
   <table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 \
solid;">  <tr>
     <td>
      This is an automatically generated e-mail. To reply, visit:
      <a href="http://git.reviewboard.kde.org/r/106620/">http://git.reviewboard.kde.org/r/106620/</a>
  </td>
    </tr>
   </table>
   <br />





<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <p style="margin-top: 0;">On September 28th, 2012, 7:58 p.m., <b>Thomas \
Lübking</b> wrote:</p>  <blockquote style="margin-left: 1em; border-left: 2px solid \
#d0d0d0; padding-left: 10px;">  <pre style="white-space: pre-wrap; white-space: \
-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: \
break-word;">Afaics atm. the patch makes resizing windows *much* slower, activate \
(thus repaint) and init move seems en par at best, but the lag on repainting is \
notable (as in 20fps ./. 2fps - w/ all compositors, bespin, oxygen and Plastik QML)

I doubt the problem is that repainting decos is somewhere in the hot compositing \
loop, but that it&#39;s in the compositing &amp; event handling thread.</pre>  \
</blockquote>




 <p>On September 28th, 2012, 9:04 p.m., <b>Fredrik Höglund</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Triggering the repaint \
from the compositing path ensures that the decorations are never repainted more than \
once / frame. </pre>
 </blockquote>





 <p>On September 28th, 2012, 9:08 p.m., <b>Martin Gräßlin</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I had not observered a \
regression in resizing, but did not test that condition completely (mostly only \
tested whether it works). I&#39;ll look into that one.

Part of the idea behind this change was to move the painting out of the compositor to \
be able to move the compositor into a second thread. So far that had been a major \
issue as it crashed when using any QWidget based decoration.</pre>  </blockquote>





 <p>On September 28th, 2012, 9:52 p.m., <b>Thomas Lübking</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">It has the biggest \
impact on windows not supporting the XSYNC protocol (had an mplayer window open, used \
that to test. then tried on an xterm to rule out the client - actually kwrite resizes \
at pretty much the same speed)</pre>  </blockquote>





 <p>On September 28th, 2012, 10:38 p.m., <b>Thomas Lübking</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Can possibly be resolved \
by tacting unsynced resizes, what also -in a way- resolves the nasty judder it \
currently has on resizes (regardless of the WM, may be nvidia issue) but a trivial \
patch requires HAVE_XSYNC defined (or we remove it everywhere but for the very \
relevant getters end end up with the sync counter just being None if XSYNC is not \
available. </pre>
 </blockquote>





 <p>On September 29th, 2012, 6:05 p.m., <b>Fredrik Höglund</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">The problem is that the \
event filter in PaintRedirector now schedules repaints in response to Paint events as \
soon as kwin returns to the event loop. And that can happen many times before we \
actually update the screen. I also note that we recreate the decoration pixmaps on \
every resize event, and not just before we paint the decoration.

But if the decorations need to be updated it needs to happen exactly once before we \
paint the screen. If we do that in Window::performPaint(), or in performCompositing() \
or somewhere else probably doesn&#39;t matter from a performance point of view, \
because it still takes the same amount of time to do it. But doing it in \
Window::performPaint() does have the advantage that the update is deferred if the \
window isn&#39;t going to be painted because it is obscured or on another \
desktop.</pre>  </blockquote>





 <p>On September 29th, 2012, 8:59 p.m., <b>Martin Gräßlin</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I&#39;m going to rever \
this part of the change. Thought it&#39;s a good idea based on the assumption that Qt \
won&#39;t render at a higher framerate than KWin.

I&#39;m still hoping for a better solution as (especially with Oxygen) the painting \
can be extremely costly (I did some tests where during animations Oxygen needed &gt; \
30 msec to render the decorations (mostly spent in rendering the radial gradient)).

The new idea I have now is to move the call for ensurePixmapsPainted() before the \
blocking call to vsync. So it would still be in the same event cycle but at least we \
don&#39;t have to wait for it. Though that is still before the scene graph is \
constructed and before we decide whether it&#39;s paintGenericScreen or \
paintSimpleScreen. So it would lose the advantages of Window::performPaint() you \
pointed out above.

Maybe the best solution is to wait for Nuno and Hugo to replace the gradial radient \
by a texture ;-)</pre>  </blockquote>





 <p>On September 29th, 2012, 9:35 p.m., <b>Thomas Lübking</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">update() collects paint \
events, but repain() repaints immediately. Problem however is kwin which resizes as \
                fast as possible (unless XSYNC kicks in)
-&gt; i&#39;d suggest to clock unsynced resizes anyway to also reduce load on the \
client (30fps should be ok, but right now we cause it for every pixel by pixel, ie, \
the faster the user resizes, the more we do - 200 resize events / second is not \
much...)

Doing so does easily drop the repaint amount even under the 60fps repaint tact and as \
mentioned resolves this issue.

Putting the deco repaint before the vsync block means that we have no longer a \
reasonable idea about the time available for the event processing (if there&#39;s a \
deco to paint: &quot;none&quot; ;-)

The final solution will likely be to render the deco off thread (into a QImage or \
Pixmap w/ xlib t5hreadin enabled, or textures if we can use threading on contexts) \
and ensure a buffer update whenever the deco is done (but oc. the faster the deco \
repaints, the better)</pre>  </blockquote>





 <p>On September 30th, 2012, 7:47 a.m., <b>Fredrik Höglund</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">There is no point in \
using threads if one of the threads is always waiting for the other thread. The \
compositing thread can&#39;t start rendering until the decoration thread has finished \
updating the decorations.

There are also certain thread safety issues with OpenGL on Linux at the moment, so \
only one thread can make OpenGL calls. If the decorations are not painted in the same \
thread that does the compositing, then we can&#39;t use OpenGL in the decorations.

So I don&#39;t think offloading rendering to different threads is the right thing to \
do right now. </pre>
 </blockquote>





 <p>On September 30th, 2012, 7:56 a.m., <b>Martin Gräßlin</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Also at the moment it \
just does not work (I tried it). QWidget needs to be in the main thread and at least \
KCommonDecoration is too strongly QWidget based. If the complete compositor is in a \
background thread and the decoration painting is in the main thread it might work, \
but then we have the problem that performPaint has to block till the deco is \
rendered, so nothing is won.

Still the long time solution is probably threads.</pre>
 </blockquote>





 <p>On September 30th, 2012, 8:08 a.m., <b>Thomas Lübking</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: \
10px;">  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Why should the \
compositor wait for the deco rendering? The deco renders as fast as it can and the \
compositor uses the texture it currently has, in doubt stretched or limiting the \
resize FPS.

This ensures activating a window or resizing does not block general scene rendering \
(ie, you resize window W @5fps, but videoplayer V keeps playing @24fps)

Regarding rendering decos into textures/the scene (gets us clamping issues?) \
directly, how often does Qt fall back to the raster engine (eg. because of text?) \
Using &quot;bespin demo -graphicssystem opengl&quot; is much slower on repaints (try \
crossfading tabs) than the raster or native variant and also there&#39;re some \
graphical glitches (easy to spot with a tiled background structure, either the tile \
has a border, or drawTiledPixmap() has a clamping error)</pre>  </blockquote>








</blockquote>

<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: \
-pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">If the compositor reuses \
and scales an old texture, it will be perceived as a temporary visual glitch which is \
fixed in the next frame. I think this is something we want to avoid.

When there is a race between the compositing thread and the decoration thread it also \
creates the problem of knowing if the textures were actually up-to-date at the time \
when we rendered them. If we rendered them too soon, we have to repaint the screen \
again immediately.

Most GPU&#39;s also don&#39;t have multiple HW contexts, so all the rendering \
commands that have been queued up in a thread since the last glFlush() call are \
executed without preemption when the thread calls glFlush().

And of course with the current API all this is a moot point, because it&#39;s the \
compositing code that creates the decoration textures.

When it comes to QPainter the problem is that in order to achieve good performance \
with OpenGL it&#39;s important to minimize state changes and API overhead. The way \
you do that is you sort the objects so you can draw all the primitives that need the \
same shader and the same state at the same time. And preferably with a single call to \
glDrawArrays(). With QPainter you can&#39;t really do that, since it&#39;s an \
immediate mode API. That&#39;s why Nokia added the QML2 scene graph, which allows the \
objects in the scene to be sorted so they can be rendered in the optimal order.</pre> \
<br />








<p>- Fredrik</p>


<br />
<p>On September 30th, 2012, 8:30 a.m., Martin Gräßlin wrote:</p>






<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" \
style="background-image: \
url('http://git.reviewboard.kde.org/media/rb/images/review_request_box_top_bg.png'); \
background-position: left top; background-repeat: repeat-x; border: 1px black \
solid;">  <tr>
  <td>

<div>Review request for kwin.</div>
<div>By Martin Gräßlin.</div>


<p style="color: grey;"><i>Updated Sept. 30, 2012, 8:30 a.m.</i></p>






<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
 <table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" \
style="border: 1px solid #b8b5a0">  <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: \
-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: \
break-word;">Move decoration pixmap handling from Client to PaintRedirector

The only task of the PaintRedirector is to redirect the painting of the
window decorations into Pixmaps. So it should actually do this by also
handling the four pixmaps for the decoration. This simplifies the code
as all the logic concerning redirecting the painting is now grouped
together.

Furthermore the PaintRedirector is now a child of the decoration widget,
which means it gets automatically destroyed whenever the decoration is
destroyed - the Client does not have to care about it.

Also the PaintRedirector gets only created if the Compositor is active as
it is not needed in the non-compositing case.

REVIEW: 106620</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: \
1px solid #b8b5a0">  <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: \
-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: \
break-word;">Tested with OpenGL, XRender and no compositing</pre>  </td>
 </tr>
</table>




<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">

 <li>kwin/client.h <span style="color: \
grey">(130a67ae58a614f58f1106bb723312c89519be31)</span></li>

 <li>kwin/client.cpp <span style="color: \
grey">(07ffe031275d988507724e45881232865b30cd9f)</span></li>

 <li>kwin/deleted.h <span style="color: \
grey">(b91f4e2f5ced7a12a41d99c8aef000a634e7a413)</span></li>

 <li>kwin/deleted.cpp <span style="color: \
grey">(e2e8b8c8c655d4a17fd94ef3472bdb62d8a1d67b)</span></li>

 <li>kwin/paintredirector.h <span style="color: \
grey">(bb5d67c598fbea88bddfd9bbe36c9452709989d1)</span></li>

 <li>kwin/paintredirector.cpp <span style="color: \
grey">(61282416bfe055ff5828edf44604c709d4a2e32d)</span></li>

 <li>kwin/scene_opengl.cpp <span style="color: \
grey">(164d463eaef2d1dcf1b5bd7b0f8e32dda1265b13)</span></li>

 <li>kwin/scene_xrender.cpp <span style="color: \
grey">(f0ac20b23a022419f9cd1354a8d597acc6fa2321)</span></li>

</ul>

<p><a href="http://git.reviewboard.kde.org/r/106620/diff/" style="margin-left: \
3em;">View Diff</a></p>




  </td>
 </tr>
</table>








  </div>
 </body>
</html>



_______________________________________________
kwin mailing list
kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic