chromium/gpu/command_buffer/service/raster_decoder.cc

// Copyright 2017 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/service/raster_decoder.h"

#include <stdint.h>

#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/atomic_sequence_num.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/checked_math.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/paint_cache.h"
#include "cc/paint/paint_op.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/transfer_cache_deserialize_helper.h"
#include "cc/paint/transfer_cache_entry.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/command_buffer_id.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_result.h"
#include "gpu/command_buffer/common/debug_marker_manager.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/raster_cmd_format.h"
#include "gpu/command_buffer/common/raster_cmd_ids.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/context_state.h"
#include "gpu/command_buffer/service/copy_shared_image_helper.h"
#include "gpu/command_buffer/service/decoder_client.h"
#include "gpu/command_buffer/service/error_state.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/query_manager.h"
#include "gpu/command_buffer/service/raster_cmd_validation.h"
#include "gpu/command_buffer/service/service_font_manager.h"
#include "gpu/command_buffer/service/service_transfer_cache.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h"
#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
#include "gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h"
#include "gpu/command_buffer/service/skia_utils.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/vulkan/buildflags.h"
#include "skia/ext/legacy_display_globals.h"
#include "skia/ext/rgba_to_yuva.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/core/SkYUVAInfo.h"
#include "third_party/skia/include/core/SkYUVAPixmaps.h"
#include "third_party/skia/include/gpu/GrBackendSemaphore.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/GrTypes.h"
#include "third_party/skia/include/gpu/GrYUVABackendTextures.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/graphite/Context.h"
#include "third_party/skia/include/private/chromium/GrPromiseImageTexture.h"
#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_version_info.h"

#if BUILDFLAG(ENABLE_VULKAN)
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_util.h"
#endif  // BUILDFLAG(ENABLE_VULKAN)

#if BUILDFLAG(IS_WIN)
#include "gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h"
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(SKIA_USE_DAWN)
#include <dawn/webgpu_cpp.h>
#include "gpu/command_buffer/service/dawn_context_provider.h"
#endif  // BUILDFLAG(USE_DAWN)

#if BUILDFLAG(SKIA_USE_DAWN) && BUILDFLAG(IS_CHROMEOS_ASH)
#include "gpu/command_buffer/service/drm_modifiers_filter_dawn.h"
#endif  // BUILDFLAG(SKIA_USE_DAWN) && BUILDFLAG(IS_CHROMEOS_ASH)

// Local versions of the SET_GL_ERROR macros
#define LOCAL_SET_GL_ERROR(error, function_name, msg)
#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label)
#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name)
#define LOCAL_PEEK_GL_ERROR(function_name)
#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name)
#define LOCAL_PERFORMANCE_WARNING(msg)
#define LOCAL_RENDER_WARNING(msg)

