// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string_view>
#include <vector>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/command_buffer_direct.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/raster_decoder.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_manager.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_context_egl.h"
#include "ui/gl/gl_context_stub.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_stub_api.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"

#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif

namespace gpu {
namespace {

const uint32_t kCommandBufferSize = 16384;
const uint32_t kTransferBufferSize = 16384;
const uint32_t kSmallTransferBufferSize = 16;
const uint32_t kTinyTransferBufferSize = 3;

#if !defined(GPU_FUZZER_USE_ANGLE) && !defined(GPU_FUZZER_USE_SWANGLE)
#define GPU_FUZZER_USE_STUB
#endif

constexpr const char* kExtensions[] = {
    "GL_AMD_compressed_ATC_texture",
    "GL_ANGLE_client_arrays",
    "GL_ANGLE_depth_texture",
    "GL_ANGLE_framebuffer_multisample",
    "GL_ANGLE_instanced_arrays",
    "GL_ANGLE_request_extension",
    "GL_ANGLE_robust_client_memory",
    "GL_ANGLE_robust_resource_initialization",
    "GL_ANGLE_texture_compression_dxt3",
    "GL_ANGLE_texture_compression_dxt5",
    "GL_ANGLE_texture_rectangle",
    "GL_ANGLE_texture_usage",
    "GL_ANGLE_translated_shader_source",
    "GL_ANGLE_webgl_compatibility",
    "GL_APPLE_texture_format_BGRA8888",
    "GL_APPLE_vertex_array_object",
    "GL_APPLE_ycbcr_422",
    "GL_ARB_blend_func_extended",
    "GL_ARB_depth_texture",
    "GL_ARB_draw_buffers",
    "GL_ARB_draw_instanced",
    "GL_ARB_ES3_compatibility",
    "GL_ARB_explicit_attrib_location",
    "GL_ARB_explicit_uniform_location",
    "GL_ARB_framebuffer_sRGB",
    "GL_ARB_instanced_arrays",
    "GL_ARB_map_buffer_range",
    "GL_ARB_occlusion_query",
    "GL_ARB_occlusion_query2",
    "GL_ARB_pixel_buffer_object",
    "GL_ARB_program_interface_query",
    "GL_ARB_robustness",
    "GL_ARB_sampler_objects",
    "GL_ARB_shader_image_load_store",
    "GL_ARB_shading_language_420pack",
    "GL_ARB_texture_float",
    "GL_ARB_texture_gather",
    "GL_ARB_texture_non_power_of_two",
    "GL_ARB_texture_rectangle",
    "GL_ARB_texture_rg",
    "GL_ARB_texture_storage",
    "GL_ARB_timer_query",
    "GL_ARB_vertex_array_object",
    "GL_ATI_texture_compression_atitc",
    "GL_CHROMIUM_bind_generates_resource",
    "GL_CHROMIUM_color_buffer_float_rgb",
    "GL_CHROMIUM_color_buffer_float_rgba",
    "GL_CHROMIUM_copy_compressed_texture",
    "GL_CHROMIUM_copy_texture",
    "GL_EXT_blend_func_extended",
    "GL_EXT_blend_minmax",
    "GL_EXT_float_blend",
    "GL_EXT_color_buffer_float",
    "GL_EXT_color_buffer_half_float",
    "GL_EXT_debug_marker",
    "GL_EXT_direct_state_access",
    "GL_EXT_discard_framebuffer",
    "GL_EXT_disjoint_timer_query",
    "GL_EXT_draw_buffers",
    "GL_EXT_frag_depth",
    "GL_EXT_framebuffer_multisample",
    "GL_EXT_framebuffer_sRGB",
    "GL_EXT_map_buffer_range",
    "GL_EXT_multisample_compatibility",
    "GL_EXT_multisampled_render_to_texture",
    "GL_EXT_occlusion_query_boolean",
    "GL_EXT_packed_depth_stencil",
    "GL_EXT_read_format_bgra",
    "GL_EXT_robustness",
    "GL_EXT_shader_texture_lod",
    "GL_EXT_sRGB",
    "GL_EXT_sRGB_write_control",
    "GL_EXT_texture_compression_bptc",
    "GL_EXT_texture_compression_rgtc",
    "GL_EXT_texture_compression_dxt1",
    "GL_EXT_texture_compression_s3tc",
    "GL_EXT_texture_compression_s3tc_srgb",
    "GL_EXT_texture_filter_anisotropic",
    "GL_EXT_texture_format_BGRA8888",
    "GL_EXT_texture_norm16",
    "GL_EXT_texture_rg",
    "GL_EXT_texture_sRGB",
    "GL_EXT_texture_sRGB_decode",
    "GL_EXT_texture_storage",
    "GL_EXT_timer_query",
    "GL_IMG_multisampled_render_to_texture",
    "GL_IMG_texture_compression_pvrtc",
    "GL_INTEL_framebuffer_CMAA",
    "GL_KHR_blend_equation_advanced",
    "GL_KHR_blend_equation_advanced_coherent",
    "GL_KHR_debug",
    "GL_KHR_robustness",
    "GL_KHR_texture_compression_astc_ldr",
    "GL_NV_blend_equation_advanced",
    "GL_NV_blend_equation_advanced_coherent",
    "GL_NV_draw_buffers",
    "GL_NV_EGL_stream_consumer_external",
    "GL_NV_fence",
    "GL_NV_framebuffer_mixed_samples",
    "GL_NV_path_rendering",
    "GL_NV_pixel_buffer_object",
    "GL_NV_sRGB_formats",
    "GL_OES_compressed_ETC1_RGB8_texture",
    "GL_OES_depth24",
    "GL_OES_depth_texture",
    "GL_OES_draw_buffers_indexed",
    "GL_OES_EGL_image_external",
    "GL_OES_element_index_uint",
    "GL_OES_fbo_render_mipmap",
    "GL_OES_packed_depth_stencil",
    "GL_OES_rgb8_rgba8",
    "GL_OES_standard_derivatives",
    "GL_OES_texture_float",
    "GL_OES_texture_float_linear",
    "GL_OES_texture_half_float",
    "GL_OES_texture_half_float_linear",
    "GL_OES_texture_npot",
    "GL_OES_vertex_array_object"};
constexpr size_t kExtensionCount = std::size(kExtensions);

#if defined(GPU_FUZZER_USE_STUB)
constexpr const char* kDriverVersions[] = {"OpenGL ES 2.0", "OpenGL ES 3.1",
                                           "2.0", "4.5.0"};
#endif

class BitIterator {
 public:
  BitIterator(const uint8_t* data, size_t size) : data_(data), size_(size) {}

