Merge lp:~vanvugt/compiz/XDamageReport into lp:compiz/0.9.8

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 3239
Proposed branch: lp:~vanvugt/compiz/XDamageReport
Merge into: lp:compiz/0.9.8
Diff against target: 86 lines (+15/-3)
5 files modified
plugins/composite/src/privates.h (+3/-0)
plugins/composite/src/screen.cpp (+9/-0)
plugins/composite/src/window.cpp (+1/-1)
plugins/decor/src/decor.cpp (+1/-1)
plugins/opengl/src/texture.cpp (+1/-1)
To merge this branch: bzr merge lp:~vanvugt/compiz/XDamageReport
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
Tim Penhey (community) Approve
Review via email: mp+108307@code.launchpad.net

Commit message

Use the XDamage extension more efficiently (the way it was designed to be
used). This dramatically reduces CPU usage, reduces wakeups, and increases
frame rates. It also solves at least one observed performance bug
(LP: #1007299) and probably several more.

Description of the change

Results!

--- Intel driver ---

BEFORE:
Application FPS = 5500
Compiz XDamageNotify per sec = 11000
CPU usage = 4%
Compiz frame rate = 30 FPS

AFTER:
Application FPS = 5500
Compiz XDamageNotify per sec = 120
CPU usage = 1-2%
Compiz frame rate = 60 FPS

RESULT:
2x frame rate
50-75% reduction in CPU
99% reduction in X event traffic

--- NVIDIA driver ---

BEFORE:
Application FPS = 3700
Compiz XDamageNotify per sec = 7400
CPU usage = 12%
Compiz frame rate = 60 FPS

AFTER:
Application FPS = 3700
Compiz XDamageNotify per sec = 120
CPU usage = 9-10%
Compiz frame rate = 60 FPS

RESULT:
Frame rate change not noticeable.
10-25% reduction in CPU
99% reduction in X event traffic

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

On Fri, 1 Jun 2012, Daniel van Vugt wrote:

I'm happy with the change to using XDamageReportBoundingRects . In
fact, it really shouldn't be an option - BoundingRects will be just
as effecient as RawRectangles when only one rectangle is being
delivered per-paint. And since the rectangles
are per-drawable anyways, the performance penalty in that case
will only arrive if you have a large window with two small
sections that are updating (and even then, redrawing the whole
large window isn't really that expensive)

> Daniel van Vugt has proposed merging lp:~vanvugt/compiz/XDamageReport into lp:compiz.
>
> Requested reviews:
> Compiz Maintainers (compiz-team)
> Related bugs:
> Bug #1007299 in Compiz: "Compiz frame rate decreases if application frame rates are too high (unthrottled)"
> https://bugs.launchpad.net/compiz/+bug/1007299
>
> For more details, see:
> https://code.launchpad.net/~vanvugt/compiz/XDamageReport/+merge/108307
>
> Results!
>
> --- Intel driver ---
>
> BEFORE:
> Application FPS = 5500
> Compiz XDamageNotify per sec = 11000
> CPU usage = 4%
> Compiz frame rate = 30 FPS
>
> AFTER:
> Application FPS = 5500
> Compiz XDamageNotify per sec = 120
> CPU usage = 1-2%
> Compiz frame rate = 60 FPS
>
> RESULT:
> 2x frame rate
> 50-75% reduction in CPU
> 99% reduction in X event traffic
>
> --- NVIDIA driver ---
>
> BEFORE:
> Application FPS = 3700
> Compiz XDamageNotify per sec = 7400
> CPU usage = 12%
> Compiz frame rate = 60 FPS
>
> AFTER:
> Application FPS = 3700
> Compiz XDamageNotify per sec = 120
> CPU usage = 9-10%
> Compiz frame rate = 60 FPS
>
> RESULT:
> Frame rate change not noticeable.
> 10-25% reduction in CPU
> 99% reduction in X event traffic
> --
> https://code.launchpad.net/~vanvugt/compiz/XDamageReport/+merge/108307
> Your team Compiz Maintainers is requested to review the proposed merge of lp:~vanvugt/compiz/XDamageReport into lp:compiz.
>

Revision history for this message
Tim Penhey (thumper) wrote :

The actual code changes look fine to me.

The two plugin changes at the bottom almost had me recommending having a factory method for Damage. Two uses is my general guideline limit before refactoring :)

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

If we are defaulting to bounding box, can we remove the option? It doesn't make sense to expose stuff like this, and we'll be dealing with bug reports when DeltaRectangles involves artefacts.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I would like to remove the option, because it makes the diff fantastically simple. But I added the option so people could:
  (1) Go back to RawRectangles if there was any regression.
  (2) Experiment with what mode is fastest.
  (3) Most important: Turn on RawRectangles to compare the performance of before and after.

Though they're all short-term requirements. Longer term it makes sense to not be an option.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> I would like to remove the option, because it makes the diff fantastically
> simple. But I added the option so people could:
> (1) Go back to RawRectangles if there was any regression.
> (2) Experiment with what mode is fastest.
> (3) Most important: Turn on RawRectangles to compare the performance of
> before and after.
>

If there is a regression, we can just revert the branch ;-) In any case, if we want to keep it as an option so we can get feedback, please make the option between BoundingBox and RawRectangles and propose a merge to remove the other one within the next two weeks.

