Mir

Merge lp:~kdub/mir/post-if-optimizable into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 1649
Proposed branch: lp:~kdub/mir/post-if-optimizable
Merge into: lp:mir
Prerequisite: lp:~kdub/mir/connect-fallback-to-hwc-device
Diff against target: 702 lines (+149/-182)
22 files modified
examples/render_overlays.cpp (+1/-2)
include/platform/mir/graphics/display_buffer.h (+16/-8)
include/test/mir_test_doubles/mock_display_buffer.h (+1/-2)
include/test/mir_test_doubles/mock_render_function.h (+0/-40)
include/test/mir_test_doubles/null_display_buffer.h (+1/-3)
include/test/mir_test_doubles/stub_display_builder.h (+1/-3)
src/platform/graphics/android/display_buffer.cpp (+27/-11)
src/platform/graphics/android/display_buffer.h (+1/-3)
src/platform/graphics/mesa/display_buffer.cpp (+2/-4)
src/platform/graphics/mesa/display_buffer.h (+1/-2)
src/server/compositor/screencast_display_buffer.cpp (+2/-7)
src/server/compositor/screencast_display_buffer.h (+1/-3)
src/server/graphics/nested/nested_output.cpp (+2/-3)
src/server/graphics/nested/nested_output.h (+1/-3)
src/server/graphics/offscreen/display_buffer.cpp (+2/-3)
src/server/graphics/offscreen/display_buffer.h (+1/-3)
tests/integration-tests/test_surface_stack_with_compositor.cpp (+2/-3)
tests/unit-tests/compositor/test_screencast_display_buffer.cpp (+2/-24)
tests/unit-tests/graphics/android/test_fb_device.cpp (+0/-1)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+8/-29)
tests/unit-tests/graphics/android/test_hwc_display.cpp (+76/-24)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+1/-1)
To merge this branch: bzr merge lp:~kdub/mir/post-if-optimizable
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alberto Aguirre (community) Approve
Andreas Pokorny (community) Approve
Alexandros Frantzis (community) Approve
Chris Halse Rogers Needs Information
Review via email: mp+217991@code.launchpad.net

Commit message

graphics: change the DisplayBuffer::render_and_post_update() so that it can reject the list submitted to it (more like can_bypass). Have android scan over the list and reject lists that are not supportable by HWC

Description of the change

graphics: change the DisplayBuffer::render_and_post_update() so that it can reject the list submitted to it (more like can_bypass). Have android scan over the list and reject lists that are not supportable by HWC.

When I reintroduced Renderable, it was an interface that android could guarantee that it would render via HWC. It has morphed a bit since then, and will continue to morph as we go to support more GL shell stuff. Now the list has to be scanned so the platform can figure out if the image the RenderableList represents is applicable to the platform's capabilities.

Alberto asked on IRC what if the compositor writer wants to do something that can't be represented with a RenderableList, like spread or a window animation. The answer to this question is that the compositor writer knows that something complex is going on so they should just stick to post_update() for those complex frames and then try the optimization function again when the scene becomes simpler.

The compositor writer doesn't have to think about what's going on under the hood or what platform they are on, they just have to think about "can what I want on the screen be represented by a RenderableList". If it can, then they're doing something simple enough that we might know a way to optimize, and if it cannot be represented by a RenderableList, they have the OpenGL available to do whatever they want.

note1:
If you're interested in what this means for the DefaultDisplayBufferCompositor or mesa, take a look here:
http://bazaar.launchpad.net/~kdub/mir/future-default-display-buffer-compositor/view/head:/src/server/compositor/default_display_buffer_compositor.cpp#L64
http://bazaar.launchpad.net/~kdub/mir/future-default-display-buffer-compositor/view/head:/src/platform/graphics/mesa/display_buffer.cpp#L195

There's still that same optimized/not optimized code path in DefaultDisplayBufferCompositor, which is nice.

note2:
For the android platform, something like this could happen:
1) Scan list, list passes hwc check
2) hwc prepare() rejects some of the renderables
3) mir has to draw OpenGL via the fallback path
4) hwc set() will post the accepted renderables as overlays, along with the fallback, OpenGL renderables

note3:
For the mesa platform, I hope it improves so mesa scans the list, and figures if it can do 'hardware cursor + bypass' or "only bypass" or "only hardware cursor"

To post a comment you must log in.
Revision history for this message
Kevin DuBois (kdub) wrote :

Also, this breaks API because of the change to DisplayBuffer (although that API is not really used in the wild yet). W.R.T the new versioning policies, maybe I should put that in the commit msg? the changelog?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

