blob: f51db8b84c1155bef5f432b6eb47ddae5811159e [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_OUTPUT_SURFACE_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_OUTPUT_SURFACE_H_
#include <memory>
#include <string>
#include <vector>
#include "build/build_config.h"
#include "components/viz/common/quads/aggregated_render_pass.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/service/display/external_use_client.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/display/overlay_processor_interface.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkYUVAInfo.h"
#include "ui/gfx/gpu_fence_handle.h"
#if BUILDFLAG(IS_WIN)
#include "components/viz/service/display/dc_layer_overlay.h"
#endif
#if BUILDFLAG(IS_APPLE)
#include "components/viz/service/display/ca_layer_overlay.h"
#endif
class SkCanvas;
class SkImage;
namespace gfx {
class ColorSpace;
} // namespace gfx
namespace viz {
class OverlayCandidate;
class ContextLostObserver;
class CopyOutputRequest;
namespace copy_output {
struct RenderPassGeometry;
} // namespace copy_output
// This class extends the OutputSurface for SkiaRenderer needs. In future, the
// SkiaRenderer will be the only renderer. When other renderers are removed,
// we will replace OutputSurface with SkiaOutputSurface, and remove all
// OutputSurface's methods which are not useful for SkiaRenderer.
class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
public ExternalUseClient {
public:
using OverlayList = std::vector<OverlayCandidate>;
explicit SkiaOutputSurface(OutputSurface::Type type);
SkiaOutputSurface(const SkiaOutputSurface&) = delete;
SkiaOutputSurface& operator=(const SkiaOutputSurface&) = delete;
~SkiaOutputSurface() override;
SkiaOutputSurface* AsSkiaOutputSurface() override;
// Begin painting the current frame. This method will create a
// SkDeferredDisplayListRecorder and return a SkCanvas of it.
// The SkiaRenderer will use this SkCanvas to paint the current
// frame.
// And this SkCanvas may become invalid, when FinishPaintCurrentFrame is
// called.
virtual SkCanvas* BeginPaintCurrentFrame() = 0;
// Make a promise SkImage from the given |image_context|. The SkiaRenderer can
// use the image with SkCanvas returned by |GetSkCanvasForCurrentFrame|, but
// Skia will not read the content of the resource until the |sync_token| in
// the |image_context| is satisfied. The SwapBuffers should take care of this
// by scheduling a GPU task with all resource sync tokens recorded by
// MakePromiseSkImage for the current frame. The |yuv_color_space| is the
// original color space needed for yuv to rgb conversion.
virtual void MakePromiseSkImage(
ExternalUseClient::ImageContext* image_context,
const gfx::ColorSpace& yuv_color_space) = 0;
// Make a promise SkImage from the given |contexts| and |image_color_space|.
// The number of contexts provided should match the number of planes indicated
// by plane_config.
virtual sk_sp<SkImage> MakePromiseSkImageFromYUV(
const std::vector<ExternalUseClient::ImageContext*>& contexts,
sk_sp<SkColorSpace> image_color_space,
SkYUVAInfo::PlaneConfig plane_config,
SkYUVAInfo::Subsampling subsampling) = 0;
// Called if SwapBuffers() will be skipped.
virtual void SwapBuffersSkipped(const gfx::Rect root_pass_damage_rect) = 0;
// TODO(weiliangc): This API should move to OverlayProcessor.
// Schedule |output_surface_plane| as an overlay plane to be displayed.
virtual void ScheduleOutputSurfaceAsOverlay(
OverlayProcessorInterface::OutputSurfaceOverlayPlane
output_surface_plane) = 0;
// Begin painting a render pass. This method will create a
// SkDeferredDisplayListRecorder and return a SkCanvas of it. The SkiaRenderer
// will use this SkCanvas to paint the render pass.
// Note: BeginPaintRenderPass cannot be called without finishing the prior
// paint render pass.
virtual SkCanvas* BeginPaintRenderPass(const AggregatedRenderPassId& id,
const gfx::Size& size,
SharedImageFormat format,
bool mipmap,
bool scanout_dcomp_surface,
sk_sp<SkColorSpace> color_space,
bool is_overlay,
const gpu::Mailbox& mailbox) = 0;
// Create an overdraw recorder for the current paint which will be drawn on
// top of the current canvas when EndPaint() is called. Returns the new
// wrapped SkCanvas to be used by SkiaRenderer.
// This should be called for the root render pass only when
// debug_settings.show_overdraw_feedback = true.
virtual SkCanvas* RecordOverdrawForCurrentPaint() = 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
// play the DDL back on GPU thread on a cached SkSurface.
// Optionally the caller may specify |on_finished| callback to be called after
// the GPU has finished processing all submitted commands. The callback may be
// called on a different thread. The caller may also specify
// |return_release_fence_cb| callback to be called after all commands are
// submitted. The callback will return the release fence which will be
// signaled once the submitted commands are processed.
// |update_rect| should be the scissor rect used to clear the render pass
// backing and cull its draw quads.
// When finishing painting of a render pass that will be presented as an
// overlay, |is_overlay| should be true so the GPU thread knows to keep the
// ScopedWriteAccess open long enough.
virtual void EndPaint(
base::OnceClosure on_finished,
base::OnceCallback<void(gfx::GpuFenceHandle)> return_release_fence_cb,
const gfx::Rect& update_rect,
bool is_overlay) = 0;
// Make a promise SkImage from a render pass id. The render pass has been
// painted with BeginPaintRenderPass and FinishPaintRenderPass. The format
// and mipmap must match arguments used for BeginPaintRenderPass() to paint
// this render pass.
virtual sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
const AggregatedRenderPassId& id,
const gfx::Size& size,
SharedImageFormat format,
bool mipmap,
sk_sp<SkColorSpace> color_space,
const gpu::Mailbox& mailbox) = 0;
// Remove cached resources generated by BeginPaintRenderPass and
// FinishPaintRenderPass.
virtual void RemoveRenderPassResource(
std::vector<AggregatedRenderPassId> ids) = 0;
// Copy the output of the current frame if the |mailbox| is zero, otherwise
// create an SkSurface for the given |mailbox| and copy the output.
virtual void CopyOutput(const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
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.
// Optionally the caller may specify |on_finished| callback to be called after
// the GPU has finished processing all submitted commands. The callback may be
// called on a different thread.
virtual void ScheduleOverlays(OverlayList overlays,
std::vector<gpu::SyncToken> sync_tokens) = 0;
// Add context lost observer.
virtual void AddContextLostObserver(ContextLostObserver* observer) = 0;
// Remove context lost observer.
virtual void RemoveContextLostObserver(ContextLostObserver* observer) = 0;
// Only used for SkiaOutputSurfaceImpl unit tests.
virtual void ScheduleGpuTaskForTesting(
base::OnceClosure callback,
std::vector<gpu::SyncToken> sync_tokens) = 0;
// Android specific, asks GLSurfaceEGLSurfaceControl to not detach child
// surface controls during destruction. This is necessary for cases when we
// switch from chrome to other app, the OS will take care of the cleanup.
virtual void PreserveChildSurfaceControls() = 0;
// Flush pending GPU tasks. This method returns a sync token which can be
// waited on in a command buffer to ensure all pending tasks are executed on
// the GPU main thread.
virtual gpu::SyncToken Flush() = 0;
// Set the number of frame buffers to use when
// `supports_dynamic_frame_buffer_allocation` is true. `n` must satisfy
// 0 < n <= capabilities_.number_of_buffers.
// Return true if new buffers are allocated.
virtual bool EnsureMinNumberOfBuffers(int n) = 0;
// Enqueue a GPU task to create a shared image with the specified params and
// returns the mailbox.
// Note: |kTopLeft_GrSurfaceOrigin| and |kPremul_SkAlphaType| params are used
// for all images.
virtual gpu::Mailbox CreateSharedImage(SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage,
base::StringPiece debug_label,
gpu::SurfaceHandle surface_handle) = 0;
// Enqueue a GPU task to create a 1x1 shared image of the specified color.
virtual gpu::Mailbox CreateSolidColorSharedImage(
const SkColor4f& color,
const gfx::ColorSpace& color_space) = 0;
// Enqueue a GPU task to delete the specified shared image.
virtual void DestroySharedImage(const gpu::Mailbox& mailbox) = 0;
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_OUTPUT_SURFACE_H_