3flutter_surface

RenderSurface类设计图解

classDiagram

class FlutterSurfaceView {
-FlutterRenderer flutterRenderer
-SurfaceHolder_Callback surfaceCallback
}

class FlutterTextureView {
  -FlutterRenderer flutterRenderer;
  -Surface renderSurface;
}

class FlutterImageView {
-FlutterRenderer flutterRenderer;
-ImageReader imageReader
}

TextureView<|--FlutterTextureView
RenderSurface<|--FlutterTextureView

SurfaceView<|--FlutterSurfaceView
RenderSurface<|--FlutterSurfaceView

View<|--FlutterImageView
RenderSurface<|--FlutterImageView

class FlutterView
classDiagram
class AndroidSurface {
+SetNativeWindow(AndroidNativeWindow)
}
class AndroidSurfaceGL {
  fml::RefPtr<AndroidNativeWindow> native_window_;
  std::unique_ptr<AndroidEGLSurface> onscreen_surface_;
  std::unique_ptr<AndroidEGLSurface> offscreen_surface_;
}

GPUSurfaceSoftwareDelegate<|--AndroidSurfaceSoftware
AndroidSurface<|--AndroidSurfaceSoftware
AndroidSurface<|--AndroidSurfaceGL
GPUSurfaceGLDelegate<|--AndroidSurfaceGL
AndroidSurface<|--AndroidSurfaceVulkan
GPUSurfaceVulkanDelegate<|--AndroidSurfaceVulkan

class GPUSurfaceGL {
GPUSurfaceGLDelegate* delegate_
sk_sp<SkSurface> onscreen_surface_
}
Surface<|--GPUSurfaceGL

class AndroidEGLSurface {
  const EGLSurface surface_;
  const EGLDisplay display_;
  const EGLContext context_;
  bool SwapBuffers();
}

Flutter通过Surface自绘图解

graph LR
subgraph Platform

Surface
end

Surface-->|flutterRenderer.startRenderingToSurface|Rasterizer'sSurface

subgraph Native

Rasterizer'sSurface

end

subgraph Flutter

Rasterizer::DrawToSurface

end

Rasterizer::DrawToSurface-->|post and draw to|Rasterizer'sSurface
public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseCursorViewDelegate {

    // Internal view hierarchy references.
  @Nullable private FlutterSurfaceView flutterSurfaceView;
  @Nullable private FlutterTextureView flutterTextureView;
  @Nullable private FlutterImageView flutterImageView;
  @Nullable private RenderSurface renderSurface;
  @Nullable private RenderSurface previousRenderSurface;
  private final Set<FlutterUiDisplayListener> flutterUiDisplayListeners = new HashSet<>();
  private boolean isFlutterUiDisplayed;

  // Connections to a Flutter execution context.
  @Nullable private FlutterEngine flutterEngine;
  
}
  public FlutterView(@NonNull Context context, @NonNull FlutterSurfaceView flutterSurfaceView) {
    this(context, null, flutterSurfaceView);
  }

  public FlutterView(@NonNull Context context, @NonNull FlutterTextureView flutterTextureView) {
    this(context, null, flutterTextureView);
  }

  public FlutterView(@NonNull Context context, @NonNull FlutterImageView flutterImageView) {
    this(context, null, flutterImageView);
  }
  private FlutterSurfaceView(//FlutterTextureView和FlutterImageView构造方法类似
      @NonNull Context context, @Nullable AttributeSet attrs, boolean renderTransparently) {
    super(context, attrs);
    this.renderTransparently = renderTransparently;
    init();
  }
  private void init() {
    Log.v(TAG, "Initializing FlutterView");

    if (flutterSurfaceView != null) {
      Log.v(TAG, "Internally using a FlutterSurfaceView.");
      addView(flutterSurfaceView);
    } else if (flutterTextureView != null) {
      Log.v(TAG, "Internally using a FlutterTextureView.");
      addView(flutterTextureView);
    } else {
      Log.v(TAG, "Internally using a FlutterImageView.");
      addView(flutterImageView);
    }

    // FlutterView needs to be focusable so that the InputMethodManager can interact with it.
    setFocusable(true);
    setFocusableInTouchMode(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS);
    }
  }

