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