// 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.

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

#include "gpu/command_buffer/client/raster_implementation.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <GLES3/gl3.h>
#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <array>
#include <limits>
#include <set>
#include <sstream>
#include <string>

#include "base/atomic_sequence_num.h"
#include "base/atomicops.h"
#include "base/bits.h"
#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/stack_allocated.h"
#include "base/metrics/histogram_macros.h"
#include "base/notimplemented.h"
#include "base/numerics/safe_math.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 "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/decode_stashing_image_provider.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/skottie_serialization_history.h"
#include "cc/paint/transfer_cache_entry.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/raster_cmd_helper.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/ipc/color/gfx_param_traits.h"

#if defined(GPU_CLIENT_DEBUG)
#define GPU_CLIENT_SINGLE_THREAD_CHECK() SingleThreadChecker checker(this);
#else  // !defined(GPU_CLIENT_DEBUG)
#define GPU_CLIENT_SINGLE_THREAD_CHECK()
#endif  // defined(GPU_CLIENT_DEBUG)

// TODO(backer): Update APIs to always write to the destination? See below.
//
// Check that destination pointers point to initialized memory.
// When the context is lost, calling GL function has no effect so if destination
// pointers point to initialized memory it can often lead to crash bugs. eg.
//
// If it was up to us we'd just always write to the destination but the OpenGL
// spec defines the behavior of OpenGL functions, not us. :-(
#if defined(GPU_DCHECK)
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) GPU_DCHECK(v)
#define GPU_CLIENT_DCHECK(v) GPU_DCHECK(v)
#elif defined(DCHECK)
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) DCHECK(v)
#define GPU_CLIENT_DCHECK(v) DCHECK(v)
#else
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) ASSERT(v)
#define GPU_CLIENT_DCHECK(v) ASSERT(v)
#endif

#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(type, ptr) \
  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(          \
      ptr &&                                                     \
      (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));

#define GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(type, ptr) \
  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(                   \
      !ptr ||                                                             \
      (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));

using gpu::gles2::GLES2Util;

namespace gpu {
namespace raster {

namespace {

// TODO(crbug.com/40058879): Disable this work-around, once call-sites are
// handling failures correctly.
BASE_FEATURE(kDisableErrorHandlingForReadback,
             "kDisableErrorHandlingForReadback",
             base::FEATURE_ENABLED_BY_DEFAULT);

const uint32_t kMaxTransferCacheEntrySizeForTransferBuffer = 1024;
const size_t kMaxImmediateDeletedPaintCachePaths = 1024;
constexpr size_t kMaxImmediateDeletedPaintCacheEffects = 10u;

#define DEFINE_PAINT_CACHE_DELETION(                                     \
    IMMEDIATE_SIZE_CONSTANT, IMMEDIATE_FUNCTION, NON_IMMEDIATE_FUNCTION) \
  if (ids.size() <= IMMEDIATE_SIZE_CONSTANT) {                           \
    helper_->IMMEDIATE_FUNCTION(ids.size(), ids.data());                 \
  } else {                                                               \
    size_t data_size = ids.size() * sizeof(GLuint);                      \
    ScopedSharedMemoryPtr dest(data_size, transfer_buffer_,              \
                               mapped_memory_.get(), helper());          \
    if (dest.valid()) {                                                  \
      memcpy(dest.address(), ids.data(), data_size);                     \
      helper_->NON_IMMEDIATE_FUNCTION(ids.size(), dest.shm_id(),         \
                                      dest.offset());                    \
    } else {                                                             \
      SetGLError(GL_INVALID_OPERATION, "glDeletePaintCacheINTERNAL",     \
                 "couldn't allocate shared memory");                     \
    }                                                                    \
  }

class ScopedSharedMemoryPtr {
 public:
  ScopedSharedMemoryPtr(size_t size,
                        TransferBufferInterface* transfer_buffer,
                        MappedMemoryManager* mapped_memory,
                        RasterCmdHelper* helper) {
    // Prefer transfer buffer but fall back to MappedMemory if there's not
    // enough free space.
    if (transfer_buffer->GetFreeSize() < size) {
      scoped_mapped_ptr_.emplace(size, helper, mapped_memory);
    } else {
      scoped_transfer_ptr_.emplace(size, helper, transfer_buffer);
    }
  }
  ~ScopedSharedMemoryPtr() = default;

  GLuint size() {
    return scoped_transfer_ptr_ ? scoped_transfer_ptr_->size()
                                : scoped_mapped_ptr_->size();
  }

  GLint shm_id() {
    return scoped_transfer_ptr_ ? scoped_transfer_ptr_->shm_id()
                                : scoped_mapped_ptr_->shm_id();
  }

  GLuint offset() {
    return scoped_transfer_ptr_ ? scoped_transfer_ptr_->offset()
                                : scoped_mapped_ptr_->offset();
  }

  bool valid() {
    return scoped_transfer_ptr_ ? scoped_transfer_ptr_->valid()
                                : scoped_mapped_ptr_->valid();
  }

  void* address() {
    return scoped_transfer_ptr_ ? scoped_transfer_ptr_->address()
                                : scoped_mapped_ptr_->address();
  }

 private:
  std::optional<ScopedMappedMemoryPtr> scoped_mapped_ptr_;
  std::optional<ScopedTransferBufferPtr> scoped_transfer_ptr_;
};

}  // namespace

// Helper to copy data to the GPU service over the transfer cache.
class RasterImplementation::TransferCacheSerializeHelperImpl final
    : public cc::TransferCacheSerializeHelper {
 public:
  explicit TransferCacheSerializeHelperImpl(RasterImplementation* ri)
      : ri_(ri) {}

  TransferCacheSerializeHelperImpl(const TransferCacheSerializeHelperImpl&) =
      delete;
  TransferCacheSerializeHelperImpl& operator=(
      const TransferCacheSerializeHelperImpl&) = delete;

  ~TransferCacheSerializeHelperImpl() final = default;

  uint32_t take_end_offset_of_last_inlined_entry() {
    auto offset = end_offset_of_last_inlined_entry_;
    end_offset_of_last_inlined_entry_ = 0u;
    return offset;
  }

 private:
  bool LockEntryInternal(const EntryKey& key) final {
    return ri_->ThreadsafeLockTransferCacheEntry(
        static_cast<uint32_t>(key.first), key.second);
  }

  uint32_t CreateEntryInternal(const cc::ClientTransferCacheEntry& entry,
                               uint8_t* memory) final {
    uint32_t size = entry.SerializedSize();
    // Cap the entries inlined to a specific size.
    if (size <= ri_->max_inlined_entry_size_ && ri_->raster_mapped_buffer_) {
      uint32_t written = InlineEntry(entry, memory);
      if (written > 0u) {
        return written;
      }
    }

    base::span<uint8_t> data = ri_->MapTransferCacheEntry(size);
    if (data.empty()) {
      return 0u;
    }

    bool succeeded = entry.Serialize(data);
    DCHECK(succeeded);
    ri_->UnmapAndCreateTransferCacheEntry(entry.UnsafeType(), entry.Id());
    return 0u;
  }

  void FlushEntriesInternal(std::set<EntryKey> entries) final {
    std::vector<std::pair<uint32_t, uint32_t>> transformed;
    transformed.reserve(entries.size());
    for (const auto& e : entries) {
      transformed.emplace_back(static_cast<uint32_t>(e.first), e.second);
    }
    ri_->UnlockTransferCacheEntries(transformed);
  }

  // Writes the entry into |memory| if there is enough space. Returns the number
  // of bytes written on success or 0u on failure due to insufficient size.
  uint32_t InlineEntry(const cc::ClientTransferCacheEntry& entry,
                       uint8_t* memory) {
    DCHECK(memory);
    DCHECK(SkIsAlign4(reinterpret_cast<uintptr_t>(memory)));

    // The memory passed from the PaintOpWriter for inlining the transfer cache
    // entry must be from the transfer buffer mapped during RasterCHROMIUM.
    const auto& buffer = ri_->raster_mapped_buffer_;
    DCHECK(buffer->BelongsToBuffer(memory));

    DCHECK(base::CheckedNumeric<uint32_t>(
               memory - static_cast<uint8_t*>(buffer->address()))
               .IsValid());
    uint32_t memory_offset = memory - static_cast<uint8_t*>(buffer->address());
    uint32_t bytes_to_write = entry.SerializedSize();
    uint32_t bytes_remaining = buffer->size() - memory_offset;
    DCHECK_GT(bytes_to_write, 0u);

    if (bytes_to_write > bytes_remaining) {
      return 0u;
    }

    bool succeeded = entry.Serialize(
        base::span(reinterpret_cast<uint8_t*>(memory), bytes_remaining));
    DCHECK(succeeded);
    ri_->transfer_cache_.AddTransferCacheEntry(
        entry.UnsafeType(), entry.Id(), buffer->shm_id(),
        buffer->offset() + memory_offset, bytes_to_write);

    end_offset_of_last_inlined_entry_ = memory_offset + bytes_to_write;
    return bytes_to_write;
  }

  const raw_ptr<RasterImplementation> ri_;
  uint32_t end_offset_of_last_inlined_entry_ = 0u;
};

// Helper to copy PaintOps to the GPU service over the transfer buffer.
class RasterImplementation::PaintOpSerializer {
  STACK_ALLOCATED();

