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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 bool enforce_internal_framebuffer, | 311 bool enforce_internal_framebuffer, |
312 bool internal); | 312 bool internal); |
313 ~ScopedResolvedFrameBufferBinder(); | 313 ~ScopedResolvedFrameBufferBinder(); |
314 | 314 |
315 private: | 315 private: |
316 GLES2DecoderImpl* decoder_; | 316 GLES2DecoderImpl* decoder_; |
317 bool resolve_and_bind_; | 317 bool resolve_and_bind_; |
318 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); | 318 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); |
319 }; | 319 }; |
320 | 320 |
| 321 // This class records texture upload time when in scope. |
| 322 class ScopedTextureUploadTimer { |
| 323 public: |
| 324 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder); |
| 325 ~ScopedTextureUploadTimer(); |
| 326 |
| 327 private: |
| 328 GLES2DecoderImpl* decoder_; |
| 329 base::TimeTicks begin_time_; |
| 330 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer); |
| 331 }; |
| 332 |
321 // Encapsulates an OpenGL texture. | 333 // Encapsulates an OpenGL texture. |
322 class Texture { | 334 class Texture { |
323 public: | 335 public: |
324 explicit Texture(GLES2DecoderImpl* decoder); | 336 explicit Texture(GLES2DecoderImpl* decoder); |
325 ~Texture(); | 337 ~Texture(); |
326 | 338 |
327 // Create a new render texture. | 339 // Create a new render texture. |
328 void Create(); | 340 void Create(); |
329 | 341 |
330 // Set the initial size and format of a render texture or resize it. | 342 // Set the initial size and format of a render texture or resize it. |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 const base::Callback<void(gfx::Size)>& callback); | 525 const base::Callback<void(gfx::Size)>& callback); |
514 | 526 |
515 virtual void SetMsgCallback(const MsgCallback& callback); | 527 virtual void SetMsgCallback(const MsgCallback& callback); |
516 | 528 |
517 virtual void SetStreamTextureManager(StreamTextureManager* manager); | 529 virtual void SetStreamTextureManager(StreamTextureManager* manager); |
518 virtual bool GetServiceTextureId(uint32 client_texture_id, | 530 virtual bool GetServiceTextureId(uint32 client_texture_id, |
519 uint32* service_texture_id); | 531 uint32* service_texture_id); |
520 | 532 |
521 virtual uint32 GetGLError() OVERRIDE; | 533 virtual uint32 GetGLError() OVERRIDE; |
522 | 534 |
| 535 virtual uint32 GetTextureUploadCount() OVERRIDE; |
| 536 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; |
| 537 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; |
| 538 |
523 // Restores the current state to the user's settings. | 539 // Restores the current state to the user's settings. |
524 void RestoreCurrentFramebufferBindings(); | 540 void RestoreCurrentFramebufferBindings(); |
525 void RestoreCurrentRenderbufferBindings(); | 541 void RestoreCurrentRenderbufferBindings(); |
526 void RestoreCurrentTexture2DBindings(); | 542 void RestoreCurrentTexture2DBindings(); |
527 | 543 |
528 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. | 544 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. |
529 void ApplyDirtyState(); | 545 void ApplyDirtyState(); |
530 | 546 |
531 // Reapply the texture parameters to the given texture. | 547 // Reapply the texture parameters to the given texture. |
532 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info); | 548 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info); |
533 | 549 |
534 // These check the state of the currently bound framebuffer or the | 550 // These check the state of the currently bound framebuffer or the |
535 // backbuffer if no framebuffer is bound. | 551 // backbuffer if no framebuffer is bound. |
536 bool BoundFramebufferHasColorAttachmentWithAlpha(); | 552 bool BoundFramebufferHasColorAttachmentWithAlpha(); |
537 bool BoundFramebufferHasDepthAttachment(); | 553 bool BoundFramebufferHasDepthAttachment(); |
538 bool BoundFramebufferHasStencilAttachment(); | 554 bool BoundFramebufferHasStencilAttachment(); |
539 | 555 |
540 virtual error::ContextLostReason GetContextLostReason(); | 556 virtual error::ContextLostReason GetContextLostReason(); |
541 | 557 |
542 private: | 558 private: |
543 friend class ScopedGLErrorSuppressor; | 559 friend class ScopedGLErrorSuppressor; |
544 friend class ScopedResolvedFrameBufferBinder; | 560 friend class ScopedResolvedFrameBufferBinder; |
| 561 friend class ScopedTextureUploadTimer; |
545 friend class Texture; | 562 friend class Texture; |
546 friend class RenderBuffer; | 563 friend class RenderBuffer; |
547 friend class FrameBuffer; | 564 friend class FrameBuffer; |
548 | 565 |
549 // State associated with each texture unit. | 566 // State associated with each texture unit. |
550 struct TextureUnit { | 567 struct TextureUnit { |
551 TextureUnit() : bind_target(GL_TEXTURE_2D) { } | 568 TextureUnit() : bind_target(GL_TEXTURE_2D) { } |
552 | 569 |
553 // The last target that was bound to this texture unit. | 570 // The last target that was bound to this texture unit. |
554 GLenum bind_target; | 571 GLenum bind_target; |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 typedef std::vector<GLES2DecoderImpl*> ChildList; | 1595 typedef std::vector<GLES2DecoderImpl*> ChildList; |
1579 ChildList children_; | 1596 ChildList children_; |
1580 | 1597 |
1581 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; | 1598 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; |
1582 | 1599 |
1583 // Cached values of the currently assigned viewport dimensions. | 1600 // Cached values of the currently assigned viewport dimensions. |
1584 GLint viewport_x_, viewport_y_; | 1601 GLint viewport_x_, viewport_y_; |
1585 GLsizei viewport_width_, viewport_height_; | 1602 GLsizei viewport_width_, viewport_height_; |
1586 GLsizei viewport_max_width_, viewport_max_height_; | 1603 GLsizei viewport_max_width_, viewport_max_height_; |
1587 | 1604 |
| 1605 // Command buffer stats. |
| 1606 int texture_upload_count_; |
| 1607 base::TimeDelta total_texture_upload_time_; |
| 1608 base::TimeDelta total_processing_commands_time_; |
| 1609 |
1588 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 1610 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
1589 }; | 1611 }; |
1590 | 1612 |
1591 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder) | 1613 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder) |
1592 : decoder_(decoder) { | 1614 : decoder_(decoder) { |
1593 decoder_->CopyRealGLErrorsToWrapper(); | 1615 decoder_->CopyRealGLErrorsToWrapper(); |
1594 } | 1616 } |
1595 | 1617 |
1596 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { | 1618 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { |
1597 decoder_->ClearRealGLErrors(); | 1619 decoder_->ClearRealGLErrors(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1693 if (!resolve_and_bind_) | 1715 if (!resolve_and_bind_) |
1694 return; | 1716 return; |
1695 | 1717 |
1696 ScopedGLErrorSuppressor suppressor(decoder_); | 1718 ScopedGLErrorSuppressor suppressor(decoder_); |
1697 decoder_->RestoreCurrentFramebufferBindings(); | 1719 decoder_->RestoreCurrentFramebufferBindings(); |
1698 if (decoder_->enable_scissor_test_) { | 1720 if (decoder_->enable_scissor_test_) { |
1699 glEnable(GL_SCISSOR_TEST); | 1721 glEnable(GL_SCISSOR_TEST); |
1700 } | 1722 } |
1701 } | 1723 } |
1702 | 1724 |
| 1725 ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder) |
| 1726 : decoder_(decoder), |
| 1727 begin_time_(base::TimeTicks::HighResNow()) { |
| 1728 } |
| 1729 |
| 1730 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { |
| 1731 decoder_->texture_upload_count_++; |
| 1732 decoder_->total_texture_upload_time_ += |
| 1733 base::TimeTicks::HighResNow() - begin_time_; |
| 1734 } |
| 1735 |
1703 Texture::Texture(GLES2DecoderImpl* decoder) | 1736 Texture::Texture(GLES2DecoderImpl* decoder) |
1704 : decoder_(decoder), | 1737 : decoder_(decoder), |
1705 memory_tracker_(decoder->GetContextGroup()->memory_tracker(), | 1738 memory_tracker_(decoder->GetContextGroup()->memory_tracker(), |
1706 NULL, NULL), | 1739 NULL, NULL), |
1707 id_(0) { | 1740 id_(0) { |
1708 } | 1741 } |
1709 | 1742 |
1710 Texture::~Texture() { | 1743 Texture::~Texture() { |
1711 // This does not destroy the render texture because that would require that | 1744 // This does not destroy the render texture because that would require that |
1712 // the associated GL context was current. Just check that it was explicitly | 1745 // the associated GL context was current. Just check that it was explicitly |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 needs_mac_nvidia_driver_workaround_(false), | 2016 needs_mac_nvidia_driver_workaround_(false), |
1984 needs_glsl_built_in_function_emulation_(false), | 2017 needs_glsl_built_in_function_emulation_(false), |
1985 force_webgl_glsl_validation_(false), | 2018 force_webgl_glsl_validation_(false), |
1986 derivatives_explicitly_enabled_(false), | 2019 derivatives_explicitly_enabled_(false), |
1987 compile_shader_always_succeeds_(false), | 2020 compile_shader_always_succeeds_(false), |
1988 viewport_x_(0), | 2021 viewport_x_(0), |
1989 viewport_y_(0), | 2022 viewport_y_(0), |
1990 viewport_width_(0), | 2023 viewport_width_(0), |
1991 viewport_height_(0), | 2024 viewport_height_(0), |
1992 viewport_max_width_(0), | 2025 viewport_max_width_(0), |
1993 viewport_max_height_(0) { | 2026 viewport_max_height_(0), |
| 2027 texture_upload_count_(0) { |
1994 DCHECK(group); | 2028 DCHECK(group); |
1995 | 2029 |
1996 GLES2DecoderImpl* this_temp = this; | 2030 GLES2DecoderImpl* this_temp = this; |
1997 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp)); | 2031 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp)); |
1998 | 2032 |
1999 attrib_0_value_.v[0] = 0.0f; | 2033 attrib_0_value_.v[0] = 0.0f; |
2000 attrib_0_value_.v[1] = 0.0f; | 2034 attrib_0_value_.v[1] = 0.0f; |
2001 attrib_0_value_.v[2] = 0.0f; | 2035 attrib_0_value_.v[2] = 0.0f; |
2002 attrib_0_value_.v[3] = 1.0f; | 2036 attrib_0_value_.v[3] = 1.0f; |
2003 | 2037 |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2829 uint32* service_texture_id) { | 2863 uint32* service_texture_id) { |
2830 TextureManager::TextureInfo* texture = | 2864 TextureManager::TextureInfo* texture = |
2831 texture_manager()->GetTextureInfo(client_texture_id); | 2865 texture_manager()->GetTextureInfo(client_texture_id); |
2832 if (texture) { | 2866 if (texture) { |
2833 *service_texture_id = texture->service_id(); | 2867 *service_texture_id = texture->service_id(); |
2834 return true; | 2868 return true; |
2835 } | 2869 } |
2836 return false; | 2870 return false; |
2837 } | 2871 } |
2838 | 2872 |
| 2873 uint32 GLES2DecoderImpl::GetTextureUploadCount() { |
| 2874 return texture_upload_count_; |
| 2875 } |
| 2876 |
| 2877 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { |
| 2878 return total_texture_upload_time_; |
| 2879 } |
| 2880 |
| 2881 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { |
| 2882 return total_processing_commands_time_; |
| 2883 } |
| 2884 |
2839 void GLES2DecoderImpl::Destroy(bool have_context) { | 2885 void GLES2DecoderImpl::Destroy(bool have_context) { |
2840 DCHECK(!have_context || context_->IsCurrent(NULL)); | 2886 DCHECK(!have_context || context_->IsCurrent(NULL)); |
2841 | 2887 |
2842 ChildList children = children_; | 2888 ChildList children = children_; |
2843 for (ChildList::iterator it = children.begin(); it != children.end(); ++it) | 2889 for (ChildList::iterator it = children.begin(); it != children.end(); ++it) |
2844 (*it)->SetParent(NULL, 0); | 2890 (*it)->SetParent(NULL, 0); |
2845 DCHECK(children_.empty()); | 2891 DCHECK(children_.empty()); |
2846 SetParent(NULL, 0); | 2892 SetParent(NULL, 0); |
2847 | 2893 |
2848 // Unbind everything. | 2894 // Unbind everything. |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3206 | 3252 |
3207 // Decode command with its arguments, and call the corresponding GL function. | 3253 // Decode command with its arguments, and call the corresponding GL function. |
3208 // Note: args is a pointer to the command buffer. As such, it could be changed | 3254 // Note: args is a pointer to the command buffer. As such, it could be changed |
3209 // by a (malicious) client at any time, so if validation has to happen, it | 3255 // by a (malicious) client at any time, so if validation has to happen, it |
3210 // should operate on a copy of them. | 3256 // should operate on a copy of them. |
3211 error::Error GLES2DecoderImpl::DoCommand( | 3257 error::Error GLES2DecoderImpl::DoCommand( |
3212 unsigned int command, | 3258 unsigned int command, |
3213 unsigned int arg_count, | 3259 unsigned int arg_count, |
3214 const void* cmd_data) { | 3260 const void* cmd_data) { |
3215 error::Error result = error::kNoError; | 3261 error::Error result = error::kNoError; |
| 3262 base::TimeTicks begin_time(base::TimeTicks::HighResNow()); |
3216 if (log_commands()) { | 3263 if (log_commands()) { |
3217 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried | 3264 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried |
3218 // LOG(INFO), tried VLOG(1), no luck. | 3265 // LOG(INFO), tried VLOG(1), no luck. |
3219 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: " | 3266 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: " |
3220 << GetCommandName(command); | 3267 << GetCommandName(command); |
3221 } | 3268 } |
3222 unsigned int command_index = command - kStartPoint - 1; | 3269 unsigned int command_index = command - kStartPoint - 1; |
3223 if (command_index < arraysize(g_command_info)) { | 3270 if (command_index < arraysize(g_command_info)) { |
3224 const CommandInfo& info = g_command_info[command_index]; | 3271 const CommandInfo& info = g_command_info[command_index]; |
3225 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); | 3272 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); |
(...skipping 24 matching lines...) Expand all Loading... |
3250 } else { | 3297 } else { |
3251 result = error::kInvalidArguments; | 3298 result = error::kInvalidArguments; |
3252 } | 3299 } |
3253 } else { | 3300 } else { |
3254 result = DoCommonCommand(command, arg_count, cmd_data); | 3301 result = DoCommonCommand(command, arg_count, cmd_data); |
3255 } | 3302 } |
3256 if (result == error::kNoError && current_decoder_error_ != error::kNoError) { | 3303 if (result == error::kNoError && current_decoder_error_ != error::kNoError) { |
3257 result = current_decoder_error_; | 3304 result = current_decoder_error_; |
3258 current_decoder_error_ = error::kNoError; | 3305 current_decoder_error_ = error::kNoError; |
3259 } | 3306 } |
| 3307 total_processing_commands_time_ += |
| 3308 base::TimeTicks::HighResNow() - begin_time; |
3260 return result; | 3309 return result; |
3261 } | 3310 } |
3262 | 3311 |
3263 void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) { | 3312 void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) { |
3264 buffer_manager()->RemoveBufferInfo(client_id); | 3313 buffer_manager()->RemoveBufferInfo(client_id); |
3265 } | 3314 } |
3266 | 3315 |
3267 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { | 3316 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { |
3268 if (GetProgramInfo(client_id)) { | 3317 if (GetProgramInfo(client_id)) { |
3269 return false; | 3318 return false; |
(...skipping 4526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7796 GLsizei tex_width = 0; | 7845 GLsizei tex_width = 0; |
7797 GLsizei tex_height = 0; | 7846 GLsizei tex_height = 0; |
7798 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | 7847 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
7799 DCHECK(ok); | 7848 DCHECK(ok); |
7800 if (xoffset != 0 || yoffset != 0 || | 7849 if (xoffset != 0 || yoffset != 0 || |
7801 width != tex_width || height != tex_height) { | 7850 width != tex_width || height != tex_height) { |
7802 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | 7851 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
7803 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); | 7852 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); |
7804 return; | 7853 return; |
7805 } | 7854 } |
| 7855 ScopedTextureUploadTimer timer(this); |
7806 glTexSubImage2D( | 7856 glTexSubImage2D( |
7807 target, level, xoffset, yoffset, width, height, format, type, data); | 7857 target, level, xoffset, yoffset, width, height, format, type, data); |
7808 return; | 7858 return; |
7809 } | 7859 } |
7810 | 7860 |
7811 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { | 7861 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { |
| 7862 ScopedTextureUploadTimer timer(this); |
7812 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the | 7863 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
7813 // same as internal_foramt. If that changes we'll need to look them up. | 7864 // same as internal_foramt. If that changes we'll need to look them up. |
7814 WrappedTexImage2D( | 7865 WrappedTexImage2D( |
7815 target, level, format, width, height, 0, format, type, data); | 7866 target, level, format, width, height, 0, format, type, data); |
7816 } else { | 7867 } else { |
| 7868 ScopedTextureUploadTimer timer(this); |
7817 glTexSubImage2D( | 7869 glTexSubImage2D( |
7818 target, level, xoffset, yoffset, width, height, format, type, data); | 7870 target, level, xoffset, yoffset, width, height, format, type, data); |
7819 } | 7871 } |
7820 texture_manager()->SetLevelCleared(info, target, level); | 7872 texture_manager()->SetLevelCleared(info, target, level); |
7821 } | 7873 } |
7822 | 7874 |
7823 error::Error GLES2DecoderImpl::HandleTexSubImage2D( | 7875 error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
7824 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { | 7876 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { |
7825 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); | 7877 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); |
7826 GLboolean internal = static_cast<GLboolean>(c.internal); | 7878 GLboolean internal = static_cast<GLboolean>(c.internal); |
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9238 } | 9290 } |
9239 | 9291 |
9240 | 9292 |
9241 // Include the auto-generated part of this file. We split this because it means | 9293 // Include the auto-generated part of this file. We split this because it means |
9242 // we can easily edit the non-auto generated parts right here in this file | 9294 // we can easily edit the non-auto generated parts right here in this file |
9243 // instead of having to edit some template or the code generator. | 9295 // instead of having to edit some template or the code generator. |
9244 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9296 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
9245 | 9297 |
9246 } // namespace gles2 | 9298 } // namespace gles2 |
9247 } // namespace gpu | 9299 } // namespace gpu |
OLD | NEW |