fuzzer_main.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <vector>
  8. #include "base/at_exit.h"
  9. #include "base/bind.h"
  10. #include "base/callback_helpers.h"
  11. #include "base/command_line.h"
  12. #include "base/i18n/icu_util.h"
  13. #include "base/logging.h"
  14. #include "base/memory/ref_counted.h"
  15. #include "base/strings/string_piece.h"
  16. #include "base/strings/string_util.h"
  17. #include "build/build_config.h"
  18. #include "gpu/command_buffer/common/constants.h"
  19. #include "gpu/command_buffer/common/context_creation_attribs.h"
  20. #include "gpu/command_buffer/common/shared_image_usage.h"
  21. #include "gpu/command_buffer/service/buffer_manager.h"
  22. #include "gpu/command_buffer/service/command_buffer_direct.h"
  23. #include "gpu/command_buffer/service/context_group.h"
  24. #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
  25. #include "gpu/command_buffer/service/gpu_switches.h"
  26. #include "gpu/command_buffer/service/gpu_tracer.h"
  27. #include "gpu/command_buffer/service/logger.h"
  28. #include "gpu/command_buffer/service/mailbox_manager_impl.h"
  29. #include "gpu/command_buffer/service/passthrough_discardable_manager.h"
  30. #include "gpu/command_buffer/service/raster_decoder.h"
  31. #include "gpu/command_buffer/service/service_discardable_manager.h"
  32. #include "gpu/command_buffer/service/shared_context_state.h"
  33. #include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
  34. #include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
  35. #include "gpu/command_buffer/service/transfer_buffer_manager.h"
  36. #include "ui/gfx/geometry/size.h"
  37. #include "ui/gl/gl_context.h"
  38. #include "ui/gl/gl_context_egl.h"
  39. #include "ui/gl/gl_context_stub.h"
  40. #include "ui/gl/gl_image_ref_counted_memory.h"
  41. #include "ui/gl/gl_share_group.h"
  42. #include "ui/gl/gl_stub_api.h"
  43. #include "ui/gl/gl_surface.h"
  44. #include "ui/gl/gl_surface_egl.h"
  45. #include "ui/gl/gl_surface_stub.h"
  46. #include "ui/gl/gl_utils.h"
  47. #include "ui/gl/init/gl_factory.h"
  48. #include "ui/gl/test/gl_surface_test_support.h"
  49. #if defined(USE_OZONE)
  50. #include "ui/ozone/public/ozone_platform.h"
  51. #endif
  52. namespace gpu {
  53. namespace {
  54. const uint32_t kCommandBufferSize = 16384;
  55. const uint32_t kTransferBufferSize = 16384;
  56. const uint32_t kSmallTransferBufferSize = 16;
  57. const uint32_t kTinyTransferBufferSize = 3;
  58. #if !defined(GPU_FUZZER_USE_ANGLE) && !defined(GPU_FUZZER_USE_SWANGLE)
  59. #define GPU_FUZZER_USE_STUB
  60. #endif
  61. constexpr const char* kExtensions[] = {
  62. "GL_AMD_compressed_ATC_texture",
  63. "GL_ANGLE_client_arrays",
  64. "GL_ANGLE_depth_texture",
  65. "GL_ANGLE_framebuffer_multisample",
  66. "GL_ANGLE_instanced_arrays",
  67. "GL_ANGLE_request_extension",
  68. "GL_ANGLE_robust_client_memory",
  69. "GL_ANGLE_robust_resource_initialization",
  70. "GL_ANGLE_texture_compression_dxt3",
  71. "GL_ANGLE_texture_compression_dxt5",
  72. "GL_ANGLE_texture_rectangle",
  73. "GL_ANGLE_texture_usage",
  74. "GL_ANGLE_translated_shader_source",
  75. "GL_ANGLE_webgl_compatibility",
  76. "GL_APPLE_texture_format_BGRA8888",
  77. "GL_APPLE_vertex_array_object",
  78. "GL_APPLE_ycbcr_422",
  79. "GL_ARB_blend_func_extended",
  80. "GL_ARB_depth_texture",
  81. "GL_ARB_draw_buffers",
  82. "GL_ARB_draw_instanced",
  83. "GL_ARB_ES3_compatibility",
  84. "GL_ARB_explicit_attrib_location",
  85. "GL_ARB_explicit_uniform_location",
  86. "GL_ARB_framebuffer_sRGB",
  87. "GL_ARB_instanced_arrays",
  88. "GL_ARB_map_buffer_range",
  89. "GL_ARB_occlusion_query",
  90. "GL_ARB_occlusion_query2",
  91. "GL_ARB_pixel_buffer_object",
  92. "GL_ARB_program_interface_query",
  93. "GL_ARB_robustness",
  94. "GL_ARB_sampler_objects",
  95. "GL_ARB_shader_image_load_store",
  96. "GL_ARB_shading_language_420pack",
  97. "GL_ARB_texture_float",
  98. "GL_ARB_texture_gather",
  99. "GL_ARB_texture_non_power_of_two",
  100. "GL_ARB_texture_rectangle",
  101. "GL_ARB_texture_rg",
  102. "GL_ARB_texture_storage",
  103. "GL_ARB_timer_query",
  104. "GL_ARB_vertex_array_object",
  105. "GL_ATI_texture_compression_atitc",
  106. "GL_CHROMIUM_bind_generates_resource",
  107. "GL_CHROMIUM_color_buffer_float_rgb",
  108. "GL_CHROMIUM_color_buffer_float_rgba",
  109. "GL_CHROMIUM_copy_compressed_texture",
  110. "GL_CHROMIUM_copy_texture",
  111. "GL_CHROMIUM_texture_filtering_hint",
  112. "GL_EXT_blend_func_extended",
  113. "GL_EXT_blend_minmax",
  114. "GL_EXT_float_blend",
  115. "GL_EXT_color_buffer_float",
  116. "GL_EXT_color_buffer_half_float",
  117. "GL_EXT_debug_marker",
  118. "GL_EXT_direct_state_access",
  119. "GL_EXT_discard_framebuffer",
  120. "GL_EXT_disjoint_timer_query",
  121. "GL_EXT_draw_buffers",
  122. "GL_EXT_frag_depth",
  123. "GL_EXT_framebuffer_multisample",
  124. "GL_EXT_framebuffer_sRGB",
  125. "GL_EXT_map_buffer_range",
  126. "GL_EXT_multisample_compatibility",
  127. "GL_EXT_multisampled_render_to_texture",
  128. "GL_EXT_occlusion_query_boolean",
  129. "GL_EXT_packed_depth_stencil",
  130. "GL_EXT_read_format_bgra",
  131. "GL_EXT_robustness",
  132. "GL_EXT_shader_texture_lod",
  133. "GL_EXT_sRGB",
  134. "GL_EXT_sRGB_write_control",
  135. "GL_EXT_texture_compression_bptc",
  136. "GL_EXT_texture_compression_rgtc",
  137. "GL_EXT_texture_compression_dxt1",
  138. "GL_EXT_texture_compression_s3tc",
  139. "GL_EXT_texture_compression_s3tc_srgb",
  140. "GL_EXT_texture_filter_anisotropic",
  141. "GL_EXT_texture_format_BGRA8888",
  142. "GL_EXT_texture_norm16",
  143. "GL_EXT_texture_rg",
  144. "GL_EXT_texture_sRGB",
  145. "GL_EXT_texture_sRGB_decode",
  146. "GL_EXT_texture_storage",
  147. "GL_EXT_timer_query",
  148. "GL_IMG_multisampled_render_to_texture",
  149. "GL_IMG_texture_compression_pvrtc",
  150. "GL_INTEL_framebuffer_CMAA",
  151. "GL_KHR_blend_equation_advanced",
  152. "GL_KHR_blend_equation_advanced_coherent",
  153. "GL_KHR_debug",
  154. "GL_KHR_robustness",
  155. "GL_KHR_texture_compression_astc_ldr",
  156. "GL_NV_blend_equation_advanced",
  157. "GL_NV_blend_equation_advanced_coherent",
  158. "GL_NV_draw_buffers",
  159. "GL_NV_EGL_stream_consumer_external",
  160. "GL_NV_fence",
  161. "GL_NV_framebuffer_mixed_samples",
  162. "GL_NV_path_rendering",
  163. "GL_NV_pixel_buffer_object",
  164. "GL_NV_sRGB_formats",
  165. "GL_OES_compressed_ETC1_RGB8_texture",
  166. "GL_OES_depth24",
  167. "GL_OES_depth_texture",
  168. "GL_OES_draw_buffers_indexed",
  169. "GL_OES_EGL_image_external",
  170. "GL_OES_element_index_uint",
  171. "GL_OES_fbo_render_mipmap",
  172. "GL_OES_packed_depth_stencil",
  173. "GL_OES_rgb8_rgba8",
  174. "GL_OES_standard_derivatives",
  175. "GL_OES_texture_float",
  176. "GL_OES_texture_float_linear",
  177. "GL_OES_texture_half_float",
  178. "GL_OES_texture_half_float_linear",
  179. "GL_OES_texture_npot",
  180. "GL_OES_vertex_array_object"};
  181. constexpr size_t kExtensionCount = std::size(kExtensions);
  182. #if defined(GPU_FUZZER_USE_STUB)
  183. constexpr const char* kDriverVersions[] = {"OpenGL ES 2.0", "OpenGL ES 3.1",
  184. "2.0", "4.5.0"};
  185. #endif
  186. class BitIterator {
  187. public:
  188. BitIterator(const uint8_t* data, size_t size) : data_(data), size_(size) {}
  189. bool GetBit() {
  190. if (offset_ == size_)
  191. return false;
  192. bool value = !!(data_[offset_] & (1u << bit_));
  193. if (++bit_ == 8) {
  194. bit_ = 0;
  195. ++offset_;
  196. }
  197. return value;
  198. }
  199. void Advance(size_t bits) {
  200. bit_ += bits;
  201. offset_ += bit_ / 8;
  202. if (offset_ >= size_) {
  203. offset_ = size_;
  204. bit_ = 0;
  205. } else {
  206. bit_ = bit_ % 8;
  207. }
  208. }
  209. size_t consumed_bytes() const { return offset_ + (bit_ + 7) / 8; }
  210. private:
  211. const uint8_t* data_;
  212. size_t size_;
  213. size_t offset_ = 0;
  214. size_t bit_ = 0;
  215. };
  216. struct Config {
  217. size_t MakeFromBits(const uint8_t* bits, size_t size) {
  218. BitIterator it(bits, size);
  219. attrib_helper.red_size = 8;
  220. attrib_helper.green_size = 8;
  221. attrib_helper.blue_size = 8;
  222. attrib_helper.alpha_size = it.GetBit() ? 8 : 0;
  223. attrib_helper.depth_size = it.GetBit() ? 24 : 0;
  224. attrib_helper.stencil_size = it.GetBit() ? 8 : 0;
  225. attrib_helper.buffer_preserved = it.GetBit();
  226. attrib_helper.bind_generates_resource = it.GetBit();
  227. attrib_helper.single_buffer = it.GetBit();
  228. [[maybe_unused]] bool es3 = it.GetBit();
  229. #if defined(GPU_FUZZER_USE_RASTER_DECODER)
  230. attrib_helper.context_type = CONTEXT_TYPE_OPENGLES2;
  231. #else
  232. bool es31 = it.GetBit();
  233. if (es3) {
  234. attrib_helper.context_type =
  235. es31 ? CONTEXT_TYPE_OPENGLES31_FOR_TESTING : CONTEXT_TYPE_OPENGLES3;
  236. } else {
  237. attrib_helper.context_type = CONTEXT_TYPE_OPENGLES2;
  238. }
  239. #endif
  240. attrib_helper.enable_oop_rasterization = it.GetBit();
  241. #if defined(GPU_FUZZER_USE_STUB)
  242. std::vector<base::StringPiece> enabled_extensions;
  243. enabled_extensions.reserve(kExtensionCount);
  244. for (const char* extension : kExtensions) {
  245. if (it.GetBit())
  246. enabled_extensions.push_back(extension);
  247. }
  248. extensions = base::JoinString(enabled_extensions, " ");
  249. bool desktop_driver = it.GetBit();
  250. size_t version_index = (desktop_driver ? 2 : 0) + (es3 ? 1 : 0);
  251. version = kDriverVersions[version_index];
  252. #else
  253. // We consume bits even if we don't use them, so that the same inputs can be
  254. // used for every fuzzer variation
  255. it.Advance(kExtensionCount + 1);
  256. #endif
  257. #define GPU_OP(type, name) workarounds.name = it.GetBit();
  258. GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP)
  259. #undef GPU_OP
  260. #if defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER) && \
  261. !defined(GPU_FUZZER_USE_RASTER_DECODER)
  262. gl_context_attribs.bind_generates_resource =
  263. attrib_helper.bind_generates_resource;
  264. gl_context_attribs.webgl_compatibility_context =
  265. IsWebGLContextType(attrib_helper.context_type);
  266. gl_context_attribs.global_texture_share_group = true;
  267. gl_context_attribs.robust_resource_initialization = true;
  268. gl_context_attribs.robust_buffer_access = true;
  269. gl_context_attribs.client_major_es_version =
  270. IsWebGL2OrES3OrHigherContextType(attrib_helper.context_type) ? 3 : 2;
  271. gl_context_attribs.client_minor_es_version =
  272. IsES31ForTestingContextType(attrib_helper.context_type) ? 1 : 0;
  273. #endif
  274. return it.consumed_bytes();
  275. }
  276. GpuDriverBugWorkarounds workarounds;
  277. ContextCreationAttribs attrib_helper;
  278. gl::GLContextAttribs gl_context_attribs;
  279. #if defined(GPU_FUZZER_USE_STUB)
  280. const char* version;
  281. std::string extensions;
  282. #endif
  283. };
  284. GpuPreferences GetGpuPreferences() {
  285. GpuPreferences preferences;
  286. #if defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER)
  287. preferences.use_passthrough_cmd_decoder = true;
  288. #endif
  289. return preferences;
  290. }
  291. class CommandBufferSetup {
  292. public:
  293. CommandBufferSetup()
  294. : at_exit_manager_(),
  295. gpu_preferences_(GetGpuPreferences()),
  296. share_group_(new gl::GLShareGroup),
  297. translator_cache_(gpu_preferences_) {
  298. logging::SetMinLogLevel(logging::LOG_FATAL);
  299. CHECK(base::i18n::InitializeICU());
  300. base::CommandLine::Init(0, nullptr);
  301. [[maybe_unused]] auto* command_line =
  302. base::CommandLine::ForCurrentProcess();
  303. #if defined(USE_OZONE)
  304. ui::OzonePlatform::InitializeForGPU(ui::OzonePlatform::InitParams());
  305. #endif
  306. #if defined(GPU_FUZZER_USE_ANGLE)
  307. command_line->AppendSwitchASCII(switches::kUseGL,
  308. gl::kGLImplementationANGLEName);
  309. #if defined(GPU_FUZZER_USE_SWANGLE)
  310. command_line->AppendSwitchASCII(switches::kUseANGLE,
  311. gl::kANGLEImplementationSwiftShaderName);
  312. #else
  313. command_line->AppendSwitchASCII(switches::kUseANGLE,
  314. gl::kANGLEImplementationNullName);
  315. #endif
  316. CHECK(gl::init::InitializeStaticGLBindingsImplementation(
  317. gl::GLImplementationParts(gl::kGLImplementationEGLANGLE), false));
  318. display_ = gl::init::InitializeGLOneOffPlatformImplementation(
  319. /*fallback_to_software_gl=*/false,
  320. /*disable_gl_drawing=*/false,
  321. /*init_extensions=*/true,
  322. /*system_device_id=*/0);
  323. CHECK(display_);
  324. #elif defined(GPU_FUZZER_USE_STUB)
  325. gl::GLSurfaceTestSupport::InitializeOneOffWithStubBindings();
  326. // Because the context depends on configuration bits, we want to recreate
  327. // it every time.
  328. recreate_context_ = true;
  329. #else
  330. #error invalid configuration
  331. #endif
  332. discardable_manager_ =
  333. std::make_unique<ServiceDiscardableManager>(gpu_preferences_);
  334. passthrough_discardable_manager_ =
  335. std::make_unique<PassthroughDiscardableManager>(gpu_preferences_);
  336. if (gpu_preferences_.use_passthrough_cmd_decoder)
  337. recreate_context_ = true;
  338. surface_ = gl::init::CreateOffscreenGLSurface(display_, gfx::Size());
  339. if (!recreate_context_) {
  340. InitContext();
  341. }
  342. }
  343. ~CommandBufferSetup() {
  344. if (display_) {
  345. gl::init::ShutdownGL(display_, false);
  346. display_ = nullptr;
  347. }
  348. }
  349. bool InitDecoder() {
  350. if (!context_) {
  351. InitContext();
  352. }
  353. context_->MakeCurrent(surface_.get());
  354. GpuFeatureInfo gpu_feature_info;
  355. #if defined(GPU_FUZZER_USE_RASTER_DECODER)
  356. gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] =
  357. kGpuFeatureStatusEnabled;
  358. #endif
  359. auto feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
  360. config_.workarounds, gpu_feature_info);
  361. command_buffer_.reset(new CommandBufferDirect());
  362. if (gpu_preferences_.use_passthrough_cmd_decoder) {
  363. // Virtualized contexts don't work with passthrough command decoder.
  364. // See https://crbug.com/914976
  365. config_.workarounds.use_virtualized_gl_contexts = false;
  366. }
  367. scoped_refptr<gl::GLContext> shared_context;
  368. if (config_.workarounds.use_virtualized_gl_contexts) {
  369. shared_context = context_;
  370. } else {
  371. shared_context = CreateContext();
  372. }
  373. shared_context->MakeCurrent(surface_.get());
  374. context_state_ = base::MakeRefCounted<SharedContextState>(
  375. share_group_, surface_, std::move(shared_context),
  376. config_.workarounds.use_virtualized_gl_contexts, base::DoNothing(),
  377. gpu_preferences_.gr_context_type);
  378. context_state_->InitializeGrContext(gpu_preferences_, config_.workarounds,
  379. nullptr);
  380. context_state_->InitializeGL(gpu_preferences_, feature_info);
  381. shared_image_manager_ = std::make_unique<SharedImageManager>();
  382. shared_image_factory_ = std::make_unique<SharedImageFactory>(
  383. gpu_preferences_, config_.workarounds, gpu_feature_info,
  384. context_state_.get(), &mailbox_manager_, shared_image_manager_.get(),
  385. /*image_factory=*/nullptr, /*memory_tracker=*/nullptr,
  386. /*is_for_display_compositor=*/false);
  387. for (uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
  388. usage <= SHARED_IMAGE_USAGE_RGB_EMULATION; usage <<= 1) {
  389. Mailbox::Name name;
  390. memset(name, 0, sizeof(name));
  391. name[0] = usage;
  392. // Mark this as a SharedImage mailbox.
  393. constexpr size_t kSharedImageFlagIndex = GL_MAILBOX_SIZE_CHROMIUM - 1;
  394. constexpr int8_t kSharedImageFlag = 0x1;
  395. name[kSharedImageFlagIndex] |= kSharedImageFlag;
  396. Mailbox mailbox;
  397. mailbox.SetName(name);
  398. shared_image_factory_->CreateSharedImage(
  399. mailbox, viz::RGBA_8888, gfx::Size(256, 256),
  400. gfx::ColorSpace::CreateSRGB(), kTopLeft_GrSurfaceOrigin,
  401. kPremul_SkAlphaType, gfx::kNullAcceleratedWidget, usage);
  402. }
  403. #if defined(GPU_FUZZER_USE_RASTER_DECODER)
  404. context_state_->MakeCurrent(nullptr);
  405. auto* context = context_state_->context();
  406. decoder_.reset(raster::RasterDecoder::Create(
  407. command_buffer_.get(), command_buffer_->service(), &outputter_,
  408. gpu_feature_info, gpu_preferences_, nullptr /* memory_tracker */,
  409. shared_image_manager_.get(), /*image_factory=*/nullptr, context_state_,
  410. true /* is_privileged */));
  411. #else
  412. context_->MakeCurrent(surface_.get());
  413. // GLES2Decoder may Initialize feature_info differently than
  414. // SharedContextState and should have its own.
  415. auto decoder_feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
  416. config_.workarounds, gpu_feature_info);
  417. scoped_refptr<gles2::ContextGroup> context_group = new gles2::ContextGroup(
  418. gpu_preferences_, true, &mailbox_manager_, nullptr /* memory_tracker */,
  419. &translator_cache_, &completeness_cache_, decoder_feature_info,
  420. config_.attrib_helper.bind_generates_resource,
  421. nullptr /* image_factory */, nullptr /* progress_reporter */,
  422. gpu_feature_info, discardable_manager_.get(),
  423. passthrough_discardable_manager_.get(), shared_image_manager_.get());
  424. auto* context = context_.get();
  425. decoder_.reset(gles2::GLES2Decoder::Create(
  426. command_buffer_.get(), command_buffer_->service(), &outputter_,
  427. context_group.get()));
  428. #endif
  429. decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
  430. auto result = decoder_->Initialize(surface_.get(), context, true,
  431. gles2::DisallowedFeatures(),
  432. config_.attrib_helper);
  433. if (result != gpu::ContextResult::kSuccess)
  434. return false;
  435. decoder_initialized_ = true;
  436. command_buffer_->set_handler(decoder_.get());
  437. InitializeInitialCommandBuffer();
  438. decoder_->set_max_bucket_size(8 << 20);
  439. #if !defined(GPU_FUZZER_USE_RASTER_DECODER)
  440. if (context_group->buffer_manager()) {
  441. context_group->buffer_manager()->set_max_buffer_size(8 << 20);
  442. }
  443. #endif
  444. return decoder_->MakeCurrent();
  445. }
  446. void ResetDecoder() {
  447. bool context_lost = false;
  448. if (decoder_) {
  449. #if !defined(GPU_FUZZER_USE_RASTER_DECODER)
  450. // Keep a reference to the translators, which keeps them in the cache even
  451. // after the decoder is reset. They are expensive to initialize, but they
  452. // don't keep state.
  453. scoped_refptr<gles2::ShaderTranslatorInterface> translator =
  454. decoder_->GetTranslator(GL_VERTEX_SHADER);
  455. if (translator)
  456. translator->AddRef();
  457. translator = decoder_->GetTranslator(GL_FRAGMENT_SHADER);
  458. if (translator)
  459. translator->AddRef();
  460. #endif
  461. context_lost = decoder_->WasContextLost();
  462. // Only safe to call CheckResetStatus if !WasContextLost.
  463. if (!context_lost)
  464. context_lost = decoder_initialized_ && decoder_->CheckResetStatus();
  465. // If |decoder_->Initialize(...)| was unsuccessful, |decoder_| would have
  466. // already called Destroy.
  467. if (decoder_initialized_)
  468. decoder_->Destroy(!context_lost);
  469. decoder_.reset();
  470. if (!context_lost)
  471. context_lost = !context_state_->MakeCurrent(nullptr);
  472. shared_image_factory_->DestroyAllSharedImages(!context_lost);
  473. shared_image_factory_.reset();
  474. shared_image_manager_.reset();
  475. context_state_->MakeCurrent(nullptr);
  476. context_state_.reset();
  477. }
  478. if (context_) {
  479. if (recreate_context_ || context_lost) {
  480. context_->ReleaseCurrent(nullptr);
  481. context_ = nullptr;
  482. }
  483. }
  484. command_buffer_.reset();
  485. decoder_initialized_ = false;
  486. }
  487. void RunCommandBuffer(const uint8_t* data, size_t size) {
  488. size_t consumed = config_.MakeFromBits(data, size);
  489. consumed = (consumed + 3) & ~3;
  490. if (consumed > size)
  491. return;
  492. data += consumed;
  493. size -= consumed;
  494. // The commands are flushed at a uint32_t granularity. If the data is not
  495. // a full command, we zero-pad it.
  496. size_t padded_size = (size + 3) & ~3;
  497. // crbug.com/638836 The -max_len argument is sometimes not respected, so the
  498. // fuzzer may give us too much data. Bail ASAP in that case.
  499. if (padded_size > kCommandBufferSize)
  500. return;
  501. if (!InitDecoder()) {
  502. ResetDecoder();
  503. return;
  504. }
  505. uint32_t buffer_size = buffer_->size();
  506. CHECK_LE(padded_size, buffer_size);
  507. command_buffer_->SetGetBuffer(buffer_id_);
  508. auto* memory = static_cast<char*>(buffer_->memory());
  509. memcpy(memory, data, size);
  510. if (size < buffer_size)
  511. memset(memory + size, 0, buffer_size - size);
  512. command_buffer_->Flush(padded_size / 4);
  513. ResetDecoder();
  514. }
  515. private:
  516. void CreateTransferBuffer(uint32_t size, int32_t id) {
  517. scoped_refptr<Buffer> buffer =
  518. command_buffer_->CreateTransferBufferWithId(size, id);
  519. memset(buffer->memory(), 0, size);
  520. }
  521. void InitializeInitialCommandBuffer() {
  522. buffer_id_ = 1;
  523. buffer_ = command_buffer_->CreateTransferBufferWithId(kCommandBufferSize,
  524. buffer_id_);
  525. CHECK(buffer_);
  526. // Create some transfer buffers. This is somewhat arbitrary, but having a
  527. // reasonably sized buffer in slot 4 allows us to prime the corpus with data
  528. // extracted from unit tests.
  529. CreateTransferBuffer(kTransferBufferSize, 2);
  530. CreateTransferBuffer(kSmallTransferBufferSize, 3);
  531. CreateTransferBuffer(kTransferBufferSize, 4);
  532. CreateTransferBuffer(kTinyTransferBufferSize, 5);
  533. }
  534. scoped_refptr<gl::GLContext> CreateContext() {
  535. #if defined(GPU_FUZZER_USE_STUB)
  536. auto stub = base::MakeRefCounted<gl::GLContextStub>(share_group_.get());
  537. stub->SetGLVersionString(config_.version);
  538. stub->SetExtensionsString(config_.extensions.c_str());
  539. stub->SetUseStubApi(true);
  540. return stub;
  541. #else
  542. auto context = base::MakeRefCounted<gl::GLContextEGL>(share_group_.get());
  543. context->Initialize(surface_.get(), config_.gl_context_attribs);
  544. return context;
  545. #endif
  546. }
  547. void InitContext() {
  548. context_ = CreateContext();
  549. // When not using the passthrough decoder, ANGLE should not be generating
  550. // errors (the decoder should prevent those from happening). We register a
  551. // callback to catch them if it does.
  552. #if defined(GPU_FUZZER_USE_ANGLE) && \
  553. !defined(GPU_FUZZER_USE_PASSTHROUGH_CMD_DECODER)
  554. context_->MakeCurrent(surface_.get());
  555. glEnable(GL_DEBUG_OUTPUT);
  556. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  557. glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr,
  558. GL_FALSE);
  559. glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
  560. GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
  561. glDebugMessageCallback(&LogGLDebugMessage, nullptr);
  562. #endif
  563. }
  564. static void APIENTRY LogGLDebugMessage(GLenum source,
  565. GLenum type,
  566. GLuint id,
  567. GLenum severity,
  568. GLsizei length,
  569. const GLchar* message,
  570. const GLvoid* user_param) {
  571. LOG_IF(FATAL, (id != GL_OUT_OF_MEMORY)) << "GL Driver Message: " << message;
  572. }
  573. base::AtExitManager at_exit_manager_;
  574. GpuPreferences gpu_preferences_;
  575. Config config_;
  576. gles2::MailboxManagerImpl mailbox_manager_;
  577. gles2::TraceOutputter outputter_;
  578. scoped_refptr<gl::GLShareGroup> share_group_;
  579. std::unique_ptr<ServiceDiscardableManager> discardable_manager_;
  580. std::unique_ptr<PassthroughDiscardableManager>
  581. passthrough_discardable_manager_;
  582. std::unique_ptr<SharedImageManager> shared_image_manager_;
  583. std::unique_ptr<SharedImageFactory> shared_image_factory_;
  584. bool recreate_context_ = false;
  585. gl::GLDisplay* display_ = nullptr;
  586. scoped_refptr<gl::GLSurface> surface_;
  587. scoped_refptr<gl::GLContext> context_;
  588. scoped_refptr<SharedContextState> context_state_;
  589. gles2::ShaderTranslatorCache translator_cache_;
  590. gles2::FramebufferCompletenessCache completeness_cache_;
  591. std::unique_ptr<CommandBufferDirect> command_buffer_;
  592. #if defined(GPU_FUZZER_USE_RASTER_DECODER)
  593. std::unique_ptr<raster::RasterDecoder> decoder_;
  594. #else
  595. std::unique_ptr<gles2::GLES2Decoder> decoder_;
  596. #endif
  597. scoped_refptr<Buffer> buffer_;
  598. int32_t buffer_id_ = 0;
  599. bool decoder_initialized_ = false;
  600. };
  601. // Intentionally leaked because asan tries to exit cleanly after a crash, but
  602. // the decoder is usually in a bad state at that point.
  603. // We need to load ANGLE libraries before the fuzzer infrastructure starts,
  604. // because it gets confused about new coverage counters being dynamically
  605. // registered, causing crashes.
  606. CommandBufferSetup* g_setup = new CommandBufferSetup();
  607. } // anonymous namespace
  608. } // namespace gpu
  609. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  610. gpu::g_setup->RunCommandBuffer(data, size);
  611. return 0;
  612. }