> Though they're all short-term requirements. Longer term it makes sense to not
> be an option.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I'd rather only merge this stuff once, so will remove the option to change the reporting mode.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Conditional approval once the option is removed.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Done.

Revision history for this message
Sam Spilsbury (smspillaz) :
review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Before merging this - could you explain what the XDamageSubtract is for? It seems like on reading the documentation it is a no-op with None, None, although the documentation is very breif on this matter.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

XDamageSubtract is the most critical part of this proposal :)

It tells the X server that we have redrawn/repaired the regions that were damaged. Without the call the XDamageSubtract, most of the screen never gets redrawn. Because in the more efficient reporting modes, the X server only reports damage events for those regions it hasn't yet told you about. That's why we need to "subtract" all the damaged regions once per frame -- to tell the server we've repaired them and it can now send more events if the same region is damaged again.

"None, None" tells the server we have repaired the entire drawable (so the first None means infinite-region), and don't care to keep a copy of what the old damage region was (the second None).

[http://cgit.freedesktop.org/xorg/proto/damageproto/plain/damageproto.txt]

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Great, thanks. (And we're using std::set so there's no dupe calls). Approved.

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

With regards to the potential race condition - I had a look at mutter and kwin, and it seems like the race condition is that further damage may be accumulated on the server before we call glXBindTexImage, for example:

    if (damaged && pixmap)
    {
        XGrabServer (screen->dpy ());
        XDamageSubtract (screen->dpy (), damage, None, None);
        XSync (screen->dpy (), false);
        XUngrabServer (screen->dpy ());
        XSync (screen->dpy (), false);
 (*GL::releaseTexImage) (screen->dpy (), pixmap, GLX_FRONT_LEFT_EXT);
 (*GL::bindTexImage) (screen->dpy (), pixmap, GLX_FRONT_LEFT_EXT, NULL);
    }

I'm not able to test it, but it seems to me that you have to flush all drawing to the kernel before calling glXBindTexImage.

(Also, we should remove the damage event tracking on both the composite and decor plugins and just make opengl track the damage. There isn't much sense in tracking it multiple times, and that probably causes more issues)

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

This completed proposal is not the correct place for this discussion ^. But thanks, I suspected something like that. Unfortunately it's not a priority to revisit for a while.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/composite/src/privates.h'
2--- plugins/composite/src/privates.h 2012-05-25 03:54:23 +0000
3+++ plugins/composite/src/privates.h 2012-06-05 07:54:18 +0000
4@@ -30,6 +30,7 @@
5
6 #include <composite/composite.h>
7 #include <core/atoms.h>
8+#include <set>
9
10 #include "composite_options.h"
11
12@@ -106,6 +107,8 @@
13
14 Atom cmSnAtom;
15 Window newCmSnOwner;
16+
17+ std::set<Damage> damages;
18 };
19
20 class PrivateCompositeWindow : WindowInterface
21
22=== modified file 'plugins/composite/src/screen.cpp'
23--- plugins/composite/src/screen.cpp 2012-03-27 12:14:56 +0000
24+++ plugins/composite/src/screen.cpp 2012-06-05 07:54:18 +0000
25@@ -98,6 +98,11 @@
26 }
27 }
28 }
29+ else if (event->type == damageEvent + XDamageNotify)
30+ {
31+ XDamageNotifyEvent *de = (XDamageNotifyEvent*)event;
32+ damages.insert (de->damage);
33+ }
34 break;
35 }
36
37@@ -791,6 +796,10 @@
38 damageScreen ();
39 }
40
41+ foreach (Damage d, priv->damages)
42+ XDamageSubtract (screen->dpy(), d, None, None);
43+ priv->damages.clear ();
44+
45 priv->damage = CompRegion ();
46
47 int mask = priv->damageMask;
48
49=== modified file 'plugins/composite/src/window.cpp'
50--- plugins/composite/src/window.cpp 2012-05-25 03:54:23 +0000
51+++ plugins/composite/src/window.cpp 2012-06-05 07:54:18 +0000
52@@ -36,7 +36,7 @@
53 if (w->windowClass () != InputOnly)
54 {
55 priv->damage = XDamageCreate (s->dpy (), w->id (),
56- XDamageReportRawRectangles);
57+ XDamageReportBoundingBox);
58 }
59 else
60 {
61
62=== modified file 'plugins/decor/src/decor.cpp'
63--- plugins/decor/src/decor.cpp 2012-05-27 04:32:55 +0000
64+++ plugins/decor/src/decor.cpp 2012-06-05 07:54:18 +0000
65@@ -326,7 +326,7 @@
66 textures[0]->setMipmap (false);
67
68 damage = XDamageCreate (screen->dpy (), pixmap->getPixmap (),
69- XDamageReportRawRectangles);
70+ XDamageReportBoundingBox);
71 }
72
73 /*
74
75=== modified file 'plugins/opengl/src/texture.cpp'
76--- plugins/opengl/src/texture.cpp 2012-01-19 18:12:31 +0000
77+++ plugins/opengl/src/texture.cpp 2012-06-05 07:54:18 +0000
78@@ -581,7 +581,7 @@
79 glBindTexture (texTarget, 0);
80
81 tex->damage = XDamageCreate (screen->dpy (), pixmap,
82- XDamageReportRawRectangles);
83+ XDamageReportBoundingBox);
84 boundPixmapTex[tex->damage] = tex;
85
86 return rv;

Subscribers

People subscribed via source and target branches