AGENTS.md
This file provides guidance to Agents when working with code in this repository.
Overview
This is graphics_effect (abbreviated GE), a component of OpenHarmony's graphics subsystem providing visual effects algorithm capabilities including blur, shadow, gradient, grayscale, edge lighting, and other shader-based effects. The library integrates with the 2D graphics rendering pipeline.
Build System
This project uses GN (Generate Ninja) as its build system, standard for OpenHarmony projects.
Building
# Build the main graphics_effect library (independent build)
# MUST run from the OpenHarmony root (where build.py lives), NOT from this repo!
hb build graphics_effect -i
# Build with full OH code, product could be rk3568 etc.
./build.sh --product-name <product> --build-target graphics_effect
Testing
# Build all tests (independent build)
hb build graphics_effect -t
# Build with full OH code
./build.sh --product-name <product> --build-target graphics_effect_test
Test Organization
- Unit tests:
test/unittest/— files follow patternge_*_test.cpp - Fuzz tests:
test/fuzztest/— each fuzzer has its own subdirectory - Tool tests:
test/tooltest/— tool robustness tests - Tests use cflags
-Dprivate=public -Dprotected=publicto access private members (OpenHarmony test framework cannot access private members without this)
Test Naming Convention
- Don't use
_001suffix — use descriptive names (e.g.,TestKawaseBlurRadiusnotTestKawaseBlur_001). Numbered suffixes are a legacy pattern.
Tool Chain
Python-based tooling for effect scaffolding and parameter metadata generation. See tool/create_effect/README.md and tool/generate_metadata/README.md for detailed syntax and configuration.
Effect Scaffolding
python tool/create_effect/create_effect.py <name> <type>
- Types:
filter,mask,shader,shape - Generates
.params.in,.h,.cppscaffold files — shader logic must be implemented manually
Code Generation
python tool/generate_metadata/gen_metadata.py— Run after any.params.infile is modified. Generatesge_params_reflection.h/cpp(auto-generated — do not manually edit).python tool/generate_metadata/gen_effect_header.py— Run after any.params.infile is added or removed. Generatesge_effects_params.h(auto-generated — do not manually edit).
Complete New Effect Workflow
- Scaffold:
python tool/create_effect/create_effect.py <name> <type> - Register: Add enum value to
ge_filter_type.h - Implement: Write shader logic in the generated
.cppfile - Generate metadata:
python tool/generate_metadata/gen_metadata.py - Generate effects header:
python tool/generate_metadata/gen_effect_header.py
Directory Structure
include/— Public headers (core, effect/{filter,shader,mask,shape}, pipeline, hps, ext, effect_cfg, util)src/— Implementations (mirrors include structure)tool/— Code generation and scaffolding (create_effect, generate_metadata)test/— Tests (unittest, fuzztest, tooltest)
Architecture
The codebase follows a modular, layered architecture. → Full architecture details
- Core Layer (
include/core/) — Base interfaces (IGEFilterType), visual effect container, type registration, effect factory. - Pipeline Layer (
include/pipeline/) — Rendering interface (GERender), multi-pass composition (GEFilterComposer), caching. - Effect Layer (
include/effect/) — Four effect types:GEShaderFilter(image filters),GEShader(direct shaders),GEShaderMask(masking),GEShaderShape(SDF shapes). - HPS Layer (
include/hps/) — High Performance Shader integration for optimized rendering. - Extension Layer (
include/ext/) — Dynamic loading of external effects. - Utility Layer (
include/util/) — Common definitions, logging, tracing, system properties, tone mapping, transform helpers. - Effect Configuration Layer (
include/effect_cfg/) — XML configuration parsing (systemgraphic_config.xml).
Key Subsystems
SDF (Signed Distance Field) System
SDF-based shape rendering and effects (edge lighting, shadows, borders, clipping). Flow: define shape → optionally combine shapes → generate SDF distance shader → bind effect shader → draw. → Full details
Filter Composition Pipeline
Multi-pass effect composition with different rendering strategies. Four passes in fixed order: HpsBuild → MesaFusion → HpsUpscale → DirectDrawOnCanvas. → Full details
Rendering System
Main rendering interface via GERender. Key entry points: DrawImageEffect(), ApplyImageEffect(), DrawShaderEffect(), ApplyHpsGEImageEffect(). → Full details
Caching System
Two independent mechanisms: per-effect cache (std::any per filter) and cross-effect shared store (IGECacheProvider dependency injection). → Full details
HPS Integration
GPU-optimized rendering via High Performance Shaders. Requires GPU extension support + system property enablement. Pure HPS or mixed GE/HPS composition. → Full details
Extension System
Dynamic loading of external effects via dlopen. Factory registration with EXTERNAL/EXTERNAL_FALLBACK/CUSTOM macros. Runtime dispatch via system property. → Full details
Effect Development
Shaders are written inline as GLSL/SkSL strings in C++ source files. Key patterns:
- RuntimeEffect creation: Use
Drawing::RuntimeEffectfor shader compilation - Shader parameters: Set via
RuntimeShaderBuilderuniform binding - Image inputs: Pass as shader children via
RuntimeShaderBuilder - Output: Shaders generate
Drawing::Imageor draw toDrawing::Canvas
The parameter system follows a three-stage pipeline: definition (.params.in files) → generation (gen_metadata.py) → runtime (SetParam API). Two entry points for setting parameters:
- Tag-based:
SetParam(GEParamsMemberTag tag, T value)— type-safe, compile-time checked - String-based:
SetParam(const std::string& tag, T value)— converts string to tag, then delegates to tag-based path
auto ve = GEEffectFactory::CreateFilter(GEFilterType::DISPERSION);
ve->SetParam(GEParamsMemberTag::DISPERSION_OPACITY, 0.5f); // tag-based (type-safe)
ve->SetParam(GE_FILTER_DISPERSION_OPACITY, 0.5f); // constexpr char[] (string-based)
See tool/generate_metadata/README.md for .params.in definition syntax and generated API details.
Code Conventions
Naming
- Classes:
GEprefix (e.g.,GERender,GEVisualEffect) - Files: Match class names with snake_case (e.g.,
ge_render.cppforGERender) - SDF classes:
GESDFprefix (e.g.,GESDFEdgeLight) - Extension classes:
GEXprefix (e.g.,GEXDotMatrixShader)
Platform Macros
GE_OHOS— OpenHarmony platformGE_PLATFORM_UNIX— Unix-like platforms (Linux, OHOS)USE_M133_SKIA— Skia version flag (M133+)
Dependencies
- 2D Graphics:
graphic_2d:2d_graphics— provides Drawing API (Canvas,Image,RuntimeEffect) - Logging:
hilog:libhilog
Boundaries
-
✅ Always:
- Run
gen_metadata.pyafter modifying.params.in - Run
gen_effect_header.pyafter adding/removing.params.in - Follow scaffolding workflow for new effects
- Use
GEprefix for new classes - Run
git clang-formaton modified code before committing
- Run
-
⚠️ Ask first:
- Before changing core interfaces (
IGEFilterType,GEVisualEffect,GERender) - Before modifying
graphic_config.xmlparsing logic
- Before changing core interfaces (
-
🚫 Never:
- Manually edit
ge_params_reflection.h/cpporge_effects_params.h(auto-generated) - Run
hbfrom this repo root (must run from OpenHarmony root wherebuild.pylives) - Use
_001suffix in test names - Commit secrets/API keys
- Manually edit