未验证 提交 a48f05f8 编写于 作者: J Jason Simmons 提交者: GitHub

Clarify the relationship between PictureRecorder and Canvas (#19393)

上级 29e256a7
......@@ -3433,6 +3433,8 @@ class Canvas extends NativeFieldWrapperClass2 {
Canvas(PictureRecorder recorder, [ Rect? cullRect ]) : assert(recorder != null) { // ignore: unnecessary_null_comparison
if (recorder.isRecording)
throw ArgumentError('"recorder" must not already be associated with another Canvas.');
_recorder = recorder;
_recorder!._canvas = this;
cullRect ??= Rect.largest;
_constructor(recorder, cullRect.left, cullRect.top, cullRect.right, cullRect.bottom);
}
......@@ -3442,6 +3444,11 @@ class Canvas extends NativeFieldWrapperClass2 {
double right,
double bottom) native 'Canvas_constructor';
// The underlying Skia SkCanvas is owned by the PictureRecorder used to create this Canvas.
// The Canvas holds a reference to the PictureRecorder to prevent the recorder from being
// garbage collected until PictureRecorder.endRecording is called.
PictureRecorder? _recorder;
/// Saves a copy of the current transform and clip on the save stack.
///
/// Call [restore] to pop the save stack.
......@@ -4232,7 +4239,7 @@ class PictureRecorder extends NativeFieldWrapperClass2 {
/// call to [endRecording], and false if either this
/// [PictureRecorder] has not yet been associated with a [Canvas],
/// or the [endRecording] method has already been called.
bool get isRecording native 'PictureRecorder_isRecording';
bool get isRecording => _canvas != null;
/// Finishes recording graphical operations.
///
......@@ -4240,12 +4247,18 @@ class PictureRecorder extends NativeFieldWrapperClass2 {
/// recorded thus far. After calling this function, both the picture recorder
/// and the canvas objects are invalid and cannot be used further.
Picture endRecording() {
if (_canvas == null)
throw StateError('PictureRecorder did not start recording.');
final Picture picture = Picture._();
_endRecording(picture);
_canvas!._recorder = null;
_canvas = null;
return picture;
}
void _endRecording(Picture outPicture) native 'PictureRecorder_endRecording';
Canvas? _canvas;
}
/// A single shadow.
......
......@@ -79,7 +79,6 @@ fml::RefPtr<Canvas> Canvas::Create(PictureRecorder* recorder,
if (!recorder)
Dart_ThrowException(
ToDart("Canvas constructor called with non-genuine PictureRecorder."));
FML_DCHECK(!recorder->isRecording()); // verified by Dart code
fml::RefPtr<Canvas> canvas = fml::MakeRefCounted<Canvas>(
recorder->BeginRecording(SkRect::MakeLTRB(left, top, right, bottom)));
recorder->set_canvas(canvas);
......@@ -432,12 +431,11 @@ void Canvas::drawShadow(const CanvasPath* path,
elevation, transparentOccluder, dpr);
}
void Canvas::Clear() {
void Canvas::Invalidate() {
if (dart_wrapper()) {
ClearDartWrapper();
}
canvas_ = nullptr;
}
bool Canvas::IsRecording() const {
return !!canvas_;
}
} // namespace flutter
......@@ -165,8 +165,7 @@ class Canvas : public RefCountedDartWrappable<Canvas> {
bool transparentOccluder);
SkCanvas* canvas() const { return canvas_; }
void Clear();
bool IsRecording() const;
void Invalidate();
static void RegisterNatives(tonic::DartLibraryNatives* natives);
......
......@@ -20,9 +20,7 @@ static void PictureRecorder_constructor(Dart_NativeArguments args) {
IMPLEMENT_WRAPPERTYPEINFO(ui, PictureRecorder);
#define FOR_EACH_BINDING(V) \
V(PictureRecorder, isRecording) \
V(PictureRecorder, endRecording)
#define FOR_EACH_BINDING(V) V(PictureRecorder, endRecording)
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
......@@ -40,16 +38,12 @@ PictureRecorder::PictureRecorder() {}
PictureRecorder::~PictureRecorder() {}
bool PictureRecorder::isRecording() {
return canvas_ && canvas_->IsRecording();
}
SkCanvas* PictureRecorder::BeginRecording(SkRect bounds) {
return picture_recorder_.beginRecording(bounds, &rtree_factory_);
}
fml::RefPtr<Picture> PictureRecorder::endRecording(Dart_Handle dart_picture) {
if (!isRecording())
if (!canvas_)
return nullptr;
fml::RefPtr<Picture> picture =
......@@ -58,8 +52,7 @@ fml::RefPtr<Picture> PictureRecorder::endRecording(Dart_Handle dart_picture) {
picture_recorder_.finishRecordingAsPicture()),
canvas_->external_allocation_size());
canvas_->Clear();
canvas_->ClearDartWrapper();
canvas_->Invalidate();
canvas_ = nullptr;
ClearDartWrapper();
return picture;
......
......@@ -27,7 +27,6 @@ class PictureRecorder : public RefCountedDartWrappable<PictureRecorder> {
SkCanvas* BeginRecording(SkRect bounds);
fml::RefPtr<Picture> endRecording(Dart_Handle dart_picture);
bool isRecording();
void set_canvas(fml::RefPtr<Canvas> canvas) { canvas_ = std::move(canvas); }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册