Use mailboxes for RenderPass in SkiaOutputSurfaceImpl
SkiaOutputSurfaceImpl currently uses offscreen_surfaces for reading and writing shared images for RenderPass. This CL replaces offscreen surfaces to use mailboxes for reading and writing to shared images for RenderPass. It also uses USAGE_MIPMAP for supporting render passes using mipmap. Bug: 991659 Change-Id: I2d12952c51a759bb792f44444b858b32c92f2a7c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2987218 Commit-Queue: Saifuddin Hitawala <hitawala@chromium.org> Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org> Cr-Commit-Position: refs/heads/master@{#899778}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
3bc5c5609c
commit
0188a4d64f
cc/trees
components/viz
common
display
service
display
display_embedder
test
@ -1088,6 +1088,22 @@ class LayerTreeHostCopyRequestTestCountSharedImages
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
|
||||
const viz::RendererSettings& renderer_settings,
|
||||
double refresh_rate,
|
||||
scoped_refptr<viz::ContextProvider> compositor_context_provider,
|
||||
scoped_refptr<viz::RasterContextProvider> worker_context_provider)
|
||||
override {
|
||||
// Since this test counts shared images and SkiaRenderer uses shared images
|
||||
// for render passes, we need render pass allocation to be stable.
|
||||
auto settings = renderer_settings;
|
||||
settings.disable_render_pass_bypassing = true;
|
||||
auto frame_sink = LayerTreeHostCopyRequestTest::CreateLayerTreeFrameSink(
|
||||
settings, refresh_rate, std::move(compositor_context_provider),
|
||||
std::move(worker_context_provider));
|
||||
return frame_sink;
|
||||
}
|
||||
|
||||
void DisplayDidDrawAndSwapOnThread() override {
|
||||
auto* sii = display_context_provider_->SharedImageInterface();
|
||||
switch (num_swaps_++) {
|
||||
|
@ -36,6 +36,7 @@ class VIZ_COMMON_EXPORT RendererSettings {
|
||||
int highp_threshold_min = 0;
|
||||
bool auto_resize_output_surface = true;
|
||||
bool requires_alpha_channel = false;
|
||||
bool disable_render_pass_bypassing = false;
|
||||
|
||||
int slow_down_compositing_scale_factor = 1;
|
||||
|
||||
|
@ -116,7 +116,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) = 0;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) = 0;
|
||||
|
||||
// Finish painting the current frame or current render pass, depends on which
|
||||
// BeginPaint function is called last. This method will schedule a GPU task to
|
||||
@ -135,7 +136,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) = 0;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) = 0;
|
||||
|
||||
// Remove cached resources generated by BeginPaintRenderPass and
|
||||
// FinishPaintRenderPass.
|
||||
@ -147,7 +149,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
|
||||
virtual void CopyOutput(AggregatedRenderPassId id,
|
||||
const copy_output::RenderPassGeometry& geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) = 0;
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) = 0;
|
||||
|
||||
// Schedule drawing overlays at next SwapBuffers() call. Waits on
|
||||
// |sync_tokens| for the overlay textures to be ready before scheduling.
|
||||
@ -179,6 +182,9 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
|
||||
// the GPU main thread.
|
||||
virtual gpu::SyncToken Flush() = 0;
|
||||
|
||||
// Only used for creating and destroying shared images for render passes
|
||||
virtual gpu::SharedImageInterface* GetSharedImageInterface() = 0;
|
||||
|
||||
#if defined(OS_APPLE) || defined(USE_OZONE)
|
||||
virtual SkCanvas* BeginPaintRenderPassOverlay(
|
||||
const gfx::Size& size,
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "components/viz/service/display/resource_fence.h"
|
||||
#include "components/viz/service/display/skia_output_surface.h"
|
||||
#include "gpu/command_buffer/client/gles2_interface.h"
|
||||
#include "gpu/command_buffer/client/shared_image_interface.h"
|
||||
#include "gpu/command_buffer/common/shared_image_usage.h"
|
||||
#include "gpu/command_buffer/common/sync_token.h"
|
||||
#include "skia/ext/opacity_filter_canvas.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
@ -900,7 +902,7 @@ void SkiaRenderer::BindFramebufferToTexture(
|
||||
RenderPassBacking& backing = iter->second;
|
||||
current_canvas_ = skia_output_surface_->BeginPaintRenderPass(
|
||||
render_pass_id, backing.size, backing.format, backing.generate_mipmap,
|
||||
backing.color_space.ToSkColorSpace());
|
||||
backing.color_space.ToSkColorSpace(), backing.mailbox);
|
||||
}
|
||||
|
||||
void SkiaRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
|
||||
@ -1391,6 +1393,10 @@ bool SkiaRenderer::CanExplicitlyScissor(
|
||||
|
||||
const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(
|
||||
const AggregatedRenderPass* pass) {
|
||||
// If render pass bypassing is disabled for testing
|
||||
if (settings_->disable_render_pass_bypassing)
|
||||
return nullptr;
|
||||
|
||||
// TODO(michaelludwig) - For now, this only supports opaque, src-over quads
|
||||
// with invertible transforms and simple content (image or color only).
|
||||
// Can only collapse a single tile quad.
|
||||
@ -2612,7 +2618,8 @@ void SkiaRenderer::DrawRenderPassQuad(const AggregatedRenderPassDrawQuad* quad,
|
||||
sk_sp<SkImage> content_image =
|
||||
skia_output_surface_->MakePromiseSkImageFromRenderPass(
|
||||
quad->render_pass_id, backing.size, backing.format,
|
||||
backing.generate_mipmap, backing.color_space.ToSkColorSpace());
|
||||
backing.generate_mipmap, backing.color_space.ToSkColorSpace(),
|
||||
backing.mailbox);
|
||||
DLOG_IF(ERROR, !content_image)
|
||||
<< "MakePromiseSkImageFromRenderPass() failed for render pass";
|
||||
|
||||
@ -2656,13 +2663,18 @@ void SkiaRenderer::CopyDrawnRenderPass(
|
||||
|
||||
// Root framebuffer uses id 0 in SkiaOutputSurface.
|
||||
AggregatedRenderPassId render_pass_id;
|
||||
gpu::Mailbox mailbox;
|
||||
const auto* const render_pass = current_frame()->current_render_pass;
|
||||
if (render_pass != current_frame()->root_render_pass) {
|
||||
render_pass_id = render_pass->id;
|
||||
auto it = render_pass_backings_.find(render_pass_id);
|
||||
DCHECK(it != render_pass_backings_.end());
|
||||
mailbox = it->second.mailbox;
|
||||
}
|
||||
|
||||
skia_output_surface_->CopyOutput(render_pass_id, geometry,
|
||||
CurrentRenderPassColorSpace(),
|
||||
std::move(request));
|
||||
std::move(request), mailbox);
|
||||
}
|
||||
|
||||
void SkiaRenderer::DidChangeVisibility() {
|
||||
@ -2741,6 +2753,8 @@ void SkiaRenderer::UpdateRenderPassTextures(
|
||||
// again.
|
||||
for (size_t i = 0; i < passes_to_delete.size(); ++i) {
|
||||
auto it = render_pass_backings_.find(passes_to_delete[i]);
|
||||
skia_output_surface_->GetSharedImageInterface()->DestroySharedImage(
|
||||
gpu::SyncToken(), it->second.mailbox);
|
||||
render_pass_backings_.erase(it);
|
||||
}
|
||||
|
||||
@ -2765,10 +2779,18 @@ void SkiaRenderer::AllocateRenderPassResourceIfNeeded(
|
||||
auto format = color_space.IsHDR()
|
||||
? RGBA_F16
|
||||
: PlatformColor::BestSupportedTextureFormat(caps);
|
||||
uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY;
|
||||
if (requirements.generate_mipmap)
|
||||
usage |= gpu::SHARED_IMAGE_USAGE_MIPMAP;
|
||||
auto mailbox =
|
||||
skia_output_surface_->GetSharedImageInterface()->CreateSharedImage(
|
||||
format, requirements.size, color_space,
|
||||
GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
|
||||
SkAlphaType::kPremul_SkAlphaType, usage, gpu::kNullSurfaceHandle);
|
||||
render_pass_backings_.emplace(
|
||||
render_pass_id,
|
||||
RenderPassBacking({requirements.size, requirements.generate_mipmap,
|
||||
color_space, format}));
|
||||
color_space, format, mailbox}));
|
||||
}
|
||||
|
||||
void SkiaRenderer::FlushOutputSurface() {
|
||||
@ -2942,7 +2964,8 @@ void SkiaRenderer::PrepareRenderPassOverlay(
|
||||
DCHECK(backing);
|
||||
auto content_image = skia_output_surface_->MakePromiseSkImageFromRenderPass(
|
||||
quad->render_pass_id, backing->size, backing->format,
|
||||
backing->generate_mipmap, backing->color_space.ToSkColorSpace());
|
||||
backing->generate_mipmap, backing->color_space.ToSkColorSpace(),
|
||||
backing->mailbox);
|
||||
if (!content_image) {
|
||||
DLOG(ERROR)
|
||||
<< "MakePromiseSkImageFromRenderPass() failed for render pass";
|
||||
|
@ -267,6 +267,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
|
||||
bool generate_mipmap;
|
||||
gfx::ColorSpace color_space;
|
||||
ResourceFormat format;
|
||||
gpu::Mailbox mailbox;
|
||||
};
|
||||
base::flat_map<AggregatedRenderPassId, RenderPassBacking>
|
||||
render_pass_backings_;
|
||||
|
@ -24,26 +24,15 @@ ImageContextImpl::ImageContextImpl(
|
||||
ResourceFormat resource_format,
|
||||
bool maybe_concurrent_reads,
|
||||
const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info,
|
||||
sk_sp<SkColorSpace> color_space)
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const bool allow_keeping_read_access)
|
||||
: ImageContext(mailbox_holder,
|
||||
size,
|
||||
resource_format,
|
||||
ycbcr_info,
|
||||
color_space),
|
||||
maybe_concurrent_reads_(maybe_concurrent_reads) {}
|
||||
|
||||
ImageContextImpl::ImageContextImpl(AggregatedRenderPassId render_pass_id,
|
||||
const gfx::Size& size,
|
||||
ResourceFormat resource_format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space)
|
||||
: ImageContext(gpu::MailboxHolder(),
|
||||
size,
|
||||
resource_format,
|
||||
/*ycbcr_info=*/absl::nullopt,
|
||||
std::move(color_space)),
|
||||
render_pass_id_(render_pass_id),
|
||||
mipmap_(mipmap ? GrMipMapped::kYes : GrMipMapped::kNo) {}
|
||||
maybe_concurrent_reads_(maybe_concurrent_reads),
|
||||
allow_keeping_read_access_(allow_keeping_read_access) {}
|
||||
|
||||
ImageContextImpl::~ImageContextImpl() {
|
||||
if (fallback_context_state_)
|
||||
@ -267,7 +256,8 @@ void ImageContextImpl::EndAccessIfNecessary() {
|
||||
|
||||
// Avoid unnecessary read access churn for representations that
|
||||
// support multiple readers.
|
||||
if (representation_->SupportsMultipleConcurrentReadAccess())
|
||||
if (representation_->SupportsMultipleConcurrentReadAccess() &&
|
||||
allow_keeping_read_access_)
|
||||
return;
|
||||
|
||||
representation_scoped_read_access_.reset();
|
||||
|
@ -51,17 +51,9 @@ class ImageContextImpl final : public ExternalUseClient::ImageContext {
|
||||
ResourceFormat resource_format,
|
||||
bool maybe_concurrent_reads,
|
||||
const absl::optional<gpu::VulkanYCbCrInfo>& ycbcr_info,
|
||||
sk_sp<SkColorSpace> color_space);
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const bool allow_keeping_read_access = true);
|
||||
|
||||
// TODO(https://crbug.com/991659): The use of ImageContext for
|
||||
// SkiaOutputSurfaceImplOnGpu::OffscreenSurface can be factored out. This
|
||||
// would make ImageContextImpl cleaner and handling of render passes less
|
||||
// confusing.
|
||||
ImageContextImpl(AggregatedRenderPassId render_pass_id,
|
||||
const gfx::Size& size,
|
||||
ResourceFormat resource_format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space);
|
||||
~ImageContextImpl() final;
|
||||
|
||||
void OnContextLost() final;
|
||||
@ -69,9 +61,6 @@ class ImageContextImpl final : public ExternalUseClient::ImageContext {
|
||||
// Returns true if there might be concurrent reads to the backing texture.
|
||||
bool maybe_concurrent_reads() const { return maybe_concurrent_reads_; }
|
||||
|
||||
AggregatedRenderPassId render_pass_id() const { return render_pass_id_; }
|
||||
GrMipMapped mipmap() const { return mipmap_; }
|
||||
|
||||
void set_promise_image_texture(
|
||||
sk_sp<SkPromiseImageTexture> promise_image_texture) {
|
||||
owned_promise_image_texture_ = std::move(promise_image_texture);
|
||||
@ -108,10 +97,8 @@ class ImageContextImpl final : public ExternalUseClient::ImageContext {
|
||||
bool BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base,
|
||||
gfx::Size* size);
|
||||
|
||||
const AggregatedRenderPassId render_pass_id_;
|
||||
const GrMipMapped mipmap_ = GrMipMapped::kNo;
|
||||
|
||||
const bool maybe_concurrent_reads_ = false;
|
||||
const bool allow_keeping_read_access_ = true;
|
||||
|
||||
// Fallback in case we cannot produce a |representation_|.
|
||||
gpu::SharedContextState* fallback_context_state_ = nullptr;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "components/viz/common/frame_sinks/copy_output_request.h"
|
||||
#include "components/viz/common/frame_sinks/copy_output_util.h"
|
||||
#include "components/viz/common/resources/resource_format_utils.h"
|
||||
#include "components/viz/service/display/external_use_client.h"
|
||||
#include "components/viz/service/display/output_surface_client.h"
|
||||
#include "components/viz/service/display/output_surface_frame.h"
|
||||
#include "components/viz/service/display/overlay_candidate.h"
|
||||
@ -78,12 +79,14 @@ SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
|
||||
|
||||
SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
|
||||
SkSurfaceCharacterization characterization)
|
||||
: ScopedPaint(characterization, AggregatedRenderPassId(0)) {}
|
||||
: ScopedPaint(characterization, AggregatedRenderPassId(0), gpu::Mailbox()) {
|
||||
}
|
||||
|
||||
SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint(
|
||||
SkSurfaceCharacterization characterization,
|
||||
AggregatedRenderPassId render_pass_id)
|
||||
: render_pass_id_(render_pass_id) {
|
||||
AggregatedRenderPassId render_pass_id,
|
||||
gpu::Mailbox mailbox)
|
||||
: render_pass_id_(render_pass_id), mailbox_(mailbox) {
|
||||
recorder_storage_.emplace(characterization);
|
||||
recorder_ = &recorder_storage_.value();
|
||||
}
|
||||
@ -562,7 +565,8 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
|
||||
const gfx::Size& surface_size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) {
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
// Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
|
||||
DCHECK(!current_paint_);
|
||||
@ -574,7 +578,7 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
|
||||
if (!characterization.isValid())
|
||||
return nullptr;
|
||||
|
||||
current_paint_.emplace(characterization, id);
|
||||
current_paint_.emplace(characterization, id, mailbox);
|
||||
return current_paint_->recorder()->getCanvas();
|
||||
}
|
||||
|
||||
@ -632,7 +636,7 @@ void SkiaOutputSurfaceImpl::EndPaint(base::OnceClosure on_finished) {
|
||||
|
||||
auto task = base::BindOnce(
|
||||
&SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass,
|
||||
base::Unretained(impl_on_gpu_.get()), current_paint_->render_pass_id(),
|
||||
base::Unretained(impl_on_gpu_.get()), current_paint_->mailbox(),
|
||||
std::move(ddl), std::move(images_in_current_paint_),
|
||||
resource_sync_tokens_, std::move(on_finished));
|
||||
EnqueueGpuTask(std::move(task), std::move(resource_sync_tokens_),
|
||||
@ -672,14 +676,18 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromRenderPass(
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) {
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
DCHECK(current_paint_);
|
||||
|
||||
auto& image_context = render_pass_image_cache_[id];
|
||||
if (!image_context) {
|
||||
image_context = std::make_unique<ImageContextImpl>(id, size, format, mipmap,
|
||||
std::move(color_space));
|
||||
gpu::MailboxHolder mailbox_holder(mailbox, gpu::SyncToken(), 0);
|
||||
image_context = std::make_unique<ImageContextImpl>(
|
||||
mailbox_holder, size, format, /*maybe_concurrent_reads=*/false,
|
||||
/*ycbcr_info=*/absl::nullopt, std::move(color_space),
|
||||
/*allow_keeping_read_access=*/false);
|
||||
}
|
||||
if (!image_context->has_image()) {
|
||||
SkColorType color_type =
|
||||
@ -689,7 +697,8 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromRenderPass(
|
||||
image_context->SetImage(
|
||||
current_paint_->recorder()->makePromiseTexture(
|
||||
backend_format, image_context->size().width(),
|
||||
image_context->size().height(), image_context->mipmap(),
|
||||
image_context->size().height(),
|
||||
mipmap ? GrMipMapped::kYes : GrMipMapped::kNo,
|
||||
image_context->origin(), color_type, image_context->alpha_type(),
|
||||
image_context->color_space(), Fulfill,
|
||||
/*releaseTextureProc=*/nullptr, image_context.get()),
|
||||
@ -707,7 +716,7 @@ void SkiaOutputSurfaceImpl::RemoveRenderPassResource(
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
DCHECK(!ids.empty());
|
||||
|
||||
std::vector<std::unique_ptr<ImageContextImpl>> image_contexts;
|
||||
std::vector<std::unique_ptr<ExternalUseClient::ImageContext>> image_contexts;
|
||||
image_contexts.reserve(ids.size());
|
||||
for (const auto id : ids) {
|
||||
auto it = render_pass_image_cache_.find(id);
|
||||
@ -720,26 +729,29 @@ void SkiaOutputSurfaceImpl::RemoveRenderPassResource(
|
||||
}
|
||||
}
|
||||
|
||||
// impl_on_gpu_ is released on the GPU thread by a posted task from
|
||||
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
|
||||
auto callback =
|
||||
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource,
|
||||
base::Unretained(impl_on_gpu_.get()), std::move(ids),
|
||||
std::move(image_contexts));
|
||||
// RemoveRenderPassResources will delete gpu resources and needs MakeCurrent.
|
||||
EnqueueGpuTask(std::move(callback), {}, /*make_current=*/true,
|
||||
/*need_framebuffer=*/false);
|
||||
if (!image_contexts.empty()) {
|
||||
// impl_on_gpu_ is released on the GPU thread by a posted task from
|
||||
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
|
||||
auto callback = base::BindOnce(
|
||||
&SkiaOutputSurfaceImplOnGpu::ReleaseImageContexts,
|
||||
base::Unretained(impl_on_gpu_.get()), std::move(image_contexts));
|
||||
// ReleaseImageContexts will delete gpu resources and needs MakeCurrent.
|
||||
EnqueueGpuTask(std::move(callback), {}, /*make_current=*/true,
|
||||
/*need_framebuffer=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaOutputSurfaceImpl::CopyOutput(
|
||||
AggregatedRenderPassId id,
|
||||
const copy_output::RenderPassGeometry& geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) {
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput,
|
||||
base::Unretained(impl_on_gpu_.get()), id,
|
||||
geometry, color_space, std::move(request));
|
||||
auto callback =
|
||||
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput,
|
||||
base::Unretained(impl_on_gpu_.get()), id, geometry,
|
||||
color_space, std::move(request), mailbox);
|
||||
EnqueueGpuTask(std::move(callback), std::move(resource_sync_tokens_),
|
||||
/*make_current=*/true, /*need_framebuffer=*/!id);
|
||||
}
|
||||
@ -1178,6 +1190,10 @@ base::ScopedClosureRunner SkiaOutputSurfaceImpl::GetCacheBackBufferCb() {
|
||||
return dependency_->CacheGLSurface(impl_on_gpu_->gl_surface());
|
||||
}
|
||||
|
||||
gpu::SharedImageInterface* SkiaOutputSurfaceImpl::GetSharedImageInterface() {
|
||||
return display_compositor_controller_->shared_image_interface();
|
||||
}
|
||||
|
||||
void SkiaOutputSurfaceImpl::AddContextLostObserver(
|
||||
ContextLostObserver* observer) {
|
||||
observers_.AddObserver(observer);
|
||||
|
@ -115,7 +115,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
|
||||
const gfx::Size& surface_size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) override;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
void EndPaint(base::OnceClosure on_finished) override;
|
||||
void MakePromiseSkImage(ImageContext* image_context) override;
|
||||
sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
|
||||
@ -123,7 +124,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) override;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
|
||||
void RemoveRenderPassResource(
|
||||
std::vector<AggregatedRenderPassId> ids) override;
|
||||
@ -134,10 +136,12 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
|
||||
void CopyOutput(AggregatedRenderPassId id,
|
||||
const copy_output::RenderPassGeometry& geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) override;
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
void AddContextLostObserver(ContextLostObserver* observer) override;
|
||||
void RemoveContextLostObserver(ContextLostObserver* observer) override;
|
||||
void PreserveChildSurfaceControls() override;
|
||||
gpu::SharedImageInterface* GetSharedImageInterface() override;
|
||||
gpu::SyncToken Flush() override;
|
||||
|
||||
#if defined(OS_APPLE) || defined(USE_OZONE)
|
||||
@ -240,11 +244,13 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
|
||||
explicit ScopedPaint(SkDeferredDisplayListRecorder* root_recorder);
|
||||
explicit ScopedPaint(SkSurfaceCharacterization characterization);
|
||||
ScopedPaint(SkSurfaceCharacterization characterization,
|
||||
AggregatedRenderPassId render_pass_id);
|
||||
AggregatedRenderPassId render_pass_id,
|
||||
gpu::Mailbox mailbox);
|
||||
~ScopedPaint();
|
||||
|
||||
SkDeferredDisplayListRecorder* recorder() { return recorder_; }
|
||||
AggregatedRenderPassId render_pass_id() { return render_pass_id_; }
|
||||
gpu::Mailbox mailbox() { return mailbox_; }
|
||||
|
||||
private:
|
||||
// This is recorder being used for current paint
|
||||
@ -253,6 +259,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
|
||||
// it's stored here
|
||||
absl::optional<SkDeferredDisplayListRecorder> recorder_storage_;
|
||||
const AggregatedRenderPassId render_pass_id_;
|
||||
const gpu::Mailbox mailbox_;
|
||||
};
|
||||
|
||||
// Tracks damage across at most `number_of_buffers`. Note this implementation
|
||||
|
@ -3,11 +3,11 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h"
|
||||
#include <memory>
|
||||
|
||||
#include "base/atomic_sequence_num.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/containers/cxx20_erase.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/trace_event/memory_dump_manager.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
@ -41,6 +41,7 @@
|
||||
#include "gpu/ipc/common/gpu_surface_lookup.h"
|
||||
#include "gpu/vulkan/buildflags.h"
|
||||
#include "skia/buildflags.h"
|
||||
#include "skia/ext/legacy_display_globals.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/libyuv/include/libyuv/planar_functions.h"
|
||||
#include "third_party/skia/include/core/SkDeferredDisplayList.h"
|
||||
@ -444,44 +445,6 @@ CreateSharedImageRepresentationFactory(SkiaOutputSurfaceDependency* deps,
|
||||
|
||||
} // namespace
|
||||
|
||||
// Offscreen surfaces for render passes. It can only be accessed on GPU
|
||||
// thread.
|
||||
class SkiaOutputSurfaceImplOnGpu::OffscreenSurface {
|
||||
public:
|
||||
OffscreenSurface() = default;
|
||||
OffscreenSurface(const OffscreenSurface& offscreen_surface) = delete;
|
||||
OffscreenSurface(OffscreenSurface&& offscreen_surface) = default;
|
||||
OffscreenSurface& operator=(const OffscreenSurface& offscreen_surface) =
|
||||
delete;
|
||||
OffscreenSurface& operator=(OffscreenSurface&& offscreen_surface) = default;
|
||||
~OffscreenSurface() = default;
|
||||
|
||||
SkSurface* surface() { return surface_.get(); }
|
||||
void set_surface(sk_sp<SkSurface> surface) {
|
||||
surface_ = std::move(surface);
|
||||
promise_texture_ = {};
|
||||
}
|
||||
|
||||
SkPromiseImageTexture* fulfill() {
|
||||
DCHECK(surface_);
|
||||
if (!promise_texture_) {
|
||||
promise_texture_ =
|
||||
SkPromiseImageTexture::Make(surface_->getBackendTexture(
|
||||
SkSurface::kFlushRead_BackendHandleAccess));
|
||||
}
|
||||
return promise_texture_.get();
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> TakeSurface() {
|
||||
promise_texture_ = {};
|
||||
return std::move(surface_);
|
||||
}
|
||||
|
||||
private:
|
||||
sk_sp<SkSurface> surface_;
|
||||
sk_sp<SkPromiseImageTexture> promise_texture_;
|
||||
};
|
||||
|
||||
SkiaOutputSurfaceImplOnGpu::ReleaseCurrent::ReleaseCurrent(
|
||||
scoped_refptr<gl::GLSurface> gl_surface,
|
||||
scoped_refptr<gpu::SharedContextState> context_state)
|
||||
@ -709,7 +672,7 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame(
|
||||
if (!begin_semaphores.empty()) {
|
||||
auto result = scoped_output_device_paint_->Wait(
|
||||
begin_semaphores.size(), begin_semaphores.data(),
|
||||
/*deleteSemaphoresAfterWait=*/false);
|
||||
/*delete_semaphores_after_wait=*/false);
|
||||
DCHECK(result);
|
||||
}
|
||||
|
||||
@ -789,7 +752,7 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffersSkipped() {
|
||||
}
|
||||
|
||||
void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
|
||||
AggregatedRenderPassId id,
|
||||
const gpu::Mailbox& mailbox,
|
||||
sk_sp<SkDeferredDisplayList> ddl,
|
||||
std::vector<ImageContextImpl*> image_contexts,
|
||||
std::vector<gpu::SyncToken> sync_tokens,
|
||||
@ -806,30 +769,41 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
|
||||
return;
|
||||
}
|
||||
|
||||
auto& offscreen = offscreen_surfaces_[id];
|
||||
if (!offscreen.surface()) {
|
||||
offscreen.set_surface(SkSurface::MakeRenderTarget(
|
||||
gr_context(), ddl->characterization(), SkBudgeted::kNo));
|
||||
DCHECK(offscreen.surface());
|
||||
auto backing_representation =
|
||||
shared_image_representation_factory_->ProduceSkia(mailbox,
|
||||
context_state_.get());
|
||||
DCHECK(backing_representation);
|
||||
|
||||
std::vector<GrBackendSemaphore> begin_semaphores;
|
||||
std::vector<GrBackendSemaphore> end_semaphores;
|
||||
auto scoped_access = backing_representation->BeginScopedWriteAccess(
|
||||
/*final_msaa_count=*/0, ddl->characterization().surfaceProps(),
|
||||
&begin_semaphores, &end_semaphores,
|
||||
gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
|
||||
if (!scoped_access) {
|
||||
MarkContextLost(CONTEXT_LOST_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
SkSurface* surface = scoped_access->surface();
|
||||
DCHECK(surface);
|
||||
|
||||
{
|
||||
absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
|
||||
if (dependency_->GetGrShaderCache()) {
|
||||
cache_use.emplace(dependency_->GetGrShaderCache(),
|
||||
gpu::kDisplayCompositorClientId);
|
||||
}
|
||||
std::vector<GrBackendSemaphore> begin_semaphores;
|
||||
std::vector<GrBackendSemaphore> end_semaphores;
|
||||
promise_image_access_helper_.BeginAccess(
|
||||
std::move(image_contexts), &begin_semaphores, &end_semaphores);
|
||||
if (!begin_semaphores.empty()) {
|
||||
auto result = offscreen.surface()->wait(
|
||||
begin_semaphores.size(), begin_semaphores.data(),
|
||||
/*deleteSemaphoresAfterWait=*/false);
|
||||
auto result =
|
||||
surface->wait(begin_semaphores.size(), begin_semaphores.data(),
|
||||
/*deleteSemaphoresAfterWait=*/false);
|
||||
DCHECK(result);
|
||||
}
|
||||
offscreen.surface()->draw(ddl);
|
||||
surface->draw(ddl);
|
||||
backing_representation->SetCleared();
|
||||
destroy_after_swap_.emplace_back(std::move(ddl));
|
||||
|
||||
GrFlushInfo flush_info = {
|
||||
@ -840,7 +814,7 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
|
||||
&flush_info);
|
||||
if (on_finished)
|
||||
gpu::AddCleanupTaskForSkiaFlush(std::move(on_finished), &flush_info);
|
||||
auto result = offscreen.surface()->flush(flush_info);
|
||||
auto result = surface->flush(flush_info);
|
||||
if (result != GrSemaphoresSubmitted::kYes &&
|
||||
!(begin_semaphores.empty() && end_semaphores.empty())) {
|
||||
// TODO(penghuang): handle vulkan device lost.
|
||||
@ -855,26 +829,6 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource(
|
||||
std::vector<AggregatedRenderPassId> ids,
|
||||
std::vector<std::unique_ptr<ImageContextImpl>> image_contexts) {
|
||||
TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource");
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
DCHECK(!ids.empty());
|
||||
|
||||
for (AggregatedRenderPassId id : ids) {
|
||||
// It's possible that |offscreen_surfaces_| won't contain an entry for the
|
||||
// render pass if draw failed early.
|
||||
auto it = offscreen_surfaces_.find(id);
|
||||
if (it != offscreen_surfaces_.end()) {
|
||||
DeleteSkSurface(context_state_.get(), it->second.TakeSurface());
|
||||
offscreen_surfaces_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// |image_contexts| will go out of scope and be destroyed now.
|
||||
}
|
||||
|
||||
static void PostTaskFromMainToImplThread(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
|
||||
ReleaseCallback callback,
|
||||
@ -888,7 +842,8 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput(
|
||||
AggregatedRenderPassId id,
|
||||
copy_output::RenderPassGeometry geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) {
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::CopyOutput");
|
||||
// TODO(crbug.com/898595): Do this on the GPU instead of CPU with Vulkan.
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
@ -899,11 +854,33 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput(
|
||||
bool from_framebuffer = !id;
|
||||
DCHECK(scoped_output_device_paint_ || !from_framebuffer);
|
||||
|
||||
DCHECK(from_framebuffer ||
|
||||
offscreen_surfaces_.find(id) != offscreen_surfaces_.end());
|
||||
SkSurface* surface = from_framebuffer
|
||||
? scoped_output_device_paint_->sk_surface()
|
||||
: offscreen_surfaces_[id].surface();
|
||||
SkSurface* surface;
|
||||
std::unique_ptr<gpu::SharedImageRepresentationSkia> backing_representation;
|
||||
std::unique_ptr<gpu::SharedImageRepresentationSkia::ScopedWriteAccess>
|
||||
scoped_access;
|
||||
std::vector<GrBackendSemaphore> begin_semaphores;
|
||||
std::vector<GrBackendSemaphore> end_semaphores;
|
||||
if (from_framebuffer) {
|
||||
surface = scoped_output_device_paint_->sk_surface();
|
||||
} else {
|
||||
backing_representation = shared_image_representation_factory_->ProduceSkia(
|
||||
mailbox, context_state_.get());
|
||||
DCHECK(backing_representation);
|
||||
|
||||
// TODO(crbug.com/1226672): Use BeginScopedReadAccess instead
|
||||
scoped_access = backing_representation->BeginScopedWriteAccess(
|
||||
/*final_msaa_count=*/0, skia::LegacyDisplayGlobals::GetSkSurfaceProps(),
|
||||
&begin_semaphores, &end_semaphores,
|
||||
gpu::SharedImageRepresentation::AllowUnclearedAccess::kNo);
|
||||
surface = scoped_access->surface();
|
||||
if (!begin_semaphores.empty()) {
|
||||
auto result =
|
||||
surface->wait(begin_semaphores.size(), begin_semaphores.data(),
|
||||
/*deleteSemaphoresAfterWait=*/false);
|
||||
DCHECK(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not support reading back from vulkan secondary command buffer.
|
||||
if (!surface)
|
||||
return;
|
||||
@ -1080,6 +1057,23 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput(
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
if (!end_semaphores.empty()) {
|
||||
GrFlushInfo flush_info;
|
||||
flush_info.fNumSemaphores = end_semaphores.size();
|
||||
flush_info.fSignalSemaphores = end_semaphores.data();
|
||||
gpu::AddVulkanCleanupTaskForSkiaFlush(vulkan_context_provider_,
|
||||
&flush_info);
|
||||
auto flush_result =
|
||||
surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flush_info);
|
||||
if (flush_result != GrSemaphoresSubmitted::kYes &&
|
||||
!(begin_semaphores.empty() && end_semaphores.empty())) {
|
||||
// TODO(penghuang): handle vulkan device lost.
|
||||
DLOG(ERROR) << "surface->flush() failed.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScheduleCheckReadbackCompletion();
|
||||
}
|
||||
|
||||
@ -1103,32 +1097,19 @@ void SkiaOutputSurfaceImplOnGpu::BeginAccessImages(
|
||||
|
||||
for (auto* context : image_contexts) {
|
||||
// Prepare for accessing render pass.
|
||||
if (context->render_pass_id()) {
|
||||
// We don't cache promise image for render pass, so the it should always
|
||||
// be nullptr.
|
||||
auto it = offscreen_surfaces_.find(context->render_pass_id());
|
||||
DCHECK(it != offscreen_surfaces_.end());
|
||||
context->set_promise_image_texture(sk_ref_sp(it->second.fulfill()));
|
||||
if (!context->promise_image_texture()) {
|
||||
DLOG(ERROR) << "Failed to fulfill the promise texture created from "
|
||||
"CompositorRenderPassId:"
|
||||
<< context->render_pass_id();
|
||||
}
|
||||
} else {
|
||||
context->BeginAccessIfNecessary(
|
||||
context_state_.get(), shared_image_representation_factory_.get(),
|
||||
dependency_->GetMailboxManager(), begin_semaphores, end_semaphores);
|
||||
if (context->end_access_state())
|
||||
image_contexts_with_end_access_state_.emplace(context);
|
||||
context->BeginAccessIfNecessary(
|
||||
context_state_.get(), shared_image_representation_factory_.get(),
|
||||
dependency_->GetMailboxManager(), begin_semaphores, end_semaphores);
|
||||
if (context->end_access_state())
|
||||
image_contexts_with_end_access_state_.emplace(context);
|
||||
|
||||
// Texture parameters can be modified by concurrent reads so reset them
|
||||
// before compositing from the texture. See https://crbug.com/1092080.
|
||||
if (is_gl && context->maybe_concurrent_reads()) {
|
||||
auto* promise_texture = context->promise_image_texture();
|
||||
if (promise_texture) {
|
||||
GrBackendTexture backend_texture = promise_texture->backendTexture();
|
||||
backend_texture.glTextureParametersModified();
|
||||
}
|
||||
// Texture parameters can be modified by concurrent reads so reset them
|
||||
// before compositing from the texture. See https://crbug.com/1092080.
|
||||
if (is_gl && context->maybe_concurrent_reads()) {
|
||||
auto* promise_texture = context->promise_image_texture();
|
||||
if (promise_texture) {
|
||||
GrBackendTexture backend_texture = promise_texture->backendTexture();
|
||||
backend_texture.glTextureParametersModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ class SkiaOutputSurfaceImplOnGpu
|
||||
void SwapBuffersSkipped();
|
||||
void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); }
|
||||
void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); }
|
||||
void FinishPaintRenderPass(AggregatedRenderPassId id,
|
||||
void FinishPaintRenderPass(const gpu::Mailbox& mailbox,
|
||||
sk_sp<SkDeferredDisplayList> ddl,
|
||||
std::vector<ImageContextImpl*> image_contexts,
|
||||
std::vector<gpu::SyncToken> sync_tokens,
|
||||
@ -160,7 +160,8 @@ class SkiaOutputSurfaceImplOnGpu
|
||||
void CopyOutput(AggregatedRenderPassId id,
|
||||
copy_output::RenderPassGeometry geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request);
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox);
|
||||
|
||||
void BeginAccessImages(const std::vector<ImageContextImpl*>& image_contexts,
|
||||
std::vector<GrBackendSemaphore>* begin_semaphores,
|
||||
@ -228,7 +229,6 @@ class SkiaOutputSurfaceImplOnGpu
|
||||
pending_receiver);
|
||||
|
||||
private:
|
||||
class OffscreenSurface;
|
||||
class DisplayContext;
|
||||
|
||||
bool Initialize();
|
||||
@ -355,8 +355,6 @@ class SkiaOutputSurfaceImplOnGpu
|
||||
absl::optional<OverlayProcessorInterface::OutputSurfaceOverlayPlane>
|
||||
output_surface_plane_;
|
||||
|
||||
base::flat_map<AggregatedRenderPassId, OffscreenSurface> offscreen_surfaces_;
|
||||
|
||||
// Micro-optimization to get to issuing GPU SwapBuffers as soon as possible.
|
||||
std::vector<sk_sp<SkDeferredDisplayList>> destroy_after_swap_;
|
||||
|
||||
|
@ -164,7 +164,7 @@ TEST_F(SkiaOutputSurfaceImplTest, EndPaint) {
|
||||
geometry.readback_offset = gfx::Vector2d(0, 0);
|
||||
|
||||
output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space,
|
||||
std::move(request));
|
||||
std::move(request), gpu::Mailbox());
|
||||
output_surface_->SwapBuffersSkipped(kSurfaceRect);
|
||||
output_surface_->Flush();
|
||||
BlockMainThread();
|
||||
@ -231,7 +231,7 @@ TEST_F(SkiaOutputSurfaceImplTest, CopyOutputBitmapSupportedColorSpace) {
|
||||
|
||||
PaintRootRenderPass(kSurfaceRect, base::DoNothing::Once());
|
||||
output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space,
|
||||
std::move(request));
|
||||
std::move(request), gpu::Mailbox());
|
||||
output_surface_->SwapBuffersSkipped(kSurfaceRect);
|
||||
output_surface_->Flush();
|
||||
run_loop.Run();
|
||||
@ -270,7 +270,7 @@ TEST_F(SkiaOutputSurfaceImplTest, CopyOutputBitmapUnsupportedColorSpace) {
|
||||
|
||||
PaintRootRenderPass(kSurfaceRect, base::DoNothing::Once());
|
||||
output_surface_->CopyOutput(AggregatedRenderPassId{0}, geometry, color_space,
|
||||
std::move(request));
|
||||
std::move(request), gpu::Mailbox());
|
||||
output_surface_->SwapBuffersSkipped(kSurfaceRect);
|
||||
output_surface_->Flush();
|
||||
run_loop.Run();
|
||||
|
@ -193,7 +193,8 @@ SkCanvas* FakeSkiaOutputSurface::BeginPaintRenderPass(
|
||||
const gfx::Size& surface_size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) {
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
// Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
|
||||
DCHECK_EQ(current_render_pass_id_, AggregatedRenderPassId{0u});
|
||||
@ -225,7 +226,8 @@ sk_sp<SkImage> FakeSkiaOutputSurface::MakePromiseSkImageFromRenderPass(
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) {
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
|
||||
auto it = sk_surfaces_.find(id);
|
||||
@ -249,7 +251,8 @@ void FakeSkiaOutputSurface::CopyOutput(
|
||||
AggregatedRenderPassId id,
|
||||
const copy_output::RenderPassGeometry& geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) {
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
|
||||
DCHECK(sk_surfaces_.find(id) != sk_surfaces_.end());
|
||||
@ -305,6 +308,10 @@ void FakeSkiaOutputSurface::CopyOutput(
|
||||
geometry.result_bounds, std::move(bitmap)));
|
||||
}
|
||||
|
||||
gpu::SharedImageInterface* FakeSkiaOutputSurface::GetSharedImageInterface() {
|
||||
return context_provider_->SharedImageInterface();
|
||||
}
|
||||
|
||||
void FakeSkiaOutputSurface::AddContextLostObserver(
|
||||
ContextLostObserver* observer) {
|
||||
NOTIMPLEMENTED();
|
||||
|
@ -79,7 +79,8 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
|
||||
const gfx::Size& surface_size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) override;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
void EndPaint(base::OnceClosure on_finished) override;
|
||||
void MakePromiseSkImage(ImageContext* image_context) override;
|
||||
sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
|
||||
@ -87,7 +88,8 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
|
||||
const gfx::Size& size,
|
||||
ResourceFormat format,
|
||||
bool mipmap,
|
||||
sk_sp<SkColorSpace> color_space) override;
|
||||
sk_sp<SkColorSpace> color_space,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
void RemoveRenderPassResource(
|
||||
std::vector<AggregatedRenderPassId> ids) override;
|
||||
void ScheduleOverlays(OverlayList overlays,
|
||||
@ -99,9 +101,11 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
|
||||
void CopyOutput(AggregatedRenderPassId id,
|
||||
const copy_output::RenderPassGeometry& geometry,
|
||||
const gfx::ColorSpace& color_space,
|
||||
std::unique_ptr<CopyOutputRequest> request) override;
|
||||
std::unique_ptr<CopyOutputRequest> request,
|
||||
const gpu::Mailbox& mailbox) override;
|
||||
void AddContextLostObserver(ContextLostObserver* observer) override;
|
||||
void RemoveContextLostObserver(ContextLostObserver* observer) override;
|
||||
gpu::SharedImageInterface* GetSharedImageInterface() override;
|
||||
gpu::SyncToken Flush() override;
|
||||
#if defined(OS_APPLE) || defined(USE_OZONE)
|
||||
SkCanvas* BeginPaintRenderPassOverlay(
|
||||
|
Reference in New Issue
Block a user