Merge lp:~alan-griffiths/unity-system-compositor/incorporate-logo-into-spinner-binary into lp:unity-system-compositor

Proposed by Alan Griffiths on 2015-06-05
Status: Merged
Approved by: Alan Griffiths on 2015-06-11
Approved revision: no longer in the source branch.
Merged at revision: 220
Proposed branch: lp:~alan-griffiths/unity-system-compositor/incorporate-logo-into-spinner-binary
Merge into: lp:unity-system-compositor
Diff against target: 376 lines (+155/-68)
7 files modified
CMakeLists.txt (+1/-2)
cmake/FindPIL.cmake (+8/-0)
debian/control (+1/-1)
debian/unity-system-compositor.install (+0/-1)
spinner/CMakeLists.txt (+31/-11)
spinner/eglspinner.cpp (+28/-53)
tools/png2header.py (+86/-0)
To merge this branch: bzr merge lp:~alan-griffiths/unity-system-compositor/incorporate-logo-into-spinner-binary
Reviewer Review Type Date Requested Status
Alberto Aguirre Approve on 2015-06-11
Andreas Pokorny (community) Approve on 2015-06-11
Alexandros Frantzis (community) 2015-06-05 Approve on 2015-06-11
PS Jenkins bot continuous-integration Approve on 2015-06-11
Review via email: mp+261181@code.launchpad.net

Commit Message

Incorporate logo into spinner binary

Description of the Change

Incorporate logo into spinner binary

/1/ avoid the dynamic loading of .png files and the failure mode if they are not installed
/2/ removes dependency on cairo

To post a comment you must log in.
Alexandros Frantzis (afrantzis) wrote :

We are keeping the original PNG files, which may create some confusion if we need to update the images. I suggest that we either delete the PNGs or, preferably, produce the header files from the PNGs during build.

It would be better if the image was already premultiplied, so we didn't need to premultiply on the fly, but it's not critical for the image sizes we are dealing with.

review: Needs Fixing
Andreas Pokorny (andreas-pokorny) wrote :

> We are keeping the original PNG files, which may create some confusion if we
> need to update the images. I suggest that we either delete the PNGs or,
> preferably, produce the header files from the PNGs during build.

+1 but I would prefer if we could keep the png but generate on build.

> It would be better if the image was already premultiplied, so we didn't need
> to premultiply on the fly, but it's not critical for the image sizes we are
> dealing with.

I wonder whether pre-multiply will make a measurable difference to just use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).

review: Approve
Andreas Pokorny (andreas-pokorny) wrote :

Approve when alfs needs fixing is resolved.

review: Needs Fixing
219. By Alexandros Frantzis on 2015-06-11

spinner: Fix failure to run on Android

This MP:

1. Passes surface dimensions in addition to the output_id when placing on a specific output. This is needed as a workaround for our Android backend, which unfortunately uses the value of mir_display_output_invalid_id (0) as a valid output id!

2. Sets swapinterval correctly per surface.

3. Uses eglQuerySurface to get the surface size (instead of mir_buffer_stream_get_current_buffer() which returns a platform dependent structure).

4. Uses a dummy pbuffer surface to emulate a surfaceless context on platforms that don't support it (e.g. Android). Fixes: https://bugs.launchpad.net/bugs/1463855.

Approved by Chris Halse Rogers, Alan Griffiths, PS Jenkins bot.

Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Andreas Pokorny (andreas-pokorny) wrote :

fine

review: Approve
Alberto Aguirre (albaguirre) wrote :

LGTM.

review: Approve
220. By Alan Griffiths on 2015-06-11

Incorporate logo into spinner binary.

