From 94091275eee27fb55af8c8c7146ae3ce7473aa72 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Fri, 17 Oct 2025 02:23:04 +0800 Subject: [PATCH] Automate compositing declarations generation This replaces 128 manually maintained func declarations with automated generation system. The build system automatically generates src/composite-decls.h from src/primitive.c macro patterns. --- .gitignore | 1 + Makefile | 16 ++++ scripts/gen-composite-decls.py | 126 +++++++++++++++++++++++++++++++ src/twin_private.h | 132 +-------------------------------- 4 files changed, 145 insertions(+), 130 deletions(-) create mode 100755 scripts/gen-composite-decls.py diff --git a/.gitignore b/.gitignore index fe3a53e9..c339cd6f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ mado-perf .mado-perf font-edit .font-edit +src/composite-decls.h # Swap [._]*.s[a-v][a-z] diff --git a/Makefile b/Makefile index ce8a608f..dfaedcfd 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ -include .config +# Set default goal explicitly +.DEFAULT_GOAL := all + check_goal := $(strip $(MAKECMDGOALS)) ifeq ($(filter $(check_goal),config defconfig),) ifneq "$(CONFIG_CONFIGURED)" "y" @@ -58,6 +61,11 @@ libtwin.a_includes-y := \ include \ src +# Auto-generate compositing function declarations if missing +src/composite-decls.h: scripts/gen-composite-decls.py + @echo " GEN $@" + @$< > $@ + # Optional features libtwin.a_files-$(CONFIG_LOGGING) += src/log.c @@ -189,6 +197,14 @@ endif CFLAGS += -include config.h +# Ensure composite-decls.h exists before including build rules +# (needed for dependency generation in mk/common.mk) +ifeq ($(filter config defconfig clean,$(MAKECMDGOALS)),) + ifeq ($(wildcard src/composite-decls.h),) + $(shell scripts/gen-composite-decls.py > src/composite-decls.h) + endif +endif + # Only skip build rules when running ONLY config/defconfig (no other targets) ifneq ($(filter-out config defconfig,$(check_goal)),) # Has targets other than config/defconfig diff --git a/scripts/gen-composite-decls.py b/scripts/gen-composite-decls.py new file mode 100755 index 00000000..52156b19 --- /dev/null +++ b/scripts/gen-composite-decls.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +""" +Generate composite function declarations for twin_private.h + +This script generates the ~128 function declarations for compositing operations +that are currently manually listed in twin_private.h:280-405. + +The functions are actually generated by macros in src/primitive.c, but we need +their declarations in the header. +""" + +# Format types for src, msk, and dst +FORMATS = ["argb32", "rgb16", "a8", "c"] +# Operators +OPS = ["over", "source"] + + +def generate_3operand_decls(): + """ + Generate declarations for 3-operand functions: + _twin_{src}_in_{msk}_{op}_{dst} + + These are generated by MAKE_TWIN_in_op_dsts_srcs_msks macro + """ + decls = [] + + # Format: _twin_{src}_in_{msk}_{op}_{dst} + # Generated from primitive.c:179 + # MAKE_TWIN_in_op_dsts_srcs_msks(over) + # MAKE_TWIN_in_op_dsts_srcs_msks(source) + + for op in OPS: + for dst in ["argb32", "rgb16", "a8"]: # dst doesn't include 'c' + for src in FORMATS: + for msk in FORMATS: + func_name = f"_twin_{src}_in_{msk}_{op}_{dst}" + decls.append(f"twin_in_op_func {func_name};") + + return decls + + +def generate_2operand_decls(): + """ + Generate declarations for 2-operand functions: + _twin_{src}_{op}_{dst} + + These are generated by MAKE_TWIN_op_dsts_srcs macro + """ + decls = [] + + # Format: _twin_{src}_{op}_{dst} + # Generated from primitive.c:220-221 + # MAKE_TWIN_op_dsts_srcs(over); + # MAKE_TWIN_op_dsts_srcs(source); + + for op in OPS: + for dst in ["argb32", "rgb16", "a8"]: # dst doesn't include 'c' + for src in FORMATS: + func_name = f"_twin_{src}_{op}_{dst}" + decls.append(f"twin_op_func {func_name};") + + return decls + + +def generate_vectorized_decls(): + """ + Generate declarations for vectorized functions + These are hand-written optimizations + """ + return [ + "twin_op_func _twin_vec_argb32_over_argb32;", + "twin_op_func _twin_vec_argb32_source_argb32;", + ] + + +def generate_header(): + """Generate header comment""" + return """/* + * Compositing operation function declarations + * + * These functions are generated by macros in src/primitive.c + * This file is auto-generated by the build system - DO NOT EDIT + */ + +#ifndef _TWIN_COMPOSITE_DECLS_H_ +#define _TWIN_COMPOSITE_DECLS_H_ + +/* Forward declarations for function types */ +typedef void twin_in_op_func(twin_pointer_t dst, + twin_source_u src, + twin_source_u msk, + int width); + +typedef void twin_op_func(twin_pointer_t dst, twin_source_u src, int width); +""" + + +def generate_footer(): + """Generate footer""" + return """ +#endif /* _TWIN_COMPOSITE_DECLS_H_ */ +""" + + +def main(): + print(generate_header()) + + print("\n/* 3-operand compositing: _twin_{src}_in_{msk}_{op}_{dst} */") + print("/* Total: 2 ops * 3 dsts * 4 srcs * 4 msks = 96 functions */") + for decl in generate_3operand_decls(): + print(decl) + + print("\n/* 2-operand compositing: _twin_{src}_{op}_{dst} */") + print("/* Total: 2 ops * 3 dsts * 4 srcs = 24 functions */") + for decl in generate_2operand_decls(): + print(decl) + + print("\n/* Vectorized implementations (hand-optimized) */") + for decl in generate_vectorized_decls(): + print(decl) + + print(generate_footer()) + + +if __name__ == "__main__": + main() diff --git a/src/twin_private.h b/src/twin_private.h index 0060a8b9..723280c7 100644 --- a/src/twin_private.h +++ b/src/twin_private.h @@ -276,136 +276,8 @@ typedef struct _twin_gpoint { twin_gfixed_t x, y; } twin_gpoint_t; -/* - * FIXME: should be refactored to reduce the number of functions. - */ -twin_in_op_func _twin_argb32_in_argb32_over_argb32; -twin_in_op_func _twin_argb32_in_rgb16_over_argb32; -twin_in_op_func _twin_argb32_in_a8_over_argb32; -twin_in_op_func _twin_argb32_in_c_over_argb32; -twin_in_op_func _twin_rgb16_in_argb32_over_argb32; -twin_in_op_func _twin_rgb16_in_rgb16_over_argb32; -twin_in_op_func _twin_rgb16_in_a8_over_argb32; -twin_in_op_func _twin_rgb16_in_c_over_argb32; -twin_in_op_func _twin_a8_in_argb32_over_argb32; -twin_in_op_func _twin_a8_in_rgb16_over_argb32; -twin_in_op_func _twin_a8_in_a8_over_argb32; -twin_in_op_func _twin_a8_in_c_over_argb32; -twin_in_op_func _twin_c_in_argb32_over_argb32; -twin_in_op_func _twin_c_in_rgb16_over_argb32; -twin_in_op_func _twin_c_in_a8_over_argb32; -twin_in_op_func _twin_c_in_c_over_argb32; -twin_in_op_func _twin_argb32_in_argb32_over_rgb16; -twin_in_op_func _twin_argb32_in_rgb16_over_rgb16; -twin_in_op_func _twin_argb32_in_a8_over_rgb16; -twin_in_op_func _twin_argb32_in_c_over_rgb16; -twin_in_op_func _twin_rgb16_in_argb32_over_rgb16; -twin_in_op_func _twin_rgb16_in_rgb16_over_rgb16; -twin_in_op_func _twin_rgb16_in_a8_over_rgb16; -twin_in_op_func _twin_rgb16_in_c_over_rgb16; -twin_in_op_func _twin_a8_in_argb32_over_rgb16; -twin_in_op_func _twin_a8_in_rgb16_over_rgb16; -twin_in_op_func _twin_a8_in_a8_over_rgb16; -twin_in_op_func _twin_a8_in_c_over_rgb16; -twin_in_op_func _twin_c_in_argb32_over_rgb16; -twin_in_op_func _twin_c_in_rgb16_over_rgb16; -twin_in_op_func _twin_c_in_a8_over_rgb16; -twin_in_op_func _twin_c_in_c_over_rgb16; -twin_in_op_func _twin_argb32_in_argb32_over_a8; -twin_in_op_func _twin_argb32_in_rgb16_over_a8; -twin_in_op_func _twin_argb32_in_a8_over_a8; -twin_in_op_func _twin_argb32_in_c_over_a8; -twin_in_op_func _twin_rgb16_in_argb32_over_a8; -twin_in_op_func _twin_rgb16_in_rgb16_over_a8; -twin_in_op_func _twin_rgb16_in_a8_over_a8; -twin_in_op_func _twin_rgb16_in_c_over_a8; -twin_in_op_func _twin_a8_in_argb32_over_a8; -twin_in_op_func _twin_a8_in_rgb16_over_a8; -twin_in_op_func _twin_a8_in_a8_over_a8; -twin_in_op_func _twin_a8_in_c_over_a8; -twin_in_op_func _twin_c_in_argb32_over_a8; -twin_in_op_func _twin_c_in_rgb16_over_a8; -twin_in_op_func _twin_c_in_a8_over_a8; -twin_in_op_func _twin_c_in_c_over_a8; -twin_in_op_func _twin_argb32_in_argb32_over_c; - -twin_in_op_func _twin_argb32_in_argb32_source_argb32; -twin_in_op_func _twin_argb32_in_rgb16_source_argb32; -twin_in_op_func _twin_argb32_in_a8_source_argb32; -twin_in_op_func _twin_argb32_in_c_source_argb32; -twin_in_op_func _twin_rgb16_in_argb32_source_argb32; -twin_in_op_func _twin_rgb16_in_rgb16_source_argb32; -twin_in_op_func _twin_rgb16_in_a8_source_argb32; -twin_in_op_func _twin_rgb16_in_c_source_argb32; -twin_in_op_func _twin_a8_in_argb32_source_argb32; -twin_in_op_func _twin_a8_in_rgb16_source_argb32; -twin_in_op_func _twin_a8_in_a8_source_argb32; -twin_in_op_func _twin_a8_in_c_source_argb32; -twin_in_op_func _twin_c_in_argb32_source_argb32; -twin_in_op_func _twin_c_in_rgb16_source_argb32; -twin_in_op_func _twin_c_in_a8_source_argb32; -twin_in_op_func _twin_c_in_c_source_argb32; -twin_in_op_func _twin_argb32_in_argb32_source_rgb16; -twin_in_op_func _twin_argb32_in_rgb16_source_rgb16; -twin_in_op_func _twin_argb32_in_a8_source_rgb16; -twin_in_op_func _twin_argb32_in_c_source_rgb16; -twin_in_op_func _twin_rgb16_in_argb32_source_rgb16; -twin_in_op_func _twin_rgb16_in_rgb16_source_rgb16; -twin_in_op_func _twin_rgb16_in_a8_source_rgb16; -twin_in_op_func _twin_rgb16_in_c_source_rgb16; -twin_in_op_func _twin_a8_in_argb32_source_rgb16; -twin_in_op_func _twin_a8_in_rgb16_source_rgb16; -twin_in_op_func _twin_a8_in_a8_source_rgb16; -twin_in_op_func _twin_a8_in_c_source_rgb16; -twin_in_op_func _twin_c_in_argb32_source_rgb16; -twin_in_op_func _twin_c_in_rgb16_source_rgb16; -twin_in_op_func _twin_c_in_a8_source_rgb16; -twin_in_op_func _twin_c_in_c_source_rgb16; -twin_in_op_func _twin_argb32_in_argb32_source_a8; -twin_in_op_func _twin_argb32_in_rgb16_source_a8; -twin_in_op_func _twin_argb32_in_a8_source_a8; -twin_in_op_func _twin_argb32_in_c_source_a8; -twin_in_op_func _twin_rgb16_in_argb32_source_a8; -twin_in_op_func _twin_rgb16_in_rgb16_source_a8; -twin_in_op_func _twin_rgb16_in_a8_source_a8; -twin_in_op_func _twin_rgb16_in_c_source_a8; -twin_in_op_func _twin_a8_in_argb32_source_a8; -twin_in_op_func _twin_a8_in_rgb16_source_a8; -twin_in_op_func _twin_a8_in_a8_source_a8; -twin_in_op_func _twin_a8_in_c_source_a8; -twin_in_op_func _twin_c_in_argb32_source_a8; -twin_in_op_func _twin_c_in_rgb16_source_a8; -twin_in_op_func _twin_c_in_a8_source_a8; -twin_in_op_func _twin_c_in_c_source_a8; -twin_in_op_func _twin_argb32_in_argb32_source_c; - -twin_op_func _twin_argb32_over_argb32; -twin_op_func _twin_rgb16_over_argb32; -twin_op_func _twin_a8_over_argb32; -twin_op_func _twin_c_over_argb32; -twin_op_func _twin_argb32_over_rgb16; -twin_op_func _twin_rgb16_over_rgb16; -twin_op_func _twin_a8_over_rgb16; -twin_op_func _twin_c_over_rgb16; -twin_op_func _twin_argb32_over_a8; -twin_op_func _twin_rgb16_over_a8; -twin_op_func _twin_a8_over_a8; -twin_op_func _twin_c_over_a8; -twin_op_func _twin_argb32_source_argb32; -twin_op_func _twin_rgb16_source_argb32; -twin_op_func _twin_a8_source_argb32; -twin_op_func _twin_c_source_argb32; -twin_op_func _twin_argb32_source_rgb16; -twin_op_func _twin_rgb16_source_rgb16; -twin_op_func _twin_a8_source_rgb16; -twin_op_func _twin_c_source_rgb16; -twin_op_func _twin_argb32_source_a8; -twin_op_func _twin_rgb16_source_a8; -twin_op_func _twin_a8_source_a8; -twin_op_func _twin_c_source_a8; - -twin_op_func _twin_vec_argb32_over_argb32; -twin_op_func _twin_vec_argb32_source_argb32; +/* Compositing function declarations - auto-generated */ +#include "composite-decls.h" twin_argb32_t *_twin_fetch_rgb16(twin_pixmap_t *pixmap, int x,