From 81ae27ab6187adf138be71c8778730fab2db1856 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 2 Jun 2016 21:01:02 -0700 Subject: [PATCH] Remove startup flicker on Android (#2733) According to hackbod on Stack Overflow, we're supposed to block in the surfaceCreated callback until we've actually drawn into the surface: http://stackoverflow.com/questions/8772862/surfaceview-flashes-black-on-load/8888108#8888108 --- sky/shell/gpu/direct/rasterizer_direct.cc | 5 ++++- sky/shell/gpu/direct/rasterizer_direct.h | 4 +++- sky/shell/gpu/direct/surface_notifications_direct.cc | 6 ++++-- sky/shell/gpu/direct/surface_notifications_direct.h | 4 +++- sky/shell/platform/android/platform_view_android.cc | 5 +++-- sky/shell/platform/android/platform_view_android.h | 2 ++ sky/shell/platform/glfw/platform_view_glfw.cc | 2 +- sky/shell/platform/mac/platform_view_mac.mm | 2 +- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/sky/shell/gpu/direct/rasterizer_direct.cc b/sky/shell/gpu/direct/rasterizer_direct.cc index 1e66e006b..d4ab6c58e 100644 --- a/sky/shell/gpu/direct/rasterizer_direct.cc +++ b/sky/shell/gpu/direct/rasterizer_direct.cc @@ -52,7 +52,8 @@ void RasterizerDirect::ConnectToRasterizer( Shell::Shared().AddRasterizer(GetWeakRasterizerPtr()); } -void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { +void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget, + base::WaitableEvent* did_draw) { gfx::SurfaceConfiguration config; config.stencil_bits = 8; surface_ = gfx::GLSurface::CreateViewGLSurface(widget, config); @@ -66,6 +67,8 @@ void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widge glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); surface_->SwapBuffers(); + if (did_draw) + did_draw->Signal(); } void RasterizerDirect::Draw(uint64_t layer_tree_ptr, diff --git a/sky/shell/gpu/direct/rasterizer_direct.h b/sky/shell/gpu/direct/rasterizer_direct.h index 07e766b7c..072aa7214 100644 --- a/sky/shell/gpu/direct/rasterizer_direct.h +++ b/sky/shell/gpu/direct/rasterizer_direct.h @@ -6,6 +6,7 @@ #define SKY_SHELL_GPU_DIRECT_RASTERIZER_H_ #include "base/memory/weak_ptr.h" +#include "base/synchronization/waitable_event.h" #include "flow/compositor_context.h" #include "skia/ext/refptr.h" #include "sky/shell/gpu/direct/ganesh_canvas.h" @@ -35,7 +36,8 @@ class RasterizerDirect : public Rasterizer { void ConnectToRasterizer( mojo::InterfaceRequest request) override; - void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget); + void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget, + base::WaitableEvent* did_draw); void OnOutputSurfaceDestroyed(); flow::LayerTree* GetLastLayerTree() override; diff --git a/sky/shell/gpu/direct/surface_notifications_direct.cc b/sky/shell/gpu/direct/surface_notifications_direct.cc index 4974a0f2f..167d88eb2 100644 --- a/sky/shell/gpu/direct/surface_notifications_direct.cc +++ b/sky/shell/gpu/direct/surface_notifications_direct.cc @@ -14,13 +14,15 @@ namespace sky { namespace shell { void SurfaceNotificationsDirect::NotifyCreated( - const PlatformView::Config& config, gfx::AcceleratedWidget widget) { + const PlatformView::Config& config, + gfx::AcceleratedWidget widget, + base::WaitableEvent* did_draw) { RasterizerDirect* rasterizer = static_cast(config.rasterizer); config.ui_task_runner->PostTask( FROM_HERE, base::Bind(&UIDelegate::OnOutputSurfaceCreated, config.ui_delegate, base::Bind(&RasterizerDirect::OnAcceleratedWidgetAvailable, - rasterizer->GetWeakPtr(), widget))); + rasterizer->GetWeakPtr(), widget, did_draw))); } void SurfaceNotificationsDirect::NotifyDestroyed( diff --git a/sky/shell/gpu/direct/surface_notifications_direct.h b/sky/shell/gpu/direct/surface_notifications_direct.h index 1cb94bfa4..d3ac16910 100644 --- a/sky/shell/gpu/direct/surface_notifications_direct.h +++ b/sky/shell/gpu/direct/surface_notifications_direct.h @@ -5,6 +5,7 @@ #ifndef SKY_SHELL_GPU_DIRECT_SURFACE_NOTIFICATIONS_DIRECT_H_ #define SKY_SHELL_GPU_DIRECT_SURFACE_NOTIFICATIONS_DIRECT_H_ +#include "base/synchronization/waitable_event.h" #include "sky/shell/platform_view.h" namespace sky { @@ -13,7 +14,8 @@ namespace shell { class SurfaceNotificationsDirect { public: static void NotifyCreated(const PlatformView::Config& config, - gfx::AcceleratedWidget widget); + gfx::AcceleratedWidget widget, + base::WaitableEvent* did_draw); static void NotifyDestroyed(const PlatformView::Config& config); }; diff --git a/sky/shell/platform/android/platform_view_android.cc b/sky/shell/platform/android/platform_view_android.cc index df1f61177..06d52e55f 100644 --- a/sky/shell/platform/android/platform_view_android.cc +++ b/sky/shell/platform/android/platform_view_android.cc @@ -43,7 +43,7 @@ PlatformView* PlatformView::Create(const Config& config) { } PlatformViewAndroid::PlatformViewAndroid(const Config& config) - : PlatformView(config), window_(nullptr) { + : PlatformView(config), window_(nullptr), did_draw_(false, false) { } PlatformViewAndroid::~PlatformViewAndroid() { @@ -65,7 +65,8 @@ void PlatformViewAndroid::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurf base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); window_ = ANativeWindow_fromSurface(env, jsurface); } - SurfaceNotificationsDirect::NotifyCreated(config_, window_); + SurfaceNotificationsDirect::NotifyCreated(config_, window_, &did_draw_); + did_draw_.Wait(); } void PlatformViewAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) { diff --git a/sky/shell/platform/android/platform_view_android.h b/sky/shell/platform/android/platform_view_android.h index 5c5cd3d45..ec6c046c9 100644 --- a/sky/shell/platform/android/platform_view_android.h +++ b/sky/shell/platform/android/platform_view_android.h @@ -5,6 +5,7 @@ #ifndef SKY_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_ #define SKY_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_ +#include "base/synchronization/waitable_event.h" #include "sky/shell/platform_view.h" struct ANativeWindow; @@ -36,6 +37,7 @@ class PlatformViewAndroid : public PlatformView { // |Detach|, which will eventually cause |~PlatformViewAndroid|. std::unique_ptr shell_view_; gfx::AcceleratedWidget window_; + base::WaitableEvent did_draw_; DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid); }; diff --git a/sky/shell/platform/glfw/platform_view_glfw.cc b/sky/shell/platform/glfw/platform_view_glfw.cc index cc683b912..cc0ae0047 100644 --- a/sky/shell/platform/glfw/platform_view_glfw.cc +++ b/sky/shell/platform/glfw/platform_view_glfw.cc @@ -21,7 +21,7 @@ PlatformViewGLFW::~PlatformViewGLFW() {} void PlatformViewGLFW::SurfaceCreated(gfx::AcceleratedWidget widget) { DCHECK(window_ == gfx::kNullAcceleratedWidget); window_ = widget; - SurfaceNotificationsDirect::NotifyCreated(config_, window_); + SurfaceNotificationsDirect::NotifyCreated(config_, window_, nullptr); } void PlatformViewGLFW::SurfaceDestroyed() { diff --git a/sky/shell/platform/mac/platform_view_mac.mm b/sky/shell/platform/mac/platform_view_mac.mm index dda5db89e..97229b4ce 100644 --- a/sky/shell/platform/mac/platform_view_mac.mm +++ b/sky/shell/platform/mac/platform_view_mac.mm @@ -21,7 +21,7 @@ PlatformViewMac::~PlatformViewMac() {} void PlatformViewMac::SurfaceCreated(gfx::AcceleratedWidget widget) { DCHECK(window_ == gfx::kNullAcceleratedWidget); window_ = widget; - SurfaceNotificationsDirect::NotifyCreated(config_, window_); + SurfaceNotificationsDirect::NotifyCreated(config_, window_, nullptr); } void PlatformViewMac::SurfaceDestroyed() { -- GitLab