chromium/cc/tiles/gpu_image_decode_cache.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 <inttypes.h>

#include <algorithm>
#include <limits>
#include <string>

#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/span.h"
#include "base/debug/alias.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/hash/hash.h"
#include "base/logging.h"
#include "base/memory/discardable_memory_allocator.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/numerics/safe_math.h"
#include "base/ranges/algorithm.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_manager.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/features.h"
#include "cc/base/histograms.h"
#include "cc/base/switches.h"
#include "cc/paint/paint_flags.h"
#include "cc/raster/scoped_grcontext_access.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/mipmap_util.h"
#include "cc/tiles/raster_dark_mode_filter.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_info.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkSamplingOptions.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkYUVAPixmaps.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/GrYUVABackendTextures.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gl/trace_util.h"

namespace cc {

namespace {

// The number or entries to keep in the cache, depending on the memory state of
// the system. This limit can be breached by in-use cache items, which cannot
// be deleted.
static const int kNormalMaxItemsInCacheForGpu =;
static const int kSuspendedMaxItemsInCacheForGpu =;

// The maximum number of images that we can lock simultaneously in our working
// set. This is separate from the memory limit, as keeping very large numbers
// of small images simultaneously locked can lead to performance issues and
// memory spikes.
static const int kMaxItemsInWorkingSet =;

// lock_count │ used  │ result state
// ═══════════╪═══════╪══════════════════
//  1         │ false │ WASTED_ONCE
//  1         │ true  │ USED_ONCE
//  >1        │ false │ WASTED_RELOCKED
//  >1        │ true  │ USED_RELOCKED
// Note that it's important not to reorder the following enum, since the
// numerical values are used in the histogram code.
enum ImageUsageState : int {};

// Returns true if an image would not be drawn and should therefore be
// skipped rather than decoded.
bool SkipImage(const DrawImage& draw_image) {}

// Returns the filter quality to use for scaling the image to upload scale as
// well as for using when passing the decoded image to skia. Due to parity with
// SW and power impliciation, limit the filter quality to medium.
PaintFlags::FilterQuality CalculateDesiredFilterQuality(
    const DrawImage& draw_image) {}

// Calculates the scale factor which can be used to scale an image to a given
// mip level.
SkSize CalculateScaleFactorForMipLevel(const DrawImage& draw_image,
                                       AuxImage aux_image,
                                       int upload_scale_mip_level) {}

// Calculates the size of a given mip level.
gfx::Size CalculateSizeForMipLevel(const DrawImage& draw_image,
                                   AuxImage aux_image,
                                   int upload_scale_mip_level) {}

// Determines whether a draw image requires mips.
bool ShouldGenerateMips(const DrawImage& draw_image,
                        AuxImage aux_image,
                        int upload_scale_mip_level) {}

// Estimates the byte size of the decoded data for an image that goes through
// hardware decode acceleration. The actual byte size is only known once the
// image is decoded in the service side because different drivers have different
// pixel format and alignment requirements.
size_t EstimateHardwareDecodedDataSize(
    const ImageHeaderMetadata* image_metadata) {}

// Draws and scales the provided |draw_image| into the |target_pixmap|. If the
// draw/scale can be done directly, calls directly into PaintImage::Decode.
// if not, decodes to a compatible temporary pixmap and then converts that into
// the |target_pixmap|.
bool DrawAndScaleImageRGB(const DrawImage& draw_image,
                          AuxImage aux_image,
                          SkPixmap& target_pixmap,
                          PaintImage::GeneratorClientId client_id) {}

// Decode and scale for YUV pixmaps.
//
// The pixmaps in `yuva_pixmaps` share a contiguous block of allocated backing
// memory. If scaling needs to happen, it is done individually for each plane.
bool DrawAndScaleImageYUV(
    const DrawImage& draw_image,
    AuxImage aux_image,
    PaintImage::GeneratorClientId client_id,
    const SkYUVAPixmapInfo::SupportedDataTypes& yuva_supported_data_types,
    SkYUVAPixmaps& yuva_pixmaps) {}

// Takes ownership of the backing texture of an SkImage. This allows us to
// delete this texture under Skia (via discardable).
sk_sp<SkImage> TakeOwnershipOfSkImageBacking(GrDirectContext* context,
                                             sk_sp<SkImage> image) {}

// Immediately deletes an SkImage, preventing caching of that image. Must be
// called while holding the context lock.
void DeleteSkImageAndPreventCaching(viz::RasterContextProvider* context,
                                    sk_sp<SkImage>&& image) {}

// TODO(ericrk): Replace calls to this with calls to SkImages::TextureFromImage,
// once that function handles colorspaces. https://crbug.com/834837
sk_sp<SkImage> MakeTextureImage(viz::RasterContextProvider* context,
                                sk_sp<SkImage> source_image,
                                sk_sp<SkColorSpace> target_color_space,
                                skgpu::Mipmapped mip_mapped) {}

// We use this below, instead of just a std::unique_ptr, so that we can run
// a Finch experiment to check the impact of not using discardable memory on the
// GPU decode path.
class HeapDiscardableMemory : public base::DiscardableMemory {};

std::optional<SkYUVAPixmapInfo> GetYUVADecodeInfo(
    const DrawImage& draw_image,
    AuxImage aux_image,
    const SkISize target_size,
    const SkYUVAPixmapInfo::SupportedDataTypes& yuva_supported_data_types) {}

bool NeedsToneMapping(sk_sp<SkColorSpace> image_color_space, bool has_gainmap) {}

}  // namespace

// Extract the information to uniquely identify a DrawImage for the purposes of
// the |in_use_cache_|.
GpuImageDecodeCache::InUseCacheKey::InUseCacheKey(const DrawImage& draw_image,
                                                  int mip_level)
    :{}

bool GpuImageDecodeCache::InUseCacheKey::operator==(
    const InUseCacheKey& other) const {}

size_t GpuImageDecodeCache::InUseCacheKeyHash::operator()(
    const InUseCacheKey& cache_key) const {}

GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(
    scoped_refptr<ImageData> image_data)
    :{}
GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(const InUseCacheEntry&) =
    default;
GpuImageDecodeCache::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) =
    default;