  bool GetBit() {
    if (offset_ == size_)
      return false;
    bool value = !!(data_[offset_] & (1u << bit_));
    if (++bit_ == 8) {
      bit_ = 0;
      ++offset_;
    }
    return value;
  }

  void Advance(size_t bits) {
    bit_ += bits;
    offset_ += bit_ / 8;
    if (offset_ >= size_) {
      offset_ = size_;
      bit_ = 0;
    } else {
      bit_ = bit_ % 8;
    }
  }

  size_t consumed_bytes() const { return offset_ + (bit_ + 7) / 8; }

 private:
  const uint8_t* data_;
  size_t size_;
  size_t offset_ = 0;
  size_t bit_ = 0;
};

struct Config {
  size_t MakeFromBits(const uint8_t* bits, size_t size) {
    BitIterator it(bits, size);
    [[maybe_unused]] bool es3 = it.GetBit();
#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    context_type = CONTEXT_TYPE_OPENGLES2;
#else
    bool es31 = it.GetBit();
    if (es3) {
      context_type =
          es31 ? CONTEXT_TYPE_OPENGLES31_FOR_TESTING : CONTEXT_TYPE_OPENGLES3;
    } else {
      context_type = CONTEXT_TYPE_OPENGLES2;
    }
#endif
    enable_gpu_rasterization = it.GetBit();

#if defined(GPU_FUZZER_USE_STUB)
    std::vector<std::string_view> enabled_extensions;
    enabled_extensions.reserve(kExtensionCount);
    for (const char* extension : kExtensions) {
      if (it.GetBit())
        enabled_extensions.push_back(extension);
    }
    extensions = base::JoinString(enabled_extensions, " ");

    bool desktop_driver = it.GetBit();
    size_t version_index = (desktop_driver ? 2 : 0) + (es3 ? 1 : 0);
    version = kDriverVersions[version_index];
#else
    // We consume bits even if we don't use them, so that the same inputs can be
    // used for every fuzzer variation
    it.Advance(kExtensionCount + 1);
#endif

#define GPU_OP(type, name) workarounds.name = it.GetBit();
    GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP)
#undef GPU_OP

#if defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER) && \
    !defined(GPU_FUZZER_USE_RASTER_DECODER)
    gl_context_attribs.webgl_compatibility_context =
        IsWebGLContextType(context_type);
    gl_context_attribs.global_texture_share_group = true;
    gl_context_attribs.robust_resource_initialization = true;
    gl_context_attribs.robust_buffer_access = true;
    gl_context_attribs.allow_client_arrays = false;
    gl_context_attribs.client_major_es_version =
        IsWebGL2OrES3OrHigherContextType(context_type) ? 3 : 2;
    gl_context_attribs.client_minor_es_version =
        IsES31ForTestingContextType(context_type) ? 1 : 0;
#endif

