Mir

Merge lp:~vanvugt/mir/black-bars into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 4035
Proposed branch: lp:~vanvugt/mir/black-bars
Merge into: lp:mir
Diff against target: 157 lines (+132/-0)
2 files modified
src/renderers/gl/renderer.cpp (+31/-0)
tests/unit-tests/renderers/gl/test_gl_renderer.cpp (+101/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/black-bars
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
Mir CI Bot continuous-integration Approve
Review via email: mp+317293@code.launchpad.net

Commit message

Add letterboxing/black bars support to the GL renderer, for when
the logical viewport aspect doesn't match that of the screen.

This will be used in future for arbitrary cloning of one monitor
to another (LP: #1639226)

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4038
https://mir-jenkins.ubuntu.com/job/mir-ci/2997/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/3994
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4080
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4070
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4070
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4070
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4021/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/2997/rebuild

review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/renderers/gl/renderer.cpp'
2--- src/renderers/gl/renderer.cpp 2017-01-27 08:13:36 +0000
3+++ src/renderers/gl/renderer.cpp 2017-02-15 10:20:35 +0000
4@@ -370,6 +370,37 @@
5 0.0f});
6
7 viewport = rect;
8+
9+ /*
10+ * Letterboxing: Move the glViewport to add black bars in the case that
11+ * the logical viewport aspect ratio doesn't match the display aspect.
12+ * This keeps pixels square. Note "black"-bars are really glClearColor.
13+ */
14+ auto transformed_viewport = display_transform *
15+ glm::vec4(viewport.size.width.as_int(),
16+ viewport.size.height.as_int(), 0, 1);
17+ auto viewport_width = fabs(transformed_viewport[0]);
18+ auto viewport_height = fabs(transformed_viewport[1]);
19+ auto dpy = eglGetCurrentDisplay();
20+ auto surf = eglGetCurrentSurface(EGL_DRAW);
21+ EGLint buf_width = 0, buf_height = 0;
22+
23+ if (viewport_width > 0.0f && viewport_height > 0.0f &&
24+ eglQuerySurface(dpy, surf, EGL_WIDTH, &buf_width) && buf_width > 0 &&
25+ eglQuerySurface(dpy, surf, EGL_HEIGHT, &buf_height) && buf_height > 0)
26+ {
27+ GLint reduced_width = buf_width, reduced_height = buf_height;
28+ // if viewport_aspect_ratio >= buf_aspect_ratio
29+ if (viewport_width * buf_height >= buf_width * viewport_height)
30+ reduced_height = buf_width * viewport_height / viewport_width;
31+ else
32+ reduced_width = buf_height * viewport_width / viewport_height;
33+
34+ GLint offset_x = (buf_width - reduced_width) / 2;
35+ GLint offset_y = (buf_height - reduced_height) / 2;
36+
37+ glViewport(offset_x, offset_y, reduced_width, reduced_height);
38+ }
39 }
40
41 void mrg::Renderer::set_output_transform(glm::mat2 const& t)
42
43=== modified file 'tests/unit-tests/renderers/gl/test_gl_renderer.cpp'
44--- tests/unit-tests/renderers/gl/test_gl_renderer.cpp 2016-01-29 08:18:22 +0000
45+++ tests/unit-tests/renderers/gl/test_gl_renderer.cpp 2017-02-15 10:20:35 +0000
46@@ -39,6 +39,7 @@
47 using testing::Pointee;
48 using testing::AnyNumber;
49 using testing::AtLeast;
50+using testing::DoAll;
51 using testing::_;
52
53 namespace mt=mir::test;
54@@ -314,3 +315,103 @@
55
56 renderer.render(renderable_list);
57 }
58+
59+TEST_F(GLRenderer, sets_viewport_unscaled_exact)
60+{
61+ int const screen_width = 1920;
62+ int const screen_height = 1080;
63+ mir::geometry::Rectangle const view_area{{0,0}, {1920,1080}};
64+
65+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_WIDTH,_))
66+ .WillByDefault(DoAll(SetArgPointee<3>(screen_width),
67+ Return(EGL_TRUE)));
68+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_HEIGHT,_))
69+ .WillByDefault(DoAll(SetArgPointee<3>(screen_height),
70+ Return(EGL_TRUE)));
71+ ON_CALL(mock_display_buffer, view_area())
72+ .WillByDefault(Return(view_area));
73+
74+ EXPECT_CALL(mock_gl, glViewport(0, 0, screen_width, screen_height));
75+
76+ mrg::Renderer renderer(mock_display_buffer);
77+}
78+
79+TEST_F(GLRenderer, sets_viewport_upscaled_exact)
80+{
81+ int const screen_width = 1920;
82+ int const screen_height = 1080;
83+ mir::geometry::Rectangle const view_area{{0,0}, {1280,720}};
84+
85+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_WIDTH,_))
86+ .WillByDefault(DoAll(SetArgPointee<3>(screen_width),
87+ Return(EGL_TRUE)));
88+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_HEIGHT,_))
89+ .WillByDefault(DoAll(SetArgPointee<3>(screen_height),
90+ Return(EGL_TRUE)));
91+ ON_CALL(mock_display_buffer, view_area())
92+ .WillByDefault(Return(view_area));
93+
94+ EXPECT_CALL(mock_gl, glViewport(0, 0, screen_width, screen_height));
95+
96+ mrg::Renderer renderer(mock_display_buffer);
97+}
98+
99+TEST_F(GLRenderer, sets_viewport_downscaled_exact)
100+{
101+ int const screen_width = 1280;
102+ int const screen_height = 720;
103+ mir::geometry::Rectangle const view_area{{0,0}, {1920,1080}};
104+
105+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_WIDTH,_))
106+ .WillByDefault(DoAll(SetArgPointee<3>(screen_width),
107+ Return(EGL_TRUE)));
108+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_HEIGHT,_))
109+ .WillByDefault(DoAll(SetArgPointee<3>(screen_height),
110+ Return(EGL_TRUE)));
111+ ON_CALL(mock_display_buffer, view_area())
112+ .WillByDefault(Return(view_area));
113+
114+ EXPECT_CALL(mock_gl, glViewport(0, 0, screen_width, screen_height));
115+
116+ mrg::Renderer renderer(mock_display_buffer);
117+}
118+
119+TEST_F(GLRenderer, sets_viewport_upscaled_narrow)
120+{
121+ int const screen_width = 1920;
122+ int const screen_height = 1080;
123+ mir::geometry::Rectangle const view_area{{0,0}, {640,480}};
124+
125+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_WIDTH,_))
126+ .WillByDefault(DoAll(SetArgPointee<3>(screen_width),
127+ Return(EGL_TRUE)));
128+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_HEIGHT,_))
129+ .WillByDefault(DoAll(SetArgPointee<3>(screen_height),
130+ Return(EGL_TRUE)));
131+ ON_CALL(mock_display_buffer, view_area())
132+ .WillByDefault(Return(view_area));
133+
134+ EXPECT_CALL(mock_gl, glViewport(240, 0, 1440, 1080));
135+
136+ mrg::Renderer renderer(mock_display_buffer);
137+}
138+
139+TEST_F(GLRenderer, sets_viewport_downscaled_wide)
140+{
141+ int const screen_width = 640;
142+ int const screen_height = 480;
143+ mir::geometry::Rectangle const view_area{{0,0}, {1920,1080}};
144+
145+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_WIDTH,_))
146+ .WillByDefault(DoAll(SetArgPointee<3>(screen_width),
147+ Return(EGL_TRUE)));
148+ ON_CALL(mock_egl, eglQuerySurface(_,_,EGL_HEIGHT,_))
149+ .WillByDefault(DoAll(SetArgPointee<3>(screen_height),
150+ Return(EGL_TRUE)));
151+ ON_CALL(mock_display_buffer, view_area())
152+ .WillByDefault(Return(view_area));
153+
154+ EXPECT_CALL(mock_gl, glViewport(0, 60, 640, 360));
155+
156+ mrg::Renderer renderer(mock_display_buffer);
157+}

Subscribers

People subscribed via source and target branches