GpuImageDecodeCache::InUseCacheEntry::~InUseCacheEntry() = default;

// Task which decodes an image and stores the result in discardable memory.
// This task does not use GPU resources and can be run on any thread.
class GpuImageDecodeTaskImpl : public TileTask {};

// Task which creates an image from decoded data. Typically this involves
// uploading data to the GPU, which requires this task be run on the non-
// concurrent thread.
class ImageUploadTaskImpl : public TileTask {};

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::ImageDataBase

GpuImageDecodeCache::ImageDataBase::ImageDataBase() = default;
GpuImageDecodeCache::ImageDataBase::~ImageDataBase() = default;

void GpuImageDecodeCache::ImageDataBase::OnSetLockedData(bool out_of_raster) {}

void GpuImageDecodeCache::ImageDataBase::OnResetData() {}

void GpuImageDecodeCache::ImageDataBase::OnLock() {}

void GpuImageDecodeCache::ImageDataBase::OnUnlock() {}

int GpuImageDecodeCache::ImageDataBase::UsageState() const {}

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::DecodedAuxImageData

GpuImageDecodeCache::DecodedAuxImageData::DecodedAuxImageData() = default;

GpuImageDecodeCache::DecodedAuxImageData::DecodedAuxImageData(
    const SkPixmap& rgba_pixmap,
    std::unique_ptr<base::DiscardableMemory> in_data) {}

GpuImageDecodeCache::DecodedAuxImageData::DecodedAuxImageData(
    const SkYUVAPixmaps& yuva_pixmaps,
    std::unique_ptr<base::DiscardableMemory> in_data) {}

GpuImageDecodeCache::DecodedAuxImageData::DecodedAuxImageData(
    DecodedAuxImageData&& other)
    :{}

GpuImageDecodeCache::DecodedAuxImageData&
GpuImageDecodeCache::DecodedAuxImageData::operator=(
    DecodedAuxImageData&& other) {}

GpuImageDecodeCache::DecodedAuxImageData::~DecodedAuxImageData() = default;

bool GpuImageDecodeCache::DecodedAuxImageData::IsEmpty() const {}