Platform surface配置到native层

flutterImageView

  /**
   * Invoked by the owner of this {@code FlutterImageView} when it wants to begin rendering a
   * Flutter UI to this {@code FlutterImageView}.
   */
  @Override
  public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
    switch (kind) {
      case background:
        flutterRenderer.swapSurface(imageReader.getSurface());//main
        break;
      case overlay:
        // Do nothing since the attachment is done by the handler of
        // `FlutterJNI#createOverlaySurface()` in the native side.
        break;
    }
    setAlpha(1.0f);
    this.flutterRenderer = flutterRenderer;
    isAttachedToFlutterRenderer = true;
  }

flutterRenderer.swapSurface

  /**
   * Swaps the {@link Surface} used to render the current frame.
   *
   * <p>In hybrid composition, the root surfaces changes from {@link
   * android.view.SurfaceHolder#getSurface()} to {@link android.media.ImageReader#getSurface()} when
   * a platform view is in the current frame.
   */
  public void swapSurface(@NonNull Surface surface) {
    this.surface = surface;
    flutterJNI.onSurfaceWindowChanged(surface);
  }

flutterJNI.onSurfaceWindowChanged

  @UiThread
  public void onSurfaceWindowChanged(@NonNull Surface surface) {
    ensureRunningOnMainThread();
    ensureAttachedToNative();
    nativeSurfaceWindowChanged(nativeShellHolderId, surface);
  }

flutterSurfaceView

getHolder().addCallback

  private void init() {
    // If transparency is desired then we'll enable a transparent pixel format and place
    // our Window above everything else to get transparent background rendering.
    if (renderTransparently) {
      getHolder().setFormat(PixelFormat.TRANSPARENT);
      setZOrderOnTop(true);
    }

    // Grab a reference to our underlying Surface and register callbacks with that Surface so we
    // can monitor changes and forward those changes on to native Flutter code.
    getHolder().addCallback(surfaceCallback);

    // Keep this SurfaceView transparent until Flutter has a frame ready to render. This avoids
    // displaying a black rectangle in our place.
    setAlpha(0.0f);
  }
// Connects the {@code Surface} beneath this {@code SurfaceView} with Flutter's native code.
  // Callbacks are received by this Object and then those messages are forwarded to our
  // FlutterRenderer, and then on to the JNI bridge over to native Flutter code.
  private final SurfaceHolder.Callback surfaceCallback =
      new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(@NonNull SurfaceHolder holder) {
          isSurfaceAvailableForRendering = true;

          if (isAttachedToFlutterRenderer) {
            connectSurfaceToRenderer();
          }
        }

        @Override
        public void surfaceChanged(
            @NonNull SurfaceHolder holder, int format, int width, int height) {
          if (isAttachedToFlutterRenderer) {
            changeSurfaceSize(width, height);
          }
        }

        @Override
        public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
          isSurfaceAvailableForRendering = false;

          if (isAttachedToFlutterRenderer) {
            disconnectSurfaceFromRenderer();
          }
        }
      };

attachToRenderer

/**
   * Invoked by the owner of this {@code FlutterSurfaceView} when it wants to begin rendering a
   * Flutter UI to this {@code FlutterSurfaceView}.
   *
   * <p>If an Android {@link android.view.Surface} is available, this method will give that {@link
   * android.view.Surface} to the given {@link FlutterRenderer} to begin rendering Flutter's UI to
   * this {@code FlutterSurfaceView}.
   *
   * <p>If no Android {@link android.view.Surface} is available yet, this {@code FlutterSurfaceView}
   * will wait until a {@link android.view.Surface} becomes available and then give that {@link
   * android.view.Surface} to the given {@link FlutterRenderer} to begin rendering Flutter's UI to
   * this {@code FlutterSurfaceView}.
   */  
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
    Log.v(TAG, "Attaching to FlutterRenderer.");
    if (this.flutterRenderer != null) {
      Log.v(
          TAG,
          "Already connected to a FlutterRenderer. Detaching from old one and attaching to new one.");
      this.flutterRenderer.stopRenderingToSurface();
      this.flutterRenderer.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);
    }

    this.flutterRenderer = flutterRenderer;
    isAttachedToFlutterRenderer = true;

    this.flutterRenderer.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);

    // If we're already attached to an Android window then we're now attached to both a renderer
    // and the Android window. We can begin rendering now.
    if (isSurfaceAvailableForRendering) {
      Log.v(TAG,"Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
      connectSurfaceToRenderer();
    }
  }

connectSurfaceToRenderer

  // FlutterRenderer and getSurfaceTexture() must both be non-null.
  private void connectSurfaceToRenderer() {
    flutterRenderer.startRenderingToSurface(getHolder().getSurface());
  }

FlutterTextureView

  // Connects the {@code SurfaceTexture} beneath this {@code TextureView} with Flutter's native
  // code.
  // Callbacks are received by this Object and then those messages are forwarded to our
  // FlutterRenderer, and then on to the JNI bridge over to native Flutter code.
  private final SurfaceTextureListener surfaceTextureListener =
      new SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(
            SurfaceTexture surfaceTexture, int width, int height) {
          Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureAvailable()");
          isSurfaceAvailableForRendering = true;

          // If we're already attached to a FlutterRenderer then we're now attached to both a
          // renderer
          // and the Android window, so we can begin rendering now.
          if (isAttachedToFlutterRenderer) {
            connectSurfaceToRenderer();
          }
        }
    
  }

  public FlutterTextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
  }

setSurfaceTextureListener

  private void init() {
    // Listen for when our underlying SurfaceTexture becomes available, changes size, or
    // gets destroyed, and take the appropriate actions.
    setSurfaceTextureListener(surfaceTextureListener);
  }

attachToRenderer

/**
   * Invoked by the owner of this {@code FlutterTextureView} when it wants to begin rendering a
   * Flutter UI to this {@code FlutterTextureView}.
   *
   * <p>If an Android {@link SurfaceTexture} is available, this method will give that {@link
   * SurfaceTexture} to the given {@link FlutterRenderer} to begin rendering Flutter's UI to this
   * {@code FlutterTextureView}.
   *
   * <p>If no Android {@link SurfaceTexture} is available yet, this {@code FlutterTextureView} will
   * wait until a {@link SurfaceTexture} becomes available and then give that {@link SurfaceTexture}
   * to the given {@link FlutterRenderer} to begin rendering Flutter's UI to this {@code
   * FlutterTextureView}.
   */
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
    Log.v(TAG, "Attaching to FlutterRenderer.");
    if (this.flutterRenderer != null) {
      Log.v(
          TAG,
          "Already connected to a FlutterRenderer. Detaching from old one and attaching to new one.");
      this.flutterRenderer.stopRenderingToSurface();
    }

    this.flutterRenderer = flutterRenderer;
    isAttachedToFlutterRenderer = true;

    // If we're already attached to an Android window then we're now attached to both a renderer
    // and the Android window. We can begin rendering now.
    if (isSurfaceAvailableForRendering) {
      Log.v(TAG,"Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
      connectSurfaceToRenderer();
    }
  }

connectSurfaceToRenderer

  // FlutterRenderer and getSurfaceTexture() must both be non-null.
  private void connectSurfaceToRenderer() {
    if (flutterRenderer == null || getSurfaceTexture() == null) {
      throw new IllegalStateException(
          "connectSurfaceToRenderer() should only be called when flutterRenderer and getSurfaceTexture() are non-null.");
    }

    renderSurface = new Surface(getSurfaceTexture());
    flutterRenderer.startRenderingToSurface(renderSurface);
  }
    /**
     * Create Surface from a {@link SurfaceTexture}.
     *
     * Images drawn to the Surface will be made available to the {@link
     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
     * SurfaceTexture#updateTexImage}.
     *
     * Please note that holding onto the Surface created here is not enough to
     * keep the provided SurfaceTexture from being reclaimed.  In that sense,
     * the Surface will act like a
     * {@link java.lang.ref.WeakReference weak reference} to the SurfaceTexture.
     *
     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
     * Surface.
     * @throws OutOfResourcesException if the surface could not be created.
     */
    public Surface(SurfaceTexture surfaceTexture) {
        if (surfaceTexture == null) {
            throw new IllegalArgumentException("surfaceTexture must not be null");
        }
        mIsSingleBuffered = surfaceTexture.isSingleBuffered();
        synchronized (mLock) {
            mName = surfaceTexture.toString();
            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
        }
    }

