chromium/gpu/command_buffer/client/raster_implementation.cc

// 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 <limits>
#include <set>
#include <sstream>
#include <string>

#include "base/atomic_sequence_num.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/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 "components/miracle_parameter/common/public/miracle_parameter.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/image_decode_accelerator_interface.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()
#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
#define GPU_CLIENT_DCHECK
#elif defined(DCHECK)
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v)
#define GPU_CLIENT_DCHECK(v)
#else
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT
#define GPU_CLIENT_DCHECK
#endif

#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(type, ptr)

#define GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(type, ptr)

GLES2Util;

namespace gpu {
namespace raster {

namespace {

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

BASE_FEATURE();

MIRACLE_PARAMETER_FOR_INT(GetNormalPaintCacheBudget,
                          kPaintCacheBudgetConfigurableFeature,
                          "NormalPaintCacheBudgetBytes",
                          4 * 1024 * 1024)

MIRACLE_PARAMETER_FOR_INT(GetLowEndPaintCacheBudget,
                          kPaintCacheBudgetConfigurableFeature,
                          "LowEndPaintCacheBudgetBytes",
                          256 * 1024)

const uint32_t kMaxTransferCacheEntrySizeForTransferBuffer =;
const size_t kMaxImmediateDeletedPaintCachePaths =;

class ScopedSharedMemoryPtr {};

}  // namespace

// Helper to copy data to the GPU service over the transfer cache.
class RasterImplementation::TransferCacheSerializeHelperImpl final
    : public cc::TransferCacheSerializeHelper {};

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

RasterImplementation::SingleThreadChecker::SingleThreadChecker(
    RasterImplementation* raster_implementation)
    :{}

RasterImplementation::SingleThreadChecker::~SingleThreadChecker() {}

struct RasterImplementation::AsyncARGBReadbackRequest {};

struct RasterImplementation::AsyncYUVReadbackRequest {};

RasterImplementation::RasterImplementation(
    RasterCmdHelper* helper,
    TransferBufferInterface* transfer_buffer,
    bool bind_generates_resource,
    bool lose_context_when_out_of_memory,
    GpuControl* gpu_control,
    ImageDecodeAcceleratorInterface* image_decode_accelerator)
    :{}

gpu::ContextResult RasterImplementation::Initialize(
    const SharedMemoryLimits& limits) {}

RasterImplementation::~RasterImplementation() {}

RasterCmdHelper* RasterImplementation::helper() const {}

IdAllocator* RasterImplementation::GetIdAllocator(IdNamespaces namespace_id) {}

void RasterImplementation::OnGpuControlLostContext() {}

void RasterImplementation::OnGpuControlLostContextMaybeReentrant() {}

void RasterImplementation::OnGpuControlErrorMessage(const char* message,
                                                    int32_t id) {}

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

void RasterImplementation::SetAggressivelyFreeResources(
    bool aggressively_free_resources) {}

uint64_t RasterImplementation::ShareGroupTracingGUID() const {}

void RasterImplementation::SetErrorMessageCallback(
    base::RepeatingCallback<void(const char*, int32_t)> callback) {}

bool RasterImplementation::ThreadSafeShallowLockDiscardableTexture(
    uint32_t texture_id) {}

void RasterImplementation::CompleteLockDiscardableTexureOnContextThread(
    uint32_t texture_id) {}

bool RasterImplementation::ThreadsafeDiscardableTextureIsDeletedForTracing(
    uint32_t texture_id) {}

void* RasterImplementation::MapTransferCacheEntry(uint32_t serialized_size) {}

void RasterImplementation::UnmapAndCreateTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {}

bool RasterImplementation::ThreadsafeLockTransferCacheEntry(uint32_t type,
                                                            uint32_t id) {}

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

void RasterImplementation::DeleteTransferCacheEntry(uint32_t type,
                                                    uint32_t id) {}

unsigned int RasterImplementation::GetTransferBufferFreeSize() const {}

bool RasterImplementation::IsJpegDecodeAccelerationSupported() const {}

bool RasterImplementation::IsWebPDecodeAccelerationSupported() const {}

bool RasterImplementation::CanDecodeWithHardwareAcceleration(
    const cc::ImageHeaderMetadata* image_metadata) const {}

const std::string& RasterImplementation::GetLogPrefix() const {}

GLenum RasterImplementation::GetError() {}

void RasterImplementation::IssueBeginQuery(GLenum target,
                                           GLuint id,
                                           uint32_t sync_data_shm_id,
                                           uint32_t sync_data_shm_offset) {}

void RasterImplementation::IssueEndQuery(GLenum target, GLuint submit_count) {}

void RasterImplementation::IssueQueryCounter(GLuint id,
                                             GLenum target,
                                             uint32_t sync_data_shm_id,
                                             uint32_t sync_data_shm_offset,
                                             GLuint submit_count) {}

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

GLenum RasterImplementation::GetClientSideGLError() {}

CommandBufferHelper* RasterImplementation::cmd_buffer_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) {}

void RasterImplementation::IssueDeleteTransferCacheEntry(GLuint entry_type,
                                                         GLuint entry_id) {}

void RasterImplementation::IssueUnlockTransferCacheEntry(GLuint entry_type,
                                                         GLuint entry_id) {}

CommandBuffer* RasterImplementation::command_buffer() const {}

GLenum RasterImplementation::GetGLError() {}

#if defined(RASTER_CLIENT_FAIL_GL_ERRORS)
void RasterImplementation::FailGLError(GLenum error) {
  if (error != GL_NO_ERROR) {
    NOTREACHED_IN_MIGRATION() << "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) {}

void RasterImplementation::SetGLErrorInvalidEnum(const char* function_name,
                                                 GLenum value,
                                                 const char* label) {}

bool RasterImplementation::GetQueryObjectValueHelper(const char* function_name,
                                                     GLuint id,
                                                     GLenum pname,
                                                     GLuint64* params) {}

void RasterImplementation::Flush() {}

// InterfaceBase implementation.
void RasterImplementation::GenSyncTokenCHROMIUM(GLbyte* sync_token) {}
void RasterImplementation::GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) {}
void RasterImplementation::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
                                                    GLsizei count) {}
void RasterImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {}
void RasterImplementation::ShallowFlushCHROMIUM() {}

// ImplementationBase implementation.
void RasterImplementation::IssueShallowFlush() {}

void RasterImplementation::FlushHelper() {}

void RasterImplementation::OrderingBarrierCHROMIUM() {}

void RasterImplementation::Finish() {}

void RasterImplementation::FinishHelper() {}

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

GLenum RasterImplementation::GetGraphicsResetStatusKHR() {}

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

void RasterImplementation::BeginQueryEXT(GLenum target, GLuint id) {}

void RasterImplementation::EndQueryEXT(GLenum target) {}

void RasterImplementation::QueryCounterEXT(GLuint id, GLenum target) {}
void RasterImplementation::GetQueryObjectuivEXT(GLuint id,
                                                GLenum pname,
                                                GLuint* params) {}

void RasterImplementation::GetQueryObjectui64vEXT(GLuint id,
                                                  GLenum pname,
                                                  GLuint64* params) {}

void* RasterImplementation::MapRasterCHROMIUM(uint32_t size,
                                              uint32_t* size_allocated) {}

void* RasterImplementation::MapFontBuffer(uint32_t size) {}

void RasterImplementation::UnmapRasterCHROMIUM(uint32_t raster_written_size,
                                               uint32_t total_written_size) {}

// 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,
                                           GLenum dest_target,
                                           GLint xoffset,
                                           GLint yoffset,
                                           GLint x,
                                           GLint y,
                                           GLsizei width,
                                           GLsizei height,
                                           GLboolean unpack_flip_y,
                                           GLboolean unpack_premultiply_alpha) {}

