Mir

Merge lp:~kdub/mir/detect-demo-decorations into lp:mir

Proposed by Kevin DuBois
Status: Work in progress
Proposed branch: lp:~kdub/mir/detect-demo-decorations
Merge into: lp:mir
Prerequisite: lp:~kdub/mir/fix-1299977-take3
Diff against target: 334 lines (+174/-11)
10 files modified
examples/demo-shell/CMakeLists.txt (+6/-2)
examples/demo-shell/demo_compositor.cpp (+38/-6)
examples/demo-shell/demo_compositor.h (+5/-2)
examples/demo-shell/demo_shell.cpp (+1/-1)
include/test/mir_test_doubles/mock_display_buffer.h (+2/-0)
include/test/mir_test_doubles/mock_gl.h (+1/-0)
tests/mir_test_doubles/mock_gl.cpp (+6/-0)
tests/unit-tests/CMakeLists.txt (+2/-0)
tests/unit-tests/examples/CMakeLists.txt (+5/-0)
tests/unit-tests/examples/test_demo_compositor.cpp (+108/-0)
To merge this branch: bzr merge lp:~kdub/mir/detect-demo-decorations
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Resubmitting
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+227396@code.launchpad.net

Commit message

demo shell: detect when decorations for the windows are on screen. When a decoration that can't be represented in the optimized abstraction needs to be painted, render using opengl. This makes the --disable-overlays false option on android not look so bad.

Description of the change

demo shell: detect when decorations for the windows are on screen. When a decoration that can't be represented in the optimized abstraction needs to be painted, render using opengl. This makes the --disable-overlays false option on android not look so bad. More work is still needed to detect when only the grey background is visible before the demo shell looks good when android is transitioning back and forth from gl to overlay. (and change the default to overlay on by default)

Note how the demo compositor code is not thinking about what sort of hardware optimization would go on, only if it could represent what it wants to paint as a RenderableList. On the mesa platform, an exactly fullscreen client would be bypassed. On android, a fullscreen client and larger would be optimized as an overlay.

To post a comment you must log in.
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 prereq branch is blocked and I think should not land. So this needs to not depend on it.

Also, more generally we should not treat decorations alone. Doing free-form GL rendering outside of surface rectangles encompasses much more than decorations. For example, resize highlights, FPS overlays and other temporary effect/animation rendering.

The alternate solution we're also working toward is for *everything* to be in the scene graph. When that happens, detection of what's on screen is a graph traversal exercise.

So,
  (1) Resubmit to not depend on the parent branch.
  (2) Don't treat decorations as the special case, but rather any free-form rendering needs to be detected (or just flagged as a bool somewhere).
  (3) Consider continuing on the road toward "everything's in the scene graph" so it can just be done as a graph traversal.

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

The depends-on-branch was close to landing, so I just wanted to pipeline this on Friday. Seeing as that branch was blocked, no point reviewing this until the base branch's block is resolved.

Unmerged revisions

1699. By Kevin DuBois

make a type richer

1698. By Kevin DuBois

remerge in fix base branch, because bzr cant tfigure out the history here apparently

1697. By Kevin DuBois

merge devel

1696. By Kevin DuBois

test to pass

1695. By Kevin DuBois

work through some problems to see the test fail

1694. By Kevin DuBois

make it possible to statically link the test binary to the demo shell code

1693. By Kevin DuBois

