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
=== modified file 'examples/render_overlays.cpp'
--- examples/render_overlays.cpp 2014-05-14 18:40:19 +0000
+++ examples/render_overlays.cpp 2014-05-21 17:27:23 +0000
@@ -198,8 +198,7 @@
198 buffer.make_current();198 buffer.make_current();
199 client1->update_green_channel();199 client1->update_green_channel();
200 client2->update_green_channel();200 client2->update_green_channel();
201 auto render_fn = [](mg::Renderable const&) {};201 buffer.post_renderables_if_optimizable(renderlist);
202 buffer.render_and_post_update(renderlist, render_fn);
203 });202 });
204 }203 }
205 return 0;204 return 0;
206205
=== modified file 'include/platform/mir/graphics/display_buffer.h'
--- include/platform/mir/graphics/display_buffer.h 2014-03-26 05:48:59 +0000
+++ include/platform/mir/graphics/display_buffer.h 2014-05-21 17:27:23 +0000
@@ -24,7 +24,6 @@
24#include <mir_toolkit/common.h>24#include <mir_toolkit/common.h>
2525
26#include <memory>26#include <memory>
27#include <functional>
2827
29namespace mir28namespace mir
30{29{
@@ -51,13 +50,22 @@
51 /** This will trigger OpenGL rendering and post the result to the screen. */50 /** This will trigger OpenGL rendering and post the result to the screen. */
52 virtual void post_update() = 0;51 virtual void post_update() = 0;
5352
54 /** This will render renderlist to the screen and post the result to the screen.53 /** This will render renderlist to the screen and post the result to the
55 For each renderable, the DisplayBuffer will decide if its more efficient to render54 * screen if there is a hardware optimization that can be done.
56 that Renderable via OpenGL, or via another method. If the Renderable is to be rendered55 * \param [in] renderlist
57 via OpenGL, render_fn will be invoked on that Renderable. */56 * The renderables that should appear on the screen if the hardware
58 virtual void render_and_post_update(57 * is capable of optmizing that list somehow. If what you want
59 RenderableList const& renderlist,58 * displayed on the screen cannot be represented by a RenderableList,
60 std::function<void(Renderable const&)> const& render_fn) = 0;59 * then you should draw using OpenGL and use post_update()
60 * \returns
61 * true if the hardware can optimize the rendering of the list.
62 * When this call completes, the renderlist will have been posted
63 * to the screen.
64 * false if the hardware platform cannot optimize the list. The screen
65 * will not be updated. The caller should render the list another way,
66 * and post using post_update()
67 **/
68 virtual bool post_renderables_if_optimizable(RenderableList const& renderlist) = 0;
6169
62 /** to be deprecated */70 /** to be deprecated */
63 virtual bool can_bypass() const = 0;71 virtual bool can_bypass() const = 0;
6472
=== modified file 'include/test/mir_test_doubles/mock_display_buffer.h'
--- include/test/mir_test_doubles/mock_display_buffer.h 2014-03-26 05:48:59 +0000
+++ include/test/mir_test_doubles/mock_display_buffer.h 2014-05-21 17:27:23 +0000
@@ -46,8 +46,7 @@
46 MOCK_METHOD0(release_current, void());46 MOCK_METHOD0(release_current, void());
47 MOCK_METHOD0(post_update, void());47 MOCK_METHOD0(post_update, void());
48 MOCK_CONST_METHOD0(can_bypass, bool());48 MOCK_CONST_METHOD0(can_bypass, bool());
49 MOCK_METHOD2(render_and_post_update, void(graphics::RenderableList const&, 49 MOCK_METHOD1(post_renderables_if_optimizable, bool(graphics::RenderableList const&));
50 std::function<void(graphics::Renderable const&)> const&));
51 MOCK_CONST_METHOD0(orientation, MirOrientation());50 MOCK_CONST_METHOD0(orientation, MirOrientation());
52};51};
5352
5453
=== removed file 'include/test/mir_test_doubles/mock_render_function.h'
--- include/test/mir_test_doubles/mock_render_function.h 2014-02-18 16:48:24 +0000
+++ include/test/mir_test_doubles/mock_render_function.h 1970-01-01 00:00:00 +0000
@@ -1,40 +0,0 @@
1/*
2 * Copyright © 2014 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: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
20#define MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_
21
22#include <mir/graphics/renderable.h>
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31struct MockRenderFunction
32{
33 MOCK_METHOD1(called, void(graphics::Renderable const&));
34};
35
36}
37}
38}
39
40#endif /* MIR_TEST_DOUBLES_MOCK_RENDER_FUNCTION_H_ */
410
=== modified file 'include/test/mir_test_doubles/null_display_buffer.h'
--- include/test/mir_test_doubles/null_display_buffer.h 2014-03-26 05:48:59 +0000
+++ include/test/mir_test_doubles/null_display_buffer.h 2014-05-21 17:27:23 +0000
@@ -36,9 +36,7 @@
36 void release_current() {}36 void release_current() {}
37 void post_update() {}37 void post_update() {}
38 bool can_bypass() const override { return false; }38 bool can_bypass() const override { return false; }
39 void render_and_post_update(39 bool post_renderables_if_optimizable(graphics::RenderableList const&) { return false; }
40 graphics::RenderableList const&,
41 std::function<void(graphics::Renderable const&)> const&) {}
42 MirOrientation orientation() const override { return mir_orientation_normal; }40 MirOrientation orientation() const override { return mir_orientation_normal; }
43};41};
4442
4543
=== modified file 'include/test/mir_test_doubles/stub_display_builder.h'
--- include/test/mir_test_doubles/stub_display_builder.h 2014-05-01 07:13:02 +0000
+++ include/test/mir_test_doubles/stub_display_builder.h 2014-05-21 17:27:23 +0000
@@ -42,9 +42,7 @@
42 void release_current() {}42 void release_current() {}
43 void post_update() {}43 void post_update() {}
44 bool can_bypass() const override { return false; }44 bool can_bypass() const override { return false; }
45 void render_and_post_update(45 bool post_renderables_if_optimizable(graphics::RenderableList const&) { return false; }
46 graphics::RenderableList const&,
47 std::function<void(graphics::Renderable const&)> const&) {}
48 MirOrientation orientation() const override { return mir_orientation_normal; }46 MirOrientation orientation() const override { return mir_orientation_normal; }
49 void configure(graphics::DisplayConfigurationOutput const&) {} 47 void configure(graphics::DisplayConfigurationOutput const&) {}
50 graphics::DisplayConfigurationOutput configuration() const48 graphics::DisplayConfigurationOutput configuration() const
5149
=== modified file 'src/platform/graphics/android/display_buffer.cpp'
--- src/platform/graphics/android/display_buffer.cpp 2014-05-19 02:55:29 +0000
+++ src/platform/graphics/android/display_buffer.cpp 2014-05-21 17:27:23 +0000
@@ -30,6 +30,28 @@
30namespace mga=mir::graphics::android;30namespace mga=mir::graphics::android;
31namespace geom=mir::geometry;31namespace geom=mir::geometry;
3232
33namespace
34{
35bool renderable_list_is_hwc_incompatible(mg::RenderableList const& list)
36{
37 if (list.empty())
38 return true;
39
40 for(auto const& renderable : list)
41 {
42 //TODO: enable alpha, 90 deg rotation
43 static glm::mat4 const identity;
44 if (renderable->shaped() ||
45 renderable->alpha_enabled() ||
46 (renderable->transformation() != identity))
47 {
48 return true;
49 }
50 }
51 return false;
52}
53}
54
33mga::DisplayBuffer::DisplayBuffer(55mga::DisplayBuffer::DisplayBuffer(
34 std::shared_ptr<FramebufferBundle> const& fb_bundle,56 std::shared_ptr<FramebufferBundle> const& fb_bundle,
35 std::shared_ptr<DisplayDevice> const& display_device,57 std::shared_ptr<DisplayDevice> const& display_device,
@@ -86,20 +108,14 @@
86 gl_context.release_current();108 gl_context.release_current();
87}109}
88110
89void mga::DisplayBuffer::render_and_post_update(111bool mga::DisplayBuffer::post_renderables_if_optimizable(RenderableList const& renderlist)
90 RenderableList const& renderlist,
91 std::function<void(Renderable const&)> const&)
92{112{
93 if (renderlist.empty())113 if (renderable_list_is_hwc_incompatible(renderlist))
94 {114 return false;
95 display_device->render_gl(gl_context);
96 }
97 else
98 {
99 display_device->prepare_overlays(gl_context, renderlist, overlay_program);
100 }
101115
116 display_device->prepare_overlays(gl_context, renderlist, overlay_program);
102 post();117 post();
118 return true;
103}119}
104120
105void mga::DisplayBuffer::post_update()121void mga::DisplayBuffer::post_update()
106122
=== modified file 'src/platform/graphics/android/display_buffer.h'
--- src/platform/graphics/android/display_buffer.h 2014-05-01 07:13:02 +0000
+++ src/platform/graphics/android/display_buffer.h 2014-05-21 17:27:23 +0000
@@ -52,9 +52,7 @@
52 void post_update();52 void post_update();
53 bool can_bypass() const override;53 bool can_bypass() const override;
5454
55 void render_and_post_update(55 bool post_renderables_if_optimizable(RenderableList const& renderlist);
56 RenderableList const& renderlist,
57 std::function<void(Renderable const&)> const& render_fn);
58 MirOrientation orientation() const override;56 MirOrientation orientation() const override;
5957
60 DisplayConfigurationOutput configuration() const;58 DisplayConfigurationOutput configuration() const;
6159
=== modified file 'src/platform/graphics/mesa/display_buffer.cpp'
--- src/platform/graphics/mesa/display_buffer.cpp 2014-05-05 03:36:45 +0000
+++ src/platform/graphics/mesa/display_buffer.cpp 2014-05-21 17:27:23 +0000
@@ -197,11 +197,9 @@
197 return rotation;197 return rotation;
198}198}
199199
200void mgm::DisplayBuffer::render_and_post_update(200bool mgm::DisplayBuffer::post_renderables_if_optimizable(RenderableList const&)
201 RenderableList const&,
202 std::function<void(Renderable const&)> const&)
203{201{
204 post_update(nullptr); 202 return false;
205}203}
206204
207void mgm::DisplayBuffer::post_update()205void mgm::DisplayBuffer::post_update()
208206
=== modified file 'src/platform/graphics/mesa/display_buffer.h'
--- src/platform/graphics/mesa/display_buffer.h 2014-03-27 09:52:04 +0000
+++ src/platform/graphics/mesa/display_buffer.h 2014-05-21 17:27:23 +0000
@@ -61,8 +61,7 @@
6161
62 bool can_bypass() const override;62 bool can_bypass() const override;
63 void post_update(std::shared_ptr<graphics::Buffer> bypass_buf) override;63 void post_update(std::shared_ptr<graphics::Buffer> bypass_buf) override;
64 void render_and_post_update(RenderableList const& renderlist,64 bool post_renderables_if_optimizable(RenderableList const& renderlist) override;
65 std::function<void(Renderable const&)> const& render_fn);
66 MirOrientation orientation() const override;65 MirOrientation orientation() const override;
67 void schedule_set_crtc();66 void schedule_set_crtc();
68 void wait_for_page_flip();67 void wait_for_page_flip();
6968
=== modified file 'src/server/compositor/screencast_display_buffer.cpp'
--- src/server/compositor/screencast_display_buffer.cpp 2014-03-26 05:48:59 +0000
+++ src/server/compositor/screencast_display_buffer.cpp 2014-05-21 17:27:23 +0000
@@ -85,14 +85,9 @@
85 old_viewport[2], old_viewport[3]);85 old_viewport[2], old_viewport[3]);
86}86}
8787
88void mc::ScreencastDisplayBuffer::render_and_post_update(88bool mc::ScreencastDisplayBuffer::post_renderables_if_optimizable(mg::RenderableList const&)
89 mg::RenderableList const& renderables,
90 std::function<void(mg::Renderable const&)> const& render)
91{89{
92 for (auto const& renderable : renderables)90 return false;
93 render(*renderable);
94
95 post_update();
96}91}
9792
98void mc::ScreencastDisplayBuffer::post_update()93void mc::ScreencastDisplayBuffer::post_update()
9994
=== modified file 'src/server/compositor/screencast_display_buffer.h'
--- src/server/compositor/screencast_display_buffer.h 2014-03-26 05:48:59 +0000
+++ src/server/compositor/screencast_display_buffer.h 2014-05-21 17:27:23 +0000
@@ -59,9 +59,7 @@
5959
60 void release_current();60 void release_current();
6161
62 void render_and_post_update(62 bool post_renderables_if_optimizable(graphics::RenderableList const&);
63 graphics::RenderableList const&,
64 std::function<void(graphics::Renderable const&)> const&);
6563
66 void post_update();64 void post_update();
6765
6866
=== modified file 'src/server/graphics/nested/nested_output.cpp'
--- src/server/graphics/nested/nested_output.cpp 2014-05-08 11:02:47 +0000
+++ src/server/graphics/nested/nested_output.cpp 2014-05-21 17:27:23 +0000
@@ -71,10 +71,9 @@
71 return false;71 return false;
72}72}
7373
74void mgn::detail::NestedOutput::render_and_post_update(74bool mgn::detail::NestedOutput::post_renderables_if_optimizable(RenderableList const&)
75 RenderableList const&,
76 std::function<void(Renderable const&)> const&)
77{75{
76 return false;
78}77}
7978
80MirOrientation mgn::detail::NestedOutput::orientation() const79MirOrientation mgn::detail::NestedOutput::orientation() const
8180
=== modified file 'src/server/graphics/nested/nested_output.h'
--- src/server/graphics/nested/nested_output.h 2014-05-08 11:02:47 +0000
+++ src/server/graphics/nested/nested_output.h 2014-05-21 17:27:23 +0000
@@ -51,9 +51,7 @@
51 virtual bool can_bypass() const override;51 virtual bool can_bypass() const override;
52 MirOrientation orientation() const override;52 MirOrientation orientation() const override;
5353
54 void render_and_post_update(54 bool post_renderables_if_optimizable(RenderableList const& renderlist);
55 RenderableList const& renderlist,
56 std::function<void(Renderable const&)> const& render_fn);
5755
58 NestedOutput(NestedOutput const&) = delete;56 NestedOutput(NestedOutput const&) = delete;
59 NestedOutput operator=(NestedOutput const&) = delete;57 NestedOutput operator=(NestedOutput const&) = delete;
6058
=== modified file 'src/server/graphics/offscreen/display_buffer.cpp'
--- src/server/graphics/offscreen/display_buffer.cpp 2014-03-26 05:48:59 +0000
+++ src/server/graphics/offscreen/display_buffer.cpp 2014-05-21 17:27:23 +0000
@@ -149,10 +149,9 @@
149 return false;149 return false;
150}150}
151151
152void mgo::DisplayBuffer::render_and_post_update(152bool mgo::DisplayBuffer::post_renderables_if_optimizable(RenderableList const&)
153 RenderableList const&,
154 std::function<void(Renderable const&)> const&)
155{153{
154 return false;
156}155}
157156
158MirOrientation mgo::DisplayBuffer::orientation() const157MirOrientation mgo::DisplayBuffer::orientation() const
159158
=== modified file 'src/server/graphics/offscreen/display_buffer.h'
--- src/server/graphics/offscreen/display_buffer.h 2014-03-26 05:48:59 +0000
+++ src/server/graphics/offscreen/display_buffer.h 2014-05-21 17:27:23 +0000
@@ -70,9 +70,7 @@
70 bool can_bypass() const;70 bool can_bypass() const;
71 MirOrientation orientation() const override;71 MirOrientation orientation() const override;
7272
73 void render_and_post_update(73 bool post_renderables_if_optimizable(RenderableList const& renderlist) override;
74 RenderableList const& renderlist,
75 std::function<void(Renderable const&)> const& render_fn);
7674
77private:75private:
78 SurfacelessEGLContext const egl_context;76 SurfacelessEGLContext const egl_context;
7977
=== modified file 'tests/integration-tests/test_surface_stack_with_compositor.cpp'
--- tests/integration-tests/test_surface_stack_with_compositor.cpp 2014-05-19 02:55:29 +0000
+++ tests/integration-tests/test_surface_stack_with_compositor.cpp 2014-05-21 17:27:23 +0000
@@ -66,11 +66,10 @@
66 return true;66 return true;
67 }67 }
6868
69 void render_and_post_update(69 bool post_renderables_if_optimizable(mg::RenderableList const&)
70 mg::RenderableList const&,
71 std::function<void(mg::Renderable const&)> const&) override
72 {70 {
73 increment_post_count();71 increment_post_count();
72 return true;
74 }73 }
7574
76 void post_update() override75 void post_update() override
7776
=== modified file 'tests/unit-tests/compositor/test_screencast_display_buffer.cpp'
--- tests/unit-tests/compositor/test_screencast_display_buffer.cpp 2014-03-05 07:02:29 +0000
+++ tests/unit-tests/compositor/test_screencast_display_buffer.cpp 2014-05-21 17:27:23 +0000
@@ -34,16 +34,6 @@
34namespace34namespace
35{35{
3636
37struct MockRenderFunctor
38{
39 void operator()(mg::Renderable const& r)
40 {
41 operator_call(&r);
42 }
43
44 MOCK_METHOD1(operator_call, void(mg::Renderable const*));
45};
46
47struct ScreencastDisplayBufferTest : testing::Test37struct ScreencastDisplayBufferTest : testing::Test
48{38{
49 testing::NiceMock<mtd::MockGL> mock_gl;39 testing::NiceMock<mtd::MockGL> mock_gl;
@@ -158,10 +148,8 @@
158 db.post_update();148 db.post_update();
159}149}
160150
161TEST_F(ScreencastDisplayBufferTest, renders_renderables_on_render_and_post_update)151TEST_F(ScreencastDisplayBufferTest, rejects_attempt_to_optimize)
162{152{
163 using namespace testing;
164
165 geom::Rectangle const rect{{100,100}, {800,600}};153 geom::Rectangle const rect{{100,100}, {800,600}};
166 mtd::StubBuffer stub_buffer;154 mtd::StubBuffer stub_buffer;
167155
@@ -172,15 +160,5 @@
172160
173 mc::ScreencastDisplayBuffer db{rect, stub_buffer};161 mc::ScreencastDisplayBuffer db{rect, stub_buffer};
174162
175 Mock::VerifyAndClearExpectations(&mock_gl);163 EXPECT_FALSE(db.post_renderables_if_optimizable(renderables));
176 MockRenderFunctor mock_render_functor;
177
178 InSequence s;
179
180 for (auto const& renderable : renderables)
181 EXPECT_CALL(mock_render_functor, operator_call(renderable.get()));
182
183 EXPECT_CALL(mock_gl, glFinish());
184
185 db.render_and_post_update(renderables, std::ref(mock_render_functor));
186}164}
187165
=== modified file 'tests/unit-tests/graphics/android/test_fb_device.cpp'
--- tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-19 02:55:29 +0000
+++ tests/unit-tests/graphics/android/test_fb_device.cpp 2014-05-21 17:27:23 +0000
@@ -26,7 +26,6 @@
26#include "mir_test_doubles/stub_buffer.h"26#include "mir_test_doubles/stub_buffer.h"
27#include "mir_test_doubles/stub_renderable.h"27#include "mir_test_doubles/stub_renderable.h"
28#include "mir_test_doubles/mock_android_native_buffer.h"28#include "mir_test_doubles/mock_android_native_buffer.h"
29#include "mir_test_doubles/mock_render_function.h"
30#include "mir_test_doubles/mock_swapping_gl_context.h"29#include "mir_test_doubles/mock_swapping_gl_context.h"
31#include "mir_test_doubles/stub_renderable_list_compositor.h"30#include "mir_test_doubles/stub_renderable_list_compositor.h"
32#include "mir_test_doubles/mock_renderable_list_compositor.h"31#include "mir_test_doubles/mock_renderable_list_compositor.h"
3332
=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-05-19 02:55:29 +0000
+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-05-21 17:27:23 +0000
@@ -31,7 +31,6 @@
31#include "mir_test_doubles/mock_hwc_device_wrapper.h"31#include "mir_test_doubles/mock_hwc_device_wrapper.h"
32#include "mir_test/fake_shared.h"32#include "mir_test/fake_shared.h"
33#include "hwc_struct_helpers.h"33#include "hwc_struct_helpers.h"
34#include "mir_test_doubles/mock_render_function.h"
35#include "mir_test_doubles/mock_swapping_gl_context.h"34#include "mir_test_doubles/mock_swapping_gl_context.h"
36#include "mir_test_doubles/stub_swapping_gl_context.h"35#include "mir_test_doubles/stub_swapping_gl_context.h"
37#include "mir_test_doubles/stub_renderable_list_compositor.h"36#include "mir_test_doubles/stub_renderable_list_compositor.h"
@@ -252,36 +251,16 @@
252 device.render_gl(stub_context);251 device.render_gl(stub_context);
253}252}
254253
255namespace
256{
257MATCHER_P(MatchesRenderableList, value, std::string(""))
258{
259 if (value.size() != arg.size())
260 return false;
261
262 bool match{true};
263 auto it = value.begin();
264 for(auto const& a : arg)
265 {
266 if (a != *it)
267 match = false;
268 it++;
269 }
270 return match;
271}
272
273}
274
275TEST_F(HwcDevice, calls_render_with_list_of_rejected_overlays)254TEST_F(HwcDevice, calls_render_with_list_of_rejected_overlays)
276{255{
277 using namespace testing;256 using namespace testing;
278 mtd::MockRenderableListCompositor mock_compositor;257 mtd::MockRenderableListCompositor mock_compositor;
279258
280 std::list<std::shared_ptr<mg::Renderable>> updated_list({259 mg::RenderableList updated_list({
281 stub_renderable1,260 stub_renderable1,
282 stub_renderable2261 stub_renderable2
283 });262 });
284 std::list<std::shared_ptr<mg::Renderable>> expected_renderable_list({263 mg::RenderableList expected_renderable_list({
285 stub_renderable2264 stub_renderable2
286 });265 });
287266
@@ -303,7 +282,7 @@
303 contents.hwLayers[2].compositionType = HWC_FRAMEBUFFER_TARGET;282 contents.hwLayers[2].compositionType = HWC_FRAMEBUFFER_TARGET;
304 }));283 }));
305284
306 EXPECT_CALL(mock_compositor, render(MatchesRenderableList(expected_renderable_list),Ref(mock_context)))285 EXPECT_CALL(mock_compositor, render(expected_renderable_list,Ref(mock_context)))
307 .InSequence(seq);286 .InSequence(seq);
308287
309 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);288 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
@@ -333,7 +312,7 @@
333 .InSequence(seq);312 .InSequence(seq);
334 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);313 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
335314
336 std::list<std::shared_ptr<mg::Renderable>> updated_list({315 mg::RenderableList updated_list({
337 stub_renderable1,316 stub_renderable1,
338 stub_renderable2317 stub_renderable2
339 });318 });
@@ -408,7 +387,7 @@
408 };387 };
409388
410 /* set non-default renderlist */389 /* set non-default renderlist */
411 std::list<std::shared_ptr<mg::Renderable>> updated_list({390 mg::RenderableList updated_list({
412 stub_renderable1,391 stub_renderable1,
413 stub_renderable1392 stub_renderable1
414 });393 });
@@ -491,7 +470,7 @@
491TEST_F(HwcDevice, discards_second_set_if_all_overlays_and_nothing_has_changed)470TEST_F(HwcDevice, discards_second_set_if_all_overlays_and_nothing_has_changed)
492{471{
493 using namespace testing;472 using namespace testing;
494 std::list<std::shared_ptr<mg::Renderable>> updated_list({473 mg::RenderableList updated_list({
495 stub_renderable1,474 stub_renderable1,
496 stub_renderable2475 stub_renderable2
497 });476 });
@@ -519,7 +498,7 @@
519TEST_F(HwcDevice, submits_every_time_if_at_least_one_layer_is_gl_rendered)498TEST_F(HwcDevice, submits_every_time_if_at_least_one_layer_is_gl_rendered)
520{499{
521 using namespace testing;500 using namespace testing;
522 std::list<std::shared_ptr<mg::Renderable>> updated_list({501 mg::RenderableList updated_list({
523 stub_renderable1,502 stub_renderable1,
524 stub_renderable2503 stub_renderable2
525 });504 });
@@ -562,7 +541,7 @@
562 .WillOnce(Return(native_handle_2))541 .WillOnce(Return(native_handle_2))
563 .WillOnce(Return(native_handle_3));542 .WillOnce(Return(native_handle_3));
564543
565 std::list<std::shared_ptr<mg::Renderable>> updated_list({stub_renderable1});544 mg::RenderableList updated_list({stub_renderable1});
566545
567 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);546 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
568547
569548
=== modified file 'tests/unit-tests/graphics/android/test_hwc_display.cpp'
--- tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-19 02:55:29 +0000
+++ tests/unit-tests/graphics/android/test_hwc_display.cpp 2014-05-21 17:27:23 +0000
@@ -31,6 +31,11 @@
31#include "mir_test_doubles/stub_gl_config.h"31#include "mir_test_doubles/stub_gl_config.h"
32#include "mir_test_doubles/mock_framebuffer_bundle.h"32#include "mir_test_doubles/mock_framebuffer_bundle.h"
33#include "mir_test_doubles/stub_gl_program_factory.h"33#include "mir_test_doubles/stub_gl_program_factory.h"
34#define GLM_FORCE_RADIANS
35#define GLM_PRECISION_MEDIUMP_FLOAT
36#include <glm/glm.hpp>
37#include <glm/gtc/matrix_transform.hpp>
38#include <glm/gtc/type_ptr.hpp>
34#include <memory>39#include <memory>
3540
36namespace geom=mir::geometry;41namespace geom=mir::geometry;
@@ -38,6 +43,36 @@
38namespace mga=mir::graphics::android;43namespace mga=mir::graphics::android;
39namespace mtd=mir::test::doubles;44namespace mtd=mir::test::doubles;
4045
46namespace
47{
48struct TransformedRenderable : public mtd::StubRenderable
49{
50 glm::mat4 transformation() const override
51 {
52 glm::mat4 transform(1.0);
53 glm::vec3 vec(1.0, 0.0, 0.0);
54 transform = glm::rotate(transform, 33.0f, vec);
55 return transform;
56 }
57};
58
59//hopefully the alpha representation gets condensed at some point
60struct ShapedRenderable : public mtd::StubRenderable
61{
62 bool shaped() const override
63 {
64 return true;
65 }
66};
67
68struct TranslucentRenderable : public mtd::StubRenderable
69{
70 bool alpha_enabled() const override
71 {
72 return true;
73 }
74};
75
41class AndroidDisplayBuffer : public ::testing::Test76class AndroidDisplayBuffer : public ::testing::Test
42{77{
43protected:78protected:
@@ -83,7 +118,7 @@
83 geom::Size const display_size{433,232};118 geom::Size const display_size{433,232};
84 double const refresh_rate{60.0};119 double const refresh_rate{60.0};
85};120};
86121}
87TEST_F(AndroidDisplayBuffer, can_post_update_with_gl_only)122TEST_F(AndroidDisplayBuffer, can_post_update_with_gl_only)
88{123{
89 using namespace testing;124 using namespace testing;
@@ -97,40 +132,57 @@
97 EXPECT_CALL(*mock_display_device, post(Ref(*stub_buffer)))132 EXPECT_CALL(*mock_display_device, post(Ref(*stub_buffer)))
98 .Times(1);133 .Times(1);
99134
100 std::list<std::shared_ptr<mg::Renderable>> renderlist{};135 mg::RenderableList renderlist{};
101 mga::DisplayBuffer db(136 mga::DisplayBuffer db(
102 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);137 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
103 db.post_update();138 db.post_update();
104}139}
105140
106TEST_F(AndroidDisplayBuffer, performs_default_post_if_empty_list)141TEST_F(AndroidDisplayBuffer, rejects_empty_list)
107{142{
108 using namespace testing;143 using namespace testing;
109144
110 mga::DisplayBuffer db(145 mga::DisplayBuffer db(
111 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);146 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
112147
113 InSequence seq;148 mg::RenderableList renderlist{};
114 EXPECT_CALL(*mock_display_device, render_gl(_))149 EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
115 .Times(1);150}
116 EXPECT_CALL(*mock_fb_bundle, last_rendered_buffer())151
117 .Times(1)152//TODO: we could accept a 90 degree transform
118 .WillOnce(Return(stub_buffer));153TEST_F(AndroidDisplayBuffer, rejects_list_containing_transformed)
119 EXPECT_CALL(*mock_display_device, post(Ref(*stub_buffer)))154{
120 .Times(1);155 using namespace testing;
121156
122 std::list<std::shared_ptr<mg::Renderable>> renderlist{};157 mga::DisplayBuffer db(
123 auto render_fn = [] (mg::Renderable const&) {};158 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
124 db.render_and_post_update(renderlist, render_fn);159
160 auto renderable = std::make_shared<TransformedRenderable>();
161 mg::RenderableList renderlist{renderable};
162 EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
163}
164
165//TODO: remove once alpha+HWC is turned on
166TEST_F(AndroidDisplayBuffer, rejects_list_containing_alpha)
167{
168 using namespace testing;
169
170 mga::DisplayBuffer db(
171 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
172
173 mg::RenderableList renderlist{std::make_shared<TranslucentRenderable>()};
174 EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist));
175
176 mg::RenderableList renderlist2{std::make_shared<ShapedRenderable>()};
177 EXPECT_FALSE(db.post_renderables_if_optimizable(renderlist2));
125}178}
126179
127TEST_F(AndroidDisplayBuffer, posts_overlay_list)180TEST_F(AndroidDisplayBuffer, posts_overlay_list)
128{181{
129 using namespace testing;182 using namespace testing;
130 std::list<std::shared_ptr<mg::Renderable>> renderlist{183 mg::RenderableList renderlist{
131 std::make_shared<mtd::StubRenderable>(),184 std::make_shared<mtd::StubRenderable>(),
132 std::make_shared<mtd::StubRenderable>()};185 std::make_shared<mtd::StubRenderable>()};
133 std::function<void(mg::Renderable const&)> render_fn;
134186
135 InSequence seq;187 InSequence seq;
136 EXPECT_CALL(*mock_display_device, prepare_overlays(_, Ref(renderlist), _))188 EXPECT_CALL(*mock_display_device, prepare_overlays(_, Ref(renderlist), _))
@@ -143,7 +195,7 @@
143195
144 mga::DisplayBuffer db(196 mga::DisplayBuffer db(
145 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);197 mock_fb_bundle, mock_display_device, native_window, *gl_context, stub_program_factory);
146 db.render_and_post_update(renderlist, render_fn); 198 EXPECT_TRUE(db.post_renderables_if_optimizable(renderlist));
147}199}
148200
149TEST_F(AndroidDisplayBuffer, defaults_to_normal_orientation)201TEST_F(AndroidDisplayBuffer, defaults_to_normal_orientation)
150202
=== modified file 'tests/unit-tests/graphics/android/test_hwc_fb_device.cpp'
--- tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-19 02:55:29 +0000
+++ tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-05-21 17:27:23 +0000
@@ -25,10 +25,10 @@
25#include "mir_test_doubles/mock_framebuffer_bundle.h"25#include "mir_test_doubles/mock_framebuffer_bundle.h"
26#include "mir_test_doubles/mock_fb_hal_device.h"26#include "mir_test_doubles/mock_fb_hal_device.h"
27#include "mir_test_doubles/stub_renderable.h"27#include "mir_test_doubles/stub_renderable.h"
28#include "mir_test_doubles/mock_render_function.h"
29#include "mir_test_doubles/stub_swapping_gl_context.h"28#include "mir_test_doubles/stub_swapping_gl_context.h"
30#include "mir_test_doubles/mock_egl.h"29#include "mir_test_doubles/mock_egl.h"
31#include "mir_test_doubles/mock_hwc_device_wrapper.h"30#include "mir_test_doubles/mock_hwc_device_wrapper.h"
31#include "mir_test_doubles/stub_renderable_list_compositor.h"
32#include "mir_test_doubles/mock_renderable_list_compositor.h"32#include "mir_test_doubles/mock_renderable_list_compositor.h"
33#include "src/platform/graphics/android/overlay_gl_compositor.h"33#include "src/platform/graphics/android/overlay_gl_compositor.h"
34#include "hwc_struct_helpers.h"34#include "hwc_struct_helpers.h"

Subscribers

People subscribed via source and target branches