diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index d4a58e89131ffe..aeadd129a623bd 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc @@ -367,6 +367,12 @@ void SkiaOutputSurfaceImpl::Reshape(const gfx::Size& size, const gfx::ColorSpace& color_space, bool has_alpha, bool use_stencil) { + reshape_surface_size_ = size; + reshape_device_scale_factor_ = device_scale_factor; + reshape_color_space_ = color_space; + reshape_has_alpha_ = has_alpha; + reshape_use_stencil_ = use_stencil; + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (initialize_waitable_event_) { initialize_waitable_event_->Wait(); @@ -374,15 +380,23 @@ void SkiaOutputSurfaceImpl::Reshape(const gfx::Size& size, } SkSurfaceCharacterization* characterization = nullptr; - if (characterization_.isValid()) { - // TODO(weiliang): suppoot color space. https://crbug.com/795132 - characterization_ = - characterization_.createResized(size.width(), size.height()); - } else { + // If the render target is changed between GL fbo zero and non-zero, we cannot + // recreate SkSurface characterization from the existing characterization. So + // we have to request a new SkSurface characterization from + // SkiaOutputSurfaceImplOnGpu. + backing_framebuffer_object_ = + gl_surface_ ? gl_surface_->GetBackingFramebufferObject() : 0; + if (!characterization_.isValid() || + (!is_using_vulkan_ && + characterization_.usesGLFBO0() != (backing_framebuffer_object_ == 0))) { characterization = &characterization_; initialize_waitable_event_ = std::make_unique( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); + } else { + // TODO(weiliang): support color space. https://crbug.com/795132 + characterization_ = + characterization_.createResized(size.width(), size.height()); } // impl_on_gpu_ is released on the GPU thread by a posted task from @@ -464,6 +478,15 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() { } DCHECK(characterization_.isValid()); + // The fbo is changed, in that case we need notify SkiaOutputSurfaceImplOnGpu, + // so it can recreate SkSurface from the new fbo, and return a updated + // SkSurfaceCharacterization if necessary. + if (gl_surface_ && backing_framebuffer_object_ != + gl_surface_->GetBackingFramebufferObject()) { + Reshape(reshape_surface_size_, reshape_device_scale_factor_, + reshape_color_space_, reshape_has_alpha_, reshape_use_stencil_); + } + recorder_.emplace(characterization_); if (!show_overdraw_feedback_) return recorder_->getCanvas(); @@ -680,10 +703,9 @@ void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event) { if (task_executor_) { impl_on_gpu_ = std::make_unique( - task_executor_.get(), std::move(gl_surface_), - std::move(shared_context_state_), sequence_->GetSequenceId(), - did_swap_buffer_complete_callback, buffer_presented_callback, - context_lost_callback); + task_executor_.get(), gl_surface_, std::move(shared_context_state_), + sequence_->GetSequenceId(), did_swap_buffer_complete_callback, + buffer_presented_callback, context_lost_callback); } else { impl_on_gpu_ = std::make_unique( gpu_service_, surface_handle_, did_swap_buffer_complete_callback, diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index 4476db3aaeb8f0..cd715818d4acc9 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h @@ -148,6 +148,13 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { SyntheticBeginFrameSource* const synthetic_begin_frame_source_; OutputSurfaceClient* client_ = nullptr; + unsigned int backing_framebuffer_object_ = 0; + gfx::Size reshape_surface_size_; + float reshape_device_scale_factor_ = 0.f; + gfx::ColorSpace reshape_color_space_; + bool reshape_has_alpha_ = false; + bool reshape_use_stencil_ = false; + std::unique_ptr initialize_waitable_event_; SkSurfaceCharacterization characterization_; base::Optional recorder_; diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 4fdb435ce0d53f..0e061d74bdda1f 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc @@ -322,9 +322,6 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame( if (gr_shader_cache_) { cache_use.emplace(gr_shader_cache_, gpu::kInProcessCommandBufferClientId); } - if (backing_framebuffer_object_ != - gl_surface_->GetBackingFramebufferObject()) - CreateSkSurfaceForGL(); sk_surface_->draw(ddl.get()); gr_context()->flush(); } @@ -751,8 +748,7 @@ void SkiaOutputSurfaceImplOnGpu::CreateSkSurfaceForGL() { SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType); GrGLFramebufferInfo framebuffer_info; - backing_framebuffer_object_ = gl_surface_->GetBackingFramebufferObject(); - framebuffer_info.fFBOID = backing_framebuffer_object_; + framebuffer_info.fFBOID = gl_surface_->GetBackingFramebufferObject(); if (supports_alpha_) { framebuffer_info.fFormat = gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8; diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index e4c85baffd9e4f..eb22f837d8edf8 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h @@ -222,7 +222,6 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { gfx::Size size_; gfx::ColorSpace color_space_; scoped_refptr gl_surface_; - unsigned int backing_framebuffer_object_ = 0; sk_sp sk_surface_; scoped_refptr context_state_; const gl::GLVersionInfo* gl_version_info_ = nullptr;