flutterRenderer.startRenderingToSurface

/**
 * Represents the rendering responsibilities of a {@code FlutterEngine}.
 *
 * <p>{@code FlutterRenderer} works in tandem with a provided {@link RenderSurface} to paint Flutter
 * pixels to an Android {@code View} hierarchy.
 *
 * <p>{@code FlutterRenderer} manages textures for rendering, and forwards some Java calls to native
 * Flutter code via JNI. The corresponding {@link RenderSurface} provides the Android {@link
 * Surface} that this renderer paints.
 *
 * <p>{@link io.flutter.embedding.android.FlutterSurfaceView} and {@link
 * io.flutter.embedding.android.FlutterTextureView} are implementations of {@link RenderSurface}.
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class FlutterRenderer implements TextureRegistry {
    @NonNull private final FlutterJNI flutterJNI;
  public void startRenderingToSurface(@NonNull Surface surface) {
    if (this.surface != null) {
      stopRenderingToSurface();
    }

    this.surface = surface;

    flutterJNI.onSurfaceCreated(surface);
  }

flutterJNI.onSurfaceCreated

  /**
   * Call this method when a {@link Surface} has been created onto which you would like Flutter to
   * paint.
   *
   * <p>See {@link android.view.SurfaceHolder.Callback#surfaceCreated(SurfaceHolder)} for an example
   * of where this call might originate.
   */
  @UiThread
  public void onSurfaceCreated(@NonNull Surface surface) {
    ensureRunningOnMainThread();
    ensureAttachedToNative();
    nativeSurfaceCreated(nativeShellHolderId, surface);
  }
  private native void nativeSurfaceCreated(long nativeShellHolderId, @NonNull Surface surface);

nativeSurfaceCreated

shell/platform/android/platform_view_android_jni_impl.cc

static void SurfaceCreated(JNIEnv* env,
                           jobject jcaller,
                           jlong shell_holder,
                           jobject jsurface) {
  // Note: This frame ensures that any local references used by
  // ANativeWindow_fromSurface are released immediately. This is needed as a
  // workaround for https://code.google.com/p/android/issues/detail?id=68174
  fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
  auto window = fml::MakeRefCounted<AndroidNativeWindow>(
      ANativeWindow_fromSurface(env, jsurface));
  ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));//main
}

ANativeWindow_fromSurface

frameworks/base/native/android/native_window_jni.cpp

ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) {
    sp<ANativeWindow> win = android_view_Surface_getNativeWindow(env, surface);
    if (win != NULL) {
        win->incStrong((void*)ANativeWindow_fromSurface);
    }
    return win.get();
}

frameworks/base/core/jni/android_view_Surface.cpp

sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
    return android_view_Surface_getSurface(env, surfaceObj);
}

sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
    sp<Surface> sur;
    jobject lock = env->GetObjectField(surfaceObj,
            gSurfaceClassInfo.mLock);
    if (env->MonitorEnter(lock) == JNI_OK) {
        sur = reinterpret_cast<Surface *>(
                env->GetLongField(surfaceObj, gSurfaceClassInfo.mNativeObject));
        env->MonitorExit(lock);
    }
    env->DeleteLocalRef(lock);
    return sur;
}
static struct {
    jclass clazz;
    jfieldID mNativeObject;//对应java对象Surface的long mNativeObject成员变量
    jfieldID mLock;
    jmethodID ctor;
} gSurfaceClassInfo;

shell/platform/android/platform_view_android.cc

