Merge lp:~compiz-team/compiz/compiz.fix_1024304.1 into lp:compiz/0.9.10

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1024304.1
Merge into: lp:compiz/0.9.10
Diff against target: 2383 lines (+1494/-88)
27 files modified
plugins/animation/src/animation.cpp (+1/-1)
plugins/composite/CMakeLists.txt (+6/-1)
plugins/composite/include/composite/agedamagequery.h (+53/-0)
plugins/composite/include/composite/composite.h (+49/-14)
plugins/composite/src/backbuffertracking/CMakeLists.txt (+31/-0)
plugins/composite/src/backbuffertracking/include/backbuffertracking.h (+125/-0)
plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp (+214/-0)
plugins/composite/src/backbuffertracking/tests/CMakeLists.txt (+24/-0)
plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp (+450/-0)
plugins/composite/src/privates.h (+18/-2)
plugins/composite/src/screen.cpp (+138/-11)
plugins/kdecompat/src/kdecompat.cpp (+2/-2)
plugins/opengl/include/opengl/opengl.h (+18/-3)
plugins/opengl/src/paint.cpp (+13/-8)
plugins/opengl/src/privates.h (+31/-4)
plugins/opengl/src/screen.cpp (+301/-30)
plugins/opengl/src/window.cpp (+1/-2)
plugins/place/src/place.cpp (+1/-2)
plugins/resize/src/resize.cpp (+1/-1)
plugins/ring/src/ring.cpp (+1/-1)
plugins/scale/src/scale.cpp (+3/-1)
plugins/staticswitcher/src/staticswitcher.cpp (+1/-1)
plugins/switcher/src/switcher.cpp (+1/-1)
plugins/td/src/3d.cpp (+1/-1)
plugins/water/src/water.cpp (+7/-0)
plugins/water/src/water.h (+1/-0)
src/window.cpp (+2/-2)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1024304.1
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andrea Azzarone Pending
Esokrates testing, benchmarking Pending
Daniel van Vugt Pending
Timo Jyrinki build&run Pending
Review via email: mp+156466@code.launchpad.net

This proposal supersedes a proposal from 2013-02-28.

This proposal has been superseded by a proposal from 2013-04-24.

Commit message

Add support for the GLX_EXT_buffer_age extension on hardware that supports it, which should result in a nice speed-boost due to the fact that we no longer have to abuse fillrate by retaining old frame contents, and instead asking the driver how defined the current frame is.

Added external API for plugins to register their own damage tracking objects - with a callback as to whether or not to track the specified damage. This allows plugins that rely on both the retrospective and new damage to the framebuffer to ignore feedback caused by their old damage events.

(LP: #1024304)

Description of the change

Add support for the GLX_EXT_buffer_age extension on hardware that supports it, which should result in a nice speed-boost due to the fact that we no longer have to abuse fillrate by retaining old frame contents, and instead asking the driver how defined the current frame is.

Note: I've marked this needs review for now, but it shouldn't be merged because it confuses unity a fair bit. I've got some branches on unity which will make it work with this code (albeit, the launcher and panel will be re-presented on every frame, but that is what was happening anyways and is harmless for performance).

1. https://code.launchpad.net/~smspillaz/nux/nux.fix_1091589/+merge/147543 (WindowThread::PresentWindowsIntersectingGeometryOnThisFrame, WindowThread::ForeignFrameCutoff, WindowThread::ForeignFrameEnded)
2. https://code.launchpad.net/~smspillaz/unity/unity.fix_1080947/+merge/147544 (make unity use the new APIs)

Note 2: I don't have any solid numbers on this yet. Daniel reported a 10% difference with redirect-to-fbo-on-each-frame in bug 1024304, so I think that is a good start, because with this branch we are effectively not doing that (on NVIDIA). I've got some testers to gather some more concrete numbers in a few days.

Update: test results here: http://www.ucc.asn.au/~smspillaz/phoronix-test-suite/composite.xml

I was careful to modify phoronix-test-suite to run tests in windowed mode only, and those were the only three tests I was able to get to run in windowed mode. Of particular interest was the fact that the unigine demos had a 5x performance improvement, probably because the driver was spending less time filling redundant pixels from the compositor. In other areas we had a roughly 5FPS boost.

Compiz framerate graph:

http://www.ucc.asn.au/~smspillaz/compiz-perf-graph.png

You'll see that especially on the last test, it drops off quite a bit on the non buffer_age case, and is generally speaking lower across the board.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Esokrates (esokrarkose) wrote : Posted in a previous version of this proposal

I have used the ppa containing these changes since the beginning and could confirm the performance improvements using Phoronix Test Suite (and of course my subjective feeling). Comparing benchmarks of compiz 0.9.9.0 and the branch containing the improvements (both disabled "unredirect fullscreen windows") clearly shows that there is an substantial performance improvement.
Part of my benchmark results can be downloaded here:
http://ubuntuone.com/2JNLvWQiYiQmOCAca0bIEn

review: Approve (testing, benchmarking)
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

The change to debian/changelog seems to be unintended and should probably be removed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal

I'm getting a crash on Intel SandyBridge with this branch. At least machine information at bug #1153482 - that was after canceling the first apport dialog. Apport refuses to file the actual compiz .crash file since it notices the version numbers are out of date, but I can send the CoreDump.gz and/or .crash via e-mail.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Don't worry it doesn't matter. I've been told that all
non-insignificant changes to compiz are automatically vetoed at this
point.

On Mon, Mar 11, 2013 at 3:52 PM, Timo Jyrinki
<email address hidden> wrote:
> Review: Needs Fixing
>
> I'm getting a crash on Intel SandyBridge with this branch. At least machine information at bug #1153482 - that was after canceling the first apport dialog. Apport refuses to file the actual compiz .crash file since it notices the version numbers are out of date, but I can send the CoreDump.gz and/or .crash via e-mail.
> --
> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1024304.1/+merge/150951
> Your team Compiz Maintainers is subscribed to branch lp:compiz.

--
Sam Spilsbury

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Stacktrace would be nice though. Can you get one manually?

On Mon, Mar 11, 2013 at 4:01 PM, Sam Spilsbury <email address hidden> wrote:
> Don't worry it doesn't matter. I've been told that all
> non-insignificant changes to compiz are automatically vetoed at this
> point.
>
> On Mon, Mar 11, 2013 at 3:52 PM, Timo Jyrinki
> <email address hidden> wrote:
>> Review: Needs Fixing
>>
>> I'm getting a crash on Intel SandyBridge with this branch. At least machine information at bug #1153482 - that was after canceling the first apport dialog. Apport refuses to file the actual compiz .crash file since it notices the version numbers are out of date, but I can send the CoreDump.gz and/or .crash via e-mail.
>> --
>> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1024304.1/+merge/150951
>> Your team Compiz Maintainers is subscribed to branch lp:compiz.
>
>
>
> --
> Sam Spilsbury

--
Sam Spilsbury

Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal

Sorry, PEBKAC, recompiled Unity against it and now it works. I don't have a raring machine where I could test the actual functionality, but seems to work on Intel identically to before.

So approved with regards to build / run on Intel without GLX_EXT_buffer_age.

review: Approve (build&run)
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Ah, cool that you got it working on intel hw.

Unfortunately my understanding is that this won't go in for raring. It requires both a Unity and Nux change in order to ensure that there isn't a performance /regression/ (because of Unity's brain-dead damageScreen-on-any-damage hook), and those changes are quite substantial.

Sadly, the ps-team had three months to review these changes and I kept them up-to-date during that entire time, but the feet-dragging has effectively meant its come to a point where they won't be merged :(

Revision history for this message
Andrea Azzarone (azzar1) wrote : Posted in a previous version of this proposal
review: Needs Information
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal

Andrea: I don't think so (I might be wrong), but these are surely required to go in together with this:
https://code.launchpad.net/~smspillaz/unity/unity.fix_1080947/+merge/147544
https://code.launchpad.net/~smspillaz/nux/nux.fix_1091589/+merge/147543

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

@Timo: at the moment, it kinda pulls in https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1040478/+merge/150949 because I wrote https://code.launchpad.net/~smspillaz/unity/unity.fix_1080947/+merge/147544 with the former in mind. If we're still interested in getting this is (I'd be happy if we were) I can do a quick refactor to try and remove the dependency.

Revision history for this message
Andrea Azzarone (azzar1) wrote : Posted in a previous version of this proposal

> @Timo: at the moment, it kinda pulls in https://code.launchpad.net/~compiz-
> team/compiz/compiz.fix_1040478/+merge/150949 because I wrote
> https://code.launchpad.net/~smspillaz/unity/unity.fix_1080947/+merge/147544
> with the former in mind. If we're still interested in getting this is (I'd be
> happy if we were) I can do a quick refactor to try and remove the dependency.

Yes, please. If we can get this into a mergeable state in the next week there's a good chance we can get it in by final beta freeze (March 28). Otherwise, it's still worth getting in post-13.04

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Thu, Mar 21, 2013 at 9:14 PM, Andrea Azzarone <email address hidden> wrote:
>> @Timo: at the moment, it kinda pulls in https://code.launchpad.net/~compiz-
>> team/compiz/compiz.fix_1040478/+merge/150949 because I wrote
>> https://code.launchpad.net/~smspillaz/unity/unity.fix_1080947/+merge/147544
>> with the former in mind. If we're still interested in getting this is (I'd be
>> happy if we were) I can do a quick refactor to try and remove the dependency.
>
> Yes, please. If we can get this into a mergeable state in the next week there's a good chance we can get it in by final beta freeze (March 28). Otherwise, it's still worth getting in post-13.04

:) Alrighty, glad to see this resolved. Is it cleared with distro?
> --
> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1024304.1/+merge/150951
> Your team Compiz Maintainers is subscribed to branch lp:compiz.

--
Sam Spilsbury

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : Posted in a previous version of this proposal

Hey Sam, do you mind talking to duflu and see if he gets time to review this branch? If he's happy with it, we can get it in.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I think Daniel is busy on other projects. Subscribe him if you want, but I
think this should be left to the main legacy stack maintainers.
On 21/03/2013 11:39 PM, "Didier Roche" <email address hidden> wrote:

> Hey Sam, do you mind talking to duflu and see if he gets time to review
> this branch? If he's happy with it, we can get it in.
> --
>
> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1024304.1/+merge/150951
> Your team Compiz Maintainers is subscribed to branch lp:compiz.
>

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Okay, so the unity branch should only depend on this one now.

Though the other one is certainly a nice to have - it means we don't have to read out the bindings from opengl in unity.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Please re-target this for lp:compiz/0.9.10

review: Needs Resubmitting
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Okay, so I've talked to Didier about this and we've come up with a small plan of action. We'll need to give this a week solid of QA at the beginning of the S cycle and then make sure that we don't have any AP regressions. That'll happen in about two weeks.

3632. By Sam Spilsbury

Merge lp:compiz

3633. By Sam Spilsbury

Merge lp:compiz

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
3634. By Sam Spilsbury

Merge lp:compiz

3635. By Sam Spilsbury

Fix typo

3636. By Sam Spilsbury

We reset the frame provider at the end of glXInitContext, no need to do
it before that in the GLES case

3637. By Sam Spilsbury

Revert unrelated changes, unrevert some unintentional changes to
window.cpp

3638. By Sam Spilsbury

Merge lp:compiz

3639. By Sam Spilsbury

Merge lp:compiz

3640. By Sam Spilsbury

Merge lp:compiz

3641. By Sam Spilsbury

Revert introduction of PAINT_WINDOW_NO_DRAW_MASKS. It isn't entirely
relevant here.

3642. By Sam Spilsbury

Merge lp:compiz

3643. By Sam Spilsbury

Rename addOverdrawDamageRegion to recordDamageOnCurrentFrame and tidy
up some formatting

3644. By Sam Spilsbury

Allow an empty callback argument to getDamageQuery. Makes the plugin API
simpler

3645. By Sam Spilsbury

Merge lp:compiz

3646. By Sam Spilsbury

Merge lp:compiz

3647. By Sam Spilsbury

Merge lp:compiz

Unmerged revisions

3647. By Sam Spilsbury

Merge lp:compiz

3646. By Sam Spilsbury

Merge lp:compiz

3645. By Sam Spilsbury

Merge lp:compiz

3644. By Sam Spilsbury

Allow an empty callback argument to getDamageQuery. Makes the plugin API
simpler

3643. By Sam Spilsbury

Rename addOverdrawDamageRegion to recordDamageOnCurrentFrame and tidy
up some formatting

3642. By Sam Spilsbury

Merge lp:compiz

3641. By Sam Spilsbury

Revert introduction of PAINT_WINDOW_NO_DRAW_MASKS. It isn't entirely
relevant here.

3640. By Sam Spilsbury

Merge lp:compiz

3639. By Sam Spilsbury

Merge lp:compiz

3638. By Sam Spilsbury

