Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
ae3ca76
feat: Clip layer which behind viewer.
StarryThrone Nov 21, 2025
bb792a6
feat: Draw child with preserve 3D style.
StarryThrone Nov 24, 2025
6fba9b4
feat: Draw offscreen split children for layer which started a 3D rend…
StarryThrone Nov 25, 2025
651e776
feat: Draw layer with depth occultation.
StarryThrone Nov 27, 2025
b43a371
feat: Clip filter image only for layers outside the 3D rendering cont…
StarryThrone Nov 28, 2025
b4e9e05
feat: Calculate render bounds correctly.
StarryThrone Dec 1, 2025
83b3f1a
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Dec 1, 2025
4a34b31
feat: Draw rasterized image cache.
StarryThrone Dec 2, 2025
7d30598
feat: Hide layer when any point behind viewer.
StarryThrone Dec 2, 2025
e15aac6
feat: Enable MSAA to solve aliasing issue.
StarryThrone Dec 3, 2025
01984d0
feat: Draw image of 3D rendering context into background canvas.
StarryThrone Dec 3, 2025
9f4bafb
feat: Disable the background style of all subsequent sub-layers of th…
StarryThrone Dec 3, 2025
4adb42f
feat: Adjust the clipping area and anti-aliasing method to solve the …
StarryThrone Dec 4, 2025
37590ad
feat: Disable the background style of the subsequent nodes of the 3D …
StarryThrone Dec 4, 2025
f414663
feat: The subsequent layer of the 3D layer obtains the content image …
StarryThrone Dec 5, 2025
ebfb512
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Dec 5, 2025
091810d
Refactor 3D rendering context propagation and add alpha support for 3…
StarryThrone Dec 9, 2025
2db8bb7
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Dec 9, 2025
a0fa69f
Translate Chinese comments to English in Layer.cpp.
StarryThrone Dec 9, 2025
16409b5
feat: Resolve build problem.
StarryThrone Dec 9, 2025
d710d42
feat: Resolve build problem.
StarryThrone Dec 9, 2025
5b4956e
feat: Optimize code.
StarryThrone Dec 9, 2025
c1c7c78
feat: Refactor 3D context rendering logic and simplify draw functions.
StarryThrone Dec 16, 2025
22d1417
Move styleSourceTypes from function parameter to DrawArgs.
StarryThrone Dec 16, 2025
a93777a
Add 3D context handling to computeBounds for consistent bounds calcul…
StarryThrone Dec 16, 2025
4e721ed
Rename drawChildByStarting3DContext to drawLayerByStarting3DContext a…
StarryThrone Dec 16, 2025
3f59a7d
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Dec 16, 2025
a356559
Simplify canExtend3DContext by removing blendMode and allowsGroupOpac…
StarryThrone Dec 16, 2025
2487800
Refactor: remove redundant destructor and optimize structured binding
StarryThrone Dec 17, 2025
a25a667
Add trailing newlines and improve IsTransformedLayerRectBehindViewer …
StarryThrone Dec 17, 2025
b31d902
feat: Remove getContentBounds and use content bounds directly in 3D c…
StarryThrone Dec 17, 2025
0994a31
Refactor 3D rendering context drawing logic and update API documentat…
StarryThrone Dec 17, 2025
e7dee9a
Simplify updateRenderBounds interface by consolidating 3D context par…
StarryThrone Dec 17, 2025
9c2a74e
Simplify dirty region calculation for layers in 3D context.
StarryThrone Dec 17, 2025
040d83c
Refactor 3D rendering context implementation and optimize related com…
StarryThrone Dec 18, 2025
1b3c6d3
Refactor 3D rendering context bounds calculation and fix background b…
StarryThrone Dec 22, 2025
ecad22f
Merge branch 'main' into feature/jasonrjchen_3D_context.
StarryThrone Dec 23, 2025
3aa2334
Merge remote-tracking branch 'origin/main' into feature/jasonrjchen_3…
StarryThrone Dec 23, 2025
fd2c005
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Dec 25, 2025
b196b60
Refactor 3D compositing with BSP tree depth sorting.
StarryThrone Dec 26, 2025
5161f3b
Refactor 3D rendering to support BSP-split polygon quads.
StarryThrone Dec 31, 2025
51d771b
Fix getGlobalMatrix to project child layer matrix before concatenation.
StarryThrone Dec 31, 2025
e439a6b
Use args.context instead of canvas->getSurface()->getContext().
StarryThrone Dec 31, 2025
456551d
Return empty rect when 3D transform matrix is singular in reverse bou…
StarryThrone Dec 31, 2025
b471520
Merge remote-tracking branch 'origin/main' into feature/jasonrjchen_3…
StarryThrone Dec 31, 2025
6cf364b
Refactor computeBounds to extract content bounds calculation into a s…
StarryThrone Dec 31, 2025
4badc5d
Update baseline version for Matrix3D and Transform3D tests.
StarryThrone Dec 31, 2025
206638d
feat: Optimize code.
StarryThrone Jan 5, 2026
fa176bd
Merge main branch into feature/jasonrjchen_3D_context.
StarryThrone Jan 5, 2026
6c6673b
feat: Optimize code.
StarryThrone Jan 5, 2026
1b5620f
feat: Optimize code.
StarryThrone Jan 5, 2026
94e4722
feat: Optimize code.
StarryThrone Jan 5, 2026
e89e3b9
feat: Optimize code.
StarryThrone Jan 5, 2026
8102d1d
Refactor 3D rendering context code for clarity and robustness.
StarryThrone Jan 5, 2026
64ad2d7
Refactor computeBounds variable ordering and format code.
StarryThrone Jan 6, 2026
d758849
Simplify 3D context checks and fix mask drawing in 3D context.
StarryThrone Jan 6, 2026
58acc98
Replace unordered_set with vector for styleSourceTypes in DrawArgs.
Jan 6, 2026
0b3dcd8
Add RemoveStyleSource helper and fix background style removal for 3D …
StarryThrone Jan 7, 2026
8bff268
Store 3D transform in Render3DContext instead of passing through func…
StarryThrone Jan 7, 2026
f21f13f
Move camera culling from draw phase to updateRenderBounds for early r…
StarryThrone Jan 7, 2026
23ab08b
Refactor Render3DContext to use state stack based recording.
StarryThrone Jan 7, 2026
8519634
Merge origin/main into feature/jasonrjchen_3D_context.
StarryThrone Jan 7, 2026
d618caf
Remove clipContentByCanvas and add clip calculation in Render3DContext.
StarryThrone Jan 8, 2026
29ea7fc
Add Matrix3DRegionTransformer and simplify updateRenderBounds paramet…
StarryThrone Jan 8, 2026
fa888a6
Remove CodeBuddy user commands from gitignore.
StarryThrone Jan 8, 2026
70d3704
Merge branch 'main' into feature/jasonrjchen_3D_context
StarryThrone Jan 8, 2026
7972ca3
feat: Optimize code.
StarryThrone Jan 8, 2026
1645e23
Move 3D compositing files to compositing3d subdirectory.
StarryThrone Jan 8, 2026
2802e82
Add behind-camera checks in computeBounds and fix Create3DContext bou…
StarryThrone Jan 8, 2026
2f1c8a1
Use emplace to construct Render3DContextState in place.
StarryThrone Jan 8, 2026
9e99b06
Remove redundant backgroundCanvas restore call.
StarryThrone Jan 8, 2026
e78b3fc
Use cached matrix3DIsAffine instead of IsMatrix3DAffine call.
Jan 8, 2026
af61ad1
Add behind-camera check to Transform3DImageFilter and defer matrix ad…
Jan 8, 2026
b4a24f3
Add missing include for std::optional in RegionTransformer.h.
Jan 8, 2026
6b2ec12
Remove redundant FloatCeilToInt after roundOut in PictureToImage.
Jan 8, 2026
8604fb5
Refactor behindCamera logic and fix background style processing.
StarryThrone Jan 9, 2026
1ace7c1
Refactor Render3DContext with improved encapsulation and memory safety.
StarryThrone Jan 9, 2026
f1de2a7
Add Matrix3DUtils class to centralize Matrix3D utility functions.
StarryThrone Jan 9, 2026
e425a4f
Remove Transform3DFilter and add ScaleAdaptedMatrix3D utility.
StarryThrone Jan 9, 2026
9d41b69
Merge remote-tracking branch 'origin/main' into feature/jasonrjchen_3…
StarryThrone Jan 9, 2026
2874403
Use makeTextureImage instead of lockTextureProxy in Context3DCompositor.
StarryThrone Jan 9, 2026
04c0a7f
Add boundary checks for Create3DContext function.
StarryThrone Jan 9, 2026
bc6009d
Replace TransformStyle enum with bool preserve3D property.
StarryThrone Jan 9, 2026
006e37c
Replace Matrix3DCombineMode enum with bool canCombine parameter.
StarryThrone Jan 9, 2026
5abed60
Update copyright year to 2026 for newly added files.
StarryThrone Jan 9, 2026
6ff760e
Extract duplicate styleSourceTypes initialization to a static constant.
StarryThrone Jan 9, 2026
d1ee2d8
Extract scroll rect clipping lambda to static function ClipScrollRect.
StarryThrone Jan 9, 2026
30ff73e
Refactor BspTree traversal by extracting visitNode to reduce code dup…
StarryThrone Jan 9, 2026
3b9f227
Merge remote-tracking branch 'origin/main' into feature/jasonrjchen_3…
StarryThrone Jan 9, 2026
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
63 changes: 38 additions & 25 deletions include/tgfx/core/Matrix3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ class Matrix3D {
*/
Vec4 getRow(int i) const;

/**
* Sets the matrix values at the given row.
* @param i Row index, valid range 0..3.
* @param v Vector containing the values to set.
*/
void setRow(int i, const Vec4& v);

/**
* Returns the matrix value at the given row and column.
* @param r Row index, valid range 0..3.
Expand Down Expand Up @@ -204,6 +211,11 @@ class Matrix3D {
postSkew(kxy, 0, kyx, 0, 0, 0);
}

/**
* Concatenates the given matrix with this matrix, and stores the result in this matrix. M' = M * m.
*/
void preConcat(const Matrix3D& m);

/**
* Concatenates this matrix with the given matrix, and stores the result in this matrix. M' = M * m.
*/
Expand Down Expand Up @@ -253,9 +265,24 @@ class Matrix3D {

/**
* Maps a 3D point using this matrix.
* The point is treated as (x, y, z, 1) in homogeneous coordinates.
* The returned result is the coordinate after perspective division.
*/
Vec3 mapVec3(const Vec3& v) const;
Vec3 mapPoint(const Vec3& point) const;

/**
* Maps a 3D vector using this matrix.
* The vector is treated as (x, y, z, 0) in homogeneous coordinates, so translation does not
* affect the result.
*/
Vec3 mapVector(const Vec3& vector) const;

/**
* Maps a 4D homogeneous coordinate (x, y, z, w) using this matrix.
* If the current matrix contains a perspective transformation, the returned Vec4 is not
* perspective-divided; i.e., the w component of the result may not be 1.
*/
Vec4 mapHomogeneous(float x, float y, float z, float w) const;

/**
* Returns true if the matrix is an identity matrix.
Expand Down Expand Up @@ -293,11 +320,6 @@ class Matrix3D {
*/
void setConcat(const Matrix3D& a, const Matrix3D& b);

/**
* Concatenates the given matrix with this matrix, and stores the result in this matrix. M' = M * m.
*/
void preConcat(const Matrix3D& m);

/**
* Pre-concatenates a scale to this matrix. M' = M * S.
*/
Expand All @@ -308,34 +330,25 @@ class Matrix3D {
*/
Matrix3D transpose() const;

/**
* Maps a 4D point (x, y, z, w) using this matrix.
* If the current matrix contains a perspective transformation, the returned Vec4 is not
* perspective-divided; i.e., the w component of the result may not be 1.
*/
Vec4 mapPoint(float x, float y, float z, float w) const;

Vec4 getCol(int i) const {
Vec4 v;
memcpy(&v, values + i * 4, sizeof(Vec4));
return v;
}

void setAll(float m00, float m01, float m02, float m03, float m10, float m11, float m12,
float m13, float m20, float m21, float m22, float m23, float m30, float m31,
float m32, float m33);

void setRow(int i, const Vec4& v) {
values[i + 0] = v.x;
values[i + 4] = v.y;
values[i + 8] = v.z;
values[i + 12] = v.w;
}

/**
* Sets the matrix values at the given column.
* @param i Column index, valid range 0..3.
* @param v Vector containing the values to set.
*/
void setColumn(int i, const Vec4& v) {
memcpy(&values[i * 4], v.ptr(), sizeof(v));
}

void setAll(float m00, float m01, float m02, float m03, float m10, float m11, float m12,
float m13, float m20, float m21, float m22, float m23, float m30, float m31,
float m32, float m33);

void setIdentity() {
*this = Matrix3D();
}
Expand All @@ -353,7 +366,7 @@ class Matrix3D {
}

Vec4 operator*(const Vec4& v) const {
return this->mapPoint(v.x, v.y, v.z, v.w);
return this->mapHomogeneous(v.x, v.y, v.z, v.w);
}

float values[16] = {.0f};
Expand Down
7 changes: 7 additions & 0 deletions include/tgfx/core/Vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ struct Vec3 {
return sqrtf(Dot(*this, *this));
}

/**
* Returns the squared length of the vector.
*/
float lengthSquared() const {
return Dot(*this, *this);
}

/**
* Returns a pointer to the vector's immutable data.
*/
Expand Down
95 changes: 68 additions & 27 deletions include/tgfx/layers/Layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class DisplayList;
class DrawArgs;
class RegionTransformer;
class RootLayer;
class Render3DContext;
struct LayerStyleSource;
struct MaskData;
class BackgroundContext;
Expand Down Expand Up @@ -125,6 +126,8 @@ class Layer : public std::enable_shared_from_this<Layer> {

/**
* Sets the blend mode of the layer.
* Note: Layers inside a 3D Rendering Context (see preserve3D()) always use SrcOver blend mode
* regardless of this setting.
*/
void setBlendMode(BlendMode value);

Expand All @@ -139,6 +142,8 @@ class Layer : public std::enable_shared_from_this<Layer> {

/**
* Sets whether the layer passes through its background to sublayers.
* Note: Layers that can start or extend a 3D Rendering Context (see preserve3D()) always disable
* pass-through background regardless of this setting.
*/
void setPassThroughBackground(bool value);

Expand Down Expand Up @@ -178,6 +183,39 @@ class Layer : public std::enable_shared_from_this<Layer> {
*/
void setMatrix3D(const Matrix3D& value);

/**
* Returns whether the layer preserves the 3D state of its content and child layers. The default
* value is false.
*
* When false, content and child layers are projected onto the layer's local space. Child layers
* are drawn in the order they were added, so later-added opaque layers completely cover earlier
* ones.
*
* When true, 3D rendering is enabled. If the parent layer has preserve3D disabled, this layer
* establishes a new 3D Rendering Context. If the parent also has preserve3D enabled, this layer
* inherits and extends the parent's context.
*
* Within a 3D Rendering Context, all child layers share the coordinate space of the context
* root's parent (or the DisplayList if no parent exists). Depth occlusion is applied based on
* actual 3D positions: opaque pixels closer to the observer occlude those farther away at the
* same xy coordinates.
*
* Note: preserve3D falls back to false behavior when any of the following conditions are met:
* 1. Layer styles is not empty.
* 2. Filters is not empty.
* 3. Mask is not empty.
* These features require projecting child layers into the current layer's local coordinate
* system, which is incompatible with 3D context preservation.
*/
bool preserve3D() const {
return _preserve3D;
}

/**
* Sets whether the layer preserves the 3D state of its content and child layers.
*/
void setPreserve3D(bool value);

/**
* Returns whether the layer is visible. The default value is true.
*/
Expand Down Expand Up @@ -217,6 +255,8 @@ class Layer : public std::enable_shared_from_this<Layer> {

/**
* Sets whether the layer is allowed to be composited as a separate group from their parent.
* Note: Layers inside a 3D Rendering Context (see preserve3D()) always apply alpha individually
* to each element regardless of this setting.
*/
void setAllowsGroupOpacity(bool value);

Expand All @@ -233,6 +273,14 @@ class Layer : public std::enable_shared_from_this<Layer> {

/**
* Sets the list of layer styles applied to the layer.
* Note: Background-dependent layer styles (e.g., BackgroundBlurStyle) have the following
* limitations:
* 1. Layers that start a 3D Rendering Context (see preserve3D()) disable background styles for
* the entire subtree rooted at that layer. The 3D Rendering Context uses a different rendering
* strategy that has not yet fully adapted background layer drawing.
* 2. Layers with a 3D or projection transformation disable background styles for all descendant
* layers (excluding the layer itself), because descendants cannot correctly obtain the
* background.
*/
void setLayerStyles(const std::vector<std::shared_ptr<LayerStyle>>& value);

Expand Down Expand Up @@ -577,17 +625,22 @@ class Layer : public std::enable_shared_from_this<Layer> {

void drawDirectly(const DrawArgs& args, Canvas* canvas, float alpha);

void drawDirectly(const DrawArgs& args, Canvas* canvas, float alpha,
const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes);

void drawContents(const DrawArgs& args, Canvas* canvas, float alpha,
const LayerStyleSource* layerStyleSource = nullptr,
const Layer* stopChild = nullptr,
const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes = {});
const Layer* stopChild = nullptr);

bool drawChildren(const DrawArgs& args, Canvas* canvas, float alpha,
const Layer* stopChild = nullptr);

void drawByStarting3DContext(const DrawArgs& args, Canvas* canvas);

std::optional<DrawArgs> createChildArgs(const DrawArgs& args, Canvas* canvas, Layer* child,
bool skipBackground, int childIndex,
int lastBackgroundIndex);

void drawChild(const DrawArgs& args, Canvas* canvas, Layer* child, float alpha,
const Matrix3D& transform3D, Render3DContext* context3D, bool started3DContext);

float drawBackgroundLayers(const DrawArgs& args, Canvas* canvas);

std::unique_ptr<LayerStyleSource> getLayerStyleSource(const DrawArgs& args, const Matrix& matrix,
Expand All @@ -598,7 +651,7 @@ class Layer : public std::enable_shared_from_this<Layer> {

/**
* Gets the background image of the minimum axis-aligned bounding box after drawing the layer
* subtree with the current layer as the root node.
* subtree with the current layer as the root node
*/
std::shared_ptr<Image> getBoundsBackgroundImage(const DrawArgs& args, float contentScale,
Point* offset);
Expand All @@ -608,12 +661,8 @@ class Layer : public std::enable_shared_from_this<Layer> {
void drawLayerStyles(const DrawArgs& args, Canvas* canvas, float alpha,
const LayerStyleSource* source, LayerStylePosition position);

void drawLayerStyles(const DrawArgs& args, Canvas* canvas, float alpha,
const LayerStyleSource* source, LayerStylePosition position,
const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes);

void drawBackgroundLayerStyles(const DrawArgs& args, Canvas* canvas, float alpha,
const Matrix3D& transform);
const Matrix3D& transform3D);

bool getLayersUnderPointInternal(float x, float y, std::vector<std::shared_ptr<Layer>>* results);

Expand Down Expand Up @@ -657,27 +706,18 @@ class Layer : public std::enable_shared_from_this<Layer> {
const Matrix3D* transform3D,
const std::shared_ptr<MaskFilter>& maskFilter);

std::shared_ptr<Image> getContentImage(
const DrawArgs& args, const Matrix& contentMatrix, const std::optional<Rect>& clipBounds,
const std::vector<LayerStyleExtraSourceType>& extraSourceTypes, Matrix* imageMatrix);
std::shared_ptr<Image> getContentImage(const DrawArgs& args, const Matrix& contentMatrix,
const std::optional<Rect>& clipBounds,
Matrix* imageMatrix);

std::shared_ptr<Image> getPassThroughContentImage(
const DrawArgs& args, Canvas* canvas, const std::optional<Rect>& clipBounds,
const std::vector<LayerStyleExtraSourceType>& extraSourceTypes, Matrix* imageMatrix);
std::shared_ptr<Image> getPassThroughContentImage(const DrawArgs& args, Canvas* canvas,
const std::optional<Rect>& clipBounds,
Matrix* imageMatrix);

std::optional<Rect> computeContentBounds(const std::optional<Rect>& clipBounds,
bool excludeEffects);

/**
* Returns the equivalent transformation matrix adapted for a custom anchor point.
* The matrix is defined based on a local coordinate system, with the transformation anchor point
* being the origin of that coordinate system. This function returns an affine transformation
* matrix that produces the same visual effect when using any point within this coordinate system
* as the new origin and anchor point.
* @param matrix The original transformation matrix.
* @param anchor The specified anchor point.
*/
Matrix3D anchorAdaptedMatrix(const Matrix3D& matrix, const Point& anchor) const;
bool canPreserve3D() const;

void invalidateSubtree();

Expand All @@ -703,6 +743,7 @@ class Layer : public std::enable_shared_from_this<Layer> {
float _alpha = 1.0f;
// The actual transformation matrix that determines the geometric position of the layer
Matrix3D _matrix3D = {};
bool _preserve3D = false;
std::shared_ptr<Layer> _mask = nullptr;
Layer* maskOwner = nullptr;
std::unique_ptr<Rect> _scrollRect = nullptr;
Expand Down
3 changes: 1 addition & 2 deletions include/tgfx/layers/filters/LayerFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ class LayerFilter : public LayerProperty {
BlurFilter,
ColorMatrixFilter,
DropShadowFilter,
InnerShadowFilter,
Transform3DFilter
InnerShadowFilter
};

virtual Type type() const {
Expand Down
Loading