diff --git a/components/viz/service/display/ca_layer_overlay.h b/components/viz/service/display/ca_layer_overlay.h index 9076cfa0a06669..713474a1f152a8 100644 --- a/components/viz/service/display/ca_layer_overlay.h +++ b/components/viz/service/display/ca_layer_overlay.h @@ -62,8 +62,7 @@ class VIZ_SERVICE_EXPORT CALayerOverlay { scoped_refptr shared_state; // Texture that corresponds to an IOSurface to set as the content of the - // CALayer. If this is 0 then the CALayer is a solid color, or it's the root - // render pass if |is_root_render_pass| = true. + // CALayer. If this is 0 then the CALayer is a solid color. ResourceId contents_resource_id = kInvalidResourceId; // Mailbox from contents_resource_id. It is used by SkiaRenderer. gpu::Mailbox mailbox; @@ -89,8 +88,6 @@ class VIZ_SERVICE_EXPORT CALayerOverlay { // If |rpdq| is present, then the renderer must draw the filter effects and // copy the result into an IOSurface. const AggregatedRenderPassDrawQuad* rpdq = nullptr; - // Whether this overlay candidate represents the root render pass. - bool is_root_render_pass = false; }; typedef std::vector CALayerOverlayList; diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 589dd221db660b..395b18c29970a7 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc @@ -29,7 +29,6 @@ #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/common/resources/platform_color.h" -#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/viz_utils.h" #include "components/viz/service/display/bsp_tree.h" #include "components/viz/service/display/bsp_walk_action.h" @@ -192,15 +191,10 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( base::flat_map render_passes_in_frame; for (const auto& pass : render_passes_in_draw_order) { - // The root render pass doesn't need to be updated here because the backing - // is reused and updated in AllocateRenderPassResourceIfNeeded(). - if (pass == root_render_pass) { - continue; - } - // If there's a copy request, we need an explicit renderpass backing so // only try to draw directly if there are no copy requests. - if (pass->copy_requests.empty()) { + bool is_root = pass == root_render_pass; + if (!is_root && pass->copy_requests.empty()) { if (const DrawQuad* quad = CanPassBeDrawnDirectly(pass.get())) { // If the render pass is drawn directly, it will not be drawn from as // a render pass so it's not added to the map. @@ -208,7 +202,12 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( continue; } } - gfx::Size size = CalculateTextureSizeForRenderPass(pass.get()); + gfx::Size size = pass->output_rect.size(); + // We should not change the buffer size for the root render pass. + // The requirement is used for non-root render pass only. + if (!is_root) { + size = CalculateTextureSizeForRenderPass(pass.get()); + } auto color_space = RenderPassColorSpace(pass.get()); auto format = GetColorSpaceResourceFormat(color_space); @@ -785,24 +784,20 @@ void DirectRenderer::UseRenderPass(const AggregatedRenderPass* render_pass) { return; } - RenderPassRequirements requirements; - // The root pass will use values from |reshape_params_| so this doesn't - // matter. + gfx::Size size = render_pass->output_rect.size(); + // We should not change the buffer size for the root render pass. if (!is_root) { - requirements.size = CalculateTextureSizeForRenderPass(render_pass); - requirements.size.Enlarge(enlarge_pass_texture_amount_.width(), - enlarge_pass_texture_amount_.height()); - requirements.generate_mipmap = render_pass->generate_mipmap; - requirements.color_space = CurrentRenderPassColorSpace(); - requirements.format = GetColorSpaceResourceFormat(requirements.color_space); - } else { - requirements.size = surface_size_for_swap_buffers(); - requirements.generate_mipmap = false; - requirements.color_space = reshape_color_space(); - requirements.format = GetResourceFormat(reshape_buffer_format()); + size = CalculateTextureSizeForRenderPass(render_pass); + size.Enlarge(enlarge_pass_texture_amount_.width(), + enlarge_pass_texture_amount_.height()); } - AllocateRenderPassResourceIfNeeded(render_pass->id, requirements); + auto color_space = CurrentRenderPassColorSpace(); + auto format = GetColorSpaceResourceFormat(color_space); + + AllocateRenderPassResourceIfNeeded( + render_pass->id, + {size, render_pass->generate_mipmap, format, color_space}); // TODO(crbug.com/582554): This change applies only when Vulkan is enabled and // it will be removed once SkiaRenderer has complete support for Vulkan. diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 3244e4cc3531dd..19d42c00140ef3 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc @@ -871,24 +871,19 @@ void SkiaRenderer::FinishDrawingFrame() { if (!buffer_queue_) { skia_output_surface_->ScheduleOutputSurfaceAsOverlay(surface_plane); } else { -#if BUILDFLAG(IS_WIN) - // Windows does not use buffer_queue_ so this won't be reached. +#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) + // Windows and Mac have different OverlayList types, but those platforms + // aren't supported by buffer_queue_ yet, so this won't be reached. NOTREACHED(); #else + auto root_pass_backing = + render_pass_backings_.find(current_frame()->root_render_pass->id); + // The root pass backing should always exist. + DCHECK(root_pass_backing != render_pass_backings_.end()); -#if BUILDFLAG(IS_MAC) - CALayerOverlay surface_candidate; - surface_candidate.shared_state = - base::MakeRefCounted(); - surface_candidate.shared_state->sorting_context_id = 0; - surface_candidate.shared_state->rounded_corner_bounds = - surface_plane.rounded_corners; - surface_candidate.contents_rect = surface_plane.uv_rect; - surface_candidate.bounds_rect = surface_plane.display_rect; - surface_candidate.opacity = surface_plane.opacity; - surface_candidate.filter = GL_LINEAR; -#else OverlayCandidate surface_candidate; + surface_candidate.mailbox = root_pass_backing->second.mailbox; + surface_candidate.is_root_render_pass = true; surface_candidate.transform = surface_plane.transform; surface_candidate.display_rect = surface_plane.display_rect; surface_candidate.uv_rect = surface_plane.uv_rect; @@ -902,19 +897,10 @@ void SkiaRenderer::FinishDrawingFrame() { surface_candidate.damage_rect = gfx::RectF(surface_plane.damage_rect.value_or( gfx::Rect(surface_plane.resource_size))); -#endif // BUILDFLAG(IS_MAC) - - auto root_pass_backing = - render_pass_backings_.find(current_frame()->root_render_pass->id); - // The root pass backing should always exist. - DCHECK(root_pass_backing != render_pass_backings_.end()); - - surface_candidate.mailbox = root_pass_backing->second.mailbox; - surface_candidate.is_root_render_pass = true; current_frame()->overlay_list.insert( current_frame()->overlay_list.begin(), surface_candidate); -#endif // BUILDFLAG(IS_WIN) +#endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) } } ScheduleOverlays(); @@ -2719,10 +2705,6 @@ void SkiaRenderer::ScheduleOverlays() { } #elif BUILDFLAG(IS_APPLE) for (CALayerOverlay& ca_layer_overlay : current_frame()->overlay_list) { - if (ca_layer_overlay.is_root_render_pass) { - continue; - } - if (ca_layer_overlay.rpdq) { PrepareRenderPassOverlay(&ca_layer_overlay); locks.emplace_back(ca_layer_overlay.mailbox); @@ -3165,12 +3147,6 @@ void SkiaRenderer::UpdateRenderPassTextures( render_passes_in_frame) { std::vector passes_to_delete; for (const auto& pair : render_pass_backings_) { - // The single root render pass backing is updated in - // AllocateRenderPassResourceIfNeeded(), so we should never erase it here. - if (pair.second.is_root) { - continue; - } - auto render_pass_it = render_passes_in_frame.find(pair.first); if (render_pass_it == render_passes_in_frame.end()) { passes_to_delete.push_back(pair.first); @@ -3198,7 +3174,12 @@ void SkiaRenderer::UpdateRenderPassTextures( for (size_t i = 0; i < passes_to_delete.size(); ++i) { auto it = render_pass_backings_.find(passes_to_delete[i]); auto& backing = it->second; - skia_output_surface_->DestroySharedImage(backing.mailbox); + // Buffers for root render pass backings are managed by |buffer_queue_|, not + // DisplayResourceProvider, so we should not destroy them here. This + // reallocation is done in Reshape before drawing the frame + if (!backing.is_root) { + skia_output_surface_->DestroySharedImage(backing.mailbox); + } render_pass_backings_.erase(it); } @@ -3215,10 +3196,10 @@ void SkiaRenderer::AllocateRenderPassResourceIfNeeded( auto& root_pass_backing = render_pass_backings_[render_pass_id]; root_pass_backing.is_root = true; root_pass_backing.mailbox = buffer_queue_->GetCurrentBuffer(); - root_pass_backing.generate_mipmap = requirements.generate_mipmap; - root_pass_backing.size = requirements.size; - root_pass_backing.format = requirements.format; - root_pass_backing.color_space = requirements.color_space; + root_pass_backing.generate_mipmap = false; + root_pass_backing.size = surface_size_for_swap_buffers(); + root_pass_backing.format = GetResourceFormat(reshape_buffer_format()); + root_pass_backing.color_space = reshape_color_space(); return; } diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc index 47e9ee0457ec2d..c65ae0a73814b1 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc @@ -62,12 +62,10 @@ class SkiaOutputDeviceBufferQueue::OverlayData { OverlayData(std::unique_ptr representation, std::unique_ptr - scoped_read_access, - bool is_root_render_pass) + scoped_read_access) : representation_(std::move(representation)), scoped_read_access_(std::move(scoped_read_access)), - ref_(1), - is_root_render_pass_(is_root_render_pass) { + ref_(1) { DCHECK(representation_); DCHECK(scoped_read_access_); } @@ -77,7 +75,7 @@ class SkiaOutputDeviceBufferQueue::OverlayData { ~OverlayData() { Reset(); } OverlayData& operator=(OverlayData&& other) { - DCHECK(is_root_render_pass_ || !IsInUseByWindowServer()); + DCHECK(!IsInUseByWindowServer()); DCHECK(!ref_); DCHECK(!scoped_read_access_); DCHECK(!representation_); @@ -85,20 +83,13 @@ class SkiaOutputDeviceBufferQueue::OverlayData { representation_ = std::move(other.representation_); ref_ = other.ref_; other.ref_ = 0; - is_root_render_pass_ = other.is_root_render_pass_; return *this; } bool IsInUseByWindowServer() const { #if BUILDFLAG(IS_MAC) - if (!scoped_read_access_) { + if (!scoped_read_access_) return false; - } - // The root render pass buffers are managed by SkiaRenderer so we don't care - // if they're in use by the window server. - if (is_root_render_pass_) { - return false; - } return scoped_read_access_->IsInUseByWindowServer(); #else return false; @@ -112,7 +103,7 @@ class SkiaOutputDeviceBufferQueue::OverlayData { if (ref_ > 1) { --ref_; } else if (ref_ == 1) { - DCHECK(is_root_render_pass_ || !IsInUseByWindowServer()); + DCHECK(!IsInUseByWindowServer()); Reset(); } } @@ -126,8 +117,6 @@ class SkiaOutputDeviceBufferQueue::OverlayData { return scoped_read_access_.get(); } - bool IsRootRenderPass() { return is_root_render_pass_; } - private: void Reset() { scoped_read_access_.reset(); @@ -139,7 +128,6 @@ class SkiaOutputDeviceBufferQueue::OverlayData { std::unique_ptr scoped_read_access_; int ref_ = 0; - bool is_root_render_pass_ = false; }; SkiaOutputDeviceBufferQueue::SkiaOutputDeviceBufferQueue( @@ -333,7 +321,6 @@ void SkiaOutputDeviceBufferQueue::SchedulePrimaryPlane( SkiaOutputDeviceBufferQueue::OverlayData* SkiaOutputDeviceBufferQueue::GetOrCreateOverlayData(const gpu::Mailbox& mailbox, - bool is_root_render_pass, bool* is_existing) { if (is_existing) *is_existing = false; @@ -367,9 +354,8 @@ SkiaOutputDeviceBufferQueue::GetOrCreateOverlayData(const gpu::Mailbox& mailbox, } bool result; - std::tie(it, result) = - overlays_.emplace(std::move(shared_image), std::move(shared_image_access), - is_root_render_pass); + std::tie(it, result) = overlays_.emplace(std::move(shared_image), + std::move(shared_image_access)); DCHECK(result); DCHECK(it->unique()); @@ -408,8 +394,8 @@ void SkiaOutputDeviceBufferQueue::ScheduleOverlays( OutputPresenter::ScopedOverlayAccess* access = nullptr; bool overlay_has_been_submitted; - auto* overlay_data = GetOrCreateOverlayData( - mailbox, overlay.is_root_render_pass, &overlay_has_been_submitted); + auto* overlay_data = + GetOrCreateOverlayData(mailbox, &overlay_has_been_submitted); if (overlay_data) { access = overlay_data->scoped_read_access(); pending_overlay_mailboxes_.emplace_back(mailbox); @@ -603,17 +589,11 @@ void SkiaOutputDeviceBufferQueue::DoFinishSwapBuffers( // Go through backings of all overlays, and release overlay backings which are // not used. base::EraseIf(overlays_, [&on_overlay_release](auto& overlay) { - if (!overlay.unique()) { + if (!overlay.unique()) return false; - } - if (overlay.IsInUseByWindowServer()) { + if (overlay.IsInUseByWindowServer()) return false; - } - // The root render pass buffers are managed by SkiaRenderer so we don't need - // to explicitly return them via callback. - if (!overlay.IsRootRenderPass()) { - on_overlay_release(overlay); - } + on_overlay_release(overlay); overlay.Unref(); return true; }); diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue.h b/components/viz/service/display_embedder/skia_output_device_buffer_queue.h index f4a766d994cb69..a5717d9f0a01bd 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue.h +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue.h @@ -93,7 +93,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue : public SkiaOutputDevice { // Given an overlay mailbox, returns the corresponding OverlayData* from // |overlays_|. Inserts an OverlayData if mailbox is not in |overlays_|. OverlayData* GetOrCreateOverlayData(const gpu::Mailbox& mailbox, - bool is_root_render_pass, bool* is_existing = nullptr); std::unique_ptr presenter_;