未验证 提交 387ca2ef 编写于 作者: A Amir Hardon 提交者: GitHub

Add an internal_nodes_canvas to PaintContext. (#6728)

When we visit a PlatformViewLayer during the paint traversal it replaces
the PaintContext's canvas with a new one that is painted ontop of the
embedded view.
We need to make sure that operations applied by parent layers are also
applied to the new canvas.

To achieve this we collect all the canvases in a SkNWayCanvas and use
this canvas by non leaf nodes. Leaf nodes still paint only to the "current"
canvas.

This PR moves the overlay canvas creation from the paint phase to the
preroll phase, collects them into a SkNWayCanvas and set it in
PaintContext.

To keep this PR focused, I only used the internal_nodes_canvas in the
tranform_layer.
Will followup with a PR that changes all internal layers to use the
internal_nodes_canvas.
上级 22fc0202
...@@ -16,7 +16,6 @@ class EmbeddedViewParams { ...@@ -16,7 +16,6 @@ class EmbeddedViewParams {
public: public:
SkPoint offsetPixels; SkPoint offsetPixels;
SkSize sizePoints; SkSize sizePoints;
SkISize canvasBaseLayerSize;
}; };
// This is only used on iOS when running in a non headless mode, // This is only used on iOS when running in a non headless mode,
...@@ -26,6 +25,12 @@ class ExternalViewEmbedder { ...@@ -26,6 +25,12 @@ class ExternalViewEmbedder {
public: public:
ExternalViewEmbedder() = default; ExternalViewEmbedder() = default;
virtual void SetFrameSize(SkISize frame_size) = 0;
virtual void PrerollCompositeEmbeddedView(int view_id) = 0;
virtual std::vector<SkCanvas*> GetCurrentCanvases() = 0;
// Must be called on the UI thread. // Must be called on the UI thread.
virtual SkCanvas* CompositeEmbeddedView(int view_id, virtual SkCanvas* CompositeEmbeddedView(int view_id,
const EmbeddedViewParams& params) = 0; const EmbeddedViewParams& params) = 0;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkRRect.h" #include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
...@@ -44,6 +45,7 @@ class ContainerLayer; ...@@ -44,6 +45,7 @@ class ContainerLayer;
struct PrerollContext { struct PrerollContext {
RasterCache* raster_cache; RasterCache* raster_cache;
GrContext* gr_context; GrContext* gr_context;
ExternalViewEmbedder* view_embedder;
SkColorSpace* dst_color_space; SkColorSpace* dst_color_space;
SkRect child_paint_bounds; SkRect child_paint_bounds;
...@@ -64,6 +66,21 @@ class Layer { ...@@ -64,6 +66,21 @@ class Layer {
virtual void Preroll(PrerollContext* context, const SkMatrix& matrix); virtual void Preroll(PrerollContext* context, const SkMatrix& matrix);
struct PaintContext { struct PaintContext {
// When splitting the scene into multiple canvases (e.g when embedding
// a platform view on iOS) during the paint traversal we apply the non leaf
// flow layers to all canvases, and leaf layers just to the "current"
// canvas. Applying the non leaf layers to all canvases ensures that when
// we switch a canvas (when painting a PlatformViewLayer) the next canvas
// has the exact same state as the current canvas.
// The internal_nodes_canvas is a SkNWayCanvas which is used by non leaf
// and applies the operations to all canvases.
// The leaf_nodes_canvas is the "current" canvas and is used by leaf
// layers.
SkCanvas* internal_nodes_canvas;
// I'm temporarily leaving the name of this field to be canvas to reduce
// noise in the incremental change. A followup change will rename this
// and use the corrrect canvas in each callsite.
// TODO(amirh) rename canvas to leaf_nodes_canvas.
SkCanvas* canvas; SkCanvas* canvas;
ExternalViewEmbedder* view_embedder; ExternalViewEmbedder* view_embedder;
const Stopwatch& frame_time; const Stopwatch& frame_time;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "flutter/flow/layers/layer.h" #include "flutter/flow/layers/layer.h"
#include "flutter/fml/trace_event.h" #include "flutter/fml/trace_event.h"
#include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
namespace flow { namespace flow {
...@@ -28,6 +29,7 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, ...@@ -28,6 +29,7 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
PrerollContext context = { PrerollContext context = {
ignore_raster_cache ? nullptr : &frame.context().raster_cache(), ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
frame.gr_context(), frame.gr_context(),
frame.view_embedder(),
color_space, color_space,
SkRect::MakeEmpty(), SkRect::MakeEmpty(),
frame.context().frame_time(), frame.context().frame_time(),
...@@ -66,7 +68,18 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, ...@@ -66,7 +68,18 @@ void LayerTree::UpdateScene(SceneUpdateContext& context,
void LayerTree::Paint(CompositorContext::ScopedFrame& frame, void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
bool ignore_raster_cache) const { bool ignore_raster_cache) const {
TRACE_EVENT0("flutter", "LayerTree::Paint"); TRACE_EVENT0("flutter", "LayerTree::Paint");
SkISize canvas_size = frame.canvas()->getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
internal_nodes_canvas.addCanvas(frame.canvas());
if (frame.view_embedder() != nullptr) {
auto overlay_canvases = frame.view_embedder()->GetCurrentCanvases();
for (size_t i = 0; i < overlay_canvases.size(); i++) {
internal_nodes_canvas.addCanvas(overlay_canvases[i]);
}
}
Layer::PaintContext context = { Layer::PaintContext context = {
(SkCanvas*)&internal_nodes_canvas,
frame.canvas(), frame.canvas(),
frame.view_embedder(), frame.view_embedder(),
frame.context().frame_time(), frame.context().frame_time(),
...@@ -98,6 +111,7 @@ sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) { ...@@ -98,6 +111,7 @@ sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) {
PrerollContext preroll_context{ PrerollContext preroll_context{
nullptr, // raster_cache (don't consult the cache) nullptr, // raster_cache (don't consult the cache)
nullptr, // gr_context (used for the raster cache) nullptr, // gr_context (used for the raster cache)
nullptr, // external view embedder
nullptr, // SkColorSpace* dst_color_space nullptr, // SkColorSpace* dst_color_space
SkRect::MakeEmpty(), // SkRect child_paint_bounds SkRect::MakeEmpty(), // SkRect child_paint_bounds
unused_stopwatch, // frame time (dont care) unused_stopwatch, // frame time (dont care)
...@@ -106,7 +120,12 @@ sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) { ...@@ -106,7 +120,12 @@ sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) {
false, // checkerboard_offscreen_layers false, // checkerboard_offscreen_layers
}; };
SkISize canvas_size = canvas->getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
internal_nodes_canvas.addCanvas(canvas);
Layer::PaintContext paint_context = { Layer::PaintContext paint_context = {
(SkCanvas*)&internal_nodes_canvas,
canvas, // canvas canvas, // canvas
nullptr, nullptr,
unused_stopwatch, // frame time (dont care) unused_stopwatch, // frame time (dont care)
......
...@@ -14,6 +14,13 @@ void PlatformViewLayer::Preroll(PrerollContext* context, ...@@ -14,6 +14,13 @@ void PlatformViewLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) { const SkMatrix& matrix) {
set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(), set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(),
size_.height())); size_.height()));
if (context->view_embedder == nullptr) {
FML_LOG(ERROR) << "Trying to embed a platform view but the PrerollContext "
"does not support embedding";
return;
}
context->view_embedder->PrerollCompositeEmbeddedView(view_id_);
} }
void PlatformViewLayer::Paint(PaintContext& context) const { void PlatformViewLayer::Paint(PaintContext& context) const {
...@@ -27,12 +34,9 @@ void PlatformViewLayer::Paint(PaintContext& context) const { ...@@ -27,12 +34,9 @@ void PlatformViewLayer::Paint(PaintContext& context) const {
params.offsetPixels = params.offsetPixels =
SkPoint::Make(transform.getTranslateX(), transform.getTranslateY()); SkPoint::Make(transform.getTranslateX(), transform.getTranslateY());
params.sizePoints = size_; params.sizePoints = size_;
params.canvasBaseLayerSize = context.canvas->getBaseLayerSize();
SkCanvas* canvas = SkCanvas* canvas =
context.view_embedder->CompositeEmbeddedView(view_id_, params); context.view_embedder->CompositeEmbeddedView(view_id_, params);
// TODO(amirh): copy the full canvas state here
canvas->concat(context.canvas->getTotalMatrix());
context.canvas = canvas; context.canvas = canvas;
} }
} // namespace flow } // namespace flow
...@@ -36,8 +36,8 @@ void TransformLayer::Paint(PaintContext& context) const { ...@@ -36,8 +36,8 @@ void TransformLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "TransformLayer::Paint"); TRACE_EVENT0("flutter", "TransformLayer::Paint");
FML_DCHECK(needs_painting()); FML_DCHECK(needs_painting());
SkAutoCanvasRestore save(context.canvas, true); SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.canvas->concat(transform_); context.internal_nodes_canvas->concat(transform_);
PaintChildren(context); PaintChildren(context);
} }
......
...@@ -156,7 +156,12 @@ void RasterCache::Prepare(PrerollContext* context, ...@@ -156,7 +156,12 @@ void RasterCache::Prepare(PrerollContext* context,
entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space, entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space,
checkerboard_images_, layer->paint_bounds(), checkerboard_images_, layer->paint_bounds(),
[layer, context](SkCanvas* canvas) { [layer, context](SkCanvas* canvas) {
SkISize canvas_size = canvas->getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(
canvas_size.width(), canvas_size.height());
internal_nodes_canvas.addCanvas(canvas);
Layer::PaintContext paintContext = { Layer::PaintContext paintContext = {
(SkCanvas*)&internal_nodes_canvas,
canvas, canvas,
nullptr, nullptr,
context->frame_time, context->frame_time,
......
...@@ -188,6 +188,7 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { ...@@ -188,6 +188,7 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) {
FML_DCHECK(task.surface); FML_DCHECK(task.surface);
SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas();
Layer::PaintContext context = {canvas, Layer::PaintContext context = {canvas,
canvas,
nullptr, nullptr,
frame.context().frame_time(), frame.context().frame_time(),
frame.context().engine_time(), frame.context().engine_time(),
......
...@@ -164,6 +164,11 @@ bool Rasterizer::DrawToSurface(flow::LayerTree& layer_tree) { ...@@ -164,6 +164,11 @@ bool Rasterizer::DrawToSurface(flow::LayerTree& layer_tree) {
auto external_view_embedder = surface_->GetExternalViewEmbedder(); auto external_view_embedder = surface_->GetExternalViewEmbedder();
// TODO(amirh): uncomment this once external_view_embedder is populated.
// if (external_view_embedder != nullptr) {
// external_view_embedder->SetFrameSize(layer_tree.frame_size());
// }
auto compositor_frame = compositor_context_->AcquireFrame( auto compositor_frame = compositor_context_->AcquireFrame(
surface_->GetContext(), canvas, external_view_embedder, surface_->GetContext(), canvas, external_view_embedder,
surface_->GetRootTransformation(), true); surface_->GetRootTransformation(), true);
......
...@@ -128,6 +128,25 @@ void FlutterPlatformViewsController::RegisterViewFactory( ...@@ -128,6 +128,25 @@ void FlutterPlatformViewsController::RegisterViewFactory(
fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>([factory retain]); fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>([factory retain]);
} }
void FlutterPlatformViewsController::SetFrameSize(SkISize frame_size) {
frame_size_ = frame_size;
}
void FlutterPlatformViewsController::PrerollCompositeEmbeddedView(int view_id) {
EnsureOverlayInitialized(view_id);
composition_frames_[view_id] = (overlays_[view_id]->surface->AcquireFrame(frame_size_));
composition_order_.push_back(view_id);
}
std::vector<SkCanvas*> FlutterPlatformViewsController::GetCurrentCanvases() {
std::vector<SkCanvas*> canvases;
for (size_t i = 0; i < composition_order_.size(); i++) {
int64_t view_id = composition_order_[i];
canvases.push_back(composition_frames_[view_id]->SkiaCanvas());
}
return canvases;
}
SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView( SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView(
int view_id, int view_id,
const flow::EmbeddedViewParams& params, const flow::EmbeddedViewParams& params,
...@@ -135,7 +154,6 @@ SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView( ...@@ -135,7 +154,6 @@ SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView(
// TODO(amirh): assert that this is running on the platform thread once we support the iOS // TODO(amirh): assert that this is running on the platform thread once we support the iOS
// embedded views thread configuration. // embedded views thread configuration.
// TODO(amirh): do nothing if the params didn't change. // TODO(amirh): do nothing if the params didn't change.
EnsureOverlayInitialized(view_id);
CGFloat screenScale = [[UIScreen mainScreen] scale]; CGFloat screenScale = [[UIScreen mainScreen] scale];
CGRect rect = CGRect rect =
CGRectMake(params.offsetPixels.x() / screenScale, params.offsetPixels.y() / screenScale, CGRectMake(params.offsetPixels.x() / screenScale, params.offsetPixels.y() / screenScale,
...@@ -143,19 +161,17 @@ SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView( ...@@ -143,19 +161,17 @@ SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView(
UIView* view = views_[view_id].get(); UIView* view = views_[view_id].get();
[view setFrame:rect]; [view setFrame:rect];
composition_order_.push_back(view_id);
composition_frames_.push_back( SkCanvas* canvas = composition_frames_[view_id]->SkiaCanvas();
overlays_[view_id]->surface->AcquireFrame(params.canvasBaseLayerSize));
SkCanvas* canvas = composition_frames_.back()->SkiaCanvas();
canvas->clear(SK_ColorTRANSPARENT); canvas->clear(SK_ColorTRANSPARENT);
return canvas; return canvas;
} }
bool FlutterPlatformViewsController::Present() { bool FlutterPlatformViewsController::Present() {
bool did_submit = true; bool did_submit = true;
for (size_t i = 0; i < composition_frames_.size(); i++) { for (size_t i = 0; i < composition_order_.size(); i++) {
did_submit &= composition_frames_[i]->Submit(); int64_t view_id = composition_order_[i];
did_submit &= composition_frames_[view_id]->Submit();
} }
composition_frames_.clear(); composition_frames_.clear();
if (composition_order_ == active_composition_order_) { if (composition_order_ == active_composition_order_) {
......
...@@ -49,6 +49,12 @@ class FlutterPlatformViewsController { ...@@ -49,6 +49,12 @@ class FlutterPlatformViewsController {
void RegisterViewFactory(NSObject<FlutterPlatformViewFactory>* factory, NSString* factoryId); void RegisterViewFactory(NSObject<FlutterPlatformViewFactory>* factory, NSString* factoryId);
void SetFrameSize(SkISize frame_size);
void PrerollCompositeEmbeddedView(int view_id);
std::vector<SkCanvas*> GetCurrentCanvases();
SkCanvas* CompositeEmbeddedView(int view_id, SkCanvas* CompositeEmbeddedView(int view_id,
const flow::EmbeddedViewParams& params, const flow::EmbeddedViewParams& params,
IOSSurface& surface); IOSSurface& surface);
...@@ -63,6 +69,7 @@ class FlutterPlatformViewsController { ...@@ -63,6 +69,7 @@ class FlutterPlatformViewsController {
std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_; std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_;
std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> views_; std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> views_;
std::map<int64_t, std::unique_ptr<FlutterPlatformViewLayer>> overlays_; std::map<int64_t, std::unique_ptr<FlutterPlatformViewLayer>> overlays_;
SkISize frame_size_;
// A vector of embedded view IDs according to their composition order. // A vector of embedded view IDs according to their composition order.
// The last ID in this vector belond to the that is composited on top of all others. // The last ID in this vector belond to the that is composited on top of all others.
...@@ -71,7 +78,7 @@ class FlutterPlatformViewsController { ...@@ -71,7 +78,7 @@ class FlutterPlatformViewsController {
// The latest composition order that was presented in Present(). // The latest composition order that was presented in Present().
std::vector<int64_t> active_composition_order_; std::vector<int64_t> active_composition_order_;
std::vector<std::unique_ptr<SurfaceFrame>> composition_frames_; std::map<int64_t, std::unique_ptr<SurfaceFrame>> composition_frames_;
void OnCreate(FlutterMethodCall* call, FlutterResult& result); void OnCreate(FlutterMethodCall* call, FlutterResult& result);
void OnDispose(FlutterMethodCall* call, FlutterResult& result); void OnDispose(FlutterMethodCall* call, FlutterResult& result);
......
...@@ -45,6 +45,15 @@ class IOSSurfaceGL : public IOSSurface, ...@@ -45,6 +45,15 @@ class IOSSurfaceGL : public IOSSurface,
// |shell::GPUSurfaceGLDelegate| // |shell::GPUSurfaceGLDelegate|
flow::ExternalViewEmbedder* GetExternalViewEmbedder() override; flow::ExternalViewEmbedder* GetExternalViewEmbedder() override;
// |flow::ExternalViewEmbedder|
void SetFrameSize(SkISize frame_size) override;
// |flow::ExternalViewEmbedder|
void PrerollCompositeEmbeddedView(int view_id) override;
// |flow::ExternalViewEmbedder|
std::vector<SkCanvas*> GetCurrentCanvases() override;
// |flow::ExternalViewEmbedder| // |flow::ExternalViewEmbedder|
SkCanvas* CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override; SkCanvas* CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override;
......
...@@ -74,6 +74,24 @@ flow::ExternalViewEmbedder* IOSSurfaceGL::GetExternalViewEmbedder() { ...@@ -74,6 +74,24 @@ flow::ExternalViewEmbedder* IOSSurfaceGL::GetExternalViewEmbedder() {
} }
} }
void IOSSurfaceGL::SetFrameSize(SkISize frame_size) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
platform_views_controller->SetFrameSize(frame_size);
}
void IOSSurfaceGL::PrerollCompositeEmbeddedView(int view_id) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
platform_views_controller->PrerollCompositeEmbeddedView(view_id);
}
std::vector<SkCanvas*> IOSSurfaceGL::GetCurrentCanvases() {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
return platform_views_controller->GetCurrentCanvases();
}
SkCanvas* IOSSurfaceGL::CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) { SkCanvas* IOSSurfaceGL::CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController(); FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr); FML_CHECK(platform_views_controller != nullptr);
......
...@@ -45,6 +45,15 @@ class IOSSurfaceSoftware final : public IOSSurface, ...@@ -45,6 +45,15 @@ class IOSSurfaceSoftware final : public IOSSurface,
// |shell::GPUSurfaceSoftwareDelegate| // |shell::GPUSurfaceSoftwareDelegate|
flow::ExternalViewEmbedder* GetExternalViewEmbedder() override; flow::ExternalViewEmbedder* GetExternalViewEmbedder() override;
// |flow::ExternalViewEmbedder|
void SetFrameSize(SkISize frame_size) override;
// |flow::ExternalViewEmbedder|
void PrerollCompositeEmbeddedView(int view_id) override;
// |flow::ExternalViewEmbedder|
std::vector<SkCanvas*> GetCurrentCanvases() override;
// |flow::ExternalViewEmbedder| // |flow::ExternalViewEmbedder|
SkCanvas* CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override; SkCanvas* CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override;
......
...@@ -138,6 +138,24 @@ flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() { ...@@ -138,6 +138,24 @@ flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() {
} }
} }
void IOSSurfaceSoftware::SetFrameSize(SkISize frame_size) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
platform_views_controller->SetFrameSize(frame_size);
}
void IOSSurfaceSoftware::PrerollCompositeEmbeddedView(int view_id) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
platform_views_controller->PrerollCompositeEmbeddedView(view_id);
}
std::vector<SkCanvas*> IOSSurfaceSoftware::GetCurrentCanvases() {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
FML_CHECK(platform_views_controller != nullptr);
return platform_views_controller->GetCurrentCanvases();
}
SkCanvas* IOSSurfaceSoftware::CompositeEmbeddedView(int view_id, SkCanvas* IOSSurfaceSoftware::CompositeEmbeddedView(int view_id,
const flow::EmbeddedViewParams& params) { const flow::EmbeddedViewParams& params) {
FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController(); FlutterPlatformViewsController* platform_views_controller = GetPlatformViewsController();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册