Approved by Alberto Aguirre, Andreas Pokorny, Alexandros Frantzis, PS Jenkins bot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-04-07 13:36:48 +0000
3+++ CMakeLists.txt 2015-06-11 09:15:53 +0000
4@@ -15,7 +15,6 @@
5 # Authored by: Robert Ancell <robert.ancell@canonical.com>
6
7 project(UnitySystemCompositor)
8-set(PACKAGE "unity-system-compositor")
9 set(USC_VERSION_MAJOR 0)
10 set(USC_VERSION_MINOR 0)
11 set(USC_VERSION_PATCH 4)
12@@ -40,7 +39,6 @@
13
14 find_package(PkgConfig)
15 pkg_check_modules(ANDROIDPROPS libandroid-properties)
16-pkg_check_modules(CAIRO REQUIRED cairo)
17 pkg_check_modules(GLIB REQUIRED glib-2.0)
18 pkg_check_modules(MIRCLIENT REQUIRED mirclient)
19 pkg_check_modules(MIRSERVER REQUIRED mirserver)
20@@ -48,6 +46,7 @@
21
22 find_package(Boost 1.48.0 COMPONENTS system REQUIRED)
23 find_package(GLESv2 REQUIRED)
24+find_package(PIL REQUIRED)
25
26 add_subdirectory(spinner/)
27 add_subdirectory(src/)
28
29=== added file 'cmake/FindPIL.cmake'
30--- cmake/FindPIL.cmake 1970-01-01 00:00:00 +0000
31+++ cmake/FindPIL.cmake 2015-06-11 09:15:53 +0000
32@@ -0,0 +1,8 @@
33+execute_process(
34+ COMMAND python -c "from PIL import Image"
35+ RESULT_VARIABLE HAVE_PIL
36+)
37+
38+if (NOT ${HAVE_PIL} EQUAL 0)
39+ message(FATAL_ERROR "Python Imaging Library (PIL) not found")
40+endif()
41
42=== modified file 'debian/control'
43--- debian/control 2015-05-06 16:09:19 +0000
44+++ debian/control 2015-06-11 09:15:53 +0000
45@@ -11,7 +11,6 @@
46 libandroid-properties-dev [i386 amd64 armhf],
47 libboost-dev,
48 libboost-system-dev,
49- libcairo2-dev,
50 libdbus-1-dev,
51 libglib2.0-dev,
52 libgles2-mesa-dev,
53@@ -21,6 +20,7 @@
54 pkg-config,
55 python:any (>= 2.7),
56 python-setuptools,
57+ python-pil,
58 Standards-Version: 3.9.4
59 Homepage: https://launchpad.net/unity-system-compositor
60 # if you don't have have commit access to this branch but would like to upload
61
62=== modified file 'debian/unity-system-compositor.install'
63--- debian/unity-system-compositor.install 2014-06-16 16:53:55 +0000
64+++ debian/unity-system-compositor.install 2015-06-11 09:15:53 +0000
65@@ -4,4 +4,3 @@
66 usr/bin/unity-system-compositor-spinner
67 usr/sbin/unity-system-compositor
68 usr/share/dbus-1/interfaces/com.canonical.Unity.Screen.xml
69-usr/share/unity-system-compositor
70
71=== modified file 'spinner/CMakeLists.txt'
72--- spinner/CMakeLists.txt 2015-05-26 13:00:29 +0000
73+++ spinner/CMakeLists.txt 2015-06-11 09:15:53 +0000
74@@ -14,17 +14,32 @@
75 # You should have received a copy of the GNU General Public License
76 # along with this program. If not, see <http://www.gnu.org/licenses/>.
77
78+function(png2header png header varname)
79+ add_custom_command(
80+ OUTPUT ${header}
81+ COMMAND python ${CMAKE_SOURCE_DIR}/tools/png2header.py ${png} ${varname} > ${header}
82+ DEPENDS ${png} ${CMAKE_SOURCE_DIR}/tools/png2header.py
83+ )
84+endfunction()
85+
86+png2header(
87+ ${CMAKE_CURRENT_SOURCE_DIR}/spinner-glow.png
88+ ${CMAKE_CURRENT_BINARY_DIR}/spinner_glow.h
89+ spinner_glow
90+)
91+
92+png2header(
93+ ${CMAKE_CURRENT_SOURCE_DIR}/spinner-logo.png
94+ ${CMAKE_CURRENT_BINARY_DIR}/spinner_logo.h
95+ spinner_logo
96+)
97+
98 include_directories(
99- ${CAIRO_INCLUDE_DIRS}
100 ${GLIB_INCLUDE_DIRS}
101 ${ANDROIDPROPS_INCLUDE_DIRS}
102 ${GLESv2_INCLUDE_DIRS}
103 ${MIRCLIENT_INCLUDE_DIRS}
104-)
105-add_definitions(
106- -DPACKAGE="${PACKAGE}"
107- -DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}"
108- -DPKGDATADIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}/${PACKAGE}"
109+ ${CMAKE_CURRENT_BINARY_DIR}
110 )
111
112 if(ANDROIDPROPS_FOUND)
113@@ -33,16 +48,21 @@
114
115 link_directories(${MIRCLIENT_LIBRARY_DIRS})
116
117-add_executable(unity-system-compositor-spinner eglapp.cpp eglapp.h eglspinner.cpp miregl.h miregl.cpp)
118+add_executable(unity-system-compositor-spinner
119+ eglapp.cpp
120+ eglapp.h
121+ eglspinner.cpp
122+ miregl.h
123+ miregl.cpp
124+ ${CMAKE_CURRENT_BINARY_DIR}/spinner_logo.h
125+ ${CMAKE_CURRENT_BINARY_DIR}/spinner_glow.h
126+)
127+
128 target_link_libraries(unity-system-compositor-spinner
129 EGL
130- ${CAIRO_LDFLAGS}
131 ${GLIB_LDFLAGS}
132 ${ANDROIDPROPS_LDFLAGS}
133 ${GLESv2_LIBRARIES}
134 ${MIRCLIENT_LDFLAGS}
135 )
136 install(TARGETS unity-system-compositor-spinner RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
137-
138-install(FILES spinner-logo.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PACKAGE})
139-install(FILES spinner-glow.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PACKAGE})
140
141=== modified file 'spinner/eglspinner.cpp'
142--- spinner/eglspinner.cpp 2015-05-28 15:25:28 +0000
143+++ spinner/eglspinner.cpp 2015-06-11 09:15:53 +0000
144@@ -1,5 +1,5 @@
145 /*
146- * Copyright © 2013 Canonical Ltd.
147+ * Copyright © 2013-2015 Canonical Ltd.
148 *
149 * This program is free software: you can redistribute it and/or modify
150 * it under the terms of the GNU General Public License version 3 as
151@@ -15,12 +15,13 @@
152 *
153 * Authors: Daniel van Vugt <daniel.van.vugt@canonical.com>
154 * Mirco Müller <mirco.mueller@canonical.com>
155+ * Alan Griffiths <alan@octopull.co.uk>
156+ * Kevin DuBois <kevin.dubois@canonical.com>
157 */
158
159 #include "eglapp.h"
160 #include "miregl.h"
161 #include <assert.h>
162-#include <cairo.h>
163 #include <glib.h>
164 #include <string.h>
165 #include <GLES2/gl2.h>
166@@ -30,6 +31,9 @@
167 #endif
168 #include <signal.h>
169
170+#include "spinner_glow.h"
171+#include "spinner_logo.h"
172+
173 // this is needed for get_gu() to obtain the grid-unit value
174 #define MAX_LENGTH 256
175 #define VALUE_KEY "GRID_UNIT_PX"
176@@ -132,42 +136,20 @@
177 #define BLACK 0.0f, 0.0f, 0.0f
178 //#define WHITE 1.0f, 1.0f, 1.0f
179
180-cairo_surface_t* pngToSurface (const char* filename)
181-{
182- if (access(filename, F_OK & R_OK) != 0)
183- throw std::runtime_error("Failed to load png: " + std::string(filename) + "\n");
184-
185- // create surface from PNG
186- cairo_surface_t* surface = NULL;
187- surface = cairo_image_surface_create_from_png (filename);
188- if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
189- throw std::runtime_error("Failed to load png: " + std::string(filename) + "\n");
190-
191- return surface;
192-}
193-
194-void uploadTexture (GLuint id, const char* filename)
195-{
196- if (!id || !filename)
197- return;
198-
199- cairo_surface_t* surface = pngToSurface (filename);
200-
201+template <typename Image>
202+void uploadTexture (GLuint id, Image& image)
203+{
204 glBindTexture(GL_TEXTURE_2D, id);
205
206- if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
207- {
208- glTexImage2D(GL_TEXTURE_2D,
209- 0,
210- cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ? GL_RGBA : GL_RGB,
211- cairo_image_surface_get_width (surface),
212- cairo_image_surface_get_height (surface),
213- 0,
214- cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ? GL_RGBA : GL_RGB,
215- GL_UNSIGNED_BYTE,
216- cairo_image_surface_get_data (surface));
217- cairo_surface_destroy (surface);
218- }
219+ glTexImage2D(GL_TEXTURE_2D,
220+ 0,
221+ GL_RGBA,
222+ image.width,
223+ image.height,
224+ 0,
225+ GL_RGBA,
226+ GL_UNSIGNED_BYTE,
227+ image.pixel_data);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
231@@ -286,13 +268,9 @@
232 "uniform float uFadeGlow; \n"
233 "void main() \n"
234 "{ \n"
235- " // swizzle because texture was created with cairo\n"
236- " vec4 col = texture2D(uSampler, vTexCoords).bgra; \n"
237- " float r = col.r * uFadeGlow; \n"
238- " float g = col.g * uFadeGlow; \n"
239- " float b = col.b * uFadeGlow; \n"
240- " float a = col.a * uFadeGlow; \n"
241- " gl_FragColor = vec4(r, g, b, a); \n"
242+ " vec4 col = texture2D(uSampler, vTexCoords); \n"
243+ " col = col * uFadeGlow; \n"
244+ " gl_FragColor = col; \n"
245 "} \n";
246
247 const char fShaderSrcLogo[] =
248@@ -302,13 +280,9 @@
249 "uniform float uFadeLogo; \n"
250 "void main() \n"
251 "{ \n"
252- " // swizzle because texture was created with cairo\n"
253- " vec4 col = texture2D(uSampler, vTexCoords).bgra; \n"
254- " float r = col.r * uFadeLogo; \n"
255- " float g = col.g * uFadeLogo; \n"
256- " float b = col.b * uFadeLogo; \n"
257- " float a = col.a * uFadeLogo; \n"
258- " gl_FragColor = vec4(r, g, b, a); \n"
259+ " vec4 col = texture2D(uSampler, vTexCoords); \n"
260+ " col = col * uFadeLogo; \n"
261+ " gl_FragColor = col; \n"
262 "} \n";
263
264 static volatile sig_atomic_t running = 0;
265@@ -381,9 +355,10 @@
266 fadeLogo = glGetUniformLocation(prog[1], "uFadeLogo");
267
268 // create and upload spinner-artwork
269+ // note that the embedded image data has pre-multiplied alpha
270 glGenTextures(2, texture);
271- uploadTexture(texture[0], PKGDATADIR "/spinner-glow.png");
272- uploadTexture(texture[1], PKGDATADIR "/spinner-logo.png");
273+ uploadTexture(texture[0], spinner_glow);
274+ uploadTexture(texture[1], spinner_logo);
275
276 // bunch of shader-attributes to enable
277 glVertexAttribPointer(aTexCoords[0], 2, GL_FLOAT, GL_FALSE, 0, texCoordsSpinner);
278@@ -451,4 +426,4 @@
279 {
280 printf("%s\n", x.what());
281 return EXIT_FAILURE;
282-}
283\ No newline at end of file
284+}
285
286=== added directory 'tools'
287=== added file 'tools/png2header.py'
288--- tools/png2header.py 1970-01-01 00:00:00 +0000
289+++ tools/png2header.py 2015-06-11 09:15:53 +0000
290@@ -0,0 +1,86 @@
291+#!/usr/bin/env python
292+# coding: utf-8
293+
294+# Copyright © 2015 Canonical Ltd.
295+#
296+# This program is free software: you can redistribute it and/or modify
297+# it under the terms of the GNU General Public License version 3 as
298+# published by the Free Software Foundation.
299+#
300+# This program is distributed in the hope that it will be useful,
301+# but WITHOUT ANY WARRANTY; without even the implied warranty of
302+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303+# GNU General Public License for more details.
304+#
305+# You should have received a copy of the GNU General Public License
306+# along with this program. If not, see <http://www.gnu.org/licenses/>.
307+#
308+# Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
309+
310+import sys
311+from PIL import Image
312+
313+def premultiply(image):
314+ pixels = image.load()
315+ for i in range(image.size[0]):
316+ for j in range(image.size[1]):
317+ orig = pixels[i,j]
318+ m = orig[3] / 255.0
319+ pixels[i,j] = (int(orig[0] * m) , int(orig[1] * m), int(orig[2] * m), orig[3])
320+
321+def tocstring(data):
322+ result = ''
323+ line_chars = 0
324+ line_limit = 80
325+
326+ for c in data:
327+ if line_chars == 0:
328+ result += ' "'
329+
330+ s = '\\%o' % ord(c)
331+ result += s
332+ line_chars += len(s)
333+
334+ if line_chars >= line_limit:
335+ result += '"\n'
336+ line_chars = 0
337+
338+ if line_chars != 0:
339+ result += '"'
340+
341+ return result
342+
343+def bytes_per_pixel(image):
344+ if image.mode == 'RGBA':
345+ return 4
346+ elif image.mode == 'RGB':
347+ return 3
348+ else:
349+ raise "Unsupported image mode %s" % image.mode
350+
351+def export(image, variable_name):
352+ image_info = (image.size[0], image.size[1], bytes_per_pixel(image))
353+ print "static const struct {"
354+ print " unsigned int width;"
355+ print " unsigned int height;"
356+ print " unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */"
357+ print " unsigned char pixel_data[%d * %d * %d + 1];" % image_info
358+ print "} %s = {" % variable_name
359+ print " %d, %d, %d," % image_info
360+ print tocstring(image.tostring())
361+ print "};"
362+
363+def show_usage():
364+ print >>sys.stderr, "Usage: ./png2header.py PNGFILE VARNAME > HEADER_FILE"
365+ print >>sys.stderr, "Convert a PNG image to an embeddable C/C++ header file"
366+
367+if len(sys.argv) < 3:
368+ show_usage()
369+ sys.exit(1)
370+
371+image_filename = sys.argv[1]
372+variable_name = sys.argv[2]
373+
374+image = Image.open(image_filename)
375+premultiply(image)
376+export(image, variable_name)

Subscribers

People subscribed via source and target branches