chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"

#include <string>

#include "base/debug/dump_without_crashing.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "base/task/bind_post_task.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "cc/paint/decode_stashing_image_provider.h"
#include "cc/paint/display_item_list.h"
#include "cc/tiles/software_image_decode_cache.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_capabilities.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_feature_type.h"
#include "skia/buildflags.h"
#include "skia/ext/legacy_display_globals.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_shared_image_interface_provider.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/instrumentation/canvas_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GpuTypes.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/GrTypes.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"

namespace blink {

class FlushForImageListener {};

static FlushForImageListener* GetFlushForImageListener() {}

namespace {

bool IsGMBAllowed(const SkImageInfo& info, const gpu::Capabilities& caps) {}

}  // namespace

class CanvasResourceProvider::CanvasImageProvider : public cc::ImageProvider {};

// * Renders to a Skia RAM-backed bitmap.
// * Mailboxing is not supported : cannot be directly composited.
class CanvasResourceProviderBitmap : public CanvasResourceProvider {};

// * Renders to a shared memory bitmap.
// * Uses SharedBitmaps to pass frames directly to the compositor.
class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap,
                                           public BitmapGpuChannelLostObserver {};

// * Renders to a SharedImage, which manages memory internally.
// * Layers are overlay candidates.
class CanvasResourceProviderSharedImage : public CanvasResourceProvider {};

// This class does nothing except answering to ProduceCanvasResource() by piping
// it to NewOrRecycledResource().  This ResourceProvider is meant to be used
// with an imported external CanvasResource, and all drawing and lifetime logic
// must be kept at a higher level.
class CanvasResourceProviderPassThrough final : public CanvasResourceProvider {};

// * Renders to back buffer of a shared image swap chain.
// * Presents swap chain and exports front buffer mailbox to compositor to
//   support low latency mode.
// * Layers are overlay candidates.
class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {};

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateBitmapProvider(
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    ShouldInitialize should_initialize,
    CanvasResourceHost* resource_host) {}

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateSharedBitmapProvider(
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    ShouldInitialize should_initialize,
    base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
    WebGraphicsSharedImageInterfaceProvider* shared_image_interface_provider,
    CanvasResourceHost* resource_host) {}

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateSharedImageProvider(
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    ShouldInitialize should_initialize,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
    RasterMode raster_mode,
    uint32_t shared_image_usage_flags,
    CanvasResourceHost* resource_host) {}

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateWebGPUImageProvider(
    const SkImageInfo& info,
    uint32_t shared_image_usage_flags,
    CanvasResourceHost* resource_host) {}

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreatePassThroughProvider(
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
    base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
    bool is_origin_top_left,
    CanvasResourceHost* resource_host) {}

std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateSwapChainProvider(
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    ShouldInitialize should_initialize,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
    base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
    CanvasResourceHost* resource_host) {}

CanvasResourceProvider::CanvasImageProvider::CanvasImageProvider(
    cc::ImageDecodeCache* cache_n32,
    cc::ImageDecodeCache* cache_f16,
    const gfx::ColorSpace& target_color_space,
    SkColorType canvas_color_type,
    cc::PlaybackImageProvider::RasterMode raster_mode)
    :{}

cc::ImageProvider::ScopedResult
CanvasResourceProvider::CanvasImageProvider::GetRasterContent(
    const cc::DrawImage& draw_image) {}

void CanvasResourceProvider::CanvasImageProvider::CanUnlockImage(
    ScopedResult image) {}

void CanvasResourceProvider::CanvasImageProvider::CleanupLockedImages() {}

bool CanvasResourceProvider::CanvasImageProvider::IsHardwareDecodeCache()
    const {}

BASE_FEATURE();

// When enabled, unused resources (ready to be recycled) are reclaimed after a
// delay.
BASE_FEATURE();

// The following parameters attempt to reach a compromise between not flushing
// too often, and not accumulating an unreasonable backlog. Flushing too
// often will hurt performance due to overhead costs. Accumulating large
// backlogs, in the case of OOPR-Canvas, results in poor parellelism and
// janky UI. With OOPR-Canvas disabled, it is still desirable to flush
// periodically to guard against run-away memory consumption caused by
// PaintOpBuffers that grow indefinitely. The OOPR-related jank is caused by
// long-running RasterCHROMIUM calls that monopolize the main thread
// of the GPU process. By flushing periodically, we allow the rasterization
// of canvas contents to be interleaved with other compositing and UI work.
//
// The default values for these parameters were initially determined
// empirically. They were selected to maximize the MotionMark score on
// desktop computers. Field trials may be used to tune these parameters
// further by using metrics data from the field.
const base::FeatureParam<int> kMaxRecordedOpKB(&kCanvas2DAutoFlushParams,
                                               "max_recorded_op_kb",
                                               2 * 1024);

const base::FeatureParam<int> kMaxPinnedImageKB(&kCanvas2DAutoFlushParams,
                                                "max_pinned_image_kb",
                                                32 * 1024);

// Graphite can generally handle more ops, increase the size accordingly.
const base::FeatureParam<int> kMaxRecordedOpGraphiteKB(
    &kCanvas2DAutoFlushParams,
    "max_recorded_op_graphite_kb",
    6 * 1024);

CanvasResourceProvider::CanvasResourceProvider(
    const ResourceProviderType& type,
    const SkImageInfo& info,
    cc::PaintFlags::FilterQuality filter_quality,
    bool is_origin_top_left,
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
    base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
    CanvasResourceHost* resource_host)
    :{}

CanvasResourceProvider::~CanvasResourceProvider() {}

std::unique_ptr<MemoryManagedPaintRecorder>
CanvasResourceProvider::ReleaseRecorder() {}

void CanvasResourceProvider::SetRecorder(
    std::unique_ptr<MemoryManagedPaintRecorder> recorder) {}

void CanvasResourceProvider::FlushIfRecordingLimitExceeded() {}

SkSurface* CanvasResourceProvider::GetSkSurface() const {}

void CanvasResourceProvider::NotifyWillTransfer(
    cc::PaintImage::ContentId content_id) {}

bool CanvasResourceProvider::OverwriteImage(
    const gpu::Mailbox& shared_image_mailbox,
    const gfx::Rect& copy_rect,
    bool unpack_flip_y,
    bool unpack_premultiply_alpha,
    const gpu::SyncToken& ready_sync_token,
    gpu::SyncToken& completion_sync_token) {}

void CanvasResourceProvider::EnsureSkiaCanvas() {}

CanvasResourceProvider::CanvasImageProvider*
CanvasResourceProvider::GetOrCreateCanvasImageProvider() {}

void CanvasResourceProvider::InitializeForRecording(
    cc::PaintCanvas* canvas) const {}

void CanvasResourceProvider::RecordingCleared() {}

MemoryManagedPaintCanvas& CanvasResourceProvider::Canvas(bool needs_will_draw) {}

void CanvasResourceProvider::OnContextDestroyed() {}

void CanvasResourceProvider::OnFlushForImage(PaintImage::ContentId content_id) {}

void CanvasResourceProvider::ReleaseLockedImages() {}

scoped_refptr<StaticBitmapImage> CanvasResourceProvider::SnapshotInternal(
    ImageOrientation orientation,
    FlushReason reason) {}

cc::PaintImage CanvasResourceProvider::MakeImageSnapshot(FlushReason reason) {}

gpu::gles2::GLES2Interface* CanvasResourceProvider::ContextGL() const {}

gpu::raster::RasterInterface* CanvasResourceProvider::RasterInterface() const {}

GrDirectContext* CanvasResourceProvider::GetGrContext() const {}

gfx::Size CanvasResourceProvider::Size() const {}

SkSurfaceProps CanvasResourceProvider::GetSkSurfaceProps() const {}

gfx::ColorSpace CanvasResourceProvider::GetColorSpace() const {}

std::optional<cc::PaintRecord> CanvasResourceProvider::FlushCanvas(
    FlushReason reason) {}

void CanvasResourceProvider::RasterRecord(cc::PaintRecord last_recording) {}

void CanvasResourceProvider::RasterRecordOOP(cc::PaintRecord last_recording,
                                             bool needs_clear,
                                             gpu::Mailbox mailbox) {}

bool CanvasResourceProvider::IsGpuContextLost() const {}

bool CanvasResourceProvider::IsSharedBitmapGpuChannelLost() const {}

bool CanvasResourceProvider::WritePixels(const SkImageInfo& orig_info,
                                         const void* pixels,
                                         size_t row_bytes,
                                         int x,
                                         int y) {}

void CanvasResourceProvider::Clear() {}

uint32_t CanvasResourceProvider::ContentUniqueID() const {}

scoped_refptr<CanvasResource> CanvasResourceProvider::CreateResource() {}

cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCacheRGBA8() {}

cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCacheF16() {}

void CanvasResourceProvider::RecycleResource(
    scoped_refptr<CanvasResource>&& resource) {}

void CanvasResourceProvider::SetResourceRecyclingEnabled(bool value) {}

void CanvasResourceProvider::ClearRecycledResources() {}

void CanvasResourceProvider::OnDestroyResource() {}

void CanvasResourceProvider::RegisterUnusedResource(
    scoped_refptr<CanvasResource>&& resource) {}

void CanvasResourceProvider::MaybePostUnusedResourcesReclaimTask() {}

void CanvasResourceProvider::ClearOldUnusedResources() {}

scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() {}

void CanvasResourceProvider::TryEnableSingleBuffering() {}

bool CanvasResourceProvider::ImportResource(
    scoped_refptr<CanvasResource>&& resource) {}

scoped_refptr<CanvasResource> CanvasResourceProvider::GetImportedResource()
    const {}

void CanvasResourceProvider::RestoreBackBuffer(const cc::PaintImage& image) {}

void CanvasResourceProvider::TearDownSkSurface() {}

size_t CanvasResourceProvider::ComputeSurfaceSize() const {}

void CanvasResourceProvider::OnMemoryDump(
    base::trace_event::ProcessMemoryDump* pmd) {}

size_t CanvasResourceProvider::GetSize() const {}

void CanvasResourceProvider::DisableLineDrawingAsPathsIfNecessary() {}

}  // namespace blink