Mir

Merge lp:~kdub/mir/hwc-alpha-support into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 1708
Proposed branch: lp:~kdub/mir/hwc-alpha-support
Merge into: lp:mir
Diff against target: 357 lines (+85/-21)
11 files modified
debian/control (+1/-1)
include/test/mir_test_doubles/stub_renderable.h (+12/-0)
src/platform/graphics/android/hwc_device.cpp (+14/-4)
src/platform/graphics/android/hwc_fallback_gl_renderer.cpp (+6/-1)
src/platform/graphics/android/hwc_layers.cpp (+12/-1)
tests/unit-tests/graphics/android/hwc_struct_helpers.cpp (+1/-0)
tests/unit-tests/graphics/android/hwc_struct_helpers.h (+1/-0)
tests/unit-tests/graphics/android/test_hwc_device.cpp (+10/-6)
tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp (+24/-7)
tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+1/-0)
tests/unit-tests/graphics/android/test_hwc_layers.cpp (+3/-1)
To merge this branch: bzr merge lp:~kdub/mir/hwc-alpha-support
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Alan Griffiths Approve
Chris Halse Rogers Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+223617@code.launchpad.net

Commit message

android: support alpha blending overlays together in HWC. bumps android-headers version requirement from 4.2.2 to 4.4.2. also change to premultiplied blending in hwc by default, as thats more in line with the rest of the system.

lp: #1329879

Description of the change

android: support alpha blending overlays together in HWC. bumps android-headers version requirement from 4.2.2 to 4.4.2. also change to premultiplied blending in hwc by default, as thats more in line with the rest of the system.

lp: #1329879

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
Chris Halse Rogers (raof) wrote :

LGTM

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

Nit:

30 + return 1.0f - ( 3.0f / 1024.0f );

"Parentheses should have no spaces inside them."

http://unity.ubuntu.com/mir/cppguide/index.html?showone=Horizontal_Whitespace#Horizontal_Whitespace

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

