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
1=== modified file 'src/server/compositor/CMakeLists.txt'
2--- src/server/compositor/CMakeLists.txt 2013-10-02 07:02:18 +0000
3+++ src/server/compositor/CMakeLists.txt 2013-10-17 05:56:50 +0000
4@@ -12,6 +12,7 @@
5 multi_threaded_compositor.cpp
6 switching_bundle.cpp
7 bypass.cpp
8+ occlusion.cpp
9 )
10
11 ADD_LIBRARY(
12
13=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
14--- src/server/compositor/default_display_buffer_compositor.cpp 2013-10-03 03:57:28 +0000
15+++ src/server/compositor/default_display_buffer_compositor.cpp 2013-10-17 05:56:50 +0000
16@@ -26,6 +26,7 @@
17 #include "mir/graphics/buffer.h"
18 #include "mir/surfaces/buffer_stream.h"
19 #include "bypass.h"
20+#include "occlusion.h"
21 #include <mutex>
22 #include <cstdlib>
23 #include <vector>
24@@ -38,16 +39,21 @@
25
26 struct FilterForVisibleSceneInRegion : public mc::FilterForScene
27 {
28- FilterForVisibleSceneInRegion(mir::geometry::Rectangle const& enclosing_region)
29- : enclosing_region(enclosing_region)
30+ FilterForVisibleSceneInRegion(
31+ mir::geometry::Rectangle const& enclosing_region,
32+ mc::OcclusionMatch const& occlusions)
33+ : enclosing_region(enclosing_region),
34+ occlusions(occlusions)
35 {
36 }
37 bool operator()(mc::CompositingCriteria const& info)
38 {
39- return info.should_be_rendered_in(enclosing_region);
40+ return info.should_be_rendered_in(enclosing_region) &&
41+ !occlusions.occluded(info);
42 }
43
44 mir::geometry::Rectangle const& enclosing_region;
45+ mc::OcclusionMatch const& occlusions;
46 };
47
48 std::mutex global_frameno_lock;
49@@ -127,9 +133,14 @@
50 display_buffer.make_current();
51
52 auto const& view_area = display_buffer.view_area();
53+
54+ mc::OcclusionFilter occlusion_search(view_area);
55+ mc::OcclusionMatch occlusion_match;
56+ scene->reverse_for_each_if(occlusion_search, occlusion_match);
57+
58 renderer->clear(local_frameno);
59 mc::RenderingOperator applicator(*renderer, save_resource);
60- FilterForVisibleSceneInRegion selector(view_area);
61+ FilterForVisibleSceneInRegion selector(view_area, occlusion_match);
62 scene->for_each_if(selector, applicator);
63 overlay_renderer->render(view_area, save_resource);
64
65
66=== added file 'src/server/compositor/occlusion.cpp'
67--- src/server/compositor/occlusion.cpp 1970-01-01 00:00:00 +0000
68+++ src/server/compositor/occlusion.cpp 2013-10-17 05:56:50 +0000
69@@ -0,0 +1,86 @@
70+/*
71+ * Copyright © 2013 Canonical Ltd.
72+ *
73+ * This program is free software: you can redistribute it and/or modify it
74+ * under the terms of the GNU General Public License version 3,
75+ * as published by the Free Software Foundation.
76+ *
77+ * This program is distributed in the hope that it will be useful,
78+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
79+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80+ * GNU General Public License for more details.
81+ *
82+ * You should have received a copy of the GNU General Public License
83+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
84+ *
85+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
86+ */
87+
88+#include "mir/compositor/compositing_criteria.h"
89+#include "mir/geometry/rectangle.h"
90+#include "occlusion.h"
91+
92+using namespace mir;
93+using namespace mir::compositor;
94+
95+OcclusionFilter::OcclusionFilter(const geometry::Rectangle &area)
96+ : area(area)
97+{
98+}
99+
100+bool OcclusionFilter::operator()(const CompositingCriteria &criteria)
101+{
102+ const glm::mat4 &trans = criteria.transformation();
103+ bool orthogonal =
104+ trans[0][1] == 0.0f &&
105+ trans[0][2] == 0.0f &&
106+ trans[0][3] == 0.0f &&
107+ trans[1][0] == 0.0f &&
108+ trans[1][2] == 0.0f &&
109+ trans[1][3] == 0.0f &&
110+ trans[2][0] == 0.0f &&
111+ trans[2][1] == 0.0f &&
112+ trans[2][2] == 0.0f &&
113+ trans[2][3] == 0.0f &&
114+ trans[3][2] == 0.0f &&
115+ trans[3][3] == 1.0f;
116+
117+ if (!orthogonal)
118+ return false; // Weirdly transformed. Assume never occluded.
119+
120+ // This could be replaced by adding a "CompositingCriteria::rect()"
121+ int width = trans[0][0];
122+ int height = trans[1][1];
123+ int x = trans[3][0] - width / 2;
124+ int y = trans[3][1] - height / 2;
125+ geometry::Rectangle window{{x, y}, {width, height}};
126+
127+ if (!criteria.should_be_rendered_in(area))
128+ return true; // Not on the display, or invisible; definitely occluded.
129+
130+ bool occluded = false;
131+ for (const auto &r : coverage)
132+ {
133+ if (r.contains(window))
134+ {
135+ occluded = true;
136+ break;
137+ }
138+ }
139+
140+ if (!occluded && criteria.alpha() == 1.0f && !criteria.shaped())
141+ coverage.push_back(window);
142+
143+ return occluded;
144+}
145+
146+void OcclusionMatch::operator()(const CompositingCriteria &criteria,
147+ surfaces::BufferStream &)
148+{
149+ hidden.insert(&criteria);
150+}
151+
152+bool OcclusionMatch::occluded(const CompositingCriteria &criteria) const
153+{
154+ return hidden.find(&criteria) != hidden.end();
155+}
156
157=== added file 'src/server/compositor/occlusion.h'
158--- src/server/compositor/occlusion.h 1970-01-01 00:00:00 +0000
159+++ src/server/compositor/occlusion.h 2013-10-17 05:56:50 +0000
160@@ -0,0 +1,61 @@
161+/*
162+ * Copyright © 2013 Canonical Ltd.
163+ *
164+ * This program is free software: you can redistribute it and/or modify it
165+ * under the terms of the GNU General Public License version 3,
166+ * as published by the Free Software Foundation.
167+ *
168+ * This program is distributed in the hope that it will be useful,
169+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
170+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
171+ * GNU General Public License for more details.
172+ *
173+ * You should have received a copy of the GNU General Public License
174+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
175+ *
176+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
177+ */
178+
179+#ifndef MIR_COMPOSITOR_OCCLUSION_H_
180+#define MIR_COMPOSITOR_OCCLUSION_H_
181+
182+#include "mir/compositor/scene.h"
183+#include <vector>
184+#include <set>
185+
186+namespace mir
187+{
188+namespace compositor
189+{
190+class CompositingCriteria;
191+
192+class OcclusionFilter : public FilterForScene
193+{
194+public:
195+ OcclusionFilter(const geometry::Rectangle &area);
196+ bool operator()(const CompositingCriteria &criteria) override;
197+
198+private:
199+ const geometry::Rectangle &area;
200+
201+ typedef std::vector<geometry::Rectangle> RectangleList;
202+ RectangleList coverage;
203+};
204+
205+class OcclusionMatch : public OperatorForScene
206+{
207+public:
208+ void operator()(const CompositingCriteria &,
209+ surfaces::BufferStream &stream) override;
210+
211+ bool occluded(const CompositingCriteria &criteria) const;
212+
213+private:
214+ typedef std::set<const CompositingCriteria*> RenderableSet;
215+ RenderableSet hidden;
216+};
217+
218+} // namespace compositor
219+} // namespace mir
220+
221+#endif // MIR_COMPOSITOR_OCCLUSION_H_
222
223=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
224--- tests/unit-tests/compositor/CMakeLists.txt 2013-08-28 03:41:48 +0000
225+++ tests/unit-tests/compositor/CMakeLists.txt 2013-10-17 05:56:50 +0000
226@@ -7,6 +7,7 @@
227 ${CMAKE_CURRENT_SOURCE_DIR}/test_switching_bundle.cpp
228 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
229 ${CMAKE_CURRENT_SOURCE_DIR}/test_bypass.cpp
230+ ${CMAKE_CURRENT_SOURCE_DIR}/test_occlusion.cpp
231 )
232
233 set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)
234
235=== modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp'
236--- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-10-16 07:57:33 +0000
237+++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2013-10-17 05:56:50 +0000
238@@ -78,7 +78,16 @@
239 }
240 }
241
242- void reverse_for_each_if(mc::FilterForScene&, mc::OperatorForScene&) {}
243+ void reverse_for_each_if(mc::FilterForScene &filter,
244+ mc::OperatorForScene &op)
245+ {
246+ for (auto it = surfaces.rbegin(); it != surfaces.rend(); ++it)
247+ {
248+ mc::CompositingCriteria &criteria = **it;
249+ if (filter(criteria))
250+ op(criteria, stub_stream);
251+ }
252+ }
253
254 void set_change_callback(std::function<void()> const&) {}
255
256@@ -153,6 +162,9 @@
257 EXPECT_CALL(scene, for_each_if(_,_))
258 .Times(1);
259
260+ EXPECT_CALL(scene, reverse_for_each_if(_,_))
261+ .Times(1);
262+
263 mc::DefaultDisplayBufferCompositorFactory factory(
264 mt::fake_shared(scene),
265 mt::fake_shared(renderer_factory),
266@@ -197,9 +209,20 @@
267
268 NiceMock<mtd::MockCompositingCriteria> mock_criteria1, mock_criteria2, mock_criteria3;
269
270- EXPECT_CALL(mock_criteria1, should_be_rendered_in(_)).WillOnce(Return(true));
271- EXPECT_CALL(mock_criteria2, should_be_rendered_in(_)).WillOnce(Return(false));
272- EXPECT_CALL(mock_criteria3, should_be_rendered_in(_)).WillOnce(Return(true));
273+ glm::mat4 simple;
274+ EXPECT_CALL(mock_criteria1, transformation())
275+ .WillOnce(ReturnRef(simple));
276+ EXPECT_CALL(mock_criteria2, transformation())
277+ .WillOnce(ReturnRef(simple));
278+ EXPECT_CALL(mock_criteria3, transformation())
279+ .WillOnce(ReturnRef(simple));
280+
281+ EXPECT_CALL(mock_criteria1, should_be_rendered_in(_))
282+ .WillOnce(Return(true));
283+ EXPECT_CALL(mock_criteria2, should_be_rendered_in(_))
284+ .WillOnce(Return(false));
285+ EXPECT_CALL(mock_criteria3, should_be_rendered_in(_))
286+ .WillOnce(Return(true));
287
288 std::vector<mc::CompositingCriteria*> renderable_vec;
289 renderable_vec.push_back(&mock_criteria1);
290@@ -347,7 +370,7 @@
291 renderable_vec.push_back(&fullscreen);
292
293 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
294- .Times(1);
295+ .Times(0); // zero due to occlusion detection
296 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))
297 .Times(1);
298
299@@ -396,7 +419,7 @@
300 renderable_vec.push_back(&fullscreen);
301
302 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
303- .Times(1);
304+ .Times(0); // zero due to occlusion detection
305 EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(fullscreen),_))
306 .Times(1);
307
308@@ -505,3 +528,47 @@
309 comp->composite();
310 }
311
312+TEST(DefaultDisplayBufferCompositor, occluded_surface_is_never_rendered)
313+{
314+ using namespace testing;
315+
316+ StubRendererFactory renderer_factory;
317+ NiceMock<MockOverlayRenderer> overlay_renderer;
318+
319+ geom::Rectangle screen{{0, 0}, {1366, 768}};
320+
321+ mtd::MockDisplayBuffer display_buffer;
322+ EXPECT_CALL(display_buffer, view_area())
323+ .WillRepeatedly(Return(screen));
324+ EXPECT_CALL(display_buffer, make_current())
325+ .Times(1);
326+ EXPECT_CALL(display_buffer, post_update())
327+ .Times(1);
328+ EXPECT_CALL(display_buffer, can_bypass())
329+ .WillRepeatedly(Return(false));
330+
331+ mtd::StubCompositingCriteria large(0, 0, 100, 100);
332+ mtd::StubCompositingCriteria small(10, 20, 30, 40);
333+
334+ std::vector<mc::CompositingCriteria*> renderable_vec;
335+ renderable_vec.push_back(&small);
336+ renderable_vec.push_back(&large);
337+
338+ EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(small),_))
339+ .Times(0);
340+ EXPECT_CALL(renderer_factory.mock_renderer, render(_,Ref(large),_))
341+ .Times(1);
342+
343+ FakeScene scene(renderable_vec);
344+
345+ mc::DefaultDisplayBufferCompositorFactory factory(
346+ mt::fake_shared(scene),
347+ mt::fake_shared(renderer_factory),
348+ mt::fake_shared(overlay_renderer));
349+
350+ auto comp = factory.create_compositor_for(display_buffer);
351+
352+ comp->composite();
353+}
354+
355+
356
357=== added file 'tests/unit-tests/compositor/test_occlusion.cpp'
358--- tests/unit-tests/compositor/test_occlusion.cpp 1970-01-01 00:00:00 +0000
359+++ tests/unit-tests/compositor/test_occlusion.cpp 2013-10-17 05:56:50 +0000
360@@ -0,0 +1,163 @@
361+/*
362+ * Copyright © 2013 Canonical Ltd.
363+ *
364+ * This program is free software: you can redistribute it and/or modify
365+ * it under the terms of the GNU General Public License version 3 as
366+ * published by the Free Software Foundation.
367+ *
368+ * This program is distributed in the hope that it will be useful,
369+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
370+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
371+ * GNU General Public License for more details.
372+ *
373+ * You should have received a copy of the GNU General Public License
374+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
375+ *
376+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
377+ */
378+
379+#include "mir/compositor/compositing_criteria.h"
380+#include "mir/geometry/rectangle.h"
381+#include "src/server/compositor/occlusion.h"
382+#include "mir_test_doubles/stub_buffer_stream.h"
383+#include "mir_test_doubles/stub_compositing_criteria.h"
384+
385+#include <gtest/gtest.h>
386+#include <memory>
387+
388+using namespace testing;
389+using namespace mir::geometry;
390+using namespace mir::compositor;
391+using namespace mir::test::doubles;
392+
393+struct OcclusionFilterTest : public Test
394+{
395+ OcclusionFilterTest()
396+ {
397+ monitor_rect.top_left = {0, 0};
398+ monitor_rect.size = {1920, 1200};
399+ }
400+
401+ Rectangle monitor_rect;
402+};
403+
404+TEST_F(OcclusionFilterTest, single_window_not_occluded)
405+{
406+ OcclusionFilter filter(monitor_rect);
407+
408+ StubCompositingCriteria win(12, 34, 56, 78);
409+
410+ EXPECT_FALSE(filter(win));
411+}
412+
413+TEST_F(OcclusionFilterTest, smaller_window_occluded)
414+{
415+ OcclusionFilter filter(monitor_rect);
416+
417+ StubCompositingCriteria front(10, 10, 10, 10);
418+ EXPECT_FALSE(filter(front));
419+
420+ StubCompositingCriteria back(12, 12, 5, 5);
421+ EXPECT_TRUE(filter(back));
422+}
423+
424+TEST_F(OcclusionFilterTest, translucent_window_occludes_nothing)
425+{
426+ OcclusionFilter filter(monitor_rect);
427+
428+ StubCompositingCriteria front(10, 10, 10, 10, 0.5f);
429+ EXPECT_FALSE(filter(front));
430+
431+ StubCompositingCriteria back(12, 12, 5, 5, 1.0f);
432+ EXPECT_FALSE(filter(back));
433+}
434+
435+TEST_F(OcclusionFilterTest, hidden_window_is_self_occluded)
436+{
437+ OcclusionFilter filter(monitor_rect);
438+
439+ StubCompositingCriteria front(10, 10, 10, 10, 1.0f, true, false);
440+ EXPECT_TRUE(filter(front));
441+}
442+
443+TEST_F(OcclusionFilterTest, hidden_window_occludes_nothing)
444+{
445+ OcclusionFilter filter(monitor_rect);
446+
447+ StubCompositingCriteria front(10, 10, 10, 10, 1.0f, true, false);
448+ EXPECT_TRUE(filter(front));
449+
450+ StubCompositingCriteria back(12, 12, 5, 5);
451+ EXPECT_FALSE(filter(back));
452+}
453+
454+TEST_F(OcclusionFilterTest, shaped_window_occludes_nothing)
455+{
456+ OcclusionFilter filter(monitor_rect);
457+
458+ StubCompositingCriteria front(10, 10, 10, 10, 1.0f, false, true);
459+ EXPECT_FALSE(filter(front));
460+
461+ StubCompositingCriteria back(12, 12, 5, 5);
462+ EXPECT_FALSE(filter(back));
463+}
464+
465+TEST_F(OcclusionFilterTest, identical_window_occluded)
466+{
467+ OcclusionFilter filter(monitor_rect);
468+
469+ StubCompositingCriteria front(10, 10, 10, 10);
470+ EXPECT_FALSE(filter(front));
471+
472+ StubCompositingCriteria back(10, 10, 10, 10);
473+ EXPECT_TRUE(filter(back));
474+}
475+
476+TEST_F(OcclusionFilterTest, larger_window_never_occluded)
477+{
478+ OcclusionFilter filter(monitor_rect);
479+
480+ StubCompositingCriteria front(10, 10, 10, 10);
481+ EXPECT_FALSE(filter(front));
482+
483+ StubCompositingCriteria back(9, 9, 12, 12);
484+ EXPECT_FALSE(filter(back));
485+}
486+
487+TEST_F(OcclusionFilterTest, cascaded_windows_never_occluded)
488+{
489+ OcclusionFilter filter(monitor_rect);
490+
491+ for (int x = 0; x < 10; x++)
492+ {
493+ StubCompositingCriteria win(x, x, 200, 100);
494+ ASSERT_FALSE(filter(win));
495+ }
496+}
497+
498+TEST_F(OcclusionFilterTest, some_occluded_and_some_not)
499+{
500+ OcclusionFilter filter(monitor_rect);
501+
502+ StubCompositingCriteria front(10, 20, 400, 300);
503+ EXPECT_FALSE(filter(front));
504+
505+ EXPECT_TRUE(filter(StubCompositingCriteria(10, 20, 5, 5)));
506+ EXPECT_TRUE(filter(StubCompositingCriteria(100, 100, 20, 20)));
507+ EXPECT_TRUE(filter(StubCompositingCriteria(200, 200, 50, 50)));
508+
509+ EXPECT_FALSE(filter(StubCompositingCriteria(500, 600, 34, 56)));
510+ EXPECT_FALSE(filter(StubCompositingCriteria(200, 200, 1000, 1000)));
511+}
512+
513+TEST(OcclusionMatchTest, remembers_matches)
514+{
515+ OcclusionMatch match;
516+ StubCompositingCriteria win(1, 2, 3, 4);
517+ StubBufferStream bufs;
518+
519+ EXPECT_FALSE(match.occluded(win));
520+ match(win, bufs);
521+ EXPECT_TRUE(match.occluded(win));
522+}
523+

Subscribers

People subscribed via source and target branches