Merge lp:compiz

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/animation/src/animation.cpp'
--- plugins/animation/src/animation.cpp 2013-02-27 11:33:10 +0000
+++ plugins/animation/src/animation.cpp 2013-04-24 14:57:28 +0000
@@ -1617,7 +1617,7 @@
1617 // Is this the first glPaint call this round1617 // Is this the first glPaint call this round
1618 // without the mask PAINT_WINDOW_OCCLUSION_DETECTION_MASK?1618 // without the mask PAINT_WINDOW_OCCLUSION_DETECTION_MASK?
1619 if (mPAScreen->mStartingNewPaintRound &&1619 if (mPAScreen->mStartingNewPaintRound &&
1620 !(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK))1620 !(mask & PAINT_WINDOW_NO_DRAW_MASKS))
1621 {1621 {
1622 mPAScreen->mStartingNewPaintRound = false;1622 mPAScreen->mStartingNewPaintRound = false;
16231623
16241624
=== modified file 'plugins/composite/CMakeLists.txt'
--- plugins/composite/CMakeLists.txt 2012-09-25 01:15:36 +0000
+++ plugins/composite/CMakeLists.txt 2013-04-24 14:57:28 +0000
@@ -2,9 +2,14 @@
22
3include (CompizPlugin)3include (CompizPlugin)
44
5include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
5include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinding/include)6include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinding/include)
7include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/backbuffertracking/include)
8
6link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/pixmapbinding)9link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/pixmapbinding)
10link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/backbuffertracking)
711
8compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinding)12compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinding compiz_composite_backbuffertracking)
913
10add_subdirectory (src/pixmapbinding)14add_subdirectory (src/pixmapbinding)
15add_subdirectory (src/backbuffertracking)
1116
=== added file 'plugins/composite/include/composite/agedamagequery.h'
--- plugins/composite/include/composite/agedamagequery.h 1970-01-01 00:00:00 +0000
+++ plugins/composite/include/composite/agedamagequery.h 2013-04-24 14:57:28 +0000
@@ -0,0 +1,53 @@
1/*
2 * Compiz, composite plugin, GLX_EXT_buffer_age logic
3 *
4 * Copyright (c) 2012 Sam Spilsbury
5 * Authors: Sam Spilsbury <smspillaz@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef _COMPIZ_COMPOSITE_AGEDAMAGEQUERY_H
26#define _COMPIZ_COMPOSITE_AGEDAMAGEQUERY_H
27
28#include <boost/shared_ptr.hpp>
29#include <core/region.h>
30
31namespace compiz
32{
33namespace composite
34{
35namespace buffertracking
36{
37class AgeDamageQuery
38{
39 public:
40
41 typedef boost::shared_ptr <AgeDamageQuery> Ptr;
42 typedef boost::function <bool (const CompRegion &)> AreaShouldBeMarkedDirty;
43
44 virtual ~AgeDamageQuery () {}
45 virtual CompRegion damageForFrameAge (unsigned int) = 0;
46 virtual const CompRegion & currentFrameDamage () = 0;
47};
48}
49}
50}
51
52#endif
53
054
=== modified file 'plugins/composite/include/composite/composite.h'
--- plugins/composite/include/composite/composite.h 2012-10-16 05:11:10 +0000
+++ plugins/composite/include/composite/composite.h 2013-04-24 14:57:28 +0000
@@ -30,7 +30,7 @@
3030
31#include <X11/extensions/Xcomposite.h>31#include <X11/extensions/Xcomposite.h>
3232
33#define COMPIZ_COMPOSITE_ABI 533#define COMPIZ_COMPOSITE_ABI 6
3434
35#include "core/pluginclasshandler.h"35#include "core/pluginclasshandler.h"
36#include "core/timer.h"36#include "core/timer.h"
@@ -38,6 +38,8 @@
38#include "core/screen.h"38#include "core/screen.h"
39#include "core/wrapsystem.h"39#include "core/wrapsystem.h"
4040
41#include "composite/agedamagequery.h"
42
41#define COMPOSITE_SCREEN_DAMAGE_PENDING_MASK (1 << 0)43#define COMPOSITE_SCREEN_DAMAGE_PENDING_MASK (1 << 0)
42#define COMPOSITE_SCREEN_DAMAGE_REGION_MASK (1 << 1)44#define COMPOSITE_SCREEN_DAMAGE_REGION_MASK (1 << 1)
43#define COMPOSITE_SCREEN_DAMAGE_ALL_MASK (1 << 2)45#define COMPOSITE_SCREEN_DAMAGE_ALL_MASK (1 << 2)
@@ -98,18 +100,19 @@
98namespace composite100namespace composite
99{101{
100class PaintHandler {102class PaintHandler {
101public:103 public:
102 virtual ~PaintHandler () {};104 virtual ~PaintHandler () {};
103105
104 virtual void paintOutputs (CompOutput::ptrList &outputs,106 virtual void paintOutputs (CompOutput::ptrList &outputs,
105 unsigned int mask,107 unsigned int mask,
106 const CompRegion &region) = 0;108 const CompRegion &region) = 0;
107109
108 virtual bool hasVSync () { return false; };110 virtual bool hasVSync () { return false; };
109 virtual bool requiredForcedRefreshRate () { return false; };111 virtual bool requiredForcedRefreshRate () { return false; };
110112
111 virtual void prepareDrawing () {};113 virtual void prepareDrawing () {};
112 virtual bool compositingActive () { return false; };114 virtual bool compositingActive () { return false; };
115 virtual unsigned int getFrameAge () { return 1; }
113};116};
114}117}
115}118}
@@ -173,12 +176,19 @@
173 * Hookable function to damage regions directly176 * Hookable function to damage regions directly
174 */177 */
175 virtual void damageRegion (const CompRegion &r);178 virtual void damageRegion (const CompRegion &r);
179
180 /**
181 * Hookable function to notify plugins that the last damage
182 * event for this frame has been received, and all further damage
183 * events will be for the next frame
184 */
185 virtual void damageCutoff ();
176};186};
177187
178extern template class PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>;188extern template class PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>;
179189
180class CompositeScreen :190class CompositeScreen :
181 public WrapableHandler<CompositeScreenInterface, 7>,191 public WrapableHandler<CompositeScreenInterface, 8>,
182 public PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>,192 public PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>,
183 public CompOption::Class193 public CompOption::Class
184{194{
@@ -203,6 +213,24 @@
203 void damageScreen ();213 void damageScreen ();
204214
205 void damagePending ();215 void damagePending ();
216
217 /**
218 * Causes the damage that was recorded on N - 1 number of
219 * frames ago to be added to the current frame, applied
220 * culmulatively. An age of "zero" means that the entire frame
221 * is considered undefined and must be completely repaired,
222 * wheras an age of 1 means that this frame is the same as the
223 * last frame, so no damage is required.
224 */
225 void applyDamageForFrameAge (unsigned int);
226 unsigned int getFrameAge ();
227 void addOverdrawDamageRegion (const CompRegion &);
228
229 typedef compiz::composite::buffertracking::AgeDamageQuery DamageQuery;
230 typedef DamageQuery::AreaShouldBeMarkedDirty AreaShouldBeMarkedDirty;
231
232 DamageQuery::Ptr
233 getDamageQuery (const AreaShouldBeMarkedDirty &callback);
206 234
207235
208 unsigned int damageMask ();236 unsigned int damageMask ();
@@ -248,6 +276,7 @@
248 * event loop276 * event loop
249 */277 */
250 WRAPABLE_HND (6, CompositeScreenInterface, void, damageRegion, const CompRegion &);278 WRAPABLE_HND (6, CompositeScreenInterface, void, damageRegion, const CompRegion &);
279 WRAPABLE_HND (7, CompositeScreenInterface, void, damageCutoff);
251280
252 friend class PrivateCompositeDisplay;281 friend class PrivateCompositeDisplay;
253282
@@ -310,6 +339,12 @@
310 */339 */
311#define PAINT_WINDOW_BLEND_MASK (1 << 19)340#define PAINT_WINDOW_BLEND_MASK (1 << 19)
312341
342/**
343 * flags that would indicate the window is never actually drawn
344 */
345#define PAINT_WINDOW_NO_DRAW_MASKS (PAINT_WINDOW_OCCLUSION_DETECTION_MASK | \
346 PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
347
313class CompositeWindowInterface;348class CompositeWindowInterface;
314extern template class WrapableInterface<CompositeWindow, CompositeWindowInterface>;349extern template class WrapableInterface<CompositeWindow, CompositeWindowInterface>;
315350
316351
=== added directory 'plugins/composite/src/backbuffertracking'
=== added file 'plugins/composite/src/backbuffertracking/CMakeLists.txt'
--- plugins/composite/src/backbuffertracking/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/composite/src/backbuffertracking/CMakeLists.txt 2013-04-24 14:57:28 +0000
@@ -0,0 +1,31 @@
1INCLUDE_DIRECTORIES (
2 ${CMAKE_CURRENT_SOURCE_DIR}/../../include
3 ${CMAKE_CURRENT_SOURCE_DIR}/include
4 ${CMAKE_CURRENT_SOURCE_DIR}/src
5
6 ${Boost_INCLUDE_DIRS}
7)
8
9LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS})
10
11SET(
12 SRCS
13 ${CMAKE_CURRENT_SOURCE_DIR}/src/backbuffertracking.cpp
14)
15
16ADD_LIBRARY(
17 compiz_composite_backbuffertracking STATIC
18
19 ${SRCS}
20)
21
22if (COMPIZ_BUILD_TESTING)
23ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
24endif (COMPIZ_BUILD_TESTING)
25
26TARGET_LINK_LIBRARIES(
27 compiz_composite_backbuffertracking
28
29 compiz_size
30 compiz_core
31)
032
=== added directory 'plugins/composite/src/backbuffertracking/include'
=== added file 'plugins/composite/src/backbuffertracking/include/backbuffertracking.h'
--- plugins/composite/src/backbuffertracking/include/backbuffertracking.h 1970-01-01 00:00:00 +0000
+++ plugins/composite/src/backbuffertracking/include/backbuffertracking.h 2013-04-24 14:57:28 +0000
@@ -0,0 +1,125 @@
1/*
2 * Compiz, composite plugin, GLX_EXT_buffer_age logic
3 *
4 * Copyright (c) 2012 Sam Spilsbury
5 * Authors: Sam Spilsbury <smspillaz@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef _COMPIZ_COMPOSITE_BACKBUFFERTRACKING_H
26#define _COMPIZ_COMPOSITE_BACKBUFFERTRACKING_H
27
28#include <memory>
29#include <boost/noncopyable.hpp>
30#include <boost/shared_ptr.hpp>
31#include <boost/weak_ptr.hpp>
32#include <boost/function.hpp>
33
34#include <composite/agedamagequery.h>
35
36class CompSize;
37class CompRegion;
38
39namespace compiz
40{
41namespace composite
42{
43namespace buffertracking
44{
45class DamageAgeTracking
46{
47 public:
48
49 virtual ~DamageAgeTracking () {};
50 virtual void dirtyAreaOnCurrentFrame (const CompRegion &) = 0;
51 virtual void overdrawRegionOnPaintingFrame (const CompRegion &) = 0;
52 virtual void subtractObscuredArea (const CompRegion &) = 0;
53 virtual void incrementFrameAges () = 0;
54};
55
56class AgeingDamageBufferObserver
57{
58 public:
59
60 virtual ~AgeingDamageBufferObserver () {};
61 virtual void observe (DamageAgeTracking &damageAgeTracker) = 0;
62 virtual void unobserve (DamageAgeTracking &damageAgeTracker) = 0;
63};
64
65class AgeingDamageBuffers :
66 public AgeingDamageBufferObserver,
67 boost::noncopyable
68{
69 public:
70
71 AgeingDamageBuffers ();
72
73 void observe (DamageAgeTracking &damageAgeTracker);
74 void unobserve (DamageAgeTracking &damageAgeTracker);
75 void incrementAges ();
76 void markAreaDirty (const CompRegion &reg);
77 void markAreaDirtyOnLastFrame (const CompRegion &reg);
78 void subtractObscuredArea (const CompRegion &reg);
79
80 private:
81
82 class Private;
83 std::auto_ptr <Private> priv;
84};
85
86class FrameRoster :
87 public DamageAgeTracking,
88 public AgeDamageQuery,
89 boost::noncopyable
90{
91 public:
92
93 typedef AgeDamageQuery::AreaShouldBeMarkedDirty AreaShouldBeMarkedDirty;
94 typedef boost::shared_ptr <FrameRoster> Ptr;
95
96 FrameRoster (const CompSize &size,
97 AgeingDamageBufferObserver &tracker,
98 const AreaShouldBeMarkedDirty &shouldMarkDirty);
99
100 ~FrameRoster ();
101
102 void dirtyAreaOnCurrentFrame (const CompRegion &);
103 void overdrawRegionOnPaintingFrame (const CompRegion &);
104 void subtractObscuredArea (const CompRegion &);
105 void incrementFrameAges ();
106 CompRegion damageForFrameAge (unsigned int);
107 const CompRegion & currentFrameDamage ();
108
109 class Private;
110 std::auto_ptr <Private> priv;
111
112 static const unsigned int NUM_TRACKED_FRAMES = 10;
113
114 static
115 FrameRoster::Ptr create (const CompSize &size,
116
117 const AreaShouldBeMarkedDirty &shouldMarkDirty);
118
119 private:
120
121};
122} // namespace buffertracking
123} // namespace composite
124} // namespace compiz
125#endif
0126
=== added directory 'plugins/composite/src/backbuffertracking/src'
=== added file 'plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp'
--- plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp 1970-01-01 00:00:00 +0000
+++ plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp 2013-04-24 14:57:28 +0000
@@ -0,0 +1,214 @@
1/*
2 * Compiz, composite plugin, GLX_EXT_buffer_age logic
3 *
4 * Copyright (c) 2012 Sam Spilsbury
5 * Authors: Sam Spilsbury <smspillaz@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include <deque>
26#include <core/size.h>
27#include <core/region.h>
28#include "backbuffertracking.h"
29#include <cstdio>
30
31namespace bt = compiz::composite::buffertracking;
32
33class bt::FrameRoster::Private
34{
35 public:
36
37 Private (const CompSize &size,
38 bt::AgeingDamageBufferObserver &observer,
39 const bt::FrameRoster::AreaShouldBeMarkedDirty &shouldBeMarkedDirty) :
40 screenSize (size),
41 observer (observer),
42 shouldBeMarkedDirty (shouldBeMarkedDirty),
43 oldFrames (1)
44 {
45 }
46
47 CompSize screenSize;
48 bt::AgeingDamageBufferObserver &observer;
49 bt::FrameRoster::AreaShouldBeMarkedDirty shouldBeMarkedDirty;
50 std::deque <CompRegion> oldFrames;
51};
52
53bt::FrameRoster::FrameRoster (const CompSize &size,
54 bt::AgeingDamageBufferObserver &tracker,
55 const AreaShouldBeMarkedDirty &shouldBeMarkedDirty) :
56 priv (new bt::FrameRoster::Private (size,
57 tracker,
58 shouldBeMarkedDirty))
59{
60 priv->observer.observe (*this);
61}
62
63bt::FrameRoster::~FrameRoster ()
64{
65 priv->observer.unobserve (*this);
66}
67
68CompRegion
69bt::FrameRoster::damageForFrameAge (unsigned int age)
70{
71 if (!age)
72 return CompRegion (0, 0,
73 priv->screenSize.width (),
74 priv->screenSize.height ());
75
76 if (age >= priv->oldFrames.size ())
77 return CompRegion (0, 0,
78 priv->screenSize.width (),
79 priv->screenSize.height ());
80
81 CompRegion accumulatedDamage;
82
83 while (age--)
84 {
85 unsigned int frameNum = (priv->oldFrames.size () - age) - 1;
86 accumulatedDamage += priv->oldFrames[frameNum];
87 }
88
89 return accumulatedDamage;
90}
91
92void
93bt::FrameRoster::dirtyAreaOnCurrentFrame (const CompRegion &r)
94{
95 if (priv->shouldBeMarkedDirty (r))
96 (*priv->oldFrames.rbegin ()) += r;
97}
98
99void
100bt::FrameRoster::subtractObscuredArea (const CompRegion &r)
101{
102 (*priv->oldFrames.rbegin ()) -= r;
103}
104
105void
106bt::FrameRoster::overdrawRegionOnPaintingFrame (const CompRegion &r)
107{
108 assert (priv->oldFrames.size () > 1);
109 std::deque <CompRegion>::reverse_iterator it = priv->oldFrames.rbegin ();
110 ++it;
111 (*it) += r;
112}
113
114void
115bt::FrameRoster::incrementFrameAges ()
116{
117 priv->oldFrames.push_back (CompRegion ());
118
119 /* Get rid of old frames */
120 if (priv->oldFrames.size () > NUM_TRACKED_FRAMES)
121 priv->oldFrames.pop_front ();
122}
123
124const CompRegion &
125bt::FrameRoster::currentFrameDamage ()
126{
127 return *priv->oldFrames.rbegin ();
128}
129
130class bt::AgeingDamageBuffers::Private
131{
132 public:
133
134 std::vector <bt::DamageAgeTracking *> damageAgeTrackers;
135};
136
137bt::AgeingDamageBuffers::AgeingDamageBuffers () :
138 priv (new bt::AgeingDamageBuffers::Private ())
139{
140}
141
142void
143bt::AgeingDamageBuffers::observe (bt::DamageAgeTracking &damageAgeTracker)
144{
145 priv->damageAgeTrackers.push_back (&damageAgeTracker);
146}
147
148void
149bt::AgeingDamageBuffers::unobserve (bt::DamageAgeTracking &damageAgeTracker)
150{
151 std::vector <bt::DamageAgeTracking *>::iterator it =
152 std::find (priv->damageAgeTrackers.begin (),
153 priv->damageAgeTrackers.end (),
154 &damageAgeTracker);
155
156 if (it != priv->damageAgeTrackers.end ())
157 priv->damageAgeTrackers.erase (it);
158}
159
160void
161bt::AgeingDamageBuffers::incrementAges ()
162{
163 for (std::vector <bt::DamageAgeTracking *>::iterator it =
164 priv->damageAgeTrackers.begin ();
165 it != priv->damageAgeTrackers.end ();
166 ++it)
167 {
168 bt::DamageAgeTracking *tracker = *it;
169
170 tracker->incrementFrameAges ();
171 }
172}
173
174void
175bt::AgeingDamageBuffers::markAreaDirty (const CompRegion &reg)
176{
177 for (std::vector <bt::DamageAgeTracking *>::iterator it =
178 priv->damageAgeTrackers.begin ();
179 it != priv->damageAgeTrackers.end ();
180 ++it)
181 {
182 bt::DamageAgeTracking *tracker = *it;
183
184 tracker->dirtyAreaOnCurrentFrame (reg);
185 }
186}
187
188void
189bt::AgeingDamageBuffers::subtractObscuredArea (const CompRegion &reg)
190{
191 for (std::vector <bt::DamageAgeTracking *>::iterator it =
192 priv->damageAgeTrackers.begin ();
193 it != priv->damageAgeTrackers.end ();
194 ++it)
195 {
196 bt::DamageAgeTracking *tracker = *it;
197
198 tracker->subtractObscuredArea (reg);
199 }
200}
201
202void
203bt::AgeingDamageBuffers::markAreaDirtyOnLastFrame (const CompRegion &reg)
204{
205 for (std::vector <bt::DamageAgeTracking *>::iterator it =
206 priv->damageAgeTrackers.begin ();
207 it != priv->damageAgeTrackers.end ();
208 ++it)
209 {
210 bt::DamageAgeTracking *tracker = *it;
211
212 tracker->overdrawRegionOnPaintingFrame (reg);
213 }
214}
0215
=== added directory 'plugins/composite/src/backbuffertracking/tests'
=== added file 'plugins/composite/src/backbuffertracking/tests/CMakeLists.txt'
--- plugins/composite/src/backbuffertracking/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/composite/src/backbuffertracking/tests/CMakeLists.txt 2013-04-24 14:57:28 +0000
@@ -0,0 +1,24 @@
1find_library (GMOCK_LIBRARY gmock)
2find_library (GMOCK_MAIN_LIBRARY gmock_main)
3
4if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
5 message ("Google Mock and Google Test not found - cannot build tests!")
6 set (COMPIZ_BUILD_TESTING OFF)
7endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
8
9include_directories (${GTEST_INCLUDE_DIRS})
10
11link_directories (${COMPIZ_LIBRARY_DIRS})
12
13add_executable (compiz_test_composite_backbuffertracking
14 ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-backbuffertracking.cpp)
15
16target_link_libraries (compiz_test_composite_backbuffertracking
17 compiz_composite_backbuffertracking
18 ${GTEST_BOTH_LIBRARIES}
19 ${GMOCK_LIBRARY}
20 ${GMOCK_MAIN_LIBRARY}
21 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
22 )
23
24compiz_discover_tests (compiz_test_composite_backbuffertracking COVERAGE compiz_composite_backbuffertracking)
025
=== added file 'plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp'
--- plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp 1970-01-01 00:00:00 +0000
+++ plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp 2013-04-24 14:57:28 +0000
@@ -0,0 +1,450 @@
1/*
2 * Compiz, composite plugin, GLX_EXT_buffer_age logic
3 *
4 * Copyright (c) 2012 Sam Spilsbury
5 * Authors: Sam Spilsbury <smspillaz@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include <boost/bind.hpp>
26
27#include <gtest/gtest.h>
28#include <gmock/gmock.h>
29
30#include <core/region.h>
31#include <core/size.h>
32
33#include "backbuffertracking.h"
34
35using ::testing::NiceMock;
36using ::testing::_;
37using ::testing::AtLeast;
38
39namespace bt = compiz::composite::buffertracking;
40
41namespace
42{
43class MockAgeingDamageBufferObserver :
44 public bt::AgeingDamageBufferObserver
45{
46 public:
47
48 MOCK_METHOD1 (observe, void (bt::DamageAgeTracking &));
49 MOCK_METHOD1 (unobserve, void (bt::DamageAgeTracking &));
50};
51
52bool alwaysTrackDamage (const CompRegion &)
53{
54 return true;
55}
56
57
58class BackbufferTracking :
59 public ::testing::Test
60{
61 public:
62
63 BackbufferTracking () :
64 screen (1000, 1000),
65 roster ()
66 {
67 }
68
69 virtual void SetUp ()
70 {
71 SetupRoster ();
72 }
73
74 virtual void SetupRoster ()
75 {
76 roster.reset (new bt::FrameRoster (screen,
77 niceTracker,
78 boost::bind (alwaysTrackDamage,
79 _1)));
80 }
81
82 protected:
83
84 CompSize screen;
85 NiceMock <MockAgeingDamageBufferObserver> niceTracker;
86 bt::FrameRoster::Ptr roster;
87};
88
89class BackbufferTrackingCallbacks :
90 public BackbufferTracking
91{
92 public:
93
94 BackbufferTrackingCallbacks () :
95 shouldDamage (false)
96 {
97 }
98
99 protected:
100
101 void allowDamage (bool allow)
102 {
103 shouldDamage = allow;
104 }
105
106 private:
107
108 virtual void SetupRoster ()
109 {
110 roster.reset (new bt::FrameRoster (screen,
111 niceTracker,
112 boost::bind (&BackbufferTrackingCallbacks::shouldDamageCallback,
113 this, _1)));
114 }
115
116 bool shouldDamageCallback (const CompRegion &)
117 {
118 return shouldDamage;
119 }
120
121 bool shouldDamage;
122};
123}
124
125std::ostream &
126operator<< (std::ostream &os, const CompRegion &reg)
127{
128 os << "Region with Bounding Rectangle : " <<
129 reg.boundingRect ().x () << " " <<
130 reg.boundingRect ().y () << " " <<
131 reg.boundingRect ().width () << " " <<
132 reg.boundingRect ().height () << std::endl;
133 CompRect::vector rects (reg.rects ());
134 for (CompRect::vector::iterator it = rects.begin ();
135 it != rects.end ();
136 it++)
137 os << " - subrectangle: " <<
138 (*it).x () << " " <<
139 (*it).y () << " " <<
140 (*it).width () << " " <<
141 (*it).height () << " " << std::endl;
142
143 return os;
144}
145
146TEST (BackbufferTrackingConstruction, CreateAddsToObserverList)
147{
148 MockAgeingDamageBufferObserver mockAgeingDamageBufferObserver;
149
150 /* We can't verify the argument here,
151 * but we can verify the function call */
152 EXPECT_CALL (mockAgeingDamageBufferObserver, observe (_));
153 EXPECT_CALL (mockAgeingDamageBufferObserver, unobserve (_)).Times (AtLeast (0));
154 bt::FrameRoster roster (CompSize (),
155 mockAgeingDamageBufferObserver,
156 boost::bind (alwaysTrackDamage, _1));
157}
158
159TEST (BackbufferTrackingConstruction, DestroyRemovesFromObserverList)
160{
161 MockAgeingDamageBufferObserver mockAgeingDamageBufferObserver;
162
163 /* We can't verify the argument here,
164 * but we can verify the function call */
165 EXPECT_CALL (mockAgeingDamageBufferObserver, observe (_)).Times (AtLeast (0));
166 EXPECT_CALL (mockAgeingDamageBufferObserver, unobserve (_));
167 bt::FrameRoster roster (CompSize (),
168 mockAgeingDamageBufferObserver,
169 boost::bind (alwaysTrackDamage, _1));
170}
171
172TEST_F (BackbufferTrackingCallbacks, TrackIntoCurrentIfCallbackTrue)
173{
174 allowDamage (true);
175 CompRegion damage (100, 100, 100, 100);
176 roster->dirtyAreaOnCurrentFrame (damage);
177 EXPECT_EQ (damage, roster->currentFrameDamage ());
178}
179
180TEST_F (BackbufferTrackingCallbacks, NoTrackIntoCurrentIfCallbackFalse)
181{
182 allowDamage (false);
183 CompRegion damage (100, 100, 100, 100);
184 roster->dirtyAreaOnCurrentFrame (damage);
185 EXPECT_EQ (emptyRegion, roster->currentFrameDamage ());
186}
187
188TEST_F (BackbufferTracking, DirtyAreaSubtraction)
189{
190 CompRegion dirty (100, 100, 100, 100);
191 CompRegion obscured (150, 150, 50, 50);
192 roster->dirtyAreaOnCurrentFrame (dirty);
193 roster->subtractObscuredArea (obscured);
194 EXPECT_EQ (dirty - obscured, roster->currentFrameDamage ());
195}
196
197TEST_F (BackbufferTracking, DirtyAreaForAgeZeroAll)
198{
199 EXPECT_EQ (CompRegion (0, 0, screen.width (), screen.height ()),
200 roster->damageForFrameAge (0));
201}
202
203TEST_F (BackbufferTracking, DirtyAreaAllForOlderThanTrackedAge)
204{
205 EXPECT_EQ (CompRegion (0, 0, screen.width (), screen.height ()),
206 roster->damageForFrameAge (1));
207}
208
209TEST_F (BackbufferTracking, NoDirtyAreaForLastFrame)
210{
211 CompRegion all (0, 0, screen.width (), screen.height ());
212 roster->dirtyAreaOnCurrentFrame (all);
213 roster->incrementFrameAges ();
214 EXPECT_EQ (emptyRegion, roster->damageForFrameAge (1));
215}
216
217TEST_F (BackbufferTracking, DirtyAreaIfMoreSinceLastFrame)
218{
219 CompRegion all (0, 0, screen.width (), screen.height ());
220 roster->dirtyAreaOnCurrentFrame (all);
221 roster->incrementFrameAges ();
222 roster->dirtyAreaOnCurrentFrame(all);
223 EXPECT_EQ (all, roster->damageForFrameAge (1));
224}
225
226TEST_F (BackbufferTracking, AddOverdrawRegionForLastFrame)
227{
228 CompRegion all (0, 0, screen.width (), screen.height ());
229 roster->dirtyAreaOnCurrentFrame (all);
230 roster->incrementFrameAges ();
231 roster->incrementFrameAges ();
232 roster->overdrawRegionOnPaintingFrame (all);
233 EXPECT_EQ (all, roster->damageForFrameAge (2));
234}
235
236TEST_F (BackbufferTracking, TwoFramesAgo)
237{
238 CompRegion all (0, 0, screen.width (), screen.height ());
239 CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2);
240
241 roster->dirtyAreaOnCurrentFrame (all);
242 roster->incrementFrameAges ();
243 roster->dirtyAreaOnCurrentFrame (topleft);
244 roster->incrementFrameAges ();
245 EXPECT_EQ (topleft, roster->damageForFrameAge (2));
246}
247
248TEST_F (BackbufferTracking, TwoFramesAgoCulmulative)
249{
250 CompRegion all (0, 0, screen.width (), screen.height ());
251 CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2);
252 CompRegion topright (0, screen.width () / 2,
253 screen.width () / 2,
254 screen.height () / 2);
255
256 roster->dirtyAreaOnCurrentFrame (all);
257 roster->incrementFrameAges ();
258 roster->dirtyAreaOnCurrentFrame (topleft);
259 roster->dirtyAreaOnCurrentFrame (topright);
260 roster->incrementFrameAges ();
261 EXPECT_EQ (topleft + topright, roster->damageForFrameAge (2));
262}
263
264TEST_F (BackbufferTracking, ThreeFramesAgo)
265{
266 CompRegion all (0, 0, screen.width (), screen.height ());
267 CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2);
268 CompRegion bottomright (screen.width () / 2,
269 screen.height () / 2,
270 screen.width () / 2,
271 screen.height () / 2);
272
273 roster->dirtyAreaOnCurrentFrame (all);
274 roster->incrementFrameAges ();
275 roster->dirtyAreaOnCurrentFrame (topleft);
276 roster->incrementFrameAges ();
277 roster->dirtyAreaOnCurrentFrame (bottomright);
278 roster->incrementFrameAges ();
279
280 EXPECT_EQ (topleft + bottomright, roster->damageForFrameAge (3));
281}
282
283/* These are more or less functional tests from this point forward
284 * just checking a number of different situations */
285
286TEST_F (BackbufferTracking, ThreeFramesAgoWithFourFrames)
287{
288 CompRegion all (0, 0, screen.width (), screen.height ());
289 CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2);
290 CompRegion bottomright (screen.width () / 2,
291 screen.height () / 2,
292 screen.width () / 2,
293 screen.height () / 2);
294 CompRegion topright (screen.width () / 2,
295 0,
296 screen.width () / 2,
297 screen.height () / 2);
298
299 roster->dirtyAreaOnCurrentFrame (all);
300 roster->incrementFrameAges ();
301 roster->dirtyAreaOnCurrentFrame (topleft);
302 roster->incrementFrameAges ();
303 roster->dirtyAreaOnCurrentFrame (bottomright);
304 roster->incrementFrameAges ();
305 roster->dirtyAreaOnCurrentFrame (topright);
306 roster->incrementFrameAges ();
307
308 EXPECT_EQ (topright + bottomright, roster->damageForFrameAge (3));
309}
310
311TEST_F (BackbufferTracking, ThreeFramesAgoWithFourFramesAndOverlap)
312{
313 CompRegion all (0, 0, screen.width (), screen.height ());
314 CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2);
315 CompRegion bottomright (screen.width () / 2,
316 screen.height () / 2,
317 screen.width () / 2,
318 screen.height () / 2);
319 CompRegion topright (screen.width () / 2,
320 0,
321 screen.width () / 2,
322 screen.height () / 2);
323
324 roster->dirtyAreaOnCurrentFrame (all);
325 roster->incrementFrameAges ();
326 roster->dirtyAreaOnCurrentFrame (topleft);
327 roster->incrementFrameAges ();
328 roster->dirtyAreaOnCurrentFrame (bottomright);
329 roster->incrementFrameAges ();
330 roster->dirtyAreaOnCurrentFrame (bottomright);
331 roster->incrementFrameAges ();
332
333 EXPECT_EQ (bottomright, roster->damageForFrameAge (3));
334}
335
336TEST_F (BackbufferTracking, AllDamageForExceedingMaxTrackedFrames)
337{
338 CompRegion all (0, 0, screen.width (), screen.height ());
339 CompRegion damage (0, 0, 1, 1);
340
341 roster->dirtyAreaOnCurrentFrame (all);
342
343 for (unsigned int i = 0; i < bt::FrameRoster::NUM_TRACKED_FRAMES - 1; ++i)
344 {
345 roster->incrementFrameAges ();
346 roster->dirtyAreaOnCurrentFrame (damage);
347 }
348
349 EXPECT_EQ (all, roster->damageForFrameAge (bt::FrameRoster::NUM_TRACKED_FRAMES + 1));
350}
351
352TEST_F (BackbufferTracking, DamageForMaxTrackedFrame)
353{
354 CompRegion all (0, 0, screen.width (), screen.height ());
355 CompRegion damage (0, 0, 1, 1);
356
357 roster->dirtyAreaOnCurrentFrame (all);
358
359 for (unsigned int i = 0; i < bt::FrameRoster::NUM_TRACKED_FRAMES + 1; ++i)
360 {
361 roster->incrementFrameAges ();
362 roster->dirtyAreaOnCurrentFrame (damage);
363 }
364
365 EXPECT_EQ (all, roster->damageForFrameAge (bt::FrameRoster::NUM_TRACKED_FRAMES));
366}
367
368class MockDamageAgeTracking :
369 public bt::DamageAgeTracking
370{
371 public:
372
373 typedef boost::shared_ptr <MockDamageAgeTracking> Ptr;
374
375 MOCK_METHOD0 (incrementFrameAges, void ());
376 MOCK_METHOD1 (dirtyAreaOnCurrentFrame, void (const CompRegion &));
377 MOCK_METHOD1 (subtractObscuredArea, void (const CompRegion &));
378 MOCK_METHOD1 (overdrawRegionOnPaintingFrame, void (const CompRegion &));
379};
380
381class AgeingDamageBuffers :
382 public ::testing::Test
383{
384 public:
385
386 AgeingDamageBuffers ()
387 {
388 ageing.observe (mockDamageAgeTracker);
389 }
390
391 MockDamageAgeTracking mockDamageAgeTracker;
392 bt::AgeingDamageBuffers ageing;
393};
394
395TEST_F (AgeingDamageBuffers, IncrementAgesOnValidRosters)
396{
397 EXPECT_CALL (mockDamageAgeTracker, incrementFrameAges ());
398 ageing.incrementAges ();
399}
400
401TEST_F (AgeingDamageBuffers, DirtyAreaOnValidRosters)
402{
403 CompRegion dirtyArea (100, 100, 100, 100);
404 EXPECT_CALL (mockDamageAgeTracker, dirtyAreaOnCurrentFrame (dirtyArea));
405 ageing.markAreaDirty (dirtyArea);
406}
407
408TEST_F (AgeingDamageBuffers, SubtractObscuredAreaOnValidRosters)
409{
410 CompRegion obscuredArea (100, 100, 100, 100);
411 EXPECT_CALL (mockDamageAgeTracker, subtractObscuredArea (obscuredArea));
412 ageing.subtractObscuredArea (obscuredArea);
413}
414
415TEST_F (AgeingDamageBuffers, AddOverdrawAreaOnValidRosters)
416{
417 CompRegion overdrawArea (100, 100, 100, 100);
418 EXPECT_CALL (mockDamageAgeTracker, overdrawRegionOnPaintingFrame (overdrawArea));
419 ageing.markAreaDirtyOnLastFrame (overdrawArea);
420}
421
422TEST_F (AgeingDamageBuffers, IncrementAgesOnInvalidRosters)
423{
424 EXPECT_CALL (mockDamageAgeTracker, incrementFrameAges ()).Times (0);
425 ageing.unobserve (mockDamageAgeTracker);
426 ageing.incrementAges ();
427}
428
429TEST_F (AgeingDamageBuffers, DirtyAreaOnInvalidRosters)
430{
431 EXPECT_CALL (mockDamageAgeTracker, dirtyAreaOnCurrentFrame (_)).Times (0);
432 ageing.unobserve (mockDamageAgeTracker);
433 ageing.markAreaDirty (emptyRegion);
434}
435
436TEST_F (AgeingDamageBuffers, SubtractObscuredAreaOnInvalidRosters)
437{
438 EXPECT_CALL (mockDamageAgeTracker, subtractObscuredArea (_)).Times (0);
439 ageing.unobserve (mockDamageAgeTracker);
440 ageing.subtractObscuredArea (emptyRegion);
441}
442
443TEST_F (AgeingDamageBuffers, AddOverdrawAreaOnInvalidRosters)
444{
445 EXPECT_CALL (mockDamageAgeTracker, overdrawRegionOnPaintingFrame (_)).Times (0);
446 ageing.unobserve (mockDamageAgeTracker);
447 ageing.markAreaDirtyOnLastFrame (emptyRegion);
448}
449
450
0451
=== modified file 'plugins/composite/src/privates.h'
--- plugins/composite/src/privates.h 2012-09-20 09:35:40 +0000
+++ plugins/composite/src/privates.h 2013-04-24 14:57:28 +0000
@@ -36,12 +36,20 @@
36#include <map>36#include <map>
3737
38#include "pixmapbinding.h"38#include "pixmapbinding.h"
39#include "backbuffertracking.h"
39#include "composite_options.h"40#include "composite_options.h"
4041
41extern CompPlugin::VTable *compositeVTable;42extern CompPlugin::VTable *compositeVTable;
4243
43extern CompWindow *lastDamagedWindow;44extern CompWindow *lastDamagedWindow;
4445
46enum DamageTracking
47{
48 DamageForCurrentFrame = 0,
49 DamageForLastFrame = 1,
50 DamageFinalPaintRegion
51};
52
45class PrivateCompositeScreen :53class PrivateCompositeScreen :
46 ScreenInterface,54 ScreenInterface,
47 public CompositeOptions55 public CompositeOptions
@@ -66,6 +74,8 @@
6674
67 void scheduleRepaint ();75 void scheduleRepaint ();
6876
77 const CompRegion * damageTrackedBuffer (const CompRegion &);
78
69 public:79 public:
7080
71 CompositeScreen *cScreen;81 CompositeScreen *cScreen;
@@ -80,10 +90,12 @@
80 bool randrExtension;90 bool randrExtension;
81 int randrEvent, randrError;91 int randrEvent, randrError;
8292
83 CompRegion damage;93 CompRegion lastFrameDamage;
84 unsigned long damageMask;94 unsigned long damageMask;
8595
86 CompRegion tmpRegion;96 CompRegion tmpRegion;
97
98 DamageTracking currentlyTrackingDamage;
8799
88 Window overlay;100 Window overlay;
89 Window output;101 Window output;
@@ -99,6 +111,7 @@
99 int redrawTime;111 int redrawTime;
100 int optimalRedrawTime;112 int optimalRedrawTime;
101 bool scheduled, painting, reschedule;113 bool scheduled, painting, reschedule;
114 bool damageRequiresRepaintReschedule;
102115
103 bool slowAnimations;116 bool slowAnimations;
104117
@@ -115,6 +128,9 @@
115128
116 /* Map Damage handle to its bounding box */129 /* Map Damage handle to its bounding box */
117 std::map<Damage, XRectangle> damages;130 std::map<Damage, XRectangle> damages;
131
132 compiz::composite::buffertracking::AgeingDamageBuffers ageingBuffers;
133 compiz::composite::buffertracking::FrameRoster roster;
118};134};
119135
120class PrivateCompositeWindow :136class PrivateCompositeWindow :
121137
=== modified file 'plugins/composite/src/screen.cpp'
--- plugins/composite/src/screen.cpp 2013-04-19 11:03:09 +0000
+++ plugins/composite/src/screen.cpp 2013-04-24 14:57:28 +0000
@@ -47,6 +47,8 @@
4747
48template class WrapableInterface<CompositeScreen, CompositeScreenInterface>;48template class WrapableInterface<CompositeScreen, CompositeScreenInterface>;
4949
50namespace bt = compiz::composite::buffertracking;
51
50static const int FALLBACK_REFRESH_RATE = 60; /* if all else fails */52static const int FALLBACK_REFRESH_RATE = 60; /* if all else fails */
5153
52CompWindow *lastDamagedWindow = 0;54CompWindow *lastDamagedWindow = 0;
@@ -265,6 +267,15 @@
265 delete priv;267 delete priv;
266}268}
267269
270namespace
271{
272bool alwaysMarkDirty ()
273{
274 return true;
275}
276}
277
278
268PrivateCompositeScreen::PrivateCompositeScreen (CompositeScreen *cs) :279PrivateCompositeScreen::PrivateCompositeScreen (CompositeScreen *cs) :
269 cScreen (cs),280 cScreen (cs),
270 compositeEvent (0),281 compositeEvent (0),
@@ -282,6 +293,7 @@
282 randrEvent (0),293 randrEvent (0),
283 randrError (0),294 randrError (0),
284 damageMask (COMPOSITE_SCREEN_DAMAGE_ALL_MASK),295 damageMask (COMPOSITE_SCREEN_DAMAGE_ALL_MASK),
296 currentlyTrackingDamage (DamageForCurrentFrame),
285 overlay (None),297 overlay (None),
286 output (None),298 output (None),
287 exposeRects (),299 exposeRects (),
@@ -293,12 +305,16 @@
293 scheduled (false),305 scheduled (false),
294 painting (false),306 painting (false),
295 reschedule (false),307 reschedule (false),
308 damageRequiresRepaintReschedule (true),
296 slowAnimations (false),309 slowAnimations (false),
297 pHnd (NULL),310 pHnd (NULL),
298 FPSLimiterMode (CompositeFPSLimiterModeDefault),311 FPSLimiterMode (CompositeFPSLimiterModeDefault),
299 withDestroyedWindows (),312 withDestroyedWindows (),
300 cmSnAtom (0),313 cmSnAtom (0),
301 newCmSnOwner (None)314 newCmSnOwner (None),
315 roster (*screen,
316 ageingBuffers,
317 boost::bind (alwaysMarkDirty))
302{318{
303 gettimeofday (&lastRedraw, 0);319 gettimeofday (&lastRedraw, 0);
304 // wrap outputChangeNotify320 // wrap outputChangeNotify
@@ -474,22 +490,62 @@
474 return false;490 return false;
475}491}
476492
493const CompRegion *
494PrivateCompositeScreen::damageTrackedBuffer (const CompRegion &region)
495{
496 const CompRegion *currentDamage = NULL;
497
498 switch (currentlyTrackingDamage)
499 {
500 case DamageForCurrentFrame:
501 currentDamage = &(roster.currentFrameDamage ());
502 ageingBuffers.markAreaDirty (region);
503 break;
504 case DamageForLastFrame:
505 currentDamage = &(lastFrameDamage);
506 lastFrameDamage += region;
507 break;
508 case DamageFinalPaintRegion:
509 currentDamage = &(tmpRegion);
510 tmpRegion += region;
511 break;
512 default:
513 compLogMessage ("composite", CompLogLevelFatal, "unreachable section");
514 assert (false);
515 abort ();
516 }
517
518 assert (currentDamage);
519 return currentDamage;
520}
521
477void522void
478CompositeScreen::damageScreen ()523CompositeScreen::damageScreen ()
479{524{
525 /* Don't tell plugins about damage events when the damage buffer is already full */
480 bool alreadyDamaged = priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK;526 bool alreadyDamaged = priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK;
527 alreadyDamaged |= ((currentDamage () & screen->region ()) == screen->region ());
481528
482 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_ALL_MASK;529 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_ALL_MASK;
483 priv->damageMask &= ~COMPOSITE_SCREEN_DAMAGE_REGION_MASK;530 priv->damageMask &= ~COMPOSITE_SCREEN_DAMAGE_REGION_MASK;
484531
485 priv->scheduleRepaint ();532 if (priv->damageRequiresRepaintReschedule)
533 priv->scheduleRepaint ();
486534
487 /*535 /*
488 * Call through damageRegion since plugins listening for incoming damage536 * Call through damageRegion since plugins listening for incoming damage
489 * may need to know that the whole screen was redrawn537 * may need to know that the whole screen was redrawn
490 */538 */
491 if (!alreadyDamaged)539 if (!alreadyDamaged)
540 {
492 damageRegion (CompRegion (0, 0, screen->width (), screen->height ()));541 damageRegion (CompRegion (0, 0, screen->width (), screen->height ()));
542
543 /* Set the damage region as the fullscreen region, because if
544 * windows are unredirected we need to correctly subtract from
545 * it later
546 */
547 priv->damageTrackedBuffer (screen->region ());
548 }
493}549}
494550
495void551void
@@ -500,7 +556,12 @@
500 if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)556 if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
501 return;557 return;
502558
503 priv->damage += region;559 /* Don't cause repaints to be scheduled for empty damage
560 * regions */
561 if (region.isEmpty ())
562 return;
563
564 const CompRegion *currentDamage = priv->damageTrackedBuffer (region);
504 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_REGION_MASK;565 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_REGION_MASK;
505566
506 /* If the number of damage rectangles grows two much between repaints,567 /* If the number of damage rectangles grows two much between repaints,
@@ -509,17 +570,61 @@
509 * the whole screen if we have a lot of damage rects570 * the whole screen if we have a lot of damage rects
510 */571 */
511572
512 if (priv->damage.numRects () > 100)573 if (currentDamage->numRects () > 100)
513 damageScreen ();574 damageScreen ();
514575
515 priv->scheduleRepaint ();576 if (priv->damageRequiresRepaintReschedule)
577 priv->scheduleRepaint ();
578}
579
580void
581CompositeScreen::damageCutoff ()
582{
583 WRAPABLE_HND_FUNCTN (damageCutoff);
516}584}
517585
518void586void
519CompositeScreen::damagePending ()587CompositeScreen::damagePending ()
520{588{
521 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_PENDING_MASK;589 priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_PENDING_MASK;
522 priv->scheduleRepaint ();590
591 if (priv->damageRequiresRepaintReschedule)
592 priv->scheduleRepaint ();
593}
594
595void
596CompositeScreen::applyDamageForFrameAge (unsigned int age)
597{
598 /* Track into "last frame damage" */
599 priv->currentlyTrackingDamage = DamageForLastFrame;
600 damageRegion (priv->roster.damageForFrameAge (age));
601 priv->currentlyTrackingDamage = DamageForCurrentFrame;
602}
603
604unsigned int
605CompositeScreen::getFrameAge ()
606{
607 if (priv->pHnd)
608 return priv->pHnd->getFrameAge ();
609
610 return 1;
611}
612
613void
614CompositeScreen::addOverdrawDamageRegion (const CompRegion &r)
615{
616 priv->ageingBuffers.markAreaDirtyOnLastFrame (r);
617}
618
619typedef CompositeScreen::AreaShouldBeMarkedDirty ShouldMarkDirty;
620
621CompositeScreen::DamageQuery::Ptr
622CompositeScreen::getDamageQuery (const ShouldMarkDirty &callback)
623{
624 /* No initial damage */
625 return bt::FrameRoster::Ptr (new bt::FrameRoster (CompSize (),
626 priv->ageingBuffers,
627 callback));
523}628}
524629
525unsigned int630unsigned int
@@ -758,6 +863,12 @@
758863
759 if (priv->damageMask)864 if (priv->damageMask)
760 {865 {
866 int timeDiff;
867
868 /* Damage that accumulates here does not require a repaint reschedule
869 * as it will end up on this frame */
870 priv->damageRequiresRepaintReschedule = false;
871
761 if (priv->pHnd)872 if (priv->pHnd)
762 priv->pHnd->prepareDrawing ();873 priv->pHnd->prepareDrawing ();
763874
@@ -792,7 +903,7 @@
792 continue;903 continue;
793904
794 if (!CompositeWindow::get (w)->redirected ())905 if (!CompositeWindow::get (w)->redirected ())
795 priv->damage -= w->region ();906 priv->ageingBuffers.subtractObscuredArea (w->region ());
796907
797 break;908 break;
798 }909 }
@@ -804,7 +915,13 @@
804 }915 }
805 }916 }
806917
807 priv->tmpRegion = priv->damage & screen->region ();918 /* All further damage is for the next frame now, as
919 * priv->tmpRegion will be assigned. Notify plugins that do
920 * damage tracking of this */
921 damageCutoff ();
922
923 priv->tmpRegion = (priv->roster.currentFrameDamage () + priv->lastFrameDamage) & screen->region ();
924 priv->currentlyTrackingDamage = DamageFinalPaintRegion;
808925
809 if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK &&926 if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK &&
810 priv->tmpRegion == screen->region ())927 priv->tmpRegion == screen->region ())
@@ -826,7 +943,9 @@
826 XSync (dpy, False);943 XSync (dpy, False);
827 priv->damages.clear ();944 priv->damages.clear ();
828945
829 priv->damage = CompRegion ();946 /* Any more damage requires a repaint reschedule */
947 priv->damageRequiresRepaintReschedule = true;
948 priv->lastFrameDamage = CompRegion ();
830949
831 int mask = priv->damageMask;950 int mask = priv->damageMask;
832 priv->damageMask = 0;951 priv->damageMask = 0;
@@ -844,9 +963,13 @@
844 else963 else
845 outputs.push_back (&screen->fullscreenOutput ());964 outputs.push_back (&screen->fullscreenOutput ());
846965
966 priv->currentlyTrackingDamage = DamageForCurrentFrame;
967
968 /* All new damage goes on the next frame */
969 priv->ageingBuffers.incrementAges ();
970
847 paint (outputs, mask);971 paint (outputs, mask);
848972
849
850 donePaint ();973 donePaint ();
851974
852 priv->outputShapeChanged = false;975 priv->outputShapeChanged = false;
@@ -1003,8 +1126,12 @@
1003CompositeScreenInterface::damageRegion (const CompRegion &r)1126CompositeScreenInterface::damageRegion (const CompRegion &r)
1004 WRAPABLE_DEF (damageRegion, r);1127 WRAPABLE_DEF (damageRegion, r);
10051128
1129void
1130CompositeScreenInterface::damageCutoff ()
1131 WRAPABLE_DEF (damageCutoff);
1132
1006const CompRegion &1133const CompRegion &
1007CompositeScreen::currentDamage () const1134CompositeScreen::currentDamage () const
1008{1135{
1009 return priv->damage;1136 return priv->roster.currentFrameDamage ();
1010}1137}
10111138
=== modified file 'plugins/kdecompat/src/kdecompat.cpp'
--- plugins/kdecompat/src/kdecompat.cpp 2012-08-14 06:33:22 +0000
+++ plugins/kdecompat/src/kdecompat.cpp 2013-04-24 14:57:28 +0000
@@ -196,7 +196,7 @@
196 if ((!(ks->optionGetPlasmaThumbnails () || mPreviews.empty ()) &&196 if ((!(ks->optionGetPlasmaThumbnails () || mPreviews.empty ()) &&
197 !(mSlideData || mSlideData->remaining)) ||197 !(mSlideData || mSlideData->remaining)) ||
198 !window->mapNum () ||198 !window->mapNum () ||
199 (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK))199 (mask & PAINT_WINDOW_NO_DRAW_MASKS))
200 {200 {
201 status = gWindow->glPaint (attrib, transform, region, mask);201 status = gWindow->glPaint (attrib, transform, region, mask);
202 return status;202 return status;
@@ -210,7 +210,7 @@
210 CompRect clipBox (window->x (), window->y (),210 CompRect clipBox (window->x (), window->y (),
211 window->width (), window->height ());211 window->width (), window->height ());
212212
213 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)213 if (mask & PAINT_WINDOW_NO_DRAW_MASKS)
214 return false;214 return false;
215215
216 remainder = (float) data->remaining / data->duration;216 remainder = (float) data->remaining / data->duration;
217217
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2013-01-10 09:23:24 +0000
+++ plugins/opengl/include/opengl/opengl.h 2013-04-24 14:57:28 +0000
@@ -37,6 +37,13 @@
37#else37#else
38#include <GL/gl.h>38#include <GL/gl.h>
39#include <GL/glx.h>39#include <GL/glx.h>
40
41/* Some implementations have not yet given a definition
42 * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined
43 * in the spec (https://www.opengl.org/registry/specs/EXT/glx_buffer_age.txt)
44 */
45#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
46
40#endif47#endif
4148
42#include <core/size.h>49#include <core/size.h>
@@ -50,7 +57,7 @@
50#include <opengl/programcache.h>57#include <opengl/programcache.h>
51#include <opengl/shadercache.h>58#include <opengl/shadercache.h>
5259
53#define COMPIZ_OPENGL_ABI 660#define COMPIZ_OPENGL_ABI 8
5461
55/*62/*
56 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but63 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but
@@ -525,6 +532,7 @@
525 extern bool shaders;532 extern bool shaders;
526 extern bool stencilBuffer;533 extern bool stencilBuffer;
527 extern GLint maxTextureUnits;534 extern GLint maxTextureUnits;
535 extern bool bufferAge;
528536
529 extern bool canDoSaturated;537 extern bool canDoSaturated;
530 extern bool canDoSlightlySaturated;538 extern bool canDoSlightlySaturated;
@@ -663,6 +671,11 @@
663 unsigned int mask);671 unsigned int mask);
664672
665 /**673 /**
674 * Return true if glPaintCompositedOutput is required for this frame
675 */
676 virtual bool glPaintCompositedOutputRequired ();
677
678 /**
666 * Hookable function used by plugins to determine stenciling mask679 * Hookable function used by plugins to determine stenciling mask
667 */680 */
668 virtual void glBufferStencil (const GLMatrix &matrix,681 virtual void glBufferStencil (const GLMatrix &matrix,
@@ -674,7 +687,7 @@
674extern template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>;687extern template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>;
675688
676class GLScreen :689class GLScreen :
677 public WrapableHandler<GLScreenInterface, 8>,690 public WrapableHandler<GLScreenInterface, 9>,
678 public PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>,691 public PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>,
679 public CompOption::Class692 public CompOption::Class
680{693{
@@ -788,7 +801,9 @@
788 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,801 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,
789 const CompRegion &, GLFramebufferObject *, unsigned int);802 const CompRegion &, GLFramebufferObject *, unsigned int);
790803
791 WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &,804 WRAPABLE_HND (7, GLScreenInterface, bool, glPaintCompositedOutputRequired);
805
806 WRAPABLE_HND (8, GLScreenInterface, void, glBufferStencil, const GLMatrix &,
792 GLVertexBuffer &,807 GLVertexBuffer &,
793 CompOutput *);808 CompOutput *);
794809
795810
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2013-01-03 16:05:26 +0000
+++ plugins/opengl/src/paint.cpp 2013-04-24 14:57:28 +0000
@@ -418,11 +418,6 @@
418 if (w->destroyed ())418 if (w->destroyed ())
419 continue;419 continue;
420420
421 gw = GLWindow::get (w);
422
423 /* Release any queued ConfigureWindow requests now */
424 gw->priv->configureLock->release ();
425
426 if (unredirected.find (w) != unredirected.end ())421 if (unredirected.find (w) != unredirected.end ())
427 continue;422 continue;
428423
@@ -432,6 +427,8 @@
432 continue;427 continue;
433 }428 }
434429
430 gw = GLWindow::get (w);
431
435 const CompRegion &clip =432 const CompRegion &clip =
436 (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ?433 (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ?
437 gw->clip () : region;434 gw->clip () : region;
@@ -629,8 +626,8 @@
629 if (mask & PAINT_SCREEN_FULL_MASK)626 if (mask & PAINT_SCREEN_FULL_MASK)
630 {627 {
631 glPaintTransformedOutput (sAttrib, sTransform,628 glPaintTransformedOutput (sAttrib, sTransform,
632 CompRegion (*output), output, mask);629 CompRegionRef (output->region ()), output, mask);
633630 priv->cScreen->addOverdrawDamageRegion (CompRegionRef (output->region ()));
634 return true;631 return true;
635 }632 }
636633
@@ -660,8 +657,9 @@
660 }657 }
661 else if (mask & PAINT_SCREEN_FULL_MASK)658 else if (mask & PAINT_SCREEN_FULL_MASK)
662 {659 {
663 glPaintTransformedOutput (sAttrib, sTransform, CompRegion (*output),660 glPaintTransformedOutput (sAttrib, sTransform, CompRegionRef (output->region ()),
664 output, mask);661 output, mask);
662 priv->cScreen->addOverdrawDamageRegion (CompRegionRef (output->region ()));
665663
666 return true;664 return true;
667 }665 }
@@ -671,6 +669,13 @@
671 }669 }
672}670}
673671
672bool
673GLScreen::glPaintCompositedOutputRequired ()
674{
675 WRAPABLE_HND_FUNCTN_RETURN (bool, glPaintCompositedOutputRequired);
676 return false;
677}
678
674void679void
675GLScreen::glPaintCompositedOutput (const CompRegion &region,680GLScreen::glPaintCompositedOutput (const CompRegion &region,
676 GLFramebufferObject *fbo,681 GLFramebufferObject *fbo,
677682
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2013-01-03 16:05:26 +0000
+++ plugins/opengl/src/privates.h 2013-04-24 14:57:28 +0000
@@ -29,11 +29,13 @@
29#define _OPENGL_PRIVATES_H29#define _OPENGL_PRIVATES_H
3030
31#include <memory>31#include <memory>
32#include <vector>
33#include <tr1/tuple>
34#include <boost/shared_ptr.hpp>
3235
33#include <composite/composite.h>36#include <composite/composite.h>
34#include <opengl/opengl.h>37#include <opengl/opengl.h>
35#include <core/atoms.h>38#include <core/atoms.h>
36#include <core/configurerequestbuffer.h>
3739
38#ifdef USE_GLES40#ifdef USE_GLES
39#include <opengl/framebufferobject.h>41#include <opengl/framebufferobject.h>
@@ -120,8 +122,26 @@
120 GLTexture::List textures;122 GLTexture::List textures;
121};123};
122124
125class FrameProvider
126{
127 public:
128
129 typedef boost::shared_ptr <FrameProvider> Ptr;
130 typedef std::tr1::tuple <GLFramebufferObject *, int> Frame;
131
132 virtual ~FrameProvider () {}
133
134 virtual GLuint getCurrentFrame () = 0;
135 virtual void endFrame () = 0;
136
137 virtual bool providesPersistence () = 0;
138 virtual bool alwaysPostprocess () = 0;
139 virtual void invalidateAll () = 0;
140};
141
123class PrivateGLScreen :142class PrivateGLScreen :
124 public ScreenInterface,143 public ScreenInterface,
144 public CompositeScreenInterface,
125 public compiz::composite::PaintHandler,145 public compiz::composite::PaintHandler,
126 public OpenglOptions146 public OpenglOptions
127{147{
@@ -142,12 +162,17 @@
142 bool hasVSync ();162 bool hasVSync ();
143 bool requiredForcedRefreshRate ();163 bool requiredForcedRefreshRate ();
144164
165 unsigned int getFrameAge ();
166
145 void updateRenderMode ();167 void updateRenderMode ();
168 void updateFrameProvider ();
146169
147 void prepareDrawing ();170 void prepareDrawing ();
148171
149 bool compositingActive ();172 bool compositingActive ();
150173
174 void damageCutoff ();
175
151 void paintBackground (const GLMatrix &transform,176 void paintBackground (const GLMatrix &transform,
152 const CompRegion &region,177 const CompRegion &region,
153 bool transformed);178 bool transformed);
@@ -163,6 +188,8 @@
163188
164 bool driverIsBlacklisted (const char *regex) const;189 bool driverIsBlacklisted (const char *regex) const;
165190
191 bool postprocessRequiredForCurrentFrame ();
192
166 public:193 public:
167194
168 GLScreen *gScreen;195 GLScreen *gScreen;
@@ -197,7 +224,7 @@
197 GLXDoubleBuffer doubleBuffer;224 GLXDoubleBuffer doubleBuffer;
198 #endif225 #endif
199226
200 GLFramebufferObject *scratchFbo;227 boost::shared_ptr <GLFramebufferObject> scratchFbo;
201 CompRegion outputRegion;228 CompRegion outputRegion;
202229
203 XRectangle lastViewport;230 XRectangle lastViewport;
@@ -222,8 +249,10 @@
222 Pixmap rootPixmapCopy;249 Pixmap rootPixmapCopy;
223 CompSize rootPixmapSize;250 CompSize rootPixmapSize;
224251
252 FrameProvider::Ptr frameProvider;
225 const char *glVendor, *glRenderer, *glVersion;253 const char *glVendor, *glRenderer, *glVersion;
226254
255 bool postprocessingRequired;
227 mutable CompString prevRegex;256 mutable CompString prevRegex;
228 mutable bool prevBlacklisted;257 mutable bool prevBlacklisted;
229};258};
@@ -284,8 +313,6 @@
284 GLVertexBuffer::AutoProgram *autoProgram;313 GLVertexBuffer::AutoProgram *autoProgram;
285314
286 std::list<GLIcon> icons;315 std::list<GLIcon> icons;
287
288 compiz::window::configure_buffers::Releasable::Ptr configureLock;
289};316};
290317
291#endif318#endif
292319
=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2013-01-09 10:57:03 +0000
+++ plugins/opengl/src/screen.cpp 2013-04-24 14:57:28 +0000
@@ -186,6 +186,7 @@
186 bool vboEnabled = false;186 bool vboEnabled = false;
187 bool shaders = false;187 bool shaders = false;
188 GLint maxTextureUnits = 1;188 GLint maxTextureUnits = 1;
189 bool bufferAge = false;
189190
190 bool canDoSaturated = false;191 bool canDoSaturated = false;
191 bool canDoSlightlySaturated = false;192 bool canDoSlightlySaturated = false;
@@ -301,6 +302,52 @@
301302
302#ifndef USE_GLES303#ifndef USE_GLES
303304
305class BufferAgeFrameProvider :
306 public FrameProvider
307{
308 public:
309
310 BufferAgeFrameProvider (Display *disp,
311 GLXDrawable drawable) :
312 mDisplay (disp),
313 mDrawable (drawable)
314 {
315 }
316
317 unsigned int getCurrentFrame ()
318 {
319 unsigned int age = 0;
320 (*GL::queryDrawable) (mDisplay,
321 mDrawable,
322 GLX_BACK_BUFFER_AGE_EXT,
323 &age);
324 return age;
325 }
326
327 void endFrame ()
328 {
329 }
330
331 void invalidateAll ()
332 {
333 }
334
335 bool providesPersistence ()
336 {
337 return true;
338 }
339
340 bool alwaysPostprocess ()
341 {
342 return false;
343 }
344
345 private:
346
347 Display *mDisplay;
348 GLXDrawable mDrawable;
349};
350
304namespace compiz351namespace compiz
305{352{
306namespace opengl353namespace opengl
@@ -358,6 +405,137 @@
358405
359#endif406#endif
360407
408class UndefinedFrameProvider :
409 public FrameProvider
410{
411 public:
412
413 unsigned int getCurrentFrame ()
414 {
415 return 0;
416 }
417
418 void endFrame ()
419 {
420 }
421
422 void invalidateAll ()
423 {
424 }
425
426 bool providesPersistence ()
427 {
428 return false;
429 }
430
431 bool alwaysPostprocess ()
432 {
433 return false;
434 }
435};
436
437class PostprocessFrameProvider :
438 public FrameProvider
439{
440 public:
441
442 PostprocessFrameProvider (GLFramebufferObject *object) :
443 mObject (object),
444 mAge (0)
445 {
446 }
447
448 unsigned int getCurrentFrame ()
449 {
450 /* We are now using this buffer, reset
451 * age back to zero */
452 unsigned int lastAge = mAge;
453 mAge = 0;
454
455 return lastAge;
456 }
457
458 void endFrame ()
459 {
460 ++mAge;
461 }
462
463 void invalidateAll ()
464 {
465 mAge = 0;
466 }
467
468 bool providesPersistence ()
469 {
470 return true;
471 }
472
473 bool alwaysPostprocess ()
474 {
475 return true;
476 }
477
478 private:
479
480 GLFramebufferObject *mObject;
481 unsigned int mAge;
482};
483
484class OptionalPostprocessFrameProvider :
485 public FrameProvider
486{
487 public:
488
489 typedef boost::function <bool ()> PostprocessRequired;
490
491 OptionalPostprocessFrameProvider (const FrameProvider::Ptr &backbuffer,
492 const FrameProvider::Ptr &scratchbuffer,
493 const PostprocessRequired &ppRequired) :
494 mBackbuffer (backbuffer),
495 mScratchbuffer (scratchbuffer),
496 mPPRequired (ppRequired)
497 {
498 }
499
500 unsigned int getCurrentFrame ()
501 {
502 if (mPPRequired ())
503 return mScratchbuffer->getCurrentFrame ();
504 else
505 return mBackbuffer->getCurrentFrame ();
506 }
507
508 void endFrame ()
509 {
510 mScratchbuffer->endFrame ();
511 }
512
513 void invalidateAll ()
514 {
515 mScratchbuffer->invalidateAll ();
516 }
517
518 bool providesPersistence ()
519 {
520 /* We are only as good as the backbuffer is */
521 return mBackbuffer->providesPersistence ();
522 }
523
524 bool alwaysPostprocess ()
525 {
526 if (mPPRequired ())
527 return mScratchbuffer->alwaysPostprocess ();
528 else
529 return mBackbuffer->alwaysPostprocess ();
530 }
531
532 private:
533
534 FrameProvider::Ptr mBackbuffer;
535 FrameProvider::Ptr mScratchbuffer;
536 PostprocessRequired mPPRequired;
537};
538
361bool539bool
362GLScreen::glInitContext (XVisualInfo *visinfo)540GLScreen::glInitContext (XVisualInfo *visinfo)
363{541{
@@ -593,6 +771,8 @@
593771
594 priv->incorrectRefreshRate = false;772 priv->incorrectRefreshRate = false;
595773
774 priv->frameProvider.reset (new PostprocessFrameProvider ());
775
596 #else776 #else
597777
598 Display *dpy = screen->dpy ();778 Display *dpy = screen->dpy ();
@@ -899,12 +1079,17 @@
8991079
900 if (GL::fboSupported)1080 if (GL::fboSupported)
901 {1081 {
902 priv->scratchFbo = new GLFramebufferObject;1082 priv->scratchFbo.reset (new GLFramebufferObject ());
903 priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);1083 priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);
904 }1084 }
9051085
906 GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram);1086 GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram);
9071087
1088 /* We need scratchFbo to be set before doing this, and it is common
1089 * to both the GLES and non-GLES codepaths, so using another #ifdef
1090 */
1091 priv->updateFrameProvider ();
1092
908 return true;1093 return true;
909}1094}
9101095
@@ -993,6 +1178,13 @@
993 return;1178 return;
994 }1179 }
9951180
1181 if (strstr (glxExtensions, "GLX_EXT_buffer_age"))
1182 {
1183 compLogMessage ("opengl", CompLogLevelInfo,
1184 "GLX_EXT_buffer_age is supported");
1185 GL::bufferAge = true;
1186 }
1187
996 priv->getProcAddress = (GL::GLXGetProcAddressProc)1188 priv->getProcAddress = (GL::GLXGetProcAddressProc)
997 getProcAddress ("glXGetProcAddressARB");1189 getProcAddress ("glXGetProcAddressARB");
998 GL::bindTexImage = (GL::GLXBindTexImageProc)1190 GL::bindTexImage = (GL::GLXBindTexImageProc)
@@ -1209,9 +1401,6 @@
1209 glXDestroyContext (screen->dpy (), priv->ctx);1401 glXDestroyContext (screen->dpy (), priv->ctx);
1210 #endif1402 #endif
12111403
1212 if (priv->scratchFbo)
1213 delete priv->scratchFbo;
1214
1215 delete priv;1404 delete priv;
1216}1405}
12171406
@@ -1233,7 +1422,7 @@
1233 ctx (EGL_NO_CONTEXT),1422 ctx (EGL_NO_CONTEXT),
1234 doubleBuffer (screen->dpy (), *screen, surface),1423 doubleBuffer (screen->dpy (), *screen, surface),
1235 #endif1424 #endif
1236 scratchFbo (NULL),1425 scratchFbo (),
1237 outputRegion (),1426 outputRegion (),
1238 refreshSubBuffer (false),1427 refreshSubBuffer (false),
1239 lastMask (0),1428 lastMask (0),
@@ -1246,13 +1435,16 @@
1246 autoProgram (new GLScreenAutoProgram(gs)),1435 autoProgram (new GLScreenAutoProgram(gs)),
1247 rootPixmapCopy (None),1436 rootPixmapCopy (None),
1248 rootPixmapSize (),1437 rootPixmapSize (),
1438 frameProvider (),
1249 glVendor (NULL),1439 glVendor (NULL),
1250 glRenderer (NULL),1440 glRenderer (NULL),
1251 glVersion (NULL),1441 glVersion (NULL),
1442 postprocessingRequired (false),
1252 prevRegex (),1443 prevRegex (),
1253 prevBlacklisted (false)1444 prevBlacklisted (false)
1254{1445{
1255 ScreenInterface::setHandler (screen);1446 ScreenInterface::setHandler (screen);
1447 CompositeScreenInterface::setHandler (cScreen);
1256}1448}
12571449
1258PrivateGLScreen::~PrivateGLScreen ()1450PrivateGLScreen::~PrivateGLScreen ()
@@ -1443,8 +1635,11 @@
1443{1635{
1444 screen->outputChangeNotify ();1636 screen->outputChangeNotify ();
14451637
1638 frameProvider->invalidateAll ();
1639
1446 if (scratchFbo)1640 if (scratchFbo)
1447 scratchFbo->allocate (*screen, NULL, GL_BGRA);1641 scratchFbo->allocate (*screen, NULL, GL_BGRA);
1642
1448 updateView ();1643 updateView ();
1449}1644}
14501645
@@ -1669,6 +1864,10 @@
1669GLScreenInterface::projectionMatrix ()1864GLScreenInterface::projectionMatrix ()
1670 WRAPABLE_DEF (projectionMatrix)1865 WRAPABLE_DEF (projectionMatrix)
16711866
1867bool
1868GLScreenInterface::glPaintCompositedOutputRequired ()
1869 WRAPABLE_DEF (glPaintCompositedOutputRequired)
1870
1672void1871void
1673GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,1872GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,
1674 GLFramebufferObject *fbo,1873 GLFramebufferObject *fbo,
@@ -1977,18 +2176,6 @@
1977 glDepthMask (GL_FALSE);2176 glDepthMask (GL_FALSE);
1978 glStencilMask (0);2177 glStencilMask (0);
19792178
1980 GLFramebufferObject *oldFbo = NULL;
1981 bool useFbo = false;
1982
1983 /* Clear the color buffer where appropriate */
1984 if (GL::fboEnabled && scratchFbo)
1985 {
1986 oldFbo = scratchFbo->bind ();
1987 useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
1988 if (!useFbo)
1989 GLFramebufferObject::rebind (oldFbo);
1990 }
1991
1992#ifdef UNSAFE_ARM_SGX_FIXME2179#ifdef UNSAFE_ARM_SGX_FIXME
1993 refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&2180 refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
1994 !(mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&2181 !(mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
@@ -2006,8 +2193,21 @@
2006 }2193 }
2007#endif2194#endif
20082195
2009 CompRegion tmpRegion = (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) ?2196 CompRegion paintRegion ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) ?
2010 screen->region () : region;2197 screen->region () : region);
2198 bool useFbo = false;
2199 GLFramebufferObject *oldFbo = NULL;
2200
2201 postprocessingRequired = gScreen->glPaintCompositedOutputRequired ();
2202 postprocessingRequired |= frameProvider->alwaysPostprocess ();
2203
2204 /* Clear the color buffer where appropriate */
2205 if ((GL::fboEnabled && postprocessRequiredForCurrentFrame ()))
2206 {
2207 oldFbo = scratchFbo->bind ();
2208 if (scratchFbo->checkStatus ())
2209 useFbo = true;
2210 }
20112211
2012 foreach (CompOutput *output, outputs)2212 foreach (CompOutput *output, outputs)
2013 {2213 {
@@ -2034,7 +2234,8 @@
20342234
2035 gScreen->glPaintOutput (defaultScreenPaintAttrib,2235 gScreen->glPaintOutput (defaultScreenPaintAttrib,
2036 identity,2236 identity,
2037 CompRegion (*output), output,2237 CompRegion (*output),
2238 output,
2038 PAINT_SCREEN_REGION_MASK |2239 PAINT_SCREEN_REGION_MASK |
2039 PAINT_SCREEN_FULL_MASK);2240 PAINT_SCREEN_FULL_MASK);
2040 }2241 }
@@ -2057,7 +2258,9 @@
2057 tmpRegion = CompRegion (*output);2258 tmpRegion = CompRegion (*output);
2058#endif2259#endif
20592260
2060 outputRegion = tmpRegion & CompRegion (*output);2261 /* Clip current paint region to output extents */
2262 CompRegionRef wholeOutput (output->region ());
2263 outputRegion = (paintRegion & wholeOutput);
20612264
2062 if (!gScreen->glPaintOutput (defaultScreenPaintAttrib,2265 if (!gScreen->glPaintOutput (defaultScreenPaintAttrib,
2063 identity,2266 identity,
@@ -2068,10 +2271,11 @@
20682271
2069 gScreen->glPaintOutput (defaultScreenPaintAttrib,2272 gScreen->glPaintOutput (defaultScreenPaintAttrib,
2070 identity,2273 identity,
2071 CompRegion (*output), output,2274 wholeOutput, output,
2072 PAINT_SCREEN_FULL_MASK);2275 PAINT_SCREEN_FULL_MASK);
20732276
2074 tmpRegion += *output;2277 paintRegion += wholeOutput;
2278 cScreen->addOverdrawDamageRegion (wholeOutput);
2075 }2279 }
2076 }2280 }
2077 }2281 }
@@ -2082,13 +2286,18 @@
20822286
2083 if (useFbo)2287 if (useFbo)
2084 {2288 {
2085 GLFramebufferObject::rebind (oldFbo);
2086
2087 // FIXME: does not work if screen dimensions exceed max texture size2289 // FIXME: does not work if screen dimensions exceed max texture size
2088 // We should try to use glBlitFramebuffer instead.2290 // We should try to use glBlitFramebuffer instead.
2089 gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask);2291 GLFramebufferObject::rebind (oldFbo);
2292 /* If we must always postprocess, then we don't have any
2293 * "real" backbuffer persistence, redraw the whole thing */
2294 gScreen->glPaintCompositedOutput (frameProvider->alwaysPostprocess () ?
2295 screen->region () :
2296 paintRegion, scratchFbo.get (), mask);
2090 }2297 }
20912298
2299 frameProvider->endFrame ();
2300
2092 if (cScreen->outputWindowChanged ())2301 if (cScreen->outputWindowChanged ())
2093 {2302 {
2094 /*2303 /*
@@ -2100,20 +2309,27 @@
2100 return;2309 return;
2101 }2310 }
21022311
2312 bool persistence = frameProvider->providesPersistence ();
2103 bool alwaysSwap = optionGetAlwaysSwapBuffers ();2313 bool alwaysSwap = optionGetAlwaysSwapBuffers ();
2104 bool fullscreen = useFbo ||2314 bool fullscreen = persistence ||
2105 alwaysSwap ||2315 alwaysSwap ||
2106 ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&2316 ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
2107 commonFrontbuffer);2317 commonFrontbuffer);
21082318
2109 doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ());2319 doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ());
2110 doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, useFbo);2320 doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, persistence);
2111 doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap);2321 doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap);
2112 doubleBuffer.render (tmpRegion, fullscreen);2322 doubleBuffer.render (paintRegion, fullscreen);
21132323
2114 lastMask = mask;2324 lastMask = mask;
2115}2325}
21162326
2327unsigned int
2328PrivateGLScreen::getFrameAge ()
2329{
2330 return frameProvider->getCurrentFrame ();
2331}
2332
2117bool2333bool
2118PrivateGLScreen::hasVSync ()2334PrivateGLScreen::hasVSync ()
2119{2335{
@@ -2138,6 +2354,13 @@
2138}2354}
21392355
2140void2356void
2357PrivateGLScreen::damageCutoff ()
2358{
2359 cScreen->applyDamageForFrameAge (frameProvider->getCurrentFrame ());
2360 cScreen->damageCutoff ();
2361}
2362
2363void
2141PrivateGLScreen::updateRenderMode ()2364PrivateGLScreen::updateRenderMode ()
2142{2365{
2143#ifndef USE_GLES2366#ifndef USE_GLES
@@ -2147,12 +2370,54 @@
2147}2370}
21482371
2149void2372void
2373PrivateGLScreen::updateFrameProvider ()
2374{
2375#ifndef USE_GLES
2376 const Window outputWindow = CompositeScreen::get (screen)->output ();
2377
2378 if (GL::fboEnabled)
2379 {
2380 if (GL::bufferAge)
2381 {
2382 FrameProvider::Ptr back (new BufferAgeFrameProvider (screen->dpy (),
2383 outputWindow));
2384 FrameProvider::Ptr scratch (new PostprocessFrameProvider (scratchFbo.get ()));
2385 OptionalPostprocessFrameProvider::PostprocessRequired ppReq
2386 (boost::bind (&PrivateGLScreen::postprocessRequiredForCurrentFrame,
2387 this));
2388 frameProvider.reset (new OptionalPostprocessFrameProvider (back,
2389 scratch,
2390 ppReq));
2391 }
2392 else
2393 {
2394 /* Prefer using FBO's instead of switching between a defined/undefined backbuffer */
2395 frameProvider.reset (new PostprocessFrameProvider (scratchFbo.get ()));
2396 }
2397 }
2398 else
2399 {
2400 if (GL::bufferAge)
2401 frameProvider.reset (new BufferAgeFrameProvider (screen->dpy (),
2402 outputWindow));
2403 else
2404 frameProvider.reset (new UndefinedFrameProvider ());
2405 }
2406#else
2407 frameProvider.reset (new PostprocessFrameProvider (scratchFbo.get ()));
2408#endif
2409}
2410
2411void
2150PrivateGLScreen::prepareDrawing ()2412PrivateGLScreen::prepareDrawing ()
2151{2413{
2152 bool wasFboEnabled = GL::fboEnabled;2414 bool wasFboEnabled = GL::fboEnabled;
2153 updateRenderMode ();2415 updateRenderMode ();
2154 if (wasFboEnabled != GL::fboEnabled)2416 if (wasFboEnabled != GL::fboEnabled)
2417 {
2418 updateFrameProvider ();
2155 CompositeScreen::get (screen)->damageScreen ();2419 CompositeScreen::get (screen)->damageScreen ();
2420 }
2156}2421}
21572422
2158bool2423bool
@@ -2170,6 +2435,12 @@
2170 return prevBlacklisted;2435 return prevBlacklisted;
2171}2436}
21722437
2438bool
2439PrivateGLScreen::postprocessRequiredForCurrentFrame ()
2440{
2441 return postprocessingRequired;
2442}
2443
2173GLTexture::BindPixmapHandle2444GLTexture::BindPixmapHandle
2174GLScreen::registerBindPixmap (GLTexture::BindPixmapProc proc)2445GLScreen::registerBindPixmap (GLTexture::BindPixmapProc proc)
2175{2446{
@@ -2198,7 +2469,7 @@
2198GLFramebufferObject *2469GLFramebufferObject *
2199GLScreen::fbo ()2470GLScreen::fbo ()
2200{2471{
2201 return priv->scratchFbo;2472 return priv->scratchFbo.get ();
2202}2473}
22032474
2204GLTexture *2475GLTexture *
22052476
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2013-01-03 16:05:26 +0000
+++ plugins/opengl/src/window.cpp 2013-04-24 14:57:28 +0000
@@ -86,8 +86,7 @@
86 bindFailed (false),86 bindFailed (false),
87 vertexBuffer (new GLVertexBuffer ()),87 vertexBuffer (new GLVertexBuffer ()),
88 autoProgram(new GLWindowAutoProgram(this)),88 autoProgram(new GLWindowAutoProgram(this)),
89 icons (),89 icons ()
90 configureLock (w->obtainLockOnConfigureRequests ())
91{90{
92 paint.xScale = 1.0f;91 paint.xScale = 1.0f;
93 paint.yScale = 1.0f;92 paint.yScale = 1.0f;
9493
=== modified file 'plugins/place/src/place.cpp'
--- plugins/place/src/place.cpp 2013-04-10 12:27:25 +0000
+++ plugins/place/src/place.cpp 2013-04-24 14:57:28 +0000
@@ -565,7 +565,7 @@
565 }565 }
566566
567 switch (mode) {567 switch (mode) {
568 case PlaceOptions::ModeCascade:568 case PlaceOptions::ModeCascade:
569 placeCascade (workArea, pos);569 placeCascade (workArea, pos);
570 break;570 break;
571 case PlaceOptions::ModeCentered:571 case PlaceOptions::ModeCentered:
@@ -1150,7 +1150,6 @@
1150 window->border (),1150 window->border (),
1151 workArea,1151 workArea,
1152 staticGravity);1152 staticGravity);
1153
1154}1153}
11551154
1156bool1155bool
11571156
=== modified file 'plugins/resize/src/resize.cpp'
--- plugins/resize/src/resize.cpp 2012-10-19 09:23:11 +0000
+++ plugins/resize/src/resize.cpp 2013-04-24 14:57:28 +0000
@@ -257,7 +257,7 @@
257 float xScale, yScale;257 float xScale, yScale;
258 int x, y;258 int x, y;
259259
260 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)260 if (mask & PAINT_WINDOW_NO_DRAW_MASKS)
261 return false;261 return false;
262262
263 status = gWindow->glPaint (attrib, transform, region,263 status = gWindow->glPaint (attrib, transform, region,
264264
=== modified file 'plugins/ring/src/ring.cpp'
--- plugins/ring/src/ring.cpp 2013-01-19 11:47:22 +0000
+++ plugins/ring/src/ring.cpp 2013-04-24 14:57:28 +0000
@@ -264,7 +264,7 @@
264 GLWindowPaintAttrib wAttrib (gWindow->lastPaintAttrib ());264 GLWindowPaintAttrib wAttrib (gWindow->lastPaintAttrib ());
265 GLMatrix wTransform = transform;265 GLMatrix wTransform = transform;
266266
267 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)267 if (mask & PAINT_WINDOW_NO_DRAW_MASKS)
268 return false;268 return false;
269269
270 if (mSlot)270 if (mSlot)
271271
=== modified file 'plugins/scale/src/scale.cpp'
--- plugins/scale/src/scale.cpp 2013-01-29 23:16:32 +0000
+++ plugins/scale/src/scale.cpp 2013-04-24 14:57:28 +0000
@@ -384,12 +384,14 @@
384384
385 status = gWindow->glPaint (sAttrib, transform, region, mask);385 status = gWindow->glPaint (sAttrib, transform, region, mask);
386386
387 mask &= ~(PAINT_WINDOW_NO_CORE_INSTANCE_MASK);
388
387 if (scaled)389 if (scaled)
388 {390 {
389 GLWindowPaintAttrib lastAttrib (gWindow->lastPaintAttrib ());391 GLWindowPaintAttrib lastAttrib (gWindow->lastPaintAttrib ());
390 GLMatrix wTransform (transform);392 GLMatrix wTransform (transform);
391393
392 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)394 if (mask & PAINT_WINDOW_NO_DRAW_MASKS)
393 return false;395 return false;
394396
395 if (window->alpha () || lastAttrib.opacity != OPAQUE)397 if (window->alpha () || lastAttrib.opacity != OPAQUE)
396398
=== modified file 'plugins/staticswitcher/src/staticswitcher.cpp'
--- plugins/staticswitcher/src/staticswitcher.cpp 2012-12-10 03:28:47 +0000
+++ plugins/staticswitcher/src/staticswitcher.cpp 2013-04-24 14:57:28 +0000
@@ -1246,7 +1246,7 @@
12461246
1247 const CompWindow::Geometry &g = window->geometry ();1247 const CompWindow::Geometry &g = window->geometry ();
12481248
1249 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK ||1249 if (mask & PAINT_WINDOW_NO_DRAW_MASKS ||
1250 sScreen->ignoreSwitcher)1250 sScreen->ignoreSwitcher)
1251 return false;1251 return false;
12521252
12531253
=== modified file 'plugins/switcher/src/switcher.cpp'
--- plugins/switcher/src/switcher.cpp 2012-12-10 03:28:47 +0000
+++ plugins/switcher/src/switcher.cpp 2013-04-24 14:57:28 +0000
@@ -971,7 +971,7 @@
971971
972 const CompWindow::Geometry &g = window->geometry ();972 const CompWindow::Geometry &g = window->geometry ();
973973
974 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK ||974 if (mask & PAINT_WINDOW_NO_DRAW_MASKS ||
975 sScreen->ignoreSwitcher)975 sScreen->ignoreSwitcher)
976 return false;976 return false;
977977
978978
=== modified file 'plugins/td/src/3d.cpp'
--- plugins/td/src/3d.cpp 2013-02-03 17:50:59 +0000
+++ plugins/td/src/3d.cpp 2013-04-24 14:57:28 +0000
@@ -163,7 +163,7 @@
163 glGetIntegerv (GL_CULL_FACE_MODE, &cull);163 glGetIntegerv (GL_CULL_FACE_MODE, &cull);
164 cullInv = (cull == GL_BACK)? GL_FRONT : GL_BACK;164 cullInv = (cull == GL_BACK)? GL_FRONT : GL_BACK;
165165
166 if (ww && wh && !(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) &&166 if (ww && wh && !(mask & PAINT_WINDOW_NO_DRAW_MASKS) &&
167 ((cs->paintOrder () == FTB && mFtb) ||167 ((cs->paintOrder () == FTB && mFtb) ||
168 (cs->paintOrder () == BTF && !mFtb)))168 (cs->paintOrder () == BTF && !mFtb)))
169 {169 {
170170
=== modified file 'plugins/water/src/water.cpp'
--- plugins/water/src/water.cpp 2013-01-28 19:45:04 +0000
+++ plugins/water/src/water.cpp 2013-04-24 14:57:28 +0000
@@ -317,6 +317,12 @@
317 }317 }
318}318}
319319
320bool
321WaterScreen::glPaintCompositedOutputRequired ()
322{
323 return true;
324}
325
320void326void
321WaterScreen::glPaintCompositedOutput (const CompRegion &region,327WaterScreen::glPaintCompositedOutput (const CompRegion &region,
322 GLFramebufferObject *fbo,328 GLFramebufferObject *fbo,
@@ -467,6 +473,7 @@
467 cScreen->preparePaintSetEnabled (this, false);473 cScreen->preparePaintSetEnabled (this, false);
468 gScreen->glPaintOutputSetEnabled (this, false);474 gScreen->glPaintOutputSetEnabled (this, false);
469 gScreen->glPaintCompositedOutputSetEnabled (this, false);475 gScreen->glPaintCompositedOutputSetEnabled (this, false);
476 gScreen->glPaintCompositedOutputRequiredSetEnabled (this, false);
470 cScreen->donePaintSetEnabled (this, false);477 cScreen->donePaintSetEnabled (this, false);
471 }478 }
472479
473480
=== modified file 'plugins/water/src/water.h'
--- plugins/water/src/water.h 2012-09-07 23:56:21 +0000
+++ plugins/water/src/water.h 2013-04-24 14:57:28 +0000
@@ -64,6 +64,7 @@
6464
65 void handleEvent (XEvent *);65 void handleEvent (XEvent *);
6666
67 bool glPaintCompositedOutputRequired ();
67 void glPaintCompositedOutput (const CompRegion &region,68 void glPaintCompositedOutput (const CompRegion &region,
68 GLFramebufferObject *fbo,69 GLFramebufferObject *fbo,
69 unsigned int mask);70 unsigned int mask);
7071
=== modified file 'src/window.cpp'
--- src/window.cpp 2013-03-27 01:55:26 +0000
+++ src/window.cpp 2013-04-24 14:57:28 +0000
@@ -3222,7 +3222,7 @@
3222 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)3222 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3223 frameValueMask &= ~(CWY);3223 frameValueMask &= ~(CWY);
32243224
3225 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 23225 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3226 + serverInput.left + serverInput.right)3226 + serverInput.left + serverInput.right)
3227 frameValueMask &= ~(CWWidth);3227 frameValueMask &= ~(CWWidth);
32283228
@@ -6922,7 +6922,7 @@
6922 * but that's all */6922 * but that's all */
6923 XSelectInput (dpy, screen->root (), SubstructureNotifyMask);6923 XSelectInput (dpy, screen->root (), SubstructureNotifyMask);
69246924
6925 /* Gravity here is assumed to be SouthEast, clients can update6925 /* Gravity here is assumed to be NorthWest, clients can update
6926 * that if need be */6926 * that if need be */
69276927
6928 /* Awaiting a new frame to be given to us */6928 /* Awaiting a new frame to be given to us */

Subscribers

People subscribed via source and target branches

to all changes: