Mir

Merge lp:~vanvugt/mir/occlude into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1146
Proposed branch: lp:~vanvugt/mir/occlude
Merge into: lp:mir
Prerequisite: lp:~vanvugt/mir/reverse-scene-traversal
Diff against target: 523 lines (+400/-10)
7 files modified
src/server/compositor/CMakeLists.txt (+1/-0)
src/server/compositor/default_display_buffer_compositor.cpp (+15/-4)
src/server/compositor/occlusion.cpp (+86/-0)
src/server/compositor/occlusion.h (+61/-0)
tests/unit-tests/compositor/CMakeLists.txt (+1/-0)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+73/-6)
tests/unit-tests/compositor/test_occlusion.cpp (+163/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/occlude
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Alan Griffiths Approve
Alexandros Frantzis (community) Approve
Review via email: mp+191157@code.launchpad.net

Commit message

Avoid rendering surfaces that are fully hidden by other surfaces. This is
particularly important for mobile device performance. (LP: #1227739)

Description of the change

Technically the region searching algorithm used here is not proper region searching. We only look for rectangles fully enclosed by other rectangles. However what we have here is faster and simpler than arbitrary region calculations, and will still solve 99% of the important cases (touch apps). I also think it's a good thing to avoid complex region calculations for as long as possible.

Also note, for this to work, we need clients to create properly opaque surfaces using pixel format RGBX/XRGB etc. Any surface with an alpha channel will potentially be arbitrary in shape and translucency so cannot be considered as an occlusion.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I just realized, this doesn't help Nexus 4. Mako only supports one pixel format: ABGR, meaning occlusion detection can never be used.

So to fix for N4 we need to do one of:
  (a) Introduce a dummy XBGR mode which is actually implemented as ABGR; or
  (b) Expose more pixel formats, because surely the hardware has a non-alpha mode; or
  (c) Remove the "shape" detection part of occlusion detection (though that's likely to completely break the current Unity8 shell); or
  (d) Implement an entirely new fix for bug 1227739 in Unity8 itself (?)

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Nits:

183 +#include "glm/glm.hpp"

Not needed.

216 + * This is realible, but not ideal -- using the criteria address as a

Typo?

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> So to fix for N4 we need to do one of:
> (a) Introduce a dummy XBGR mode which is actually implemented as ABGR; or
> (b) Expose more pixel formats, because surely the hardware has a non-alpha
> mode;

My vote goes to (b) if possible. It's useful to have non-alpha format in general, anyway.

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

Nits fixed. Pretend I never mentioned Nexus 4. That's a separate problem for another day, which doesn't have to be solved here.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

OK for now. Hopefully we will be able to handle occlusion more elegantly (i.e. no filter/match interplay) in our rework our scengraph/surfaces/model infrastructure.

> Pretend I never mentioned Nexus 4. That's a separate problem for another day, which doesn't have to be solved here.

I didn't expect it to :)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

But apart from merge conflicts seems reasonable

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> But apart from merge conflicts seems reasonable

Actually, this probably doesn't need fixing as the jenkins bot doesn't see it.

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

lgtm

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

That's weird. The conflict never showed up locally for me. But apparently gone now anyway.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

The failure is unrelated to the proposal. See bug 1227683.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/server/compositor/CMakeLists.txt'
--- src/server/compositor/CMakeLists.txt 2013-10-02 07:02:18 +0000
+++ src/server/compositor/CMakeLists.txt 2013-10-17 05:56:50 +0000
@@ -12,6 +12,7 @@
12 multi_threaded_compositor.cpp12 multi_threaded_compositor.cpp
13 switching_bundle.cpp13 switching_bundle.cpp
14 bypass.cpp14 bypass.cpp
15 occlusion.cpp
15)16)
1617
17ADD_LIBRARY(18ADD_LIBRARY(
1819
=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
--- src/server/compositor/default_display_buffer_compositor.cpp 2013-10-03 03:57:28 +0000
+++ src/server/compositor/default_display_buffer_compositor.cpp 2013-10-17 05:56:50 +0000
@@ -26,6 +26,7 @@
26#include "mir/graphics/buffer.h"26#include "mir/graphics/buffer.h"
27#include "mir/surfaces/buffer_stream.h"27#include "mir/surfaces/buffer_stream.h"
28#include "bypass.h"28#include "bypass.h"
29#include "occlusion.h"
29#include <mutex>30#include <mutex>
30#include <cstdlib>31#include <cstdlib>
31#include <vector>32#include <vector>
@@ -38,16 +39,21 @@
3839
39struct FilterForVisibleSceneInRegion : public mc::FilterForScene40struct FilterForVisibleSceneInRegion : public mc::FilterForScene
40{41{
41 FilterForVisibleSceneInRegion(mir::geometry::Rectangle const& enclosing_region)42 FilterForVisibleSceneInRegion(
42 : enclosing_region(enclosing_region)43 mir::geometry::Rectangle const& enclosing_region,
44 mc::OcclusionMatch const& occlusions)
45 : enclosing_region(enclosing_region),
46 occlusions(occlusions)
43 {47 {
44 }48 }
45 bool operator()(mc::CompositingCriteria const& info)49 bool operator()(mc::CompositingCriteria const& info)
46 {50 {
47 return info.should_be_rendered_in(enclosing_region);51 return info.should_be_rendered_in(enclosing_region) &&
52 !occlusions.occluded(info);
48 }53 }
4954
50 mir::geometry::Rectangle const& enclosing_region;55 mir::geometry::Rectangle const& enclosing_region;
56 mc::OcclusionMatch const& occlusions;
51};57};
5258
53std::mutex global_frameno_lock;59std::mutex global_frameno_lock;
@@ -127,9 +133,14 @@
127 display_buffer.make_current();133 display_buffer.make_current();
128134
129 auto const& view_area = display_buffer.view_area();135 auto const& view_area = display_buffer.view_area();
136
137 mc::OcclusionFilter occlusion_search(view_area);
138 mc::OcclusionMatch occlusion_match;
139 scene->reverse_for_each_if(occlusion_search, occlusion_match);
140
130 renderer->clear(local_frameno);141 renderer->clear(local_frameno);
131 mc::RenderingOperator applicator(*renderer, save_resource);142 mc::RenderingOperator applicator(*renderer, save_resource);
132 FilterForVisibleSceneInRegion selector(view_area);143 FilterForVisibleSceneInRegion selector(view_area, occlusion_match);
133 scene->for_each_if(selector, applicator);144 scene->for_each_if(selector, applicator);
134 overlay_renderer->render(view_area, save_resource);145 overlay_renderer->render(view_area, save_resource);
135146
136147
=== added file 'src/server/compositor/occlusion.cpp'
--- src/server/compositor/occlusion.cpp 1970-01-01 00:00:00 +0000
+++ src/server/compositor/occlusion.cpp 2013-10-17 05:56:50 +0000
@@ -0,0 +1,86 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
17 */
18
19#include "mir/compositor/compositing_criteria.h"
20#include "mir/geometry/rectangle.h"
21#include "occlusion.h"
22
23using namespace mir;
24using namespace mir::compositor;
25
26OcclusionFilter::OcclusionFilter(const geometry::Rectangle &area)
27 : area(area)
28{
29}
30
31bool OcclusionFilter::operator()(const CompositingCriteria &criteria)
32{
33 const glm::mat4 &trans = criteria.transformation();
34 bool orthogonal =
35 trans[0][1] == 0.0f &&
36 trans[0][2] == 0.0f &&
37 trans[0][3] == 0.0f &&
38 trans[1][0] == 0.0f &&
39 trans[1][2] == 0.0f &&
40 trans[1][3] == 0.0f &&
41 trans[2][0] == 0.0f &&
42 trans[2][1] == 0.0f &&
43 trans[2][2] == 0.0f &&
44 trans[2][3] == 0.0f &&
45 trans[3][2] == 0.0f &&
46 trans[3][3] == 1.0f;
47
48 if (!orthogonal)
49 return false; // Weirdly transformed. Assume never occluded.
50
51 // This could be replaced by adding a "CompositingCriteria::rect()"
52 int width = trans[0][0];
53 int height = trans[1][1];
54 int x = trans[3][0] - width / 2;
55 int y = trans[3][1] - height / 2;
56 geometry::Rectangle window{{x, y}, {width, height}};
57
58 if (!criteria.should_be_rendered_in(area))
59 return true; // Not on the display, or invisible; definitely occluded.
60
61 bool occluded = false;
62 for (const auto &r : coverage)
63 {
64 if (r.contains(window))
65 {
66 occluded = true;
67 break;
68 }
69 }
70
71 if (!occluded && criteria.alpha() == 1.0f && !criteria.shaped())
72 coverage.push_back(window);
73
74 return occluded;
75}
76
77void OcclusionMatch::operator()(const CompositingCriteria &criteria,
78 surfaces::BufferStream &)
79{
80 hidden.insert(&criteria);
81}
82
83bool OcclusionMatch::occluded(const CompositingCriteria &criteria) const
84{
85 return hidden.find(&criteria) != hidden.end();
86}
087
=== added file 'src/server/compositor/occlusion.h'
--- src/server/compositor/occlusion.h 1970-01-01 00:00:00 +0000
+++ src/server/compositor/occlusion.h 2013-10-17 05:56:50 +0000
@@ -0,0 +1,61 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
17 */
18
19#ifndef MIR_COMPOSITOR_OCCLUSION_H_
20#define MIR_COMPOSITOR_OCCLUSION_H_
21
22#include "mir/compositor/scene.h"
23#include <vector>
24#include <set>
25
26namespace mir
27{
28namespace compositor
29{
30class CompositingCriteria;
31
32class OcclusionFilter : public FilterForScene
33{
34public:
35 OcclusionFilter(const geometry::Rectangle &area);
36 bool operator()(const CompositingCriteria &criteria) override;
37
38private:
39 const geometry::Rectangle &area;
40
41 typedef std::vector<geometry::Rectangle> RectangleList;
42 RectangleList coverage;
43};
44
45class OcclusionMatch : public OperatorForScene
46{
47public:
48 void operator()(const CompositingCriteria &,
49 surfaces::BufferStream &stream) override;
50
51 bool occluded(const CompositingCriteria &criteria) const;
52
53private:
54 typedef std::set<const CompositingCriteria*> RenderableSet;
55 RenderableSet hidden;
56};
57
58} // namespace compositor
59} // namespace mir
60
61#endif // MIR_COMPOSITOR_OCCLUSION_H_
062
=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
--- tests/unit-tests/compositor/CMakeLists.txt 2013-08-28 03:41:48 +0000
+++ tests/unit-tests/compositor/CMakeLists.txt 2013-10-17 05:56:50 +0000
@@ -7,6 +7,7 @@
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_switching_bundle.cpp7 ${CMAKE_CURRENT_SOURCE_DIR}/test_switching_bundle.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp8 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_bypass.cpp9 ${CMAKE_CURRENT_SOURCE_DIR}/test_bypass.cpp
10 ${CMAKE_CURRENT_SOURCE_DIR}/test_occlusion.cpp
10)11)
1112
12set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)13set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)
1314
=== modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp'
--- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-10-16 07:57:33 +0000
+++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-10-17 05:56:50 +0000
@@ -78,7 +78,16 @@
78 }78 }
79 }79 }
8080
81 void reverse_for_each_if(mc::FilterForScene&, mc::OperatorForScene&) {}81 void reverse_for_each_if(mc::FilterForScene &filter,
82 mc::OperatorForScene &op)
83 {
84 for (auto it = surfaces.rbegin(); it != surfaces.rend(); ++it)
85 {
86 mc::CompositingCriteria &criteria = **it;
87 if (filter(criteria))
88 op(criteria, stub_stream);
89 }
90 }
8291
83 void set_change_callback(std::function<void()> const&) {}92 void set_change_callback(std::function<void()> const&) {}
8493
@@ -153,6 +162,9 @@
153 EXPECT_CALL(scene, for_each_if(_,_))162 EXPECT_CALL(scene, for_each_if(_,_))
154 .Times(1);163 .Times(1);
155164
165 EXPECT_CALL(scene, reverse_for_each_if(_,_))
166 .Times(1);
167
156 mc::DefaultDisplayBufferCompositorFactory factory(168 mc::DefaultDisplayBufferCompositorFactory factory(
157 mt::fake_shared(scene),169 mt::fake_shared(scene),
158 mt::fake_shared(renderer_factory),170 mt::fake_shared(renderer_factory),
@@ -197,9 +209,20 @@
197209
198 NiceMock<mtd::MockCompositingCriteria> mock_criteria1, mock_criteria2, mock_criteria3;210 NiceMock<mtd::MockCompositingCriteria> mock_criteria1, mock_criteria2, mock_criteria3;
199211
200 EXPECT_CALL(mock_criteria1, should_be_rendered_in(_)).WillOnce(Return(true));212 glm::mat4 simple;
201 EXPECT_CALL(mock_criteria2, should_be_rendered_in(_)).WillOnce(Return(false));213 EXPECT_CALL(mock_criteria1, transformation())
202 EXPECT_CALL(mock_criteria3, should_be_rendered_in(_)).WillOnce(Return(true));214 .WillOnce(ReturnRef(simple));
215 EXPECT_CALL(mock_criteria2, transformation())
216 .WillOnce(ReturnRef(simple));
217 EXPECT_CALL(mock_criteria3, transformation())
218 .WillOnce(ReturnRef(simple));
219
220 EXPECT_CALL(mock_criteria1, should_be_rendered_in(_))
221 .WillOnce(Return(true));
222 EXPECT_CALL(mock_criteria2, should_be_rendered_in(_))
223 .WillOnce(Return(false));
224 EXPECT_CALL(mock_criteria3, should_be_rendered_in(_))
225 .WillOnce(Return(true));
203226
204 std::vector<mc::CompositingCriteria*> renderable_vec;227 std::vector<mc::CompositingCriteria*> renderable_vec;
205 renderable_vec.push_back(&mock_criteria1);228 renderable_vec.push_back(&mock_criteria1);
@@ -347,7 +370,7 @@
347 renderable_vec.push_back(&fullscreen);370 renderable_vec.push_back(&fullscreen);
348371
349 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))372 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
350 .Times(1);373 .Times(0); // zero due to occlusion detection
351 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))374 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))
352 .Times(1);375 .Times(1);
353376
@@ -396,7 +419,7 @@
396 renderable_vec.push_back(&fullscreen);419 renderable_vec.push_back(&fullscreen);
397420
398 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))421 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
399 .Times(1);422 .Times(0); // zero due to occlusion detection
400 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))423 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))
401 .Times(1);424 .Times(1);
402425
@@ -505,3 +528,47 @@
505 comp->composite();528 comp->composite();
506}529}
507530
531TEST(DefaultDisplayBufferCompositor, occluded_surface_is_never_rendered)
532{
533 using namespace testing;
534
535 StubRendererFactory renderer_factory;
536 NiceMock<MockOverlayRenderer> overlay_renderer;
537
538 geom::Rectangle screen{{0, 0}, {1366, 768}};
539
540 mtd::MockDisplayBuffer display_buffer;
541 EXPECT_CALL(display_buffer, view_area())
542 .WillRepeatedly(Return(screen));
543 EXPECT_CALL(display_buffer, make_current())
544 .Times(1);
545 EXPECT_CALL(display_buffer, post_update())
546 .Times(1);
547 EXPECT_CALL(display_buffer, can_bypass())
548 .WillRepeatedly(Return(false));
549
550 mtd::StubCompositingCriteria large(0, 0, 100, 100);
551 mtd::StubCompositingCriteria small(10, 20, 30, 40);
552
553 std::vector<mc::CompositingCriteria*> renderable_vec;
554 renderable_vec.push_back(&small);
555 renderable_vec.push_back(&large);
556
557 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
558 .Times(0);
559 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(large),_))
560 .Times(1);
561
562 FakeScene scene(renderable_vec);
563
564 mc::DefaultDisplayBufferCompositorFactory factory(
565 mt::fake_shared(scene),
566 mt::fake_shared(renderer_factory),
567 mt::fake_shared(overlay_renderer));
568
569 auto comp = factory.create_compositor_for(display_buffer);
570
571 comp->composite();
572}
573
574
508575
=== added file 'tests/unit-tests/compositor/test_occlusion.cpp'
--- tests/unit-tests/compositor/test_occlusion.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/compositor/test_occlusion.cpp 2013-10-17 05:56:50 +0000
@@ -0,0 +1,163 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
17 */
18
19#include "mir/compositor/compositing_criteria.h"
20#include "mir/geometry/rectangle.h"
21#include "src/server/compositor/occlusion.h"
22#include "mir_test_doubles/stub_buffer_stream.h"
23#include "mir_test_doubles/stub_compositing_criteria.h"
24
25#include <gtest/gtest.h>
26#include <memory>
27
28using namespace testing;
29using namespace mir::geometry;
30using namespace mir::compositor;
31using namespace mir::test::doubles;
32
33struct OcclusionFilterTest : public Test
34{
35 OcclusionFilterTest()
36 {
37 monitor_rect.top_left = {0, 0};
38 monitor_rect.size = {1920, 1200};
39 }
40
41 Rectangle monitor_rect;
42};
43
44TEST_F(OcclusionFilterTest, single_window_not_occluded)
45{
46 OcclusionFilter filter(monitor_rect);
47
48 StubCompositingCriteria win(12, 34, 56, 78);
49
50 EXPECT_FALSE(filter(win));
51}
52
53TEST_F(OcclusionFilterTest, smaller_window_occluded)
54{
55 OcclusionFilter filter(monitor_rect);
56
57 StubCompositingCriteria front(10, 10, 10, 10);
58 EXPECT_FALSE(filter(front));
59
60 StubCompositingCriteria back(12, 12, 5, 5);
61 EXPECT_TRUE(filter(back));
62}
63
64TEST_F(OcclusionFilterTest, translucent_window_occludes_nothing)
65{
66 OcclusionFilter filter(monitor_rect);
67
68 StubCompositingCriteria front(10, 10, 10, 10, 0.5f);
69 EXPECT_FALSE(filter(front));
70
71 StubCompositingCriteria back(12, 12, 5, 5, 1.0f);
72 EXPECT_FALSE(filter(back));
73}
74
75TEST_F(OcclusionFilterTest, hidden_window_is_self_occluded)
76{
77 OcclusionFilter filter(monitor_rect);
78
79 StubCompositingCriteria front(10, 10, 10, 10, 1.0f, true, false);
80 EXPECT_TRUE(filter(front));
81}
82
83TEST_F(OcclusionFilterTest, hidden_window_occludes_nothing)
84{
85 OcclusionFilter filter(monitor_rect);
86
87 StubCompositingCriteria front(10, 10, 10, 10, 1.0f, true, false);
88 EXPECT_TRUE(filter(front));
89
90 StubCompositingCriteria back(12, 12, 5, 5);
91 EXPECT_FALSE(filter(back));
92}
93
94TEST_F(OcclusionFilterTest, shaped_window_occludes_nothing)
95{
96 OcclusionFilter filter(monitor_rect);
97
98 StubCompositingCriteria front(10, 10, 10, 10, 1.0f, false, true);
99 EXPECT_FALSE(filter(front));
100
101 StubCompositingCriteria back(12, 12, 5, 5);
102 EXPECT_FALSE(filter(back));
103}
104
105TEST_F(OcclusionFilterTest, identical_window_occluded)
106{
107 OcclusionFilter filter(monitor_rect);
108
109 StubCompositingCriteria front(10, 10, 10, 10);
110 EXPECT_FALSE(filter(front));
111
112 StubCompositingCriteria back(10, 10, 10, 10);
113 EXPECT_TRUE(filter(back));
114}
115
116TEST_F(OcclusionFilterTest, larger_window_never_occluded)
117{
118 OcclusionFilter filter(monitor_rect);
119
120 StubCompositingCriteria front(10, 10, 10, 10);
121 EXPECT_FALSE(filter(front));
122
123 StubCompositingCriteria back(9, 9, 12, 12);
124 EXPECT_FALSE(filter(back));
125}
126
127TEST_F(OcclusionFilterTest, cascaded_windows_never_occluded)
128{
129 OcclusionFilter filter(monitor_rect);
130
131 for (int x = 0; x < 10; x++)
132 {
133 StubCompositingCriteria win(x, x, 200, 100);
134 ASSERT_FALSE(filter(win));
135 }
136}
137
138TEST_F(OcclusionFilterTest, some_occluded_and_some_not)
139{
140 OcclusionFilter filter(monitor_rect);
141
142 StubCompositingCriteria front(10, 20, 400, 300);
143 EXPECT_FALSE(filter(front));
144
145 EXPECT_TRUE(filter(StubCompositingCriteria(10, 20, 5, 5)));
146 EXPECT_TRUE(filter(StubCompositingCriteria(100, 100, 20, 20)));
147 EXPECT_TRUE(filter(StubCompositingCriteria(200, 200, 50, 50)));
148
149 EXPECT_FALSE(filter(StubCompositingCriteria(500, 600, 34, 56)));
150 EXPECT_FALSE(filter(StubCompositingCriteria(200, 200, 1000, 1000)));
151}
152
153TEST(OcclusionMatchTest, remembers_matches)
154{
155 OcclusionMatch match;
156 StubCompositingCriteria win(1, 2, 3, 4);
157 StubBufferStream bufs;
158
159 EXPECT_FALSE(match.occluded(win));
160 match(win, bufs);
161 EXPECT_TRUE(match.occluded(win));
162}
163

Subscribers

People subscribed via source and target branches