 public:
  PaintOpSerializer(uint32_t initial_size,
                    RasterImplementation* ri,
                    cc::DecodeStashingImageProvider* stashing_image_provider,
                    TransferCacheSerializeHelperImpl* transfer_cache_helper,
                    ClientFontManager* font_manager,
                    size_t* max_op_size_hint)
      : ri_(ri),
        stashing_image_provider_(stashing_image_provider),
        transfer_cache_helper_(transfer_cache_helper),
        font_manager_(font_manager),
        max_op_size_hint_(max_op_size_hint) {
    buffer_ =
        static_cast<char*>(ri_->MapRasterCHROMIUM(initial_size, &free_bytes_));
  }

  PaintOpSerializer(const PaintOpSerializer&) = delete;
  PaintOpSerializer& operator=(const PaintOpSerializer&) = delete;

  ~PaintOpSerializer() {
    // Need to call SendSerializedData;
    DCHECK(!written_bytes_);
  }

  size_t SerializeImpl(const cc::PaintOp& op,
                       const cc::PaintOp::SerializeOptions& options,
                       const cc::PaintFlags* flags_to_serialize,
                       const SkM44& current_ctm,
                       const SkM44& original_ctm) {
    if (!valid()) {
      return 0;
    }

    size_t size = op.Serialize(buffer_ + written_bytes_, free_bytes_, options,
                               flags_to_serialize, current_ctm, original_ctm);
    size_t block_size = *max_op_size_hint_;

    if (!size) {
      // The entries serialized for |op| above will not be transferred since the
      // op will be re-serialized once the buffer is remapped.
      ri_->paint_cache_->AbortPendingEntries();
      SendSerializedData();

      const unsigned int max_size = ri_->transfer_buffer_->GetMaxSize();
      DCHECK_LE(block_size, max_size);
      while (true) {
        buffer_ = static_cast<char*>(
            ri_->MapRasterCHROMIUM(block_size, &free_bytes_));
        if (!buffer_) {
          return 0;
        }

        size = op.Serialize(buffer_ + written_bytes_, free_bytes_, options,
                            flags_to_serialize, current_ctm, original_ctm);
        if (size) {
          *max_op_size_hint_ = std::max(size, *max_op_size_hint_);
          break;
        }

        ri_->paint_cache_->AbortPendingEntries();
        ri_->UnmapRasterCHROMIUM(0u, 0u);

        if (block_size == max_size) {
          break;
        }
        block_size = std::min(block_size * 2, static_cast<size_t>(max_size));
      }

      if (!size) {
        LOG(ERROR) << "Failed to serialize op in " << block_size << " bytes.";
        return 0u;
      }
    }

    DCHECK_LE(size, free_bytes_);
    DCHECK(base::CheckAdd<uint32_t>(written_bytes_, size).IsValid());

    ri_->paint_cache_->FinalizePendingEntries();
    written_bytes_ += size;
    free_bytes_ -= size;
    return size;
  }

  static size_t Serialize(void* instance,
                          const cc::PaintOp& op,
                          const cc::PaintOp::SerializeOptions& options,
                          const cc::PaintFlags* flags_to_serialize,
                          const SkM44& current_ctm,
                          const SkM44& original_ctm) {
    return reinterpret_cast<PaintOpSerializer*>(instance)->SerializeImpl(
        op, options, flags_to_serialize, current_ctm, original_ctm);
  }

  void SendSerializedData() {
    if (!valid()) {
      return;
    }

    // Serialize fonts before sending raster commands.
    font_manager_->Serialize();

    // Check the address of the last inlined entry to figured out whether
    // transfer cache entries were written past the last successfully serialized
    // op.
    uint32_t total_written_size = std::max(
        written_bytes_,
        transfer_cache_helper_->take_end_offset_of_last_inlined_entry());

    // Send the raster command itself now that the commands for its
    // dependencies have been sent.
    ri_->UnmapRasterCHROMIUM(written_bytes_, total_written_size);

    // Now that we've issued the RasterCHROMIUM referencing the stashed
    // images, Reset the |stashing_image_provider_|, causing us to issue
    // unlock commands for these images.
    stashing_image_provider_->Reset();

    // Unlock all the transfer cache entries used (both immediate and deferred).
    transfer_cache_helper_->FlushEntries();
    written_bytes_ = 0;
  }

  bool valid() const { return !!buffer_; }

 private:
  RasterImplementation* const ri_ = nullptr;
  char* buffer_ = nullptr;
  cc::DecodeStashingImageProvider* const stashing_image_provider_ = nullptr;
  TransferCacheSerializeHelperImpl* const transfer_cache_helper_ = nullptr;
  ClientFontManager* font_manager_ = nullptr;

  uint32_t written_bytes_ = 0;
  uint32_t free_bytes_ = 0;

  size_t* max_op_size_hint_ = nullptr;
};

RasterImplementation::SingleThreadChecker::SingleThreadChecker(
    RasterImplementation* raster_implementation)
    : raster_implementation_(raster_implementation) {
  CHECK_EQ(0, raster_implementation_->use_count_);
  ++raster_implementation_->use_count_;
}

RasterImplementation::SingleThreadChecker::~SingleThreadChecker() {
  --raster_implementation_->use_count_;
  CHECK_EQ(0, raster_implementation_->use_count_);
}

struct RasterImplementation::AsyncARGBReadbackRequest {
  AsyncARGBReadbackRequest(void* dst_pixels,
                           GLuint dst_size,
                           GLuint pixels_offset,
                           GLuint finished_query,
                           std::unique_ptr<ScopedMappedMemoryPtr> shared_memory,
                           base::OnceCallback<void(bool)> callback)
      : dst_pixels(dst_pixels),
        dst_size(dst_size),
        pixels_offset(pixels_offset),
        shared_memory(std::move(shared_memory)),
        callback(std::move(callback)),
        query(finished_query),
        done(false),
        readback_successful(false) {}
  ~AsyncARGBReadbackRequest() {
    // Sometimes `callback` owns `dst_pixels`, this prevents dangling raw ptr
    dst_pixels = nullptr;
    std::move(callback).Run(readback_successful);
  }

  raw_ptr<void> dst_pixels;
  GLuint dst_size;
  GLuint pixels_offset;
  std::unique_ptr<ScopedMappedMemoryPtr> shared_memory;
  base::OnceCallback<void(bool)> callback;
  GLuint query;
  bool done;
  bool readback_successful;
};

struct RasterImplementation::AsyncYUVReadbackRequest {
  AsyncYUVReadbackRequest(gfx::Rect output_rect,
                          GLuint query,
                          int y_plane_stride,
                          GLuint y_plane_offset,
                          uint8_t* y_plane_data,
                          int u_plane_stride,
                          GLuint u_plane_offset,
                          uint8_t* u_plane_data,
                          int v_plane_stride,
                          GLuint v_plane_offset,
                          uint8_t* v_plane_data,
                          std::unique_ptr<ScopedMappedMemoryPtr> shared_memory,
                          base::OnceCallback<void()> release_mailbox,
                          base::OnceCallback<void(bool)> readback_done)
      : output_rect(output_rect),
        query(query),
        y_plane_stride(y_plane_stride),
        y_plane_offset(y_plane_offset),
        y_plane_data(y_plane_data),
        u_plane_stride(u_plane_stride),
        u_plane_offset(u_plane_offset),
        u_plane_data(u_plane_data),
        v_plane_stride(v_plane_stride),
        v_plane_offset(v_plane_offset),
        v_plane_data(v_plane_data),
        shared_memory(std::move(shared_memory)),
        release_mailbox(std::move(release_mailbox)),
        readback_done(std::move(readback_done)) {}
  ~AsyncYUVReadbackRequest() {
    // Sometimes `callback` owns plane ptrs, this prevents dangling raw ptrs
    y_plane_data = nullptr;
    u_plane_data = nullptr;
    v_plane_data = nullptr;
    std::move(release_mailbox).Run();
    std::move(readback_done).Run(readback_successful);
  }