void GpuImageDecodeCache::DecodedAuxImageData::ResetData() {}

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::DecodedImageData

GpuImageDecodeCache::DecodedImageData::DecodedImageData(
    bool is_bitmap_backed,
    bool can_do_hardware_accelerated_decode,
    bool do_hardware_accelerated_decode)
    :{}

GpuImageDecodeCache::DecodedImageData::~DecodedImageData() {}

bool GpuImageDecodeCache::DecodedImageData::Lock() {}

void GpuImageDecodeCache::DecodedImageData::Unlock() {}

void GpuImageDecodeCache::DecodedImageData::SetLockedData(
    DecodedAuxImageData aux_image_data[kAuxImageCount],
    bool out_of_raster) {}

void GpuImageDecodeCache::DecodedImageData::SetBitmapImage(
    sk_sp<SkImage> image) {}

void GpuImageDecodeCache::DecodedImageData::ResetBitmapImage() {}

void GpuImageDecodeCache::DecodedImageData::ResetData() {}

void GpuImageDecodeCache::DecodedImageData::ReportUsageStats() const {}

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::UploadedImageData

GpuImageDecodeCache::UploadedImageData::UploadedImageData() = default;
GpuImageDecodeCache::UploadedImageData::~UploadedImageData() {}

void GpuImageDecodeCache::UploadedImageData::SetImage(
    sk_sp<SkImage> image,
    bool represents_yuv_image) {}

void GpuImageDecodeCache::UploadedImageData::SetYuvImage(
    sk_sp<SkImage> y_image_input,
    sk_sp<SkImage> u_image_input,
    sk_sp<SkImage> v_image_input) {}

void GpuImageDecodeCache::UploadedImageData::SetTransferCacheId(uint32_t id) {}

void GpuImageDecodeCache::UploadedImageData::Reset() {}

void GpuImageDecodeCache::UploadedImageData::ReportUsageStats() const {}

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::ImageInfo

GpuImageDecodeCache::ImageInfo::ImageInfo() = default;

GpuImageDecodeCache::ImageInfo::ImageInfo(const SkImageInfo& rgba)
    :{}

GpuImageDecodeCache::ImageInfo::ImageInfo(const SkYUVAPixmapInfo& yuva)
    :{}

GpuImageDecodeCache::ImageInfo::ImageInfo(const ImageInfo&) = default;

GpuImageDecodeCache::ImageInfo& GpuImageDecodeCache::ImageInfo::operator=(
    const ImageInfo&) = default;

GpuImageDecodeCache::ImageInfo::~ImageInfo() = default;

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache::ImageData

GpuImageDecodeCache::ImageData::ImageData(
    PaintImage::Id paint_image_id,
    DecodedDataMode mode,
    const gfx::ColorSpace& target_color_space,
    PaintFlags::FilterQuality quality,
    int upload_scale_mip_level,
    bool needs_mips,
    bool is_bitmap_backed,
    bool can_do_hardware_accelerated_decode,
    bool do_hardware_accelerated_decode,
    ImageInfo image_info[kAuxImageCount])
    :{}

GpuImageDecodeCache::ImageData::~ImageData() {}

bool GpuImageDecodeCache::ImageData::IsGpuOrTransferCache() const {}

bool GpuImageDecodeCache::ImageData::HasUploadedData() const {}

void GpuImageDecodeCache::ImageData::ValidateBudgeted() const {}

size_t GpuImageDecodeCache::ImageData::GetTotalSize() const {}

////////////////////////////////////////////////////////////////////////////////
// GpuImageDecodeCache

// static
GrGLuint GpuImageDecodeCache::GlIdFromSkImage(const SkImage* image) {}

GpuImageDecodeCache::GpuImageDecodeCache(
    viz::RasterContextProvider* context,
    bool use_transfer_cache,
    SkColorType color_type,
    size_t max_working_set_bytes,
    int max_texture_size,
    RasterDarkModeFilter* const dark_mode_filter)
    :{}

GpuImageDecodeCache::~GpuImageDecodeCache() {}

ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRef(
    ClientId client_id,
    const DrawImage& draw_image,
    const TracingInfo& tracing_info) {}

