提交 c457ec63 编写于 作者: J Jason Simmons 提交者: GitHub

AndroidSurfaceSoftware renderer based on NDK native window APIs (#3745)

上级 2e74a6ba
......@@ -16,7 +16,26 @@
namespace shell {
AndroidSurfaceSoftware::AndroidSurfaceSoftware() : AndroidSurface() {}
namespace {
bool GetSkColorType(int32_t buffer_format, SkColorType* color_type) {
switch (buffer_format) {
case WINDOW_FORMAT_RGB_565:
*color_type = kRGB_565_SkColorType;
return true;
case WINDOW_FORMAT_RGBA_8888:
*color_type = kRGBA_8888_SkColorType;
return true;
default:
return false;
}
}
} // anonymous namespace
AndroidSurfaceSoftware::AndroidSurfaceSoftware()
: AndroidSurface(),
target_color_type_(kRGBA_8888_SkColorType) {}
AndroidSurfaceSoftware::~AndroidSurfaceSoftware() = default;
......@@ -56,8 +75,11 @@ sk_sp<SkSurface> AndroidSurfaceSoftware::AcquireBackingStore(
return sk_surface_;
}
sk_surface_ = SkSurface::MakeRasterN32Premul(
size.fWidth, size.fHeight, nullptr /* SkSurfaceProps as out */);
SkImageInfo image_info = SkImageInfo::Make(
size.fWidth, size.fHeight, target_color_type_, kPremul_SkAlphaType);
sk_surface_ = SkSurface::MakeRaster(image_info);
return sk_surface_;
}
......@@ -73,24 +95,33 @@ bool AndroidSurfaceSoftware::PresentBackingStore(
return false;
}
// Some basic sanity checking.
uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4;
if (expected_pixmap_data_size != pixmap.getSize64()) {
ANativeWindow_Buffer native_buffer;
if (ANativeWindow_lock(native_window_->handle(), &native_buffer, nullptr)) {
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()));
SkColorType color_type;
if (GetSkColorType(native_buffer.format, &color_type)) {
SkImageInfo native_image_info = SkImageInfo::Make(
native_buffer.width, native_buffer.height, color_type, kPremul_SkAlphaType);
std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(
native_image_info,
native_buffer.bits,
native_buffer.stride * SkColorTypeBytesPerPixel(color_type));
if (canvas) {
SkBitmap bitmap;
if (bitmap.installPixels(pixmap)) {
canvas->drawBitmapRect(
bitmap,
SkRect::MakeIWH(native_buffer.width, native_buffer.height),
nullptr);
}
}
}
FlutterViewUpdateSoftwareBuffer(env, flutter_view_.get(env).obj(),
direct_buffer.obj(), pixmap.width(),
pixmap.height());
ANativeWindow_unlockAndPost(native_window_->handle());
return true;
}
......@@ -108,6 +139,14 @@ bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const {
bool AndroidSurfaceSoftware::SetNativeWindow(
ftl::RefPtr<AndroidNativeWindow> window,
PlatformView::SurfaceConfig config) {
native_window_ = std::move(window);
if (!(native_window_ && native_window_->IsValid()))
return false;
int32_t window_format = ANativeWindow_getFormat(native_window_->handle());
if (window_format < 0)
return false;
if (!GetSkColorType(window_format, &target_color_type_))
return false;
return true;
}
......
......@@ -47,6 +47,9 @@ class AndroidSurfaceSoftware : public AndroidSurface,
fml::jni::JavaObjectWeakGlobalRef flutter_view_;
ftl::RefPtr<AndroidNativeWindow> native_window_;
SkColorType target_color_type_;
FTL_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceSoftware);
};
......
......@@ -204,18 +204,6 @@ public class FlutterView extends SurfaceView
return super.onKeyDown(keyCode, event);
}
// This method will be called on the GPU Thread.
public void updateSoftwareBuffer(ByteBuffer buffer, int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
Canvas canvas = getHolder().lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bitmap, new Matrix(), null);
getHolder().unlockCanvasAndPost(canvas);
}
}
public void addActivityLifecycleListener(ActivityLifecycleListener listener) {
mActivityLifecycleListeners.add(listener);
}
......
......@@ -49,17 +49,6 @@ void FlutterViewUpdateSemantics(JNIEnv* env,
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
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
......@@ -350,13 +339,6 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
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;
}
......
......@@ -27,12 +27,6 @@ void FlutterViewUpdateSemantics(JNIEnv* env,
jobject buffer,
jobjectArray strings);
void FlutterViewUpdateSoftwareBuffer(JNIEnv* env,
jobject obj,
jobject buffer,
jint width,
jint height);
} // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册