Merge lp:~vanvugt/mir/16bpp into lp:mir
- 16bpp
- Merge into development-branch
Status: | Merged | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Daniel van Vugt | ||||||||||||||||||||
Approved revision: | no longer in the source branch. | ||||||||||||||||||||
Merged at revision: | 2751 | ||||||||||||||||||||
Proposed branch: | lp:~vanvugt/mir/16bpp | ||||||||||||||||||||
Merge into: | lp:mir | ||||||||||||||||||||
Diff against target: |
1191 lines (+556/-130) 24 files modified
examples/eglapp.c (+50/-23) examples/image_renderer.cpp (+1/-0) examples/multiwin.c (+73/-21) include/common/mir_toolkit/common.h (+39/-15) playground/demo-shell/typo/typo_glcache.cpp (+1/-0) src/platform/graphics/pixel_format_utils.cpp (+59/-36) src/platforms/android/server/android_buffer_allocator.cpp (+2/-1) src/platforms/android/server/android_format_conversion-inl.h (+6/-2) src/platforms/mesa/server/common/buffer_allocator.cpp (+23/-17) src/platforms/mesa/server/common/buffer_allocator.h (+0/-1) src/platforms/mesa/server/common/gbm_buffer.cpp (+42/-0) src/platforms/mesa/server/common/shm_buffer.cpp (+76/-4) src/platforms/mesa/server/common/shm_buffer.h (+2/-0) src/utils/screencast.cpp (+8/-0) tests/include/mir/test/doubles/mock_gbm.h (+3/-0) tests/include/mir/test/doubles/mock_gl.h (+1/-0) tests/mir_test_doubles/mock_gbm.cpp (+9/-0) tests/mir_test_doubles/mock_gl.cpp (+6/-0) tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp (+11/-1) tests/unit-tests/graphics/android/test_pixel_format.cpp (+6/-3) tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp (+2/-0) tests/unit-tests/graphics/mesa/common/test_shm_buffer.cpp (+110/-6) tests/unit-tests/graphics/test_graphics_platform.cpp (+2/-0) tests/unit-tests/graphics/test_pixel_format_utils.cpp (+24/-0) |
||||||||||||||||||||
To merge this branch: | bzr merge lp:~vanvugt/mir/16bpp | ||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Kevin DuBois (community) | Approve | ||
Robert Carr (community) | Approve | ||
Review via email: mp+264246@code.launchpad.net |
Commit message
Pixel formats! Add some and fix some.
* Added support for common 16-bpp pixel formats (LP: #1469673),
* Added support for software surface (ShmBuffer) compositing in GL
of every single pixel format except bgr_888 (which OpenGL does not
support). (LP: #1424909)
* Fix texture upload alignment that caused corrupt images and/or
crashes with non-32-bit formats.
* Enhance some examples to support the new pixel formats, and also to
allow the user to force a pixel format.
* Detect supported pixel formats more accurately during surface
creation. Sadly not in supported_
* Started on (documented but not enabled) support for big endian.
Future work:
* Move ShmBuffer out of mesa. It should be usable by any driver and
even Android should benefit from using its wider pixel format
support than Android native buffers provide right now.
* Find out why forcing some unsupported pixel formats on mako makes
the phone reboot instead of providing nice errors.
* More big endian support.
* Enhance (or remove) supported_
like intended usage, so that it may give more accurate answers.
* Fix compositing of those "X instead of A" formats (LP: #1423462)
* Automatically relate EGLConfig to desired pixel format in
examples at least.
Tips:
* To test a working rgb_565 EGL surface on mako (LP: #1460149),
try this:
mir_
Fixes: LP: #1469673, LP: #1424909
Related but not yet fully fixed: LP: #1423462, LP: #1460149
Description of the change
The scope of this work has already grown beyond expectations. Please forgive all those TODOs and as yet unresolved future work.
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2798
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2801
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : | # |
Looks good to me.
+TEST_F(
These tests seem like good candidates for parameterization.
gbm_buffer.cpp:
Nice candidate for a static table or something
Kevin DuBois (kdub) wrote : | # |
Alright by me, although two questions:
l301, What was wrong with the current definition of pixel formats?
1076 +#if __BYTE_ORDER == __LITTLE_ENDIAN
We haven't quite solved hardware-dependent testing problem... maybe we should move these and that "HardwareSanity*" test suite that I ported last week to its own binary?
Daniel van Vugt (vanvugt) wrote : | # |
I'm trying to keep the diff size down. So only new code gets lookup tables. Existing switch statements remain.
l301: The old description was incomplete (did not address 16/24-bpp formats) and for 3-byte/24-bpp formats was misleadingly wrong. You can see this in that we've had format "bgr_888" for a long time but it apparently never worked. I've augmented it with new format rgb_888 that actually does work, and verified the right colours appear on screen.
You can't entirely get away from endianess switching if you want pixel formats that are addressable as whole uint32's. Either you use our definition, which allows the client to write pixels endian-
Kevin DuBois (kdub) wrote : | # |
Eh, so I see the problem, and think that the newer definitions are an improvement, so +1 to that.
I also guess that endianness is hardware-specific (in one sense), but pretty well guarded by the debian architecture definitions... all systems have an endianness, but not all systems have display hardware, so on second thought, seems like a slightly different problem. Anyways, lgtm
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'examples/eglapp.c' |
2 | --- examples/eglapp.c 2015-07-01 09:18:10 +0000 |
3 | +++ examples/eglapp.c 2015-07-13 09:10:30 +0000 |
4 | @@ -194,6 +194,7 @@ |
5 | EGLContext eglctx; |
6 | EGLBoolean ok; |
7 | EGLint swapinterval = 1; |
8 | + MirPixelFormat pixel_format = mir_pixel_format_invalid; |
9 | unsigned int output_id = mir_display_output_id_invalid; |
10 | char *mir_socket = NULL; |
11 | char const* cursor_name = mir_default_cursor_name; |
12 | @@ -273,6 +274,23 @@ |
13 | *width = 0; |
14 | *height = 0; |
15 | break; |
16 | + case 'p': |
17 | + { |
18 | + arg += 2; |
19 | + if (!arg[0] && i < argc-1) |
20 | + { |
21 | + ++i; |
22 | + arg = argv[i]; |
23 | + } |
24 | + if (sscanf(arg, "%u", &pixel_format) != 1 || |
25 | + pixel_format == mir_pixel_format_invalid || |
26 | + pixel_format >= mir_pixel_formats) |
27 | + { |
28 | + printf("Invalid pixel format: %s\n", arg); |
29 | + help = 1; |
30 | + } |
31 | + } |
32 | + break; |
33 | case 's': |
34 | { |
35 | unsigned int w, h; |
36 | @@ -325,6 +343,7 @@ |
37 | " -h Show this help text\n" |
38 | " -f Force full screen\n" |
39 | " -o ID Force placement on output monitor ID\n" |
40 | + " -p pixelformat Force a pixel format (integer)\n" |
41 | " -n Don't sync to vblank\n" |
42 | " -m socket Mir server socket\n" |
43 | " -s WIDTHxHEIGHT Force surface size\n" |
44 | @@ -339,6 +358,36 @@ |
45 | connection = mir_connect_sync(mir_socket, appname); |
46 | CHECK(mir_connection_is_valid(connection), "Can't get connection"); |
47 | |
48 | + if (pixel_format == mir_pixel_format_invalid) |
49 | + { |
50 | + unsigned int format[mir_pixel_formats]; |
51 | + unsigned int nformats; |
52 | + |
53 | + mir_connection_get_available_surface_formats(connection, |
54 | + format, mir_pixel_formats, &nformats); |
55 | + |
56 | + pixel_format = format[0]; |
57 | + for (unsigned int f = 0; f < nformats; f++) |
58 | + { |
59 | + const int opaque = (format[f] == mir_pixel_format_xbgr_8888 || |
60 | + format[f] == mir_pixel_format_xrgb_8888 || |
61 | + format[f] == mir_pixel_format_rgb_565 || |
62 | + format[f] == mir_pixel_format_rgb_888 || |
63 | + format[f] == mir_pixel_format_bgr_888); |
64 | + |
65 | + if ((mir_eglapp_background_opacity == 1.0f && opaque) || |
66 | + (mir_eglapp_background_opacity < 1.0f && !opaque)) |
67 | + { |
68 | + pixel_format = format[f]; |
69 | + break; |
70 | + } |
71 | + } |
72 | + |
73 | + printf("Server supports %d of %d surface pixel formats. " |
74 | + "Using format: %d\n", |
75 | + nformats, mir_pixel_formats, pixel_format); |
76 | + } |
77 | + |
78 | /* eglapps are interested in the screen size, so |
79 | use mir_connection_create_display_config */ |
80 | MirDisplayConfiguration* display_config = |
81 | @@ -354,27 +403,6 @@ |
82 | |
83 | const MirDisplayMode *mode = &output->modes[output->current_mode]; |
84 | |
85 | - unsigned int format[mir_pixel_formats]; |
86 | - unsigned int nformats; |
87 | - |
88 | - mir_connection_get_available_surface_formats(connection, |
89 | - format, mir_pixel_formats, &nformats); |
90 | - |
91 | - MirPixelFormat pixel_format = format[0]; |
92 | - for (unsigned int f = 0; f < nformats; f++) |
93 | - { |
94 | - const int opaque = (format[f] == mir_pixel_format_xbgr_8888 || |
95 | - format[f] == mir_pixel_format_xrgb_8888 || |
96 | - format[f] == mir_pixel_format_bgr_888); |
97 | - |
98 | - if ((mir_eglapp_background_opacity == 1.0f && opaque) || |
99 | - (mir_eglapp_background_opacity < 1.0f && !opaque)) |
100 | - { |
101 | - pixel_format = format[f]; |
102 | - break; |
103 | - } |
104 | - } |
105 | - |
106 | printf("Current active output is %dx%d %+d%+d\n", |
107 | mode->horizontal_resolution, mode->vertical_resolution, |
108 | output->position_x, output->position_y); |
109 | @@ -386,13 +414,12 @@ |
110 | |
111 | mir_display_config_destroy(display_config); |
112 | |
113 | - printf("Server supports %d of %d surface pixel formats. Using format: %d\n", |
114 | - nformats, mir_pixel_formats, pixel_format); |
115 | EGLint attribs[] = |
116 | { |
117 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
118 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
119 | EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
120 | + // TODO: Improve this to automatically match pixel_format |
121 | EGL_RED_SIZE, rgb_bits, |
122 | EGL_GREEN_SIZE, rgb_bits, |
123 | EGL_BLUE_SIZE, rgb_bits, |
124 | |
125 | === modified file 'examples/image_renderer.cpp' |
126 | --- examples/image_renderer.cpp 2015-02-22 07:46:25 +0000 |
127 | +++ examples/image_renderer.cpp 2015-07-13 09:10:30 +0000 |
128 | @@ -157,6 +157,7 @@ |
129 | |
130 | GLenum format = (bytes_per_pixel == 3) ? GL_RGB : GL_RGBA; |
131 | |
132 | + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
133 | glTexImage2D(GL_TEXTURE_2D, 0, format, |
134 | size.width.as_uint32_t(), size.height.as_uint32_t(), 0, |
135 | format, GL_UNSIGNED_BYTE, pixel_data); |
136 | |
137 | === modified file 'examples/multiwin.c' |
138 | --- examples/multiwin.c 2015-06-17 05:20:42 +0000 |
139 | +++ examples/multiwin.c 2015-07-13 09:10:30 +0000 |
140 | @@ -69,6 +69,7 @@ |
141 | break; |
142 | case mir_pixel_format_xbgr_8888: |
143 | pixel = |
144 | + /* Not filling in the X byte is correct but buggy (LP: #1423462) */ |
145 | (uint32_t)color->b << 16 | |
146 | (uint32_t)color->g << 8 | |
147 | (uint32_t)color->r; |
148 | @@ -82,10 +83,21 @@ |
149 | break; |
150 | case mir_pixel_format_xrgb_8888: |
151 | pixel = |
152 | + /* Not filling in the X byte is correct but buggy (LP: #1423462) */ |
153 | (uint32_t)color->r << 16 | |
154 | (uint32_t)color->g << 8 | |
155 | (uint32_t)color->b; |
156 | break; |
157 | + case mir_pixel_format_rgb_888: |
158 | + for (n = 0; n < count; n++) |
159 | + { |
160 | + uint8_t *p = (uint8_t*)where + n * 3; |
161 | + p[0] = color->r; |
162 | + p[1] = color->g; |
163 | + p[2] = color->b; |
164 | + } |
165 | + count = 0; |
166 | + break; |
167 | case mir_pixel_format_bgr_888: |
168 | for (n = 0; n < count; n++) |
169 | { |
170 | @@ -96,6 +108,38 @@ |
171 | } |
172 | count = 0; |
173 | break; |
174 | + case mir_pixel_format_rgb_565: |
175 | + for (n = 0; n < count; n++) |
176 | + { |
177 | + uint16_t *p = (uint16_t*)where + n; |
178 | + *p = (uint16_t)(color->r >> 3) << 11 | |
179 | + (uint16_t)(color->g >> 2) << 5 | |
180 | + (uint16_t)(color->b >> 3); |
181 | + } |
182 | + count = 0; |
183 | + break; |
184 | + case mir_pixel_format_rgba_5551: |
185 | + for (n = 0; n < count; n++) |
186 | + { |
187 | + uint16_t *p = (uint16_t*)where + n; |
188 | + *p = (uint16_t)(color->r >> 3) << 11 | |
189 | + (uint16_t)(color->g >> 3) << 6 | |
190 | + (uint16_t)(color->b >> 3) << 1 | |
191 | + (uint16_t)(color->a ? 1 : 0); |
192 | + } |
193 | + count = 0; |
194 | + break; |
195 | + case mir_pixel_format_rgba_4444: |
196 | + for (n = 0; n < count; n++) |
197 | + { |
198 | + uint16_t *p = (uint16_t*)where + n; |
199 | + *p = (uint16_t)(color->r >> 4) << 12 | |
200 | + (uint16_t)(color->g >> 4) << 8 | |
201 | + (uint16_t)(color->b >> 4) << 4 | |
202 | + (uint16_t)(color->a >> 4); |
203 | + } |
204 | + count = 0; |
205 | + break; |
206 | default: |
207 | count = 0; |
208 | break; |
209 | @@ -134,11 +178,12 @@ |
210 | MirConnection *conn; |
211 | Window win[3]; |
212 | unsigned int f; |
213 | + MirPixelFormat pixel_format = mir_pixel_format_invalid; |
214 | int alpha = 0x50; |
215 | |
216 | int arg; |
217 | opterr = 0; |
218 | - while ((arg = getopt (argc, argv, "hm:a:")) != -1) |
219 | + while ((arg = getopt (argc, argv, "hm:a:p:")) != -1) |
220 | { |
221 | switch (arg) |
222 | { |
223 | @@ -146,6 +191,10 @@ |
224 | alpha = atoi(optarg); |
225 | break; |
226 | |
227 | + case 'p': |
228 | + pixel_format = (MirPixelFormat)atoi(optarg); |
229 | + break; |
230 | + |
231 | case 'm': |
232 | socket_file = optarg; |
233 | break; |
234 | @@ -156,8 +205,9 @@ |
235 | puts(argv[0]); |
236 | puts("Usage:"); |
237 | puts(" -m <Mir server socket>"); |
238 | - puts(" -a Alpha for surfaces"); |
239 | - puts(" -h: this help text"); |
240 | + puts(" -a Alpha for surfaces"); |
241 | + puts(" -p <N> Force pixel format N"); |
242 | + puts(" -h This help text"); |
243 | return -1; |
244 | } |
245 | } |
246 | @@ -169,26 +219,28 @@ |
247 | return 1; |
248 | } |
249 | |
250 | - unsigned int const pf_size = 32; |
251 | - MirPixelFormat formats[pf_size]; |
252 | - unsigned int valid_formats; |
253 | - mir_connection_get_available_surface_formats(conn, formats, pf_size, &valid_formats); |
254 | - |
255 | - MirPixelFormat pixel_format = mir_pixel_format_invalid; |
256 | - for (f = 0; f < valid_formats; f++) |
257 | - { |
258 | - if (formats[f] == mir_pixel_format_abgr_8888 || |
259 | - formats[f] == mir_pixel_format_argb_8888) |
260 | - { |
261 | - pixel_format = formats[f]; |
262 | - break; |
263 | - } |
264 | - } |
265 | if (pixel_format == mir_pixel_format_invalid) |
266 | { |
267 | - fprintf(stderr, "Could not find a fast 32-bit pixel format with " |
268 | - "alpha support. Blending won't work!.\n"); |
269 | - pixel_format = formats[0]; |
270 | + MirPixelFormat formats[mir_pixel_formats]; |
271 | + unsigned int valid_formats; |
272 | + mir_connection_get_available_surface_formats(conn, formats, |
273 | + mir_pixel_formats, &valid_formats); |
274 | + |
275 | + for (f = 0; f < valid_formats; f++) |
276 | + { |
277 | + if (formats[f] == mir_pixel_format_abgr_8888 || |
278 | + formats[f] == mir_pixel_format_argb_8888) |
279 | + { |
280 | + pixel_format = formats[f]; |
281 | + break; |
282 | + } |
283 | + } |
284 | + if (pixel_format == mir_pixel_format_invalid) |
285 | + { |
286 | + fprintf(stderr, "Could not find a fast 32-bit pixel format with " |
287 | + "alpha support. Blending won't work!.\n"); |
288 | + pixel_format = formats[0]; |
289 | + } |
290 | } |
291 | |
292 | MirSurfaceSpec *spec = |
293 | |
294 | === modified file 'include/common/mir_toolkit/common.h' |
295 | --- include/common/mir_toolkit/common.h 2015-04-28 07:54:10 +0000 |
296 | +++ include/common/mir_toolkit/common.h 2015-07-13 09:10:30 +0000 |
297 | @@ -114,27 +114,51 @@ |
298 | } MirPromptSessionState; |
299 | |
300 | /** |
301 | - * The order of components in a format enum matches the |
302 | - * order of the components as they would be written in an |
303 | - * integer representing a pixel value of that format. |
304 | - * |
305 | - * For example, abgr_8888 corresponds to 0xAABBGGRR, which will |
306 | - * end up as R,G,B,A in memory in a little endian system, and |
307 | - * as A,B,G,R in memory in a big endian system. |
308 | + * 32-bit pixel formats (8888): |
309 | + * The order of components in the enum matches the order of the components |
310 | + * as they would be written in an integer representing a pixel value of that |
311 | + * format. For example; abgr_8888 should be coded as 0xAABBGGRR, which will |
312 | + * end up as R,G,B,A in memory on a little endian system, and as A,B,G,R on a |
313 | + * big endian system. |
314 | + * |
315 | + * 24-bit pixel formats (888): |
316 | + * These are in literal byte order, regardless of CPU architecture it's always |
317 | + * the same. Writing these 3-byte pixels is typically slower than other formats |
318 | + * but uses less memory than 32-bit and is endian-independent. |
319 | + * |
320 | + * 16-bit pixel formats (565/5551/4444): |
321 | + * Always interpreted as one 16-bit integer per pixel with components in |
322 | + * high-to-low bit order following the format name. These are the fastest |
323 | + * formats, however colour quality is visibly lower. |
324 | */ |
325 | typedef enum MirPixelFormat |
326 | { |
327 | - mir_pixel_format_invalid, |
328 | - mir_pixel_format_abgr_8888, |
329 | - mir_pixel_format_xbgr_8888, |
330 | - mir_pixel_format_argb_8888, |
331 | - mir_pixel_format_xrgb_8888, |
332 | - mir_pixel_format_bgr_888, |
333 | - mir_pixel_formats |
334 | + mir_pixel_format_invalid = 0, |
335 | + mir_pixel_format_abgr_8888 = 1, |
336 | + mir_pixel_format_xbgr_8888 = 2, |
337 | + mir_pixel_format_argb_8888 = 3, |
338 | + mir_pixel_format_xrgb_8888 = 4, |
339 | + mir_pixel_format_bgr_888 = 5, |
340 | + mir_pixel_format_rgb_888 = 6, |
341 | + mir_pixel_format_rgb_565 = 7, |
342 | + mir_pixel_format_rgba_5551 = 8, |
343 | + mir_pixel_format_rgba_4444 = 9, |
344 | + /* |
345 | + * TODO: Big endian support would require additional formats in order to |
346 | + * composite software surfaces using OpenGL (GL_RGBA/GL_BGRA_EXT): |
347 | + * mir_pixel_format_rgb[ax]_8888 |
348 | + * mir_pixel_format_bgr[ax]_8888 |
349 | + */ |
350 | + mir_pixel_formats /* Note: This is always max format + 1 */ |
351 | } MirPixelFormat; |
352 | |
353 | /* This could be improved... https://bugs.launchpad.net/mir/+bug/1236254 */ |
354 | -#define MIR_BYTES_PER_PIXEL(f) (((f) == mir_pixel_format_bgr_888) ? 3 : 4) |
355 | +#define MIR_BYTES_PER_PIXEL(f) ((f) == mir_pixel_format_bgr_888 ? 3 : \ |
356 | + (f) == mir_pixel_format_rgb_888 ? 3 : \ |
357 | + (f) == mir_pixel_format_rgb_565 ? 2 : \ |
358 | + (f) == mir_pixel_format_rgba_5551 ? 2 : \ |
359 | + (f) == mir_pixel_format_rgba_4444 ? 2 : \ |
360 | + 4) |
361 | |
362 | /** Direction relative to the "natural" orientation of the display */ |
363 | typedef enum MirOrientation |
364 | |
365 | === modified file 'playground/demo-shell/typo/typo_glcache.cpp' |
366 | --- playground/demo-shell/typo/typo_glcache.cpp 2015-02-19 09:30:02 +0000 |
367 | +++ playground/demo-shell/typo/typo_glcache.cpp 2015-07-13 09:10:30 +0000 |
368 | @@ -87,6 +87,7 @@ |
369 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
370 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
371 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
372 | + glPixelStorei(GL_UNPACK_ALIGNMENT, img.align); |
373 | glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, |
374 | img.width, img.height, 0, GL_ALPHA, |
375 | GL_UNSIGNED_BYTE, img.buf); |
376 | |
377 | === modified file 'src/platform/graphics/pixel_format_utils.cpp' |
378 | --- src/platform/graphics/pixel_format_utils.cpp 2014-01-08 16:07:36 +0000 |
379 | +++ src/platform/graphics/pixel_format_utils.cpp 2015-07-13 09:10:30 +0000 |
380 | @@ -1,5 +1,5 @@ |
381 | /* |
382 | - * Copyright © 2014 Canonical Ltd. |
383 | + * Copyright © 2015 Canonical Ltd. |
384 | * |
385 | * This program is free software: you can redistribute it and/or modify it |
386 | * under the terms of the GNU Lesser General Public License version 3, |
387 | @@ -13,42 +13,65 @@ |
388 | * You should have received a copy of the GNU Lesser General Public License |
389 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
390 | * |
391 | - * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
392 | + * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com> |
393 | */ |
394 | |
395 | #include "mir/graphics/pixel_format_utils.h" |
396 | |
397 | -namespace mg = mir::graphics; |
398 | - |
399 | -bool mg::contains_alpha(MirPixelFormat format) |
400 | -{ |
401 | - return (format == mir_pixel_format_abgr_8888 || |
402 | - format == mir_pixel_format_argb_8888); |
403 | -} |
404 | - |
405 | -bool mg::valid_pixel_format(MirPixelFormat format) |
406 | -{ |
407 | - return (format > mir_pixel_format_invalid && |
408 | - format < mir_pixel_formats); |
409 | -} |
410 | - |
411 | -int mg::red_channel_depth(MirPixelFormat format) |
412 | -{ |
413 | - return valid_pixel_format(format) ? 8 : 0; |
414 | -} |
415 | - |
416 | -int mg::blue_channel_depth(MirPixelFormat format) |
417 | -{ |
418 | - return valid_pixel_format(format) ? 8 : 0; |
419 | -} |
420 | - |
421 | -int mg::green_channel_depth(MirPixelFormat format) |
422 | -{ |
423 | - return valid_pixel_format(format) ? 8 : 0; |
424 | -} |
425 | - |
426 | -int mg::alpha_channel_depth(MirPixelFormat format) |
427 | -{ |
428 | - return contains_alpha(format) ? 8 : 0; |
429 | -} |
430 | - |
431 | +namespace { |
432 | + |
433 | +const struct |
434 | +{ |
435 | + MirPixelFormat mir_format; |
436 | + int red_bits, green_bits, blue_bits, alpha_bits; |
437 | +} detail[mir_pixel_formats] = |
438 | +{ |
439 | + {mir_pixel_format_invalid, 0,0,0,0}, |
440 | + {mir_pixel_format_abgr_8888, 8,8,8,8}, |
441 | + {mir_pixel_format_xbgr_8888, 8,8,8,0}, |
442 | + {mir_pixel_format_argb_8888, 8,8,8,8}, |
443 | + {mir_pixel_format_xrgb_8888, 8,8,8,0}, |
444 | + {mir_pixel_format_bgr_888, 8,8,8,0}, |
445 | + {mir_pixel_format_rgb_888, 8,8,8,0}, |
446 | + {mir_pixel_format_rgb_565, 5,6,5,0}, |
447 | + {mir_pixel_format_rgba_5551, 5,5,5,1}, |
448 | + {mir_pixel_format_rgba_4444, 4,4,4,4}, |
449 | +}; |
450 | + |
451 | +} // anonymous namespace |
452 | + |
453 | +namespace mir { namespace graphics { |
454 | + |
455 | +bool valid_pixel_format(MirPixelFormat f) |
456 | +{ |
457 | + return f > mir_pixel_format_invalid && |
458 | + f < mir_pixel_formats && |
459 | + detail[f].mir_format == f; |
460 | +} |
461 | + |
462 | +int red_channel_depth(MirPixelFormat f) |
463 | +{ |
464 | + return valid_pixel_format(f) ? detail[f].red_bits : 0; |
465 | +} |
466 | + |
467 | +int green_channel_depth(MirPixelFormat f) |
468 | +{ |
469 | + return valid_pixel_format(f) ? detail[f].green_bits : 0; |
470 | +} |
471 | + |
472 | +int blue_channel_depth(MirPixelFormat f) |
473 | +{ |
474 | + return valid_pixel_format(f) ? detail[f].blue_bits : 0; |
475 | +} |
476 | + |
477 | +int alpha_channel_depth(MirPixelFormat f) |
478 | +{ |
479 | + return valid_pixel_format(f) ? detail[f].alpha_bits : 0; |
480 | +} |
481 | + |
482 | +bool contains_alpha(MirPixelFormat format) |
483 | +{ |
484 | + return alpha_channel_depth(format); |
485 | +} |
486 | + |
487 | +} } // namespace mir::graphics |
488 | |
489 | === modified file 'src/platforms/android/server/android_buffer_allocator.cpp' |
490 | --- src/platforms/android/server/android_buffer_allocator.cpp 2015-06-17 05:20:42 +0000 |
491 | +++ src/platforms/android/server/android_buffer_allocator.cpp 2015-07-13 09:10:30 +0000 |
492 | @@ -107,7 +107,8 @@ |
493 | static std::vector<MirPixelFormat> const pixel_formats{ |
494 | mir_pixel_format_abgr_8888, |
495 | mir_pixel_format_xbgr_8888, |
496 | - mir_pixel_format_bgr_888 |
497 | + mir_pixel_format_rgb_888, |
498 | + mir_pixel_format_rgb_565 |
499 | }; |
500 | |
501 | return pixel_formats; |
502 | |
503 | === modified file 'src/platforms/android/server/android_format_conversion-inl.h' |
504 | --- src/platforms/android/server/android_format_conversion-inl.h 2015-02-22 07:46:25 +0000 |
505 | +++ src/platforms/android/server/android_format_conversion-inl.h 2015-07-13 09:10:30 +0000 |
506 | @@ -41,8 +41,10 @@ |
507 | return HAL_PIXEL_FORMAT_BGRA_8888; |
508 | case mir_pixel_format_xrgb_8888: |
509 | return HAL_PIXEL_FORMAT_BGRA_8888; |
510 | - case mir_pixel_format_bgr_888: |
511 | + case mir_pixel_format_rgb_888: |
512 | return HAL_PIXEL_FORMAT_RGB_888; |
513 | + case mir_pixel_format_rgb_565: |
514 | + return HAL_PIXEL_FORMAT_RGB_565; |
515 | default: |
516 | return 0; |
517 | } |
518 | @@ -59,7 +61,9 @@ |
519 | case HAL_PIXEL_FORMAT_BGRA_8888: |
520 | return mir_pixel_format_argb_8888; |
521 | case HAL_PIXEL_FORMAT_RGB_888: |
522 | - return mir_pixel_format_bgr_888; |
523 | + return mir_pixel_format_rgb_888; |
524 | + case HAL_PIXEL_FORMAT_RGB_565: |
525 | + return mir_pixel_format_rgb_565; |
526 | default: |
527 | return mir_pixel_format_invalid; |
528 | } |
529 | |
530 | === modified file 'src/platforms/mesa/server/common/buffer_allocator.cpp' |
531 | --- src/platforms/mesa/server/common/buffer_allocator.cpp 2015-06-17 05:20:42 +0000 |
532 | +++ src/platforms/mesa/server/common/buffer_allocator.cpp 2015-07-13 09:10:30 +0000 |
533 | @@ -138,13 +138,6 @@ |
534 | |
535 | uint32_t const gbm_format = mgm::mir_format_to_gbm_format(buffer_properties.format); |
536 | |
537 | - if (!is_pixel_format_supported(buffer_properties.format) || |
538 | - gbm_format == mgm::invalid_gbm_format) |
539 | - { |
540 | - BOOST_THROW_EXCEPTION( |
541 | - std::runtime_error("Trying to create GBM buffer with unsupported pixel format")); |
542 | - } |
543 | - |
544 | /* |
545 | * Bypass is generally only beneficial to hardware buffers where the |
546 | * blitting happens on the GPU. For software buffers it is slower to blit |
547 | @@ -164,6 +157,12 @@ |
548 | bo_flags |= GBM_BO_USE_SCANOUT; |
549 | } |
550 | |
551 | + if (!gbm_device_is_format_supported(device, gbm_format, bo_flags)) |
552 | + { |
553 | + BOOST_THROW_EXCEPTION( |
554 | + std::runtime_error("Trying to create GBM buffer with unsupported pixel format")); |
555 | + } |
556 | + |
557 | gbm_bo *bo_raw = gbm_bo_create( |
558 | device, |
559 | buffer_properties.size.width.as_uint32_t(), |
560 | @@ -189,7 +188,7 @@ |
561 | std::shared_ptr<mg::Buffer> mgm::BufferAllocator::alloc_software_buffer( |
562 | BufferProperties const& buffer_properties) |
563 | { |
564 | - if (!is_pixel_format_supported(buffer_properties.format)) |
565 | + if (!ShmBuffer::supports(buffer_properties.format)) |
566 | { |
567 | BOOST_THROW_EXCEPTION( |
568 | std::runtime_error( |
569 | @@ -213,6 +212,22 @@ |
570 | |
571 | std::vector<MirPixelFormat> mgm::BufferAllocator::supported_pixel_formats() |
572 | { |
573 | + /* |
574 | + * supported_pixel_formats() is kind of a kludge. The right answer depends |
575 | + * on whether you're using hardware or software, and it depends on |
576 | + * the usage type (e.g. scanout). In the future it's also expected to |
577 | + * depend on the GPU model in use at runtime. |
578 | + * To be precise, ShmBuffer now supports OpenGL compositing of all |
579 | + * but one MirPixelFormat (bgr_888). But GBM only supports [AX]RGB. |
580 | + * So since we don't yet have an adequate API in place to query what the |
581 | + * intended usage will be, we need to be conservative and report the |
582 | + * intersection of ShmBuffer and GBM's pixel format support. That is |
583 | + * just these two. Be aware however you can create a software surface |
584 | + * with almost any pixel format and it will also work... |
585 | + * TODO: Convert this to a loop that just queries the intersection of |
586 | + * gbm_device_is_format_supported and ShmBuffer::supports(), however not |
587 | + * yet while the former is buggy. (FIXME: LP: #1473901) |
588 | + */ |
589 | static std::vector<MirPixelFormat> const pixel_formats{ |
590 | mir_pixel_format_argb_8888, |
591 | mir_pixel_format_xrgb_8888 |
592 | @@ -221,15 +236,6 @@ |
593 | return pixel_formats; |
594 | } |
595 | |
596 | -bool mgm::BufferAllocator::is_pixel_format_supported(MirPixelFormat format) |
597 | -{ |
598 | - auto formats = supported_pixel_formats(); |
599 | - |
600 | - auto iter = std::find(formats.begin(), formats.end(), format); |
601 | - |
602 | - return iter != formats.end(); |
603 | -} |
604 | - |
605 | std::unique_ptr<mg::Buffer> mgm::BufferAllocator::reconstruct_from( |
606 | MirBufferPackage* package, |
607 | MirPixelFormat format) |
608 | |
609 | === modified file 'src/platforms/mesa/server/common/buffer_allocator.h' |
610 | --- src/platforms/mesa/server/common/buffer_allocator.h 2015-06-17 05:20:42 +0000 |
611 | +++ src/platforms/mesa/server/common/buffer_allocator.h 2015-07-13 09:10:30 +0000 |
612 | @@ -51,7 +51,6 @@ |
613 | std::vector<MirPixelFormat> supported_pixel_formats(); |
614 | |
615 | private: |
616 | - bool is_pixel_format_supported(MirPixelFormat format); |
617 | std::shared_ptr<Buffer> alloc_hardware_buffer( |
618 | graphics::BufferProperties const& buffer_properties); |
619 | std::shared_ptr<Buffer> alloc_software_buffer( |
620 | |
621 | === modified file 'src/platforms/mesa/server/common/gbm_buffer.cpp' |
622 | --- src/platforms/mesa/server/common/gbm_buffer.cpp 2015-06-17 05:20:42 +0000 |
623 | +++ src/platforms/mesa/server/common/gbm_buffer.cpp 2015-07-13 09:10:30 +0000 |
624 | @@ -46,6 +46,27 @@ |
625 | case GBM_FORMAT_XRGB8888: |
626 | pf = mir_pixel_format_xrgb_8888; |
627 | break; |
628 | + case GBM_FORMAT_ABGR8888: |
629 | + pf = mir_pixel_format_abgr_8888; |
630 | + break; |
631 | + case GBM_FORMAT_XBGR8888: |
632 | + pf = mir_pixel_format_xbgr_8888; |
633 | + break; |
634 | + case GBM_FORMAT_BGR888: |
635 | + pf = mir_pixel_format_bgr_888; |
636 | + break; |
637 | + case GBM_FORMAT_RGB888: |
638 | + pf = mir_pixel_format_rgb_888; |
639 | + break; |
640 | + case GBM_FORMAT_RGB565: |
641 | + pf = mir_pixel_format_rgb_565; |
642 | + break; |
643 | + case GBM_FORMAT_RGBA5551: |
644 | + pf = mir_pixel_format_rgba_5551; |
645 | + break; |
646 | + case GBM_FORMAT_RGBA4444: |
647 | + pf = mir_pixel_format_rgba_4444; |
648 | + break; |
649 | default: |
650 | pf = mir_pixel_format_invalid; |
651 | break; |
652 | @@ -66,6 +87,27 @@ |
653 | case mir_pixel_format_xrgb_8888: |
654 | gbm_pf = GBM_FORMAT_XRGB8888; |
655 | break; |
656 | + case mir_pixel_format_abgr_8888: |
657 | + gbm_pf = GBM_FORMAT_ABGR8888; |
658 | + break; |
659 | + case mir_pixel_format_xbgr_8888: |
660 | + gbm_pf = GBM_FORMAT_XBGR8888; |
661 | + break; |
662 | + case mir_pixel_format_bgr_888: |
663 | + gbm_pf = GBM_FORMAT_BGR888; |
664 | + break; |
665 | + case mir_pixel_format_rgb_888: |
666 | + gbm_pf = GBM_FORMAT_RGB888; |
667 | + break; |
668 | + case mir_pixel_format_rgb_565: |
669 | + gbm_pf = GBM_FORMAT_RGB565; |
670 | + break; |
671 | + case mir_pixel_format_rgba_5551: |
672 | + gbm_pf = GBM_FORMAT_RGBA5551; |
673 | + break; |
674 | + case mir_pixel_format_rgba_4444: |
675 | + gbm_pf = GBM_FORMAT_RGBA4444; |
676 | + break; |
677 | default: |
678 | gbm_pf = mgm::invalid_gbm_format; |
679 | break; |
680 | |
681 | === modified file 'src/platforms/mesa/server/common/shm_buffer.cpp' |
682 | --- src/platforms/mesa/server/common/shm_buffer.cpp 2015-06-17 05:20:42 +0000 |
683 | +++ src/platforms/mesa/server/common/shm_buffer.cpp 2015-07-13 09:10:30 +0000 |
684 | @@ -28,10 +28,69 @@ |
685 | #include <stdexcept> |
686 | |
687 | #include <string.h> |
688 | +#include <endian.h> |
689 | |
690 | namespace mgm = mir::graphics::mesa; |
691 | namespace geom = mir::geometry; |
692 | |
693 | +namespace { |
694 | + |
695 | +bool get_gl_pixel_format(MirPixelFormat mir_format, |
696 | + GLenum& gl_format, GLenum& gl_type) |
697 | +{ |
698 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
699 | + GLenum const argb = GL_BGRA_EXT; |
700 | + GLenum const abgr = GL_RGBA; |
701 | +#elif __BYTE_ORDER == __BIG_ENDIAN |
702 | + // TODO: Big endian support |
703 | + GLenum const argb = GL_INVALID_ENUM; |
704 | + GLenum const abgr = GL_INVALID_ENUM; |
705 | + GLenum const rgba = GL_RGBA; |
706 | + GLenum const bgra = GL_BGRA_EXT; |
707 | +#endif |
708 | + |
709 | + static const struct |
710 | + { |
711 | + MirPixelFormat mir_format; |
712 | + GLenum gl_format, gl_type; |
713 | + } mapping[mir_pixel_formats] = |
714 | + { |
715 | + {mir_pixel_format_invalid, GL_INVALID_ENUM, GL_INVALID_ENUM}, |
716 | + {mir_pixel_format_abgr_8888, abgr, GL_UNSIGNED_BYTE}, |
717 | + {mir_pixel_format_xbgr_8888, abgr, GL_UNSIGNED_BYTE}, |
718 | + {mir_pixel_format_argb_8888, argb, GL_UNSIGNED_BYTE}, |
719 | + {mir_pixel_format_xrgb_8888, argb, GL_UNSIGNED_BYTE}, |
720 | + {mir_pixel_format_bgr_888, GL_INVALID_ENUM, GL_INVALID_ENUM}, |
721 | + {mir_pixel_format_rgb_888, GL_RGB, GL_UNSIGNED_BYTE}, |
722 | + {mir_pixel_format_rgb_565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, |
723 | + {mir_pixel_format_rgba_5551, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, |
724 | + {mir_pixel_format_rgba_4444, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, |
725 | + }; |
726 | + |
727 | + if (mir_format > mir_pixel_format_invalid && |
728 | + mir_format < mir_pixel_formats && |
729 | + mapping[mir_format].mir_format == mir_format) // just a sanity check |
730 | + { |
731 | + gl_format = mapping[mir_format].gl_format; |
732 | + gl_type = mapping[mir_format].gl_type; |
733 | + } |
734 | + else |
735 | + { |
736 | + gl_format = GL_INVALID_ENUM; |
737 | + gl_type = GL_INVALID_ENUM; |
738 | + } |
739 | + |
740 | + return gl_format != GL_INVALID_ENUM && gl_type != GL_INVALID_ENUM; |
741 | +} |
742 | + |
743 | +} // anonymous namespace |
744 | + |
745 | +bool mgm::ShmBuffer::supports(MirPixelFormat mir_format) |
746 | +{ |
747 | + GLenum gl_format, gl_type; |
748 | + return get_gl_pixel_format(mir_format, gl_format, gl_type); |
749 | +} |
750 | + |
751 | mgm::ShmBuffer::ShmBuffer( |
752 | std::shared_ptr<ShmFile> const& shm_file, |
753 | geom::Size const& size, |
754 | @@ -65,10 +124,23 @@ |
755 | |
756 | void mgm::ShmBuffer::gl_bind_to_texture() |
757 | { |
758 | - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, |
759 | - size_.width.as_int(), size_.height.as_int(), |
760 | - 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, |
761 | - pixels); |
762 | + GLenum format, type; |
763 | + |
764 | + if (get_gl_pixel_format(pixel_format_, format, type)) |
765 | + { |
766 | + /* |
767 | + * All existing Mir logic assumes that strides are whole multiples of |
768 | + * pixels. And OpenGL defaults to expecting strides are multiples of |
769 | + * 4 bytes. These assumptions used to be compatible when we only had |
770 | + * 4-byte pixels but now we support 2/3-byte pixels we need to be more |
771 | + * careful... |
772 | + */ |
773 | + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
774 | + |
775 | + glTexImage2D(GL_TEXTURE_2D, 0, format, |
776 | + size_.width.as_int(), size_.height.as_int(), |
777 | + 0, format, type, pixels); |
778 | + } |
779 | } |
780 | |
781 | std::shared_ptr<MirNativeBuffer> mgm::ShmBuffer::native_buffer_handle() const |
782 | |
783 | === modified file 'src/platforms/mesa/server/common/shm_buffer.h' |
784 | --- src/platforms/mesa/server/common/shm_buffer.h 2015-06-17 05:20:42 +0000 |
785 | +++ src/platforms/mesa/server/common/shm_buffer.h 2015-07-13 09:10:30 +0000 |
786 | @@ -37,6 +37,8 @@ |
787 | class ShmBuffer : public BufferBasic |
788 | { |
789 | public: |
790 | + static bool supports(MirPixelFormat); |
791 | + |
792 | ShmBuffer(std::shared_ptr<ShmFile> const& shm_file, |
793 | geometry::Size const& size, |
794 | MirPixelFormat const& pixel_format); |
795 | |
796 | === modified file 'src/utils/screencast.cpp' |
797 | --- src/utils/screencast.cpp 2015-06-17 05:20:42 +0000 |
798 | +++ src/utils/screencast.cpp 2015-07-13 09:10:30 +0000 |
799 | @@ -190,7 +190,15 @@ |
800 | case mir_pixel_format_xrgb_8888: |
801 | return "BGRX"; |
802 | case mir_pixel_format_bgr_888: |
803 | + return "BGR"; |
804 | + case mir_pixel_format_rgb_888: |
805 | return "RGB"; |
806 | + case mir_pixel_format_rgb_565: |
807 | + return "RGB565"; |
808 | + case mir_pixel_format_rgba_5551: |
809 | + return "RGBA5551"; |
810 | + case mir_pixel_format_rgba_4444: |
811 | + return "RGBA4444"; |
812 | default: |
813 | throw std::logic_error("Invalid pixel format"); |
814 | } |
815 | |
816 | === modified file 'tests/include/mir/test/doubles/mock_gbm.h' |
817 | --- tests/include/mir/test/doubles/mock_gbm.h 2015-06-17 05:20:42 +0000 |
818 | +++ tests/include/mir/test/doubles/mock_gbm.h 2015-07-13 09:10:30 +0000 |
819 | @@ -54,6 +54,9 @@ |
820 | MOCK_METHOD1(gbm_create_device, struct gbm_device*(int fd)); |
821 | MOCK_METHOD1(gbm_device_destroy, void(struct gbm_device *gbm)); |
822 | MOCK_METHOD1(gbm_device_get_fd, int(struct gbm_device *gbm)); |
823 | + MOCK_METHOD3(gbm_device_is_format_supported, int(struct gbm_device *gbm, |
824 | + uint32_t format, |
825 | + uint32_t usage)); |
826 | |
827 | MOCK_METHOD5(gbm_surface_create, struct gbm_surface*(struct gbm_device *gbm, |
828 | uint32_t width, uint32_t height, |
829 | |
830 | === modified file 'tests/include/mir/test/doubles/mock_gl.h' |
831 | --- tests/include/mir/test/doubles/mock_gl.h 2015-02-22 07:46:25 +0000 |
832 | +++ tests/include/mir/test/doubles/mock_gl.h 2015-07-13 09:10:30 +0000 |
833 | @@ -85,6 +85,7 @@ |
834 | MOCK_METHOD1(glGetString, const GLubyte*(GLenum)); |
835 | MOCK_METHOD2(glGetUniformLocation, GLint(GLuint, const GLchar *)); |
836 | MOCK_METHOD1(glLinkProgram, void(GLuint)); |
837 | + MOCK_METHOD2(glPixelStorei, void(GLenum, GLint)); |
838 | MOCK_METHOD7(glReadPixels, |
839 | void(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, |
840 | GLvoid*)); |
841 | |
842 | === modified file 'tests/mir_test_doubles/mock_gbm.cpp' |
843 | --- tests/mir_test_doubles/mock_gbm.cpp 2015-06-25 03:00:08 +0000 |
844 | +++ tests/mir_test_doubles/mock_gbm.cpp 2015-07-13 09:10:30 +0000 |
845 | @@ -45,6 +45,9 @@ |
846 | ON_CALL(*this, gbm_create_device(_)) |
847 | .WillByDefault(Return(fake_gbm.device)); |
848 | |
849 | + ON_CALL(*this, gbm_device_is_format_supported(_,_,_)) |
850 | + .WillByDefault(Return(1)); |
851 | + |
852 | ON_CALL(*this, gbm_surface_create(fake_gbm.device,_,_,_,_)) |
853 | .WillByDefault(Return(fake_gbm.surface)); |
854 | |
855 | @@ -89,6 +92,12 @@ |
856 | return global_mock->gbm_device_get_fd(gbm); |
857 | } |
858 | |
859 | +int gbm_device_is_format_supported(struct gbm_device *gbm, |
860 | + uint32_t format, uint32_t usage) |
861 | +{ |
862 | + return global_mock->gbm_device_is_format_supported(gbm, format, usage); |
863 | +} |
864 | + |
865 | struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, |
866 | uint32_t width, uint32_t height, |
867 | uint32_t format, uint32_t flags) |
868 | |
869 | === modified file 'tests/mir_test_doubles/mock_gl.cpp' |
870 | --- tests/mir_test_doubles/mock_gl.cpp 2015-06-25 03:00:08 +0000 |
871 | +++ tests/mir_test_doubles/mock_gl.cpp 2015-07-13 09:10:30 +0000 |
872 | @@ -442,3 +442,9 @@ |
873 | CHECK_GLOBAL_VOID_MOCK(); |
874 | global_mock_gl->glGenerateMipmap(target); |
875 | } |
876 | + |
877 | +void glPixelStorei(GLenum pname, GLint param) |
878 | +{ |
879 | + CHECK_GLOBAL_VOID_MOCK(); |
880 | + global_mock_gl->glPixelStorei(pname, param); |
881 | +} |
882 | |
883 | === modified file 'tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp' |
884 | --- tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp 2015-06-25 03:00:08 +0000 |
885 | +++ tests/unit-tests/graphics/android/test_android_buffer_allocator.cpp 2015-07-13 09:10:30 +0000 |
886 | @@ -73,9 +73,19 @@ |
887 | supported_pixel_formats.end(), |
888 | mir_pixel_format_bgr_888); |
889 | |
890 | + auto rgb_888_count = std::count(supported_pixel_formats.begin(), |
891 | + supported_pixel_formats.end(), |
892 | + mir_pixel_format_rgb_888); |
893 | + |
894 | + auto rgb_565_count = std::count(supported_pixel_formats.begin(), |
895 | + supported_pixel_formats.end(), |
896 | + mir_pixel_format_rgb_565); |
897 | + |
898 | EXPECT_EQ(1, abgr_8888_count); |
899 | EXPECT_EQ(1, xbgr_8888_count); |
900 | - EXPECT_EQ(1, bgr_888_count); |
901 | + EXPECT_EQ(0, bgr_888_count); |
902 | + EXPECT_EQ(1, rgb_888_count); |
903 | + EXPECT_EQ(1, rgb_565_count); |
904 | } |
905 | |
906 | TEST_F(AndroidGraphicBufferAllocatorTest, supported_pixel_formats_have_sane_default_in_first_position) |
907 | |
908 | === modified file 'tests/unit-tests/graphics/android/test_pixel_format.cpp' |
909 | --- tests/unit-tests/graphics/android/test_pixel_format.cpp 2015-02-22 07:46:25 +0000 |
910 | +++ tests/unit-tests/graphics/android/test_pixel_format.cpp 2015-07-13 09:10:30 +0000 |
911 | @@ -27,9 +27,11 @@ |
912 | EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mga::to_android_format(mir_pixel_format_abgr_8888)); |
913 | EXPECT_EQ(HAL_PIXEL_FORMAT_RGBX_8888, mga::to_android_format(mir_pixel_format_xbgr_8888)); |
914 | EXPECT_EQ(HAL_PIXEL_FORMAT_BGRA_8888, mga::to_android_format(mir_pixel_format_argb_8888)); |
915 | - //note X to A conversion! |
916 | + // Note X to A conversion! We resolve this during compositing. |
917 | EXPECT_EQ(HAL_PIXEL_FORMAT_BGRA_8888, mga::to_android_format(mir_pixel_format_xrgb_8888)); |
918 | - EXPECT_EQ(HAL_PIXEL_FORMAT_RGB_888, mga::to_android_format(mir_pixel_format_bgr_888)); |
919 | + EXPECT_EQ(HAL_PIXEL_FORMAT_RGB_888, mga::to_android_format(mir_pixel_format_rgb_888)); |
920 | + EXPECT_EQ(0, mga::to_android_format(mir_pixel_format_bgr_888)); |
921 | + EXPECT_EQ(HAL_PIXEL_FORMAT_RGB_565, mga::to_android_format(mir_pixel_format_rgb_565)); |
922 | } |
923 | |
924 | TEST(PixelFormatConversion, conversion_to_mir_test) |
925 | @@ -37,5 +39,6 @@ |
926 | EXPECT_EQ(mir_pixel_format_abgr_8888, mga::to_mir_format(HAL_PIXEL_FORMAT_RGBA_8888)); |
927 | EXPECT_EQ(mir_pixel_format_xbgr_8888, mga::to_mir_format(HAL_PIXEL_FORMAT_RGBX_8888)); |
928 | EXPECT_EQ(mir_pixel_format_argb_8888, mga::to_mir_format(HAL_PIXEL_FORMAT_BGRA_8888)); |
929 | - EXPECT_EQ(mir_pixel_format_bgr_888, mga::to_mir_format(HAL_PIXEL_FORMAT_RGB_888)); |
930 | + EXPECT_EQ(mir_pixel_format_rgb_888, mga::to_mir_format(HAL_PIXEL_FORMAT_RGB_888)); |
931 | + EXPECT_EQ(mir_pixel_format_rgb_565, mga::to_mir_format(HAL_PIXEL_FORMAT_RGB_565)); |
932 | } |
933 | |
934 | === modified file 'tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp' |
935 | --- tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp 2015-06-26 08:00:59 +0000 |
936 | +++ tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp 2015-07-13 09:10:30 +0000 |
937 | @@ -277,6 +277,8 @@ |
938 | |
939 | /* We shouldn't try to create a buffer with an unsupported format */ |
940 | EXPECT_CALL(mock_gbm, gbm_bo_create(_,_,_,_,_)).Times(0); |
941 | + EXPECT_CALL(mock_gbm, gbm_device_is_format_supported(_,_,_)) |
942 | + .WillOnce(Return(0)); |
943 | |
944 | EXPECT_THROW({ |
945 | allocator->alloc_buffer(mg::BufferProperties{size, mir_pixel_format_abgr_8888, usage}); |
946 | |
947 | === modified file 'tests/unit-tests/graphics/mesa/common/test_shm_buffer.cpp' |
948 | --- tests/unit-tests/graphics/mesa/common/test_shm_buffer.cpp 2015-06-26 08:00:59 +0000 |
949 | +++ tests/unit-tests/graphics/mesa/common/test_shm_buffer.cpp 2015-07-13 09:10:30 +0000 |
950 | @@ -23,11 +23,14 @@ |
951 | |
952 | #include <gtest/gtest.h> |
953 | #include <gmock/gmock.h> |
954 | +#include <GLES2/gl2ext.h> |
955 | +#include <endian.h> |
956 | |
957 | namespace mg = mir::graphics; |
958 | namespace mgm = mir::graphics::mesa; |
959 | namespace mtd = mir::test::doubles; |
960 | namespace geom = mir::geometry; |
961 | +using namespace testing; |
962 | |
963 | namespace |
964 | { |
965 | @@ -90,12 +93,113 @@ |
966 | EXPECT_FALSE(shm_buffer.native_buffer_handle()->flags & mir_buffer_flag_can_scanout); |
967 | } |
968 | |
969 | -TEST_F(ShmBufferTest, uploads_pixels_to_texture) |
970 | +TEST_F(ShmBufferTest, cant_upload_bgr_888) |
971 | { |
972 | - using namespace testing; |
973 | - |
974 | EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, _, |
975 | - size.width.as_int(), size.height.as_int(), |
976 | - 0, _, _, stub_shm_file->fake_mapping)); |
977 | - shm_buffer.gl_bind_to_texture(); |
978 | + size.width.as_int(), size.height.as_int(), |
979 | + 0, _, _, |
980 | + stub_shm_file->fake_mapping)) |
981 | + .Times(0); |
982 | + |
983 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_bgr_888); |
984 | + buf.gl_bind_to_texture(); |
985 | +} |
986 | + |
987 | +TEST_F(ShmBufferTest, uploads_rgb_888_correctly) |
988 | +{ |
989 | + EXPECT_CALL(mock_gl, glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); |
990 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, |
991 | + size.width.as_int(), size.height.as_int(), |
992 | + 0, GL_RGB, GL_UNSIGNED_BYTE, |
993 | + stub_shm_file->fake_mapping)); |
994 | + |
995 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_rgb_888); |
996 | + buf.gl_bind_to_texture(); |
997 | +} |
998 | + |
999 | +TEST_F(ShmBufferTest, uploads_rgb_565_correctly) |
1000 | +{ |
1001 | + EXPECT_CALL(mock_gl, glPixelStorei(GL_UNPACK_ALIGNMENT, |
1002 | + AnyOf(Eq(1),Eq(2)))); |
1003 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, |
1004 | + size.width.as_int(), size.height.as_int(), |
1005 | + 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, |
1006 | + stub_shm_file->fake_mapping)); |
1007 | + |
1008 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_rgb_565); |
1009 | + buf.gl_bind_to_texture(); |
1010 | +} |
1011 | + |
1012 | +TEST_F(ShmBufferTest, uploads_rgba_5551_correctly) |
1013 | +{ |
1014 | + EXPECT_CALL(mock_gl, glPixelStorei(GL_UNPACK_ALIGNMENT, |
1015 | + AnyOf(Eq(1),Eq(2)))); |
1016 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
1017 | + size.width.as_int(), size.height.as_int(), |
1018 | + 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, |
1019 | + stub_shm_file->fake_mapping)); |
1020 | + |
1021 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_rgba_5551); |
1022 | + buf.gl_bind_to_texture(); |
1023 | +} |
1024 | + |
1025 | +TEST_F(ShmBufferTest, uploads_rgba_4444_correctly) |
1026 | +{ |
1027 | + EXPECT_CALL(mock_gl, glPixelStorei(GL_UNPACK_ALIGNMENT, |
1028 | + AnyOf(Eq(1),Eq(2)))); |
1029 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
1030 | + size.width.as_int(), size.height.as_int(), |
1031 | + 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, |
1032 | + stub_shm_file->fake_mapping)); |
1033 | + |
1034 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_rgba_4444); |
1035 | + buf.gl_bind_to_texture(); |
1036 | +} |
1037 | + |
1038 | +TEST_F(ShmBufferTest, uploads_xrgb_8888_correctly) |
1039 | +{ |
1040 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
1041 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, |
1042 | + size.width.as_int(), size.height.as_int(), |
1043 | + 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, |
1044 | + stub_shm_file->fake_mapping)); |
1045 | +#endif |
1046 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_xrgb_8888); |
1047 | + buf.gl_bind_to_texture(); |
1048 | +} |
1049 | + |
1050 | +TEST_F(ShmBufferTest, uploads_argb_8888_correctly) |
1051 | +{ |
1052 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
1053 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, |
1054 | + size.width.as_int(), size.height.as_int(), |
1055 | + 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, |
1056 | + stub_shm_file->fake_mapping)); |
1057 | +#endif |
1058 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_argb_8888); |
1059 | + buf.gl_bind_to_texture(); |
1060 | +} |
1061 | + |
1062 | +TEST_F(ShmBufferTest, uploads_xbgr_8888_correctly) |
1063 | +{ |
1064 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
1065 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
1066 | + size.width.as_int(), size.height.as_int(), |
1067 | + 0, GL_RGBA, GL_UNSIGNED_BYTE, |
1068 | + stub_shm_file->fake_mapping)); |
1069 | +#endif |
1070 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_xbgr_8888); |
1071 | + buf.gl_bind_to_texture(); |
1072 | +} |
1073 | + |
1074 | +TEST_F(ShmBufferTest, uploads_abgr_8888_correctly) |
1075 | +{ |
1076 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
1077 | + EXPECT_CALL(mock_gl, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
1078 | + size.width.as_int(), size.height.as_int(), |
1079 | + 0, GL_RGBA, GL_UNSIGNED_BYTE, |
1080 | + stub_shm_file->fake_mapping)); |
1081 | +#endif |
1082 | + mgm::ShmBuffer buf(stub_shm_file, size, mir_pixel_format_abgr_8888); |
1083 | + buf.gl_bind_to_texture(); |
1084 | } |
1085 | |
1086 | === modified file 'tests/unit-tests/graphics/test_graphics_platform.cpp' |
1087 | --- tests/unit-tests/graphics/test_graphics_platform.cpp 2015-06-25 21:34:27 +0000 |
1088 | +++ tests/unit-tests/graphics/test_graphics_platform.cpp 2015-07-13 09:10:30 +0000 |
1089 | @@ -59,6 +59,8 @@ |
1090 | ON_CALL(mock_gbm, gbm_bo_get_height(_)) |
1091 | .WillByDefault(Return(240)); |
1092 | |
1093 | + // FIXME: This format needs to match Mesa's first supported pixel |
1094 | + // format or tests will fail. The coupling is presently loose. |
1095 | ON_CALL(mock_gbm, gbm_bo_get_format(_)) |
1096 | .WillByDefault(Return(GBM_FORMAT_ARGB8888)); |
1097 | |
1098 | |
1099 | === modified file 'tests/unit-tests/graphics/test_pixel_format_utils.cpp' |
1100 | --- tests/unit-tests/graphics/test_pixel_format_utils.cpp 2014-01-08 16:07:36 +0000 |
1101 | +++ tests/unit-tests/graphics/test_pixel_format_utils.cpp 2015-07-13 09:10:30 +0000 |
1102 | @@ -26,10 +26,14 @@ |
1103 | { |
1104 | EXPECT_FALSE(contains_alpha(mir_pixel_format_xbgr_8888)); |
1105 | EXPECT_FALSE(contains_alpha(mir_pixel_format_bgr_888)); |
1106 | + EXPECT_FALSE(contains_alpha(mir_pixel_format_rgb_888)); |
1107 | EXPECT_FALSE(contains_alpha(mir_pixel_format_xrgb_8888)); |
1108 | EXPECT_FALSE(contains_alpha(mir_pixel_format_xbgr_8888)); |
1109 | + EXPECT_FALSE(contains_alpha(mir_pixel_format_rgb_565)); |
1110 | EXPECT_TRUE(contains_alpha(mir_pixel_format_argb_8888)); |
1111 | EXPECT_TRUE(contains_alpha(mir_pixel_format_abgr_8888)); |
1112 | + EXPECT_TRUE(contains_alpha(mir_pixel_format_rgba_5551)); |
1113 | + EXPECT_TRUE(contains_alpha(mir_pixel_format_rgba_4444)); |
1114 | EXPECT_FALSE(contains_alpha(mir_pixel_format_invalid)); |
1115 | EXPECT_FALSE(contains_alpha(mir_pixel_formats)); |
1116 | } |
1117 | @@ -38,10 +42,14 @@ |
1118 | { |
1119 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xbgr_8888)); |
1120 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_bgr_888)); |
1121 | + EXPECT_EQ(8, red_channel_depth(mir_pixel_format_rgb_888)); |
1122 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xrgb_8888)); |
1123 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_xbgr_8888)); |
1124 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_argb_8888)); |
1125 | EXPECT_EQ(8, red_channel_depth(mir_pixel_format_abgr_8888)); |
1126 | + EXPECT_EQ(5, red_channel_depth(mir_pixel_format_rgb_565)); |
1127 | + EXPECT_EQ(5, red_channel_depth(mir_pixel_format_rgba_5551)); |
1128 | + EXPECT_EQ(4, red_channel_depth(mir_pixel_format_rgba_4444)); |
1129 | EXPECT_EQ(0, red_channel_depth(mir_pixel_format_invalid)); |
1130 | EXPECT_EQ(0, red_channel_depth(mir_pixel_formats)); |
1131 | } |
1132 | @@ -50,10 +58,14 @@ |
1133 | { |
1134 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xbgr_8888)); |
1135 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_bgr_888)); |
1136 | + EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_rgb_888)); |
1137 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xrgb_8888)); |
1138 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_xbgr_8888)); |
1139 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_argb_8888)); |
1140 | EXPECT_EQ(8, blue_channel_depth(mir_pixel_format_abgr_8888)); |
1141 | + EXPECT_EQ(5, blue_channel_depth(mir_pixel_format_rgb_565)); |
1142 | + EXPECT_EQ(5, blue_channel_depth(mir_pixel_format_rgba_5551)); |
1143 | + EXPECT_EQ(4, blue_channel_depth(mir_pixel_format_rgba_4444)); |
1144 | EXPECT_EQ(0, blue_channel_depth(mir_pixel_format_invalid)); |
1145 | EXPECT_EQ(0, blue_channel_depth(mir_pixel_formats)); |
1146 | } |
1147 | @@ -62,10 +74,14 @@ |
1148 | { |
1149 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xbgr_8888)); |
1150 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_bgr_888)); |
1151 | + EXPECT_EQ(8, green_channel_depth(mir_pixel_format_rgb_888)); |
1152 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xrgb_8888)); |
1153 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_xbgr_8888)); |
1154 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_argb_8888)); |
1155 | EXPECT_EQ(8, green_channel_depth(mir_pixel_format_abgr_8888)); |
1156 | + EXPECT_EQ(6, green_channel_depth(mir_pixel_format_rgb_565)); |
1157 | + EXPECT_EQ(5, green_channel_depth(mir_pixel_format_rgba_5551)); |
1158 | + EXPECT_EQ(4, green_channel_depth(mir_pixel_format_rgba_4444)); |
1159 | EXPECT_EQ(0, green_channel_depth(mir_pixel_format_invalid)); |
1160 | EXPECT_EQ(0, green_channel_depth(mir_pixel_formats)); |
1161 | } |
1162 | @@ -75,10 +91,14 @@ |
1163 | { |
1164 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xbgr_8888)); |
1165 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_bgr_888)); |
1166 | + EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_rgb_888)); |
1167 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xrgb_8888)); |
1168 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_xbgr_8888)); |
1169 | EXPECT_EQ(8, alpha_channel_depth(mir_pixel_format_argb_8888)); |
1170 | EXPECT_EQ(8, alpha_channel_depth(mir_pixel_format_abgr_8888)); |
1171 | + EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_rgb_565)); |
1172 | + EXPECT_EQ(1, alpha_channel_depth(mir_pixel_format_rgba_5551)); |
1173 | + EXPECT_EQ(4, alpha_channel_depth(mir_pixel_format_rgba_4444)); |
1174 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_format_invalid)); |
1175 | EXPECT_EQ(0, alpha_channel_depth(mir_pixel_formats)); |
1176 | } |
1177 | @@ -87,10 +107,14 @@ |
1178 | { |
1179 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_xbgr_8888)); |
1180 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_bgr_888)); |
1181 | + EXPECT_TRUE(valid_pixel_format(mir_pixel_format_rgb_888)); |
1182 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_xrgb_8888)); |
1183 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_xbgr_8888)); |
1184 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_argb_8888)); |
1185 | EXPECT_TRUE(valid_pixel_format(mir_pixel_format_abgr_8888)); |
1186 | + EXPECT_TRUE(valid_pixel_format(mir_pixel_format_rgb_565)); |
1187 | + EXPECT_TRUE(valid_pixel_format(mir_pixel_format_rgba_5551)); |
1188 | + EXPECT_TRUE(valid_pixel_format(mir_pixel_format_rgba_4444)); |
1189 | EXPECT_FALSE(valid_pixel_format(mir_pixel_format_invalid)); |
1190 | EXPECT_FALSE(valid_pixel_format(mir_pixel_formats)); |
1191 | } |
PASSED: Continuous integration, rev:2795 jenkins. qa.ubuntu. com/job/ mir-ci/ 4290/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/3121 jenkins. qa.ubuntu. com/job/ mir-clang- wily-amd64- build/643 jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/3069 jenkins. qa.ubuntu. com/job/ mir-wily- amd64-ci/ 439 jenkins. qa.ubuntu. com/job/ mir-wily- amd64-ci/ 439/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 3069 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 3069/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -runner- mako/5875 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 21749
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/4290/ rebuild
http://