赞
踩
ANativeWindow_fromSurface(env, jsurface); //step1 创建SkSurface SkImageInfo image_info = SkImageInfo::Make(width,height,target_corlor_type, target_alpha_type, SkColorSpace::MakeSRGB()); sk_sp<SkSurface> backing_store = SkSurface::MakeRaster(image_info); //step2 在上层使用SkCanvas绘制完成后,提取像素点到ANativeWindow_Buffer, SkPixmap pixmap; cacking_store->peekPixels(&pixmap); ANativeWindow_Buffer native_buffer; ANativeWindow_lock(native_window->handle(), &native_buffer, nullptr); SkImageInfo native_image_info = SkImageInfo::Make(native_buffer.width, native_buffer.height, color_type, alpha_type); std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(native_image_info, native_buffer.bits, native_buffer.stride * SkColorTypeBytesPerPixel(color_type)); SkBitmap bitmap; bitmap.installPixels(pixmap); //使用canvs将bitmap数据绘制到native_buffer(native_buffer已经在上一步设置到canvas) canvas->drawImageRect( bitmap.asImage(), SkRect::MakeIWH(native_buffer.width, native_buffer.height), SkSamplingOptions()); //step3 使用ANativeWindow_unlockAndPost发送图像数据 ANativeWindow_unlockAndPost(native_window_->handle());
//
EGLSurface surface = eglCreateWindowSurface(display, config_,reinterpret_cast<EGLNativeWindowType>(window->handle()),attribs);
onscreen_surface_->MakeCurrent();
onscreen_surface_->SwapBuffers(present_info.frame_damage);
Android:SurfaceView、
TextInputChannel
MethodChannel创建
channel = new MethodChannel(dartExecutor, "flutter/textinput", JSONMethodCodec.INSTANCE);
在Flutter框架下,输入框由Dart实现,而输入法由系统实现,当点击输入框时,弹出系统输入法,点击系统键盘,输入的相关字符在输入框中展示,点击其他区域收起系统键盘。这样的一个交互,需要输入框告知系统将键盘展示或隐藏,而输入字符时,需要将相关字符发送给输入框,让其展示出来。同时,点击键盘方向键也可以控制光标位置,所以,也需要将键盘的相关事件传递给输入框处理。
输入法弹出会占用屏幕空间,FlutterView(继承自SurfaceView)会接收到此事件,即Android系统通知SurfaceView尺寸大小发生变化,回调SurfaceView.onSizeChanged方法。在FlutterView接收到此事件后,由JNI层传递给Flutter引擎,再通知到Flutter窗口系统进行调整。
BaseInputConnection(Android系统输入法连接类)
InputConnectionAdapter extends BaseInputConnection
接收Fluter View相关事件
将系统输入法事件传递给Flutter View处理
PlatformConfiguration
PlatformConfigurationNativeApi是Dart与C++的桥,获取到PlatformConfiguration对象,再取得其PlatformConfigurationClient对象调用ScheduleFrame()方法。
void PlatformConfigurationNativeApi::ScheduleFrame() {
UIDartState::ThrowIfUIOperationsProhibited();
UIDartState::Current()->platform_configuration()->client()->ScheduleFrame();
}
RuntimeController
// |PlatformConfigurationClient|
void RuntimeController::ScheduleFrame() {
client_.ScheduleFrame();
}
Engine
Shell
Shell与Engine关系,Shell提供引擎的初始化参数,
void Engine::HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) {
if (message->channel() == kAssetChannel) {
HandleAssetPlatformMessage(std::move(message));
} else {
delegate_.OnEngineHandlePlatformMessage(std::move(message));
}
}
类似Java调用C++,需要在Dart层声明,c++层注册,Java使用的是JNI,Dart使用的是FFI(Foregin Function Interfaces)。
//dart声明后直接可调用 @FfiNative<Void Function()>('PlatformConfigurationNativeApi::ScheduleFrame') external static void _scheduleFrame(); //dart_ui.cc //注册的还有Canvas、PictureRecorder、SceneBuilder、Paragraph、Patht等 V(PlatformConfigurationNativeApi::ScheduleFrame, 0) \ V(PlatformConfigurationNativeApi::Render, 1) \ V(PlatformConfigurationNativeApi::SendPlatformMessage, 3) \ V(PlatformConfigurationNativeApi::RespondToPlatformMessage, 2) \ void* ResolveFfiNativeFunction(const char* name, uintptr_t args) { auto it = g_function_dispatchers.find(name); return (it != g_function_dispatchers.end()) ? it->second : nullptr; } // Set up FFI Native resolver for dart:ui. 手动调用注入 Dart_Handle result = Dart_SetFfiNativeResolver(dart_ui, ResolveFfiNativeFunction);
C++调用Dart与C++调用Java类似,需要有一个返回获取到Dart方法的步骤
//lib/ui/hooks.dart @pragma('vm:entry-point') void _beginFrame(int microseconds, int frameNumber) { PlatformDispatcher.instance._beginFrame(microseconds); PlatformDispatcher.instance._updateFrameData(frameNumber); } @pragma('vm:entry-point') void _drawFrame() { PlatformDispatcher.instance._drawFrame(); } //platform_configuration.cc tonic::DartPersistentValue begin_frame_; tonic::DartPersistentValue draw_frame_; //绑定 Dart_Handle library = Dart_LookupLibrary(tonic::ToDart("dart:ui")); begin_frame_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_beginFrame"))); draw_frame_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_drawFrame"))); //调用 tonic::DartInvoke(begin_frame_.Get(), { Dart_NewInteger(microseconds), Dart_NewInteger(frame_number),})); tonic::DartInvokeVoid(draw_frame_.Get());
Native主动发消息给Dart核心代码时调用dart:ui库的_dispatchPlatformMessage方法,将数据传递给Dart层。
MessageChannel
DartExecutor(FlutterEngine创建了DartExecutor对象)
DartMessenger
DartMessenger.send()
DispatchPlatformMessage
//注册FFi
Dart_Handle library = Dart_LookupLibrary(tonic::ToDart("dart:ui"));
tonic::DartPersistentValue dispatch_platform_message_;
dispatch_platform_message_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_dispatchPlatformMessage")));
//发送到Dart
std::shared_ptr<tonic::DartState> dart_state = dispatch_platform_message_.dart_state().lock();
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle = (message->hasData()) ? ToByteData(message->data()) : Dart_Null();
auto response = message->response();
int response_id = next_response_id_++;
tonic::DartInvoke(dispatch_platform_message_.Get(), {tonic::ToDart(message->channel()), data_handle, tonic::ToDart(response_id)}));
通过FFI接口,调用PlatformConfigurationNativeApi::SendPlatformMessage()向Native发送消息
PlatformConfigurationNativeApi::SendPlatformMessage
PlatformConfigurationNativeApi::HandlePlatformMessage
RuntimeController::HandlePlatformMessage
Engine::HandlePlatformMessage
Shell::OnEngineHandlePlatformMessage
PlatformMessageHandler::HandlePlatformMessage
FlutterJNI::handlePlatformMessage
Surface类只用来创建一个SurfaceFrame对象,SurfaceFrame对象中需要持有SkSurface对象。
class SurfaceFrame {
bool Submit();
sk_sp<SkSurface> SkiaSurface() const;
}
// Surface主要创建一个SurfaceFrame对象,SurfaceFrame对象持有SkSurface,可供上层绘制使用
class Surface {
virtual std::unique_ptr<SurfaceFrame> AcquireFrame(const SkISize& size) = 0;
}
class GPUSurfaceSoftwareDelegate {
// Called when the GPU surface needs a new buffer to render a new frame into.
virtual sk_sp<SkSurface> AcquireBackingStore(const SkISize& size) = 0;
// Called by the platform when a frame has been rendered into the backing store and the platform must display it on-screen.
virtual bool PresentBackingStore(sk_sp<SkSurface> backing_store) = 0;
}
系统创建SkSurface对象类似
SkImageInfo image_info = SkImageInfo::Make(size.fWidth, size.fHeight, target_color_type_, target_alpha_type_, SkColorSpace::MakeSRGB());
sk_surface_ = SkSurface::MakeRaster(image_info);
//创建SkSurface对象 GrGLenum format = kUnknown_SkColorType; const SkColorType color_type = FirstSupportedColorType(context, &format); sk_sp<SkColorSpace> colorspace = SkColorSpace::MakeSRGB(); SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry); GrGLFramebufferInfo framebuffer_info = {}; framebuffer_info.fFBOID = static_cast<GrGLuint>(fbo); framebuffer_info.fFormat = format; GrBackendRenderTarget render_target(size.width(), // width size.height(), // height 0, // sample count 0, // stencil bits framebuffer_info // framebuffer info ); // context为GrDirectContext return SkSurface::MakeFromBackendRenderTarget( context, // Gr context render_target, // render target GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin, // origin color_type, // color type colorspace, // colorspace &surface_props // surface properties );
OpenGL环境初始化
//OpenGL环境初始化 EGLint w, h, dummy; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); eglChooseConfig(display, attribs, &config, 1, &numConfigs); //创建与系统窗口的绑定 surface = eglCreateWindowSurface(display, config, win, NULL); context = eglCreateContext(display, config, NULL, NULL); eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); //设置当前绘图环境,将context和surface绑定到当前线程 eglMakeCurrent(display_, onscreen_surface_, onscreen_surface_, onscreen_context_); EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); //提交数据 eglSwapBuffers(mDisplay, mSurface);
Surface创建过程
由Native层PlatformView主动触发创建,由PlatformView根据配置信息创建Surface。
PlatformView::NotifyCreated(){
std::unique_ptr<Surface> surface = platform_view->CreateRenderingSurface();
//delegate_为Shell
delegate_.OnPlatformViewCreated(std::move(surface));
}
// |PlatformView::Delegate|
void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
rasterizer->Setup(std::move(surface));
}
todo
1、 jni是如何在动态库加载
2、消息通信实现机制
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。