PlatformViewAndroid::NotifyCreated

void PlatformViewAndroid::NotifyCreated(
    fml::RefPtr<AndroidNativeWindow> native_window) {
  if (android_surface_) {
    InstallFirstFrameCallback();

    fml::AutoResetWaitableEvent latch;
    fml::TaskRunner::RunNowOrPostTask(
        task_runners_.GetRasterTaskRunner(),
        [&latch, surface = android_surface_.get(),
         native_window = std::move(native_window)]() {
          surface->SetNativeWindow(native_window);
          latch.Signal();
        });
    latch.Wait();
  }

  PlatformView::NotifyCreated();
}
AndroidSurfaceGL::SetNativeWindow
bool AndroidSurfaceGL::SetNativeWindow(
    fml::RefPtr<AndroidNativeWindow> window) {
  FML_DCHECK(IsValid());
  FML_DCHECK(window);
  native_window_ = window;
  // Ensure the destructor is called since it destroys the `EGLSurface` before
  // creating a new onscreen surface.
  onscreen_surface_ = nullptr;
  // Create the onscreen surface.
  onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(window);
  if (!onscreen_surface_->IsValid()) {
    return false;
  }
  return true;
}
AndroidContextGL::CreateOnscreenSurface
std::unique_ptr<AndroidEGLSurface> AndroidContextGL::CreateOnscreenSurface(
    fml::RefPtr<AndroidNativeWindow> window) const {
  EGLDisplay display = environment_->Display();

  const EGLint attribs[] = {EGL_NONE};

  EGLSurface surface = eglCreateWindowSurface(
      display, config_, reinterpret_cast<EGLNativeWindowType>(window->handle()),
      attribs);
  return std::make_unique<AndroidEGLSurface>(surface, display, context_);
}
PlatformView::NotifyCreated
void PlatformView::NotifyCreated() {
  std::unique_ptr<Surface> surface;

  // Threading: We want to use the platform view on the non-platform thread.
  // Using the weak pointer is illegal. But, we are going to introduce a latch
  // so that the platform view is not collected till the surface is obtained.
  auto* platform_view = this;
  fml::ManualResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(
      task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() {
        surface = platform_view->CreateRenderingSurface();
        if (surface && !surface->IsValid()) {
          surface.reset();
        }
        latch.Signal();
      });
  latch.Wait();
  if (!surface) {
    FML_LOG(ERROR) << "Failed to create platform view rendering surface";
    return;
  }
  delegate_.OnPlatformViewCreated(std::move(surface));//main
}
// |PlatformView::Delegate|
void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
  
    auto raster_task =
      fml::MakeCopyable([&waiting_for_first_frame = waiting_for_first_frame_,
                         rasterizer = rasterizer_->GetWeakPtr(),  //
                         surface = std::move(surface),            //
                         &latch]() mutable {
        if (rasterizer) {
          // Enables the thread merger which may be used by the external view
          // embedder.
          rasterizer->EnableThreadMergerIfNeeded();
          rasterizer->Setup(std::move(surface));
        }
      }
Rasterizer::Setup
void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
  surface_ = std::move(surface);

绘制到surface上

Render

//lib/ui/window/platform_configuration.cc
void Render(Dart_NativeArguments args) {
  Scene* scene =
      tonic::DartConverter<Scene*>::FromArguments(args, 1, exception);
  UIDartState::Current()->platform_configuration()->client()->Render(scene);//main
}

//runtime/runtime_controller.cc
// |PlatformConfigurationClient|
void RuntimeController::Render(Scene* scene) {
  client_.Render(scene->takeLayerTree());
}

//shell/common/engine.cc
void Engine::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
  animator_->Render(std::move(layer_tree));
}

//shell/common/animator.cc
void Animator::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
  delegate_.OnAnimatorDraw(layer_tree_pipeline_,
                           std::move(frame_timings_recorder_));
}

GetRasterTaskRunner()->PostTask

