提交 81ae27ab 编写于 作者: A Adam Barth

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
上级 482e63df
...@@ -52,7 +52,8 @@ void RasterizerDirect::ConnectToRasterizer( ...@@ -52,7 +52,8 @@ void RasterizerDirect::ConnectToRasterizer(
Shell::Shared().AddRasterizer(GetWeakRasterizerPtr()); Shell::Shared().AddRasterizer(GetWeakRasterizerPtr());
} }
void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
base::WaitableEvent* did_draw) {
gfx::SurfaceConfiguration config; gfx::SurfaceConfiguration config;
config.stencil_bits = 8; config.stencil_bits = 8;
surface_ = gfx::GLSurface::CreateViewGLSurface(widget, config); surface_ = gfx::GLSurface::CreateViewGLSurface(widget, config);
...@@ -66,6 +67,8 @@ void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widge ...@@ -66,6 +67,8 @@ void RasterizerDirect::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widge
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
surface_->SwapBuffers(); surface_->SwapBuffers();
if (did_draw)
did_draw->Signal();
} }
void RasterizerDirect::Draw(uint64_t layer_tree_ptr, void RasterizerDirect::Draw(uint64_t layer_tree_ptr,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define SKY_SHELL_GPU_DIRECT_RASTERIZER_H_ #define SKY_SHELL_GPU_DIRECT_RASTERIZER_H_
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "flow/compositor_context.h" #include "flow/compositor_context.h"
#include "skia/ext/refptr.h" #include "skia/ext/refptr.h"
#include "sky/shell/gpu/direct/ganesh_canvas.h" #include "sky/shell/gpu/direct/ganesh_canvas.h"
...@@ -35,7 +36,8 @@ class RasterizerDirect : public Rasterizer { ...@@ -35,7 +36,8 @@ class RasterizerDirect : public Rasterizer {
void ConnectToRasterizer( void ConnectToRasterizer(
mojo::InterfaceRequest<rasterizer::Rasterizer> request) override; mojo::InterfaceRequest<rasterizer::Rasterizer> request) override;
void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget); void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
base::WaitableEvent* did_draw);
void OnOutputSurfaceDestroyed(); void OnOutputSurfaceDestroyed();
flow::LayerTree* GetLastLayerTree() override; flow::LayerTree* GetLastLayerTree() override;
......
...@@ -14,13 +14,15 @@ namespace sky { ...@@ -14,13 +14,15 @@ namespace sky {
namespace shell { namespace shell {
void SurfaceNotificationsDirect::NotifyCreated( 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<RasterizerDirect*>(config.rasterizer); RasterizerDirect* rasterizer = static_cast<RasterizerDirect*>(config.rasterizer);
config.ui_task_runner->PostTask( config.ui_task_runner->PostTask(
FROM_HERE, base::Bind(&UIDelegate::OnOutputSurfaceCreated, FROM_HERE, base::Bind(&UIDelegate::OnOutputSurfaceCreated,
config.ui_delegate, config.ui_delegate,
base::Bind(&RasterizerDirect::OnAcceleratedWidgetAvailable, base::Bind(&RasterizerDirect::OnAcceleratedWidgetAvailable,
rasterizer->GetWeakPtr(), widget))); rasterizer->GetWeakPtr(), widget, did_draw)));
} }
void SurfaceNotificationsDirect::NotifyDestroyed( void SurfaceNotificationsDirect::NotifyDestroyed(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef SKY_SHELL_GPU_DIRECT_SURFACE_NOTIFICATIONS_DIRECT_H_ #ifndef SKY_SHELL_GPU_DIRECT_SURFACE_NOTIFICATIONS_DIRECT_H_
#define 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" #include "sky/shell/platform_view.h"
namespace sky { namespace sky {
...@@ -13,7 +14,8 @@ namespace shell { ...@@ -13,7 +14,8 @@ namespace shell {
class SurfaceNotificationsDirect { class SurfaceNotificationsDirect {
public: public:
static void NotifyCreated(const PlatformView::Config& config, static void NotifyCreated(const PlatformView::Config& config,
gfx::AcceleratedWidget widget); gfx::AcceleratedWidget widget,
base::WaitableEvent* did_draw);
static void NotifyDestroyed(const PlatformView::Config& config); static void NotifyDestroyed(const PlatformView::Config& config);
}; };
......
...@@ -43,7 +43,7 @@ PlatformView* PlatformView::Create(const Config& config) { ...@@ -43,7 +43,7 @@ PlatformView* PlatformView::Create(const Config& config) {
} }
PlatformViewAndroid::PlatformViewAndroid(const Config& config) PlatformViewAndroid::PlatformViewAndroid(const Config& config)
: PlatformView(config), window_(nullptr) { : PlatformView(config), window_(nullptr), did_draw_(false, false) {
} }
PlatformViewAndroid::~PlatformViewAndroid() { PlatformViewAndroid::~PlatformViewAndroid() {
...@@ -65,7 +65,8 @@ void PlatformViewAndroid::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurf ...@@ -65,7 +65,8 @@ void PlatformViewAndroid::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurf
base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
window_ = ANativeWindow_fromSurface(env, jsurface); 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) { void PlatformViewAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef SKY_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_ #ifndef SKY_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_
#define 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" #include "sky/shell/platform_view.h"
struct ANativeWindow; struct ANativeWindow;
...@@ -36,6 +37,7 @@ class PlatformViewAndroid : public PlatformView { ...@@ -36,6 +37,7 @@ class PlatformViewAndroid : public PlatformView {
// |Detach|, which will eventually cause |~PlatformViewAndroid|. // |Detach|, which will eventually cause |~PlatformViewAndroid|.
std::unique_ptr<ShellView> shell_view_; std::unique_ptr<ShellView> shell_view_;
gfx::AcceleratedWidget window_; gfx::AcceleratedWidget window_;
base::WaitableEvent did_draw_;
DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid); DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid);
}; };
......
...@@ -21,7 +21,7 @@ PlatformViewGLFW::~PlatformViewGLFW() {} ...@@ -21,7 +21,7 @@ PlatformViewGLFW::~PlatformViewGLFW() {}
void PlatformViewGLFW::SurfaceCreated(gfx::AcceleratedWidget widget) { void PlatformViewGLFW::SurfaceCreated(gfx::AcceleratedWidget widget) {
DCHECK(window_ == gfx::kNullAcceleratedWidget); DCHECK(window_ == gfx::kNullAcceleratedWidget);
window_ = widget; window_ = widget;
SurfaceNotificationsDirect::NotifyCreated(config_, window_); SurfaceNotificationsDirect::NotifyCreated(config_, window_, nullptr);
} }
void PlatformViewGLFW::SurfaceDestroyed() { void PlatformViewGLFW::SurfaceDestroyed() {
......
...@@ -21,7 +21,7 @@ PlatformViewMac::~PlatformViewMac() {} ...@@ -21,7 +21,7 @@ PlatformViewMac::~PlatformViewMac() {}
void PlatformViewMac::SurfaceCreated(gfx::AcceleratedWidget widget) { void PlatformViewMac::SurfaceCreated(gfx::AcceleratedWidget widget) {
DCHECK(window_ == gfx::kNullAcceleratedWidget); DCHECK(window_ == gfx::kNullAcceleratedWidget);
window_ = widget; window_ = widget;
SurfaceNotificationsDirect::NotifyCreated(config_, window_); SurfaceNotificationsDirect::NotifyCreated(config_, window_, nullptr);
} }
void PlatformViewMac::SurfaceDestroyed() { void PlatformViewMac::SurfaceDestroyed() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册