chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <memory>
#include <optional>
#include <unordered_set>
#include <utility>

#include "base/check.h"
#include "base/check_op.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_base.h"
#include "base/notreached.h"
#include "base/pending_task.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_image.h"
#include "cc/paint/paint_op.h"
#include "cc/test/paint_op_matchers.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
#include "gpu/command_buffer/client/test_shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_capabilities.h"
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/metrics/document_update_reason.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_data_settings.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_float32array_uint16array_uint8clampedarray.h"  // IWYU pragma: keep (https://github.com/clangd/clangd/issues/2043)
#include "third_party/blink/renderer/bindings/modules/v8/v8_begin_layer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_will_read_frequently.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/html/canvas/recording_test_utils.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style_test_utils.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types_3d.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h"
#include "third_party/blink/renderer/platform/graphics/test/gpu_memory_buffer_test_platform.h"
#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_status.h"
#include "third_party/blink/renderer/platform/scheduler/public/main_thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkM44.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/skia_util.h"

// Including "base/time/time.h" triggers a bug in IWYU:
// https://github.com/include-what-you-use/include-what-you-use/issues/1122
// IWYU pragma: no_include "base/numerics/clamped_math.h"

// GoogleTest expectation macros trigger a bug in IWYU:
// https://github.com/include-what-you-use/include-what-you-use/issues/1546
// IWYU pragma: no_include <string>

class GrDirectContext;

namespace blink {
class CanvasResourceHost;
class ExecutionContext;
}  // namespace blink

ScopedFeatureList;
ClearRectFlags;
FillFlags;
RecordedOpsAre;
ClipRectOp;
DrawColorOp;
DrawImageRectOp;
DrawPathOp;
DrawRectOp;
PaintOpEq;
PaintOpIs;
RestoreOp;
SaveLayerAlphaOp;
SaveLayerOp;
SaveOp;
SetMatrixOp;
TranslateOp;
_;
Eq;
InSequence;
Message;
Mock;
Optional;
SaveArg;

namespace blink {

enum BitmapOpacity {};

class FakeImageSource : public CanvasImageSource {};

FakeImageSource::FakeImageSource(gfx::Size size, BitmapOpacity opacity)
    :{}

scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas(
    FlushReason,
    SourceImageStatus* status,
    const gfx::SizeF&,
    const AlphaDisposition alpha_disposition = kPremultiplyAlpha) {}

//============================================================================

class CanvasRenderingContext2DTest : public ::testing::Test,
                                     public PaintTestConfigurations {};

INSTANTIATE_PAINT_TEST_SUITE_P();

CanvasRenderingContext2DTest::CanvasRenderingContext2DTest()
    :{}

void CanvasRenderingContext2DTest::CreateContext(
    OpacityMode opacity_mode,
    LatencyMode latency_mode,
    CanvasContextCreationAttributesCore::WillReadFrequently
        will_read_frequently,
    HTMLCanvasElement* canvas) {}

void CanvasRenderingContext2DTest::SetUp() {}

void CanvasRenderingContext2DTest::TearDown() {}

//============================================================================

class FakeCanvasResourceProvider : public CanvasResourceProvider {};

//============================================================================

MATCHER_P(OverdrawOpAreMatcher, expected_overdraw_ops, "") {}

template <typename... Args>
testing::Matcher<base::HistogramTester> OverdrawOpAre(Args... args) {}

TEST_P(CanvasRenderingContext2DTest, FillRect_FullCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DisableOverdrawOptimization) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_ExactCoverage) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_PartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_InsideLayer) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_InsideNestedLayer) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_GlobalAlpha) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_TransparentGradient) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_Filter) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_TransformPartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_TransformCompleteCoverage) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_IgnoreCompositeOp) {}

TEST_P(CanvasRenderingContext2DTest, ClearRect_Clipped) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_ExactCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_Magnified) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_GlobalAlpha) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_TransparentBitmap) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_Filter) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_PartialCoverage1) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_PartialCoverage2) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_FullCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_TransformFullCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_TransformPartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_TransparenBitmapOpaqueGradient) {}

TEST_P(CanvasRenderingContext2DTest,
       DrawImage_OpaqueBitmapTransparentGradient) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_CopyPartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_CopyTransformPartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, DrawImage_Clipped) {}

TEST_P(CanvasRenderingContext2DTest, PutImageData_FullCoverage) {}

TEST_P(CanvasRenderingContext2DTest, PutImageData_PartialCoverage) {}

TEST_P(CanvasRenderingContext2DTest, Path_FullCoverage) {}

//==============================================================================

TEST_P(CanvasRenderingContext2DTest, ImageResourceLifetime) {}