  void CopyYUVPlanes() {
    void* shm_address = shared_memory->address();
    auto* result =
        static_cast<cmds::ReadbackYUVImagePixelsINTERNALImmediate::Result*>(
            shm_address);
    if (!*result) {
      return;
    }

    CopyYUVPlane(output_rect.height(), y_plane_stride, y_plane_offset,
                 shm_address, y_plane_data);

    // U and V planes are half the size of the Y plane.
    CopyYUVPlane(output_rect.height() / 2, u_plane_stride, u_plane_offset,
                 shm_address, u_plane_data);
    CopyYUVPlane(output_rect.height() / 2, v_plane_stride, v_plane_offset,
                 shm_address, v_plane_data);

    readback_successful = true;
  }

  const gfx::Rect output_rect;
  GLuint query;

  int y_plane_stride;
  GLuint y_plane_offset;
  raw_ptr<uint8_t> y_plane_data;

  int u_plane_stride;
  GLuint u_plane_offset;
  raw_ptr<uint8_t> u_plane_data;

  int v_plane_stride;
  GLuint v_plane_offset;
  raw_ptr<uint8_t> v_plane_data;

  std::unique_ptr<ScopedMappedMemoryPtr> shared_memory;
  base::OnceCallback<void()> release_mailbox;
  base::OnceCallback<void(bool)> readback_done;

  bool done = false;
  bool readback_successful = false;

 private:
  void CopyYUVPlane(GLuint plane_height,
                    int plane_stride,
                    GLuint plane_offset,
                    void* in_buffer,
                    uint8_t* out_buffer) {
    // RasterDecoder writes the pixels into |in_buffer| with the requested
    // stride so we can copy the whole block here.
    // We need to use `RelaxedAtomicWriteMemcpy` because we might be writing
    // into memory observed by JS at the same time.
    size_t plane_size = plane_height * plane_stride;
    auto dst = base::span(out_buffer, plane_size);
    auto src =
        base::span(static_cast<uint8_t*>(in_buffer) + plane_offset, plane_size);
    base::subtle::RelaxedAtomicWriteMemcpy(dst, src);
  }
};

RasterImplementation::RasterImplementation(
    RasterCmdHelper* helper,
    TransferBufferInterface* transfer_buffer,
    bool lose_context_when_out_of_memory,
    GpuControl* gpu_control)
    : ImplementationBase(helper, transfer_buffer, gpu_control),
      helper_(helper),
      error_bits_(0),
      lose_context_when_out_of_memory_(lose_context_when_out_of_memory),
      use_count_(0),
      current_trace_stack_(0),
      aggressively_free_resources_(false),
      font_manager_(this, helper->command_buffer()),
      lost_(false),
      max_inlined_entry_size_(kMaxTransferCacheEntrySizeForTransferBuffer),
      transfer_cache_(this) {
  DCHECK(helper);
  DCHECK(transfer_buffer);
  DCHECK(gpu_control);

  std::stringstream ss;
  ss << std::hex << this;
  this_in_hex_ = ss.str();
}

gpu::ContextResult RasterImplementation::Initialize(
    const SharedMemoryLimits& limits) {
  TRACE_EVENT0("gpu", "RasterImplementation::Initialize");

  auto result = ImplementationBase::Initialize(limits);
  if (result != gpu::ContextResult::kSuccess) {
    return result;
  }

  return gpu::ContextResult::kSuccess;
}

RasterImplementation::~RasterImplementation() {
  // Make sure the queries are finished otherwise we'll delete the
  // shared memory (mapped_memory_) which will free the memory used
  // by the queries. The GPU process when validating that memory is still
  // shared will fail and abort (ie, it will stop running).
  WaitForCmd();

  // Run callbacks for all pending AsyncReadbackRequests to inform them of the
  // failure
  CancelRequests();
  query_tracker_.reset();

  // Make sure the commands make it the service.
  WaitForCmd();
}

RasterCmdHelper* RasterImplementation::helper() const {
  return helper_;
}

IdAllocator* RasterImplementation::GetIdAllocator(IdNamespaces namespace_id) {
  DCHECK_EQ(namespace_id, IdNamespaces::kQueries);
  return &query_id_allocator_;
}

void RasterImplementation::OnGpuControlLostContext() {
  OnGpuControlLostContextMaybeReentrant();

  // This should never occur more than once.
  DCHECK(!lost_context_callback_run_);
  lost_context_callback_run_ = true;
  if (!lost_context_callback_.is_null()) {
    std::move(lost_context_callback_).Run();
  }
}

void RasterImplementation::OnGpuControlLostContextMaybeReentrant() {
  {
    base::AutoLock hold(lost_lock_);
    lost_ = true;
  }
}

void RasterImplementation::OnGpuControlErrorMessage(const char* message,
                                                    int32_t id) {
  if (!error_message_callback_.is_null()) {
    error_message_callback_.Run(message, id);
  }
}

void RasterImplementation::OnGpuControlReturnData(
    base::span<const uint8_t> data) {
  NOTIMPLEMENTED();
}

void RasterImplementation::SetAggressivelyFreeResources(
    bool aggressively_free_resources) {
  TRACE_EVENT1("gpu", "RasterImplementation::SetAggressivelyFreeResources",
               "aggressively_free_resources", aggressively_free_resources);
  aggressively_free_resources_ = aggressively_free_resources;

  if (aggressively_free_resources_) {
    ClearPaintCache();
  }

  if (aggressively_free_resources_ && helper_->HaveRingBuffer()) {
    // Flush will delete transfer buffer resources if
    // |aggressively_free_resources_| is true.
    Flush();
  } else {
    ShallowFlushCHROMIUM();
  }

  if (aggressively_free_resources_) {
    temp_raster_offsets_.clear();
    temp_raster_offsets_.shrink_to_fit();
  }
}

void RasterImplementation::SetErrorMessageCallback(
    base::RepeatingCallback<void(const char*, int32_t)> callback) {
  error_message_callback_ = std::move(callback);
}

base::span<uint8_t> RasterImplementation::MapTransferCacheEntry(
    uint32_t serialized_size) {
  void* buffer = nullptr;
  // Prefer to use transfer buffer when possible, since transfer buffer
  // allocations are much cheaper.
  if (raster_mapped_buffer_ ||
      transfer_buffer_->GetFreeSize() < serialized_size) {
    buffer = transfer_cache_.MapEntry(mapped_memory_.get(), serialized_size);
  } else {
    buffer = transfer_cache_.MapTransferBufferEntry(transfer_buffer_,
                                                    serialized_size);
  }
  if (!buffer) {
    return base::span<uint8_t>();
  }
  return UNSAFE_TODO(
      base::span<uint8_t>(static_cast<uint8_t*>(buffer), serialized_size));
}

void RasterImplementation::UnmapAndCreateTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {
  transfer_cache_.UnmapAndCreateEntry(type, id);
}

bool RasterImplementation::ThreadsafeLockTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {
  return transfer_cache_.LockEntry(type, id);
}

void RasterImplementation::UnlockTransferCacheEntries(
    const std::vector<std::pair<uint32_t, uint32_t>>& entries) {
  transfer_cache_.UnlockEntries(entries);
}

void RasterImplementation::DeleteTransferCacheEntry(uint32_t type,
                                                    uint32_t id) {
  transfer_cache_.DeleteEntry(type, id);
}

unsigned int RasterImplementation::GetTransferBufferFreeSize() const {
  return transfer_buffer_->GetFreeSize();
}

const std::string& RasterImplementation::GetLogPrefix() const {
  const std::string& prefix(debug_marker_manager_.GetMarker());
  return prefix.empty() ? this_in_hex_ : prefix;
}

GLenum RasterImplementation::GetError() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetError()");
  GLenum err = GetGLError();
  GPU_CLIENT_LOG("returned " << GLES2Util::GetStringError(err));
  return err;
}

void RasterImplementation::IssueBeginQuery(GLenum target,
                                           GLuint id,
                                           uint32_t sync_data_shm_id,
                                           uint32_t sync_data_shm_offset) {
  helper_->BeginQueryEXT(target, id, sync_data_shm_id, sync_data_shm_offset);
}

void RasterImplementation::IssueEndQuery(GLenum target, GLuint submit_count) {
  helper_->EndQueryEXT(target, submit_count);
}

void RasterImplementation::IssueQueryCounter(GLuint id,
                                             GLenum target,
                                             uint32_t sync_data_shm_id,
                                             uint32_t sync_data_shm_offset,
                                             GLuint submit_count) {
  // This callback is invoked only by QueryTracker::QueryCounter(), which
  // RasterImplementation never calls.
  NOTREACHED();
}

void RasterImplementation::IssueSetDisjointValueSync(
    uint32_t sync_data_shm_id,
    uint32_t sync_data_shm_offset) {
  NOTIMPLEMENTED();
}

GLenum RasterImplementation::GetClientSideGLError() {
  if (error_bits_ == 0) {
    return GL_NO_ERROR;
  }

  GLenum error = GL_NO_ERROR;
  for (uint32_t mask = 1; mask != 0; mask = mask << 1) {
    if ((error_bits_ & mask) != 0) {
      error = GLES2Util::GLErrorBitToGLError(mask);
      break;
    }
  }
  error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
  return error;
}

CommandBufferHelper* RasterImplementation::cmd_buffer_helper() {
  return helper_;
}

void RasterImplementation::IssueCreateTransferCacheEntry(
    GLuint entry_type,
    GLuint entry_id,
    GLuint handle_shm_id,
    GLuint handle_shm_offset,
    GLuint data_shm_id,
    GLuint data_shm_offset,
    GLuint data_size) {
  helper_->CreateTransferCacheEntryINTERNAL(entry_type, entry_id, handle_shm_id,
                                            handle_shm_offset, data_shm_id,
                                            data_shm_offset, data_size);
}

void RasterImplementation::IssueDeleteTransferCacheEntry(GLuint entry_type,
                                                         GLuint entry_id) {
  helper_->DeleteTransferCacheEntryINTERNAL(entry_type, entry_id);
}

void RasterImplementation::IssueUnlockTransferCacheEntry(GLuint entry_type,
                                                         GLuint entry_id) {
  helper_->UnlockTransferCacheEntryINTERNAL(entry_type, entry_id);
}

CommandBuffer* RasterImplementation::command_buffer() const {
  return helper_->command_buffer();
}

GLenum RasterImplementation::GetGLError() {
  TRACE_EVENT0("gpu", "RasterImplementation::GetGLError");
  // Check the GL error first, then our wrapped error.
  auto result = GetResultAs<cmds::GetError::Result>();
  // If we couldn't allocate a result the context is lost.
  if (!result) {
    return GL_NO_ERROR;
  }
  *result = GL_NO_ERROR;
  helper_->GetError(GetResultShmId(), result.offset());
  WaitForCmd();
  GLenum error = *result;
  if (error == GL_NO_ERROR) {
    error = GetClientSideGLError();
  } else {
    // There was an error, clear the corresponding wrapped error.
    error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
  }
  return error;
}

#if defined(RASTER_CLIENT_FAIL_GL_ERRORS)
void RasterImplementation::FailGLError(GLenum error) {
  if (error != GL_NO_ERROR) {
    NOTREACHED() << "Error:" << error;
  }
}
// NOTE: Calling GetGLError overwrites data in the result buffer.
void RasterImplementation::CheckGLError() {
  FailGLError(GetGLError());
}
#endif  // defined(RASTER_CLIENT_FAIL_GL_ERRORS)

void RasterImplementation::SetGLError(GLenum error,
                                      const char* function_name,
                                      const char* msg) {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] Client Synthesized Error: "
                     << GLES2Util::GetStringError(error) << ": "
                     << function_name << ": " << msg);
  FailGLError(error);
  if (msg) {
    last_error_ = msg;
  }
  if (!error_message_callback_.is_null()) {
    std::string temp(GLES2Util::GetStringError(error) + " : " + function_name +
                     ": " + (msg ? msg : ""));
    error_message_callback_.Run(temp.c_str(), 0);
  }
  error_bits_ |= GLES2Util::GLErrorToErrorBit(error);

  if (error == GL_OUT_OF_MEMORY && lose_context_when_out_of_memory_) {
    helper_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                                 GL_UNKNOWN_CONTEXT_RESET_ARB);
  }
}

void RasterImplementation::SetGLErrorInvalidEnum(const char* function_name,
                                                 GLenum value,
                                                 const char* label) {
  SetGLError(
      GL_INVALID_ENUM, function_name,
      (std::string(label) + " was " + GLES2Util::GetStringEnum(value)).c_str());
}

bool RasterImplementation::GetQueryObjectValueHelper(const char* function_name,
                                                     GLuint id,
                                                     GLenum pname,
                                                     GLuint64* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryObjectValueHelper(" << id
                     << ", " << GLES2Util::GetStringQueryObjectParameter(pname)
                     << ", " << static_cast<const void*>(params) << ")");

  gles2::QueryTracker::Query* query = query_tracker_->GetQuery(id);
  if (!query) {
    SetGLError(GL_INVALID_OPERATION, function_name, "unknown query id");
    return false;
  }

  if (query->Active()) {
    SetGLError(GL_INVALID_OPERATION, function_name,
               "query active. Did you call glEndQueryEXT?");
    return false;
  }

  if (query->NeverUsed()) {
    SetGLError(GL_INVALID_OPERATION, function_name,
               "Never used. Did you call glBeginQueryEXT?");
    return false;
  }

  bool valid_value = false;
  const bool flush_if_pending =
      pname != GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT;
  switch (pname) {
    case GL_QUERY_RESULT_EXT:
      if (!query->CheckResultsAvailable(helper_, flush_if_pending)) {
        helper_->WaitForToken(query->token());
        if (!query->CheckResultsAvailable(helper_, flush_if_pending)) {
          FinishHelper();
          CHECK(query->CheckResultsAvailable(helper_, flush_if_pending));
        }
      }
      *params = query->GetResult();
      valid_value = true;
      break;
    case GL_QUERY_RESULT_AVAILABLE_EXT:
    case GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT:
      *params = query->CheckResultsAvailable(helper_, flush_if_pending);
      valid_value = true;
      break;
    default:
      SetGLErrorInvalidEnum(function_name, pname, "pname");
      break;
  }
  GPU_CLIENT_LOG("  " << *params);
  CheckGLError();
  return valid_value;
}

void RasterImplementation::Flush() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()");
  // Insert the cmd to call glFlush
  helper_->Flush();
  FlushHelper();
}

// InterfaceBase implementation.
void RasterImplementation::GenSyncTokenCHROMIUM(GLbyte* sync_token) {
  ImplementationBase::GenSyncToken(sync_token);
}
void RasterImplementation::GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) {
  ImplementationBase::GenUnverifiedSyncToken(sync_token);
}
void RasterImplementation::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
                                                    GLsizei count) {
  ImplementationBase::VerifySyncTokens(sync_tokens, count);
}
void RasterImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
  ImplementationBase::WaitSyncToken(sync_token);
}
void RasterImplementation::ShallowFlushCHROMIUM() {
  IssueShallowFlush();
}

// ImplementationBase implementation.
void RasterImplementation::IssueShallowFlush() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShallowFlushCHROMIUM()");
  FlushHelper();
}

void RasterImplementation::FlushHelper() {
  // Flush our command buffer
  // (tell the service to execute up to the flush cmd.)
  helper_->CommandBufferHelper::Flush();

  if (aggressively_free_resources_) {
    FreeEverything();
  }
}

void RasterImplementation::OrderingBarrierCHROMIUM() {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOrderingBarrierCHROMIUM");
  // Flush command buffer at the GPU channel level.  May be implemented as
  // Flush().
  helper_->CommandBufferHelper::OrderingBarrier();
}

void RasterImplementation::Finish() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  FinishHelper();
}

void RasterImplementation::FinishHelper() {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFinish()");
  TRACE_EVENT0("gpu", "RasterImplementation::Finish");
  // Insert the cmd to call glFinish
  helper_->Finish();
  // Finish our command buffer
  // (tell the service to execute up to the Finish cmd and wait for it to
  // execute.)
  helper_->CommandBufferHelper::Finish();

  if (aggressively_free_resources_) {
    FreeEverything();
  }
}

void RasterImplementation::GenQueriesEXTHelper(GLsizei /* n */,
                                               const GLuint* /* queries */) {}

GLenum RasterImplementation::GetGraphicsResetStatusKHR() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetGraphicsResetStatusKHR()");

  base::AutoLock hold(lost_lock_);
  if (lost_) {
    return GL_UNKNOWN_CONTEXT_RESET_KHR;
  }
  return GL_NO_ERROR;
}

void RasterImplementation::DeleteQueriesEXTHelper(GLsizei n,
                                                  const GLuint* queries) {
  IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kQueries);
  for (GLsizei ii = 0; ii < n; ++ii) {
    query_tracker_->RemoveQuery(queries[ii]);
    id_allocator->FreeID(queries[ii]);
  }

  helper_->DeleteQueriesEXTImmediate(n, queries);
}

void RasterImplementation::BeginQueryEXT(GLenum target, GLuint id) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] BeginQueryEXT("
                     << GLES2Util::GetStringQueryTarget(target) << ", " << id
                     << ")");

  switch (target) {
    case GL_COMMANDS_ISSUED_CHROMIUM:
      break;
    case GL_COMMANDS_COMPLETED_CHROMIUM:
      if (!capabilities_.sync_query) {
        SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
                   "not enabled for commands completed queries");
        return;
      }
      break;
    default:
      SetGLError(GL_INVALID_ENUM, "glBeginQueryEXT", "unknown query target");
      return;
  }

  // if any outstanding queries INV_OP
  if (query_tracker_->GetCurrentQuery(target)) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
               "query already in progress");
    return;
  }

  if (id == 0) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
    return;
  }

  if (!GetIdAllocator(IdNamespaces::kQueries)->InUse(id)) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "invalid id");
    return;
  }

  if (query_tracker_->BeginQuery(id, target, this)) {
    CheckGLError();
  }
}

void RasterImplementation::EndQueryEXT(GLenum target) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] EndQueryEXT("
                     << GLES2Util::GetStringQueryTarget(target) << ")");
  if (query_tracker_->EndQuery(target, this)) {
    CheckGLError();
  }
}

void RasterImplementation::GetQueryObjectuivEXT(GLuint id,
                                                GLenum pname,
                                                GLuint* params) {
  GLuint64 result = 0;
  if (GetQueryObjectValueHelper("glGetQueryObjectuivEXT", id, pname, &result)) {
    *params = base::saturated_cast<GLuint>(result);
  }
}

void* RasterImplementation::MapRasterCHROMIUM(uint32_t size,
                                              uint32_t* size_allocated) {
  *size_allocated = 0u;
  if (raster_mapped_buffer_) {
    SetGLError(GL_INVALID_OPERATION, "glMapRasterCHROMIUM", "already mapped");
    return nullptr;
  }
  raster_mapped_buffer_.emplace(size, helper_, transfer_buffer_);
  if (!raster_mapped_buffer_->valid()) {
    SetGLError(GL_INVALID_OPERATION, "glMapRasterCHROMIUM", "size too big");
    raster_mapped_buffer_ = std::nullopt;
    return nullptr;
  }
  *size_allocated = raster_mapped_buffer_->size();
  return raster_mapped_buffer_->address();
}

base::span<uint8_t> RasterImplementation::MapFontBuffer(uint32_t size) {
  DCHECK(size > 0);
  if (font_mapped_buffer_) {
    SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM",
               "already mapped");
    return {};
  }
  if (!raster_mapped_buffer_) {
    SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM",
               "mapped font buffer with no raster buffer");
    return {};
  }

  font_mapped_buffer_.emplace(size, helper_, mapped_memory_.get());
  if (!font_mapped_buffer_->valid()) {
    SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM", "size too big");
    font_mapped_buffer_ = std::nullopt;
    return {};
  }

  return font_mapped_buffer_->as_byte_span();
}

void RasterImplementation::UnmapRasterCHROMIUM(uint32_t raster_written_size,
                                               uint32_t total_written_size) {
  if (!raster_mapped_buffer_) {
    SetGLError(GL_INVALID_OPERATION, "glUnmapRasterCHROMIUM", "not mapped");
    return;
  }
  DCHECK(raster_mapped_buffer_->valid());
  if (total_written_size == 0) {
    raster_mapped_buffer_->Discard();
    raster_mapped_buffer_ = std::nullopt;
    return;
  }
  raster_mapped_buffer_->Shrink(total_written_size);

  uint32_t font_shm_id = 0u;
  uint32_t font_shm_offset = 0u;
  uint32_t font_shm_size = 0u;
  if (font_mapped_buffer_) {
    font_shm_id = font_mapped_buffer_->shm_id();
    font_shm_offset = font_mapped_buffer_->offset();
    font_shm_size = font_mapped_buffer_->size();
  }

  if (raster_written_size != 0u) {
    helper_->RasterCHROMIUM(
        raster_mapped_buffer_->shm_id(), raster_mapped_buffer_->offset(),
        raster_written_size, font_shm_id, font_shm_offset, font_shm_size);
  }

  raster_mapped_buffer_ = std::nullopt;
  font_mapped_buffer_ = std::nullopt;
  CheckGLError();
}

// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
#include "gpu/command_buffer/client/raster_implementation_impl_autogen.h"

void RasterImplementation::CopySharedImage(const gpu::Mailbox& source_mailbox,
                                           const gpu::Mailbox& dest_mailbox,
                                           GLint xoffset,
                                           GLint yoffset,
                                           GLint x,
                                           GLint y,
                                           GLsizei width,
                                           GLsizei height) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopySharedImage("
                     << source_mailbox.ToDebugString() << ", "
                     << dest_mailbox.ToDebugString() << ", " << xoffset << ", "
                     << yoffset << ", " << x << ", " << y << ", " << width
                     << ", " << height << ")");
  if (width < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "width < 0");
    return;
  }
  if (height < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "height < 0");
    return;
  }
  GLbyte mailboxes[sizeof(source_mailbox.name) * 2];
  memcpy(mailboxes, source_mailbox.name, sizeof(source_mailbox.name));
  memcpy(mailboxes + sizeof(source_mailbox.name), dest_mailbox.name,
         sizeof(dest_mailbox.name));
  helper_->CopySharedImageINTERNALImmediate(xoffset, yoffset, x, y, width,
                                            height, width, height, mailboxes);
  CheckGLError();
}

void RasterImplementation::CopySharedImage(const gpu::Mailbox& source_mailbox,
                                           const gpu::Mailbox& dest_mailbox,
                                           const gfx::Rect& source_rect,
                                           const gfx::Rect& dest_rect) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopySharedImage("
                     << source_mailbox.ToDebugString() << ", "
                     << dest_mailbox.ToDebugString() << ", "
                     << source_rect.ToString() << ", " << dest_rect.ToString()
                     << ")");
  if (source_rect.width() < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "src_width < 0");
    return;
  }
  if (source_rect.height() < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "src_height < 0");
    return;
  }
  if (dest_rect.width() < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "dst_width < 0");
    return;
  }
  if (dest_rect.height() < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopySharedImage", "dst_height < 0");
    return;
  }
  GLbyte mailboxes[sizeof(source_mailbox.name) * 2];
  memcpy(mailboxes, source_mailbox.name, sizeof(source_mailbox.name));
  memcpy(mailboxes + sizeof(source_mailbox.name), dest_mailbox.name,
         sizeof(dest_mailbox.name));
  helper_->CopySharedImageINTERNALImmediate(
      dest_rect.x(), dest_rect.y(), source_rect.x(), source_rect.y(),
      source_rect.width(), source_rect.height(), dest_rect.width(),
      dest_rect.height(), mailboxes);
  CheckGLError();
}

void RasterImplementation::WritePixels(const gpu::Mailbox& dest_mailbox,
                                       int dst_x_offset,
                                       int dst_y_offset,
                                       GLenum texture_target,
                                       const SkPixmap& src_sk_pixmap) {
  TRACE_EVENT0("gpu", "RasterImplementation::WritePixels");
  const auto& src_info = src_sk_pixmap.info();
  const auto& src_row_bytes = src_sk_pixmap.rowBytes();
  DCHECK_GE(src_row_bytes, src_info.minRowBytes());

  // Get the size of the SkColorSpace while maintaining 8-byte alignment.
  GLuint pixels_offset = 0;
  if (src_info.colorSpace()) {
    pixels_offset = base::bits::AlignUp(
        src_info.colorSpace()->writeToMemory(nullptr), sizeof(uint64_t));
  }

  GLuint src_size = src_sk_pixmap.computeByteSize();
  GLuint total_size =
      pixels_offset +
      base::bits::AlignUp(src_size, static_cast<GLuint>(sizeof(uint64_t)));

  std::unique_ptr<ScopedSharedMemoryPtr> scoped_shared_memory =
      std::make_unique<ScopedSharedMemoryPtr>(total_size, transfer_buffer_,
                                              mapped_memory_.get(), helper());

  if (!scoped_shared_memory->valid()) {
    SetGLError(GL_INVALID_OPERATION, "WritePixels", "size too big");
    return;
  }

  GLint shm_id = scoped_shared_memory->shm_id();
  GLuint shm_offset = scoped_shared_memory->offset();
  void* address = scoped_shared_memory->address();

  if (src_info.colorSpace()) {
    size_t bytes_written = src_info.colorSpace()->writeToMemory(address);
    DCHECK_LE(bytes_written, pixels_offset);
  }
  memcpy(static_cast<uint8_t*>(address) + pixels_offset, src_sk_pixmap.addr(),
         src_size);

  helper_->WritePixelsINTERNALImmediate(
      dst_x_offset, dst_y_offset, src_info.width(), src_info.height(),
      src_row_bytes, src_info.colorType(), src_info.alphaType(), shm_id,
      shm_offset, pixels_offset, dest_mailbox.name);
}