    return it.consumed_bytes();
  }

  ContextType context_type = CONTEXT_TYPE_OPENGLES2;
  bool enable_gpu_rasterization = false;
  GpuDriverBugWorkarounds workarounds;
  gl::GLContextAttribs gl_context_attribs;
#if defined(GPU_FUZZER_USE_STUB)
  const char* version;
  std::string extensions;
#endif
};

GpuPreferences GetGpuPreferences() {
  GpuPreferences preferences;
#if defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER)
  preferences.use_passthrough_cmd_decoder = true;
#endif
  return preferences;
}

class CommandBufferSetup {
 public:
  CommandBufferSetup()
      : at_exit_manager_(),
        gpu_preferences_(GetGpuPreferences()),
        share_group_(new gl::GLShareGroup),
        translator_cache_(gpu_preferences_) {
    logging::SetMinLogLevel(logging::LOGGING_FATAL);
    CHECK(base::i18n::InitializeICU());
    base::CommandLine::Init(0, nullptr);

    [[maybe_unused]] auto* command_line =
        base::CommandLine::ForCurrentProcess();

#if BUILDFLAG(IS_OZONE)
    ui::OzonePlatform::InitializeForGPU(ui::OzonePlatform::InitParams());
#endif

#if defined(GPU_FUZZER_USE_ANGLE)
    command_line->AppendSwitchASCII(switches::kUseGL,
                                    gl::kGLImplementationANGLEName);
#if defined(GPU_FUZZER_USE_SWANGLE)
    command_line->AppendSwitchASCII(switches::kUseANGLE,
                                    gl::kANGLEImplementationSwiftShaderName);
#else
    command_line->AppendSwitchASCII(switches::kUseANGLE,
                                    gl::kANGLEImplementationNullName);
#endif

    CHECK(gl::init::InitializeStaticGLBindingsImplementation(
        gl::GLImplementationParts(gl::kGLImplementationEGLANGLE)));
    display_ = gl::init::InitializeGLOneOffPlatformImplementation(
        /*disable_gl_drawing=*/false,
        /*init_extensions=*/true,
        /*gpu_preference=*/gl::GpuPreference::kDefault);
    CHECK(display_);
#elif defined(GPU_FUZZER_USE_STUB)
    gl::GLSurfaceTestSupport::InitializeOneOffWithStubBindings();
    // Because the context depends on configuration bits, we want to recreate
    // it every time.
    recreate_context_ = true;
#else
#error invalid configuration
#endif
    if (gpu_preferences_.use_passthrough_cmd_decoder)
      recreate_context_ = true;

    if (!recreate_context_) {
      InitContext();
    }
  }

