提交 796259c0 编写于 作者: G Gary Qian 提交者: GitHub

Allow switching to the software rendering backend on Android. (#3719)

* Enable software rendering backend on android. Add "enable-software-rendering" flag.

* Fix variable naming and threading.
上级 9e0eaa15
...@@ -26,6 +26,7 @@ struct Settings { ...@@ -26,6 +26,7 @@ struct Settings {
bool enable_dart_profiling = false; bool enable_dart_profiling = false;
bool use_test_fonts = false; bool use_test_fonts = false;
bool dart_non_checked_mode = false; bool dart_non_checked_mode = false;
bool enable_software_rendering = false;
std::string aot_snapshot_path; std::string aot_snapshot_path;
std::string aot_vm_snapshot_data_filename; std::string aot_vm_snapshot_data_filename;
std::string aot_vm_snapshot_instr_filename; std::string aot_vm_snapshot_instr_filename;
......
...@@ -136,8 +136,7 @@ void Shell::InitStandalone(ftl::CommandLine command_line, ...@@ -136,8 +136,7 @@ void Shell::InitStandalone(ftl::CommandLine command_line,
} }
} }
settings.ipv6 = settings.ipv6 = command_line.HasOption(FlagForSwitch(Switch::IPv6));
command_line.HasOption(FlagForSwitch(Switch::IPv6));
settings.start_paused = settings.start_paused =
command_line.HasOption(FlagForSwitch(Switch::StartPaused)); command_line.HasOption(FlagForSwitch(Switch::StartPaused));
...@@ -145,6 +144,9 @@ void Shell::InitStandalone(ftl::CommandLine command_line, ...@@ -145,6 +144,9 @@ void Shell::InitStandalone(ftl::CommandLine command_line,
settings.enable_dart_profiling = settings.enable_dart_profiling =
command_line.HasOption(FlagForSwitch(Switch::EnableDartProfiling)); command_line.HasOption(FlagForSwitch(Switch::EnableDartProfiling));
settings.enable_software_rendering =
command_line.HasOption(FlagForSwitch(Switch::EnableSoftwareRendering));
settings.endless_trace_buffer = settings.endless_trace_buffer =
command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer)); command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer));
......
...@@ -58,6 +58,11 @@ DEF_SWITCH(EndlessTraceBuffer, ...@@ -58,6 +58,11 @@ DEF_SWITCH(EndlessTraceBuffer,
"This is useful when very old events need to viewed. For example, " "This is useful when very old events need to viewed. For example, "
"during application launch. Memory usage will continue to grow " "during application launch. Memory usage will continue to grow "
"indefinitely however.") "indefinitely however.")
DEF_SWITCH(EnableSoftwareRendering,
"enable-software-rendering",
"Enable rendering using the Skia software backend. This is useful"
"when testing Flutter on emulators. By default, Flutter will"
"attempt to either use OpenGL or Vulkan.")
DEF_SWITCH(FLX, "flx", "Specify the the FLX path.") DEF_SWITCH(FLX, "flx", "Specify the the FLX path.")
DEF_SWITCH(Help, "help", "Display this help text.") DEF_SWITCH(Help, "help", "Display this help text.")
DEF_SWITCH(LogTag, "log-tag", "Tag associated with log messages.") DEF_SWITCH(LogTag, "log-tag", "Tag associated with log messages.")
......
...@@ -23,6 +23,8 @@ shared_library("flutter_shell_native") { ...@@ -23,6 +23,8 @@ shared_library("flutter_shell_native") {
"android_surface.h", "android_surface.h",
"android_surface_gl.cc", "android_surface_gl.cc",
"android_surface_gl.h", "android_surface_gl.h",
"android_surface_software.h",
"android_surface_software.cc",
"flutter_main.cc", "flutter_main.cc",
"flutter_main.h", "flutter_main.h",
"library_loader.cc", "library_loader.cc",
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <memory> #include <memory>
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/shell/common/platform_view.h" #include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/surface.h" #include "flutter/shell/common/surface.h"
#include "flutter/shell/platform/android/android_native_window.h" #include "flutter/shell/platform/android/android_native_window.h"
...@@ -33,6 +35,9 @@ class AndroidSurface { ...@@ -33,6 +35,9 @@ class AndroidSurface {
virtual bool SetNativeWindow(ftl::RefPtr<AndroidNativeWindow> window, virtual bool SetNativeWindow(ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config = {}) = 0; PlatformView::SurfaceConfig config = {}) = 0;
virtual void SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) = 0;
}; };
} // namespace shell } // namespace shell
......
...@@ -149,4 +149,7 @@ intptr_t AndroidSurfaceGL::GLContextFBO() const { ...@@ -149,4 +149,7 @@ intptr_t AndroidSurfaceGL::GLContextFBO() const {
return 0; return 0;
} }
void AndroidSurfaceGL::SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) {}
} // namespace shell } // namespace shell
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_GL_H_ #ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_GL_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_GL_H_ #define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_GL_H_
#include <jni.h>
#include <memory> #include <memory>
#include "flutter/shell/gpu/gpu_surface_gl.h" #include "flutter/shell/gpu/gpu_surface_gl.h"
...@@ -46,6 +47,9 @@ class AndroidSurfaceGL : public GPUSurfaceGLDelegate, public AndroidSurface { ...@@ -46,6 +47,9 @@ class AndroidSurfaceGL : public GPUSurfaceGLDelegate, public AndroidSurface {
intptr_t GLContextFBO() const override; intptr_t GLContextFBO() const override;
void SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) override;
private: private:
ftl::RefPtr<AndroidContextGL> onscreen_context_; ftl::RefPtr<AndroidContextGL> onscreen_context_;
ftl::RefPtr<AndroidContextGL> offscreen_context_; ftl::RefPtr<AndroidContextGL> offscreen_context_;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/android/android_surface_software.h"
#include "flutter/common/threads.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include <memory>
#include <vector>
#include "flutter/fml/trace_event.h"
#include "lib/ftl/logging.h"
namespace shell {
AndroidSurfaceSoftware::AndroidSurfaceSoftware() : AndroidSurface() {}
AndroidSurfaceSoftware::~AndroidSurfaceSoftware() = default;
bool AndroidSurfaceSoftware::IsValid() const {
return true;
}
bool AndroidSurfaceSoftware::ResourceContextMakeCurrent() {
// Resource Context always not available on software backend.
return false;
}
std::unique_ptr<Surface> AndroidSurfaceSoftware::CreateGPUSurface() {
if (!IsValid()) {
return nullptr;
}
auto surface = std::make_unique<GPUSurfaceSoftware>(this);
if (!surface->IsValid()) {
return nullptr;
}
return surface;
}
sk_sp<SkSurface> AndroidSurfaceSoftware::AcquireBackingStore(
const SkISize& size) {
TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::AcquireBackingStore");
if (!IsValid()) {
return nullptr;
}
if (sk_surface_ != nullptr &&
SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
// The old and new surface sizes are the same. Nothing to do here.
return sk_surface_;
}
sk_surface_ = SkSurface::MakeRasterN32Premul(
size.fWidth, size.fHeight, nullptr /* SkSurfaceProps as out */);
return sk_surface_;
}
bool AndroidSurfaceSoftware::PresentBackingStore(
sk_sp<SkSurface> backing_store) {
TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::PresentBackingStore");
if (!IsValid() || backing_store == nullptr) {
return false;
}
SkPixmap pixmap;
if (!backing_store->peekPixels(&pixmap)) {
return false;
}
// Some basic sanity checking.
uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4;
if (expected_pixmap_data_size != pixmap.getSize64()) {
return false;
}
// Pass the sk_surface buffer to the android FlutterView.
JNIEnv* env = fml::jni::AttachCurrentThread();
// Buffer will be copied into a Bitmap Java-side.
fml::jni::ScopedJavaLocalRef<jobject> direct_buffer(
env,
env->NewDirectByteBuffer(pixmap.writable_addr(), pixmap.getSize64()));
FlutterViewUpdateSoftwareBuffer(env, flutter_view_.get(env).obj(),
direct_buffer.obj(), pixmap.width(),
pixmap.height());
return true;
}
void AndroidSurfaceSoftware::TeardownOnScreenContext() {}
SkISize AndroidSurfaceSoftware::OnScreenSurfaceSize() const {
return SkISize();
}
bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const {
return true;
}
bool AndroidSurfaceSoftware::SetNativeWindow(
ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config) {
return true;
}
void AndroidSurfaceSoftware::SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) {
flutter_view_ = flutter_view;
}
} // namespace shell
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_SOFTWARE_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_SOFTWARE_H_
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/shell/gpu/gpu_surface_software.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "lib/ftl/macros.h"
namespace shell {
class AndroidSurfaceSoftware : public AndroidSurface,
public GPUSurfaceSoftwareDelegate {
public:
AndroidSurfaceSoftware();
~AndroidSurfaceSoftware() override;
bool IsValid() const override;
bool ResourceContextMakeCurrent() override;
std::unique_ptr<Surface> CreateGPUSurface() override;
sk_sp<SkSurface> AcquireBackingStore(const SkISize& size) override;
bool PresentBackingStore(sk_sp<SkSurface> backing_store) override;
void TeardownOnScreenContext() override;
SkISize OnScreenSurfaceSize() const override;
bool OnScreenSurfaceResize(const SkISize& size) const override;
bool SetNativeWindow(ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config) override;
void SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) override;
private:
sk_sp<SkSurface> sk_surface_;
fml::jni::JavaObjectWeakGlobalRef flutter_view_;
FTL_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceSoftware);
};
} // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_SOFTWARE_H_
...@@ -68,6 +68,9 @@ bool AndroidSurfaceVulkan::ResourceContextMakeCurrent() { ...@@ -68,6 +68,9 @@ bool AndroidSurfaceVulkan::ResourceContextMakeCurrent() {
return false; return false;
} }
void AndroidSurfaceVulkan::SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) {}
bool AndroidSurfaceVulkan::SetNativeWindow( bool AndroidSurfaceVulkan::SetNativeWindow(
ftl::RefPtr<AndroidNativeWindow> window, ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config) { PlatformView::SurfaceConfig config) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_VULKAN_H_ #ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_VULKAN_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_VULKAN_H_ #define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_SURFACE_VULKAN_H_
#include <jni.h>
#include <memory> #include <memory>
#include "flutter/shell/platform/android/android_native_window.h" #include "flutter/shell/platform/android/android_native_window.h"
#include "flutter/shell/platform/android/android_surface.h" #include "flutter/shell/platform/android/android_surface.h"
...@@ -34,6 +35,9 @@ class AndroidSurfaceVulkan : public AndroidSurface { ...@@ -34,6 +35,9 @@ class AndroidSurfaceVulkan : public AndroidSurface {
bool SetNativeWindow(ftl::RefPtr<AndroidNativeWindow> window, bool SetNativeWindow(ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config) override; PlatformView::SurfaceConfig config) override;
void SetFlutterView(
const fml::jni::JavaObjectWeakGlobalRef& flutter_view) override;
private: private:
ftl::RefPtr<vulkan::VulkanProcTable> proc_table_; ftl::RefPtr<vulkan::VulkanProcTable> proc_table_;
ftl::RefPtr<AndroidNativeWindow> native_window_; ftl::RefPtr<AndroidNativeWindow> native_window_;
......
...@@ -13,6 +13,9 @@ import android.content.pm.ApplicationInfo; ...@@ -13,6 +13,9 @@ import android.content.pm.ApplicationInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Matrix;
import android.os.Build; import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
...@@ -81,6 +84,9 @@ public class FlutterView extends SurfaceView ...@@ -81,6 +84,9 @@ public class FlutterView extends SurfaceView
private final BroadcastReceiver mDiscoveryReceiver; private final BroadcastReceiver mDiscoveryReceiver;
private final List<ActivityLifecycleListener> mActivityLifecycleListeners; private final List<ActivityLifecycleListener> mActivityLifecycleListeners;
private long mNativePlatformView; private long mNativePlatformView;
private boolean mIsSoftwareRenderingEnabled = false; // using the software renderer or not
private volatile Bitmap mSoftwareRenderingBitmap;
public FlutterView(Context context) { public FlutterView(Context context) {
this(context, null); this(context, null);
...@@ -89,6 +95,8 @@ public class FlutterView extends SurfaceView ...@@ -89,6 +95,8 @@ public class FlutterView extends SurfaceView
public FlutterView(Context context, AttributeSet attrs) { public FlutterView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mIsSoftwareRenderingEnabled = nativeGetIsSoftwareRenderingEnabled();
mMetrics = new ViewportMetrics(); mMetrics = new ViewportMetrics();
mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density; mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
setFocusable(true); setFocusable(true);
...@@ -198,6 +206,21 @@ public class FlutterView extends SurfaceView ...@@ -198,6 +206,21 @@ public class FlutterView extends SurfaceView
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
@Override
protected void onDraw(Canvas canvas) {
if (mSoftwareRenderingBitmap != null) {
canvas.drawBitmap(mSoftwareRenderingBitmap, new Matrix(), new Paint());
}
}
// This method will be called on the GPU Thread.
public void updateSoftwareBuffer(ByteBuffer buffer, int width, int height) {
Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
newBitmap.copyPixelsFromBuffer(buffer);
mSoftwareRenderingBitmap = newBitmap;
postInvalidate();
}
public void addActivityLifecycleListener(ActivityLifecycleListener listener) { public void addActivityLifecycleListener(ActivityLifecycleListener listener) {
mActivityLifecycleListeners.add(listener); mActivityLifecycleListeners.add(listener);
} }
...@@ -593,6 +616,8 @@ public class FlutterView extends SurfaceView ...@@ -593,6 +616,8 @@ public class FlutterView extends SurfaceView
private static native void nativeInvokePlatformMessageEmptyResponseCallback( private static native void nativeInvokePlatformMessageEmptyResponseCallback(
long nativePlatformViewAndroid, int responseId); long nativePlatformViewAndroid, int responseId);
private static native boolean nativeGetIsSoftwareRenderingEnabled();
private void updateViewportMetrics() { private void updateViewportMetrics() {
nativeSetViewportMetrics(mNativePlatformView, nativeSetViewportMetrics(mNativePlatformView,
mMetrics.devicePixelRatio, mMetrics.devicePixelRatio,
...@@ -697,7 +722,11 @@ public class FlutterView extends SurfaceView ...@@ -697,7 +722,11 @@ public class FlutterView extends SurfaceView
} }
private void resetWillNotDraw() { private void resetWillNotDraw() {
setWillNotDraw(!(mAccessibilityEnabled || mTouchExplorationEnabled)); if (!mIsSoftwareRenderingEnabled) {
setWillNotDraw(!(mAccessibilityEnabled || mTouchExplorationEnabled));
} else {
setWillNotDraw(false);
}
} }
@Override @Override
......
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include <utility> #include <utility>
#include "flutter/common/settings.h"
#include "flutter/common/threads.h" #include "flutter/common/threads.h"
#include "flutter/fml/platform/android/jni_util.h" #include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/runtime/dart_service_isolate.h" #include "flutter/runtime/dart_service_isolate.h"
#include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/gpu/gpu_rasterizer.h"
#include "flutter/shell/platform/android/android_surface_gl.h" #include "flutter/shell/platform/android/android_surface_gl.h"
#include "flutter/shell/platform/android/android_surface_software.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h" #include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/vsync_waiter_android.h" #include "flutter/shell/platform/android/vsync_waiter_android.h"
#include "lib/ftl/functional/make_copyable.h" #include "lib/ftl/functional/make_copyable.h"
...@@ -45,13 +47,12 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse { ...@@ -45,13 +47,12 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse {
void CompleteEmpty() override { void CompleteEmpty() override {
ftl::RefPtr<PlatformMessageResponseAndroid> self(this); ftl::RefPtr<PlatformMessageResponseAndroid> self(this);
blink::Threads::Platform()->PostTask( blink::Threads::Platform()->PostTask(ftl::MakeCopyable([self]() mutable {
ftl::MakeCopyable([ self ]() mutable { if (!self->view_)
if (!self->view_) return;
return; static_cast<PlatformViewAndroid*>(self->view_.get())
static_cast<PlatformViewAndroid*>(self->view_.get()) ->HandlePlatformMessageEmptyResponse(self->response_id_);
->HandlePlatformMessageEmptyResponse(self->response_id_); }));
}));
} }
private: private:
...@@ -85,7 +86,19 @@ static std::unique_ptr<AndroidSurface> InitializePlatformSurfaceVulkan() { ...@@ -85,7 +86,19 @@ static std::unique_ptr<AndroidSurface> InitializePlatformSurfaceVulkan() {
#endif // SHELL_ENABLE_VULKAN #endif // SHELL_ENABLE_VULKAN
} }
static std::unique_ptr<AndroidSurface> InitializePlatformSurfaceSoftware() {
auto surface = std::make_unique<AndroidSurfaceSoftware>();
return surface->IsValid() ? std::move(surface) : nullptr;
}
static std::unique_ptr<AndroidSurface> InitializePlatformSurface() { static std::unique_ptr<AndroidSurface> InitializePlatformSurface() {
if (blink::Settings::Get().enable_software_rendering) {
if (auto surface = InitializePlatformSurfaceSoftware()) {
FTL_DLOG(INFO) << "Software surface initialized.";
return surface;
}
}
if (auto surface = InitializePlatformSurfaceVulkan()) { if (auto surface = InitializePlatformSurfaceVulkan()) {
FTL_DLOG(INFO) << "Vulkan surface initialized."; FTL_DLOG(INFO) << "Vulkan surface initialized.";
return surface; return surface;
...@@ -252,8 +265,8 @@ void PlatformViewAndroid::DispatchEmptyPlatformMessage(JNIEnv* env, ...@@ -252,8 +265,8 @@ void PlatformViewAndroid::DispatchEmptyPlatformMessage(JNIEnv* env,
} }
PlatformView::DispatchPlatformMessage( PlatformView::DispatchPlatformMessage(
ftl::MakeRefCounted<blink::PlatformMessage>( ftl::MakeRefCounted<blink::PlatformMessage>(std::move(name),
std::move(name), std::move(response))); std::move(response)));
} }
void PlatformViewAndroid::DispatchPointerDataPacket(JNIEnv* env, void PlatformViewAndroid::DispatchPointerDataPacket(JNIEnv* env,
...@@ -281,9 +294,9 @@ void PlatformViewAndroid::InvokePlatformMessageResponseCallback( ...@@ -281,9 +294,9 @@ void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
if (it == pending_responses_.end()) if (it == pending_responses_.end())
return; return;
uint8_t* response_data = uint8_t* response_data =
static_cast<uint8_t*>(env->GetDirectBufferAddress(java_response_data)); static_cast<uint8_t*>(env->GetDirectBufferAddress(java_response_data));
std::vector<uint8_t> response = std::vector<uint8_t>(response_data, std::vector<uint8_t> response = std::vector<uint8_t>(
response_data + java_response_position); response_data, response_data + java_response_position);
auto message_response = std::move(it->second); auto message_response = std::move(it->second);
pending_responses_.erase(it); pending_responses_.erase(it);
message_response->Complete(std::move(response)); message_response->Complete(std::move(response));
...@@ -316,22 +329,22 @@ void PlatformViewAndroid::HandlePlatformMessage( ...@@ -316,22 +329,22 @@ void PlatformViewAndroid::HandlePlatformMessage(
} }
auto java_channel = fml::jni::StringToJavaString(env, message->channel()); auto java_channel = fml::jni::StringToJavaString(env, message->channel());
if (message->hasData()) { if (message->hasData()) {
fml::jni::ScopedJavaLocalRef<jbyteArray> message_array(env, fml::jni::ScopedJavaLocalRef<jbyteArray> message_array(
env->NewByteArray(message->data().size())); env, env->NewByteArray(message->data().size()));
env->SetByteArrayRegion( env->SetByteArrayRegion(
message_array.obj(), 0, message->data().size(), message_array.obj(), 0, message->data().size(),
reinterpret_cast<const jbyte*>(message->data().data())); reinterpret_cast<const jbyte*>(message->data().data()));
message = nullptr; message = nullptr;
// This call can re-enter in InvokePlatformMessageXxxResponseCallback. // This call can re-enter in InvokePlatformMessageXxxResponseCallback.
FlutterViewHandlePlatformMessage( FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
env, view.obj(), java_channel.obj(), message_array.obj(), response_id); message_array.obj(), response_id);
} else { } else {
message = nullptr; message = nullptr;
// This call can re-enter in InvokePlatformMessageXxxResponseCallback. // This call can re-enter in InvokePlatformMessageXxxResponseCallback.
FlutterViewHandlePlatformMessage( FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
env, view.obj(), java_channel.obj(), nullptr, response_id); nullptr, response_id);
} }
} }
...@@ -344,8 +357,8 @@ void PlatformViewAndroid::HandlePlatformMessageResponse( ...@@ -344,8 +357,8 @@ void PlatformViewAndroid::HandlePlatformMessageResponse(
if (view.is_null()) if (view.is_null())
return; return;
fml::jni::ScopedJavaLocalRef<jbyteArray> data_array(env, fml::jni::ScopedJavaLocalRef<jbyteArray> data_array(
env->NewByteArray(data.size())); env, env->NewByteArray(data.size()));
env->SetByteArrayRegion(data_array.obj(), 0, data.size(), env->SetByteArrayRegion(data_array.obj(), 0, data.size(),
reinterpret_cast<const jbyte*>(data.data())); reinterpret_cast<const jbyte*>(data.data()));
...@@ -353,8 +366,7 @@ void PlatformViewAndroid::HandlePlatformMessageResponse( ...@@ -353,8 +366,7 @@ void PlatformViewAndroid::HandlePlatformMessageResponse(
data_array.obj()); data_array.obj());
} }
void PlatformViewAndroid::HandlePlatformMessageEmptyResponse( void PlatformViewAndroid::HandlePlatformMessageEmptyResponse(int response_id) {
int response_id) {
JNIEnv* env = fml::jni::AttachCurrentThread(); JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env); fml::jni::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
...@@ -433,8 +445,8 @@ void PlatformViewAndroid::UpdateSemantics( ...@@ -433,8 +445,8 @@ void PlatformViewAndroid::UpdateSemantics(
buffer_int32[position++] = child; buffer_int32[position++] = child;
} }
fml::jni::ScopedJavaLocalRef<jobject> direct_buffer(env, fml::jni::ScopedJavaLocalRef<jobject> direct_buffer(
env->NewDirectByteBuffer(buffer.data(), buffer.size())); env, env->NewDirectByteBuffer(buffer.data(), buffer.size()));
FlutterViewUpdateSemantics( FlutterViewUpdateSemantics(
env, view.obj(), direct_buffer.obj(), env, view.obj(), direct_buffer.obj(),
......
...@@ -97,8 +97,10 @@ class PlatformViewAndroid : public PlatformView { ...@@ -97,8 +97,10 @@ class PlatformViewAndroid : public PlatformView {
void set_flutter_view(const fml::jni::JavaObjectWeakGlobalRef& flutter_view) { void set_flutter_view(const fml::jni::JavaObjectWeakGlobalRef& flutter_view) {
flutter_view_ = flutter_view; flutter_view_ = flutter_view;
android_surface_->SetFlutterView(flutter_view);
} }
private: private:
const std::unique_ptr<AndroidSurface> android_surface_; const std::unique_ptr<AndroidSurface> android_surface_;
fml::jni::JavaObjectWeakGlobalRef flutter_view_; fml::jni::JavaObjectWeakGlobalRef flutter_view_;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "flutter/shell/platform/android/platform_view_android_jni.h" #include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/common/settings.h"
#include "flutter/fml/platform/android/jni_util.h" #include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/jni_weak_ref.h" #include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/platform/android/scoped_java_ref.h"
...@@ -48,6 +49,17 @@ void FlutterViewUpdateSemantics(JNIEnv* env, ...@@ -48,6 +49,17 @@ void FlutterViewUpdateSemantics(JNIEnv* env,
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE); FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
} }
static jmethodID g_handle_platform_update_software_buffer = nullptr;
void FlutterViewUpdateSoftwareBuffer(JNIEnv* env,
jobject obj,
jobject buffer,
jint width,
jint height) {
env->CallVoidMethod(obj, g_handle_platform_update_software_buffer, buffer,
width, height);
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
}
// Called By Java // Called By Java
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) { static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
...@@ -179,6 +191,10 @@ static void SetSemanticsEnabled(JNIEnv* env, ...@@ -179,6 +191,10 @@ static void SetSemanticsEnabled(JNIEnv* env,
return PLATFORM_VIEW->SetSemanticsEnabled(enabled); return PLATFORM_VIEW->SetSemanticsEnabled(enabled);
} }
static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) {
return blink::Settings::Get().enable_software_rendering;
}
static void InvokePlatformMessageResponseCallback(JNIEnv* env, static void InvokePlatformMessageResponseCallback(JNIEnv* env,
jobject jcaller, jobject jcaller,
jlong platform_view, jlong platform_view,
...@@ -193,8 +209,8 @@ static void InvokePlatformMessageEmptyResponseCallback(JNIEnv* env, ...@@ -193,8 +209,8 @@ static void InvokePlatformMessageEmptyResponseCallback(JNIEnv* env,
jobject jcaller, jobject jcaller,
jlong platform_view, jlong platform_view,
jint responseId) { jint responseId) {
return PLATFORM_VIEW->InvokePlatformMessageEmptyResponseCallback( return PLATFORM_VIEW->InvokePlatformMessageEmptyResponseCallback(env,
env, responseId); responseId);
} }
bool PlatformViewAndroid::Register(JNIEnv* env) { bool PlatformViewAndroid::Register(JNIEnv* env) {
...@@ -269,7 +285,8 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { ...@@ -269,7 +285,8 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
{ {
.name = "nativeDispatchEmptyPlatformMessage", .name = "nativeDispatchEmptyPlatformMessage",
.signature = "(JLjava/lang/String;I)V", .signature = "(JLjava/lang/String;I)V",
.fnPtr = reinterpret_cast<void*>(&shell::DispatchEmptyPlatformMessage), .fnPtr =
reinterpret_cast<void*>(&shell::DispatchEmptyPlatformMessage),
}, },
{ {
.name = "nativeDispatchPointerDataPacket", .name = "nativeDispatchPointerDataPacket",
...@@ -298,6 +315,11 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { ...@@ -298,6 +315,11 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
.fnPtr = reinterpret_cast<void*>( .fnPtr = reinterpret_cast<void*>(
&shell::InvokePlatformMessageEmptyResponseCallback), &shell::InvokePlatformMessageEmptyResponseCallback),
}, },
{
.name = "nativeGetIsSoftwareRenderingEnabled",
.signature = "()Z",
.fnPtr = reinterpret_cast<void*>(&shell::GetIsSoftwareRendering),
},
}; };
if (env->RegisterNatives(g_flutter_view_class->obj(), methods, if (env->RegisterNatives(g_flutter_view_class->obj(), methods,
...@@ -328,6 +350,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { ...@@ -328,6 +350,13 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
return false; return false;
} }
g_handle_platform_update_software_buffer =
env->GetMethodID(g_flutter_view_class->obj(), "updateSoftwareBuffer",
"(Ljava/nio/ByteBuffer;II)V");
if (g_handle_platform_update_software_buffer == nullptr) {
return false;
}
return true; return true;
} }
......
...@@ -27,6 +27,12 @@ void FlutterViewUpdateSemantics(JNIEnv* env, ...@@ -27,6 +27,12 @@ void FlutterViewUpdateSemantics(JNIEnv* env,
jobject buffer, jobject buffer,
jobjectArray strings); jobjectArray strings);
void FlutterViewUpdateSoftwareBuffer(JNIEnv* env,
jobject obj,
jobject buffer,
jint width,
jint height);
} // namespace shell } // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_ #endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
...@@ -1420,6 +1420,8 @@ FILE: ../../../flutter/lib/ui/painting/vertices.cc ...@@ -1420,6 +1420,8 @@ FILE: ../../../flutter/lib/ui/painting/vertices.cc
FILE: ../../../flutter/lib/ui/painting/vertices.h FILE: ../../../flutter/lib/ui/painting/vertices.h
FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc
FILE: ../../../flutter/shell/gpu/gpu_surface_software.h FILE: ../../../flutter/shell/gpu/gpu_surface_software.h
FILE: ../../../flutter/shell/platform/android/android_surface_software.cc
FILE: ../../../flutter/shell/platform/android/android_surface_software.h
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/EventChannel.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/EventChannel.java
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册