void RasterImplementation::WritePixelsYUV(const gpu::Mailbox& dest_mailbox,
                                          const SkYUVAPixmaps& src_yuv_pixmap) {
  TRACE_EVENT0("gpu", "RasterImplementation::WritePixelsYUV");
  const auto& src_yuv_info = src_yuv_pixmap.yuvaInfo();
  const auto& src_yuv_pixmap_info = src_yuv_pixmap.pixmapsInfo();
  const std::array<SkPixmap, SkYUVAInfo::kMaxPlanes>& src_sk_pixmaps =
      src_yuv_pixmap.planes();

  GLuint total_size = 0;
  for (int plane = 0; plane < src_yuv_info.numPlanes(); plane++) {
    CHECK(src_sk_pixmaps[plane].addr());
    total_size += base::bits::AlignUp(src_sk_pixmaps[plane].computeByteSize(),
                                      sizeof(uint64_t));
  }

  ScopedSharedMemoryPtr scoped_shared_memory(total_size, transfer_buffer_,
                                             mapped_memory_.get(), helper());
  if (!scoped_shared_memory.valid()) {
    SetGLError(GL_INVALID_OPERATION, "WritePixelsYUV", "size too big");
    return;
  }

  GLint shm_id = scoped_shared_memory.shm_id();
  GLuint shm_offset = scoped_shared_memory.offset();
  void* address = scoped_shared_memory.address();

  // Copy the pixels for first plane at `address`.
  CHECK(src_sk_pixmaps[0].addr());
  memcpy(static_cast<uint8_t*>(address), src_sk_pixmaps[0].addr(),
         src_sk_pixmaps[0].computeByteSize());

  std::array<GLuint, SkYUVAInfo::kMaxPlanes> plane_offsets = {};
  for (int plane = 1; plane < src_yuv_info.numPlanes(); plane++) {
    CHECK(src_sk_pixmaps[plane].addr());
    // Calculate the offset based on previous plane offset and previous plane
    // size, and copy pixels for current plane starting at current plane
    // offset.
    GLuint prev_plane_size = src_sk_pixmaps[plane - 1].computeByteSize();
    plane_offsets[plane] =
        plane_offsets[plane - 1] +
        base::bits::AlignUp(prev_plane_size,
                            static_cast<GLuint>(sizeof(uint64_t)));
    memcpy(static_cast<uint8_t*>(address) + plane_offsets[plane],
           src_sk_pixmaps[plane].addr(),
           src_sk_pixmaps[plane].computeByteSize());
  }

  helper_->WritePixelsYUVINTERNALImmediate(
      src_yuv_info.width(), src_yuv_info.height(), src_sk_pixmaps[0].rowBytes(),
      src_sk_pixmaps[1].rowBytes(), src_sk_pixmaps[2].rowBytes(),
      src_sk_pixmaps[3].rowBytes(),
      static_cast<int>(src_yuv_info.planeConfig()),
      static_cast<int>(src_yuv_info.subsampling()),
      static_cast<int>(src_yuv_pixmap_info.dataType()), shm_id, shm_offset,
      plane_offsets[1], plane_offsets[2], plane_offsets[3], dest_mailbox.name);
}

void RasterImplementation::BeginRasterCHROMIUM(
    SkColor4f sk_color_4f,
    GLboolean needs_clear,
    GLuint msaa_sample_count,
    MsaaMode msaa_mode,
    GLboolean can_use_lcd_text,
    GLboolean visible,
    const gfx::ColorSpace& color_space,
    float hdr_headroom,
    const GLbyte* mailbox) {
  DCHECK(!raster_properties_);

  helper_->BeginRasterCHROMIUMImmediate(
      sk_color_4f.fR, sk_color_4f.fG, sk_color_4f.fB, sk_color_4f.fA,
      needs_clear, msaa_sample_count, msaa_mode, can_use_lcd_text, visible,
      hdr_headroom, mailbox);

  raster_properties_.emplace(sk_color_4f, can_use_lcd_text,
                             color_space.ToSkColorSpace());
}

void RasterImplementation::RasterCHROMIUM(
    const cc::DisplayItemList* list,
    cc::ImageProvider* provider,
    const gfx::Size& content_size,
    const gfx::Rect& full_raster_rect,
    const gfx::Rect& playback_rect,
    const gfx::Vector2dF& post_translate,
    const gfx::Vector2dF& post_scale,
    bool requires_clear,
    const ScrollOffsetMap* raster_inducing_scroll_offsets,
    size_t* max_op_size_hint) {
  TRACE_EVENT1("gpu", "RasterImplementation::RasterCHROMIUM",
               "raster_chromium_id", ++raster_chromium_id_);
  DCHECK(max_op_size_hint);

  if (std::abs(post_scale.x()) < std::numeric_limits<float>::epsilon() ||
      std::abs(post_scale.y()) < std::numeric_limits<float>::epsilon()) {
    return;
  }

  gfx::Rect query_rect = gfx::ScaleToEnclosingRect(
      playback_rect, 1.f / post_scale.x(), 1.f / post_scale.y());
  list->SearchOpsByRect(query_rect, &temp_raster_offsets_);
  // We can early out if we have nothing to draw and we don't need a clear. Note
  // that if there is nothing to draw, but a clear is required, then those
  // commands would be serialized in the preamble and it's important to play
  // those back.
  if (temp_raster_offsets_.empty() && !requires_clear) {
    return;
  }

  // TODO(enne): Tune these numbers
  static constexpr uint32_t kMinAlloc = 16 * 1024;
  uint32_t free_size = std::max(GetTransferBufferFreeSize(), kMinAlloc);

  // This section duplicates RasterSource::PlaybackToCanvas setup preamble.
  cc::PaintOpBufferSerializer::Preamble preamble;
  preamble.content_size = content_size;
  preamble.full_raster_rect = full_raster_rect;
  preamble.playback_rect = playback_rect;
  preamble.post_translation = post_translate;
  preamble.post_scale = post_scale;
  preamble.requires_clear = requires_clear;
  preamble.background_color = raster_properties_->background_color;

  // Wrap the provided provider in a stashing provider so that we can delay
  // unrefing images until we have serialized dependent commands.
  cc::DecodeStashingImageProvider stashing_image_provider(provider);

  // TODO(enne): Don't access private members of DisplayItemList.
  TransferCacheSerializeHelperImpl transfer_cache_serialize_helper(this);
  PaintOpSerializer op_serializer(free_size, this, &stashing_image_provider,
                                  &transfer_cache_serialize_helper,
                                  &font_manager_, max_op_size_hint);

  cc::PaintOpBufferSerializer serializer(
      PaintOpSerializer::Serialize, &op_serializer,
      cc::PaintOp::SerializeOptions(
          &stashing_image_provider, &transfer_cache_serialize_helper,
          GetOrCreatePaintCache(), font_manager_.strike_server(),
          raster_properties_->color_space, &skottie_serialization_history_,
          raster_properties_->can_use_lcd_text,
          capabilities().context_supports_distance_field_text,
          capabilities().max_texture_size, raster_inducing_scroll_offsets));
  serializer.Serialize(list->paint_op_buffer(), &temp_raster_offsets_,
                       preamble);
  // TODO(piman): raise error if !serializer.valid()?
  op_serializer.SendSerializedData();
}

void RasterImplementation::EndRasterCHROMIUM() {
  DCHECK(raster_properties_);

  raster_properties_.reset();
  helper_->EndRasterCHROMIUM();

  if (aggressively_free_resources_) {
    ClearPaintCache();
  } else {
    FlushPaintCachePurgedEntries();
  }

  skottie_serialization_history_.RequestInactiveAnimationsPurge();
}