OK.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-06-18 14:10:30 +0000
3+++ debian/control 2014-06-18 17:29:05 +0000
4@@ -27,7 +27,7 @@
5 libglm-dev,
6 libprotobuf-dev,
7 pkg-config,
8- android-headers (>=4.2.2) [i386 amd64 armhf],
9+ android-headers (>=4.4.2) [i386 amd64 armhf],
10 libhardware-dev [i386 amd64 armhf],
11 libandroid-properties-dev [i386 amd64 armhf],
12 libgoogle-glog-dev,
13
14=== modified file 'include/test/mir_test_doubles/stub_renderable.h'
15--- include/test/mir_test_doubles/stub_renderable.h 2014-06-13 23:30:22 +0000
16+++ include/test/mir_test_doubles/stub_renderable.h 2014-06-18 17:29:05 +0000
17@@ -130,6 +130,18 @@
18 }
19 };
20
21+struct PlaneAlphaRenderable : public StubRenderable
22+{
23+ bool alpha_enabled() const override
24+ {
25+ return true;
26+ }
27+ float alpha() const override
28+ {
29+ //approx 99% alpha
30+ return 1.0f - ( 3.0f / 1024.0f );
31+ }
32+};
33 }
34 }
35 }
36
37=== modified file 'src/platform/graphics/android/hwc_device.cpp'
38--- src/platform/graphics/android/hwc_device.cpp 2014-06-16 14:47:14 +0000
39+++ src/platform/graphics/android/hwc_device.cpp 2014-06-18 17:29:05 +0000
40@@ -25,6 +25,7 @@
41 #include "framebuffer_bundle.h"
42 #include "buffer.h"
43 #include "hwc_fallback_gl_renderer.h"
44+#include <limits>
45
46 namespace mg = mir::graphics;
47 namespace mga=mir::graphics::android;
48@@ -34,6 +35,16 @@
49 {
50 static const size_t fbtarget_plus_skip_size = 2;
51 static const size_t fbtarget_size = 1;
52+
53+bool plane_alpha_is_translucent(mg::Renderable const& renderable)
54+{
55+ float static const tolerance
56+ {
57+ 1.0f/(2.0 * static_cast<float>(std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max()))
58+ };
59+ return renderable.alpha_enabled() && (renderable.alpha() < 1.0f - tolerance);
60+}
61+
62 bool renderable_list_is_hwc_incompatible(mg::RenderableList const& list)
63 {
64 if (list.empty())
65@@ -41,11 +52,10 @@
66
67 for(auto const& renderable : list)
68 {
69- //TODO: enable alpha, 90 deg rotation
70+ //TODO: enable planeAlpha for (hwc version >= 1.2), 90 deg rotation
71 static glm::mat4 const identity;
72- if (renderable->shaped() ||
73- renderable->alpha_enabled() ||
74- (renderable->transformation() != identity))
75+ if (plane_alpha_is_translucent(*renderable) ||
76+ (renderable->transformation() != identity))
77 {
78 return true;
79 }
80
81=== modified file 'src/platform/graphics/android/hwc_fallback_gl_renderer.cpp'
82--- src/platform/graphics/android/hwc_fallback_gl_renderer.cpp 2014-06-09 16:01:59 +0000
83+++ src/platform/graphics/android/hwc_fallback_gl_renderer.cpp 2014-06-18 17:29:05 +0000
84@@ -105,12 +105,17 @@
85
86 glClearColor(0.0, 0.0, 0.0, 1.0);
87 glClear(GL_COLOR_BUFFER_BIT);
88-
89+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
90 glEnableVertexAttribArray(position_attr);
91 glEnableVertexAttribArray(texcoord_attr);
92
93 for(auto const& renderable : renderlist)
94 {
95+ if (renderable->alpha_enabled())
96+ glEnable(GL_BLEND);
97+ else
98+ glDisable(GL_BLEND);
99+
100 auto const primitive = mg::tessellate_renderable_into_rectangle(*renderable);
101 glVertexAttribPointer(position_attr, 3, GL_FLOAT, GL_FALSE, sizeof(mg::GLVertex),
102 &primitive.vertices[0].position);
103
104=== modified file 'src/platform/graphics/android/hwc_layers.cpp'
105--- src/platform/graphics/android/hwc_layers.cpp 2014-06-04 22:41:05 +0000
106+++ src/platform/graphics/android/hwc_layers.cpp 2014-06-18 17:29:05 +0000
107@@ -22,6 +22,7 @@
108 #include "mir/graphics/android/native_buffer.h"
109 #include "hwc_layerlist.h"
110
111+#include <limits>
112 #include <boost/throw_exception.hpp>
113 #include <stdexcept>
114 #include <cstring>
115@@ -30,6 +31,13 @@
116 namespace mga=mir::graphics::android;
117 namespace geom=mir::geometry;
118
119+namespace
120+{
121+decltype(hwc_layer_1_t::planeAlpha) static const plane_alpha_max{
122+ std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max()
123+};
124+}
125+
126 mga::HWCLayer& mga::HWCLayer::operator=(HWCLayer && other)
127 {
128 hwc_layer = other.hwc_layer;
129@@ -58,6 +66,7 @@
130 hwc_layer->acquireFenceFd = -1;
131 hwc_layer->releaseFenceFd = -1;
132 hwc_layer->blending = HWC_BLENDING_NONE;
133+ hwc_layer->planeAlpha = plane_alpha_max;
134
135 hwc_layer->visibleRegionScreen.numRects=1;
136 hwc_layer->visibleRegionScreen.rects= &visible_rect;
137@@ -118,10 +127,12 @@
138 void mga::HWCLayer::set_render_parameters(geometry::Rectangle position, bool alpha_enabled)
139 {
140 if (alpha_enabled)
141- hwc_layer->blending = HWC_BLENDING_COVERAGE;
142+ hwc_layer->blending = HWC_BLENDING_PREMULT;
143 else
144 hwc_layer->blending = HWC_BLENDING_NONE;
145
146+ hwc_layer->planeAlpha = plane_alpha_max;
147+
148 /* note, if the sourceCrop and DisplayFrame sizes differ, the output will be linearly scaled */
149 hwc_layer->displayFrame =
150 {
151
152=== modified file 'tests/unit-tests/graphics/android/hwc_struct_helpers.cpp'
153--- tests/unit-tests/graphics/android/hwc_struct_helpers.cpp 2014-01-27 17:32:33 +0000
154+++ tests/unit-tests/graphics/android/hwc_struct_helpers.cpp 2014-06-18 17:29:05 +0000
155@@ -41,6 +41,7 @@
156 PrintTo(layer.displayFrame, os);
157 *os << std::endl;
158 *os << "\tvisibleRegionScreen.numRects: " << layer.visibleRegionScreen.numRects << std::endl
159+ << "\tplaneAlpha: " << layer.planeAlpha << std::endl
160 << "\tacquireFenceFd: " << layer.acquireFenceFd << std::endl
161 << "\treleaseFenceFd: " << layer.releaseFenceFd << std::endl;
162 }
163
164=== modified file 'tests/unit-tests/graphics/android/hwc_struct_helpers.h'
165--- tests/unit-tests/graphics/android/hwc_struct_helpers.h 2014-03-26 05:48:59 +0000
166+++ tests/unit-tests/graphics/android/hwc_struct_helpers.h 2014-06-18 17:29:05 +0000
167@@ -61,6 +61,7 @@
168 EXPECT_THAT(arg.sourceCrop, MatchesRect(value.sourceCrop, "sourceCrop"));
169 EXPECT_THAT(arg.displayFrame, MatchesRect(value.displayFrame, "displayFrame"));
170 EXPECT_THAT(arg.visibleRegionScreen.numRects, MatchesMember(value.visibleRegionScreen.numRects, "visibleRegionScreen.numRects"));
171+ EXPECT_THAT(arg.planeAlpha, MatchesMember(value.planeAlpha, "planeAlpha"));
172 EXPECT_THAT(arg.acquireFenceFd, MatchesMember(value.acquireFenceFd, "acquireFenceFd"));
173 EXPECT_THAT(arg.releaseFenceFd, MatchesMember(value.releaseFenceFd, "releaseFenceFd"));
174
175
176=== modified file 'tests/unit-tests/graphics/android/test_hwc_device.cpp'
177--- tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-06-16 14:47:14 +0000
178+++ tests/unit-tests/graphics/android/test_hwc_device.cpp 2014-06-18 17:29:05 +0000
179@@ -96,6 +96,7 @@
180 comp_layer.visibleRegionScreen = {1, &set_region};
181 comp_layer.acquireFenceFd = -1;
182 comp_layer.releaseFenceFd = -1;
183+ comp_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
184
185 target_layer.compositionType = HWC_FRAMEBUFFER_TARGET;
186 target_layer.hints = 0;
187@@ -108,6 +109,7 @@
188 target_layer.visibleRegionScreen = {1, &set_region};
189 target_layer.acquireFenceFd = -1;
190 target_layer.releaseFenceFd = -1;
191+ target_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
192
193 skip_layer.compositionType = HWC_FRAMEBUFFER;
194 skip_layer.hints = 0;
195@@ -120,6 +122,7 @@
196 skip_layer.visibleRegionScreen = {1, &set_region};
197 skip_layer.acquireFenceFd = -1;
198 skip_layer.releaseFenceFd = -1;
199+ skip_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
200
201 set_skip_layer = skip_layer;
202 set_skip_layer.handle = mock_native_buffer->handle();
203@@ -359,6 +362,7 @@
204 comp_layer1.visibleRegionScreen = {1, &set_region};
205 comp_layer1.acquireFenceFd = overlay_acquire_fence1;
206 comp_layer1.releaseFenceFd = -1;
207+ comp_layer1.planeAlpha = 0xFF;
208
209 comp_layer2.compositionType = HWC_OVERLAY;
210 comp_layer2.hints = 0;
211@@ -371,6 +375,7 @@
212 comp_layer2.visibleRegionScreen = {1, &set_region};
213 comp_layer2.acquireFenceFd = overlay_acquire_fence2;
214 comp_layer2.releaseFenceFd = -1;
215+ comp_layer2.planeAlpha = 0xFF;
216
217 set_target_layer.acquireFenceFd = fb_acquire_fence;
218 set_target_layer.handle = native_handle_3->handle();
219@@ -572,14 +577,13 @@
220 EXPECT_FALSE(device.post_overlays(stub_context, renderlist, stub_compositor));
221 }
222
223-//TODO: remove once alpha+HWC is turned on
224-TEST_F(HwcDevice, rejects_list_containing_alpha)
225+//TODO: support plane alpha for hwc 1.2 and later
226+TEST_F(HwcDevice, rejects_list_containing_plane_alpha)
227 {
228+ using namespace testing;
229+
230 mga::HwcDevice device(mock_device, mock_hwc_device_wrapper, mock_vsync, mock_file_ops);
231
232- mg::RenderableList renderlist{std::make_shared<mtd::StubTranslucentRenderable>()};
233- EXPECT_FALSE(device.post_overlays(stub_context, renderlist, stub_compositor));
234-
235- mg::RenderableList renderlist2{std::make_shared<mtd::StubShapedRenderable>()};
236+ mg::RenderableList renderlist{std::make_shared<mtd::PlaneAlphaRenderable>()};
237 EXPECT_FALSE(device.post_overlays(stub_context, renderlist, stub_compositor));
238 }
239
240=== modified file 'tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp'
241--- tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp 2014-05-22 16:46:42 +0000
242+++ tests/unit-tests/graphics/android/test_hwc_fallback_gl_renderer.cpp 2014-06-18 17:29:05 +0000
243@@ -121,6 +121,7 @@
244 size_t const stride{sizeof(mg::GLVertex)};
245
246 testing::NiceMock<MockGLProgramFactory> mock_gl_program_factory;
247+ testing::NiceMock<mtd::MockSwappingGLContext> mock_swapping_context;
248 testing::NiceMock<MockContext> mock_context;
249 testing::NiceMock<mtd::MockGL> mock_gl;
250 testing::NiceMock<mtd::MockEGL> mock_egl;
251@@ -205,7 +206,6 @@
252 TEST_F(HWCFallbackGLRenderer, computes_vertex_coordinates_correctly)
253 {
254 using namespace testing;
255- NiceMock<mtd::MockSwappingGLContext> mock_context_s;
256 geom::Rectangle rect1{{100,200},{50, 60}};
257 geom::Rectangle rect2{{150,250},{150, 90}};
258
259@@ -238,13 +238,12 @@
260 .Times(1);
261
262 mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos);
263- glprogram.render(renderlist, mock_context_s);
264+ glprogram.render(renderlist, mock_swapping_context);
265 }
266
267 TEST_F(HWCFallbackGLRenderer, computes_texture_coordinates_correctly)
268 {
269 using namespace testing;
270- NiceMock<mtd::MockSwappingGLContext> mock_context_s;
271 geom::Rectangle rect1{{100,200},{50, 60}};
272 geom::Rectangle rect2{{150,250},{150, 90}};
273
274@@ -266,13 +265,12 @@
275 .Times(2);
276
277 mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos);
278- glprogram.render(renderlist, mock_context_s);
279+ glprogram.render(renderlist, mock_swapping_context);
280 }
281
282 TEST_F(HWCFallbackGLRenderer, executes_render_in_sequence)
283 {
284 using namespace testing;
285- NiceMock<mtd::MockSwappingGLContext> mock_context_s;
286 auto renderable1 = std::make_shared<mtd::StubRenderable>();
287 auto renderable2 = std::make_shared<mtd::StubRenderable>();
288 mg::RenderableList renderlist{ renderable1, renderable2 };
289@@ -308,8 +306,27 @@
290
291 EXPECT_CALL(mock_gl, glDisableVertexAttribArray(texcoord_attr_loc));
292 EXPECT_CALL(mock_gl, glDisableVertexAttribArray(position_attr_loc));
293- EXPECT_CALL(mock_context_s, swap_buffers());
294+ EXPECT_CALL(mock_swapping_context, swap_buffers());
295 EXPECT_CALL(mock_gl, glUseProgram(0));
296
297- glprogram.render(renderlist, mock_context_s);
298+ glprogram.render(renderlist, mock_swapping_context);
299+}
300+
301+TEST_F(HWCFallbackGLRenderer, activates_alpha_per_renderable)
302+{
303+ mg::RenderableList renderlist{
304+ std::make_shared<mtd::StubTranslucentRenderable>(),
305+ std::make_shared<mtd::StubRenderable>(),
306+ std::make_shared<mtd::StubTranslucentRenderable>()
307+ };
308+
309+ mga::HWCFallbackGLRenderer glprogram(mock_gl_program_factory, mock_context, dummy_screen_pos);
310+
311+ testing::InSequence seq;
312+ EXPECT_CALL(mock_gl, glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
313+ EXPECT_CALL(mock_gl, glEnable(GL_BLEND));
314+ EXPECT_CALL(mock_gl, glDisable(GL_BLEND));
315+ EXPECT_CALL(mock_gl, glEnable(GL_BLEND));
316+
317+ glprogram.render(renderlist, mock_swapping_context);
318 }
319
320=== modified file 'tests/unit-tests/graphics/android/test_hwc_fb_device.cpp'
321--- tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-06-16 14:47:14 +0000
322+++ tests/unit-tests/graphics/android/test_hwc_fb_device.cpp 2014-06-18 17:29:05 +0000
323@@ -69,6 +69,7 @@
324 skip_layer.visibleRegionScreen = {1, &empty_region};
325 skip_layer.acquireFenceFd = -1;
326 skip_layer.releaseFenceFd = -1;
327+ skip_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
328
329 ON_CALL(mock_context, last_rendered_buffer())
330 .WillByDefault(Return(mock_buffer));
331
332=== modified file 'tests/unit-tests/graphics/android/test_hwc_layers.cpp'
333--- tests/unit-tests/graphics/android/test_hwc_layers.cpp 2014-05-16 06:02:30 +0000
334+++ tests/unit-tests/graphics/android/test_hwc_layers.cpp 2014-06-18 17:29:05 +0000
335@@ -71,6 +71,7 @@
336 expected_layer.visibleRegionScreen = {1, &region};
337 expected_layer.acquireFenceFd = -1;
338 expected_layer.releaseFenceFd = -1;
339+ expected_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
340 }
341
342 mga::LayerType type;
343@@ -270,12 +271,13 @@
344 expected_layer.flags = 0;
345 expected_layer.handle = native_handle_1->handle();
346 expected_layer.transform = 0;
347- expected_layer.blending = HWC_BLENDING_COVERAGE;
348+ expected_layer.blending = HWC_BLENDING_PREMULT;
349 expected_layer.sourceCrop = crop;
350 expected_layer.displayFrame = screen_pos;
351 expected_layer.visibleRegionScreen = visible_region;
352 expected_layer.acquireFenceFd = -1;
353 expected_layer.releaseFenceFd = -1;
354+ expected_layer.planeAlpha = std::numeric_limits<decltype(hwc_layer_1_t::planeAlpha)>::max();
355
356 mga::HWCLayer layer(list, list_index);
357 layer.set_render_parameters(screen_position, true);

Subscribers

People subscribed via source and target branches