Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mado-perf
.mado-perf
font-edit
.font-edit
src/composite-decls.h

# Swap
[._]*.s[a-v][a-z]
Expand Down
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
126 changes: 126 additions & 0 deletions scripts/gen-composite-decls.py
Original file line number Diff line number Diff line change
@@ -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()
132 changes: 2 additions & 130 deletions src/twin_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down