bool RasterImplementation::ReadbackImagePixelsINTERNAL(
    const gpu::Mailbox& source_mailbox,
    const SkImageInfo& dst_info,
    GLuint dst_row_bytes,
    int src_x,
    int src_y,
    int plane_index,
    base::OnceCallback<void(bool)> readback_done,
    void* dst_pixels) {
  DCHECK_GE(dst_row_bytes, dst_info.minRowBytes());

  // We can't use GetResultAs<>() to store our result because it uses
  // TransferBuffer under the hood and this function is potentially
  // asynchronous. Instead, store the result at the beginning of the shared
  // memory we allocate to transfer pixels.
  GLuint color_space_offset = base::bits::AlignUp(
      sizeof(cmds::ReadbackARGBImagePixelsINTERNALImmediate::Result),
      sizeof(uint64_t));

  // Add the size of the SkColorSpace while maintaining 8-byte alignment.
  GLuint pixels_offset = color_space_offset;
  if (dst_info.colorSpace()) {
    pixels_offset = base::bits::AlignUp(
        color_space_offset + dst_info.colorSpace()->writeToMemory(nullptr),
        sizeof(uint64_t));
  }

  GLuint dst_size = dst_info.computeByteSize(dst_row_bytes);
  GLuint total_size =
      pixels_offset +
      base::bits::AlignUp(dst_size, static_cast<GLuint>(sizeof(uint64_t)));

  std::unique_ptr<ScopedMappedMemoryPtr> scoped_shared_memory =
      std::make_unique<ScopedMappedMemoryPtr>(total_size, helper(),
                                              mapped_memory_.get());

  if (!scoped_shared_memory->valid()) {
    // Note, that this runs callback out of order.
    if (readback_done) {
      std::move(readback_done).Run(/*success=*/false);
    }
    return false;
  }

  GLint shm_id = scoped_shared_memory->shm_id();
  GLuint shm_offset = scoped_shared_memory->offset();
  void* shm_address = scoped_shared_memory->address();

  // Readback success/failure result is stored at the beginning of the shared
  // memory region. Client is responsible for initialization so we do so here.
  auto* readback_result =
      static_cast<cmds::ReadbackARGBImagePixelsINTERNALImmediate::Result*>(
          shm_address);
  *readback_result = 0;

  if (dst_info.colorSpace()) {
    size_t bytes_written = dst_info.colorSpace()->writeToMemory(
        static_cast<uint8_t*>(shm_address) + color_space_offset);
    DCHECK_LE(bytes_written + color_space_offset, pixels_offset);
  }

  bool is_async = !!readback_done;

  GLuint query;
  if (is_async) {
    GenQueriesEXT(1, &query);

    // This query is currently sufficient because the readback implementation in
    // RasterDecoder is synchronous. If that call is changed to be asynchronous
    // later we'll need to implement a more sophisticated query.
    BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query);
  }

  helper_->ReadbackARGBImagePixelsINTERNALImmediate(
      src_x, src_y, plane_index, dst_info.width(), dst_info.height(),
      dst_row_bytes, dst_info.colorType(), dst_info.alphaType(), shm_id,
      shm_offset, color_space_offset, pixels_offset, source_mailbox.name);

  if (is_async) {
    EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);

    auto request = std::make_unique<AsyncARGBReadbackRequest>(
        dst_pixels, dst_size, pixels_offset, query,
        std::move(scoped_shared_memory), std::move(readback_done));
    auto* request_ptr = request.get();
    argb_request_queue_.push(std::move(request));
    SignalQuery(query,
                base::BindOnce(&RasterImplementation::OnAsyncARGBReadbackDone,
                               base::Unretained(this), request_ptr));
  } else {
    WaitForCmd();

    if (!*readback_result) {
      return false;
    }
    // We need to use `RelaxedAtomicWriteMemcpy` because we might be writing
    // into memory observed by JS at the same time.
    auto dst = base::span<uint8_t>(static_cast<uint8_t*>(dst_pixels), dst_size);
    auto src = base::span<uint8_t>(
        static_cast<uint8_t*>(shm_address) + pixels_offset, dst_size);
    base::subtle::RelaxedAtomicWriteMemcpy(dst, src);
  }

  return true;
}

void RasterImplementation::OnAsyncARGBReadbackDone(
    AsyncARGBReadbackRequest* finished_request) {
  TRACE_EVENT0("gpu", "RasterImplementation::OnAsyncARGBReadbackDone");
  finished_request->done = true;

  // Only process requests in the order they were sent, regardless of when they
  // finish.
  while (!argb_request_queue_.empty()) {
    auto& request = argb_request_queue_.front();
    if (!request->done) {
      break;
    }

    // Readback success/failure is stored at the beginning of the shared memory
    // region.
    auto* result =
        static_cast<cmds::ReadbackARGBImagePixelsINTERNALImmediate::Result*>(
            request->shared_memory->address());
    if (*result) {
      // We need to use `RelaxedAtomicWriteMemcpy` because we might be writing
      // into memory observed by JS at the same time.
      size_t plane_size = request->dst_size;
      auto dst = base::span<uint8_t>(
          static_cast<uint8_t*>(request->dst_pixels.get()), plane_size);
      auto src = base::span<uint8_t>(
          static_cast<uint8_t*>(request->shared_memory->address()) +
              request->pixels_offset,
          plane_size);
      base::subtle::RelaxedAtomicWriteMemcpy(dst, src);
      request->readback_successful = true;
    }

    if (request->query) {
      DeleteQueriesEXT(1, &request->query);
    }

    argb_request_queue_.pop();
  }
}

void RasterImplementation::CancelRequests() {
  gpu_control_->CancelAllQueries();
  while (!argb_request_queue_.empty()) {
    if (argb_request_queue_.front()->query) {
      DeleteQueriesEXT(1, &argb_request_queue_.front()->query);
    }

    argb_request_queue_.pop();
  }

  while (!yuv_request_queue_.empty()) {
    if (yuv_request_queue_.front()->query) {
      DeleteQueriesEXT(1, &yuv_request_queue_.front()->query);
    }

    yuv_request_queue_.pop();
  }
}

void RasterImplementation::ReadbackARGBPixelsAsync(
    const gpu::Mailbox& source_mailbox,
    GLenum source_target,
    GrSurfaceOrigin source_origin,
    const gfx::Size& source_size,
    const gfx::Point& source_starting_point,
    const SkImageInfo& dst_info,
    GLuint dst_row_bytes,
    base::span<uint8_t> out,
    base::OnceCallback<void(bool)> readback_done) {
  TRACE_EVENT0("gpu", "RasterImplementation::ReadbackARGBPixelsAsync");
  DCHECK(!!readback_done);
  // Note: It's possible the GL implementation supports other readback
  // types. However, as of this writing, no caller of this method will
  // request a different |color_type| (i.e., requiring using some other GL
  // format).
  if (dst_info.colorType() != kRGBA_8888_SkColorType &&
      dst_info.colorType() != kBGRA_8888_SkColorType) {
    std::move(readback_done).Run(/*readback_sucess=*/false);
    return;
  }

  ReadbackImagePixelsINTERNAL(source_mailbox, dst_info, dst_row_bytes,
                              source_starting_point.x(),
                              source_starting_point.y(), /*plane_index=*/0,
                              std::move(readback_done), out.data());
}

bool RasterImplementation::ReadbackImagePixels(
    const gpu::Mailbox& source_mailbox,
    const SkImageInfo& dst_info,
    GLuint dst_row_bytes,
    int src_x,
    int src_y,
    int plane_index,
    void* dst_pixels) {
  TRACE_EVENT0("gpu", "RasterImplementation::ReadbackImagePixels");
  return ReadbackImagePixelsINTERNAL(
             source_mailbox, dst_info, dst_row_bytes, src_x, src_y, plane_index,
             base::OnceCallback<void(bool)>(), dst_pixels) ||
         base::FeatureList::IsEnabled(kDisableErrorHandlingForReadback);
}

