Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 // Overridden from AsyncAPIInterface. | 563 // Overridden from AsyncAPIInterface. |
| 564 virtual Error DoCommand(unsigned int command, | 564 virtual Error DoCommand(unsigned int command, |
| 565 unsigned int arg_count, | 565 unsigned int arg_count, |
| 566 const void* args) OVERRIDE; | 566 const void* args) OVERRIDE; |
| 567 | 567 |
| 568 virtual error::Error DoCommands(unsigned int num_commands, | 568 virtual error::Error DoCommands(unsigned int num_commands, |
| 569 const void* buffer, | 569 const void* buffer, |
| 570 int num_entries, | 570 int num_entries, |
| 571 int* entries_processed) OVERRIDE; | 571 int* entries_processed) OVERRIDE; |
| 572 | 572 |
| 573 template <bool DebugImpl> | |
| 574 error::Error DoCommandsImpl(unsigned int num_commands, | |
| 575 const void* buffer, | |
| 576 int num_entries, | |
| 577 int* entries_processed); | |
| 578 | |
| 573 // Overridden from AsyncAPIInterface. | 579 // Overridden from AsyncAPIInterface. |
| 574 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; | 580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; |
| 575 | 581 |
| 576 // Overridden from GLES2Decoder. | 582 // Overridden from GLES2Decoder. |
| 577 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, | 583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, |
| 578 const scoped_refptr<gfx::GLContext>& context, | 584 const scoped_refptr<gfx::GLContext>& context, |
| 579 bool offscreen, | 585 bool offscreen, |
| 580 const gfx::Size& size, | 586 const gfx::Size& size, |
| 581 const DisallowedFeatures& disallowed_features, | 587 const DisallowedFeatures& disallowed_features, |
| 582 const std::vector<int32>& attribs) OVERRIDE; | 588 const std::vector<int32>& attribs) OVERRIDE; |
| (...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1802 | 1808 |
| 1803 // Command buffer stats. | 1809 // Command buffer stats. |
| 1804 base::TimeDelta total_processing_commands_time_; | 1810 base::TimeDelta total_processing_commands_time_; |
| 1805 | 1811 |
| 1806 // States related to each manager. | 1812 // States related to each manager. |
| 1807 DecoderTextureState texture_state_; | 1813 DecoderTextureState texture_state_; |
| 1808 DecoderFramebufferState framebuffer_state_; | 1814 DecoderFramebufferState framebuffer_state_; |
| 1809 | 1815 |
| 1810 scoped_ptr<GPUTracer> gpu_tracer_; | 1816 scoped_ptr<GPUTracer> gpu_tracer_; |
| 1811 scoped_ptr<GPUStateTracer> gpu_state_tracer_; | 1817 scoped_ptr<GPUStateTracer> gpu_state_tracer_; |
| 1818 const unsigned char* cb_command_trace_category_; | |
| 1812 int gpu_trace_level_; | 1819 int gpu_trace_level_; |
| 1813 bool gpu_trace_commands_; | 1820 bool gpu_trace_commands_; |
| 1821 bool gpu_debug_commands_; | |
| 1814 | 1822 |
| 1815 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; | 1823 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; |
| 1816 | 1824 |
| 1817 // Used to validate multisample renderbuffers if needed | 1825 // Used to validate multisample renderbuffers if needed |
| 1818 GLuint validation_texture_; | 1826 GLuint validation_texture_; |
| 1819 GLuint validation_fbo_multisample_; | 1827 GLuint validation_fbo_multisample_; |
| 1820 GLuint validation_fbo_; | 1828 GLuint validation_fbo_; |
| 1821 | 1829 |
| 1822 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)( | 1830 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)( |
| 1823 uint32 immediate_data_size, | 1831 uint32 immediate_data_size, |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2313 shader_texture_lod_explicitly_enabled_(false), | 2321 shader_texture_lod_explicitly_enabled_(false), |
| 2314 compile_shader_always_succeeds_(false), | 2322 compile_shader_always_succeeds_(false), |
| 2315 lose_context_when_out_of_memory_(false), | 2323 lose_context_when_out_of_memory_(false), |
| 2316 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( | 2324 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( |
| 2317 switches::kEnableGPUServiceLoggingGPU)), | 2325 switches::kEnableGPUServiceLoggingGPU)), |
| 2318 viewport_max_width_(0), | 2326 viewport_max_width_(0), |
| 2319 viewport_max_height_(0), | 2327 viewport_max_height_(0), |
| 2320 texture_state_(group_->feature_info() | 2328 texture_state_(group_->feature_info() |
| 2321 ->workarounds() | 2329 ->workarounds() |
| 2322 .texsubimage2d_faster_than_teximage2d), | 2330 .texsubimage2d_faster_than_teximage2d), |
| 2331 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( | |
| 2332 TRACE_DISABLED_BY_DEFAULT("cb_command"))), | |
| 2333 gpu_trace_level_(2), | |
| 2334 gpu_trace_commands_(false), | |
| 2335 gpu_debug_commands_(false), | |
| 2323 validation_texture_(0), | 2336 validation_texture_(0), |
| 2324 validation_fbo_multisample_(0), | 2337 validation_fbo_multisample_(0), |
| 2325 validation_fbo_(0) { | 2338 validation_fbo_(0) { |
| 2326 DCHECK(group); | 2339 DCHECK(group); |
| 2327 | 2340 |
| 2328 attrib_0_value_.v[0] = 0.0f; | 2341 attrib_0_value_.v[0] = 0.0f; |
| 2329 attrib_0_value_.v[1] = 0.0f; | 2342 attrib_0_value_.v[1] = 0.0f; |
| 2330 attrib_0_value_.v[2] = 0.0f; | 2343 attrib_0_value_.v[2] = 0.0f; |
| 2331 attrib_0_value_.v[3] = 1.0f; | 2344 attrib_0_value_.v[3] = 1.0f; |
| 2332 | 2345 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2352 const gfx::Size& size, | 2365 const gfx::Size& size, |
| 2353 const DisallowedFeatures& disallowed_features, | 2366 const DisallowedFeatures& disallowed_features, |
| 2354 const std::vector<int32>& attribs) { | 2367 const std::vector<int32>& attribs) { |
| 2355 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); | 2368 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); |
| 2356 DCHECK(context->IsCurrent(surface.get())); | 2369 DCHECK(context->IsCurrent(surface.get())); |
| 2357 DCHECK(!context_.get()); | 2370 DCHECK(!context_.get()); |
| 2358 | 2371 |
| 2359 set_initialized(); | 2372 set_initialized(); |
| 2360 gpu_tracer_.reset(new GPUTracer(this)); | 2373 gpu_tracer_.reset(new GPUTracer(this)); |
| 2361 gpu_state_tracer_ = GPUStateTracer::Create(&state_); | 2374 gpu_state_tracer_ = GPUStateTracer::Create(&state_); |
| 2362 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime | |
| 2363 gpu_trace_level_ = 2; | |
| 2364 gpu_trace_commands_ = false; | |
| 2365 | 2375 |
| 2366 if (CommandLine::ForCurrentProcess()->HasSwitch( | 2376 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 2367 switches::kEnableGPUDebugging)) { | 2377 switches::kEnableGPUDebugging)) { |
| 2368 set_debug(true); | 2378 set_debug(true); |
| 2369 } | 2379 } |
| 2370 | 2380 |
| 2371 if (CommandLine::ForCurrentProcess()->HasSwitch( | 2381 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 2372 switches::kEnableGPUCommandLogging)) { | 2382 switches::kEnableGPUCommandLogging)) { |
| 2373 set_log_commands(true); | 2383 set_log_commands(true); |
| 2374 } | 2384 } |
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3322 resize_callback_ = callback; | 3332 resize_callback_ = callback; |
| 3323 } | 3333 } |
| 3324 | 3334 |
| 3325 Logger* GLES2DecoderImpl::GetLogger() { | 3335 Logger* GLES2DecoderImpl::GetLogger() { |
| 3326 return &logger_; | 3336 return &logger_; |
| 3327 } | 3337 } |
| 3328 | 3338 |
| 3329 void GLES2DecoderImpl::BeginDecoding() { | 3339 void GLES2DecoderImpl::BeginDecoding() { |
| 3330 gpu_tracer_->BeginDecoding(); | 3340 gpu_tracer_->BeginDecoding(); |
| 3331 gpu_trace_commands_ = gpu_tracer_->IsTracing(); | 3341 gpu_trace_commands_ = gpu_tracer_->IsTracing(); |
| 3342 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ || | |
| 3343 (*cb_command_trace_category_ != 0); | |
| 3332 } | 3344 } |
| 3333 | 3345 |
| 3334 void GLES2DecoderImpl::EndDecoding() { | 3346 void GLES2DecoderImpl::EndDecoding() { |
| 3335 gpu_tracer_->EndDecoding(); | 3347 gpu_tracer_->EndDecoding(); |
| 3336 } | 3348 } |
| 3337 | 3349 |
| 3338 ErrorState* GLES2DecoderImpl::GetErrorState() { | 3350 ErrorState* GLES2DecoderImpl::GetErrorState() { |
| 3339 return state_.GetErrorState(); | 3351 return state_.GetErrorState(); |
| 3340 } | 3352 } |
| 3341 | 3353 |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3744 const void* cmd_data) { | 3756 const void* cmd_data) { |
| 3745 return DoCommands(1, cmd_data, arg_count + 1, 0); | 3757 return DoCommands(1, cmd_data, arg_count + 1, 0); |
| 3746 } | 3758 } |
| 3747 | 3759 |
| 3748 // Decode multiple commands, and call the corresponding GL functions. | 3760 // Decode multiple commands, and call the corresponding GL functions. |
| 3749 // NOTE: 'buffer' is a pointer to the command buffer. As such, it could be | 3761 // NOTE: 'buffer' is a pointer to the command buffer. As such, it could be |
| 3750 // changed by a (malicious) client at any time, so if validation has to happen, | 3762 // changed by a (malicious) client at any time, so if validation has to happen, |
| 3751 // it should operate on a copy of them. | 3763 // it should operate on a copy of them. |
| 3752 // NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the | 3764 // NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the |
| 3753 // interest of performance in this critical execution loop. | 3765 // interest of performance in this critical execution loop. |
| 3754 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands, | 3766 template <bool DebugImpl> |
| 3755 const void* buffer, | 3767 error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, |
| 3756 int num_entries, | 3768 const void* buffer, |
| 3757 int* entries_processed) { | 3769 int num_entries, |
| 3770 int* entries_processed) { | |
| 3758 commands_to_process_ = num_commands; | 3771 commands_to_process_ = num_commands; |
| 3759 error::Error result = error::kNoError; | 3772 error::Error result = error::kNoError; |
| 3760 const CommandBufferEntry* cmd_data = | 3773 const CommandBufferEntry* cmd_data = |
| 3761 static_cast<const CommandBufferEntry*>(buffer); | 3774 static_cast<const CommandBufferEntry*>(buffer); |
| 3762 int process_pos = 0; | 3775 int process_pos = 0; |
| 3763 unsigned int command = 0; | 3776 unsigned int command = 0; |
| 3764 | 3777 |
| 3765 while (process_pos < num_entries && result == error::kNoError && | 3778 while (process_pos < num_entries && result == error::kNoError && |
| 3766 commands_to_process_--) { | 3779 commands_to_process_--) { |
| 3767 const unsigned int size = cmd_data->value_header.size; | 3780 const unsigned int size = cmd_data->value_header.size; |
| 3768 command = cmd_data->value_header.command; | 3781 command = cmd_data->value_header.command; |
| 3769 | 3782 |
| 3770 if (size == 0) { | 3783 if (size == 0) { |
| 3771 result = error::kInvalidSize; | 3784 result = error::kInvalidSize; |
| 3772 break; | 3785 break; |
| 3773 } | 3786 } |
| 3774 | 3787 |
| 3775 if (static_cast<int>(size) + process_pos > num_entries) { | 3788 if (static_cast<int>(size) + process_pos > num_entries) { |
| 3776 result = error::kOutOfBounds; | 3789 result = error::kOutOfBounds; |
| 3777 break; | 3790 break; |
| 3778 } | 3791 } |
| 3779 | 3792 |
| 3780 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cb_command"), | 3793 if (DebugImpl) { |
| 3781 GetCommandName(command)); | 3794 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cb_command"), |
| 3795 GetCommandName(command)); | |
| 3782 | 3796 |
| 3783 if (log_commands()) { | 3797 if (log_commands()) { |
| 3784 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" | 3798 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" |
| 3785 << "cmd: " << GetCommandName(command); | 3799 << "cmd: " << GetCommandName(command); |
| 3800 } | |
| 3786 } | 3801 } |
| 3787 | 3802 |
| 3788 const unsigned int arg_count = size - 1; | 3803 const unsigned int arg_count = size - 1; |
| 3789 unsigned int command_index = command - kStartPoint - 1; | 3804 unsigned int command_index = command - kStartPoint - 1; |
| 3790 if (command_index < arraysize(command_info)) { | 3805 if (command_index < arraysize(command_info)) { |
| 3791 const CommandInfo& info = command_info[command_index]; | 3806 const CommandInfo& info = command_info[command_index]; |
| 3792 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); | 3807 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); |
| 3793 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || | 3808 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || |
| 3794 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { | 3809 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { |
| 3795 bool doing_gpu_trace = false; | 3810 bool doing_gpu_trace = false; |
| 3796 if (gpu_trace_commands_) { | 3811 if (DebugImpl && gpu_trace_commands_) { |
| 3797 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) { | 3812 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) { |
| 3798 doing_gpu_trace = true; | 3813 doing_gpu_trace = true; |
| 3799 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder); | 3814 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder); |
| 3800 } | 3815 } |
| 3801 } | 3816 } |
| 3802 | 3817 |
| 3803 uint32 immediate_data_size = (arg_count - info_arg_count) * | 3818 uint32 immediate_data_size = (arg_count - info_arg_count) * |
| 3804 sizeof(CommandBufferEntry); // NOLINT | 3819 sizeof(CommandBufferEntry); // NOLINT |
| 3805 | 3820 |
| 3806 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data); | 3821 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data); |
| 3807 | 3822 |
| 3808 if (doing_gpu_trace) | 3823 if (DebugImpl && doing_gpu_trace) |
| 3809 gpu_tracer_->End(kTraceDecoder); | 3824 gpu_tracer_->End(kTraceDecoder); |
| 3810 | 3825 |
| 3811 if (debug()) { | 3826 if (DebugImpl && debug()) { |
| 3812 GLenum error; | 3827 GLenum error; |
| 3813 while ((error = glGetError()) != GL_NO_ERROR) { | 3828 while ((error = glGetError()) != GL_NO_ERROR) { |
| 3814 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] " | 3829 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] " |
| 3815 << "GL ERROR: " << GLES2Util::GetStringEnum(error) | 3830 << "GL ERROR: " << GLES2Util::GetStringEnum(error) |
| 3816 << " : " << GetCommandName(command); | 3831 << " : " << GetCommandName(command); |
| 3817 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver"); | 3832 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver"); |
| 3818 } | 3833 } |
| 3819 } | 3834 } |
| 3820 } else { | 3835 } else { |
| 3821 result = error::kInvalidArguments; | 3836 result = error::kInvalidArguments; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 3839 *entries_processed = process_pos; | 3854 *entries_processed = process_pos; |
| 3840 | 3855 |
| 3841 if (error::IsError(result)) { | 3856 if (error::IsError(result)) { |
| 3842 LOG(ERROR) << "Error: " << result << " for Command " | 3857 LOG(ERROR) << "Error: " << result << " for Command " |
| 3843 << GetCommandName(command); | 3858 << GetCommandName(command); |
| 3844 } | 3859 } |
| 3845 | 3860 |
| 3846 return result; | 3861 return result; |
| 3847 } | 3862 } |
| 3848 | 3863 |
| 3864 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands, | |
| 3865 const void* buffer, | |
| 3866 int num_entries, | |
| 3867 int* entries_processed) { | |
| 3868 if (gpu_debug_commands_) | |
|
piman
2014/09/10 04:05:17
nit: style requires {}
vmiura
2014/09/10 17:09:31
Done.
| |
| 3869 return DoCommandsImpl<true>( | |
| 3870 num_commands, buffer, num_entries, entries_processed); | |
| 3871 else | |
| 3872 return DoCommandsImpl<false>( | |
| 3873 num_commands, buffer, num_entries, entries_processed); | |
| 3874 } | |
| 3875 | |
| 3849 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { | 3876 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { |
| 3850 buffer_manager()->RemoveBuffer(client_id); | 3877 buffer_manager()->RemoveBuffer(client_id); |
| 3851 } | 3878 } |
| 3852 | 3879 |
| 3853 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { | 3880 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { |
| 3854 if (GetProgram(client_id)) { | 3881 if (GetProgram(client_id)) { |
| 3855 return false; | 3882 return false; |
| 3856 } | 3883 } |
| 3857 GLuint service_id = glCreateProgram(); | 3884 GLuint service_id = glCreateProgram(); |
| 3858 if (service_id != 0) { | 3885 if (service_id != 0) { |
| (...skipping 7379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11238 } | 11265 } |
| 11239 } | 11266 } |
| 11240 | 11267 |
| 11241 // Include the auto-generated part of this file. We split this because it means | 11268 // Include the auto-generated part of this file. We split this because it means |
| 11242 // we can easily edit the non-auto generated parts right here in this file | 11269 // we can easily edit the non-auto generated parts right here in this file |
| 11243 // instead of having to edit some template or the code generator. | 11270 // instead of having to edit some template or the code generator. |
| 11244 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 11271 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 11245 | 11272 |
| 11246 } // namespace gles2 | 11273 } // namespace gles2 |
| 11247 } // namespace gpu | 11274 } // namespace gpu |
| OLD | NEW |