//shell/common/shell.cc
// |Animator::Delegate|
void Shell::OnAnimatorDraw(
    fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
    std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
  
    task_runners_.GetRasterTaskRunner()->PostTask(fml::MakeCopyable(//放置任务到rasterTaskRunner
      [&waiting_for_first_frame = waiting_for_first_frame_,
       &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
       rasterizer = rasterizer_->GetWeakPtr(), pipeline = std::move(pipeline),
       discard_callback = std::move(discard_callback),
       frame_timings_recorder = std::move(frame_timings_recorder)]() mutable {
        if (rasterizer) {
          rasterizer->Draw(std::move(frame_timings_recorder), pipeline,//main
                           std::move(discard_callback));

          if (waiting_for_first_frame.load()) {
            waiting_for_first_frame.store(false);
            waiting_for_first_frame_condition.notify_all();
          }
        }
      }));
}
//shell/common/rasterizer.cc
void Rasterizer::Draw(
    std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
    fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
    LayerTreeDiscardCallback discardCallback) {
  
    RasterStatus raster_status = RasterStatus::kFailed;
  Pipeline<flutter::LayerTree>::Consumer consumer =
      [&](std::unique_ptr<LayerTree> layer_tree) {
        if (discardCallback(*layer_tree.get())) {
          raster_status = RasterStatus::kDiscarded;
        } else {
          raster_status =
              DoDraw(std::move(frame_timings_recorder), std::move(layer_tree));//main
        }
      };

  PipelineConsumeResult consume_result = pipeline->Consume(consumer);
  
}
RasterStatus Rasterizer::DoDraw(
    std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
    std::unique_ptr<flutter::LayerTree> layer_tree) {
  
    RasterStatus raster_status =
      DrawToSurface(frame_timings_recorder->GetBuildDuration(), *layer_tree);

Rasterizer::DrawToSurface

RasterStatus Rasterizer::DrawToSurface(
    const fml::TimeDelta frame_build_duration,
    flutter::LayerTree& layer_tree) {
  
  SkCanvas* embedder_root_canvas = nullptr;
  if (external_view_embedder_) {
    external_view_embedder_->BeginFrame(
        layer_tree.frame_size(), surface_->GetContext(),
        layer_tree.device_pixel_ratio(), raster_thread_merger_);
    embedder_root_canvas = external_view_embedder_->GetRootCanvas();
  }
  
   auto frame = surface_->AcquireFrame(layer_tree.frame_size());
  
    if (compositor_frame) {
     RasterStatus raster_status = compositor_frame->Raster(layer_tree, false);//main
      
      
     frame->Submit();//main
    }
  
}
//shell/platform/android/external_view_embedder/external_view_embedder.cc
// |ExternalViewEmbedder|
SkCanvas* AndroidExternalViewEmbedder::GetRootCanvas() {
  // On Android, the root surface is created from the on-screen render target.
  return nullptr;
}

surface_->AcquireFrame

// |Surface|
std::unique_ptr<SurfaceFrame> GPUSurfaceGL::AcquireFrame(const SkISize& size) {
  if (delegate_ == nullptr) {
    return nullptr;
  }
  auto context_switch = delegate_->GLContextMakeCurrent();
  const auto root_surface_transformation = GetRootTransformation();

  sk_sp<SkSurface> surface = AcquireRenderSurface(size, root_surface_transformation);
  
  surface->getCanvas()->setMatrix(root_surface_transformation);
  SurfaceFrame::SubmitCallback submit_callback =
      [weak = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
                                          SkCanvas* canvas) {
        return weak ? weak->PresentSurface(canvas) : false;
      };

  return std::make_unique<SurfaceFrame>(
      surface, delegate_->SurfaceSupportsReadback(), submit_callback,
      std::move(context_switch));
sk_sp<SkSurface> GPUSurfaceGL::AcquireRenderSurface(
    const SkISize& untransformed_size,
    const SkMatrix& root_surface_transformation) {

  if (!CreateOrUpdateSurfaces(transformed_size)) {
    return nullptr;
  }

  return onscreen_surface_;
}
bool GPUSurfaceGL::CreateOrUpdateSurfaces(const SkISize& size) {
  sk_sp<SkSurface> onscreen_surface;
  GLFrameInfo frame_info = {static_cast<uint32_t>(size.width()),
                            static_cast<uint32_t>(size.height())};
  const uint32_t fbo_id = delegate_->GLContextFBO(frame_info);
  onscreen_surface = WrapOnscreenSurface(context_.get(),  // GL context
                                         size,            // root surface size
                                         fbo_id           // window FBO ID
  );
  onscreen_surface_ = std::move(onscreen_surface);
  fbo_id_ = fbo_id;
  return true;
}

compositor_frame->Raster

layer_tree.Paint
//flow/compositor_context.cc
RasterStatus CompositorContext::ScopedFrame::Raster(
    flutter::LayerTree& layer_tree,
    bool ignore_raster_cache) {
  layer_tree.Paint(*this, ignore_raster_cache);
}
void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
                      bool ignore_raster_cache) const {
    if (root_layer_->needs_painting(context)) {
    root_layer_->Paint(context);//main
  }
}
void ContainerLayer::Paint(PaintContext& context) const {
  FML_DCHECK(needs_painting(context));

  PaintChildren(context);
}

//下面的两个Paint相关方法会递归进行调用,直到进入PhysicalShapeLayerg或PictureLayer等具体的child layer
void ContainerLayer::PaintChildren(PaintContext& context) const {
  // We can no longer call FML_DCHECK here on the needs_painting(context)
  // condition as that test is only valid for the PaintContext that
  // is initially handed to a layer's Paint() method. By the time the
  // layer calls PaintChildren(), though, it may have modified the
  // PaintContext so the test doesn't work in this "context".

  // Intentionally not tracing here as there should be no self-time
  // and the trace event on this common function has a small overhead.
  for (auto& layer : layers_) {
    if (layer->needs_painting(context)) {
      layer->Paint(context);
    }
  }
}

void TransformLayer::Paint(PaintContext& context) const {
  SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
  context.internal_nodes_canvas->concat(transform_);

  PaintChildren(context);
}
void PhysicalShapeLayer::Paint(PaintContext& context) const {
  // Call drawPath without clip if possible for better performance.
  SkPaint paint;
  paint.setColor(color_);
  paint.setAntiAlias(true);
  if (clip_behavior_ != Clip::antiAliasWithSaveLayer) {
    context.leaf_nodes_canvas->drawPath(path_, paint);//main
  }
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
    TRACE_EVENT0("skia", TRACE_FUNC);
    this->onDrawPath(path, paint);
}

void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    AutoLayerForImageFilter layer(this, paint, &pathBounds);
    this->topDevice()->drawPath(path, layer.paint());
}