void RasterImplementation::ReadbackYUVPixelsAsync(
    const gpu::Mailbox& source_mailbox,
    GLenum source_target,
    const gfx::Size& source_size,
    const gfx::Rect& output_rect,
    bool vertically_flip_texture,
    int y_plane_row_stride_bytes,
    base::span<uint8_t> y_plane_data,
    int u_plane_row_stride_bytes,
    base::span<uint8_t> u_plane_data,
    int v_plane_row_stride_bytes,
    base::span<uint8_t> v_plane_data,
    const gfx::Point& paste_location,
    base::OnceCallback<void()> release_mailbox,
    base::OnceCallback<void(bool)> readback_done) {
  TRACE_EVENT0("gpu", "RasterImplementation::ReadbackYUVPixelsAsync");
  DCHECK(!!release_mailbox);
  DCHECK(!!readback_done);

  if (output_rect.width() % 2 != 0 || output_rect.height() % 2 != 0) {
    SetGLError(GL_INVALID_VALUE, "glReadbackYUVPixelsAsync",
               "|output_rect| width and height must be divisible by 2");
    return;
  }

  auto y_offset = static_cast<GLuint>(base::bits::AlignUp(
      sizeof(cmds::ReadbackYUVImagePixelsINTERNALImmediate::Result),
      sizeof(uint64_t)));

  if (y_plane_row_stride_bytes < output_rect.width()) {
    SetGLError(
        GL_INVALID_VALUE, "glReadbackYUVPixelsAsync",
        "|y_plane_row_stride_bytes| must be >= the width of the y plane.");
    return;
  }
  GLuint y_padded_size = output_rect.height() * y_plane_row_stride_bytes;

  constexpr auto kSizeofUint64 = static_cast<GLuint>(sizeof(uint64_t));
  GLuint u_offset =
      base::bits::AlignUp(y_offset + y_padded_size, kSizeofUint64);
  if (u_plane_row_stride_bytes < ((output_rect.width() + 1) / 2)) {
    SetGLError(
        GL_INVALID_VALUE, "glReadbackYUVPixelsAsync",
        "|u_plane_row_stride_bytes| must be >= the width of the u plane.");
    return;
  }
  GLuint u_padded_size =
      ((output_rect.height() + 1) / 2) * u_plane_row_stride_bytes;

  GLuint v_offset =
      base::bits::AlignUp(u_offset + u_padded_size, kSizeofUint64);
  if (v_plane_row_stride_bytes < ((output_rect.width() + 1) / 2)) {
    SetGLError(
        GL_INVALID_VALUE, "glReadbackYUVPixelsAsync",
        "|v_plane_row_stride_bytes| must be >= the width of the v plane.");
    return;
  }
  GLuint v_padded_size =
      ((output_rect.height() + 1) / 2) * v_plane_row_stride_bytes;

  size_t total_size =
      base::bits::AlignUp(v_offset + v_padded_size, kSizeofUint64);

  std::unique_ptr<ScopedMappedMemoryPtr> scoped_shared_memory =
      std::make_unique<ScopedMappedMemoryPtr>(total_size, helper(),
                                              mapped_memory_.get());
  if (!scoped_shared_memory->valid()) {
    SetGLError(GL_INVALID_VALUE, "glReadbackYUVPixelsAsync",
               "couldn't allocate shared memory");
    return;
  }

  GLint shm_id = scoped_shared_memory->shm_id();
  GLuint shm_offset = scoped_shared_memory->offset();
  void* shm_address = scoped_shared_memory->address();

  auto* readback_result =
      static_cast<cmds::ReadbackYUVImagePixelsINTERNALImmediate::Result*>(
          shm_address);
  *readback_result = 0;

  GLuint query;
  GenQueriesEXT(1, &query);
  BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query);
  helper_->ReadbackYUVImagePixelsINTERNALImmediate(
      output_rect.width(), output_rect.height(), shm_id, shm_offset, y_offset,
      y_plane_row_stride_bytes, u_offset, u_plane_row_stride_bytes, v_offset,
      v_plane_row_stride_bytes, source_mailbox.name);
  EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);

  auto request = std::make_unique<AsyncYUVReadbackRequest>(
      output_rect, query, y_plane_row_stride_bytes, y_offset,
      y_plane_data.data(), u_plane_row_stride_bytes, u_offset,
      u_plane_data.data(), v_plane_row_stride_bytes, v_offset,
      v_plane_data.data(), std::move(scoped_shared_memory),
      std::move(release_mailbox), std::move(readback_done));
  auto* request_ptr = request.get();
  yuv_request_queue_.push(std::move(request));
  SignalQuery(query,
              base::BindOnce(&RasterImplementation::OnAsyncYUVReadbackDone,
                             base::Unretained(this),
                             // This is safe because we own `request` through
                             // `yuv_request_queue_`, and we make certain not to
                             // run this callback when a request has been
                             // destroyed. We remove and destroy requests from
                             // `yuv_request_queue_` in two places:
                             // `OnAsyncYUVReadbackDone` and `CancelRequests`.
                             //
                             // `OnAsyncYUVReadbackDone` is this callback we're
                             // binding. We only destroy requests there if their
                             // callback has run. This is kept track of with
                             // `AsyncYUVReadbackRequest`'s `done` member.
                             //
                             // The latter calls CancelAllQueries before
                             // destroying all requests in `yuv_request_queue_`
                             // which prevents this callback from running.
                             base::Unretained(request_ptr)));
}

void RasterImplementation::OnAsyncYUVReadbackDone(
    AsyncYUVReadbackRequest* finished_request) {
  TRACE_EVENT0("gpu", "RasterImplementation::OnAsyncYUVReadbackDone");
  finished_request->done = true;

  while (!yuv_request_queue_.empty()) {
    auto& request = yuv_request_queue_.front();
    if (!request->done) {
      break;
    }

    request->CopyYUVPlanes();

    if (request->query) {
      DeleteQueriesEXT(1, &request->query);
    }

    yuv_request_queue_.pop();
  }
}

void RasterImplementation::TraceBeginCHROMIUM(const char* category_name,
                                              const char* trace_name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM("
                     << category_name << ", " << trace_name << ")");
  static constexpr size_t kMaxStrLen = 256;
  DCHECK_LE(strlen(category_name), kMaxStrLen);
  DCHECK_LE(strlen(trace_name), kMaxStrLen);
  SetBucketAsCString(kResultBucketId, category_name);
  SetBucketAsCString(kResultBucketId + 1, trace_name);
  helper_->TraceBeginCHROMIUM(kResultBucketId, kResultBucketId + 1);
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->SetBucketSize(kResultBucketId + 1, 0);
  current_trace_stack_++;
}

void RasterImplementation::TraceEndCHROMIUM() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceEndCHROMIUM(" << ")");
  if (current_trace_stack_ == 0) {
    SetGLError(GL_INVALID_OPERATION, "glTraceEndCHROMIUM",
               "missing begin trace");
    return;
  }
  helper_->TraceEndCHROMIUM();
  current_trace_stack_--;
}

void RasterImplementation::SetActiveURLCHROMIUM(const char* url) {
  DCHECK(url);
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSetActiveURLCHROMIUM(" << url);

  if (last_active_url_ == url) {
    return;
  }

  last_active_url_ = url;
  static constexpr uint32_t kMaxStrLen = 1024;
  size_t len = strlen(url);
  if (len == 0) {
    return;
  }

  SetBucketContents(kResultBucketId, url,
                    base::CheckMin(len, kMaxStrLen).ValueOrDie());
  helper_->SetActiveURLCHROMIUM(kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
}

cc::ClientPaintCache* RasterImplementation::GetOrCreatePaintCache() {
  if (!paint_cache_) {
    size_t paint_cache_budget = 0u;
    if (base::SysInfo::IsLowEndDevice()) {
      paint_cache_budget = 256 * 1024;
    } else {
      paint_cache_budget = 4 * 1024 * 1024;
    }
    paint_cache_ = std::make_unique<cc::ClientPaintCache>(paint_cache_budget);
  }
  return paint_cache_.get();
}

void RasterImplementation::FlushPaintCachePurgedEntries() {
  if (!paint_cache_) {
    return;
  }

  paint_cache_->Purge(&temp_paint_cache_purged_data_);
  for (uint32_t i = static_cast<uint32_t>(cc::PaintCacheDataType::kPath);
       i < cc::PaintCacheDataTypeCount; ++i) {
    auto& ids = temp_paint_cache_purged_data_[i];
    if (ids.empty()) {
      continue;
    }

    switch (static_cast<cc::PaintCacheDataType>(i)) {
      case cc::PaintCacheDataType::kPath:
        DEFINE_PAINT_CACHE_DELETION(kMaxImmediateDeletedPaintCachePaths,
                                    DeletePaintCachePathsINTERNALImmediate,
                                    DeletePaintCachePathsINTERNAL);
        break;
      case cc::PaintCacheDataType::kSkRuntimeEffect:
        DEFINE_PAINT_CACHE_DELETION(kMaxImmediateDeletedPaintCacheEffects,
                                    DeletePaintCacheEffectsINTERNALImmediate,
                                    DeletePaintCacheEffectsINTERNAL);
        break;
    }
    ids.clear();
  }
}

void RasterImplementation::ClearPaintCache() {
  if (!paint_cache_ || !paint_cache_->PurgeAll()) {
    return;
  }

  helper_->ClearPaintCacheINTERNAL();
}

std::unique_ptr<cc::TransferCacheSerializeHelper>
RasterImplementation::CreateTransferCacheHelperForTesting() {
  return std::make_unique<TransferCacheSerializeHelperImpl>(this);
}

void RasterImplementation::SetRasterMappedBufferForTesting(
    ScopedTransferBufferPtr buffer) {
  raster_mapped_buffer_.emplace(std::move(buffer));
}

RasterImplementation::RasterProperties::RasterProperties(
    SkColor4f background_color,
    bool can_use_lcd_text,
    sk_sp<SkColorSpace> color_space)
    : background_color(background_color),
      can_use_lcd_text(can_use_lcd_text),
      color_space(std::move(color_space)) {}

RasterImplementation::RasterProperties::~RasterProperties() = default;

}  // namespace raster
}  // namespace gpu
