flutter texture实现原理1

原理1
原理2

以下基于flutter-1.17源码分析

java层面获取SurfaceTexture

FlutterRenderer.java
  @Override
  public SurfaceTextureEntry createSurfaceTexture() {
    ···
    final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
    surfaceTexture.detachFromGLContext();
    final SurfaceTextureRegistryEntry entry =
        new SurfaceTextureRegistryEntry(nextTextureId.getAndIncrement(), surfaceTexture);
    Log.v(TAG, "New SurfaceTexture ID: " + entry.id());
    registerTexture(entry.id(), surfaceTexture);
    return entry;
  }

关注注册流程

  FlutterRenderer.java
  //注册流程
  private void registerTexture(long textureId, @NonNull SurfaceTexture surfaceTexture) {
    flutterJNI.registerTexture(textureId, surfaceTexture);
  }
  FlutterJNI.java
  private native void nativeRegisterTexture(
      long nativePlatformViewId, long textureId, @NonNull SurfaceTexture surfaceTexture);
  }
// 解注册流程
private void unregisterTexture(long textureId) {
    flutterJNI.unregisterTexture(textureId);
  }

到了native方法

platform_view_android_jni_impl.cc
static void RegisterTexture(JNIEnv* env,
                            jobject jcaller,
                            jlong shell_holder,
                            jlong texture_id,
                            jobject surface_texture) {
  ANDROID_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(
      static_cast(texture_id),                        //
      fml::jni::JavaObjectWeakGlobalRef(env, surface_texture)  //
  );
}
platform_view_android.cc
void PlatformViewAndroid::RegisterExternalTexture(
    int64_t texture_id,
    const fml::jni::JavaObjectWeakGlobalRef& surface_texture) {
  RegisterTexture(std::make_shared(
      texture_id, surface_texture, std::move(jni_facade_)));
}

texture.cc
void TextureRegistry::RegisterTexture(std::shared_ptr texture) {
  if (!texture) {
    return;
  }
  mapping_[texture->Id()] = texture;
}

native将texture存储到了texture文件中的mapping中

flutter 侧处理

视线转移到textureLayer渲染中

texture.cc
void TextureLayer::Paint(PaintContext& context) const {
  TRACE_EVENT0("flutter", "TextureLayer::Paint");
  std::shared_ptr texture =
      context.texture_registry.GetTexture(texture_id_);
  if (!texture) {
    TRACE_EVENT_INSTANT0("flutter", "null texture");
    return;
  }
  texture->Paint(*context.leaf_nodes_canvas, paint_bounds(), freeze_,
                 context.gr_context, filter_quality_);
}

我们看到了关键方法 Paint,实际执行的类是AndroidExternalTextureGL

android_external_texture_gl.cc
AndroidExternalTextureGL::AndroidExternalTextureGL(
    int64_t id,
    const fml::jni::JavaObjectWeakGlobalRef& surface_texture,
    std::shared_ptr jni_facade)
    : Texture(id),
      jni_facade_(jni_facade),
      surface_texture_(surface_texture),
      transform(SkMatrix::I()) {}
void AndroidExternalTextureGL::Paint(SkCanvas& canvas,
                                     const SkRect& bounds,
                                     bool freeze,
                                     GrDirectContext* context,
                                     SkFilterQuality filter_quality) {
  if (state_ == AttachmentState::detached) {
    return;
  }
  if (state_ == AttachmentState::uninitialized) {
    glGenTextures(1, &texture_name_);  //创建纹理
    Attach(static_cast(texture_name_));  //调用attchcontext
    state_ = AttachmentState::attached;
  }
  if (!freeze && new_frame_ready_) {
    Update();//调用updateTexImage
    new_frame_ready_ = false;
  }
  GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_,
                                 GL_RGBA8_OES};
  GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo);
  sk_sp image = SkImage::MakeFromTexture(
      canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin,
      kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
  if (image) {
    SkAutoCanvasRestore autoRestore(&canvas, true);
    canvas.translate(bounds.x(), bounds.y());
    canvas.scale(bounds.width(), bounds.height());
    if (!transform.isIdentity()) {
      SkMatrix transformAroundCenter(transform);

      transformAroundCenter.preTranslate(-0.5, -0.5);
      transformAroundCenter.postScale(1, -1);
      transformAroundCenter.postTranslate(0.5, 0.5);
      canvas.concat(transformAroundCenter);
    }
    SkPaint paint;
    paint.setFilterQuality(filter_quality);
    canvas.drawImage(image, 0, 0, &paint);
  }
}

Paint大致流程将:
1,创建纹理
2,将glContext绑定到SurfaceTexture上
3,更新纹理使用
4,获取SkImage
5,将SkImage渲染到给定的canvas上

参考:
https://cloud.tencent.com/developer/news/323655
http://gityuan.com/2019/06/16/flutter_gpu_draw/

你可能感兴趣的:(flutter texture实现原理1)