Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 7 #include <memory> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/at_exit.h" | |
| 11 #include "base/bind.h" | |
| 12 #include "base/command_line.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "build/build_config.h" | |
| 16 #include "gpu/command_buffer/common/constants.h" | |
| 17 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
| 18 #include "gpu/command_buffer/common/sync_token.h" | |
| 19 #include "gpu/command_buffer/service/buffer_manager.h" | |
| 20 #include "gpu/command_buffer/service/command_buffer_service.h" | |
| 21 #include "gpu/command_buffer/service/command_executor.h" | |
| 22 #include "gpu/command_buffer/service/context_group.h" | |
| 23 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | |
| 24 #include "gpu/command_buffer/service/logger.h" | |
| 25 #include "gpu/command_buffer/service/mailbox_manager_impl.h" | |
| 26 #include "gpu/command_buffer/service/sync_point_manager.h" | |
| 27 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | |
| 28 #include "ui/gfx/geometry/size.h" | |
| 29 #include "ui/gl/gl_context.h" | |
| 30 #include "ui/gl/gl_context_stub_with_extensions.h" | |
| 31 #include "ui/gl/gl_image_ref_counted_memory.h" | |
| 32 #include "ui/gl/gl_share_group.h" | |
| 33 #include "ui/gl/gl_stub_api.h" | |
| 34 #include "ui/gl/gl_surface.h" | |
| 35 #include "ui/gl/gl_surface_stub.h" | |
| 36 #include "ui/gl/init/gl_factory.h" | |
| 37 #include "ui/gl/test/gl_surface_test_support.h" | |
| 38 | |
| 39 namespace gpu { | |
| 40 namespace { | |
| 41 | |
| 42 const size_t kCommandBufferSize = 16384; | |
| 43 const size_t kTransferBufferSize = 16384; | |
| 44 const size_t kSmallTransferBufferSize = 16; | |
| 45 const size_t kTinyTransferBufferSize = 3; | |
| 46 | |
| 47 class CommandBufferSetup { | |
| 48 public: | |
| 49 CommandBufferSetup() | |
| 50 : atexit_manager_(), | |
| 51 sync_point_manager_(new SyncPointManager(false)), | |
| 52 sync_point_order_data_(SyncPointOrderData::Create()), | |
| 53 mailbox_manager_(new gles2::MailboxManagerImpl), | |
| 54 share_group_(new gl::GLShareGroup), | |
| 55 surface_(new gl::GLSurfaceStub), | |
| 56 context_(new gl::GLContextStub(share_group_.get())), | |
| 57 command_buffer_id_(CommandBufferId::FromUnsafeValue(1)) { | |
| 58 logging::SetMinLogLevel(logging::LOG_FATAL); | |
| 59 base::CommandLine::Init(0, NULL); | |
| 60 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 61 switches::kEnableUnsafeES3APIs); | |
| 62 gpu_preferences_.enable_unsafe_es3_apis = true; | |
| 63 | |
| 64 gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings(); | |
| 65 gl::SetStubGLApi(&api_); | |
| 66 | |
| 67 sync_point_client_ = sync_point_manager_->CreateSyncPointClient( | |
| 68 sync_point_order_data_, CommandBufferNamespace::IN_PROCESS, | |
| 69 command_buffer_id_); | |
| 70 | |
| 71 translator_cache_ = new gles2::ShaderTranslatorCache(gpu_preferences_); | |
| 72 completeness_cache_ = new gles2::FramebufferCompletenessCache; | |
| 73 } | |
| 74 | |
| 75 void InitDecoder() { | |
| 76 context_->MakeCurrent(surface_.get()); | |
| 77 scoped_refptr<gles2::FeatureInfo> feature_info = | |
| 78 new gles2::FeatureInfo(); | |
| 79 scoped_refptr<gles2::ContextGroup> context_group = new gles2::ContextGroup( | |
| 80 gpu_preferences_, mailbox_manager_.get(), nullptr, translator_cache_, | |
| 81 completeness_cache_, feature_info, true /* bind_generates_resource */, | |
| 82 nullptr /* ImageFactory */); | |
| 83 command_buffer_.reset( | |
| 84 new CommandBufferService(context_group->transfer_buffer_manager())); | |
| 85 command_buffer_->SetPutOffsetChangeCallback( | |
| 86 base::Bind(&CommandBufferSetup::PumpCommands, base::Unretained(this))); | |
| 87 command_buffer_->SetGetBufferChangeCallback(base::Bind( | |
| 88 &CommandBufferSetup::GetBufferChanged, base::Unretained(this))); | |
| 89 InitializeInitialCommandBuffer(); | |
| 90 | |
| 91 decoder_.reset(gles2::GLES2Decoder::Create(context_group.get())); | |
| 92 executor_.reset(new CommandExecutor(command_buffer_.get(), decoder_.get(), | |
| 93 decoder_.get())); | |
| 94 decoder_->set_engine(executor_.get()); | |
| 95 decoder_->SetFenceSyncReleaseCallback(base::Bind( | |
| 96 &CommandBufferSetup::OnFenceSyncRelease, base::Unretained(this))); | |
| 97 decoder_->SetWaitFenceSyncCallback(base::Bind( | |
| 98 &CommandBufferSetup::OnWaitFenceSync, base::Unretained(this))); | |
| 99 decoder_->GetLogger()->set_log_synthesized_gl_errors(false); | |
| 100 | |
| 101 gles2::ContextCreationAttribHelper attrib_helper; | |
| 102 attrib_helper.offscreen_framebuffer_size = gfx::Size(16, 16); | |
| 103 attrib_helper.red_size = 8; | |
| 104 attrib_helper.green_size = 8; | |
| 105 attrib_helper.blue_size = 8; | |
| 106 attrib_helper.alpha_size = 8; | |
| 107 attrib_helper.depth_size = 0; | |
| 108 attrib_helper.stencil_size = 0; | |
| 109 attrib_helper.context_type = gles2::CONTEXT_TYPE_OPENGLES3; | |
| 110 | |
| 111 bool result = | |
| 112 decoder_->Initialize(surface_.get(), context_.get(), true, | |
| 113 gles2::DisallowedFeatures(), attrib_helper); | |
| 114 CHECK(result); | |
| 115 decoder_->set_max_bucket_size(8 << 20); | |
| 116 context_group->buffer_manager()->set_max_buffer_size(8 << 20); | |
| 117 } | |
| 118 | |
| 119 void ResetDecoder() { | |
| 120 decoder_->Destroy(true); | |
| 121 decoder_.reset(); | |
| 122 command_buffer_.reset(); | |
| 123 } | |
| 124 | |
| 125 ~CommandBufferSetup() { | |
| 126 sync_point_client_ = nullptr; | |
| 127 if (sync_point_order_data_) { | |
| 128 sync_point_order_data_->Destroy(); | |
| 129 sync_point_order_data_ = nullptr; | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 void RunCommandBuffer(const uint8_t* data, size_t size) { | |
| 134 InitDecoder(); | |
| 135 CHECK(size <= buffer_->size()); | |
| 136 command_buffer_->SetGetBuffer(buffer_id_); | |
| 137 memcpy(buffer_->memory(), data, size); | |
| 138 command_buffer_->Flush((size + 3) / 4); | |
|
no sievers
2016/07/14 21:33:24
don't you want to round down here?
piman
2016/07/14 22:15:46
I was thinking, this gives us slightly more covera
| |
| 139 ResetDecoder(); | |
| 140 } | |
| 141 | |
| 142 private: | |
| 143 void PumpCommands() { | |
| 144 if (!decoder_->MakeCurrent()) { | |
| 145 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); | |
| 146 command_buffer_->SetParseError(::gpu::error::kLostContext); | |
| 147 return; | |
| 148 } | |
| 149 | |
| 150 uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber( | |
| 151 sync_point_manager_.get()); | |
| 152 sync_point_order_data_->BeginProcessingOrderNumber(order_num); | |
| 153 | |
| 154 executor_->PutChanged(); | |
| 155 | |
| 156 sync_point_order_data_->FinishProcessingOrderNumber(order_num); | |
| 157 } | |
| 158 | |
| 159 bool GetBufferChanged(int32_t transfer_buffer_id) { | |
| 160 return executor_->SetGetBuffer(transfer_buffer_id); | |
| 161 } | |
| 162 | |
| 163 void OnFenceSyncRelease(uint64_t release) { | |
| 164 CHECK(sync_point_client_); | |
| 165 sync_point_client_->ReleaseFenceSync(release); | |
| 166 } | |
| 167 | |
| 168 bool OnWaitFenceSync(CommandBufferNamespace namespace_id, | |
| 169 CommandBufferId command_buffer_id, | |
| 170 uint64_t release) { | |
| 171 CHECK(sync_point_client_); | |
| 172 scoped_refptr<gpu::SyncPointClientState> release_state = | |
| 173 sync_point_manager_->GetSyncPointClientState(namespace_id, | |
| 174 command_buffer_id); | |
| 175 if (!release_state) | |
| 176 return true; | |
| 177 | |
| 178 if (release_state->IsFenceSyncReleased(release)) | |
| 179 return true; | |
| 180 | |
| 181 executor_->SetScheduled(false); | |
| 182 return false; | |
| 183 } | |
| 184 | |
| 185 void InitializeInitialCommandBuffer() { | |
| 186 buffer_id_ = 1; | |
| 187 buffer_ = command_buffer_->CreateTransferBufferWithId(kCommandBufferSize, | |
| 188 buffer_id_); | |
| 189 CHECK(buffer_); | |
| 190 // Create some transfer buffers. This is somewhat arbitrary, but having a | |
| 191 // reasonably sized buffer in slot 4 allows us to prime the corpus with data | |
| 192 // extracted from unit tests. | |
| 193 command_buffer_->CreateTransferBufferWithId(kTransferBufferSize, 2); | |
| 194 command_buffer_->CreateTransferBufferWithId(kSmallTransferBufferSize, 3); | |
| 195 command_buffer_->CreateTransferBufferWithId(kTransferBufferSize, 4); | |
| 196 command_buffer_->CreateTransferBufferWithId(kTinyTransferBufferSize, 5); | |
| 197 } | |
| 198 | |
| 199 base::AtExitManager atexit_manager_; | |
| 200 | |
| 201 gl::GLStubApi api_; | |
| 202 GpuPreferences gpu_preferences_; | |
| 203 | |
| 204 std::unique_ptr<SyncPointManager> sync_point_manager_; | |
| 205 scoped_refptr<SyncPointOrderData> sync_point_order_data_; | |
| 206 std::unique_ptr<SyncPointClient> sync_point_client_; | |
| 207 scoped_refptr<gles2::MailboxManager> mailbox_manager_; | |
| 208 scoped_refptr<gl::GLShareGroup> share_group_; | |
| 209 scoped_refptr<gl::GLSurface> surface_; | |
| 210 scoped_refptr<gl::GLContext> context_; | |
| 211 const gpu::CommandBufferId command_buffer_id_; | |
| 212 | |
| 213 scoped_refptr<gles2::ShaderTranslatorCache> translator_cache_; | |
| 214 scoped_refptr<gles2::FramebufferCompletenessCache> completeness_cache_; | |
| 215 | |
| 216 std::unique_ptr<CommandBufferService> command_buffer_; | |
| 217 | |
| 218 std::unique_ptr<gles2::GLES2Decoder> decoder_; | |
| 219 std::unique_ptr<CommandExecutor> executor_; | |
| 220 | |
| 221 scoped_refptr<Buffer> buffer_; | |
| 222 int32_t buffer_id_ = 0; | |
| 223 }; | |
| 224 | |
| 225 } // anonymous namespace | |
| 226 } // namespace gpu | |
| 227 | |
| 228 | |
| 229 static gpu::CommandBufferSetup& GetSetup() { | |
| 230 static gpu::CommandBufferSetup setup; | |
| 231 return setup; | |
| 232 } | |
| 233 | |
| 234 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | |
| 235 GetSetup().RunCommandBuffer(data, size); | |
| 236 return 0; | |
| 237 } | |
| OLD | NEW |