add test that checks the demo shell compositor

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/demo-shell/CMakeLists.txt'
2--- examples/demo-shell/CMakeLists.txt 2014-07-18 20:30:29 +0000
3+++ examples/demo-shell/CMakeLists.txt 2014-07-18 20:30:30 +0000
4@@ -1,5 +1,4 @@
5-add_executable(mir_demo_server_shell
6- demo_shell.cpp
7+add_library(mirdemoshell STATIC
8 demo_compositor.cpp
9 demo_renderer.cpp
10 fullscreen_placement_strategy.cpp
11@@ -7,7 +6,12 @@
12 ../server_configuration.cpp
13 )
14
15+add_executable(mir_demo_server_shell
16+ demo_shell.cpp
17+)
18+
19 target_link_libraries(mir_demo_server_shell
20+ mirdemoshell
21 mirserver
22 mirdraw
23 )
24
25=== modified file 'examples/demo-shell/demo_compositor.cpp'
26--- examples/demo-shell/demo_compositor.cpp 2014-07-18 20:30:29 +0000
27+++ examples/demo-shell/demo_compositor.cpp 2014-07-18 20:30:30 +0000
28@@ -35,24 +35,53 @@
29 {
30 return db.uses_alpha() ? mc::DestinationAlpha::generate_from_source : mc::DestinationAlpha::opaque;
31 }
32+
33+bool decorations_need_painting(
34+ mg::RenderableList const& list,
35+ geom::Rectangle const& area,
36+ int shadow_radius, geom::Height const& titlebar_height)
37+{
38+ for(auto const& renderable : list)
39+ {
40+ auto const& pos = renderable->screen_position();
41+ geom::Rectangle titlebar_rect{
42+ {pos.top_left.x.as_int(), pos.top_left.y.as_int() - titlebar_height.as_int()},
43+ {pos.size.width, titlebar_height}};
44+ geom::Rectangle right_shadow_rect{
45+ pos.top_right(),
46+ {geom::Width{shadow_radius}, geom::Height{pos.size.height.as_int() + shadow_radius}}};
47+ geom::Rectangle bottom_shadow_rect{
48+ pos.bottom_left(),
49+ {pos.size.width, geom::Height{shadow_radius}}};
50+
51+ if (titlebar_rect.intersection_with(area) != geom::Rectangle{} ||
52+ right_shadow_rect.intersection_with(area) != geom::Rectangle{} ||
53+ bottom_shadow_rect.intersection_with(area) != geom::Rectangle{})
54+ return true;
55+ }
56+ return false;
57+}
58+
59 }
60
61 me::DemoCompositor::DemoCompositor(
62 mg::DisplayBuffer& display_buffer,
63 std::shared_ptr<mc::Scene> const& scene,
64 mg::GLProgramFactory const& factory,
65- std::shared_ptr<mc::CompositorReport> const& report) :
66+ std::shared_ptr<mc::CompositorReport> const& report,
67+ int shadow_radius,
68+ geom::Height titlebar_height) :
69 display_buffer(display_buffer),
70 scene(scene),
71 report(report),
72- shadow_radius(80),
73- titlebar_height(30),
74+ shadow_radius(shadow_radius),
75+ titlebar_height(titlebar_height),
76 renderer(
77 factory,
78 display_buffer.view_area(),
79 destination_alpha(display_buffer),
80 static_cast<float>(shadow_radius),
81- static_cast<float>(titlebar_height))
82+ titlebar_height.as_float())
83 {
84 }
85
86@@ -60,7 +89,8 @@
87 {
88 mg::RenderableList renderable_list;
89 auto elements = scene->scene_elements_for(this);
90- auto occluded = me::filter_occlusions_from(elements, display_buffer.view_area(), shadow_radius, titlebar_height);
91+ auto occluded = me::filter_occlusions_from(
92+ elements, display_buffer.view_area(), shadow_radius, titlebar_height.as_int());
93 for(auto const& it : elements)
94 {
95 renderable_list.push_back(it->renderable());
96@@ -77,7 +107,9 @@
97 report->began_frame(this);
98
99 auto renderable_list = generate_renderables();
100- if (display_buffer.post_renderables_if_optimizable(renderable_list))
101+ if (!decorations_need_painting(
102+ renderable_list, display_buffer.view_area(), shadow_radius, titlebar_height) &&
103+ (display_buffer.post_renderables_if_optimizable(renderable_list)))
104 {
105 renderer.suspend();
106 report->finished_frame(true, this);
107
108=== modified file 'examples/demo-shell/demo_compositor.h'
109--- examples/demo-shell/demo_compositor.h 2014-07-18 20:30:29 +0000
110+++ examples/demo-shell/demo_compositor.h 2014-07-18 20:30:30 +0000
111@@ -19,6 +19,7 @@
112 #ifndef MIR_EXAMPLES_DEMO_COMPOSITOR_H_
113 #define MIR_EXAMPLES_DEMO_COMPOSITOR_H_
114
115+#include "mir/geometry/dimensions.h"
116 #include "mir/compositor/display_buffer_compositor.h"
117 #include "mir/compositor/scene.h"
118 #include "mir/graphics/renderable.h"
119@@ -45,7 +46,9 @@
120 graphics::DisplayBuffer& display_buffer,
121 std::shared_ptr<compositor::Scene> const& scene,
122 graphics::GLProgramFactory const& factory,
123- std::shared_ptr<compositor::CompositorReport> const& report);
124+ std::shared_ptr<compositor::CompositorReport> const& report,
125+ int shadow_radius,
126+ geometry::Height titlebar_height);
127
128 void composite() override;
129
130@@ -55,7 +58,7 @@
131 std::shared_ptr<compositor::Scene> const scene;
132 std::shared_ptr<compositor::CompositorReport> const report;
133 int const shadow_radius;
134- int const titlebar_height;
135+ geometry::Height const titlebar_height;
136 DemoRenderer renderer;
137 };
138
139
140=== modified file 'examples/demo-shell/demo_shell.cpp'
141--- examples/demo-shell/demo_shell.cpp 2014-07-18 20:30:29 +0000
142+++ examples/demo-shell/demo_shell.cpp 2014-07-18 20:30:30 +0000
143@@ -66,7 +66,7 @@
144 mg::DisplayBuffer& display_buffer) override
145 {
146 return std::unique_ptr<mc::DisplayBufferCompositor>(
147- new me::DemoCompositor{display_buffer, scene, *gl_program_factory, report});
148+ new me::DemoCompositor{display_buffer, scene, *gl_program_factory, report, 80, geometry::Height{30}});
149 }
150
151 private:
152
153=== modified file 'include/test/mir_test_doubles/mock_display_buffer.h'
154--- include/test/mir_test_doubles/mock_display_buffer.h 2014-06-05 20:35:46 +0000
155+++ include/test/mir_test_doubles/mock_display_buffer.h 2014-07-18 20:30:30 +0000
156@@ -38,6 +38,8 @@
157 using namespace testing;
158 ON_CALL(*this, view_area())
159 .WillByDefault(Return(geometry::Rectangle{{0,0},{0,0}}));
160+ ON_CALL(*this, orientation())
161+ .WillByDefault(Return(mir_orientation_normal));
162 }
163 MOCK_CONST_METHOD0(view_area, geometry::Rectangle());
164 MOCK_METHOD0(make_current, void());
165
166=== modified file 'include/test/mir_test_doubles/mock_gl.h'
167--- include/test/mir_test_doubles/mock_gl.h 2014-06-18 12:50:31 +0000
168+++ include/test/mir_test_doubles/mock_gl.h 2014-07-18 20:30:30 +0000
169@@ -105,6 +105,7 @@
170 void(GLuint, GLint, GLenum, GLboolean, GLsizei,
171 const GLvoid *));
172 MOCK_METHOD4(glViewport, void(GLint, GLint, GLsizei, GLsizei));
173+ MOCK_METHOD1(glGenerateMipmap, void(GLenum));
174 };
175
176 }
177
178=== modified file 'tests/mir_test_doubles/mock_gl.cpp'
179--- tests/mir_test_doubles/mock_gl.cpp 2014-06-18 12:50:31 +0000
180+++ tests/mir_test_doubles/mock_gl.cpp 2014-07-18 20:30:30 +0000
181@@ -415,3 +415,9 @@
182 CHECK_GLOBAL_VOID_MOCK();
183 global_mock_gl->glFinish();
184 }
185+
186+void glGenerateMipmap(GLenum target)
187+{
188+ CHECK_GLOBAL_VOID_MOCK();
189+ global_mock_gl->glGenerateMipmap(target);
190+}
191
192=== modified file 'tests/unit-tests/CMakeLists.txt'
193--- tests/unit-tests/CMakeLists.txt 2014-07-11 21:53:44 +0000
194+++ tests/unit-tests/CMakeLists.txt 2014-07-18 20:30:30 +0000
195@@ -34,6 +34,7 @@
196 add_subdirectory(android_input/)
197 add_subdirectory(scene/)
198 add_subdirectory(draw/)
199+add_subdirectory(examples/)
200
201 link_directories(${LIBRARY_OUTPUT_PATH})
202
203@@ -50,6 +51,7 @@
204 mirdraw
205 mirtestdraw
206 mirlogging
207+ mirdemoshell
208
209 mir-test
210 mir-test-doubles
211
212=== added directory 'tests/unit-tests/examples'
213=== added file 'tests/unit-tests/examples/CMakeLists.txt'
214--- tests/unit-tests/examples/CMakeLists.txt 1970-01-01 00:00:00 +0000
215+++ tests/unit-tests/examples/CMakeLists.txt 2014-07-18 20:30:30 +0000
216@@ -0,0 +1,5 @@
217+list(APPEND UNIT_TEST_SOURCES
218+ ${CMAKE_CURRENT_SOURCE_DIR}/test_demo_compositor.cpp
219+)
220+
221+set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE)
222
223=== added file 'tests/unit-tests/examples/test_demo_compositor.cpp'
224--- tests/unit-tests/examples/test_demo_compositor.cpp 1970-01-01 00:00:00 +0000
225+++ tests/unit-tests/examples/test_demo_compositor.cpp 2014-07-18 20:30:30 +0000
226@@ -0,0 +1,108 @@
227+/*
228+ * Copyright © 2014 Canonical Ltd.
229+ *
230+ * This program is free software: you can redistribute it and/or modify
231+ * it under the terms of the GNU General Public License version 3 as
232+ * published by the Free Software Foundation.
233+ *
234+ * This program is distributed in the hope that it will be useful,
235+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
236+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
237+ * GNU General Public License for more details.
238+ *
239+ * You should have received a copy of the GNU General Public License
240+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
241+ *
242+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
243+ */
244+
245+#include "examples/demo-shell/demo_compositor.h"
246+#include "src/server/report/null_report_factory.h"
247+#include "mir_test_doubles/mock_display_buffer.h"
248+#include "mir_test_doubles/stub_gl_program_factory.h"
249+#include "mir_test_doubles/mock_scene.h"
250+#include "mir_test_doubles/stub_scene_element.h"
251+#include "mir_test_doubles/stub_renderable.h"
252+#include "mir_test_doubles/mock_gl.h"
253+#include "mir_test/fake_shared.h"
254+#include <gtest/gtest.h>
255+
256+namespace me = mir::examples;
257+namespace mc = mir::compositor;
258+namespace mt = mir::test;
259+namespace mr = mir::report;
260+namespace mtd = mir::test::doubles;
261+namespace mg = mir::graphics;
262+namespace geom = mir::geometry;
263+
264+struct DemoCompositor : public testing::Test
265+{
266+ DemoCompositor() :
267+ display_area{{10, 10}, {100,100}},
268+ titlebar_height{5},
269+ shadow_radius{3},
270+ stub_report{mr::null_compositor_report()},
271+ fullscreen{std::make_shared<mtd::StubSceneElement>(
272+ std::make_shared<mtd::StubRenderable>(display_area))},
273+ onscreen_titlebar{std::make_shared<mtd::StubSceneElement>(
274+ std::make_shared<mtd::StubRenderable>(geom::Rectangle{{90,90},{10,10}}))},
275+ onscreen_shadows{std::make_shared<mtd::StubSceneElement>(
276+ std::make_shared<mtd::StubRenderable>(geom::Rectangle{{10,10},{10,10}}))},
277+ onscreen_shadows_and_titlebar{std::make_shared<mtd::StubSceneElement>(
278+ std::make_shared<mtd::StubRenderable>(geom::Rectangle{{10,14},{10,82}}))}
279+ {
280+ using namespace testing;
281+ ON_CALL(mock_display_buffer, view_area())
282+ .WillByDefault(Return(display_area));
283+ }
284+
285+ geom::Rectangle const display_area;
286+ geom::Height const titlebar_height;
287+ unsigned int const shadow_radius;
288+ std::shared_ptr<mc::CompositorReport> const stub_report;
289+ std::shared_ptr<mc::SceneElement> const fullscreen;
290+ std::shared_ptr<mc::SceneElement> const onscreen_titlebar;
291+ std::shared_ptr<mc::SceneElement> const onscreen_shadows;
292+ std::shared_ptr<mc::SceneElement> const onscreen_shadows_and_titlebar;
293+
294+ testing::NiceMock<mtd::MockDisplayBuffer> mock_display_buffer;
295+ mtd::MockScene mock_scene;
296+ mtd::StubGLProgramFactory stub_program_factory;
297+ testing::NiceMock<mtd::MockGL> mock_gl;
298+};
299+
300+TEST_F(DemoCompositor, does_not_use_optimized_path_if_titlebar_needs_to_be_drawn)
301+{
302+ using namespace testing;
303+ EXPECT_CALL(mock_scene, scene_elements_for(_))
304+ .WillOnce(Return(mc::SceneElementSequence{onscreen_titlebar}))
305+ .WillOnce(Return(mc::SceneElementSequence{onscreen_shadows}))
306+ .WillOnce(Return(mc::SceneElementSequence{onscreen_shadows_and_titlebar}));
307+ EXPECT_CALL(mock_display_buffer, post_renderables_if_optimizable(_))
308+ .Times(0);
309+ EXPECT_CALL(mock_display_buffer, post_update())
310+ .Times(3);
311+
312+ me::DemoCompositor demo_compositor(
313+ mock_display_buffer, mt::fake_shared(mock_scene), stub_program_factory,
314+ stub_report, shadow_radius, titlebar_height);
315+ demo_compositor.composite();
316+ demo_compositor.composite();
317+ demo_compositor.composite();
318+}
319+
320+TEST_F(DemoCompositor, uses_optimized_path_if_no_decorations_present)
321+{
322+ using namespace testing;
323+ EXPECT_CALL(mock_scene, scene_elements_for(_))
324+ .WillOnce(Return(mc::SceneElementSequence{fullscreen}))
325+ .WillOnce(Return(mc::SceneElementSequence{onscreen_shadows_and_titlebar, fullscreen}));
326+ EXPECT_CALL(mock_display_buffer, post_renderables_if_optimizable(_))
327+ .Times(2);
328+
329+ me::DemoCompositor demo_compositor(
330+ mock_display_buffer, mt::fake_shared(mock_scene), stub_program_factory,
331+ stub_report, shadow_radius, titlebar_height);
332+ demo_compositor.composite();
333+ demo_compositor.composite();
334+}

Subscribers

People subscribed via source and target branches