以下基于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<int64_t>(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<AndroidExternalTextureGL>(
texture_id, surface_texture, std::move(jni_facade_)));
}
texture.cc
void TextureRegistry::RegisterTexture(std::shared_ptr<Texture> 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> 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<PlatformViewAndroidJNI> 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<jint>(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<SkImage> 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/
网友评论