ImageDecodeCache::TaskResult
GpuImageDecodeCache::GetOutOfRasterDecodeTaskForImageAndRef(
    ClientId client_id,
    const DrawImage& draw_image) {}

ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
    ClientId client_id,
    const DrawImage& draw_image,
    const TracingInfo& tracing_info,
    DecodeTaskType task_type) {}

void GpuImageDecodeCache::UnrefImage(const DrawImage& draw_image) {}

bool GpuImageDecodeCache::UseCacheForDrawImage(
    const DrawImage& draw_image) const {}

DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw(
    const DrawImage& draw_image) {}

void GpuImageDecodeCache::DrawWithImageFinished(
    const DrawImage& draw_image,
    const DecodedDrawImage& decoded_draw_image) {}

void GpuImageDecodeCache::ReduceCacheUsage() {}

void GpuImageDecodeCache::ReduceCacheUsageLocked() NO_THREAD_SAFETY_ANALYSIS {}

void GpuImageDecodeCache::SetShouldAggressivelyFreeResources(
    bool aggressively_free_resources,
    bool context_lock_acquired) {}

void GpuImageDecodeCache::ClearCache() {}

void GpuImageDecodeCache::RecordStats() {}

void GpuImageDecodeCache::AddToPersistentCache(const DrawImage& draw_image,
                                               scoped_refptr<ImageData> data) {}

template <typename Iterator>
Iterator GpuImageDecodeCache::RemoveFromPersistentCache(Iterator it) {}

bool GpuImageDecodeCache::TryFlushPendingWork() {}

bool GpuImageDecodeCache::DoPurgeOldCacheEntries(base::TimeDelta max_age) {}

void GpuImageDecodeCache::PurgeOldCacheEntriesCallback() {}

void GpuImageDecodeCache::PostPurgeOldCacheEntriesTask() {}

size_t GpuImageDecodeCache::GetMaximumMemoryLimitBytes() const {}

void GpuImageDecodeCache::AddTextureDump(
    base::trace_event::ProcessMemoryDump* pmd,
    const std::string& texture_dump_name,
    const size_t bytes,
    const GrGLuint gl_id,
    const size_t locked_size) const {}

void GpuImageDecodeCache::MemoryDumpYUVImage(
    base::trace_event::ProcessMemoryDump* pmd,
    const ImageData* image_data,
    const std::string& dump_base_name,
    size_t locked_size) const {}

bool GpuImageDecodeCache::OnMemoryDump(
    const base::trace_event::MemoryDumpArgs& args,
    base::trace_event::ProcessMemoryDump* pmd) {}

void GpuImageDecodeCache::DecodeImageInTask(const DrawImage& draw_image,
                                            TaskType task_type) {}

void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) {}

void GpuImageDecodeCache::OnImageDecodeTaskCompleted(
    const DrawImage& draw_image,
    DecodeTaskType task_type) {}

void GpuImageDecodeCache::OnImageUploadTaskCompleted(
    const DrawImage& draw_image) {}

int GpuImageDecodeCache::CalculateUploadScaleMipLevel(
    const DrawImage& draw_image,
    AuxImage aux_image) const {}

GpuImageDecodeCache::InUseCacheKey
GpuImageDecodeCache::InUseCacheKeyFromDrawImage(
    const DrawImage& draw_image) const {}

// Checks if an image decode needs a decode task and returns it.
scoped_refptr<TileTask> GpuImageDecodeCache::GetImageDecodeTaskAndRef(
    ClientId client_id,
    const DrawImage& draw_image,
    const TracingInfo& tracing_info,
    DecodeTaskType task_type) {}

void GpuImageDecodeCache::RefImageDecode(const DrawImage& draw_image,
                                         const InUseCacheKey& cache_key) {}

void GpuImageDecodeCache::UnrefImageDecode(const DrawImage& draw_image,
                                           const InUseCacheKey& cache_key) {}

void GpuImageDecodeCache::RefImage(const DrawImage& draw_image,
                                   const InUseCacheKey& cache_key) {}

void GpuImageDecodeCache::UnrefImageInternal(const DrawImage& draw_image,
                                             const InUseCacheKey& cache_key) {}

