Skip to content

Commit

Permalink
Script to inline shader into C header file
Browse files Browse the repository at this point in the history
OpenGL compiles shader code as text at runtime. It is inconvienent to
edit shader code as const char[] inside the C++ source code.

This CL contains script that reads file contents, turns them into const
char[], and combine them into a header file.

BUG=385924

Review-Url: https://codereview.chromium.org/2036023003
Cr-Commit-Position: refs/heads/master@{#398142}
  • Loading branch information
ywh233 authored and Commit bot committed Jun 6, 2016
1 parent b877548 commit 2621941
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
14 changes: 14 additions & 0 deletions remoting/client/opengl/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
shaders = [
"tex_coord_to_view.vert",
"draw_tex.frag",
]

action("inline_shaders") {
script = "../../tools/build/shader_to_header.py"
out_path = "${root_gen_dir}/remoting/client/opengl/shaders.h"
inputs = shaders
outputs = [
out_path,
]
args = [ rebase_path(out_path) ] + rebase_path(shaders)
}
96 changes: 96 additions & 0 deletions remoting/tools/build/shader_to_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/python
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Helper script to inline files as const char[] into a C header file.
Example:
Input file in_a.vert:
1"
2
3\
Input file in_b.frag:
4
5
6
shader_to_header.py "output.h" "in_a.vert" "in_b.frag" will generate this:
#ifndef OUTPUT_H_BSGN3bbEMBDD0ucC
#define OUTPUT_H_BSGN3bbEMBDD0ucC
const char kInAVert[] = "1\"\n2\n3\\\n";
const char kInBFrag[] = "4\n5\n6\n";
#endif // OUTPUT_H_BSGN3bbEMBDD0ucC
"""

import os.path
import random
import string
import sys

RANDOM_STRING_LENGTH = 16
STRING_CHARACTERS = (string.ascii_uppercase +
string.ascii_lowercase +
string.digits)

def random_str():
return ''.join(random.choice(STRING_CHARACTERS)
for _ in range(RANDOM_STRING_LENGTH))


def escape_text(line):
# encode('string-escape') doesn't escape double quote so you need to manually
# escape it.
return line.encode('string-escape').replace('"', '\\"')


def main():
if len(sys.argv) < 3:
print 'Usage: shader_to_header.py <output-file> <input-files...>'
return 1

output_path = sys.argv[1]
include_guard = (os.path.basename(output_path).upper().replace('.', '_') +
'_' + random_str())

with open(output_path, 'w') as output_file:
output_file.write('#ifndef ' + include_guard + '\n' +
'#define ' + include_guard + '\n\n')

existing_names = set()
argc = len(sys.argv)
for i in xrange(2, argc):
input_path = sys.argv[i]

with open(input_path, 'r') as input_file:
# hello_world.vert -> kHelloWorldVert
const_name = ('k' + os.path.basename(input_path).title()
.replace('_', '').replace('.', ''))
if const_name in existing_names:
print >> sys.stderr, ('Error: Constant name ' + const_name +
' is already used by a previous file. Files with the same' +
' name can\'t be inlined into the same header.')
return 1

existing_names.add(const_name)
text = input_file.read()

inlined = ('const char ' + const_name + '[] = "' + escape_text(text) +
'";\n\n');
output_file.write(inlined)

output_file.write('#endif // ' + include_guard + '\n')

return 0


if __name__ == '__main__':
sys.exit(main())

0 comments on commit 2621941

Please sign in to comment.