#ifdef UNSAFE_BUFFERS_BUILD
#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
#if BUILDFLAG(IS_WIN)
#include "gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h"
#endif
#if BUILDFLAG(SKIA_USE_DAWN)
#include <dawn/webgpu_cpp.h>
#include "gpu/command_buffer/service/dawn_context_provider.h"
#endif
#if BUILDFLAG(SKIA_USE_DAWN) && BUILDFLAG(IS_CHROMEOS_ASH)
#include "gpu/command_buffer/service/drm_modifiers_filter_dawn.h"
#endif
#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;
BASE_FEATURE(…);
const base::FeatureParam<int> kGpuYieldRasterizationOpCount(
&kGpuYieldRasterization,
"gpu_yield_rasterization_op_count",
500);
class ScopedGLErrorSuppressor { … };
bool AllowedBetweenBeginEndRaster(CommandId command) { … }
class SharedImageProviderImpl final : public cc::SharedImageProvider { … };
class RasterCommandsCompletedQuery : public QueryManager::Query { … };
class RasterQueryManager : public QueryManager { … };
SkYUVAPixmapInfo::DataType ToSkYUVADataType(viz::SharedImageFormat format) { … }
}
class RasterDecoderImpl final : public RasterDecoder,
public gles2::ErrorStateClient,
public ServiceFontManager::Client,
public SharedContextState::ContextLostObserver { … };
constexpr RasterDecoderImpl::CommandInfo RasterDecoderImpl::command_info[] = …;
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) { … }
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) { … }
}
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 {
class TransferCacheDeserializeHelperImpl final
: public cc::TransferCacheDeserializeHelper { … };
}
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 "build/chromeos_buildflags.h"
#include "gpu/command_buffer/service/raster_decoder_autogen.h"
}
}