// Called any time an image or decode ref count changes. Takes care of any
// necessary memory budget book-keeping and cleanup.
void GpuImageDecodeCache::OwnershipChanged(const DrawImage& draw_image,
                                           ImageData* image_data) {}

// Checks whether we can fit a new image of size |required_size| in our
// working set. Also frees unreferenced entries to keep us below our preferred
// items limit.
bool GpuImageDecodeCache::EnsureCapacity(size_t required_size) {}

bool GpuImageDecodeCache::CanFitInWorkingSet(size_t size) const {}

bool GpuImageDecodeCache::ExceedsCacheLimits() const {}

void GpuImageDecodeCache::InsertTransferCacheEntry(
    const ClientImageTransferCacheEntry& image_entry,
    ImageData* image_data) {}

bool GpuImageDecodeCache::NeedsDarkModeFilter(const DrawImage& draw_image,
                                              ImageData* image_data) {}

void GpuImageDecodeCache::DecodeImageAndGenerateDarkModeFilterIfNecessary(
    const DrawImage& draw_image,
    ImageData* image_data,
    TaskType task_type) {}

void GpuImageDecodeCache::DecodeImageIfNecessary(
    const DrawImage& draw_image,
    ImageData* image_data,
    TaskType task_type,
    bool needs_decode_for_dark_mode) {}

void GpuImageDecodeCache::GenerateDarkModeFilter(const DrawImage& draw_image,
                                                 ImageData* image_data) {}

void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
                                                 ImageData* image_data) {}

void GpuImageDecodeCache::UploadImageIfNecessary_TransferCache_HardwareDecode(
    const DrawImage& draw_image,
    ImageData* image_data,
    sk_sp<SkColorSpace> color_space) {}

void GpuImageDecodeCache::UploadImageIfNecessary_TransferCache_SoftwareDecode(
    const DrawImage& draw_image,
    ImageData* image_data,
    sk_sp<SkColorSpace> decoded_color_space,
    const std::optional<gfx::HDRMetadata>& hdr_metadata,
    sk_sp<SkColorSpace> target_color_space) {}

void GpuImageDecodeCache::UploadImageIfNecessary_GpuCpu_YUVA(
    const DrawImage& draw_image,
    ImageData* image_data,
    sk_sp<SkImage> uploaded_image,
    skgpu::Mipmapped image_needs_mips,
    sk_sp<SkColorSpace> decoded_color_space,
    sk_sp<SkColorSpace> color_space) {}

void GpuImageDecodeCache::UploadImageIfNecessary_GpuCpu_RGBA(
    const DrawImage& draw_image,
    ImageData* image_data,
    sk_sp<SkImage> uploaded_image,
    skgpu::Mipmapped image_needs_mips,
    sk_sp<SkColorSpace> color_space) {}

scoped_refptr<GpuImageDecodeCache::ImageData>
GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
                                     bool allow_hardware_decode) {}

void GpuImageDecodeCache::WillAddCacheEntry(const DrawImage& draw_image) {}

void GpuImageDecodeCache::DeleteImage(ImageData* image_data) {}

void GpuImageDecodeCache::UnlockImage(ImageData* image_data) {}

// YUV images are handled slightly differently because they are not themselves
// registered with the discardable memory system. We cannot use
// GlIdFromSkImage on these YUV SkImages to flush pending operations because
// doing so will flatten it to RGB.
void GpuImageDecodeCache::FlushYUVImages(
    std::vector<sk_sp<SkImage>>* yuv_images) {}

// We always run pending operations in the following order:
//   > Lock
//   > Flush YUV images that will be unlocked
//   > Unlock
//   > Flush YUV images that will be deleted
//   > Delete
// This ensures that:
//   a) We never fully unlock an image that's pending lock (lock before unlock)
//   b) We never delete an image that has pending locks/unlocks.
//   c) We never unlock or delete the underlying texture planes for a YUV
//      image before all operations referencing it have completed.
//
// As this can be run at-raster, to unlock/delete an image that was just used,
// we need to call GlIdFromSkImage, which flushes pending IO on the image,
// rather than just using a cached GL ID.
// YUV images are handled slightly differently because they are backed by
// texture images but are not themselves registered with the discardable memory
// system. We wait to delete the pointer to a YUV image until we have a context
// lock and its textures have been deleted.
void GpuImageDecodeCache::RunPendingContextThreadOperations() {}

