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_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"), |
3795 GetCommandName(command)); | |
vmiura
2014/09/10 17:09:31
Scoped TRACE_EVENT was wrong here, so changed to B
| |
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; |
3822 } | 3837 } |
3823 } else { | 3838 } else { |
3824 result = DoCommonCommand(command, arg_count, cmd_data); | 3839 result = DoCommonCommand(command, arg_count, cmd_data); |
3825 } | 3840 } |
3841 | |
3842 if (DebugImpl) { | |
3843 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"), | |
3844 GetCommandName(command)); | |
3845 } | |
3846 | |
3826 if (result == error::kNoError && | 3847 if (result == error::kNoError && |
3827 current_decoder_error_ != error::kNoError) { | 3848 current_decoder_error_ != error::kNoError) { |
3828 result = current_decoder_error_; | 3849 result = current_decoder_error_; |
3829 current_decoder_error_ = error::kNoError; | 3850 current_decoder_error_ = error::kNoError; |
3830 } | 3851 } |
3831 | 3852 |
3832 if (result != error::kDeferCommandUntilLater) { | 3853 if (result != error::kDeferCommandUntilLater) { |
3833 process_pos += size; | 3854 process_pos += size; |
3834 cmd_data += size; | 3855 cmd_data += size; |
3835 } | 3856 } |
3836 } | 3857 } |
3837 | 3858 |
3838 if (entries_processed) | 3859 if (entries_processed) |
3839 *entries_processed = process_pos; | 3860 *entries_processed = process_pos; |
3840 | 3861 |
3841 if (error::IsError(result)) { | 3862 if (error::IsError(result)) { |
3842 LOG(ERROR) << "Error: " << result << " for Command " | 3863 LOG(ERROR) << "Error: " << result << " for Command " |
3843 << GetCommandName(command); | 3864 << GetCommandName(command); |
3844 } | 3865 } |
3845 | 3866 |
3846 return result; | 3867 return result; |
3847 } | 3868 } |
3848 | 3869 |
3870 error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands, | |
3871 const void* buffer, | |
3872 int num_entries, | |
3873 int* entries_processed) { | |
3874 if (gpu_debug_commands_) { | |
3875 return DoCommandsImpl<true>( | |
3876 num_commands, buffer, num_entries, entries_processed); | |
3877 } else { | |
3878 return DoCommandsImpl<false>( | |
3879 num_commands, buffer, num_entries, entries_processed); | |
3880 } | |
3881 } | |
3882 | |
3849 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { | 3883 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { |
3850 buffer_manager()->RemoveBuffer(client_id); | 3884 buffer_manager()->RemoveBuffer(client_id); |
3851 } | 3885 } |
3852 | 3886 |
3853 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { | 3887 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { |
3854 if (GetProgram(client_id)) { | 3888 if (GetProgram(client_id)) { |
3855 return false; | 3889 return false; |
3856 } | 3890 } |
3857 GLuint service_id = glCreateProgram(); | 3891 GLuint service_id = glCreateProgram(); |
3858 if (service_id != 0) { | 3892 if (service_id != 0) { |
(...skipping 7379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11238 } | 11272 } |
11239 } | 11273 } |
11240 | 11274 |
11241 // Include the auto-generated part of this file. We split this because it means | 11275 // 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 | 11276 // 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. | 11277 // instead of having to edit some template or the code generator. |
11244 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 11278 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
11245 | 11279 |
11246 } // namespace gles2 | 11280 } // namespace gles2 |
11247 } // namespace gpu | 11281 } // namespace gpu |
OLD | NEW |