What if some of the renderables in the list can be rendered with optimization and others cannot? AFAICT from the description post_renderables_if_optimizable() is all or nothing (although it doesn't need to be), so we would miss the opportunity to render some of the renderables more efficiently.

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

"hudson.util.IOException2: remote file operation failed", hopefully a retry will work

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

> What if some of the renderables in the list can be rendered with optimization
> and others cannot? AFAICT from the description
> post_renderables_if_optimizable() is all or nothing (although it doesn't need
> to be), so we would miss the opportunity to render some of the renderables
> more efficiently.

So, we touched on this in this in the standup, but we were worried about the Nested communication of this list when we go to enable Nested optimizations (we don't want to have the render negotiated with IPC). If the DisplayBuffer wants to optimize any one of the renderables, will have to handle the list, which works for mesa or android.

Revision history for this message
Chris Halse Rogers (raof) wrote :

I thought that we were migrating the basic GL composition pass down into DisplayBuffer? So that if your scene is expressible exclusively in terms of a RenderableList then you can just dump it into render_and_post_update() and the DisplayBuffer will either GL or overlay?

This would satisfy the ‘needs no negotiation’ criterion, and would seem to make the higher levels a little bit less complex?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

> I thought that we were migrating the basic GL composition pass down into
> DisplayBuffer? So that if your scene is expressible exclusively in terms of a
> RenderableList then you can just dump it into render_and_post_update() and the
> DisplayBuffer will either GL or overlay?
>
> This would satisfy the ‘needs no negotiation’ criterion, and would seem to
> make the higher levels a little bit less complex?

So there's been a subtle shift since Renderable was reintroduced as it merged closer to the surface classes. Android can now know beforehand that it can reject the list (eg, if something is transformed to non-90degree).
The option to reject works nicely with mesa too, as mesa now does not have the burden of drawing with OpenGL, it can just reject, and the platform-independent GL compositor takes over.

So basically, the lp:~kdub/mir/overlay-gl-program branch just handles the quirky requirement that android has to draw the fallback with OpenGL. We do not require all the platforms to draw (just to reject), which is a bit nicer for the non-android DisplayBuffer implementations too.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Ah. Let me see if I've got how the nested case will work:

The inner-Mir will always accept whatever renderable list you care to pass to post_renderables_if_optimizable() and send them down to the outer-Mir. The outer-Mir will then post_renderables_if_optimizable() and either go “yay!” or do a GL composition pass.

And we optimise further the implementation of post_renderables_if_optimizable() running on the hardware will only bail if none of the renderables are optimisable.

So this makes it easier to bring up platforms in the short term, and will probably be a no-op in the long term?

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

> Ah. Let me see if I've got how the nested case will work:
>
> The inner-Mir will always accept whatever renderable list you care to pass to
> post_renderables_if_optimizable() and send them down to the outer-Mir. The
> outer-Mir will then post_renderables_if_optimizable() and either go “yay!” or
> do a GL composition pass.
>
> And we optimise further the implementation of
> post_renderables_if_optimizable() running on the hardware will only bail if
> none of the renderables are optimisable.
>

Sounds right to me.

> So this makes it easier to bring up platforms in the short term, and will
> probably be a no-op in the long term?

I'm confused as what will 'be a no-op in the long term'. post_renderables_if_optimizable() will be the hardware optimized interface that compositors should try if they know they're doing something simple, and post_update() will be the interface that the compositors use to do anything they want with GL

Revision history for this message
Chris Halse Rogers (raof) wrote :

On Wed, May 14, 2014 at 3:54 AM, Kevin DuBois
<email address hidden> wrote:
>> So this makes it easier to bring up platforms in the short term,
>> and will
>> probably be a no-op in the long term?
>
> I'm confused as what will 'be a no-op in the long term'.
> post_renderables_if_optimizable() will be the hardware optimized
> interface that compositors should try if they know they're doing
> something simple, and post_update() will be the interface that the
> compositors use to do anything they want with GL

What I mean is - as a platform (and, conceivably, Renderable) grows in
sophistication, there will be fewer and fewer RenderableLists that
contain only unoptimisable Renderables. So what I mean by “no-op”
is that post_renderables_if_optimizable() will end up always returning
true.

Particularly since the cursor is one of those Renderables.

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

>
>
> On Wed, May 14, 2014 at 3:54 AM, Kevin DuBois
> <email address hidden> wrote:
> >> So this makes it easier to bring up platforms in the short term,
> >> and will
> >> probably be a no-op in the long term?
> >
> > I'm confused as what will 'be a no-op in the long term'.
> > post_renderables_if_optimizable() will be the hardware optimized
> > interface that compositors should try if they know they're doing
> > something simple, and post_update() will be the interface that the
> > compositors use to do anything they want with GL
>
> What I mean is - as a platform (and, conceivably, Renderable) grows in
> sophistication, there will be fewer and fewer RenderableLists that
> contain only unoptimisable Renderables. So what I mean by “no-op”
> is that post_renderables_if_optimizable() will end up always returning
> true.

sure, I hope that it returns true more often as time goes on. I think though that we'll always need the post_update() interface for the compositors who know beforehand that they're doing something like wobbly windows that isn't representable by a RenderableList.

Revision history for this message
Chris Halse Rogers (raof) wrote :

On Wed, May 14, 2014 at 10:49 AM, Kevin DuBois
<email address hidden> wrote:
>>
>>
>> On Wed, May 14, 2014 at 3:54 AM, Kevin DuBois
>> <email address hidden> wrote:
>> >> So this makes it easier to bring up platforms in the short term,
>> >> and will
>> >> probably be a no-op in the long term?
>> >
>> > I'm confused as what will 'be a no-op in the long term'.
>> > post_renderables_if_optimizable() will be the hardware optimized
>> > interface that compositors should try if they know they're doing
>> > something simple, and post_update() will be the interface that the
>> > compositors use to do anything they want with GL
>>
>> What I mean is - as a platform (and, conceivably, Renderable) grows
>> in
>> sophistication, there will be fewer and fewer RenderableLists that
>> contain only unoptimisable Renderables. So what I mean by
>> “no-op”
>> is that post_renderables_if_optimizable() will end up always
>> returning
>> true.
>
> sure, I hope that it returns true more often as time goes on. I think
> though that we'll always need the post_update() interface for the
> compositors who know beforehand that they're doing something like
> wobbly windows that isn't representable by a RenderableList.

It kinda is - the results of the GL composition as a Renedeable, plus a
Cursor Renderable.

This does suggest that maybe the interaction with cursor drawing needs
thinking.

None of this is blocking, just thinking.

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

Looks good codewise. I am confused about:

> So basically, the lp:~kdub/mir/overlay-gl-program branch just handles the quirky requirement that android has to draw the fallback with OpenGL

Why does Android have to use the internal fallback and not render with GL using the normal renderer, like Mesa is supposed to do in this scenario?

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

> Looks good codewise. I am confused about:
>
> > So basically, the lp:~kdub/mir/overlay-gl-program branch just handles the
> quirky requirement that android has to draw the fallback with OpenGL
>
> Why does Android have to use the internal fallback and not render with GL
> using the normal renderer, like Mesa is supposed to do in this scenario?

Never mind, I just reread the description of https://code.launchpad.net/~kdub/mir/overlay-gl-program/+merge/217153

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

> It kinda is - the results of the GL composition as a Renedeable, plus a
> Cursor Renderable.
>
> This does suggest that maybe the interaction with cursor drawing needs
> thinking.
>
> None of this is blocking, just thinking.

Yeah, there's some "abstraction-defense" that needs to be done with the mesa cursor, future steps.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I like the simplification of the interface. Just some small findings:

Any reason why you are not reusing the typedef RenderableList in + 1052 + 1056 + 1248 + 1251 and why you are not using operator== instead of the matcher in + 1029.

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/render_overlays.cpp'
2--- examples/render_overlays.cpp 2014-05-14 18:40:19 +0000
3+++ examples/render_overlays.cpp 2014-05-21 17:27:23 +0000
4@@ -198,8 +198,7 @@
5 buffer.make_current();
6 client1->update_green_channel();
7 client2->update_green_channel();
8- auto render_fn = [](mg::Renderable const&) {};
9- buffer.render_and_post_update(renderlist, render_fn);
10+ buffer.post_renderables_if_optimizable(renderlist);
11 });
12 }
13 return 0;
14
15=== modified file 'include/platform/mir/graphics/display_buffer.h'
16--- include/platform/mir/graphics/display_buffer.h 2014-03-26 05:48:59 +0000
17+++ include/platform/mir/graphics/display_buffer.h 2014-05-21 17:27:23 +0000
18@@ -24,7 +24,6 @@
19 #include <mir_toolkit/common.h>
20
21 #include <memory>
22-#include <functional>
23
24 namespace mir
25 {
26@@ -51,13 +50,22 @@
27 /** This will trigger OpenGL rendering and post the result to the screen. */
28 virtual void post_update() = 0;
29
30- /** This will render renderlist to the screen and post the result to the screen.
31- For each renderable, the DisplayBuffer will decide if its more efficient to render
32- that Renderable via OpenGL, or via another method. If the Renderable is to be rendered
33- via OpenGL, render_fn will be invoked on that Renderable. */
34- virtual void render_and_post_update(
35- RenderableList const& renderlist,
36- std::function<void(Renderable const&)> const& render_fn) = 0;
37+ /** This will render renderlist to the screen and post the result to the
38+ * screen if there is a hardware optimization that can be done.
39+ * \param [in] renderlist
40+ * The renderables that should appear on the screen if the hardware
41+ * is capable of optmizing that list somehow. If what you want
42+ * displayed on the screen cannot be represented by a RenderableList,
43+ * then you should draw using OpenGL and use post_update()
44+ * \returns
45+ * true if the hardware can optimize the rendering of the list.
46+ * When this call completes, the renderlist will have been posted
47+ * to the screen.
48+ * false if the hardware platform cannot optimize the list. The screen
49+ * will not be updated. The caller should render the list another way,
50+ * and post using post_update()
51+ **/
52+ virtual bool post_renderables_if_optimizable(RenderableList const& renderlist) = 0;
53
54 /** to be deprecated */
55 virtual bool can_bypass() const = 0;
56
57=== modified file 'include/test/mir_test_doubles/mock_display_buffer.h'
58--- include/test/mir_test_doubles/mock_display_buffer.h 2014-03-26 05:48:59 +0000
59+++ include/test/mir_test_doubles/mock_display_buffer.h 2014-05-21 17:27:23 +0000
60@@ -46,8 +46,7 @@
61 MOCK_METHOD0(release_current, void());
62 MOCK_METHOD0(post_update, void());
63 MOCK_CONST_METHOD0(can_bypass, bool());
64- MOCK_METHOD2(render_and_post_update, void(graphics::RenderableList const&,
65- std::function<void(graphics::Renderable const&)> const&));
66+ MOCK_METHOD1(post_renderables_if_optimizable, bool(graphics::RenderableList const&));
67 MOCK_CONST_METHOD0(orientation, MirOrientation());
68 };
69
70
71=== removed file 'include/test/mir_test_doubles/mock_render_function.h'
72--- include/test/mir_test_doubles/mock_render_function.h 2014-02-18 16:48:24 +0000
73+++ include/test/mir_test_doubles/mock_render_function.h 1970-01-01 00:00:00 +0000
74@@ -1,40 +0,0 @@
75-/*
76- * Copyright © 2014 Canonical Ltd.
77- *
78- * This program is free software: you can redistribute it and/or modify it
79- * under the terms of the GNU General Public License version 3,
80- * as published by the Free Software Foundation.
81- *
82- * This program is distributed in the hope that it will be useful,
83- * but WITHOUT ANY WARRANTY; without even the implied warranty of
84- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
85- * GNU General Public License for more details.
86- *
87- * You should have received a copy of the GNU General Public License
88- * along with this program. If not, see <http://www.gnu.org/licenses/>.
89- *
90- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
91- */
92-
93-#ifndef MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
94-#define MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
95-
96-#include <mir/graphics/renderable.h>
97-
98-namespace mir
99-{
100-namespace test
101-{
102-namespace doubles
103-{
104-
105-struct MockRenderFunction
106-{
107- MOCK_METHOD1(called, void(graphics::Renderable const&));
108-};
109-
110-}
111-}
112-}
113-
114-#endif /* MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_ */
115
116=== modified file 'include/test/mir_test_doubles/null_display_buffer.h'
117--- include/test/mir_test_doubles/null_display_buffer.h 2014-03-26 05:48:59 +0000
118+++ include/test/mir_test_doubles/null_display_buffer.h 2014-05-21 17:27:23 +0000
119@@ -36,9 +36,7 @@
120 void release_current() {}
121 void post_update() {}
122 bool can_bypass() const override { return false; }
123- void render_and_post_update(
124- graphics::RenderableList const&,
125- std::function<void(graphics::Renderable const&)> const&) {}
126+ bool post_renderables_if_optimizable(graphics::RenderableList const&) { return false; }
127 MirOrientation orientation() const override { return mir_orientation_normal; }
128 };
129
130
131=== modified file 'include/test/mir_test_doubles/stub_display_builder.h'
132--- include/test/mir_test_doubles/stub_display_builder.h 2014-05-01 07:13:02 +0000
133+++ include/test/mir_test_doubles/stub_display_builder.h 2014-05-21 17:27:23 +0000
134@@ -42,9 +42,7 @@
135 void release_current() {}
136 void post_update() {}
137 bool can_bypass() const override { return false; }
138- void render_and_post_update(
139- graphics::RenderableList const&,
140- std::function<void(graphics::Renderable const&)> const&) {}
141+ bool post_renderables_if_optimizable(graphics::RenderableList const&) { return false; }
142 MirOrientation orientation() const override { return mir_orientation_normal; }
143 void configure(graphics::DisplayConfigurationOutput const&) {}
144 graphics::DisplayConfigurationOutput configuration() const
145
146=== modified file 'src/platform/graphics/android/display_buffer.cpp'
147--- src/platform/graphics/android/display_buffer.cpp 2014-05-19 02:55:29 +0000
148+++ src/platform/graphics/android/display_buffer.cpp 2014-05-21 17:27:23 +0000
149@@ -30,6 +30,28 @@
150 namespace mga=mir::graphics::android;
151 namespace geom=mir::geometry;
152
153+namespace
154+{
155+bool renderable_list_is_hwc_incompatible(mg::RenderableList const& list)
156+{
157+ if (list.empty())
158+ return true;
159+
160+ for(auto const& renderable : list)
161+ {
162+ //TODO: enable alpha, 90 deg rotation
163+ static glm::mat4 const identity;
164+ if (renderable->shaped() ||
165+ renderable->alpha_enabled() ||
166+ (renderable->transformation() != identity))
167+ {
168+ return true;
169+ }
170+ }
171+ return false;
172+}
173+}
174+
175 mga::DisplayBuffer::DisplayBuffer(
176 std::shared_ptr<FramebufferBundle> const& fb_bundle,
177 std::shared_ptr<DisplayDevice> const& display_device,
178@@ -86,20 +108,14 @@
179 gl_context.release_current();
180 }
181
182-void mga::DisplayBuffer::render_and_post_update(
183- RenderableList const& renderlist,
184- std::function<void(Renderable const&)> const&)
185+bool mga::DisplayBuffer::post_renderables_if_optimizable(RenderableList const& renderlist)
186 {
187- if (renderlist.empty())
188- {
189- display_device->render_gl(gl_context);
190- }
191- else
192- {
193- display_device->prepare_overlays(gl_context, renderlist, overlay_program);
194- }
195+ if (renderable_list_is_hwc_incompatible(renderlist))
196+ return false;
197
198+ display_device->prepare_overlays(gl_context, renderlist, overlay_program);
199 post();
200+ return true;
201 }
202
203 void mga::DisplayBuffer::post_update()
204
205=== modified file 'src/platform/graphics/android/display_buffer.h'
206--- src/platform/graphics/android/display_buffer.h 2014-05-01 07:13:02 +0000
207+++ src/platform/graphics/android/display_buffer.h 2014-05-21 17:27:23 +0000
208@@ -52,9 +52,7 @@
209 void post_update();
210 bool can_bypass() const override;
211
212- void render_and_post_update(
213- RenderableList const& renderlist,
214- std::function<void(Renderable const&)> const& render_fn);
215+ bool post_renderables_if_optimizable(RenderableList const& renderlist);
216 MirOrientation orientation() const override;
217
218 DisplayConfigurationOutput configuration() const;
219
220=== modified file 'src/platform/graphics/mesa/display_buffer.cpp'
221--- src/platform/graphics/mesa/display_buffer.cpp 2014-05-05 03:36:45 +0000
222+++ src/platform/graphics/mesa/display_buffer.cpp 2014-05-21 17:27:23 +0000
223@@ -197,11 +197,9 @@
224 return rotation;
225 }
226
227-void mgm::DisplayBuffer::render_and_post_update(
228- RenderableList const&,
229- std::function<void(Renderable const&)> const&)
230+bool mgm::DisplayBuffer::post_renderables_if_optimizable(RenderableList const&)
231 {
232- post_update(nullptr);
233+ return false;
234 }
235
236 void mgm::DisplayBuffer::post_update()
237
238=== modified file 'src/platform/graphics/mesa/display_buffer.h'
239--- src/platform/graphics/mesa/display_buffer.h 2014-03-27 09:52:04 +0000
240+++ src/platform/graphics/mesa/display_buffer.h 2014-05-21 17:27:23 +0000
241@@ -61,8 +61,7 @@
242
243 bool can_bypass() const override;
244 void post_update(std::shared_ptr<graphics::Buffer> bypass_buf) override;
245- void render_and_post_update(RenderableList const& renderlist,
246- std::function<void(Renderable const&)> const& render_fn);
247+ bool post_renderables_if_optimizable(RenderableList const& renderlist) override;
248 MirOrientation orientation() const override;
249 void schedule_set_crtc();
250 void wait_for_page_flip();
251
252=== modified file 'src/server/compositor/screencast_display_buffer.cpp'
253--- src/server/compositor/screencast_display_buffer.cpp 2014-03-26 05:48:59 +0000
254+++ src/server/compositor/screencast_display_buffer.cpp 2014-05-21 17:27:23 +0000
255@@ -85,14 +85,9 @@
256 old_viewport[2], old_viewport[3]);
257 }
258
259-void mc::ScreencastDisplayBuffer::render_and_post_update(
260- mg::RenderableList const& renderables,
261- std::function<void(mg::Renderable const&)> const& render)
262+bool mc::ScreencastDisplayBuffer::post_renderables_if_optimizable(mg::RenderableList const&)
263 {
264- for (auto const& renderable : renderables)
265- render(*renderable);
266-
267- post_update();
268+ return false;
269 }
270
271 void mc::ScreencastDisplayBuffer::post_update()
272
273=== modified file 'src/server/compositor/screencast_display_buffer.h'
274--- src/server/compositor/screencast_display_buffer.h 2014-03-26 05:48:59 +0000
275+++ src/server/compositor/screencast_display_buffer.h 2014-05-21 17:27:23 +0000
276@@ -59,9 +59,7 @@
277
278 void release_current();
279
280- void render_and_post_update(
281- graphics::RenderableList const&,
282- std::function<void(graphics::Renderable const&)> const&);
283+ bool post_renderables_if_optimizable(graphics::RenderableList const&);
284
285 void post_update();
286
287
288=== modified file 'src/server/graphics/nested/nested_output.cpp'
289--- src/server/graphics/nested/nested_output.cpp 2014-05-08 11:02:47 +0000
290+++ src/server/graphics/nested/nested_output.cpp 2014-05-21 17:27:23 +0000
291@@ -71,10 +71,9 @@
292 return false;
293 }
294
295-void mgn::detail::NestedOutput::render_and_post_update(
296- RenderableList const&,
297- std::function<void(Renderable const&)> const&)
298+bool mgn::detail::NestedOutput::post_renderables_if_optimizable(RenderableList const&)
299 {
300+ return false;
301 }
302
303 MirOrientation mgn::detail::NestedOutput::orientation() const
304
305=== modified file 'src/server/graphics/nested/nested_output.h'
306--- src/server/graphics/nested/nested_output.h 2014-05-08 11:02:47 +0000
307+++ src/server/graphics/nested/nested_output.h 2014-05-21 17:27:23 +0000
308@@ -51,9 +51,7 @@
309 virtual bool can_bypass() const override;
310 MirOrientation orientation() const override;
311
312- void render_and_post_update(
313- RenderableList const& renderlist,
314- std::function<void(Renderable const&)> const& render_fn);
315+ bool post_renderables_if_optimizable(RenderableList const& renderlist);
316
317 NestedOutput(NestedOutput const&) = delete;
318 NestedOutput operator=(NestedOutput const&) = delete;
319
320=== modified file 'src/server/graphics/offscreen/display_buffer.cpp'
321--- src/server/graphics/offscreen/display_buffer.cpp 2014-03-26 05:48:59 +0000
322+++ src/server/graphics/offscreen/display_buffer.cpp 2014-05-21 17:27:23 +0000
323@@ -149,10 +149,9 @@
324 return false;
325 }
326
327-void mgo::DisplayBuffer::render_and_post_update(
328- RenderableList const&,
329- std::function<void(Renderable const&)> const&)
330+bool mgo::DisplayBuffer::post_renderables_if_optimizable(RenderableList const&)
331 {
332+ return false;
333 }
334
335 MirOrientation mgo::DisplayBuffer::orientation() const
336
337=== modified file 'src/server/graphics/offscreen/display_buffer.h'
338--- src/server/graphics/offscreen/display_buffer.h 2014-03-26 05:48:59 +0000
339+++ src/server/graphics/offscreen/display_buffer.h 2014-05-21 17:27:23 +0000
340@@ -70,9 +70,7 @@
341 bool can_bypass() const;
342 MirOrientation orientation() const override;
343
344- void render_and_post_update(
345- RenderableList const& renderlist,
346- std::function<void(Renderable const&)> const& render_fn);
347+ bool post_renderables_if_optimizable(RenderableList const& renderlist) override;
348
349 private:
350 SurfacelessEGLContext const egl_context;
351
352=== modified file 'tests/integration-tests/test_surface_stack_with_compositor.cpp'
353--- tests/integration-tests/test_surface_stack_with_compositor.cpp 2014-05-19 02:55:29 +0000
354+++ tests/integration-tests/test_surface_stack_with_compositor.cpp 2014-05-21 17:27:23 +0000
355@@ -66,11 +66,10 @@
356 return true;
357 }
358
359- void render_and_post_update(
360- mg::RenderableList const&,
361- std::function<void(mg::Renderable const&)> const&) override
362+ bool post_renderables_if_optimizable(mg::RenderableList const&)
363 {
364 increment_post_count();
365+ return true;
366 }
367
368 void post_update() override
369
370=== modified file 'tests/unit-tests/compositor/test_screencast_display_buffer.cpp'
371--- tests/unit-tests/compositor/test_screencast_display_buffer.cpp 2014-03-05 07:02:29 +0000
372+++ tests/unit-tests/compositor/test_screencast_display_buffer.cpp 2014-05-21 17:27:23 +0000
373@@ -34,16 +34,6 @@
374 namespace
375 {
376
377-struct MockRenderFunctor
378-{
379- void operator()(mg::Renderable const& r)
380- {
381- operator_call(&r);
382- }
383-
384- MOCK_METHOD1(operator_call, void(mg::Renderable const*));
385-};
386-
387 struct ScreencastDisplayBufferTest : testing::Test
388 {
389 testing::NiceMock<mtd::MockGL> mock_gl;
390@@ -158,10 +148,8 @@
391 db.post_update();
392 }
393
394-TEST_F(ScreencastDisplayBufferTest, renders_renderables_on_render_and_post_update)
395+TEST_F(ScreencastDisplayBufferTest, rejects_attempt_to_optimize)
396 {
397- using namespace testing;
398-
399 geom::Rectangle const rect{{100,100}, {800,600}};
400 mtd::StubBuffer stub_buffer;
401
402@@ -172,15 +160,5 @@
403
404 mc::ScreencastDisplayBuffer db{rect, stub_buffer};
405
406- Mock::VerifyAndClearExpectations(&mock_gl);
407- MockRenderFunctor mock_render_functor;
408-
409- InSequence s;
410-
411- for (auto const& renderable : renderables)
412- EXPECT_CALL(mock_render_functor, operator_call(renderable.get()));
413-
414- EXPECT_CALL(mock_gl, glFinish());
415-
416- db.render_and_post_update(renderables, std::ref(mock_render_functor));
417+ EXPECT_FALSE(db.post_renderables_if_optimizable(renderables));
418 }
419
420=== modified file 'tests/unit-tests/graphics/android/test_fb_device.cpp'
421--- tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-19 02:55:29 +0000
422+++ tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-21 17:27:23 +0000
423@@ -26,7 +26,6 @@
424 #include "mir_test_doubles/stub_buffer.h"
425 #include "mir_test_doubles/stub_renderable.h"
426 #include "mir_test_doubles/mock_android_native_buffer.h"
427-#include "mir_test_doubles/mock_render_function.h"
428 #include "mir_test_doubles/mock_swapping_gl_context.h"
429 #include "mir_test_doubles/stub_renderable_list_compositor.h"
430 #include "mir_test_doubles/mock_renderable_list_compositor.h"
431
432=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
433--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-05-19 02:55:29 +0000
434+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-05-21 17:27:23 +0000
435@@ -31,7 +31,6 @@
436 #include "mir_test_doubles/mock_hwc_device_wrapper.h"
437 #include "mir_test/fake_shared.h"
438 #include "hwc_struct_helpers.h"
439-#include "mir_test_doubles/mock_render_function.h"
440 #include "mir_test_doubles/mock_swapping_gl_context.h"
441 #include "mir_test_doubles/stub_swapping_gl_context.h"
442 #include "mir_test_doubles/stub_renderable_list_compositor.h"
443@@ -252,36 +251,16 @@
444 device.render_gl(stub_context);
445 }
446
447-namespace
448-{
449-MATCHER_P(MatchesRenderableList, value, std::string(""))
450-{
451- if (value.size() != arg.size())
452- return false;
453-
454- bool match{true};
455- auto it = value.begin();
456- for(auto const& a : arg)
457- {
458- if (a != *it)
459- match = false;
460- it++;
461- }
462- return match;
463-}
464-
465-}
466-
467 TEST_F(HwcDevice, calls_render_with_list_of_rejected_overlays)
468 {
469 using namespace testing;
470 mtd::MockRenderableListCompositor mock_compositor;
471
472- std::list<std::shared_ptr<mg::Renderable>> updated_list({
473+ mg::RenderableList updated_list({
474 stub_renderable1,
475 stub_renderable2
476 });
477- std::list<std::shared_ptr<mg::Renderable>> expected_renderable_list({
478+ mg::RenderableList expected_renderable_list({
479 stub_renderable2
480 });
481
482@@ -303,7 +282,7 @@
483 contents.hwLayers[2].compositionType = HWC_FRAMEBUFFER_TARGET;
484 }));
485
486- EXPECT_CALL(mock_compositor, render(MatchesRenderableList(expected_renderable_list),Ref(mock_context)))
487+ EXPECT_CALL(mock_compositor, render(expected_renderable_list,Ref(mock_context)))
488 .InSequence(seq);
489
490 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
491@@ -333,7 +312,7 @@
492 .InSequence(seq);
493 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
494
495- std::list<std::shared_ptr<mg::Renderable>> updated_list({
496+ mg::RenderableList updated_list({
497 stub_renderable1,
498 stub_renderable2
499 });
500@@ -408,7 +387,7 @@
501 };
502
503 /* set non-default renderlist */
504- std::list<std::shared_ptr<mg::Renderable>> updated_list({
505+ mg::RenderableList updated_list({
506 stub_renderable1,
507 stub_renderable1
508 });
509@@ -491,7 +470,7 @@
510 TEST_F(HwcDevice, discards_second_set_if_all_overlays_and_nothing_has_changed)
511 {
512 using namespace testing;
513- std::list<std::shared_ptr<mg::Renderable>> updated_list({
514+ mg::RenderableList updated_list({
515 stub_renderable1,
516 stub_renderable2
517 });
518@@ -519,7 +498,7 @@
519 TEST_F(HwcDevice, submits_every_time_if_at_least_one_layer_is_gl_rendered)
520 {
521 using namespace testing;
522- std::list<std::shared_ptr<mg::Renderable>> updated_list({
523+ mg::RenderableList updated_list({
524 stub_renderable1,
525 stub_renderable2
526 });
527@@ -562,7 +541,7 @@
528 .WillOnce(Return(native_handle_2))
529 .WillOnce(Return(native_handle_3));
530
531- std::list<std::shared_ptr<mg::Renderable>> updated_list({stub_renderable1});
532+ mg::RenderableList updated_list({stub_renderable1});
533
534 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
535
536
537=== modified file 'tests/unit-tests/graphics/android/test_hwc_display.cpp'
538--- tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-19 02:55:29 +0000
539+++ tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-21 17:27:23 +0000
540@@ -31,6 +31,11 @@
541 #include "mir_test_doubles/stub_gl_config.h"
542 #include "mir_test_doubles/mock_framebuffer_bundle.h"
543 #include "mir_test_doubles/stub_gl_program_factory.h"
544+#define GLM_FORCE_RADIANS
545+#define GLM_PRECISION_MEDIUMP_FLOAT
546+#include <glm/glm.hpp>
547+#include <glm/gtc/matrix_transform.hpp>
548+#include <glm/gtc/type_ptr.hpp>
549 #include <memory>
550
551 namespace geom=mir::geometry;
552@@ -38,6 +43,36 @@
553 namespace mga=mir::graphics::android;
554 namespace mtd=mir::test::doubles;
555
556+namespace
557+{
558+struct TransformedRenderable : public mtd::StubRenderable
559+{
560+ glm::mat4 transformation() const override
561+ {
562+ glm::mat4 transform(1.0);
563+ glm::vec3 vec(1.0, 0.0, 0.0);
564+ transform = glm::rotate(transform, 33.0f, vec);
565+ return transform;
566+ }
567+};
568+
569+//hopefully the alpha representation gets condensed at some point
570+struct ShapedRenderable : public mtd::StubRenderable
571+{
572+ bool shaped() const override
573+ {
574+ return true;
575+ }
576+};
577+
578+struct TranslucentRenderable : public mtd::StubRenderable
579+{
580+ bool alpha_enabled() const override
581+ {
582+ return true;
583+ }
584+};
585+
586 class AndroidDisplayBuffer : public ::testing::Test
587 {
588 protected:
589@@ -83,7 +118,7 @@
590 geom::Size const display_size{433,232};
591 double const refresh_rate{60.0};
592 };
593-
594+}
595 TEST_F(AndroidDisplayBuffer, can_post_update_with_gl_only)
596 {
597 using namespace testing;
598@@ -97,40 +132,57 @@
599 EXPECT_CALL(*mock_display_device, post(Ref(*stub_buffer)))
600 .Times(1);
601
602- std::list<std::shared_ptr<mg::Renderable>> renderlist{};
603+ mg::RenderableList renderlist{};
604 mga::DisplayBuffer db(
605 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
606 db.post_update();
607 }
608
609-TEST_F(AndroidDisplayBuffer, performs_default_post_if_empty_list)
610-{
611- using namespace testing;
612-
613- mga::DisplayBuffer db(
614- mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
615-
616- InSequence seq;
617- EXPECT_CALL(*mock_display_device, render_gl(_))
618- .Times(1);
619- EXPECT_CALL(*mock_fb_bundle, last_rendered_buffer())
620- .Times(1)
621- .WillOnce(Return(stub_buffer));
622- EXPECT_CALL(*mock_display_device, post(Ref(*stub_buffer)))
623- .Times(1);
624-
625- std::list<std::shared_ptr<mg::Renderable>> renderlist{};
626- auto render_fn = [] (mg::Renderable const&) {};
627- db.render_and_post_update(renderlist, render_fn);
628+TEST_F(AndroidDisplayBuffer, rejects_empty_list)
629+{
630+ using namespace testing;
631+
632+ mga::DisplayBuffer db(
633+ mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
634+
635+ mg::RenderableList renderlist{};
636+ EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
637+}
638+
639+//TODO: we could accept a 90 degree transform
640+TEST_F(AndroidDisplayBuffer, rejects_list_containing_transformed)
641+{
642+ using namespace testing;
643+
644+ mga::DisplayBuffer db(
645+ mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
646+
647+ auto renderable = std::make_shared<TransformedRenderable>();
648+ mg::RenderableList renderlist{renderable};
649+ EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
650+}
651+
652+//TODO: remove once alpha+HWC is turned on
653+TEST_F(AndroidDisplayBuffer, rejects_list_containing_alpha)
654+{
655+ using namespace testing;
656+
657+ mga::DisplayBuffer db(
658+ mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
659+
660+ mg::RenderableList renderlist{std::make_shared<TranslucentRenderable>()};
661+ EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
662+
663+ mg::RenderableList renderlist2{std::make_shared<ShapedRenderable>()};
664+ EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist2));
665 }
666
667 TEST_F(AndroidDisplayBuffer, posts_overlay_list)
668 {
669 using namespace testing;
670- std::list<std::shared_ptr<mg::Renderable>> renderlist{
671+ mg::RenderableList renderlist{
672 std::make_shared<mtd::StubRenderable>(),
673 std::make_shared<mtd::StubRenderable>()};
674- std::function<void(mg::Renderable const&)> render_fn;
675
676 InSequence seq;
677 EXPECT_CALL(*mock_display_device, prepare_overlays(_, Ref(renderlist), _))
678@@ -143,7 +195,7 @@
679
680 mga::DisplayBuffer db(
681 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
682- db.render_and_post_update(renderlist, render_fn);
683+ EXPECT_TRUE(db.post_renderables_if_optimizable(renderlist));
684 }
685
686 TEST_F(AndroidDisplayBuffer, defaults_to_normal_orientation)
687
688=== modified file 'tests/unit-tests/graphics/android/test_hwc_fb_device.cpp'
689--- tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-19 02:55:29 +0000
690+++ tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-21 17:27:23 +0000
691@@ -25,10 +25,10 @@
692 #include "mir_test_doubles/mock_framebuffer_bundle.h"
693 #include "mir_test_doubles/mock_fb_hal_device.h"
694 #include "mir_test_doubles/stub_renderable.h"
695-#include "mir_test_doubles/mock_render_function.h"
696 #include "mir_test_doubles/stub_swapping_gl_context.h"
697 #include "mir_test_doubles/mock_egl.h"
698 #include "mir_test_doubles/mock_hwc_device_wrapper.h"
699+#include "mir_test_doubles/stub_renderable_list_compositor.h"
700 #include "mir_test_doubles/mock_renderable_list_compositor.h"
701 #include "src/platform/graphics/android/overlay_gl_compositor.h"
702 #include "hwc_struct_helpers.h"

Subscribers

People subscribed via source and target branches