void SkGpuDevice::drawPath(const SkPath& origSrcPath, const SkPaint& paint, bool pathIsMutable) {
    if (!paint.getMaskFilter()) {
        fSurfaceDrawContext->drawPath(this->clip(), std::move(grPaint),
                                      fSurfaceDrawContext->chooseAA(paint), this->localToDevice(),
                                      origSrcPath, GrStyle(paint));
        return;
    }
}

void GrSurfaceDrawContext::drawPath(const GrClip* clip,
                                    GrPaint&& paint,
                                    GrAA aa,
                                    const SkMatrix& viewMatrix,
                                    const SkPath& path,
                                    const GrStyle& style) {
    GrStyledShape shape(path, style, DoSimplify::kNo);
    this->drawShape(clip, std::move(paint), aa, viewMatrix, std::move(shape));
}

void GrSurfaceDrawContext::drawShape(const GrClip* clip,
                                     GrPaint&& paint,
                                     GrAA aa,
                                     const SkMatrix& viewMatrix,
                                     GrStyledShape&& shape) {
    // If we get here in drawShape(), we definitely need to use path rendering
    this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, std::move(shape),
                                     /* attemptDrawSimple */ true);
}
addDrawOp
#通过这里后续的条用堆栈可以看出,draw过程在native层也是添加drawOperation进行绘制命令的配置
GrOpsTask::OpChain::appendOp(std::__1::unique_ptr<GrOp, std::__1::default_delete<GrOp> >, GrProcessorSet::Analysis, GrXferProcessor::DstProxyView const*, GrAppliedClip const*, GrCaps const&, SkArenaAlloc*, GrAuditTrail*) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrOpsTask.cpp:335)

