chromium/cc/tiles/gpu_image_decode_cache_unittest.cc

// Copyright 2016 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 "cc/tiles/gpu_image_decode_cache.h"

#include <algorithm>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_mock_time_task_runner.h"
#include "cc/base/features.h"
#include "cc/base/switches.h"
#include "cc/paint/color_filter.h"
#include "cc/paint/draw_image.h"
#include "cc/paint/image_transfer_cache_entry.h"
#include "cc/paint/paint_image.h"
#include "cc/paint/paint_image_builder.h"
#include "cc/paint/paint_op_writer.h"
#include "cc/test/fake_paint_image_generator.h"
#include "cc/test/skia_common.h"
#include "cc/test/test_tile_task_runner.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "cc/tiles/raster_dark_mode_filter.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
#include "gpu/command_buffer/client/raster_implementation_gles.h"
#include "gpu/command_buffer/common/command_buffer_id.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/config/gpu_finch_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageGenerator.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkM44.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkYUVAPixmaps.h"
#include "third_party/skia/include/effects/SkHighContrastFilter.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/ganesh/SkImageGanesh.h"

_;
StrictMock;

namespace cc {
namespace {

class FakeDiscardableManager {};

class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
                                             public viz::TestContextSupport {};

class MockRasterImplementation : public gpu::raster::RasterImplementationGLES {};

class GPUImageDecodeTestMockContextProvider : public viz::TestContextProvider {};

class FakeRasterDarkModeFilter : public RasterDarkModeFilter {};

SkM44 CreateMatrix(const SkSize& scale) {}

#define EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE

#define EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE

size_t kGpuMemoryLimitBytes =;

class GpuImageDecodeCacheTest
    : public ::testing::TestWithParam<
          std::tuple<SkColorType,
                     bool /* use_transfer_cache */,
                     bool /* do_yuv_decode */,
                     bool /* allow_accelerated_jpeg_decoding */,
                     bool /* allow_accelerated_webp_decoding */,
                     bool /* advertise_accelerated_decoding */,
                     bool /* enable_clipped_image_scaling */,
                     bool /* no_discardable_memory */>> {};

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImage) {}

// Tests that when the GpuImageDecodeCache is used by multiple clients at the
// same time, each client gets own task for the same image and only the task
// that was executed first does decode/upload. All the consequent tasks for the
// same image are no-op.
TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSameImageDifferentClients) {}

// Verifies that if a client1 has uploaded the image, but haven't had its task
// mark as completed, a client2 doesn't have a task created. Otherwise, it'll
// crash while trying to create a decode task, which checks if the image data
// has already been uploaded.
TEST_P(GpuImageDecodeCacheTest, DoesNotCreateATaskForAlreadyUploadedImage) {}

// Almost the same as DoesNotCreateATaskForAlreadyUploadedImage, but with a
// single client and a second request for a standalone decode task.
TEST_P(GpuImageDecodeCacheTest, DoesNotCreateATaskForAlreadyUploadedImage2) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageSmallerScale) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLowerQuality) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentImage) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScale) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageLargerScaleNoReuse) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageHigherQuality) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedAndLocked) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyDecodedNotLocked) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageAlreadyUploaded) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledGetsNewTask) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageCanceledWhileReffedGetsNewTask) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageUploadCanceledButDecodeRun) {}

TEST_P(GpuImageDecodeCacheTest, NoTaskForImageAlreadyFailedDecoding) {}

TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDraw) {}

TEST_P(GpuImageDecodeCacheTest, GetHdrDecodedImageForDrawToHdr) {}

TEST_P(GpuImageDecodeCacheTest, GetHdrDecodedImageForDrawToSdr) {}

TEST_P(GpuImageDecodeCacheTest, GetLargeDecodedImageForDraw) {}

TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawAtRasterDecode) {}

TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawLargerScale) {}

TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawHigherQuality) {}

TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawNegative) {}

TEST_P(GpuImageDecodeCacheTest, GetLargeScaledDecodedImageForDraw) {}

TEST_P(GpuImageDecodeCacheTest, AtRasterUsedDirectlyIfSpaceAllows) {}

TEST_P(GpuImageDecodeCacheTest,
       GetDecodedImageForDrawAtRasterDecodeMultipleTimes) {}

TEST_P(GpuImageDecodeCacheTest,
       GetLargeDecodedImageForDrawAtRasterDecodeMultipleTimes) {}

TEST_P(GpuImageDecodeCacheTest, ZeroSizedImagesAreSkipped) {}

TEST_P(GpuImageDecodeCacheTest, NonOverlappingSrcRectImagesAreSkipped) {}

TEST_P(GpuImageDecodeCacheTest, CanceledTasksDoNotCountAgainstBudget) {}

TEST_P(GpuImageDecodeCacheTest, ShouldAggressivelyFreeResources) {}

TEST_P(GpuImageDecodeCacheTest, OrphanedImagesFreeOnReachingZeroRefs) {}

TEST_P(GpuImageDecodeCacheTest, OrphanedZeroRefImagesImmediatelyDeleted) {}

TEST_P(GpuImageDecodeCacheTest, QualityCappedAtMedium) {}

// Ensure that switching to a mipped version of an image after the initial
// cache entry creation doesn't cause a buffer overflow/crash.
TEST_P(GpuImageDecodeCacheTest, GetDecodedImageForDrawMipUsageChange) {}

TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTask) {}