std::tuple<SkImageInfo, int> GpuImageDecodeCache::CreateImageInfoForDrawImage(
    const DrawImage& draw_image,
    AuxImage aux_image) const {}

bool GpuImageDecodeCache::TryLockImage(HaveContextLock have_context_lock,
                                       const DrawImage& draw_image,
                                       ImageData* data) {}

// Tries to find an ImageData that can be used to draw the provided
// |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one
// cannot be found, it looks for a compatible entry in our |persistent_cache_|.
GpuImageDecodeCache::ImageData* GpuImageDecodeCache::GetImageDataForDrawImage(
    const DrawImage& draw_image,
    const InUseCacheKey& key) {}

// Determines if we can draw the provided |draw_image| using the provided
// |image_data|. This is true if the |image_data| is not scaled, or if it
// is scaled at an equal or larger scale and equal or larger quality to
// the provided |draw_image|.
bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
                                       const DrawImage& draw_image) const {}

size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) {}

void GpuImageDecodeCache::SetImageDecodingFailedForTesting(
    const DrawImage& image) {}

bool GpuImageDecodeCache::DiscardableIsLockedForTesting(
    const DrawImage& image) {}

bool GpuImageDecodeCache::IsInInUseCacheForTesting(
    const DrawImage& image) const {}

bool GpuImageDecodeCache::IsInPersistentCacheForTesting(
    const DrawImage& image) const {}

sk_sp<SkImage> GpuImageDecodeCache::GetSWImageDecodeForTesting(
    const DrawImage& image) {}

// Used for in-process-raster YUV decoding tests, where we often need the
// SkImages for each underlying plane because asserting or requesting fields for
// the YUV SkImage may flatten it to RGB or not be possible to request.
sk_sp<SkImage> GpuImageDecodeCache::GetUploadedPlaneForTesting(
    const DrawImage& draw_image,
    YUVIndex index) {}

size_t GpuImageDecodeCache::GetDarkModeImageCacheSizeForTesting(
    const DrawImage& draw_image) {}

bool GpuImageDecodeCache::NeedsDarkModeFilterForTesting(
    const DrawImage& draw_image) {}

void GpuImageDecodeCache::TouchCacheEntryForTesting(
    const DrawImage& draw_image) {}

void GpuImageDecodeCache::OnMemoryPressure(
    base::MemoryPressureListener::MemoryPressureLevel level) {}

bool GpuImageDecodeCache::AcquireContextLockForTesting() {}

void GpuImageDecodeCache::ReleaseContextLockForTesting()
    NO_THREAD_SAFETY_ANALYSIS {}

bool GpuImageDecodeCache::SupportsColorSpaceConversion() const {}

sk_sp<SkColorSpace> GpuImageDecodeCache::ColorSpaceForImageDecode(
    const DrawImage& image,
    DecodedDataMode mode) const {}

void GpuImageDecodeCache::CheckContextLockAcquiredIfNecessary() {}

sk_sp<SkImage> GpuImageDecodeCache::CreateImageFromYUVATexturesInternal(
    const SkImage* uploaded_y_image,
    const SkImage* uploaded_u_image,
    const SkImage* uploaded_v_image,
    const int image_width,
    const int image_height,
    const SkYUVAInfo::PlaneConfig yuva_plane_config,
    const SkYUVAInfo::Subsampling yuva_subsampling,
    const SkYUVColorSpace yuv_color_space,
    sk_sp<SkColorSpace> target_color_space,
    sk_sp<SkColorSpace> decoded_color_space) const {}

void GpuImageDecodeCache::UpdateMipsIfNeeded(const DrawImage& draw_image,
                                             ImageData* image_data) {}

// static
scoped_refptr<TileTask> GpuImageDecodeCache::GetTaskFromMapForClientId(
    const ClientId client_id,
    const ImageTaskMap& task_map) {}

base::TimeDelta GpuImageDecodeCache::get_purge_interval() {}

base::TimeDelta GpuImageDecodeCache::get_max_purge_age() {}

}  // namespace cc