  ~CommandBufferSetup() {
    if (display_) {
      gl::init::ShutdownGL(display_, false);
      display_ = nullptr;
    }
  }

  bool InitDecoder() {
    if (!context_) {
      InitContext();
    }

    context_->MakeCurrentDefault();
    GpuFeatureInfo gpu_feature_info;
#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_TILE_RASTERIZATION] =
        kGpuFeatureStatusEnabled;
#endif
    auto feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
        config_.workarounds, gpu_feature_info);
    command_buffer_.reset(new CommandBufferDirect());

    if (gpu_preferences_.use_passthrough_cmd_decoder) {
      // Virtualized contexts don't work with passthrough command decoder.
      // See https://crbug.com/914976
      config_.workarounds.use_virtualized_gl_contexts = false;
    }
    scoped_refptr<gl::GLContext> shared_context;
    if (config_.workarounds.use_virtualized_gl_contexts) {
      shared_context = context_;
    } else {
      shared_context = CreateContext();
    }
    shared_context->MakeCurrentDefault();
    context_state_ = base::MakeRefCounted<SharedContextState>(
        share_group_, shared_context->default_surface(),
        std::move(shared_context),
        config_.workarounds.use_virtualized_gl_contexts, base::DoNothing(),
        gpu_preferences_.gr_context_type);
    context_state_->InitializeSkia(gpu_preferences_, config_.workarounds);
    context_state_->InitializeGL(gpu_preferences_, feature_info);

    shared_image_manager_ = std::make_unique<SharedImageManager>();
    shared_image_factory_ = std::make_unique<SharedImageFactory>(
        gpu_preferences_, config_.workarounds, gpu_feature_info,
        context_state_.get(), shared_image_manager_.get(),
        /*memory_tracker=*/nullptr,
        /*is_for_display_compositor=*/false);
    for (uint32_t usage = SHARED_IMAGE_USAGE_GLES2_READ;
         usage <= LAST_CLIENT_USAGE; usage <<= 1) {
      Mailbox::Name name;
      memset(name, 0, sizeof(name));
      name[0] = usage;

      // Mark this as a SharedImage mailbox.
      constexpr size_t kSharedImageFlagIndex = GL_MAILBOX_SIZE_CHROMIUM - 1;
      constexpr int8_t kSharedImageFlag = 0x1;
      name[kSharedImageFlagIndex] |= kSharedImageFlag;

      Mailbox mailbox;
      mailbox.SetName(name);
      viz::SharedImageFormat si_format = viz::SinglePlaneFormat::kRGBA_8888;

      shared_image_factory_->CreateSharedImage(
          mailbox, si_format, gfx::Size(256, 256),
          gfx::ColorSpace::CreateSRGB(), kTopLeft_GrSurfaceOrigin,
          kPremul_SkAlphaType, gpu::kNullSurfaceHandle,
          SharedImageUsageSet(usage), "TestLabel");
    }

#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    context_state_->MakeCurrent(nullptr);
    decoder_ = raster::RasterDecoder::Create(
        command_buffer_.get(), command_buffer_->service(), &outputter_,
        gpu_feature_info, gpu_preferences_, /*memory_tracker=*/nullptr,
        shared_image_manager_.get(), context_state_, /*is_privileged=*/true);
    decoder_->GetLogger()->set_log_synthesized_gl_errors(false);

    auto result =
        decoder_->Initialize(config_.enable_gpu_rasterization,
                             /*lose_context_when_out_of_memory=*/false);
    if (result != gpu::ContextResult::kSuccess) {
      return false;
    }
#else
    context_->MakeCurrentDefault();
    // GLES2Decoder may Initialize feature_info differently than
    // SharedContextState and should have its own.
    auto decoder_feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
        config_.workarounds, gpu_feature_info);
    scoped_refptr<gles2::ContextGroup> context_group =
        MakeRefCounted<gles2::ContextGroup>(
            gpu_preferences_, /*memory_tracker=*/nullptr, &translator_cache_,
            &completeness_cache_, decoder_feature_info,
            /*progress_reporter=*/nullptr, gpu_feature_info,
            shared_image_manager_.get());
    auto* context = context_.get();
    decoder_ = gles2::GLES2Decoder::Create(command_buffer_.get(),
                                           command_buffer_->service(),
                                           &outputter_, context_group.get());
    decoder_->GetLogger()->set_log_synthesized_gl_errors(false);

