diff --git a/.gitignore b/.gitignore index 1943279..428737a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,10 +26,7 @@ stamp-* .dirstamp .libs .man_fixup -genshader genunifont -src/static_shaders.c -src/genshader.c src/shl_githead.c src/font_unifont_data.bin docs/reference/*.txt @@ -42,3 +39,5 @@ docs/man/*.1 docs/man/*.3 docs/man/*.5 docs/man/*.7 +src/*.vert.bin +src/*.frag.bin diff --git a/Makefile.am b/Makefile.am index 7b032a5..9cd8326 100644 --- a/Makefile.am +++ b/Makefile.am @@ -144,6 +144,29 @@ src/%.bin.lo: src/%.bin $(AM_V_at)echo "non_pic_object='$*.bin.o'" >>"$@" $(AM_V_at)echo >>"$@" +# +# Shader Converter +# We use a few built-in shader files. To reduce memory-consumption, this helper +# removes useless lines from the shaders before they are compiled into an object +# file. +# +# Following regexp are used to remove characters/lines: +# ^/*.*$ Start of multi-line comment +# ^ *.*$ Multi-line comment body +# ^[ \t]* Indentation whitespace +# \n Newlines +# + +CLEANFILES += src/*.vert.bin src/*.frag.bin +SHADER_SED = -e 's/^\/\*.*$$//' -e 's/^ \*.*$$//' -e 's/^[ \t]*//' +SHADER_TR = -d "\n" + +src/%.vert.bin: $(top_srcdir)/src/%.vert + $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" + +src/%.frag.bin: $(top_srcdir)/src/%.frag + $(AM_V_at)$(SED) $(SHADER_SED) "$<" | tr $(SHADER_TR) >"$@" + # # SHL - Static Helper Library # The SHL subsystem contains several small code pieces used all over kmscon and @@ -265,12 +288,10 @@ libuterm_la_LIBADD += $(DRM_LIBS) endif if BUILD_ENABLE_VIDEO_DRM3D -noinst_PROGRAMS += genshader libuterm_la_SOURCES += \ src/uterm_drm3d_internal.h \ src/uterm_drm3d_video.c \ src/uterm_drm3d_render.c -nodist_libuterm_la_SOURCES += src/static_shaders.c libuterm_la_CPPFLAGS += \ $(DRM_CFLAGS) \ $(EGL_CFLAGS) \ @@ -280,7 +301,13 @@ libuterm_la_LIBADD += \ $(DRM_LIBS) \ $(EGL_LIBS) \ $(GBM_LIBS) \ - $(GLES2_LIBS) + $(GLES2_LIBS) \ + src/uterm_drm3d_blend.vert.bin.lo \ + src/uterm_drm3d_blend.frag.bin.lo \ + src/uterm_drm3d_blit.vert.bin.lo \ + src/uterm_drm3d_blit.frag.bin.lo \ + src/uterm_drm3d_fill.vert.bin.lo \ + src/uterm_drm3d_fill.frag.bin.lo endif # add shared sources only once @@ -295,39 +322,6 @@ libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC) endif endif -# -# Shaders -# As there is no need to modify shaders at run-time, we statically compile them -# into object files. As autotools would ignore them, we need to add them to -# EXTRA_DIST. -# The program that converts the shaders into C-source files is "genshader". It's -# pretty simple and just creates a string with the shader source as content. -# - -SHADERS = \ - $(srcdir)/src/static_fill.vert \ - $(srcdir)/src/static_fill.frag \ - $(srcdir)/src/static_blend.vert \ - $(srcdir)/src/static_blend.frag \ - $(srcdir)/src/static_blit.vert \ - $(srcdir)/src/static_blit.frag \ - $(srcdir)/src/static_gltex.vert \ - $(srcdir)/src/static_gltex.frag - -EXTRA_DIST += $(SHADERS) -CLEANFILES += src/static_shaders.c -genshader_SOURCES = src/genshader.c - -# TODO: Using $(BUILD_EXEEXT) breaks if it doesn't equal $(EXEEXT). But stupid -# automake doesn't allow $(EXEEXT) so lets just rely on both being the same. - -src/static_shaders.c: $(SHADERS) genshader$(BUILD_EXEEXT) - $(AM_V_GEN)./genshader$(BUILD_EXEEXT) src/static_shaders.c $(SHADERS) - -genshader$(BUILD_EXEEXT) $(genshader_OBJECTS): CC = $(CC_FOR_BUILD) -genshader$(BUILD_EXEEXT) $(genshader_OBJECTS): CFLAGS = $(CFLAGS_FOR_BUILD) -genshader$(BUILD_EXEEXT): LDFLAGS = $(LDFLAGS_FOR_BUILD) - # # Unifont Generator # This generates the unifont sources from raw hex-encoded font data. @@ -407,21 +401,20 @@ mod_bbulk_la_LDFLAGS = \ if BUILD_ENABLE_RENDERER_GLTEX module_LTLIBRARIES += mod-gltex.la -noinst_PROGRAMS += genshader endif mod_gltex_la_SOURCES = \ src/kmscon_module_interface.h \ src/text_gltex.c \ src/kmscon_mod_gltex.c -nodist_mod_gltex_la_SOURCES = \ - src/static_shaders.c mod_gltex_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ $(GLES2_CFLAGS) mod_gltex_la_LIBADD = \ $(GLES2_LIBS) \ - libshl.la + libshl.la \ + src/text_gltex_atlas.vert.bin.lo \ + src/text_gltex_atlas.frag.bin.lo mod_gltex_la_LDFLAGS = \ $(AM_LDFLAGS) \ -module \ @@ -606,3 +599,10 @@ endif # BUILD_HAVE_XSLTPROC # .PHONY: $(TPHONY) + +# +# Empty .SECONDARY target causes alle intermediate files to be treated as +# secondary files. That is, they don't get deleted after make finished. +# + +.SECONDARY: diff --git a/src/genshader.c b/src/genshader.c deleted file mode 100644 index f0430f3..0000000 --- a/src/genshader.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * kmscon - Generate Shader Files - * - * Copyright (c) 2011-2012 David Herrmann - * Copyright (c) 2011 University of Tuebingen - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Shader Generator - * This takes as arguments shaders and creates a C-source file which - * contains these shaders as constants. - */ - -#include -#include -#include - -static char *read_file(const char *path, size_t *size) -{ - FILE *ffile; - ssize_t len; - char *buf; - - ffile = fopen(path, "rb"); - if (!ffile) { - fprintf(stderr, "genshader: cannot open %s: %m\n", path); - abort(); - } - - if (fseek(ffile, 0, SEEK_END) != 0) { - fprintf(stderr, "genshader: cannot seek %s: %m\n", path); - abort(); - } - - len = ftell(ffile); - if (len < 0) { - fprintf(stderr, "genshader: cannot tell %s: %m\n", path); - abort(); - } - - if (len < 1) { - fprintf(stderr, "genshader: empty file %s\n", path); - abort(); - } - - rewind(ffile); - - buf = malloc(len + 1); - if (!buf) { - fprintf(stderr, "genshader: memory allocation failed\n"); - abort(); - } - - if (len != fread(buf, 1, len, ffile)) { - fprintf(stderr, "genshader: cannot read %s: %m\n", path); - abort(); - } - - buf[len] = 0; - *size = len; - fclose(ffile); - - return buf; -} - -static const char *get_basename(const char *path) -{ - const char *res; - - res = strrchr(path, '/'); - if (!res || !*++res) - return path; - - return res; -} - -static void write_seq(FILE *out, const char *src, size_t len) -{ - size_t i; - - for (i = 0; i < len; ++i) { - if (src[i] == '\n') { - fwrite("\\n\"\n\"", 5, 1, out); - } else if (src[i] == '"') { - fwrite("\\\"", 2, 1, out); - } else { - fwrite(&src[i], 1, 1, out); - } - } -} - -static void write_name(FILE *out, const char *name) -{ - size_t i, len; - - len = strlen(name); - for (i = 0; i < len; ++i) { - if ((name[i] >= 'A' && name[i] <= 'Z') || - (name[i] >= 'a' && name[i] <= 'z') || - (name[i] >= '0' && name[i] <= '9')) - fwrite(&name[i], 1, 1, out); - else - fwrite("_", 1, 1, out); - } -} - -static void write_single_file(FILE *out, const char *path) -{ - static const char c1[] = "const char *gl_"; - static const char c2[] = " = \""; - static const char c3[] = "\";\n"; - const char *name; - char *content; - size_t len; - - name = get_basename(path); - content = read_file(path, &len); - - fwrite(c1, sizeof(c1) - 1, 1, out); - write_name(out, name); - fwrite(c2, sizeof(c2) - 1, 1, out); - write_seq(out, content, len); - fwrite(c3, sizeof(c3) - 1, 1, out); - - free(content); -} - -int main(int argc, char *argv[]) -{ - FILE *out; - size_t i; - static const char c0[] = "/* This file was generated " - "by genshader.c */\n"; - - if (argc < 2) { - fprintf(stderr, "genshader: use ./genshader [ ...]\n"); - abort(); - } - - out = fopen(argv[1], "wb"); - if (!out) { - fprintf(stderr, "genshader: cannot open %s: %m\n", argv[1]); - abort(); - } - - fwrite(c0, sizeof(c0) - 1, 1, out); - for (i = 2; i < argc; ++i) { - write_single_file(out, argv[i]); - } - - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/src/text_gltex.c b/src/text_gltex.c index beb0bba..20f7eb3 100644 --- a/src/text_gltex.c +++ b/src/text_gltex.c @@ -141,13 +141,16 @@ static void free_glyph(void *data) free(glyph); } -extern const char *gl_static_gltex_vert; -extern const char *gl_static_gltex_frag; +extern const char _binary_src_text_gltex_atlas_vert_bin_start[]; +extern const char _binary_src_text_gltex_atlas_vert_bin_end[]; +extern const char _binary_src_text_gltex_atlas_frag_bin_start[]; +extern const char _binary_src_text_gltex_atlas_frag_bin_end[]; static int gltex_set(struct kmscon_text *txt) { struct gltex *gt = txt->data; - int ret; + int ret, vlen, flen; + const char *vert, *frag; static char *attr[] = { "position", "texture_position", "fgcolor", "bgcolor" }; GLint s; @@ -177,10 +180,14 @@ static int gltex_set(struct kmscon_text *txt) goto err_bold_htable; } + vert = _binary_src_text_gltex_atlas_vert_bin_start; + vlen = _binary_src_text_gltex_atlas_vert_bin_end - vert; + frag = _binary_src_text_gltex_atlas_frag_bin_start; + flen = _binary_src_text_gltex_atlas_frag_bin_end - frag; gl_clear_error(); - ret = gl_shader_new(>->shader, gl_static_gltex_vert, -1, - gl_static_gltex_frag, -1, attr, 4, log_llog, NULL); + ret = gl_shader_new(>->shader, vert, vlen, frag, flen, attr, 4, + log_llog, NULL); if (ret) goto err_bold_htable; diff --git a/src/static_gltex.frag b/src/text_gltex_atlas.frag similarity index 100% rename from src/static_gltex.frag rename to src/text_gltex_atlas.frag diff --git a/src/static_gltex.vert b/src/text_gltex_atlas.vert similarity index 100% rename from src/static_gltex.vert rename to src/text_gltex_atlas.vert diff --git a/src/static_blend.frag b/src/uterm_drm3d_blend.frag similarity index 100% rename from src/static_blend.frag rename to src/uterm_drm3d_blend.frag diff --git a/src/static_blend.vert b/src/uterm_drm3d_blend.vert similarity index 100% rename from src/static_blend.vert rename to src/uterm_drm3d_blend.vert diff --git a/src/static_blit.frag b/src/uterm_drm3d_blit.frag similarity index 100% rename from src/static_blit.frag rename to src/uterm_drm3d_blit.frag diff --git a/src/static_blit.vert b/src/uterm_drm3d_blit.vert similarity index 100% rename from src/static_blit.vert rename to src/uterm_drm3d_blit.vert diff --git a/src/static_fill.frag b/src/uterm_drm3d_fill.frag similarity index 100% rename from src/static_fill.frag rename to src/uterm_drm3d_fill.frag diff --git a/src/static_fill.vert b/src/uterm_drm3d_fill.vert similarity index 100% rename from src/static_fill.vert rename to src/uterm_drm3d_fill.vert diff --git a/src/uterm_drm3d_render.c b/src/uterm_drm3d_render.c index 698d199..aecaf67 100644 --- a/src/uterm_drm3d_render.c +++ b/src/uterm_drm3d_render.c @@ -54,12 +54,18 @@ #define LOG_SUBSYSTEM "uterm_drm3d_render" -extern const char *gl_static_fill_vert; -extern const char *gl_static_fill_frag; -extern const char *gl_static_blend_vert; -extern const char *gl_static_blend_frag; -extern const char *gl_static_blit_vert; -extern const char *gl_static_blit_frag; +extern const char _binary_src_uterm_drm3d_blend_vert_bin_start[]; +extern const char _binary_src_uterm_drm3d_blend_vert_bin_end[]; +extern const char _binary_src_uterm_drm3d_blend_frag_bin_start[]; +extern const char _binary_src_uterm_drm3d_blend_frag_bin_end[]; +extern const char _binary_src_uterm_drm3d_blit_vert_bin_start[]; +extern const char _binary_src_uterm_drm3d_blit_vert_bin_end[]; +extern const char _binary_src_uterm_drm3d_blit_frag_bin_start[]; +extern const char _binary_src_uterm_drm3d_blit_frag_bin_end[]; +extern const char _binary_src_uterm_drm3d_fill_vert_bin_start[]; +extern const char _binary_src_uterm_drm3d_fill_vert_bin_end[]; +extern const char _binary_src_uterm_drm3d_fill_frag_bin_start[]; +extern const char _binary_src_uterm_drm3d_fill_frag_bin_end[]; static int init_shaders(struct uterm_video *video) { @@ -68,6 +74,10 @@ static int init_shaders(struct uterm_video *video) char *fill_attr[] = { "position", "color" }; char *blend_attr[] = { "position", "texture_position" }; char *blit_attr[] = { "position", "texture_position" }; + int blend_vlen, blend_flen, blit_vlen, blit_flen, fill_vlen, fill_flen; + const char *blend_vert, *blend_frag; + const char *blit_vert, *blit_frag; + const char *fill_vert, *fill_frag; if (v3d->sinit == 1) return -EFAULT; @@ -76,8 +86,21 @@ static int init_shaders(struct uterm_video *video) v3d->sinit = 1; - ret = gl_shader_new(&v3d->fill_shader, gl_static_fill_vert, -1, - gl_static_fill_frag, -1, fill_attr, 2, log_llog, + blend_vert = _binary_src_uterm_drm3d_blend_vert_bin_start; + blend_vlen = _binary_src_uterm_drm3d_blend_vert_bin_end - blend_vert; + blend_frag = _binary_src_uterm_drm3d_blend_frag_bin_start; + blend_flen = _binary_src_uterm_drm3d_blend_frag_bin_end - blend_frag; + blit_vert = _binary_src_uterm_drm3d_blit_vert_bin_start; + blit_vlen = _binary_src_uterm_drm3d_blit_vert_bin_end - blit_vert; + blit_frag = _binary_src_uterm_drm3d_blit_frag_bin_start; + blit_flen = _binary_src_uterm_drm3d_blit_frag_bin_end - blit_frag; + fill_vert = _binary_src_uterm_drm3d_fill_vert_bin_start; + fill_vlen = _binary_src_uterm_drm3d_fill_vert_bin_end - fill_vert; + fill_frag = _binary_src_uterm_drm3d_fill_frag_bin_start; + fill_flen = _binary_src_uterm_drm3d_fill_frag_bin_end - fill_frag; + + ret = gl_shader_new(&v3d->fill_shader, fill_vert, fill_vlen, + fill_frag, fill_flen, fill_attr, 2, log_llog, NULL); if (ret) return ret; @@ -85,8 +108,8 @@ static int init_shaders(struct uterm_video *video) v3d->uni_fill_proj = gl_shader_get_uniform(v3d->fill_shader, "projection"); - ret = gl_shader_new(&v3d->blend_shader, gl_static_blend_vert, -1, - gl_static_blend_frag, -1, blend_attr, 2, log_llog, + ret = gl_shader_new(&v3d->blend_shader, blend_vert, blend_vlen, + blend_frag, blend_flen, blend_attr, 2, log_llog, NULL); if (ret) return ret; @@ -100,8 +123,8 @@ static int init_shaders(struct uterm_video *video) v3d->uni_blend_bgcol = gl_shader_get_uniform(v3d->blend_shader, "bgcolor"); - ret = gl_shader_new(&v3d->blit_shader, gl_static_blit_vert, -1, - gl_static_blit_frag, -1, blit_attr, 2, log_llog, + ret = gl_shader_new(&v3d->blit_shader, blit_vert, blit_vlen, + blit_frag, blit_flen, blit_attr, 2, log_llog, NULL); if (ret) return ret;