Commit cb024857 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

SkiaRenderer: support render pass overlay on macOS

This CL implements render pass overlay on macOS. With this
implementation, SkiaRenderer draws render passes with filters with a
DDL recorder canvas, and then stores DDL and related information in
the CALayerOverlay. The SkiaOutputSurfaceImplOnGpu will create overlay
shared images backing base on the DDL, and then replays DDL against the
backing, and then the backings will be presented as overlays.

However this CL doesn't recycle overlay shared images. It always creates
new shared images for each render pass overlay. Shared image backing
recycling will be implemented in follow-up CLs.

Since recycling is not implemented, so the the render pass overlay is
not enabled in this CL.

Bug: 1100728
Change-Id: I8389393a790b9e0fdc0dda69c60afd2566a68dd9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2388885
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804832}
parent b2d65813
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "components/viz/common/quads/tile_draw_quad.h" #include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/display_resource_provider.h"
#include "gpu/GLES2/gl2extchromium.h" #include "gpu/GLES2/gl2extchromium.h"
#include "third_party/skia/include/core/SkDeferredDisplayList.h"
namespace viz { namespace viz {
...@@ -296,7 +297,10 @@ CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {} ...@@ -296,7 +297,10 @@ CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {}
CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default; CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default;
CALayerOverlay::~CALayerOverlay() {} CALayerOverlay::~CALayerOverlay() = default;
CALayerOverlay& CALayerOverlay::operator=(const CALayerOverlay& other) =
default;
bool CALayerOverlayProcessor::ProcessForCALayerOverlays( bool CALayerOverlayProcessor::ProcessForCALayerOverlays(
DisplayResourceProvider* resource_provider, DisplayResourceProvider* resource_provider,
......
...@@ -9,16 +9,20 @@ ...@@ -9,16 +9,20 @@
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "components/viz/common/quads/aggregated_render_pass.h" #include "components/viz/common/quads/aggregated_render_pass.h"
#include "components/viz/common/quads/compositor_render_pass.h" #include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/service/viz_service_export.h" #include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/mailbox.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkMatrix44.h" #include "third_party/skia/include/core/SkMatrix44.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/rrect_f.h" #include "ui/gfx/rrect_f.h"
#include "ui/gl/ca_renderer_layer_params.h" #include "ui/gl/ca_renderer_layer_params.h"
class SkDeferredDisplayList;
namespace viz { namespace viz {
class AggregatedRenderPassDrawQuad; class AggregatedRenderPassDrawQuad;
class DisplayResourceProvider; class DisplayResourceProvider;
...@@ -54,6 +58,7 @@ class VIZ_SERVICE_EXPORT CALayerOverlay { ...@@ -54,6 +58,7 @@ class VIZ_SERVICE_EXPORT CALayerOverlay {
CALayerOverlay(); CALayerOverlay();
CALayerOverlay(const CALayerOverlay& other); CALayerOverlay(const CALayerOverlay& other);
~CALayerOverlay(); ~CALayerOverlay();
CALayerOverlay& operator=(const CALayerOverlay& other);
// State that is frequently shared between consecutive CALayerOverlays. // State that is frequently shared between consecutive CALayerOverlays.
scoped_refptr<CALayerOverlaySharedState> shared_state; scoped_refptr<CALayerOverlaySharedState> shared_state;
...@@ -72,10 +77,14 @@ class VIZ_SERVICE_EXPORT CALayerOverlay { ...@@ -72,10 +77,14 @@ class VIZ_SERVICE_EXPORT CALayerOverlay {
// The edge anti-aliasing mask property for the CALayer. // The edge anti-aliasing mask property for the CALayer.
unsigned edge_aa_mask = 0; unsigned edge_aa_mask = 0;
// The minification and magnification filters for the CALayer. // The minification and magnification filters for the CALayer.
unsigned filter; unsigned filter = 0;
// If |rpdq| is present, then the renderer must draw the filter effects and // If |rpdq| is present, then the renderer must draw the filter effects and
// copy the result into an IOSurface. // copy the result into an IOSurface.
const AggregatedRenderPassDrawQuad* rpdq = nullptr; const AggregatedRenderPassDrawQuad* rpdq = nullptr;
// The DDL for generating render pass overlay buffer with SkiaRenderer.
sk_sp<SkDeferredDisplayList> ddl;
// The transform for render pass overlay.
base::Optional<SkMatrix44> transform;
}; };
typedef std::vector<CALayerOverlay> CALayerOverlayList; typedef std::vector<CALayerOverlay> CALayerOverlayList;
......
...@@ -319,6 +319,11 @@ class VIZ_SERVICE_EXPORT DirectRenderer { ...@@ -319,6 +319,11 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
DCHECK(current_frame_valid_); DCHECK(current_frame_valid_);
return &current_frame_; return &current_frame_;
} }
gfx::BufferFormat reshape_buffer_format() const {
DCHECK(reshape_buffer_format_);
return reshape_buffer_format_.value();
}
gfx::ColorSpace reshape_color_space() const { return reshape_color_space_; }
// Return a bool to inform the caller if the delegated ink renderer was // Return a bool to inform the caller if the delegated ink renderer was
// actually created or not. If the renderer doesn't support drawing delegated // actually created or not. If the renderer doesn't support drawing delegated
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
class SkCanvas; class SkCanvas;
class SkImage; class SkImage;
#if defined(OS_APPLE)
class SkDeferredDisplayList;
#endif
namespace gfx { namespace gfx {
class ColorSpace; class ColorSpace;
} // namespace gfx } // namespace gfx
...@@ -166,6 +170,15 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface, ...@@ -166,6 +170,15 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
base::OnceClosure callback, base::OnceClosure callback,
std::vector<gpu::SyncToken> sync_tokens) = 0; std::vector<gpu::SyncToken> sync_tokens) = 0;
#if defined(OS_APPLE)
virtual SkCanvas* BeginPaintRenderPassOverlay(
const gfx::Size& size,
ResourceFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space) = 0;
virtual sk_sp<SkDeferredDisplayList> EndPaintRenderPassOverlay() = 0;
#endif
private: private:
DISALLOW_COPY_AND_ASSIGN(SkiaOutputSurface); DISALLOW_COPY_AND_ASSIGN(SkiaOutputSurface);
}; };
......
...@@ -247,6 +247,11 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer { ...@@ -247,6 +247,11 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
float resource_multiplier = 1.0f); float resource_multiplier = 1.0f);
// Returns the color filter that should be applied to the current canvas. // Returns the color filter that should be applied to the current canvas.
sk_sp<SkColorFilter> GetContentColorFilter(); sk_sp<SkColorFilter> GetContentColorFilter();
#if defined(OS_APPLE)
void PrepareRenderPassOverlay(CALayerOverlay* overlay);
#endif
// A map from RenderPass id to the texture used to draw the RenderPass from. // A map from RenderPass id to the texture used to draw the RenderPass from.
struct RenderPassBacking { struct RenderPassBacking {
sk_sp<SkSurface> render_pass_surface; sk_sp<SkSurface> render_pass_surface;
......
...@@ -393,10 +393,11 @@ std::vector<OutputPresenter::OverlayData> OutputPresenterGL::ScheduleOverlays( ...@@ -393,10 +393,11 @@ std::vector<OutputPresenter::OverlayData> OutputPresenterGL::ScheduleOverlays(
gfx::ToEnclosingRect(overlay.shared_state->clip_rect), gfx::ToEnclosingRect(overlay.shared_state->clip_rect),
overlay.shared_state->rounded_corner_bounds, overlay.shared_state->rounded_corner_bounds,
overlay.shared_state->sorting_context_id, overlay.shared_state->sorting_context_id,
gfx::Transform(overlay.shared_state->transform), gl_image, gfx::Transform(overlay.transform ? *overlay.transform
overlay.contents_rect, gfx::ToEnclosingRect(overlay.bounds_rect), : overlay.shared_state->transform),
overlay.background_color, overlay.edge_aa_mask, gl_image, overlay.contents_rect,
overlay.shared_state->opacity, overlay.filter)); gfx::ToEnclosingRect(overlay.bounds_rect), overlay.background_color,
overlay.edge_aa_mask, overlay.shared_state->opacity, overlay.filter));
#endif #endif
} }
#endif // defined(OS_ANDROID) || defined(OS_APPLE) || defined(USE_OZONE) #endif // defined(OS_ANDROID) || defined(OS_APPLE) || defined(USE_OZONE)
......
...@@ -76,6 +76,10 @@ SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( ...@@ -76,6 +76,10 @@ SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
SkDeferredDisplayListRecorder* root_recorder) SkDeferredDisplayListRecorder* root_recorder)
: recorder_(root_recorder), render_pass_id_(0) {} : recorder_(root_recorder), render_pass_id_(0) {}
SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
SkSurfaceCharacterization characterization)
: ScopedPaint(characterization, AggregatedRenderPassId(0)) {}
SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
SkSurfaceCharacterization characterization, SkSurfaceCharacterization characterization,
AggregatedRenderPassId render_pass_id) AggregatedRenderPassId render_pass_id)
...@@ -503,6 +507,38 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass( ...@@ -503,6 +507,38 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
return current_paint_->recorder()->getCanvas(); return current_paint_->recorder()->getCanvas();
} }
#if defined(OS_APPLE)
SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPassOverlay(
const gfx::Size& size,
ResourceFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
DCHECK(!current_paint_);
DCHECK(resource_sync_tokens_.empty());
SkSurfaceCharacterization characterization = CreateSkSurfaceCharacterization(
size, BufferFormat(format), mipmap, std::move(color_space),
true /* is_root_render_pass */);
if (!characterization.isValid())
return nullptr;
current_paint_.emplace(characterization);
return current_paint_->recorder()->getCanvas();
}
sk_sp<SkDeferredDisplayList>
SkiaOutputSurfaceImpl::EndPaintRenderPassOverlay() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_paint_);
auto ddl = current_paint_->recorder()->detach();
current_paint_.reset();
return ddl;
}
#endif // defined(OS_APPLE)
gpu::SyncToken SkiaOutputSurfaceImpl::SubmitPaint( gpu::SyncToken SkiaOutputSurfaceImpl::SubmitPaint(
base::OnceClosure on_finished) { base::OnceClosure on_finished) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -661,8 +697,10 @@ void SkiaOutputSurfaceImpl::ScheduleOverlays( ...@@ -661,8 +697,10 @@ void SkiaOutputSurfaceImpl::ScheduleOverlays(
std::vector<gpu::SyncToken> sync_tokens) { std::vector<gpu::SyncToken> sync_tokens) {
auto task = auto task =
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::ScheduleOverlays, base::BindOnce(&SkiaOutputSurfaceImplOnGpu::ScheduleOverlays,
base::Unretained(impl_on_gpu_.get()), std::move(overlays)); base::Unretained(impl_on_gpu_.get()), std::move(overlays),
std::move(images_in_current_paint_));
ScheduleGpuTask(std::move(task), std::move(sync_tokens)); ScheduleGpuTask(std::move(task), std::move(sync_tokens));
images_in_current_paint_.clear();
} }
gpu::MemoryTracker* SkiaOutputSurfaceImpl::GetMemoryTracker() { gpu::MemoryTracker* SkiaOutputSurfaceImpl::GetMemoryTracker() {
......
...@@ -131,6 +131,15 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -131,6 +131,15 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
void AddContextLostObserver(ContextLostObserver* observer) override; void AddContextLostObserver(ContextLostObserver* observer) override;
void RemoveContextLostObserver(ContextLostObserver* observer) override; void RemoveContextLostObserver(ContextLostObserver* observer) override;
#if defined(OS_APPLE)
SkCanvas* BeginPaintRenderPassOverlay(
const gfx::Size& size,
ResourceFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space) override;
sk_sp<SkDeferredDisplayList> EndPaintRenderPassOverlay() override;
#endif
// ExternalUseClient implementation: // ExternalUseClient implementation:
gpu::SyncToken ReleaseImageContexts( gpu::SyncToken ReleaseImageContexts(
std::vector<std::unique_ptr<ImageContext>> image_contexts) override; std::vector<std::unique_ptr<ImageContext>> image_contexts) override;
...@@ -210,6 +219,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -210,6 +219,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
class ScopedPaint { class ScopedPaint {
public: public:
explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder); explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder);
explicit ScopedPaint(SkSurfaceCharacterization characterization);
ScopedPaint(SkSurfaceCharacterization characterization, ScopedPaint(SkSurfaceCharacterization characterization,
AggregatedRenderPassId render_pass_id); AggregatedRenderPassId render_pass_id);
~ScopedPaint(); ~ScopedPaint();
......
...@@ -953,8 +953,84 @@ void SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts( ...@@ -953,8 +953,84 @@ void SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts(
} }
void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays( void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
SkiaOutputSurface::OverlayList overlays) { SkiaOutputSurface::OverlayList overlays,
std::vector<ImageContextImpl*> image_contexts) {
#if defined(OS_APPLE)
std::vector<GrBackendSemaphore> begin_semaphores;
std::vector<GrBackendSemaphore> end_semaphores;
promise_image_access_helper_.BeginAccess(std::move(image_contexts),
&begin_semaphores, &end_semaphores);
// GL is used on MacOS and GL doesn't need semaphores.
DCHECK(begin_semaphores.empty());
DCHECK(end_semaphores.empty());
std::vector<gpu::Mailbox> render_pass_overlay_mailboxes;
for (auto& overlay : overlays) {
if (!overlay.ddl)
continue;
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
if (dependency_->GetGrShaderCache()) {
cache_use.emplace(dependency_->GetGrShaderCache(),
gpu::kDisplayCompositorClientId);
}
constexpr auto kOverlayUsage =
gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY |
gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
const auto& characterization = overlay.ddl->characterization();
ResourceFormat resource_format;
switch (characterization.colorType()) {
case kRGBA_8888_SkColorType:
resource_format = ResourceFormat::RGBA_8888;
break;
case kBGRA_8888_SkColorType:
resource_format = ResourceFormat::BGRA_8888;
break;
case kRGBA_F16_SkColorType:
resource_format = ResourceFormat::RGBA_F16;
break;
default:
resource_format = ResourceFormat::RGBA_8888;
NOTREACHED();
}
// TODO(https://crbug.com/1100728): reuse shared images.
DCHECK(overlay.mailbox.IsZero());
overlay.mailbox = gpu::Mailbox::GenerateForSharedImage();
shared_image_factory_->CreateSharedImage(
overlay.mailbox, resource_format,
gfx::Size(characterization.width(), characterization.height()),
gfx::ColorSpace(*characterization.colorSpace()),
characterization.origin(), characterization.imageInfo().alphaType(),
gpu::kNullSurfaceHandle, kOverlayUsage);
auto representation = shared_image_representation_factory_->ProduceSkia(
overlay.mailbox, context_state_.get());
DCHECK(representation);
auto scoped_access = representation->BeginScopedWriteAccess(
/*final_msaa_count=*/0, characterization.surfaceProps(),
/*begin_semaphores=*/nullptr,
/*end_semaphores=*/nullptr,
gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
bool result = scoped_access->surface()->draw(overlay.ddl);
DCHECK(result);
context_state_->gr_context()->flushAndSubmit();
scoped_access.reset();
representation->SetCleared();
render_pass_overlay_mailboxes.push_back(overlay.mailbox);
}
promise_image_access_helper_.EndAccess();
output_device_->ScheduleOverlays(std::move(overlays)); output_device_->ScheduleOverlays(std::move(overlays));
for (const auto& mailbox : render_pass_overlay_mailboxes) {
shared_image_factory_->DestroySharedImage(mailbox);
}
#else
DCHECK(image_contexts.empty());
output_device_->ScheduleOverlays(std::move(overlays));
#endif
} }
void SkiaOutputSurfaceImplOnGpu::SetEnableDCLayers(bool enable) { void SkiaOutputSurfaceImplOnGpu::SetEnableDCLayers(bool enable) {
......
...@@ -168,7 +168,8 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -168,7 +168,8 @@ class SkiaOutputSurfaceImplOnGpu
std::vector<std::unique_ptr<ExternalUseClient::ImageContext>> std::vector<std::unique_ptr<ExternalUseClient::ImageContext>>
image_contexts, image_contexts,
uint64_t sync_fence_release); uint64_t sync_fence_release);
void ScheduleOverlays(SkiaOutputSurface::OverlayList overlays); void ScheduleOverlays(SkiaOutputSurface::OverlayList overlays,
std::vector<ImageContextImpl*> image_contexts);
void SetEnableDCLayers(bool enable); void SetEnableDCLayers(bool enable);
void SetGpuVSyncEnabled(bool enabled); void SetGpuVSyncEnabled(bool enabled);
......
...@@ -316,6 +316,23 @@ void FakeSkiaOutputSurface::RemoveContextLostObserver( ...@@ -316,6 +316,23 @@ void FakeSkiaOutputSurface::RemoveContextLostObserver(
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
#if defined(OS_APPLE)
SkCanvas* FakeSkiaOutputSurface::BeginPaintRenderPassOverlay(
const gfx::Size& size,
ResourceFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space) {
NOTIMPLEMENTED();
return nullptr;
}
sk_sp<SkDeferredDisplayList>
FakeSkiaOutputSurface::EndPaintRenderPassOverlay() {
NOTIMPLEMENTED();
return nullptr;
}
#endif
void FakeSkiaOutputSurface::SetOutOfOrderCallbacks( void FakeSkiaOutputSurface::SetOutOfOrderCallbacks(
bool out_of_order_callbacks) { bool out_of_order_callbacks) {
TestContextSupport* support = TestContextSupport* support =
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/viz/service/display/skia_output_surface.h" #include "components/viz/service/display/skia_output_surface.h"
#include "components/viz/test/test_context_provider.h" #include "components/viz/test/test_context_provider.h"
#include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/common/sync_token.h"
#include "third_party/skia/include/core/SkDeferredDisplayList.h"
namespace viz { namespace viz {
...@@ -99,6 +100,14 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface { ...@@ -99,6 +100,14 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
std::unique_ptr<CopyOutputRequest> request) override; std::unique_ptr<CopyOutputRequest> request) override;
void AddContextLostObserver(ContextLostObserver* observer) override; void AddContextLostObserver(ContextLostObserver* observer) override;
void RemoveContextLostObserver(ContextLostObserver* observer) override; void RemoveContextLostObserver(ContextLostObserver* observer) override;
#if defined(OS_APPLE)
SkCanvas* BeginPaintRenderPassOverlay(
const gfx::Size& size,
ResourceFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space) override;
sk_sp<SkDeferredDisplayList> EndPaintRenderPassOverlay() override;
#endif
// ExternalUseClient implementation: // ExternalUseClient implementation:
gpu::SyncToken ReleaseImageContexts( gpu::SyncToken ReleaseImageContexts(
......
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