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

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

#include <memory>
#include <vector>

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.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/image_manager.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/passthrough_discardable_manager.h"
#include "gpu/command_buffer/service/raster_decoder.h"
#include "gpu/command_buffer/service/service_discardable_manager.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/command_buffer/service/shared_image_manager.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.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_image_ref_counted_memory.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/init/gl_factory.h"
#include "ui/gl/test/gl_surface_test_support.h"

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_SWIFTSHADER)
#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_CHROMIUM_texture_filtering_hint",
    "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_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_EGL_image_external",
    "GL_OES_element_index_uint",
    "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 = base::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);
    attrib_helper.red_size = 8;
    attrib_helper.green_size = 8;
    attrib_helper.blue_size = 8;
    attrib_helper.alpha_size = it.GetBit() ? 8 : 0;
    attrib_helper.depth_size = it.GetBit() ? 24 : 0;
    attrib_helper.stencil_size = it.GetBit() ? 8 : 0;
    attrib_helper.buffer_preserved = it.GetBit();
    attrib_helper.bind_generates_resource = it.GetBit();
    attrib_helper.single_buffer = it.GetBit();
    bool es3 = it.GetBit();
#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    ALLOW_UNUSED_LOCAL(es3);
    attrib_helper.context_type = CONTEXT_TYPE_OPENGLES2;
#else
    attrib_helper.context_type =
        es3 ? CONTEXT_TYPE_OPENGLES3 : CONTEXT_TYPE_OPENGLES2;
#endif
    attrib_helper.enable_oop_rasterization = it.GetBit();

#if defined(GPU_FUZZER_USE_STUB)
    std::vector<base::StringPiece> 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.bind_generates_resource =
        attrib_helper.bind_generates_resource;
    gl_context_attribs.webgl_compatibility_context =
        IsWebGLContextType(attrib_helper.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.client_major_es_version =
        IsWebGL2OrES3ContextType(attrib_helper.context_type) ? 3 : 2;
    gl_context_attribs.client_minor_es_version = 0;
#endif

    return it.consumed_bytes();
  }

  GpuDriverBugWorkarounds workarounds;
  ContextCreationAttribs attrib_helper;
  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::LOG_FATAL);
    CHECK(base::i18n::InitializeICU());
    base::CommandLine::Init(0, nullptr);

    auto* command_line = base::CommandLine::ForCurrentProcess();
    ALLOW_UNUSED_LOCAL(command_line);

#if defined(GPU_FUZZER_USE_ANGLE)
    command_line->AppendSwitchASCII(switches::kUseGL,
                                    gl::kGLImplementationANGLEName);
    command_line->AppendSwitchASCII(switches::kUseANGLE,
                                    gl::kANGLEImplementationNullName);
    CHECK(gl::init::InitializeGLOneOffImplementation(
        gl::kGLImplementationEGLGLES2, false, false, false, true));
#elif defined(GPU_FUZZER_USE_SWIFTSHADER)
    command_line->AppendSwitchASCII(switches::kUseGL,
                                    gl::kGLImplementationSwiftShaderName);
    CHECK(gl::init::InitializeGLOneOffImplementation(
        gl::kGLImplementationSwiftShaderGL, false, false, false, true));
#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
    discardable_manager_ = std::make_unique<ServiceDiscardableManager>();
    passthrough_discardable_manager_ =
        std::make_unique<PassthroughDiscardableManager>();

    if (gpu_preferences_.use_passthrough_cmd_decoder)
      recreate_context_ = true;

    surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
    if (!recreate_context_) {
      InitContext();
    }
  }

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

    context_->MakeCurrent(surface_.get());
    GpuFeatureInfo gpu_feature_info;
#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    // Cause feature_info's |chromium_raster_transport| to be enabled.
    gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_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->MakeCurrent(surface_.get());
    context_state_ = base::MakeRefCounted<SharedContextState>(
        share_group_, surface_, std::move(shared_context),
        config_.workarounds.use_virtualized_gl_contexts, base::DoNothing());
    context_state_->InitializeGrContext(config_.workarounds, nullptr);
    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(), &mailbox_manager_, shared_image_manager_.get(),
        nullptr /* image_factory */, nullptr /* memory_tracker */,
        false /* is_using_skia_renderer */, /* use_gl */ true);
    for (uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
         usage <= SHARED_IMAGE_USAGE_RGB_EMULATION; 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);
      shared_image_factory_->CreateSharedImage(
          mailbox, viz::RGBA_8888, gfx::Size(256, 256),
          gfx::ColorSpace::CreateSRGB(), usage);
    }

#if defined(GPU_FUZZER_USE_RASTER_DECODER)
    CHECK(feature_info->feature_flags().chromium_raster_transport);
    context_state_->MakeCurrent(nullptr);
    auto* context = context_state_->context();
    decoder_.reset(raster::RasterDecoder::Create(
        command_buffer_.get(), command_buffer_->service(), &outputter_,
        gpu_feature_info, gpu_preferences_, nullptr /* memory_tracker */,
        shared_image_manager_.get(), context_state_));
#else
    context_->MakeCurrent(surface_.get());
    // 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 = new gles2::ContextGroup(
        gpu_preferences_, true, &mailbox_manager_, nullptr /* memory_tracker */,
        &translator_cache_, &completeness_cache_, decoder_feature_info,
        config_.attrib_helper.bind_generates_resource, &image_manager_,
        nullptr /* image_factory */, nullptr /* progress_reporter */,
        gpu_feature_info, discardable_manager_.get(),
        passthrough_discardable_manager_.get(), shared_image_manager_.get());
    auto* context = context_.get();
    decoder_.reset(gles2::GLES2Decoder::Create(
        command_buffer_.get(), command_buffer_->service(), &outputter_,
        context_group.get()));
#endif

    decoder_->GetLogger()->set_log_synthesized_gl_errors(false);

    auto result = decoder_->Initialize(surface_.get(), context, true,
                                       gles2::DisallowedFeatures(),
                                       config_.attrib_helper);
    if (result != gpu::ContextResult::kSuccess)
      return false;
    decoder_initialized_ = true;

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

    decoder_->set_max_bucket_size(8 << 20);
#if !defined(GPU_FUZZER_USE_RASTER_DECODER)
    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_.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() {
#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);
    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_->MakeCurrent(surface_.get());
    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 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::MailboxManagerImpl mailbox_manager_;
  gles2::TraceOutputter outputter_;
  scoped_refptr<gl::GLShareGroup> share_group_;
  gles2::ImageManager image_manager_;
  std::unique_ptr<ServiceDiscardableManager> discardable_manager_;
  std::unique_ptr<PassthroughDiscardableManager>
      passthrough_discardable_manager_;
  std::unique_ptr<SharedImageManager> shared_image_manager_;
  std::unique_ptr<SharedImageFactory> shared_image_factory_;

  bool recreate_context_ = false;
  scoped_refptr<gl::GLSurface> surface_;
  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;
}