// Verifies that only one client's task does real decoding. All the consequent
// clients who want to decode the same image have their tasks as no-op.
TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeTaskMultipleClients) {}

TEST_P(GpuImageDecodeCacheTest,
       DoesNotCreateOutOfRasterDecodeTaskForNonCompletedTask) {}

TEST_P(GpuImageDecodeCacheTest, ZeroCacheNormalWorkingSet) {}

TEST_P(GpuImageDecodeCacheTest, SmallCacheNormalWorkingSet) {}

TEST_P(GpuImageDecodeCacheTest, ClearCache) {}

TEST_P(GpuImageDecodeCacheTest, ClearCacheInUse) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForImageDifferentColorSpace) {}

TEST_P(GpuImageDecodeCacheTest, GetTaskForLargeImageNonSRGBColorSpace) {}

TEST_P(GpuImageDecodeCacheTest, CacheDecodesExpectedFrames) {}

TEST_P(GpuImageDecodeCacheTest, OrphanedDataCancelledWhileReplaced) {}

TEST_P(GpuImageDecodeCacheTest, AlreadyBudgetedImagesAreNotAtRaster) {}

TEST_P(GpuImageDecodeCacheTest, ImageBudgetingByCount) {}

TEST_P(GpuImageDecodeCacheTest, ImageBudgetingBySize) {}

TEST_P(GpuImageDecodeCacheTest,
       ColorConversionDuringDecodeForLargeImageNonSRGBColorSpace) {}

TEST_P(GpuImageDecodeCacheTest,
       ColorConversionDuringUploadForSmallImageNonSRGBColorSpace) {}

TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadNoScale) {}

TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskHasNoDeps) {}

TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadTaskCancelled) {}

TEST_P(GpuImageDecodeCacheTest,
       NonLazyImageUploadTaskCancelledMultipleClients) {}

TEST_P(GpuImageDecodeCacheTest, NonLazyImageLargeImageNotColorConverted) {}

TEST_P(GpuImageDecodeCacheTest, NonLazyImageUploadDownscaled) {}

TEST_P(GpuImageDecodeCacheTest, KeepOnlyLast2ContentIds) {}

TEST_P(GpuImageDecodeCacheTest, DecodeToScale) {}

TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {}

TEST_P(GpuImageDecodeCacheTest, BasicMips) {}

TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {}

TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {}

TEST_P(GpuImageDecodeCacheTest,
       OriginalYUVDecodeScaledDrawCorrectlyMipsPlanes) {}

TEST_P(GpuImageDecodeCacheTest, HighBitDepthYUVDecoding) {}

TEST_P(GpuImageDecodeCacheTest, ScaledYUVDecodeScaledDrawCorrectlyMipsPlanes) {}

TEST_P(GpuImageDecodeCacheTest, GetBorderlineLargeDecodedImageForDraw) {}

TEST_P(GpuImageDecodeCacheTest, OutOfRasterDecodeForBitmaps) {}

TEST_P(GpuImageDecodeCacheTest, DarkModeDecodedDrawImage) {}

TEST_P(GpuImageDecodeCacheTest, DarkModeImageCacheSize) {}

TEST_P(GpuImageDecodeCacheTest, DarkModeNeedsDarkModeFilter) {}

TEST_P(GpuImageDecodeCacheTest, ClippedAndScaledDrawImageRemovesCacheEntry) {}

SkColorType test_color_types[] =;

INSTANTIATE_TEST_SUITE_P();

INSTANTIATE_TEST_SUITE_P();

class GpuImageDecodeCacheWithAcceleratedDecodesTest
    : public GpuImageDecodeCacheTest {};

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       RequestAcceleratedDecodeSuccessfully) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       RequestAcceleratedDecodeSuccessfullyWithColorSpaceConversion) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       AcceleratedDecodeRequestFails) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       CannotRequestAcceleratedDecodeBecauseOfStandAloneDecode) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       CannotRequestAcceleratedDecodeBecauseOfNonZeroUploadMipLevel) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       RequestAcceleratedDecodeSuccessfullyAfterCancellation) {}

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
       RequestAcceleratedDecodeSuccessfullyAtRasterTime) {}

INSTANTIATE_TEST_SUITE_P();

class GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest
    : public GpuImageDecodeCacheWithAcceleratedDecodesTest {};

TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
       RequestAcceleratedDecodeSuccessfully) {}

INSTANTIATE_TEST_SUITE_P();

class GpuImageDecodeCachePurgeOnTimerTest : public GpuImageDecodeCacheTest {};

GpuImageDecodeCachePurgeOnTimerTest*
    GpuImageDecodeCachePurgeOnTimerTest::last_setup_test_ =;

TEST_P(GpuImageDecodeCachePurgeOnTimerTest, SimplePurgeOneImage) {}

// Tests that we are able to purge multiple images from cache.
TEST_P(GpuImageDecodeCachePurgeOnTimerTest, SimplePurgeMultipleImages) {}

TEST_P(GpuImageDecodeCachePurgeOnTimerTest, MultipleImagesWithDelay) {}

TEST_P(GpuImageDecodeCachePurgeOnTimerTest, MultipleImagesWithTimeGap) {}

TEST_P(GpuImageDecodeCachePurgeOnTimerTest, NoDeadlock) {}

TEST_P(GpuImageDecodeCachePurgeOnTimerTest, NoCache) {}

INSTANTIATE_TEST_SUITE_P();

#undef EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE
#undef EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE

}  // namespace
}  // namespace cc