Commit 263aa9b0 authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

weblayer: Avoid flicker in surface transition

Do a complicated dance to avoid visual artifacts during transition:
1) Allocate new SurfaceData, and insert it into view hierarchy
   below the existing SurfaceData, so it is not yet showing.
2) When Surface is allocated by new View, swap chromium compositor
   to the new Surface. |markForDestroy| is called on the previous
   SurfaceData, and the two SurfaceDatas are linked through these to
   variables. Note at this point the existing view should is still
   visible.
3) Wait until new SurfaceData decides that it has content is visible
   to be shown.
   * For TextureView, wait until TextureView.invalidate is called
   * For SurfaceView, wait for two swaps from the chromium compositor
4) New SurfaceData calls |destroy| on previous SurfaceData.
   * For TextureView, it is simply detached immediately from the view
     tree
   * For SurfaceView, to avoid flicker, move it to the back first
     before and wait two frames before detaching.
5) Previous SurfaceData runs callbacks on the new SurfaceData to signal
   the completion of the transition.

Other related changes:
* Update CompositorImpl::SetNeedsComposite to force a new frame to be
  produced.
* Allow java to control caching and releasing the back buffer.
* To complete the steps above, chain the two SurfaceDatas so new one
  calls destroy on old one, and old one calls runCallbacks on the new
  one.
* Add TextureViewWithInvalidate to listen to when it is invalidated.
* Implement moveChildToBackWithoutDetach with calls to bringChildToFront
  since android does not have a moveChildToBack method.
* Send an artificial surfaceDestroyed signal in destroy to control
  back buffer caching.

Change-Id: Ie43485304c1c08df5ae11cd7756767d29e84e112
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1836605
Commit-Queue: Bo <boliu@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704494}
parent bf8cd947
......@@ -538,6 +538,10 @@ void CompositorImpl::SetNeedsComposite() {
host_->SetNeedsAnimate();
}
void CompositorImpl::SetNeedsRedraw() {
host_->SetNeedsRedrawRect(host_->device_viewport_rect());
}
void CompositorImpl::DidUpdateLayers() {
// Dump property trees and layers if run with:
// --vmodule=compositor_impl_android=3
......
......@@ -98,6 +98,7 @@ class CONTENT_EXPORT CompositorImpl
void SetWindowBounds(const gfx::Size& size) override;
void SetRequiresAlphaChannel(bool flag) override;
void SetNeedsComposite() override;
void SetNeedsRedraw() override;
ui::UIResourceProvider& GetUIResourceProvider() override;
ui::ResourceManager& GetResourceManager() override;
void CacheBackBufferForCurrentSurface() override;
......
......@@ -83,6 +83,9 @@ class CONTENT_EXPORT Compositor {
// Composite *without* having modified the layer tree.
virtual void SetNeedsComposite() = 0;
// Request a draw and swap even if there is no change to the layer tree.
virtual void SetNeedsRedraw() = 0;
// Returns the UI resource provider associated with the compositor.
virtual ui::UIResourceProvider& GetUIResourceProvider() = 0;
......
......@@ -87,8 +87,7 @@ void ContentViewRenderView::SurfaceCreated(JNIEnv* env) {
void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env,
jboolean cache_back_buffer) {
evict_back_buffer_on_next_swap_ = cache_back_buffer;
if (evict_back_buffer_on_next_swap_)
if (cache_back_buffer)
compositor_->CacheBackBufferForCurrentSurface();
compositor_->SetSurface(nullptr, false);
}
......@@ -116,13 +115,15 @@ void ContentViewRenderView::UpdateLayerTreeHost() {
void ContentViewRenderView::DidSwapFrame(int pending_frames) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_ContentViewRenderView_didSwapFrame(env, java_obj_);
if (evict_back_buffer_on_next_swap_) {
compositor_->EvictCachedBackBuffer();
evict_back_buffer_on_next_swap_ = false;
if (Java_ContentViewRenderView_didSwapFrame(env, java_obj_)) {
compositor_->SetNeedsRedraw();
}
}
void ContentViewRenderView::EvictCachedSurface(JNIEnv* env) {
compositor_->EvictCachedBackBuffer();
}
void ContentViewRenderView::InitCompositor() {
if (compositor_)
return;
......
......@@ -53,6 +53,7 @@ class ContentViewRenderView : public content::CompositorClient {
jint width,
jint height,
const base::android::JavaParamRef<jobject>& surface);
void EvictCachedSurface(JNIEnv* env);
base::android::ScopedJavaLocalRef<jobject> GetResourceManager(JNIEnv* env);
// CompositorClient implementation
......@@ -74,8 +75,6 @@ class ContentViewRenderView : public content::CompositorClient {
scoped_refptr<cc::Layer> root_container_layer_;
scoped_refptr<cc::Layer> web_contents_layer_;
bool evict_back_buffer_on_next_swap_ = false;
DISALLOW_COPY_AND_ASSIGN(ContentViewRenderView);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment