diff options
Diffstat (limited to 'gfx/skia/generate_mozbuild.py')
-rwxr-xr-x | gfx/skia/generate_mozbuild.py | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py new file mode 100755 index 0000000000..c161d24df8 --- /dev/null +++ b/gfx/skia/generate_mozbuild.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python3 + +import locale +import subprocess +from collections import defaultdict +locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') + +header = """ +# +# ##### ####### # # # # # # +# ## # # # # # # # # # # # # +# ## # # # # # # # # # # # +# ## #### # # # # # # # # # # +# ## # # # ####### # # # ####### # ### +# ## # # # # # # # # # # # ### +# # ##### ####### # # ## ## # # # ### +# +# Seriously. You shouldn't even be looking at this file unless you're +# debugging generate_mozbuild.py. +# +# DO NOT MODIFY THIS FILE IT IS AUTOGENERATED. +# + +skia_opt_flags = [] + +if CONFIG['MOZ_OPTIMIZE']: + if CONFIG['CC_TYPE'] == 'clang-cl': + skia_opt_flags += ['-O2'] + elif CONFIG['CC_TYPE'] in ('clang', 'gcc'): + skia_opt_flags += ['-O3'] + +""" + +footer = """ + +# We allow warnings for third-party code that can be updated from upstream. +AllowCompilerWarnings() + +FINAL_LIBRARY = 'gkmedias' +LOCAL_INCLUDES += [ + 'skia', +] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': + DEFINES['UNICODE'] = True + DEFINES['_UNICODE'] = True + UNIFIED_SOURCES += [ + 'skia/src/fonts/SkFontMgr_indirect.cpp', + 'skia/src/fonts/SkRemotableFontMgr.cpp', + ] + +# We should autogenerate these SSE related flags. + +if CONFIG['INTEL_ARCHITECTURE']: + SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-Dskvx=skvx_ssse3', '-mssse3'] + SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-Dskvx=skvx_sse42', '-msse4.2'] + SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-Dskvx=skvx_avx', '-mavx'] + SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma'] + if not CONFIG["MOZ_CODE_COVERAGE"]: + SOURCES['skia/src/opts/SkOpts_skx.cpp'].flags += ['-Dskvx=skvx_skx', '-mavx512f', '-mavx512dq', '-mavx512cd', '-mavx512bw', '-mavx512vl'] +elif CONFIG['TARGET_CPU'] == 'aarch64' and CONFIG['CC_TYPE'] in ('clang', 'gcc'): + SOURCES['skia/src/opts/SkOpts_crc32.cpp'].flags += ['-Dskvx=skvx_crc32', '-march=armv8-a+crc'] + +DEFINES['MOZ_SKIA'] = True + +DEFINES['SKIA_IMPLEMENTATION'] = 1 + +DEFINES['SK_PDF_USE_HARFBUZZ_SUBSETTING'] = 1 + +if CONFIG['MOZ_TREE_FREETYPE']: + DEFINES['SK_CAN_USE_DLOPEN'] = 0 + +# Suppress warnings in third-party code. +CXXFLAGS += [ + '-Wno-deprecated-declarations', + '-Wno-overloaded-virtual', + '-Wno-sign-compare', + '-Wno-unreachable-code', + '-Wno-unused-function', +] +if CONFIG['CC_TYPE'] == 'gcc': + CXXFLAGS += [ + '-Wno-logical-op', + '-Wno-maybe-uninitialized', + ] +if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'): + CXXFLAGS += [ + '-Wno-implicit-fallthrough', + '-Wno-inconsistent-missing-override', + '-Wno-macro-redefined', + '-Wno-unused-private-field', + ] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk', 'android'): + LOCAL_INCLUDES += [ + "/gfx/cairo/cairo/src", + ] + CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS'] + +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk': + CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS'] + +if CONFIG['TARGET_CPU'] in ('mips32', 'mips64'): + # The skia code uses `mips` as a variable, but it's a builtin preprocessor + # macro on mips that expands to `1`. + DEFINES['mips'] = False +""" + +import json + +platforms = ['linux', 'mac', 'android', 'win'] + +def parse_sources(output): + return set(v.replace('//', 'skia/') for v in output.decode('utf-8').split() if v.endswith('.cpp') or v.endswith('.S')) + +def generate_opt_sources(): + cpus = [('intel', 'x86', [':ssse3', ':sse42', ':avx', ':hsw', ':skx']), + ('arm64', 'arm64', [':crc32'])] + + opt_sources = {} + for key, cpu, deps in cpus: + subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_cpu="{1}"\''.format(key, cpu), shell=True) + opt_sources[key] = set() + for dep in deps: + try: + output = subprocess.check_output('cd skia && bin/gn desc out/{0} {1} sources'.format(key, dep), shell=True) + if output: + opt_sources[key].update(parse_sources(output)) + except subprocess.CalledProcessError as e: + if e.output.find(b'source_set') < 0: + raise + + return opt_sources + +def generate_platform_sources(): + sources = {} + platform_args = { + 'win' : 'win_vc="C:/" win_sdk_version="00.0.00000.0" win_toolchain_version="00.00.00000"' + } + for plat in platforms: + args = platform_args.get(plat, '') + output = subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_os="{0}" {1}\' > /dev/null && bin/gn desc out/{0} :skia sources'.format(plat, args), shell=True) + if output: + sources[plat] = parse_sources(output) + + plat_deps = { + ':fontmgr_win' : 'win', + ':fontmgr_win_gdi' : 'win', + ':fontmgr_mac_ct' : 'mac', + } + for dep, key in plat_deps.items(): + output = subprocess.check_output('cd skia && bin/gn desc out/{1} {0} sources'.format(dep, key), shell=True) + if output: + sources[key].update(parse_sources(output)) + + deps = {':pdf' : 'pdf'} + for dep, key in deps.items(): + output = subprocess.check_output('cd skia && bin/gn desc out/linux {} sources'.format(dep), shell=True) + if output: + sources[key] = parse_sources(output) + + sources.update(generate_opt_sources()) + return sources + + +def generate_separated_sources(platform_sources): + ignorelist = [ + 'skia/src/android/', + 'skia/src/effects/', + 'skia/src/fonts/', + 'skia/src/ports/SkImageEncoder', + 'skia/src/ports/SkImageGenerator', + 'SkLight', + 'codec', + 'SkWGL', + 'SkMemory_malloc', + 'third_party', + 'SkAnimCodecPlayer', + 'SkCamera', + 'SkCanvasStack', + 'SkCanvasStateUtils', + 'JSON', + 'SkMultiPictureDocument', + 'SkNullCanvas', + 'SkNWayCanvas', + 'SkOverdrawCanvas', + 'SkPaintFilterCanvas', + 'SkParseColor', + 'SkXPS', + 'SkCreateCGImageRef', + 'skia/src/ports/SkGlobalInitialization', + 'SkICC', + ] + + def isignorelisted(value): + for item in ignorelist: + if value.find(item) >= 0: + return True + + return False + + separated = defaultdict(set, { + 'common': { + 'skia/src/codec/SkMasks.cpp', + 'skia/src/effects/imagefilters/SkBlurImageFilter.cpp', + 'skia/src/effects/imagefilters/SkComposeImageFilter.cpp', + 'skia/src/effects/SkDashPathEffect.cpp', + 'skia/src/ports/SkDiscardableMemory_none.cpp', + 'skia/src/ports/SkGlobalInitialization_default.cpp', + 'skia/src/ports/SkMemory_mozalloc.cpp', + 'skia/src/ports/SkImageGenerator_none.cpp', + 'skia/modules/skcms/skcms.cc', + 'skia/src/core/SkImageFilterTypes.cpp', + 'skia/src/ports/SkFontMgr_empty_factory.cpp', + }, + 'android': { + # 'skia/src/ports/SkDebug_android.cpp', + 'skia/src/ports/SkFontHost_cairo.cpp', + # 'skia/src/ports/SkFontHost_FreeType.cpp', + 'skia/src/ports/SkFontHost_FreeType_common.cpp', + # 'skia/src/ports/SkTime_Unix.cpp', + # 'skia/src/utils/SkThreadUtils_pthread.cpp', + }, + 'linux': { + 'skia/src/ports/SkFontHost_cairo.cpp', + 'skia/src/ports/SkFontHost_FreeType_common.cpp', + }, + 'win': set (), + 'intel': set(), + 'arm': set(), + 'arm64': set(), + 'none': set(), + 'pdf': set() + }) + + for plat in platform_sources.keys(): + for value in platform_sources[plat]: + if isignorelisted(value): + continue + + if value in separated['common']: + continue + + key = plat + + if all(value in platform_sources.get(p, {}) + for p in platforms if p != plat): + key = 'common' + + separated[key].add(value) + + return separated + +def uniq(seq): + seen = set() + seen_add = seen.add + return [ x for x in seq if x not in seen and not seen_add(x)] + +def write_cflags(f, values, subsearch, cflag, indent): + def write_indent(indent): + for _ in range(indent): + f.write(' ') + + if isinstance(subsearch, str): + subsearch = [ subsearch ] + + def isallowlisted(value): + for item in subsearch: + if value.find(item) >= 0: + return True + + return False + + val_list = uniq(sorted(values, key=lambda x: x.lower())) + + if len(val_list) == 0: + return + + for val in val_list: + if isallowlisted(val): + write_indent(indent) + f.write("SOURCES[\'" + val + "\'].flags += " + cflag + "\n") + +opt_allowlist = [ + 'SkOpts', + 'SkBitmapProcState', + 'SkBlitRow', + 'SkBlitter', + 'SkSpriteBlitter', + 'SkMatrix.cpp', + 'skcms', +] + +# Unfortunately for now the gpu and pathops directories are +# non-unifiable. Keep track of this and fix it. +unified_ignorelist = [ + 'FontHost', + 'SkBitmapProcState_matrixProcs.cpp', + 'SkBlitter_A8.cpp', + 'SkBlitter_ARGB32.cpp', + 'SkBlitter_Sprite.cpp', + 'SkCpu.cpp', + 'SkScan_Antihair.cpp', + 'SkScan_AntiPath.cpp', + 'SkParse.cpp', + 'SkPDFFont.cpp', + 'SkPDFDevice.cpp', + 'SkPDFType1Font.cpp', + 'SkPictureData.cpp', + 'SkColorSpace', + 'SkPath.cpp', + 'SkPathOpsDebug.cpp', + 'SkParsePath.cpp', + 'SkRecorder.cpp', + 'SkXfermode', + 'SkRTree.cpp', + 'SkVertices.cpp', + 'SkSLLexer.cpp', +] + opt_allowlist + +def write_sources(f, values, indent): + def isignorelisted(value): + for item in unified_ignorelist: + if value.find(item) >= 0: + return True + + return False + + sources = {} + sources['nonunified'] = set() + sources['unified'] = set() + + for item in values: + if isignorelisted(item): + sources['nonunified'].add(item) + else: + sources['unified'].add(item) + + write_list(f, "UNIFIED_SOURCES", sources['unified'], indent) + write_list(f, "SOURCES", sources['nonunified'], indent) + +def write_list(f, name, values, indent): + def write_indent(indent): + for _ in range(indent): + f.write(' ') + + val_list = uniq(sorted(values, key=lambda x: x.lower())) + + if len(val_list) == 0: + return + + write_indent(indent) + f.write(name + ' += [\n') + for val in val_list: + write_indent(indent + 4) + f.write('\'' + val + '\',\n') + + write_indent(indent) + f.write(']\n') + +def write_mozbuild(sources): + filename = 'moz.build' + f = open(filename, 'w') + + f.write(header) + + write_sources(f, sources['common'], 0) + write_cflags(f, sources['common'], opt_allowlist, 'skia_opt_flags', 0) + + f.write("if CONFIG['MOZ_ENABLE_SKIA_PDF']:\n") + write_sources(f, sources['pdf'], 4) + + f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':\n") + write_sources(f, sources['android'], 4) + + f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):\n") + write_sources(f, sources['mac'], 4) + + f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk':\n") + write_sources(f, sources['linux'], 4) + + f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n") + write_list(f, "SOURCES", sources['win'], 4) + + f.write("if CONFIG['INTEL_ARCHITECTURE']:\n") + write_sources(f, sources['intel'], 4) + write_cflags(f, sources['intel'], opt_allowlist, 'skia_opt_flags', 4) + + if sources['arm']: + f.write("elif CONFIG['TARGET_CPU'] == 'arm' and CONFIG['CC_TYPE'] in ('clang', 'gcc'):\n") + write_sources(f, sources['arm'], 4) + write_cflags(f, sources['arm'], opt_allowlist, 'skia_opt_flags', 4) + + if sources['arm64']: + f.write("elif CONFIG['TARGET_CPU'] == 'aarch64':\n") + write_sources(f, sources['arm64'], 4) + write_cflags(f, sources['arm64'], opt_allowlist, 'skia_opt_flags', 4) + + if sources['none']: + f.write("else:\n") + write_sources(f, sources['none'], 4) + + f.write(footer) + + f.close() + + print('Wrote ' + filename) + +def main(): + platform_sources = generate_platform_sources() + separated_sources = generate_separated_sources(platform_sources) + write_mozbuild(separated_sources) + + +if __name__ == '__main__': + main() |