void RasterImplementation::WritePixels(const gpu::Mailbox& dest_mailbox,
                                       int dst_x_offset,
                                       int dst_y_offset,
                                       GLenum texture_target,
                                       const SkPixmap& src_sk_pixmap) {}

void RasterImplementation::WritePixelsYUV(const gpu::Mailbox& dest_mailbox,
                                          const SkYUVAPixmaps& src_yuv_pixmap) {}

namespace {
constexpr size_t kNumMailboxes =;
}  // namespace

void RasterImplementation::ConvertYUVAMailboxesToRGB(
    const gpu::Mailbox& dest_mailbox,
    GLint src_x,
    GLint src_y,
    GLsizei width,
    GLsizei height,
    SkYUVColorSpace planes_yuv_color_space,
    const SkColorSpace* planes_rgb_color_space,
    SkYUVAInfo::PlaneConfig plane_config,
    SkYUVAInfo::Subsampling subsampling,
    const gpu::Mailbox yuva_plane_mailboxes[]) {}

void RasterImplementation::ConvertRGBAToYUVAMailboxes(
    SkYUVColorSpace planes_yuv_color_space,
    SkYUVAInfo::PlaneConfig plane_config,
    SkYUVAInfo::Subsampling subsampling,
    const gpu::Mailbox yuva_plane_mailboxes[],
    const gpu::Mailbox& source_mailbox) {}

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) {}

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) {}

