Mir

Merge lp:~andreas-pokorny/mir/configure-clear-color into lp:mir

Proposed by Andreas Pokorny
Status: Rejected
Rejected by: Andreas Pokorny
Proposed branch: lp:~andreas-pokorny/mir/configure-clear-color
Merge into: lp:mir
Diff against target: 375 lines (+132/-5)
17 files modified
include/server/mir/default_configuration_options.h (+1/-0)
include/test/mir_test_doubles/mock_gl.h (+1/-0)
include/test/mir_test_doubles/mock_surface_renderer.h (+1/-0)
src/platform/graphics/android/output_builder.cpp (+2/-0)
src/server/compositor/default_configuration.cpp (+56/-2)
src/server/compositor/gl_renderer.cpp (+9/-1)
src/server/compositor/gl_renderer.h (+3/-0)
src/server/compositor/renderer.h (+5/-0)
src/server/default_configuration_options.cpp (+4/-0)
src/server/options/program_option.cpp (+1/-0)
tests/acceptance-tests/test_server_shutdown.cpp (+4/-0)
tests/integration-tests/test_session.cpp (+5/-0)
tests/integration-tests/test_surface_first_frame_sync.cpp (+5/-1)
tests/mir_test_doubles/mock_gl.cpp (+7/-1)
tests/mir_test_framework/stubbed_server_configuration.cpp (+4/-0)
tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp (+5/-0)
tests/unit-tests/compositor/test_gl_renderer.cpp (+19/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/configure-clear-color
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Kevin DuBois (community) Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+201456@code.launchpad.net

Commit message

Clear color Configuration option for GLRenderer

The configuration option is exposed through the default server configuration provided by mir_server. All demos that include a servers can be configured to use a different color with:
   --clear-color 0xDD4814FF

Description of the change

mir::compositor::Renderer is extended to allow setting the clear color and adds a --clear-color option to the demos.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

nit:
+ EXPECT_CALL(mock_gl, glClearColor(0.8f, 0.2f, 0.4f, 1.0f));
could use float matchers:
+ EXPECT_CALL(mock_gl, glClearColor(FloatEq(0.8f), FloatEq(0.2f), FloatEq(0.4f), FloatEq(1.0f)));

suggestion:
I'd prefer mg::GLRenderer not to acquire a set_clear_color(), and then begin() to actually perform the clear. (The semantics on this interface have become awkward, but its better not to compound the problem)

We could have the color come in as a parameter in the constructor of GLRenderer, since its set on the CLI and doesn't change.
Alternatively, we could have begin() be renamed to clear(Color) if we expect this to change every frame. This approach has less drawing-state stored in GLRenderer, and more kept in mir::compositor/mir::scene, where the surface stack state is

 has gotten very statefSeeing as our model keeps state in mir::compositor/mir::scene,

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Some immediate design issues I'd like to see fixed:

(1) "clearing" is not a user-visible concept. But the screen "background" is. So I suggest renaming "clear-color" to "background", "bg" or similar.

(2) Asking the user to prefix a hex number with "0x" is possibly an unnecessary information leak of how you're implementing the parameter parsing. So I think "0x" should not be required from the user perspective. And you could replace the istringstream stuff with a simple:
    if (sscanf(value.c_str(), "%lx", &color) == 1)
or
    if (sscanf(value.c_str(), "%2x%2x%2x%2x", &r, %g, &b, %a) == 4)

(3) "float clamp(unsigned long color)" does not need to exist. The input parameters are already mathematically guaranteed [0,255]. So you could remove the function and replace:
    clamp(...)
with
    (...) / 255.0f

(4) The name "ClearColorSettingRendererFactory" feels awkward. Perhaps "CustomRendererFactory" is better.

(5) Your colour components have known names and purposes, so please don't make them anonymous:
    typedef std::tuple<float, float, float, float> Color;
should be:
    struct Color {float r, g, b, a;}
The resulting code will be easier to read and generate less binary (no templates).

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

@Keven: agree, the interface begin/end/set_clear_color looks awkward - looking into - first attempt to improve was sublcassing GLRenderer and then stumbled over the GLRendererFactory having a mutex to serialize gl calls of the constructor.

(1) sure
(2) it already does both - just thought 0x looks more familiar
(3) improving - found a better name and use for clamp ..
(5) binary is equal or even smaller with tuple (only gcc knows why) but I agree to the readability wins

putting it back to WIP. Want to have a second thought on dealing with the GLRendererFactory topic.

Unmerged revisions

1331. By Andreas Pokorny

Clear color Configuration option for GLRenderer

The configuration option is exposed through the default server configuration provided by mir_server. All demos that include a servers can be configured to use a different color with
   --clear-color 0xDD4814FF

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/server/mir/default_configuration_options.h'
--- include/server/mir/default_configuration_options.h 2014-01-13 04:48:36 +0000
+++ include/server/mir/default_configuration_options.h 2014-01-13 16:47:16 +0000
@@ -43,6 +43,7 @@
43 static char const* const frontend_threads;43 static char const* const frontend_threads;
44 static char const* const name_opt;44 static char const* const name_opt;
45 static char const* const offscreen_opt;45 static char const* const offscreen_opt;
46 static char const* const clear_color;
4647
47 static char const* const glog;48 static char const* const glog;
48 static char const* const glog_stderrthreshold;49 static char const* const glog_stderrthreshold;
4950
=== modified file 'include/test/mir_test_doubles/mock_gl.h'
--- include/test/mir_test_doubles/mock_gl.h 2014-01-13 04:48:36 +0000
+++ include/test/mir_test_doubles/mock_gl.h 2014-01-13 16:47:16 +0000
@@ -47,6 +47,7 @@
47 void(GLenum, GLsizeiptr, const GLvoid *, GLenum));47 void(GLenum, GLsizeiptr, const GLvoid *, GLenum));
48 MOCK_METHOD1(glCheckFramebufferStatus, GLenum(GLenum));48 MOCK_METHOD1(glCheckFramebufferStatus, GLenum(GLenum));
49 MOCK_METHOD1(glClear, void(GLbitfield));49 MOCK_METHOD1(glClear, void(GLbitfield));
50 MOCK_METHOD4(glClearColor, void (GLclampf, GLclampf, GLclampf, GLclampf));
50 MOCK_METHOD1(glCompileShader, void(GLuint));51 MOCK_METHOD1(glCompileShader, void(GLuint));
51 MOCK_METHOD0(glCreateProgram, GLuint());52 MOCK_METHOD0(glCreateProgram, GLuint());
52 MOCK_METHOD1(glCreateShader, GLuint(GLenum));53 MOCK_METHOD1(glCreateShader, GLuint(GLenum));
5354
=== modified file 'include/test/mir_test_doubles/mock_surface_renderer.h'
--- include/test/mir_test_doubles/mock_surface_renderer.h 2014-01-13 04:48:36 +0000
+++ include/test/mir_test_doubles/mock_surface_renderer.h 2014-01-13 16:47:16 +0000
@@ -35,6 +35,7 @@
35 MOCK_CONST_METHOD2(render, void(compositor::CompositingCriteria const&, graphics::Buffer&));35 MOCK_CONST_METHOD2(render, void(compositor::CompositingCriteria const&, graphics::Buffer&));
36 MOCK_CONST_METHOD0(end, void());36 MOCK_CONST_METHOD0(end, void());
37 MOCK_METHOD0(suspend, void());37 MOCK_METHOD0(suspend, void());
38 MOCK_METHOD1(set_clear_color, void(Color const&));
3839
39 ~MockSurfaceRenderer() noexcept {}40 ~MockSurfaceRenderer() noexcept {}
40};41};
4142
=== modified file 'src/platform/graphics/android/output_builder.cpp'
--- src/platform/graphics/android/output_builder.cpp 2014-01-10 03:59:43 +0000
+++ src/platform/graphics/android/output_builder.cpp 2014-01-13 16:47:16 +0000
@@ -26,6 +26,8 @@
26#include "mir/graphics/display_report.h"26#include "mir/graphics/display_report.h"
27#include "mir/graphics/egl_resources.h"27#include "mir/graphics/egl_resources.h"
2828
29#include <hardware/hwcomposer_defs.h>
30
29namespace mg = mir::graphics;31namespace mg = mir::graphics;
30namespace mga = mir::graphics::android;32namespace mga = mir::graphics::android;
31namespace geom = mir::geometry;33namespace geom = mir::geometry;
3234
=== modified file 'src/server/compositor/default_configuration.cpp'
--- src/server/compositor/default_configuration.cpp 2014-01-13 04:48:36 +0000
+++ src/server/compositor/default_configuration.cpp 2014-01-13 16:47:16 +0000
@@ -19,12 +19,46 @@
19#include "mir/default_server_configuration.h"19#include "mir/default_server_configuration.h"
20#include "buffer_stream_factory.h"20#include "buffer_stream_factory.h"
21#include "default_display_buffer_compositor_factory.h"21#include "default_display_buffer_compositor_factory.h"
22#include "gl_renderer_factory.h"
22#include "multi_threaded_compositor.h"23#include "multi_threaded_compositor.h"
23#include "gl_renderer_factory.h"24#include "renderer.h"
25
26#include <boost/throw_exception.hpp>
27#include <stdexcept>
28#include <sstream>
2429
25namespace mc = mir::compositor;30namespace mc = mir::compositor;
26namespace ms = mir::scene;31namespace ms = mir::scene;
2732
33namespace
34{
35
36float clamp(unsigned long color)
37{
38 if (color > 255) color = 255;
39 return float(color)/255.0f;
40}
41
42mc::Renderer::Color extract_color(std::string const& value)
43{
44 unsigned long color;
45 std::istringstream in(value);
46 in >> std::hex >> color;
47
48 if (in.fail() || !(in >> std::ws).eof())
49 BOOST_THROW_EXCEPTION(std::runtime_error("Clear color should be a hexadecmial number"));
50
51 return mc::Renderer::Color
52 {
53 clamp((color >> 24) & 0xFF),
54 clamp((color >> 16) & 0xFF),
55 clamp((color >> 8) & 0xFF),
56 clamp(color & 0xFF)
57 };
58}
59
60}
61
28std::shared_ptr<ms::BufferStreamFactory>62std::shared_ptr<ms::BufferStreamFactory>
29mir::DefaultServerConfiguration::the_buffer_stream_factory()63mir::DefaultServerConfiguration::the_buffer_stream_factory()
30{64{
@@ -61,9 +95,29 @@
6195
62std::shared_ptr<mc::RendererFactory> mir::DefaultServerConfiguration::the_renderer_factory()96std::shared_ptr<mc::RendererFactory> mir::DefaultServerConfiguration::the_renderer_factory()
63{97{
98 struct ClearColorSettingRendererFactory : mc::GLRendererFactory
99 {
100 ClearColorSettingRendererFactory(mc::Renderer::Color const& color) : color(color) {}
101
102 std::unique_ptr<mc::Renderer> create_renderer_for(geometry::Rectangle const& rect) override
103 {
104 std::unique_ptr<mc::Renderer> renderer{GLRendererFactory::create_renderer_for(rect)};
105 renderer->set_clear_color(color);
106 return renderer;
107 }
108
109 mc::Renderer::Color color;
110 };
111
64 return renderer_factory(112 return renderer_factory(
65 []()113 [this]() -> std::shared_ptr<mc::RendererFactory>
66 {114 {
115 auto const options = the_options();
116 if (options->is_set(clear_color))
117 {
118 mc::Renderer::Color color = extract_color(options->get(clear_color, "0x000000FF"));
119 return std::make_shared<ClearColorSettingRendererFactory>(color);
120 }
67 return std::make_shared<mc::GLRendererFactory>();121 return std::make_shared<mc::GLRendererFactory>();
68 });122 });
69}123}
70124
=== modified file 'src/server/compositor/gl_renderer.cpp'
--- src/server/compositor/gl_renderer.cpp 2014-01-13 04:48:36 +0000
+++ src/server/compositor/gl_renderer.cpp 2014-01-13 16:47:16 +0000
@@ -125,7 +125,8 @@
125 texcoord_attr_loc(0),125 texcoord_attr_loc(0),
126 transform_uniform_loc(0),126 transform_uniform_loc(0),
127 alpha_uniform_loc(0),127 alpha_uniform_loc(0),
128 vertex_attribs_vbo(0)128 vertex_attribs_vbo(0),
129 clear_color{0.0f,0.0f,0.0f,1.0f}
129{130{
130 GLint param = 0;131 GLint param = 0;
131132
@@ -282,6 +283,8 @@
282283
283void mc::GLRenderer::begin() const284void mc::GLRenderer::begin() const
284{285{
286 glClearColor(std::get<0>(clear_color), std::get<1>(clear_color), std::get<2>(clear_color),
287 std::get<3>(clear_color));
285 glClear(GL_COLOR_BUFFER_BIT);288 glClear(GL_COLOR_BUFFER_BIT);
286}289}
287290
@@ -309,3 +312,8 @@
309{312{
310 skipped = true;313 skipped = true;
311}314}
315
316void mc::GLRenderer::set_clear_color(Color const& color)
317{
318 clear_color = color;
319}
312320
=== modified file 'src/server/compositor/gl_renderer.h'
--- src/server/compositor/gl_renderer.h 2014-01-13 04:48:36 +0000
+++ src/server/compositor/gl_renderer.h 2014-01-13 16:47:16 +0000
@@ -44,6 +44,8 @@
44 // This is called _without_ a GL context:44 // This is called _without_ a GL context:
45 void suspend() override;45 void suspend() override;
4646
47 void set_clear_color(Color const& color) override;
48
47private:49private:
48 GLuint vertex_shader;50 GLuint vertex_shader;
49 GLuint fragment_shader;51 GLuint fragment_shader;
@@ -53,6 +55,7 @@
53 GLuint transform_uniform_loc;55 GLuint transform_uniform_loc;
54 GLuint alpha_uniform_loc;56 GLuint alpha_uniform_loc;
55 GLuint vertex_attribs_vbo;57 GLuint vertex_attribs_vbo;
58 Color clear_color;
5659
57 typedef CompositingCriteria const* SurfaceID;60 typedef CompositingCriteria const* SurfaceID;
58 struct Texture61 struct Texture
5962
=== modified file 'src/server/compositor/renderer.h'
--- src/server/compositor/renderer.h 2014-01-13 04:48:36 +0000
+++ src/server/compositor/renderer.h 2014-01-13 16:47:16 +0000
@@ -19,6 +19,8 @@
19#ifndef MIR_COMPOSITOR_RENDERER_H_19#ifndef MIR_COMPOSITOR_RENDERER_H_
20#define MIR_COMPOSITOR_RENDERER_H_20#define MIR_COMPOSITOR_RENDERER_H_
2121
22#include <tuple>
23
22namespace mir24namespace mir
23{25{
24namespace graphics26namespace graphics
@@ -40,6 +42,9 @@
4042
41 virtual void suspend() = 0; // called when begin/render/end skipped43 virtual void suspend() = 0; // called when begin/render/end skipped
4244
45 typedef std::tuple<float, float, float, float> Color;
46 virtual void set_clear_color(Color const& color) = 0;
47
43protected:48protected:
44 Renderer() = default;49 Renderer() = default;
45 Renderer(const Renderer&) = delete;50 Renderer(const Renderer&) = delete;
4651
=== modified file 'src/server/default_configuration_options.cpp'
--- src/server/default_configuration_options.cpp 2014-01-13 04:48:36 +0000
+++ src/server/default_configuration_options.cpp 2014-01-13 16:47:16 +0000
@@ -81,6 +81,7 @@
81char const* const mir::ConfigurationOptions::frontend_threads = "ipc-thread-pool";81char const* const mir::ConfigurationOptions::frontend_threads = "ipc-thread-pool";
82char const* const mir::ConfigurationOptions::name_opt = "name";82char const* const mir::ConfigurationOptions::name_opt = "name";
83char const* const mir::ConfigurationOptions::offscreen_opt = "offscreen";83char const* const mir::ConfigurationOptions::offscreen_opt = "offscreen";
84char const* const mir::ConfigurationOptions::clear_color = "clear-color";
8485
85char const* const mir::ConfigurationOptions::glog = "glog";86char const* const mir::ConfigurationOptions::glog = "glog";
86char const* const mir::ConfigurationOptions::glog_stderrthreshold = "glog-stderrthreshold";87char const* const mir::ConfigurationOptions::glog_stderrthreshold = "glog-stderrthreshold";
@@ -160,6 +161,9 @@
160 "When nested, the name Mir uses when registering with the host.")161 "When nested, the name Mir uses when registering with the host.")
161 (offscreen_opt,162 (offscreen_opt,
162 "Render to offscreen buffers instead of the real outputs.")163 "Render to offscreen buffers instead of the real outputs.")
164 (clear_color, po::value<std::string>(),
165 "Configure which color should be used for clearing the framebuffer."
166 " [hexadecimal number 0xRRGGBBAA:default=0x000000FF")
163 ("vt", po::value<int>(),167 ("vt", po::value<int>(),
164 "VT to run on or 0 to use current. [int:default=0]");168 "VT to run on or 0 to use current. [int:default=0]");
165}169}
166170
=== modified file 'src/server/options/program_option.cpp'
--- src/server/options/program_option.cpp 2013-09-27 21:01:24 +0000
+++ src/server/options/program_option.cpp 2014-01-13 16:47:16 +0000
@@ -139,3 +139,4 @@
139139
140 return default_;140 return default_;
141}141}
142
142143
=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
--- tests/acceptance-tests/test_server_shutdown.cpp 2014-01-13 04:48:36 +0000
+++ tests/acceptance-tests/test_server_shutdown.cpp 2014-01-13 16:47:16 +0000
@@ -68,6 +68,10 @@
68 void suspend() override68 void suspend() override
69 {69 {
70 }70 }
71
72 void set_clear_color(Color const&) override
73 {
74 }
71};75};
7276
73class NullRendererFactory : public mc::RendererFactory77class NullRendererFactory : public mc::RendererFactory
7478
=== modified file 'tests/integration-tests/test_session.cpp'
--- tests/integration-tests/test_session.cpp 2014-01-13 04:48:36 +0000
+++ tests/integration-tests/test_session.cpp 2014-01-13 16:47:16 +0000
@@ -90,6 +90,11 @@
90 void begin() const override90 void begin() const override
91 {91 {
92 }92 }
93
94 void set_clear_color(Color const&) override
95 {
96 }
97
93 void render(mc::CompositingCriteria const&, mg::Buffer&) const override98 void render(mc::CompositingCriteria const&, mg::Buffer&) const override
94 {99 {
95 }100 }
96101
=== modified file 'tests/integration-tests/test_surface_first_frame_sync.cpp'
--- tests/integration-tests/test_surface_first_frame_sync.cpp 2014-01-13 04:48:36 +0000
+++ tests/integration-tests/test_surface_first_frame_sync.cpp 2014-01-13 16:47:16 +0000
@@ -64,7 +64,7 @@
64 {64 {
65 display_buffer_compositor_map[&display_buffer] = db_compositor_factory->create_compositor_for(display_buffer);65 display_buffer_compositor_map[&display_buffer] = db_compositor_factory->create_compositor_for(display_buffer);
66 });66 });
67}67 }
6868
69 void start()69 void start()
70 {70 {
@@ -100,6 +100,10 @@
100 {100 {
101 }101 }
102102
103 void set_clear_color(Color const&) override
104 {
105 }
106
103 void render(mc::CompositingCriteria const&, mg::Buffer&) const override107 void render(mc::CompositingCriteria const&, mg::Buffer&) const override
104 {108 {
105 while (write(render_operations_fd, "a", 1) != 1) continue;109 while (write(render_operations_fd, "a", 1) != 1) continue;
106110
=== modified file 'tests/mir_test_doubles/mock_gl.cpp'
--- tests/mir_test_doubles/mock_gl.cpp 2014-01-13 04:48:36 +0000
+++ tests/mir_test_doubles/mock_gl.cpp 2014-01-13 16:47:16 +0000
@@ -76,12 +76,18 @@
76 global_mock_gl->glUseProgram (program);76 global_mock_gl->glUseProgram (program);
77}77}
7878
79void glClear (GLbitfield mask)79void glClear(GLbitfield mask)
80{80{
81 CHECK_GLOBAL_VOID_MOCK();81 CHECK_GLOBAL_VOID_MOCK();
82 global_mock_gl->glClear(mask);82 global_mock_gl->glClear(mask);
83}83}
8484
85void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
86{
87 CHECK_GLOBAL_VOID_MOCK();
88 global_mock_gl->glClearColor(red, green, blue, alpha);
89}
90
85void glEnable(GLenum func)91void glEnable(GLenum func)
86{92{
87 CHECK_GLOBAL_VOID_MOCK();93 CHECK_GLOBAL_VOID_MOCK();
8894
=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
--- tests/mir_test_framework/stubbed_server_configuration.cpp 2014-01-13 04:48:36 +0000
+++ tests/mir_test_framework/stubbed_server_configuration.cpp 2014-01-13 16:47:16 +0000
@@ -216,6 +216,10 @@
216 void suspend() override216 void suspend() override
217 {217 {
218 }218 }
219
220 void set_clear_color(Color const&) override
221 {
222 }
219};223};
220224
221class StubRendererFactory : public mc::RendererFactory225class StubRendererFactory : public mc::RendererFactory
222226
=== modified file 'tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp'
--- tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2014-01-13 04:48:36 +0000
+++ tests/unit-tests/compositor/test_default_display_buffer_compositor.cpp 2014-01-13 16:47:16 +0000
@@ -128,6 +128,11 @@
128 renderer->suspend();128 renderer->suspend();
129 }129 }
130130
131 void set_clear_color(Color const& color) override
132 {
133 renderer->set_clear_color(color);
134 }
135
131 mc::Renderer* const renderer;136 mc::Renderer* const renderer;
132};137};
133138
134139
=== modified file 'tests/unit-tests/compositor/test_gl_renderer.cpp'
--- tests/unit-tests/compositor/test_gl_renderer.cpp 2014-01-13 04:48:36 +0000
+++ tests/unit-tests/compositor/test_gl_renderer.cpp 2014-01-13 16:47:16 +0000
@@ -465,3 +465,22 @@
465 renderer->begin();465 renderer->begin();
466 renderer->end();466 renderer->end();
467}467}
468
469TEST_F(GLRenderer, clears_with_black_by_default)
470{
471 InSequence seq;
472 EXPECT_CALL(mock_gl, glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
473 EXPECT_CALL(mock_gl, glClear(_));
474
475 renderer->begin();
476}
477
478TEST_F(GLRenderer, clears_with_clear_color)
479{
480 InSequence seq;
481 EXPECT_CALL(mock_gl, glClearColor(0.8f, 0.2f, 0.4f, 1.0f));
482 EXPECT_CALL(mock_gl, glClear(_));
483
484 renderer->set_clear_color(mc::Renderer::Color{0.8f, 0.2f, 0.4f, 1.0f});
485 renderer->begin();
486}

Subscribers

People subscribed via source and target branches