    auto result =
        decoder_->Initialize(context->default_surface(), context,
                             /*offscreen=*/true, config_.context_type,
                             /*lose_context_when_out_of_memory=*/false);
    if (result != gpu::ContextResult::kSuccess) {
      return false;
    }
#endif

    decoder_initialized_ = true;

    command_buffer_->set_handler(decoder_.get());
    InitializeInitialCommandBuffer();

    decoder_->set_max_bucket_size(8 << 20);
#if !defined(GPU_FUZZER_USE_RASTER_DECODER)
    if (context_group->buffer_manager()) {
        context_group->buffer_manager()->set_max_buffer_size(8 << 20);
    }
#endif
    return decoder_->MakeCurrent();
  }

  void ResetDecoder() {
    bool context_lost = false;
    if (decoder_) {
#if !defined(GPU_FUZZER_USE_RASTER_DECODER)
      // Keep a reference to the translators, which keeps them in the cache even
      // after the decoder is reset. They are expensive to initialize, but they
      // don't keep state.
      scoped_refptr<gles2::ShaderTranslatorInterface> translator =
          decoder_->GetTranslator(GL_VERTEX_SHADER);
      if (translator)
        translator->AddRef();
      translator = decoder_->GetTranslator(GL_FRAGMENT_SHADER);
      if (translator)
        translator->AddRef();
#endif
      context_lost = decoder_->WasContextLost();
      // Only safe to call CheckResetStatus if !WasContextLost.
      if (!context_lost)
        context_lost = decoder_initialized_ && decoder_->CheckResetStatus();

      // If |decoder_->Initialize(...)| was unsuccessful, |decoder_| would have
      // already called Destroy.
      if (decoder_initialized_)
        decoder_->Destroy(!context_lost);
      decoder_.reset();

      if (!context_lost)
        context_lost = !context_state_->MakeCurrent(nullptr);
      shared_image_factory_->DestroyAllSharedImages(!context_lost);

      shared_image_factory_.reset();
      shared_image_manager_.reset();
      context_state_->MakeCurrent(nullptr);
      context_state_.reset();
    }

    if (context_) {
      if (recreate_context_ || context_lost) {
        context_->ReleaseCurrent(nullptr);
        context_ = nullptr;
      }
    }

    command_buffer_.reset();
    decoder_initialized_ = false;
  }

  void RunCommandBuffer(const uint8_t* data, size_t size) {
    size_t consumed = config_.MakeFromBits(data, size);
    consumed = (consumed + 3) & ~3;
    if (consumed > size)
      return;
    data += consumed;
    size -= consumed;
    // The commands are flushed at a uint32_t granularity. If the data is not
    // a full command, we zero-pad it.
    size_t padded_size = (size + 3) & ~3;
    // crbug.com/638836 The -max_len argument is sometimes not respected, so the
    // fuzzer may give us too much data. Bail ASAP in that case.
    if (padded_size > kCommandBufferSize)
      return;

    if (!InitDecoder()) {
      ResetDecoder();
      return;
    }

    uint32_t buffer_size = buffer_->size();
    CHECK_LE(padded_size, buffer_size);
    command_buffer_->SetGetBuffer(buffer_id_);
    auto* memory = static_cast<char*>(buffer_->memory());
    memcpy(memory, data, size);
    if (size < buffer_size)
      memset(memory + size, 0, buffer_size - size);
    command_buffer_->Flush(padded_size / 4);
    ResetDecoder();
  }

 private:
  void CreateTransferBuffer(uint32_t size, int32_t id) {
    scoped_refptr<Buffer> buffer =
        command_buffer_->CreateTransferBufferWithId(size, id);
    memset(buffer->memory(), 0, size);
  }

  void InitializeInitialCommandBuffer() {
    buffer_id_ = 1;
    buffer_ = command_buffer_->CreateTransferBufferWithId(kCommandBufferSize,
                                                          buffer_id_);
    CHECK(buffer_);
    // Create some transfer buffers. This is somewhat arbitrary, but having a
    // reasonably sized buffer in slot 4 allows us to prime the corpus with data
    // extracted from unit tests.
    CreateTransferBuffer(kTransferBufferSize, 2);
    CreateTransferBuffer(kSmallTransferBufferSize, 3);
    CreateTransferBuffer(kTransferBufferSize, 4);
    CreateTransferBuffer(kTinyTransferBufferSize, 5);
  }

  scoped_refptr<gl::GLContext> CreateContext() {
    // The surface will be owned by the |context|.
    auto surface = gl::init::CreateOffscreenGLSurface(display_, gfx::Size());
#if defined(GPU_FUZZER_USE_STUB)
    auto stub = base::MakeRefCounted<gl::GLContextStub>(share_group_.get());
    stub->SetGLVersionString(config_.version);
    stub->SetExtensionsString(config_.extensions.c_str());
    stub->SetUseStubApi(true);
    // The stub ctx needs to be initialized so that the gl::GLContext can
    // store the |compatible_surface|.
    stub->Initialize(surface.get(), {});
    return stub;
#else
    auto context = base::MakeRefCounted<gl::GLContextEGL>(share_group_.get());
    context->Initialize(surface.get(), config_.gl_context_attribs);
    return context;
#endif
  }

  void InitContext() {
    context_ = CreateContext();

// When not using the passthrough decoder, ANGLE should not be generating
// errors (the decoder should prevent those from happening). We register a
// callback to catch them if it does.
#if defined(GPU_FUZZER_USE_ANGLE) && \
    !defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER)
    context_->MakeCurrentDefault();
    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr,
                          GL_FALSE);
    glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
                          GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);

    glDebugMessageCallback(&LogGLDebugMessage, nullptr);
