Skip to content

Commit bb314ab

Browse files
committed
WIP: Support in <Group /> for saveLayerFlags e.g. SaveLayerInitWithPrevious
1 parent cb611c8 commit bb314ab

File tree

14 files changed

+90
-30
lines changed

14 files changed

+90
-30
lines changed

packages/skia/cpp/api/recorder/JsiRecorder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class JsiRecorder : public JsiSkWrappingSharedPtrHostObject<Recorder> {
184184
}
185185

186186
JSI_HOST_FUNCTION(saveLayer) {
187-
getObject()->saveLayer();
187+
getObject()->saveLayer(runtime, arguments[0].asObject(runtime));
188188
return jsi::Value::undefined();
189189
}
190190

packages/skia/cpp/api/recorder/Paint.h

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include "Convertor.h"
99
#include "DrawingCtx.h"
1010

11+
#include "include/core/SkCanvas.h"
12+
1113
namespace RNSkia {
1214

1315
struct TransformProps {
@@ -38,7 +40,35 @@ SkMatrix processTransform(std::optional<SkMatrix> &matrix,
3840
return m3;
3941
}
4042

41-
struct CTMCmdProps : TransformProps {
43+
struct SaveLayerProps {
44+
std::optional<SkCanvas::SaveLayerFlags> saveLayerFlags;
45+
}
46+
47+
class SaveLayerCmd : public Command {
48+
private:
49+
SaveLayerProps props;
50+
51+
public:
52+
SaveLayerCmd(jsi::Runtime &runtime, const jsi::Object &object,
53+
Variables &variables)
54+
: Command(CommandType::SaveLayer) {
55+
convertProperty(runtime, object, "saveLayerFlags", props.saveLayerFlags,
56+
variables);
57+
}
58+
59+
void saveLayer(DrawingCtx *ctx) {
60+
ctx->materializePaint();
61+
auto paint = ctx->paintDeclarations.back();
62+
ctx->paintDeclarations.pop_back();
63+
64+
SkCanvas::SaveLayerRec layerRec(nullptr, &paint, nullptr,
65+
props.saveLayerFlags.value_or(0));
66+
ctx->canvas->saveLayer(layerRec);
67+
}
68+
}
69+
70+
struct CTMCmdProps : TransformProps,
71+
SaveLayerProps {
4272
std::optional<ClipDef> clip;
4373
std::optional<bool> invertClip;
4474
std::optional<Layer> layer;
@@ -58,12 +88,15 @@ class SaveCTMCmd : public Command {
5888
convertProperty(runtime, object, "clip", props.clip, variables);
5989
convertProperty(runtime, object, "invertClip", props.invertClip, variables);
6090
convertProperty(runtime, object, "layer", props.layer, variables);
91+
convertProperty(runtime, object, "saveLayerFlags", props.saveLayerFlags,
92+
variables);
6193
}
6294

6395
void saveCTM(DrawingCtx *ctx) {
6496
auto clip = props.clip;
6597
auto invertClip = props.invertClip;
6698
auto layer = props.layer;
99+
auto saveLayerFlags = props.saveLayerFlags;
67100
auto hasTransform = props.matrix.has_value() || props.transform.has_value();
68101
auto hasClip = clip.has_value();
69102
auto op = invertClip.has_value() && invertClip.value()
@@ -73,12 +106,12 @@ class SaveCTMCmd : public Command {
73106
SkMatrix m3 = processTransform(props.matrix, props.transform, props.origin);
74107
if (shouldSave) {
75108
if (layer.has_value()) {
76-
if (std::holds_alternative<bool>(layer.value())) {
77-
ctx->canvas->saveLayer(nullptr, nullptr);
78-
} else {
79-
auto paint = std::get<SkPaint>(layer.value());
80-
ctx->canvas->saveLayer(nullptr, &paint);
109+
SkCanvas::SaveLayerRec layerRec;
110+
layerRec.fPaint = std::get_if<SkPaint>(layer.value());
111+
if (saveLayerFlags.has_value()) {
112+
layerRec.fSaveLayerFlags = saveLayerFlags.value();
81113
}
114+
ctx->canvas->saveLayer(layerRec);
82115
} else {
83116
ctx->canvas->save();
84117
}

packages/skia/cpp/api/recorder/RNRecorder.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ class Recorder {
355355
std::make_unique<Command>(CommandType::RestorePaintDeclaration));
356356
}
357357

358-
void saveLayer() {
359-
pushCommand(std::make_unique<Command>(CommandType::SaveLayer));
358+
void saveLayer(jsi::Runtime &runtime, const jsi::Object &props) {
359+
pushCommand(std::make_unique<SaveLayerCmd>(runtime, props, variables));
360360
}
361361

362362
void saveBackdropFilter() {
@@ -418,10 +418,8 @@ inline void Recorder::playCommand(DrawingCtx *ctx, Command *cmd) {
418418
break;
419419
}
420420
case CommandType::SaveLayer: {
421-
ctx->materializePaint();
422-
auto paint = ctx->paintDeclarations.back();
423-
ctx->paintDeclarations.pop_back();
424-
ctx->canvas->saveLayer(SkCanvas::SaveLayerRec(nullptr, &paint, nullptr, 0));
421+
auto *saveCTMCmd = static_cast<SaveCTMCmd *>(cmd);
422+
saveCTMCmd->saveCTM(ctx);
425423
break;
426424
}
427425
case CommandType::MaterializePaint: {

packages/skia/src/dom/types/Common.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
InputMatrix,
77
InputRRect,
88
PaintStyle,
9+
SaveLayerFlag,
910
SkPaint,
1011
SkPath,
1112
SkRect,
@@ -70,7 +71,11 @@ export interface TransformProps {
7071
matrix?: InputMatrix;
7172
}
7273

73-
export interface CTMProps extends TransformProps {
74+
export interface SaveLayerProps {
75+
saveLayerFlags?: SaveLayerFlag;
76+
}
77+
78+
export interface CTMProps extends TransformProps, SaveLayerProps {
7479
clip?: ClipDef;
7580
invertClip?: boolean;
7681
layer?: SkPaint | boolean;

packages/skia/src/renderer/components/Group.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@ export interface PublicGroupProps extends Omit<GroupProps, "layer"> {
88
layer?: GroupProps["layer"] | ChildrenProps["children"];
99
}
1010

11-
export const Group = ({ layer, ...props }: SkiaProps<PublicGroupProps>) => {
11+
export const Group = ({
12+
layer,
13+
saveLayerFlags,
14+
...props
15+
}: SkiaProps<PublicGroupProps>) => {
1216
if (isValidElement(layer) && typeof layer === "object") {
1317
return (
14-
<skLayer>
18+
// keep the saveLayerFlags on whichever node triggers saveLayer
19+
<skLayer saveLayerFlags={saveLayerFlags}>
1520
{layer}
1621
<skGroup {...props} />
1722
</skLayer>
1823
);
1924
}
20-
return <skGroup layer={layer as GroupProps["layer"]} {...props} />;
25+
return (
26+
<skGroup
27+
layer={layer as GroupProps["layer"]}
28+
saveLayerFlags={saveLayerFlags}
29+
{...props}
30+
/>
31+
);
2132
};

packages/skia/src/skia/types/Recorder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type {
2828
VerticesProps,
2929
SkottieProps,
3030
DrawingNodeProps,
31+
SaveLayerProps,
3132
} from "../../dom/types";
3233
import type { AnimatedProps } from "../../renderer/processors/Animations/Animations";
3334

@@ -61,7 +62,7 @@ export interface BaseRecorder {
6162
saveCTM(props: AnimatedProps<CTMProps>): void;
6263
restoreCTM(): void;
6364
drawPaint(): void;
64-
saveLayer(): void;
65+
saveLayer(props: AnimatedProps<SaveLayerProps>): void;
6566
saveBackdropFilter(): void;
6667
drawBox(
6768
boxProps: AnimatedProps<BoxProps>,

packages/skia/src/skia/types/RuntimeEffect/RuntimeEffectFactory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ export interface RuntimeEffectFactory {
99
*/
1010
Make: (sksl: string) => SkRuntimeEffect | null;
1111
//Make(sksl: string, callback?: (err: string) => void): RuntimeEffect | null;
12+
MakeBlender: (sksl: string) => SkRuntimeEffect | null;
1213
}

packages/skia/src/skia/web/JsiSkRuntimeEffectFactory.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,12 @@ export class JsiSkRuntimeEffectFactory
2020
}
2121
return new JsiSkRuntimeEffect(this.CanvasKit, re, sksl);
2222
}
23+
24+
MakeBlender(sksl: string) {
25+
const re = this.CanvasKit.RuntimeEffect.MakeForBlender(sksl);
26+
if (re === null) {
27+
return null;
28+
}
29+
return new JsiSkRuntimeEffect(this.CanvasKit, re, sksl);
30+
}
2331
}

packages/skia/src/sksg/Elements.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ import type {
5353
BlendProps,
5454
SkottieProps,
5555
ImageFilterProps,
56+
SaveLayerProps,
5657
} from "../dom/types";
5758
import type { SkiaProps } from "../renderer";
5859

5960
declare module "react" {
6061
namespace JSX {
6162
interface IntrinsicElements {
6263
skGroup: SkiaProps<GroupProps>;
63-
skLayer: SkiaProps<ChildrenProps>;
64+
skLayer: SkiaProps<ChildrenProps & SaveLayerProps>;
6465
skPaint: SkiaProps<PaintProps>;
6566

6667
// Drawings

packages/skia/src/sksg/Recorder/Core.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type {
2222
AtlasProps,
2323
DrawingNodeProps,
2424
SkottieProps,
25+
SaveLayerProps,
2526
} from "../../dom/types";
2627

2728
export enum CommandType {
@@ -107,6 +108,7 @@ interface Props {
107108
[CommandType.DrawImage]: ImageProps;
108109
[CommandType.DrawCircle]: CircleProps;
109110
[CommandType.SaveCTM]: CTMProps;
111+
[CommandType.SaveLayer]: SaveLayerProps;
110112
[CommandType.SavePaint]: DrawingNodeProps;
111113
[CommandType.PushBlurMaskFilter]: BlurMaskFilterProps;
112114
[CommandType.DrawPoints]: PointsProps;

0 commit comments

Comments
 (0)