namespace gpu {
namespace raster {

namespace {

base::AtomicSequenceNumber g_raster_decoder_id;

// Controls whether we may yield during rasterization.
BASE_FEATURE();

// Controls how many ops are rastered before checking if we should yield.
const base::FeatureParam<int> kGpuYieldRasterizationOpCount(
    &kGpuYieldRasterization,
    "gpu_yield_rasterization_op_count",
    500);

// This class prevents any GL errors that occur when it is in scope from
// being reported to the client.
class ScopedGLErrorSuppressor {};

// Commands that are explicitly listed as OK to occur between
// BeginRasterCHROMIUM and EndRasterCHROMIUM. They do not invalidate
// GrDirectContext state tracking.
bool AllowedBetweenBeginEndRaster(CommandId command) {}

// This class is sent to cc::PaintOpReader during paint op deserialization. When
// a cc:PaintOp refers to a mailbox-backed cc:PaintImage, this class opens the
// shared image for read access and returns an SkImage reference.
// SharedImageProviderImpl maintains read access until it is destroyed
// which should occur after |end_semaphores| have been flushed to Skia.
class SharedImageProviderImpl final : public cc::SharedImageProvider {};

class RasterCommandsCompletedQuery : public QueryManager::Query {};

class RasterQueryManager : public QueryManager {};

SkYUVAPixmapInfo::DataType ToSkYUVADataType(viz::SharedImageFormat format) {}

}  // namespace

// RasterDecoderImpl uses two separate state trackers (gpu::gles2::ContextState
// and GrDirectContext) that cache the current GL driver state. Each class sees
// a fraction of the GL calls issued and can easily become inconsistent with GL
// state. We guard against that by resetting. But resetting is expensive, so we
// avoid it as much as possible.
class RasterDecoderImpl final : public RasterDecoder,
                                public gles2::ErrorStateClient,
                                public ServiceFontManager::Client,
                                public SharedContextState::ContextLostObserver {};

constexpr RasterDecoderImpl::CommandInfo RasterDecoderImpl::command_info[] =;

// static
RasterDecoder* RasterDecoder::Create(
    DecoderClient* client,
    CommandBufferServiceBase* command_buffer_service,
    gles2::Outputter* outputter,
    const GpuFeatureInfo& gpu_feature_info,
    const GpuPreferences& gpu_preferences,
    MemoryTracker* memory_tracker,
    SharedImageManager* shared_image_manager,
    scoped_refptr<SharedContextState> shared_context_state,
    bool is_privileged) {}

RasterDecoder::RasterDecoder(DecoderClient* client,
                             CommandBufferServiceBase* command_buffer_service,
                             gles2::Outputter* outputter)
    :{}

RasterDecoder::~RasterDecoder() {}

bool RasterDecoder::initialized() const {}

TextureBase* RasterDecoder::GetTextureBase(uint32_t client_id) {}

void RasterDecoder::SetLevelInfo(uint32_t client_id,
                                 int level,
                                 unsigned internal_format,
                                 unsigned width,
                                 unsigned height,
                                 unsigned depth,
                                 unsigned format,
                                 unsigned type,
                                 const gfx::Rect& cleared_rect) {}

void RasterDecoder::BeginDecoding() {}

void RasterDecoder::EndDecoding() {}

void RasterDecoder::SetLogCommands(bool log_commands) {}

gles2::Outputter* RasterDecoder::outputter() const {}

std::string_view RasterDecoder::GetLogPrefix() {}

RasterDecoderImpl::RasterDecoderImpl(
    DecoderClient* client,
    CommandBufferServiceBase* command_buffer_service,
    gles2::Outputter* outputter,
    const GpuFeatureInfo& gpu_feature_info,
    const GpuPreferences& gpu_preferences,
    MemoryTracker* memory_tracker,
    SharedImageManager* shared_image_manager,
    scoped_refptr<SharedContextState> shared_context_state,
    bool is_privileged)
    :{}

RasterDecoderImpl::~RasterDecoderImpl() {}

base::WeakPtr<DecoderContext> RasterDecoderImpl::AsWeakPtr() {}

ContextResult RasterDecoderImpl::Initialize(
    const scoped_refptr<gl::GLSurface>& surface,
    const scoped_refptr<gl::GLContext>& context,
    bool offscreen,
    const gles2::DisallowedFeatures& disallowed_features,
    const ContextCreationAttribs& attrib_helper) {}

void RasterDecoderImpl::Destroy(bool have_context) {}

// Make this decoder's GL context current.
bool RasterDecoderImpl::MakeCurrent() {}

gl::GLContext* RasterDecoderImpl::GetGLContext() {}

gl::GLSurface* RasterDecoderImpl::GetGLSurface() {}

Capabilities RasterDecoderImpl::GetCapabilities() {}

GLCapabilities RasterDecoderImpl::GetGLCapabilities() {}

const gles2::ContextState* RasterDecoderImpl::GetContextState() {}

void RasterDecoderImpl::RestoreGlobalState() const {}

void RasterDecoderImpl::ClearAllAttributes() const {}

void RasterDecoderImpl::RestoreAllAttributes() const {}

void RasterDecoderImpl::RestoreState(const gles2::ContextState* prev_state) {}

void RasterDecoderImpl::RestoreActiveTexture() const {}

void RasterDecoderImpl::RestoreAllTextureUnitAndSamplerBindings(
    const gles2::ContextState* prev_state) const {}

void RasterDecoderImpl::RestoreActiveTextureUnitBinding(
    unsigned int target) const {}

void RasterDecoderImpl::RestoreBufferBinding(unsigned int target) {}

void RasterDecoderImpl::RestoreBufferBindings() const {}

void RasterDecoderImpl::RestoreFramebufferBindings() const {}

void RasterDecoderImpl::RestoreRenderbufferBindings() {}

void RasterDecoderImpl::RestoreProgramBindings() const {}

void RasterDecoderImpl::RestoreTextureState(unsigned service_id) {}

void RasterDecoderImpl::RestoreTextureUnitBindings(unsigned unit) const {}

void RasterDecoderImpl::RestoreVertexAttribArray(unsigned index) {}

void RasterDecoderImpl::RestoreAllExternalTextureBindingsIfNeeded() {}

QueryManager* RasterDecoderImpl::GetQueryManager() {}

void RasterDecoderImpl::SetQueryCallback(unsigned int query_client_id,
                                         base::OnceClosure callback) {}

void RasterDecoderImpl::CancelAllQueries() {}

gles2::GpuFenceManager* RasterDecoderImpl::GetGpuFenceManager() {}

bool RasterDecoderImpl::HasPendingQueries() const {}

void RasterDecoderImpl::ProcessPendingQueries(bool did_finish) {}

bool RasterDecoderImpl::HasMoreIdleWork() const {}

void RasterDecoderImpl::PerformIdleWork() {}

bool RasterDecoderImpl::HasPollingWork() const {}

void RasterDecoderImpl::PerformPollingWork() {}

TextureBase* RasterDecoderImpl::GetTextureBase(uint32_t client_id) {}

void RasterDecoderImpl::SetLevelInfo(uint32_t client_id,
                                     int level,
                                     unsigned internal_format,
                                     unsigned width,
                                     unsigned height,
                                     unsigned depth,
                                     unsigned format,
                                     unsigned type,
                                     const gfx::Rect& cleared_rect) {}

bool RasterDecoderImpl::WasContextLost() const {}

bool RasterDecoderImpl::WasContextLostByRobustnessExtension() const {}

void RasterDecoderImpl::MarkContextLost(error::ContextLostReason reason) {}

void RasterDecoderImpl::OnContextLost() {}

bool RasterDecoderImpl::CheckResetStatus() {}

gles2::Logger* RasterDecoderImpl::GetLogger() {}

void RasterDecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {}

void RasterDecoderImpl::BeginDecoding() {}

void RasterDecoderImpl::EndDecoding() {}

const char* RasterDecoderImpl::GetCommandName(unsigned int command_id) const {}

template <bool DebugImpl>
error::Error RasterDecoderImpl::DoCommandsImpl(unsigned int num_commands,
                                               const volatile void* buffer,
                                               int num_entries,
                                               int* entries_processed) {}

error::Error RasterDecoderImpl::DoCommands(unsigned int num_commands,
                                           const volatile void* buffer,
                                           int num_entries,
                                           int* entries_processed) {}

void RasterDecoderImpl::ExitCommandProcessingEarly() {}

std::string_view RasterDecoderImpl::GetLogPrefix() {}

gles2::ContextGroup* RasterDecoderImpl::GetContextGroup() {}

gles2::ErrorState* RasterDecoderImpl::GetErrorState() {}

bool RasterDecoderImpl::IsCompressedTextureFormat(unsigned format) {}

bool RasterDecoderImpl::ClearLevel(gles2::Texture* texture,
                                   unsigned target,
                                   int level,
                                   unsigned format,
                                   unsigned type,
                                   int xoffset,
                                   int yoffset,
                                   int width,
                                   int height) {}

bool RasterDecoderImpl::ClearCompressedTextureLevel(gles2::Texture* texture,
                                                    unsigned target,
                                                    int level,
                                                    unsigned format,
                                                    int width,
                                                    int height) {}

bool RasterDecoderImpl::ClearCompressedTextureLevel3D(gles2::Texture* texture,
                                                      unsigned target,
                                                      int level,
                                                      unsigned format,
                                                      int width,
                                                      int height,
                                                      int depth) {}

int RasterDecoderImpl::GetRasterDecoderId() const {}

int RasterDecoderImpl::DecoderIdForTest() {}

ServiceTransferCache* RasterDecoderImpl::GetTransferCacheForTest() {}

void RasterDecoderImpl::SetUpForRasterCHROMIUMForTest() {}

void RasterDecoderImpl::SetOOMErrorForTest() {}

void RasterDecoderImpl::DisableFlushWorkaroundForTest() {}

void RasterDecoderImpl::OnContextLostError() {}

void RasterDecoderImpl::OnOutOfMemoryError() {}

error::Error RasterDecoderImpl::HandleBeginQueryEXT(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

error::Error RasterDecoderImpl::HandleEndQueryEXT(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

error::Error RasterDecoderImpl::HandleQueryCounterEXT(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

void RasterDecoderImpl::DoFinish() {}

void RasterDecoderImpl::DoFlush() {}

bool RasterDecoderImpl::GenQueriesEXTHelper(GLsizei n,
                                            const GLuint* client_ids) {}

void RasterDecoderImpl::DeleteQueriesEXTHelper(
    GLsizei n,
    const volatile GLuint* client_ids) {}

error::Error RasterDecoderImpl::HandleTraceBeginCHROMIUM(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

void RasterDecoderImpl::DoTraceEndCHROMIUM() {}

error::Error RasterDecoderImpl::HandleSetActiveURLCHROMIUM(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

void RasterDecoderImpl::DoCopySharedImageINTERNAL(
    GLint xoffset,
    GLint yoffset,
    GLint x,
    GLint y,
    GLsizei width,
    GLsizei height,
    GLboolean unpack_flip_y,
    const volatile GLbyte* mailboxes) {}

void RasterDecoderImpl::DoWritePixelsINTERNAL(GLint x_offset,
                                              GLint y_offset,
                                              GLuint src_width,
                                              GLuint src_height,
                                              GLuint row_bytes,
                                              GLuint src_sk_color_type,
                                              GLuint src_sk_alpha_type,
                                              GLint shm_id,
                                              GLuint shm_offset,
                                              GLuint pixels_offset,
                                              const volatile GLbyte* mailbox) {}

void RasterDecoderImpl::DoWritePixelsYUVINTERNAL(
    GLuint src_width,
    GLuint src_height,
    GLuint src_row_bytes_plane1,
    GLuint src_row_bytes_plane2,
    GLuint src_row_bytes_plane3,
    GLuint src_row_bytes_plane4,
    GLuint src_yuv_plane_config,
    GLuint src_yuv_subsampling,
    GLuint src_yuv_datatype,
    GLint shm_id,
    GLuint shm_offset,
    GLuint plane2_offset,
    GLuint plane3_offset,
    GLuint plane4_offset,
    const volatile GLbyte* mailbox) {}

bool RasterDecoderImpl::DoWritePixelsINTERNALDirectTextureUpload(
    SkiaImageRepresentation* dest_shared_image,
    const SkImageInfo& src_info,
    const void* pixel_data,
    size_t row_bytes) {}

void RasterDecoderImpl::DoReadbackARGBImagePixelsINTERNAL(
    GLint src_x,
    GLint src_y,
    GLint plane_index,
    GLuint dst_width,
    GLuint dst_height,
    GLuint row_bytes,
    GLuint dst_sk_color_type,
    GLuint dst_sk_alpha_type,
    GLint shm_id,
    GLuint shm_offset,
    GLuint color_space_offset,
    GLuint pixels_offset,
    const volatile GLbyte* mailbox) {}

namespace {
struct YUVReadbackResult {};

void OnReadYUVImagePixelsDone(
    void* raw_ctx,
    std::unique_ptr<const SkImage::AsyncReadResult> async_result) {}
}  // namespace

void RasterDecoderImpl::DoReadbackYUVImagePixelsINTERNAL(
    GLuint dst_width,
    GLuint dst_height,
    GLint shm_id,
    GLuint shm_offset,
    GLuint y_offset,
    GLuint y_stride,
    GLuint u_offset,
    GLuint u_stride,
    GLuint v_offset,
    GLuint v_stride,
    const volatile GLbyte* mailbox) {}

void RasterDecoderImpl::DoConvertYUVAMailboxesToRGBINTERNAL(
    GLint src_x,
    GLint src_y,
    GLsizei width,
    GLsizei height,
    GLenum planes_yuv_color_space,
    GLenum plane_config,
    GLenum subsampling,
    const volatile GLbyte* bytes_in) {}

void RasterDecoderImpl::DoConvertRGBAToYUVAMailboxesINTERNAL(
    GLenum yuv_color_space,
    GLenum plane_config,
    GLenum subsampling,
    const volatile GLbyte* mailboxes_in) {}

void RasterDecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {}

namespace {

// Helper to read client data from transfer cache.
class TransferCacheDeserializeHelperImpl final
    : public cc::TransferCacheDeserializeHelper {};

}  // namespace

void RasterDecoderImpl::DeletePaintCachePathsINTERNALHelper(
    GLsizei n,
    const volatile GLuint* paint_cache_ids) {}

void RasterDecoderImpl::DoClearPaintCacheINTERNAL() {}

void RasterDecoderImpl::DoBeginRasterCHROMIUM(GLfloat r,
                                              GLfloat g,
                                              GLfloat b,
                                              GLfloat a,
                                              GLboolean needs_clear,
                                              GLuint msaa_sample_count,
                                              MsaaMode msaa_mode,
                                              GLboolean can_use_lcd_text,
                                              GLboolean visible,
                                              GLfloat hdr_headroom,
                                              const volatile GLbyte* key) {}

scoped_refptr<Buffer> RasterDecoderImpl::GetShmBuffer(uint32_t shm_id) {}

void RasterDecoderImpl::ReportProgress() {}

error::Error RasterDecoderImpl::DoRasterCHROMIUM(GLuint raster_shm_id,
                                                 GLuint raster_shm_offset,
                                                 GLuint raster_shm_size,
                                                 GLuint font_shm_id,
                                                 GLuint font_shm_offset,
                                                 GLuint font_shm_size) {}

error::Error RasterDecoderImpl::HandleRasterCHROMIUM(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {}

void RasterDecoderImpl::DoEndRasterCHROMIUM() {}

void RasterDecoderImpl::DoCreateTransferCacheEntryINTERNAL(
    GLuint raw_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 RasterDecoderImpl::DoUnlockTransferCacheEntryINTERNAL(
    GLuint raw_entry_type,
    GLuint entry_id) {}

void RasterDecoderImpl::DoDeleteTransferCacheEntryINTERNAL(
    GLuint raw_entry_type,
    GLuint entry_id) {}

void RasterDecoderImpl::RestoreStateForAttrib(GLuint attrib_index,
                                              bool restore_array_binding) {}

// 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 "build/chromeos_buildflags.h"
#include "gpu/command_buffer/service/raster_decoder_autogen.h"

}  // namespace raster
}  // namespace gpu