Mir

Merge lp:~kdub/mir/no-rendering-operator into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 1536
Proposed branch: lp:~kdub/mir/no-rendering-operator
Merge into: lp:mir
Diff against target: 342 lines (+58/-198)
7 files modified
src/server/compositor/CMakeLists.txt (+0/-1)
src/server/compositor/default_display_buffer_compositor.cpp (+14/-32)
src/server/compositor/rendering_operator.cpp (+0/-37)
src/server/compositor/rendering_operator.h (+0/-49)
tests/unit-tests/compositor/CMakeLists.txt (+0/-1)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+44/-2)
tests/unit-tests/compositor/test_rendering_operator.cpp (+0/-76)
To merge this branch: bzr merge lp:~kdub/mir/no-rendering-operator
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alberto Aguirre (community) Approve
Review via email: mp+213943@code.launchpad.net

Commit message

Remove the RenderingOperator and VisibilityFilter classes in favor of rendering on the generated list of renderables from the scene

Description of the change

Remove the RenderingOperator and VisibilityFilter classes in favor of rendering on the generated list of renderables from the scene

This does not address the Scene locking problem, but puts us in a good position to do so!

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
Alexandros Frantzis (afrantzis) wrote :

271 + EXPECT_EQ(buf1.use_count(), use_count1);
272 + EXPECT_EQ(buf2.use_count(), use_count2);

Expectations are reversed (we can use EXPECT_THAT() which is less error prone).

But, taking a step back, I see two issues with the test:

1. It's checking the number of users *before* posting, whereas we care about the number of users *after* posting, but that's OK for a unit test (that is we are modelling a post_update() that doesn't mess with the buffers, which is reasonable).

2. The test is too strict and dependent on the internals. We are checking that the number of users at posting time is the same as the number of users at rendering time, but that's not what we really care about. What we want to check is that the buffer is held alive until after post_update(), i.e., there is at least one user (besides the test function) at that point:

EXPECT_THAT(buf2.use_count() - 1, Ge(1));
EXPECT_THAT(buf2.use_count() - 1, Ge(1));

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

So (1) is not really an issue just something that caught my eye...

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

Much easier to reason about, lgtm.

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

Looks good.

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

84 + //'renderer.get()' serves as an ID to distinguish itself from other compositors
85 + auto buffer = renderable->buffer(renderer.get());

Seems fragile, but not a reason to block this change.

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

> 84 + //'renderer.get()' serves as an ID to distinguish itself from other
> compositors
> 85 + auto buffer = renderable->buffer(renderer.get());
>
> Seems fragile, but not a reason to block this change.

indeed, just preserving what was there before. I'll have to rectify that situation before the android stuff can work.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/server/compositor/CMakeLists.txt'
--- src/server/compositor/CMakeLists.txt 2014-03-06 06:05:17 +0000
+++ src/server/compositor/CMakeLists.txt 2014-04-03 23:09:17 +0000
@@ -6,7 +6,6 @@
6 temporary_buffers.cpp6 temporary_buffers.cpp
7 buffer_stream_factory.cpp7 buffer_stream_factory.cpp
8 buffer_stream_surfaces.cpp8 buffer_stream_surfaces.cpp
9 rendering_operator.cpp
10 gl_renderer.cpp9 gl_renderer.cpp
11 gl_renderer_factory.cpp10 gl_renderer_factory.cpp
12 multi_threaded_compositor.cpp11 multi_threaded_compositor.cpp
1312
=== modified file 'src/server/compositor/default_display_buffer_compositor.cpp'
--- src/server/compositor/default_display_buffer_compositor.cpp 2014-04-01 19:44:01 +0000
+++ src/server/compositor/default_display_buffer_compositor.cpp 2014-04-03 23:09:17 +0000
@@ -19,8 +19,8 @@
1919
20#include "default_display_buffer_compositor.h"20#include "default_display_buffer_compositor.h"
2121
22#include "rendering_operator.h"
23#include "mir/compositor/scene.h"22#include "mir/compositor/scene.h"
23#include "mir/compositor/renderer.h"
24#include "mir/graphics/renderable.h"24#include "mir/graphics/renderable.h"
25#include "mir/graphics/display_buffer.h"25#include "mir/graphics/display_buffer.h"
26#include "mir/graphics/buffer.h"26#include "mir/graphics/buffer.h"
@@ -34,32 +34,6 @@
34namespace mc = mir::compositor;34namespace mc = mir::compositor;
35namespace mg = mir::graphics;35namespace mg = mir::graphics;
3636
37//TODO remove VisibilityFilter once we don't need filters/operators for rendering
38namespace
39{
40struct VisibilityFilter : public mc::FilterForScene
41{
42public:
43 VisibilityFilter(
44 mg::RenderableList const& renderable_list)
45 : list(renderable_list)
46 {
47 }
48
49 bool operator()(mg::Renderable const& r)
50 {
51 auto matcher = [&r](std::shared_ptr<mg::Renderable> const& renderable)
52 {
53 return (renderable.get() == &r);
54 };
55 return (std::find_if(list.begin(), list.end(), matcher) != list.end());
56 }
57
58private:
59 mg::RenderableList const& list;
60};
61}
62
63mc::DefaultDisplayBufferCompositor::DefaultDisplayBufferCompositor(37mc::DefaultDisplayBufferCompositor::DefaultDisplayBufferCompositor(
64 mg::DisplayBuffer& display_buffer,38 mg::DisplayBuffer& display_buffer,
65 std::shared_ptr<mc::Scene> const& scene,39 std::shared_ptr<mc::Scene> const& scene,
@@ -124,20 +98,28 @@
12498
125 if (!bypassed)99 if (!bypassed)
126 {100 {
101 //preserves buffers backing GL textures until after post_update
102 std::vector<std::shared_ptr<mg::Buffer>> saved_resources;
103
127 display_buffer.make_current();104 display_buffer.make_current();
128105
129 auto const& view_area = display_buffer.view_area();106 auto const& view_area = display_buffer.view_area();
130 auto renderable_list = scene->generate_renderable_list();107 auto renderable_list = scene->generate_renderable_list();
131 mc::filter_occlusions_from(renderable_list, view_area);108 mc::filter_occlusions_from(renderable_list, view_area);
132109
110 renderer->set_rotation(display_buffer.orientation());
111 renderer->begin();
112
133 for(auto const& renderable : renderable_list)113 for(auto const& renderable : renderable_list)
114 {
134 uncomposited_buffers |= (renderable->buffers_ready_for_compositor() > 1);115 uncomposited_buffers |= (renderable->buffers_ready_for_compositor() > 1);
135116
136 renderer->set_rotation(display_buffer.orientation());117 //'renderer.get()' serves as an ID to distinguish itself from other compositors
137 renderer->begin();118 auto buffer = renderable->buffer(renderer.get());
138 mc::RenderingOperator applicator(*renderer);119 renderer->render(*renderable, *buffer);
139 VisibilityFilter selector(renderable_list);120 saved_resources.push_back(buffer);
140 scene->for_each_if(selector, applicator);121 }
122
141 renderer->end();123 renderer->end();
142124
143 display_buffer.post_update();125 display_buffer.post_update();
144126
=== removed file 'src/server/compositor/rendering_operator.cpp'
--- src/server/compositor/rendering_operator.cpp 2014-03-26 23:41:48 +0000
+++ src/server/compositor/rendering_operator.cpp 1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
1/*
2 * Copyright © 2012 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#include "rendering_operator.h"
20#include "mir/compositor/buffer_stream.h"
21#include "mir/graphics/renderable.h"
22
23namespace mc=mir::compositor;
24
25mc::RenderingOperator::RenderingOperator(
26 Renderer& renderer)
27 : renderer(renderer)
28{
29}
30
31void mc::RenderingOperator::operator()(graphics::Renderable const& renderable)
32{
33 auto compositor_buffer = renderable.buffer(&renderer);
34 // preserves buffers used in rendering until after post_update()
35 saved_resources.push_back(compositor_buffer);
36 renderer.render(renderable, *compositor_buffer);
37}
380
=== removed file 'src/server/compositor/rendering_operator.h'
--- src/server/compositor/rendering_operator.h 2014-03-26 23:41:48 +0000
+++ src/server/compositor/rendering_operator.h 1970-01-01 00:00:00 +0000
@@ -1,49 +0,0 @@
1/*
2 * Copyright © 2012 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#ifndef MIR_COMPOSITOR_RENDERING_OPERATOR_H_
19#define MIR_COMPOSITOR_RENDERING_OPERATOR_H_
20
21#include "mir/compositor/renderer.h"
22#include "mir/compositor/scene.h"
23
24#include <vector>
25#include <functional>
26#include <memory>
27
28namespace mir
29{
30namespace compositor
31{
32
33class RenderingOperator : public OperatorForScene
34{
35public:
36 explicit RenderingOperator(
37 Renderer& renderer);
38 ~RenderingOperator() = default;
39
40 void operator()(graphics::Renderable const&);
41
42private:
43 Renderer& renderer;
44 std::vector<std::shared_ptr<void>> saved_resources;
45};
46
47}
48}
49#endif /* MIR_COMPOSITOR_RENDERING_OPERATOR_H_ */
500
=== modified file 'tests/unit-tests/compositor/CMakeLists.txt'
--- tests/unit-tests/compositor/CMakeLists.txt 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/compositor/CMakeLists.txt 2014-04-03 23:09:17 +0000
@@ -2,7 +2,6 @@
2 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_buffer_compositor.cpp2 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_buffer_compositor.cpp
3 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_stream.cpp3 ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_stream.cpp
4 ${CMAKE_CURRENT_SOURCE_DIR}/test_temporary_buffers.cpp4 ${CMAKE_CURRENT_SOURCE_DIR}/test_temporary_buffers.cpp
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_rendering_operator.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_threaded_compositor.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_multi_threaded_compositor.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_switching_bundle.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_switching_bundle.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp7 ${CMAKE_CURRENT_SOURCE_DIR}/test_gl_renderer.cpp
98
=== modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp'
--- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2014-04-01 20:39:59 +0000
+++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2014-04-03 23:09:17 +0000
@@ -119,8 +119,6 @@
119 .Times(1);119 .Times(1);
120 EXPECT_CALL(scene, generate_renderable_list())120 EXPECT_CALL(scene, generate_renderable_list())
121 .Times(1);121 .Times(1);
122 EXPECT_CALL(scene, for_each_if(_,_))
123 .Times(1);
124 EXPECT_CALL(display_buffer, post_update())122 EXPECT_CALL(display_buffer, post_update())
125 .Times(1);123 .Times(1);
126124
@@ -555,3 +553,47 @@
555 EXPECT_TRUE(compositor.composite());553 EXPECT_TRUE(compositor.composite());
556 EXPECT_FALSE(compositor.composite());554 EXPECT_FALSE(compositor.composite());
557}555}
556
557TEST_F(DefaultDisplayBufferCompositor, buffers_held_until_post_update_is_done)
558{
559 using namespace testing;
560 auto mock_renderable1 = std::make_shared<NiceMock<mtd::MockRenderable>>();
561 auto mock_renderable2 = std::make_shared<NiceMock<mtd::MockRenderable>>();
562 auto buf1 = std::make_shared<mtd::StubBuffer>();
563 auto buf2 = std::make_shared<mtd::StubBuffer>();
564 ON_CALL(*mock_renderable1, buffer(_))
565 .WillByDefault(Return(buf1));
566 ON_CALL(*mock_renderable2, buffer(_))
567 .WillByDefault(Return(buf2));
568 ON_CALL(display_buffer, view_area())
569 .WillByDefault(Return(geom::Rectangle{{0,0},{14,14}}));
570 EXPECT_CALL(*mock_renderable1, screen_position())
571 .WillRepeatedly(Return(geom::Rectangle{{1,2}, {3,4}}));
572 EXPECT_CALL(*mock_renderable2, screen_position())
573 .WillRepeatedly(Return(geom::Rectangle{{0,2}, {3,4}}));
574
575 mg::RenderableList list{
576 mock_renderable1,
577 mock_renderable2
578 };
579 FakeScene scene(list);
580
581 long test_use_count1{buf1.use_count()};
582 long test_use_count2{buf2.use_count()};
583
584 EXPECT_CALL(display_buffer, post_update())
585 .Times(1)
586 .WillOnce(Invoke([&test_use_count1, &test_use_count2, &buf1, &buf2]()
587 {
588 EXPECT_GT(buf1.use_count(), test_use_count1);
589 EXPECT_GT(buf2.use_count(), test_use_count2);
590 }));
591
592 mc::DefaultDisplayBufferCompositor compositor(
593 display_buffer,
594 mt::fake_shared(scene),
595 mt::fake_shared(mock_renderer),
596 mr::null_compositor_report());
597 compositor.composite();
598}
599
558600
=== removed file 'tests/unit-tests/compositor/test_rendering_operator.cpp'
--- tests/unit-tests/compositor/test_rendering_operator.cpp 2014-03-26 05:48:59 +0000
+++ tests/unit-tests/compositor/test_rendering_operator.cpp 1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 */
18
19#include "src/server/compositor/rendering_operator.h"
20#include "mir/geometry/rectangle.h"
21#include "mir_test_doubles/mock_renderer.h"
22#include "mir_test_doubles/mock_buffer_stream.h"
23#include "mir_test_doubles/mock_renderable.h"
24#include "mir_test_doubles/stub_buffer.h"
25
26#include <gmock/gmock.h>
27#include <gtest/gtest.h>
28
29namespace mc = mir::compositor;
30namespace mg = mir::graphics;
31namespace geom = mir::geometry;
32namespace mtd = mir::test::doubles;
33namespace mg = mir::graphics;
34
35TEST(RenderingOperator, render_operator_saves_resources)
36{
37 using namespace testing;
38
39 mtd::MockRenderer mock_renderer;
40 mtd::MockRenderable mock_renderable;
41 auto stub_buffer0 = std::make_shared<mtd::StubBuffer>();
42 auto stub_buffer1 = std::make_shared<mtd::StubBuffer>();
43 auto stub_buffer2 = std::make_shared<mtd::StubBuffer>();
44
45 EXPECT_CALL(mock_renderable, buffer(_))
46 .Times(3)
47 .WillOnce(Return(stub_buffer0))
48 .WillOnce(Return(stub_buffer1))
49 .WillOnce(Return(stub_buffer2));
50
51 Sequence seq;
52 EXPECT_CALL(mock_renderer, render(Ref(mock_renderable), Ref(*stub_buffer0)))
53 .InSequence(seq);
54 EXPECT_CALL(mock_renderer, render(Ref(mock_renderable), Ref(*stub_buffer1)))
55 .InSequence(seq);
56 EXPECT_CALL(mock_renderer, render(Ref(mock_renderable), Ref(*stub_buffer2)))
57 .InSequence(seq);
58
59 auto use_count_before0 = stub_buffer0.use_count();
60 auto use_count_before1 = stub_buffer1.use_count();
61 auto use_count_before2 = stub_buffer2.use_count();
62 {
63 mc::RenderingOperator rendering_operator(mock_renderer);
64 rendering_operator(mock_renderable);
65 rendering_operator(mock_renderable);
66 rendering_operator(mock_renderable);
67
68 EXPECT_EQ(use_count_before0 + 1, stub_buffer0.use_count());
69 EXPECT_EQ(use_count_before1 + 1, stub_buffer1.use_count());
70 EXPECT_EQ(use_count_before2 + 1, stub_buffer2.use_count());
71 }
72
73 EXPECT_EQ(use_count_before0, stub_buffer0.use_count());
74 EXPECT_EQ(use_count_before1, stub_buffer1.use_count());
75 EXPECT_EQ(use_count_before2, stub_buffer2.use_count());
76}

Subscribers

People subscribed via source and target branches