#endif
  }

  static void GL_APIENTRY LogGLDebugMessage(GLenum source,
                                            GLenum type,
                                            GLuint id,
                                            GLenum severity,
                                            GLsizei length,
                                            const GLchar* message,
                                            const GLvoid* user_param) {
    LOG_IF(FATAL, (id != GL_OUT_OF_MEMORY)) << "GL Driver Message: " << message;
  }

  base::AtExitManager at_exit_manager_;

  GpuPreferences gpu_preferences_;

  Config config_;

  gles2::TraceOutputter outputter_;
  scoped_refptr<gl::GLShareGroup> share_group_;
  std::unique_ptr<SharedImageManager> shared_image_manager_;
  std::unique_ptr<SharedImageFactory> shared_image_factory_;

  bool recreate_context_ = false;
  raw_ptr<gl::GLDisplay> display_ = nullptr;
  scoped_refptr<gl::GLContext> context_;
  scoped_refptr<SharedContextState> context_state_;

  gles2::ShaderTranslatorCache translator_cache_;
  gles2::FramebufferCompletenessCache completeness_cache_;

  std::unique_ptr<CommandBufferDirect> command_buffer_;

#if defined(GPU_FUZZER_USE_RASTER_DECODER)
  std::unique_ptr<raster::RasterDecoder> decoder_;
#else
  std::unique_ptr<gles2::GLES2Decoder> decoder_;
#endif

  scoped_refptr<Buffer> buffer_;
  int32_t buffer_id_ = 0;

  bool decoder_initialized_ = false;
};

// Intentionally leaked because asan tries to exit cleanly after a crash, but
// the decoder is usually in a bad state at that point.
// We need to load ANGLE libraries before the fuzzer infrastructure starts,
// because it gets confused about new coverage counters being dynamically
// registered, causing crashes.
CommandBufferSetup* g_setup = new CommandBufferSetup();

}  // anonymous namespace
}  // namespace gpu

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  gpu::g_setup->RunCommandBuffer(data, size);
  return 0;
}