void RasterImplementation::EndRasterCHROMIUM() {}

SyncToken RasterImplementation::ScheduleImageDecode(
    base::span<const uint8_t> encoded_data,
    const gfx::Size& output_size,
    uint32_t transfer_cache_entry_id,
    const gfx::ColorSpace& target_color_space,
    bool needs_mips) {}

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) {}

void RasterImplementation::OnAsyncARGBReadbackDone(
    AsyncARGBReadbackRequest* finished_request) {}

void RasterImplementation::CancelRequests() {}

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,
    unsigned char* out,
    base::OnceCallback<void(bool)> readback_done) {}

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) {}

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,
    unsigned char* y_plane_data,
    int u_plane_row_stride_bytes,
    unsigned char* u_plane_data,
    int v_plane_row_stride_bytes,
    unsigned char* v_plane_data,
    const gfx::Point& paste_location,
    base::OnceCallback<void()> release_mailbox,
    base::OnceCallback<void(bool)> readback_done) {}

void RasterImplementation::OnAsyncYUVReadbackDone(
    AsyncYUVReadbackRequest* finished_request) {}

void RasterImplementation::IssueImageDecodeCacheEntryCreation(
    base::span<const uint8_t> encoded_data,
    const gfx::Size& output_size,
    uint32_t transfer_cache_entry_id,
    const gfx::ColorSpace& target_color_space,
    bool needs_mips,
    SyncToken* decode_sync_token,
    ClientDiscardableHandle handle) {}

GLuint RasterImplementation::CreateAndConsumeForGpuRaster(
    const gpu::Mailbox& mailbox) {}

GLuint RasterImplementation::CreateAndConsumeForGpuRaster(
    const scoped_refptr<gpu::ClientSharedImage>& shared_image) {}

void RasterImplementation::DeleteGpuRasterTexture(GLuint texture) {}

void RasterImplementation::BeginGpuRaster() {}
void RasterImplementation::EndGpuRaster() {}

void RasterImplementation::BeginSharedImageAccessDirectCHROMIUM(GLuint texture,
                                                                GLenum mode) {}

void RasterImplementation::EndSharedImageAccessDirectCHROMIUM(GLuint texture) {}

void RasterImplementation::InitializeDiscardableTextureCHROMIUM(
    GLuint texture) {}

void RasterImplementation::UnlockDiscardableTextureCHROMIUM(GLuint texture) {}

bool RasterImplementation::LockDiscardableTextureCHROMIUM(GLuint texture) {}

void RasterImplementation::TraceBeginCHROMIUM(const char* category_name,
                                              const char* trace_name) {}

void RasterImplementation::TraceEndCHROMIUM() {}

void RasterImplementation::SetActiveURLCHROMIUM(const char* url) {}

cc::ClientPaintCache* RasterImplementation::GetOrCreatePaintCache() {}

void RasterImplementation::FlushPaintCachePurgedEntries() {}

void RasterImplementation::ClearPaintCache() {}

std::unique_ptr<cc::TransferCacheSerializeHelper>
RasterImplementation::CreateTransferCacheHelperForTesting() {}

void RasterImplementation::SetRasterMappedBufferForTesting(
    ScopedTransferBufferPtr buffer) {}

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

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

}  // namespace raster
}  // namespace gpu