提交 44f0c5c9 编写于 作者: A Adam Barth 提交者: GitHub

Remove the startup flash on Android (#3036)

We need to block in the surfaceChanged callback until we can swap the GL
surface with some content in order to avoid flashing transparent and then
black.

Fixes https://github.com/flutter/flutter/issues/5373
上级 7b2aa8f7
......@@ -48,7 +48,7 @@ void RasterizerDirect::Setup(
PlatformView* platform_view,
ftl::Closure continuation,
ftl::AutoResetWaitableEvent* setup_completion_event) {
CHECK(platform_view) << "Must be able to acquire the view.";
FTL_CHECK(platform_view) << "Must be able to acquire the view.";
// The context needs to be made current before the GrGL interface can be
// setup.
......@@ -56,15 +56,16 @@ void RasterizerDirect::Setup(
if (success) {
success = ganesh_canvas_.SetupGrGLInterface();
if (!success)
LOG(ERROR) << "Could not create the GL interface";
FTL_LOG(ERROR) << "Could not create the GL interface";
} else {
LOG(ERROR) << "Could not make the context current for initial GL setup";
FTL_LOG(ERROR) << "Could not make the context current for initial GL setup";
}
if (success) {
platform_view_ = platform_view;
} else {
LOG(ERROR) << "WARNING: Flutter will be unable to render to the display";
FTL_LOG(ERROR)
<< "WARNING: Flutter will be unable to render to the display";
}
continuation();
......@@ -72,6 +73,14 @@ void RasterizerDirect::Setup(
setup_completion_event->Signal();
}
void RasterizerDirect::Clear(SkColor color) {
SkCanvas* canvas = ganesh_canvas_.GetCanvas(
platform_view_->DefaultFramebuffer(), platform_view_->GetSize());
canvas->clear(color);
canvas->flush();
platform_view_->SwapBuffers();
}
// sky::shell::Rasterizer override.
void RasterizerDirect::Teardown(
ftl::AutoResetWaitableEvent* teardown_completion_event) {
......@@ -90,9 +99,8 @@ void RasterizerDirect::Draw(
ftl::RefPtr<flutter::Pipeline<flow::LayerTree>> pipeline) {
TRACE_EVENT0("flutter", "RasterizerDirect::Draw");
if (platform_view_ == nullptr) {
if (!platform_view_)
return;
}
flutter::Pipeline<flow::LayerTree>::Consumer consumer =
std::bind(&RasterizerDirect::DoDraw, this, std::placeholders::_1);
......@@ -107,14 +115,15 @@ void RasterizerDirect::Draw(
weak_this->Draw(pipeline);
}
});
} break;
break;
}
default:
break;
}
}
void RasterizerDirect::DoDraw(std::unique_ptr<flow::LayerTree> layer_tree) {
if (layer_tree == nullptr) {
if (!layer_tree) {
return;
}
......
......@@ -20,22 +20,19 @@ class RasterizerDirect : public Rasterizer {
~RasterizerDirect() override;
// sky::shell::Rasterizer override.
void Setup(PlatformView* platform_view,
ftl::Closure continuation,
ftl::AutoResetWaitableEvent* setup_completion_event) override;
// sky::shell::Rasterizer override.
void Clear(SkColor color) override;
void Teardown(
ftl::AutoResetWaitableEvent* teardown_completion_event) override;
// sky::shell::Rasterizer override.
ftl::WeakPtr<sky::shell::Rasterizer> GetWeakRasterizerPtr() override;
// sky::shell::Rasterizer override.
flow::LayerTree* GetLastLayerTree() override;
// sky::shell::Rasterizer override.
void Draw(ftl::RefPtr<flutter::Pipeline<flow::LayerTree>> pipeline) override;
private:
......
......@@ -17,6 +17,7 @@ import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
......@@ -115,15 +116,25 @@ public class FlutterView extends SurfaceView
attach();
assert mNativePlatformView != 0;
int color = 0xFF000000;
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.colorBackground, typedValue, true);
if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT)
color = typedValue.data;
// TODO(abarth): Consider letting the developer override this color.
final int backgroundColor = color;
mSurfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
public void surfaceCreated(SurfaceHolder holder) {
assert mNativePlatformView != 0;
nativeSurfaceCreated(mNativePlatformView, holder.getSurface());
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
assert mNativePlatformView != 0;
nativeSurfaceCreated(mNativePlatformView, holder.getSurface());
nativeSurfaceChanged(mNativePlatformView, backgroundColor);
}
@Override
......@@ -513,6 +524,7 @@ public class FlutterView extends SurfaceView
private static native void nativeDetach(long nativePlatformViewAndroid);
private static native void nativeSurfaceCreated(long nativePlatformViewAndroid,
Surface surface);
private static native void nativeSurfaceChanged(long nativePlatformViewAndroid, int backgroundColor);
private static native void nativeSurfaceDestroyed(long nativePlatformViewAndroid);
private static native Bitmap nativeGetBitmap(long nativePlatformViewAndroid);
......
......@@ -400,11 +400,14 @@ void PlatformViewAndroid::SurfaceCreated(JNIEnv* env,
}
ANativeWindow_release(window);
}
}
NotifyCreated();
void PlatformViewAndroid::SurfaceChanged(JNIEnv* env,
jobject obj,
jint backgroundColor) {
NotifyCreated(
[this, backgroundColor] { config_.rasterizer->Clear(backgroundColor); });
SetupResourceContextOnIOThread();
UpdateThreadPriorities();
}
......
......@@ -30,6 +30,9 @@ class PlatformViewAndroid : public PlatformView {
// Called from Java
void SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface);
// Called from Java
void SurfaceChanged(JNIEnv* env, jobject obj, jint backgroundColor);
// Called from Java
void SurfaceDestroyed(JNIEnv* env, jobject obj);
......
......@@ -56,23 +56,17 @@ void PlatformView::NotifyCreated() {
}
void PlatformView::NotifyCreated(ftl::Closure rasterizer_continuation) {
CHECK(config_.rasterizer != nullptr);
auto rasterizer = config_.rasterizer->GetWeakRasterizerPtr();
FTL_CHECK(config_.rasterizer);
ftl::AutoResetWaitableEvent latch;
auto delegate_continuation = [rasterizer, this, rasterizer_continuation,
&latch]() {
if (rasterizer)
rasterizer->Setup(this, rasterizer_continuation, &latch);
// TODO(abarth): We should signal the latch if the rasterizer is gone.
auto delegate_continuation = [this, rasterizer_continuation, &latch]() {
config_.rasterizer->Setup(this, rasterizer_continuation, &latch);
};
auto delegate = config_.ui_delegate;
blink::Threads::UI()->PostTask([delegate, delegate_continuation]() {
if (delegate)
delegate->OnOutputSurfaceCreated(delegate_continuation);
// TODO(abarth): We should signal the latch if the delegate is gone.
delegate->OnOutputSurfaceCreated(delegate_continuation);
});
latch.Wait();
......
......@@ -27,6 +27,8 @@ class Rasterizer {
ftl::Closure rasterizer_continuation,
ftl::AutoResetWaitableEvent* setup_completion_event) = 0;
virtual void Clear(SkColor color) = 0;
virtual void Teardown(
ftl::AutoResetWaitableEvent* teardown_completion_event) = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册