[Impeller] Do not call std::forward on the serialized arguments in the canvas recorder (flutter/engine#52307)

std::forward has move semantics and can not safely be called twice on the same arguments.

Also fix CanvasRecorder's resolution of Canvas::Save, which has a default parameter value.
This commit is contained in:
Jason Simmons 2024-04-23 10:24:19 -07:00 committed by GitHub
parent eb75c4337d
commit 10c2ef8b40
2 changed files with 13 additions and 5 deletions

View File

@ -89,7 +89,7 @@ class CanvasRecorder {
-> decltype((std::declval<Canvas>().*
canvasMethod)(std::forward<Args>(args)...)) {
// Serialize each argument
(serializer_.Write(std::forward<Args>(args)), ...);
(serializer_.Write(args), ...);
serializer_.Write(op);
return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
}
@ -110,7 +110,8 @@ class CanvasRecorder {
//////////////////////////////////////////////////////////////////////////////
void Save(uint32_t total_content_depth = Canvas::kMaxDepth) {
return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Save),
void (Canvas::*save_method)(uint32_t) = &Canvas::Save;
return ExecuteAndSerialize(CanvasRecorderOp::kSave, save_method,
total_content_depth);
}

View File

@ -12,7 +12,7 @@ class Serializer {
public:
void Write(CanvasRecorderOp op) { last_op_ = op; }
void Write(const Paint& paint) {}
void Write(const Paint& paint) { last_paint_ = paint; }
void Write(const std::optional<Rect> optional_rect) {}
@ -59,6 +59,7 @@ class Serializer {
void Write(const ContentBoundsPromise& promise) {}
CanvasRecorderOp last_op_;
Paint last_paint_;
};
} // namespace
@ -152,8 +153,11 @@ TEST(CanvasRecorder, DrawPath) {
TEST(CanvasRecorder, DrawPaint) {
CanvasRecorder<Serializer> recorder;
recorder.DrawPaint(Paint());
Paint paint;
paint.color = Color::Red();
recorder.DrawPaint(paint);
ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPaint);
ASSERT_EQ(recorder.GetSerializer().last_paint_.color, paint.color);
}
TEST(CanvasRecorder, DrawLine) {
@ -164,8 +168,11 @@ TEST(CanvasRecorder, DrawLine) {
TEST(CanvasRecorder, DrawRect) {
CanvasRecorder<Serializer> recorder;
recorder.DrawRect(Rect(), Paint());
Paint paint;
paint.color = Color::Blue();
recorder.DrawRect(Rect(), paint);
ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawRect);
ASSERT_EQ(recorder.GetSerializer().last_paint_.color, paint.color);
}
TEST(CanvasRecorder, DrawOval) {