GrOpsTask::recordOp(std::__1::unique_ptr<GrOp, std::__1::default_delete<GrOp> >, GrProcessorSet::Analysis, GrAppliedClip*, GrXferProcessor::DstProxyView const*, GrCaps const&) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrOpsTask.cpp:988)

GrOpsTask::addDrawOp(GrDrawingManager*, std::__1::unique_ptr<GrOp, std::__1::default_delete<GrOp> >, GrDrawOp::FixedFunctionFlags, GrProcessorSet::Analysis const&, GrAppliedClip&&, GrXferProcessor::DstProxyView const&, GrTextureResolveManager, GrCaps const&) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrOpsTask.cpp:434)

GrSurfaceDrawContext::addDrawOp(GrClip const*, std::__1::unique_ptr<GrOp, std::__1::default_delete<GrOp> >, std::__1::function<void (GrOp*, unsigned int)> const&) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:1972)

GrSurfaceDrawContext::drawFilledQuad(GrClip const*, GrPaint&&, GrAA, DrawQuad*, GrUserStencilSettings const*) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:646)

GrSurfaceDrawContext::fillRectToRect(GrClip const*, GrPaint&&, GrAA, SkMatrix const&, SkRect const&, SkRect const&) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:836)

GrSurfaceDrawContext::drawRect(GrClip const*, GrPaint&&, GrAA, SkMatrix const&, SkRect const&, GrStyle const*) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:761)

GrSurfaceDrawContext::drawSimpleShape(GrClip const*, GrPaint*, GrAA, SkMatrix const&, GrStyledShape const&) (/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:1729)

GrSurfaceDrawContext::drawShapeUsingPathRenderer(GrClip const*, GrPaint&&, GrAA, SkMatrix const&, GrStyledShape&&, bool)
(/Users/qianpianpian/git/flutter/fork/engine/src/third_party/skia/src/gpu/GrSurfaceDrawContext.cpp:1814)

frame->Submit

bool SurfaceFrame::Submit() {
  submitted_ = PerformSubmit();//main
  return submitted_;
}

bool SurfaceFrame::PerformSubmit() {
  if (submit_callback_(*this, SkiaCanvas())) {//submit_callback_为前面acquireFrame时配置的submit_callback
    return true;
  }
  return false;
}
  SurfaceFrame::SubmitCallback submit_callback =
      [weak = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
                                          SkCanvas* canvas) {
        return weak ? weak->PresentSurface(canvas) : false;//main
      };
bool GPUSurfaceGL::PresentSurface(SkCanvas* canvas) {
    onscreen_surface_->getCanvas()->flush();
  }

void SkCanvas::flush() {
    this->onFlush();
}

void SkCanvas::onFlush() {
#if SK_SUPPORT_GPU
    auto dContext = GrAsDirectContext(this->recordingContext());

    if (dContext) {
        dContext->flushAndSubmit();//main
    }
#endif
}
    /** engine/src/third_party/skia/include/gpu/GrDirectContext.h
    
     * Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D
     * API. This is equivalent to calling GrContext::flush with a default GrFlushInfo followed by
     * GrContext::submit(syncCpu).
     */
    void flushAndSubmit(bool syncCpu = false) {
        this->flush(GrFlushInfo());
        this->submit(syncCpu);
    }
flush
///engine/src/third_party/skia/src/gpu/GrDirectContext.cpp
GrSemaphoresSubmitted GrDirectContext::flush(const GrFlushInfo& info) {
    return this->drawingManager()->flushSurfaces({}, SkSurface::BackendSurfaceAccess::kNoAccess,
                                                 info, nullptr);
}
submit
bool GrDirectContext::submit(bool syncCpu) {
    if (!fGpu) {
        return false;
    }
    return fGpu->submitToGpu(syncCpu);
}