TEST_P(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {}

TEST_P(CanvasRenderingContext2DTest, CanvasDisposedBeforeContext) {}

TEST_P(CanvasRenderingContext2DTest, ContextDisposedBeforeCanvas) {}

TEST_P(CanvasRenderingContext2DTest,
       NoResourceProviderInCanvas2DBufferInitialization) {}

static void TestDrawSingleHighBitDepthPNGOnCanvas(
    String filepath,
    CanvasRenderingContext2D* context,
    PredefinedColorSpace context_color_space,
    Document& document,
    ImageDataSettings* color_setting,
    ScriptState* script_state) {}

static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
    PredefinedColorSpace color_space,
    Document& document,
    Persistent<HTMLCanvasElement> canvas,
    ScriptState* script_state) {}

TEST_P(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) {}

TEST_P(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) {}

// The color settings of the surface of the canvas always remaines loyal to the
// first created context 2D. Therefore, we have to test different canvas color
// space settings for CanvasRenderingContext2D::putImageData() in different
// tests.
enum class PredefinedColorSpaceSettings : uint8_t {};

// This test verifies the correct behavior of putImageData member function in
// color managed mode.
void TestPutImageDataOnCanvasWithColorSpaceSettings(
    HTMLCanvasElement& canvas_element,
    PredefinedColorSpaceSettings canvas_colorspace_setting) {}

// Test disabled due to crbug.com/780925
TEST_P(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) {}

TEST_P(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnRec2020Canvas) {}

TEST_P(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnP3Canvas) {}

TEST_P(CanvasRenderingContext2DTest,
       UnacceleratedLowLatencyIsNotSingleBuffered) {}

TEST_P(CanvasRenderingContext2DTest,
       UnacceleratedIfNormalLatencyWillReadFrequently) {}

TEST_P(CanvasRenderingContext2DTest,
       UnacceleratedIfLowLatencyWillReadFrequently) {}

TEST_P(CanvasRenderingContext2DTest,
       UnacceleratedAfterGetImageDataWithDefaultWillReadFrequently) {}

TEST_P(CanvasRenderingContext2DTest, AutoFlush) {}

TEST_P(CanvasRenderingContext2DTest, AutoFlushPinnedImages) {}

TEST_P(CanvasRenderingContext2DTest, OverdrawResetsPinnedImageBytes) {}

TEST_P(CanvasRenderingContext2DTest, AutoFlushSameImage) {}

TEST_P(CanvasRenderingContext2DTest, AutoFlushDelayedByLayer) {}

class CanvasRenderingContext2DTestAccelerated
    : public CanvasRenderingContext2DTest {};

INSTANTIATE_PAINT_TEST_SUITE_P();

TEST_P(CanvasRenderingContext2DTestAccelerated,
       RemainAcceleratedAfterGetImageDataWithWillNotReadFrequently) {}

// https://crbug.com/708445: When the Canvas2DLayerBridge hibernates or wakes up
// from hibernation, the compositing reasons for the canvas element may change.
// In these cases, the element should request a compositing update.
TEST_P(CanvasRenderingContext2DTestAccelerated,
       ElementRequestsCompositingUpdateOnHibernateAndWakeUp) {}

sk_sp<SkImage> CreateSkImage(int width, int height, SkColor color) {}

ImageBitmap* CreateImageBitmap(int width, int height, SkColor color) {}

MATCHER_P(DrawImageRectOpIs, sk_image, "") {}

TEST_P(CanvasRenderingContext2DTestAccelerated, HibernationWithUnclosedLayer) {}

TEST_P(CanvasRenderingContext2DTestAccelerated,
       NoHibernationIfNoResourceProvider) {}

TEST_P(CanvasRenderingContext2DTestAccelerated, LowLatencyIsNotSingleBuffered) {}

TEST_P(CanvasRenderingContext2DTestAccelerated, DrawImage_Video_Flush) {}

TEST_P(CanvasRenderingContext2DTestAccelerated,
       DISABLED_DisableAcceleration_UpdateGPUMemoryUsage) {}

TEST_P(CanvasRenderingContext2DTestAccelerated,
       DisableAccelerationPreservesRasterAndRecording) {}

class CanvasRenderingContext2DTestAcceleratedMultipleDisables
    : public CanvasRenderingContext2DTest {};

INSTANTIATE_PAINT_TEST_SUITE_P();

TEST_P(CanvasRenderingContext2DTestAcceleratedMultipleDisables,
       ReadFrequentlyUndefined) {}

TEST_P(CanvasRenderingContext2DTestAcceleratedMultipleDisables,
       ReadFrequentlyFalse) {}

TEST_P(CanvasRenderingContext2DTestAcceleratedMultipleDisables,
       ReadFrequentlyTrue) {}

class CanvasRenderingContext2DTestImageChromium
    : public CanvasRenderingContext2DTestAccelerated {};

INSTANTIATE_PAINT_TEST_SUITE_P();

TEST_P(CanvasRenderingContext2DTestImageChromium, LowLatencyIsSingleBuffered) {}

class CanvasRenderingContext2DTestSwapChain
    : public CanvasRenderingContext2DTestAccelerated {};

INSTANTIATE_PAINT_TEST_SUITE_P();

TEST_P(CanvasRenderingContext2DTestSwapChain, LowLatencyIsSingleBuffered) {}

}  // namespace blink