@@ -37,6 +37,7 @@ class DisplayList;
3737class DrawArgs ;
3838class RegionTransformer ;
3939class RootLayer ;
40+ class Render3DContext ;
4041struct LayerStyleSource ;
4142struct MaskData ;
4243class BackgroundContext ;
@@ -125,6 +126,8 @@ class Layer : public std::enable_shared_from_this<Layer> {
125126
126127 /* *
127128 * Sets the blend mode of the layer.
129+ * Note: Layers inside a 3D Rendering Context (see preserve3D()) always use SrcOver blend mode
130+ * regardless of this setting.
128131 */
129132 void setBlendMode (BlendMode value);
130133
@@ -139,6 +142,8 @@ class Layer : public std::enable_shared_from_this<Layer> {
139142
140143 /* *
141144 * Sets whether the layer passes through its background to sublayers.
145+ * Note: Layers that can start or extend a 3D Rendering Context (see preserve3D()) always disable
146+ * pass-through background regardless of this setting.
142147 */
143148 void setPassThroughBackground (bool value);
144149
@@ -178,6 +183,39 @@ class Layer : public std::enable_shared_from_this<Layer> {
178183 */
179184 void setMatrix3D (const Matrix3D& value);
180185
186+ /* *
187+ * Returns whether the layer preserves the 3D state of its content and child layers. The default
188+ * value is false.
189+ *
190+ * When false, content and child layers are projected onto the layer's local space. Child layers
191+ * are drawn in the order they were added, so later-added opaque layers completely cover earlier
192+ * ones.
193+ *
194+ * When true, 3D rendering is enabled. If the parent layer has preserve3D disabled, this layer
195+ * establishes a new 3D Rendering Context. If the parent also has preserve3D enabled, this layer
196+ * inherits and extends the parent's context.
197+ *
198+ * Within a 3D Rendering Context, all child layers share the coordinate space of the context
199+ * root's parent (or the DisplayList if no parent exists). Depth occlusion is applied based on
200+ * actual 3D positions: opaque pixels closer to the observer occlude those farther away at the
201+ * same xy coordinates.
202+ *
203+ * Note: preserve3D falls back to false behavior when any of the following conditions are met:
204+ * 1. Layer styles is not empty.
205+ * 2. Filters is not empty.
206+ * 3. Mask is not empty.
207+ * These features require projecting child layers into the current layer's local coordinate
208+ * system, which is incompatible with 3D context preservation.
209+ */
210+ bool preserve3D () const {
211+ return _preserve3D;
212+ }
213+
214+ /* *
215+ * Sets whether the layer preserves the 3D state of its content and child layers.
216+ */
217+ void setPreserve3D (bool value);
218+
181219 /* *
182220 * Returns whether the layer is visible. The default value is true.
183221 */
@@ -217,6 +255,8 @@ class Layer : public std::enable_shared_from_this<Layer> {
217255
218256 /* *
219257 * Sets whether the layer is allowed to be composited as a separate group from their parent.
258+ * Note: Layers inside a 3D Rendering Context (see preserve3D()) always apply alpha individually
259+ * to each element regardless of this setting.
220260 */
221261 void setAllowsGroupOpacity (bool value);
222262
@@ -233,6 +273,14 @@ class Layer : public std::enable_shared_from_this<Layer> {
233273
234274 /* *
235275 * Sets the list of layer styles applied to the layer.
276+ * Note: Background-dependent layer styles (e.g., BackgroundBlurStyle) have the following
277+ * limitations:
278+ * 1. Layers that start a 3D Rendering Context (see preserve3D()) disable background styles for
279+ * the entire subtree rooted at that layer. The 3D Rendering Context uses a different rendering
280+ * strategy that has not yet fully adapted background layer drawing.
281+ * 2. Layers with a 3D or projection transformation disable background styles for all descendant
282+ * layers (excluding the layer itself), because descendants cannot correctly obtain the
283+ * background.
236284 */
237285 void setLayerStyles (const std::vector<std::shared_ptr<LayerStyle>>& value);
238286
@@ -577,17 +625,22 @@ class Layer : public std::enable_shared_from_this<Layer> {
577625
578626 void drawDirectly (const DrawArgs& args, Canvas* canvas, float alpha);
579627
580- void drawDirectly (const DrawArgs& args, Canvas* canvas, float alpha,
581- const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes);
582-
583628 void drawContents (const DrawArgs& args, Canvas* canvas, float alpha,
584629 const LayerStyleSource* layerStyleSource = nullptr ,
585- const Layer* stopChild = nullptr ,
586- const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes = {});
630+ const Layer* stopChild = nullptr );
587631
588632 bool drawChildren (const DrawArgs& args, Canvas* canvas, float alpha,
589633 const Layer* stopChild = nullptr );
590634
635+ void drawByStarting3DContext (const DrawArgs& args, Canvas* canvas);
636+
637+ std::optional<DrawArgs> createChildArgs (const DrawArgs& args, Canvas* canvas, Layer* child,
638+ bool skipBackground, int childIndex,
639+ int lastBackgroundIndex);
640+
641+ void drawChild (const DrawArgs& args, Canvas* canvas, Layer* child, float alpha,
642+ const Matrix3D& transform3D, Render3DContext* context3D, bool started3DContext);
643+
591644 float drawBackgroundLayers (const DrawArgs& args, Canvas* canvas);
592645
593646 std::unique_ptr<LayerStyleSource> getLayerStyleSource (const DrawArgs& args, const Matrix& matrix,
@@ -598,7 +651,7 @@ class Layer : public std::enable_shared_from_this<Layer> {
598651
599652 /* *
600653 * Gets the background image of the minimum axis-aligned bounding box after drawing the layer
601- * subtree with the current layer as the root node.
654+ * subtree with the current layer as the root node
602655 */
603656 std::shared_ptr<Image> getBoundsBackgroundImage (const DrawArgs& args, float contentScale,
604657 Point* offset);
@@ -608,12 +661,8 @@ class Layer : public std::enable_shared_from_this<Layer> {
608661 void drawLayerStyles (const DrawArgs& args, Canvas* canvas, float alpha,
609662 const LayerStyleSource* source, LayerStylePosition position);
610663
611- void drawLayerStyles (const DrawArgs& args, Canvas* canvas, float alpha,
612- const LayerStyleSource* source, LayerStylePosition position,
613- const std::vector<LayerStyleExtraSourceType>& styleExtraSourceTypes);
614-
615664 void drawBackgroundLayerStyles (const DrawArgs& args, Canvas* canvas, float alpha,
616- const Matrix3D& transform );
665+ const Matrix3D& transform3D );
617666
618667 bool getLayersUnderPointInternal (float x, float y, std::vector<std::shared_ptr<Layer>>* results);
619668
@@ -657,27 +706,18 @@ class Layer : public std::enable_shared_from_this<Layer> {
657706 const Matrix3D* transform3D,
658707 const std::shared_ptr<MaskFilter>& maskFilter);
659708
660- std::shared_ptr<Image> getContentImage (
661- const DrawArgs& args, const Matrix& contentMatrix, const std::optional<Rect>& clipBounds,
662- const std::vector<LayerStyleExtraSourceType>& extraSourceTypes, Matrix* imageMatrix);
709+ std::shared_ptr<Image> getContentImage (const DrawArgs& args, const Matrix& contentMatrix,
710+ const std::optional<Rect>& clipBounds,
711+ Matrix* imageMatrix);
663712
664- std::shared_ptr<Image> getPassThroughContentImage (
665- const DrawArgs& args, Canvas* canvas, const std::optional<Rect>& clipBounds,
666- const std::vector<LayerStyleExtraSourceType>& extraSourceTypes, Matrix* imageMatrix);
713+ std::shared_ptr<Image> getPassThroughContentImage (const DrawArgs& args, Canvas* canvas,
714+ const std::optional<Rect>& clipBounds,
715+ Matrix* imageMatrix);
667716
668717 std::optional<Rect> computeContentBounds (const std::optional<Rect>& clipBounds,
669718 bool excludeEffects);
670719
671- /* *
672- * Returns the equivalent transformation matrix adapted for a custom anchor point.
673- * The matrix is defined based on a local coordinate system, with the transformation anchor point
674- * being the origin of that coordinate system. This function returns an affine transformation
675- * matrix that produces the same visual effect when using any point within this coordinate system
676- * as the new origin and anchor point.
677- * @param matrix The original transformation matrix.
678- * @param anchor The specified anchor point.
679- */
680- Matrix3D anchorAdaptedMatrix (const Matrix3D& matrix, const Point& anchor) const ;
720+ bool canPreserve3D () const ;
681721
682722 void invalidateSubtree ();
683723
@@ -703,6 +743,7 @@ class Layer : public std::enable_shared_from_this<Layer> {
703743 float _alpha = 1 .0f ;
704744 // The actual transformation matrix that determines the geometric position of the layer
705745 Matrix3D _matrix3D = {};
746+ bool _preserve3D = false ;
706747 std::shared_ptr<Layer> _mask = nullptr ;
707748 Layer* maskOwner = nullptr ;
708749 std::unique_ptr<Rect> _scrollRect = nullptr ;
0 commit comments