diff options
author | dyen <dyen@chromium.org> | 2014-09-29 11:16:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-29 18:16:48 +0000 |
commit | cb0173111c9234f9718ed14cca6fbf45841deac7 (patch) | |
tree | e60d60113483d270dcf45f74a9212a28cb945e4e | |
parent | a4dcff92312b99670e9a19657f881b00a0404e69 (diff) | |
download | chromium_src-cb0173111c9234f9718ed14cca6fbf45841deac7.zip chromium_src-cb0173111c9234f9718ed14cca6fbf45841deac7.tar.gz chromium_src-cb0173111c9234f9718ed14cca6fbf45841deac7.tar.bz2 |
Modified GPU command signature hash to use a binary representation.
FrameBuffer::GetStatus() was spending most of the time doing in printf,
I've modified it to generate signatures using a binary representation
instead. Now most of the time is spent allocating memory. If further
optimization is necessary we can precalculate the signature size
as well.
BUG= https://code.google.com/p/chromium/issues/detail?id=338035
TEST= profile FrameBuffer::GetStatus()
Review URL: https://codereview.chromium.org/593233002
Cr-Commit-Position: refs/heads/master@{#297209}
-rw-r--r-- | gpu/command_buffer/service/framebuffer_manager.cc | 29 | ||||
-rw-r--r-- | gpu/command_buffer/service/framebuffer_manager.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/renderbuffer_manager.cc | 43 | ||||
-rw-r--r-- | gpu/command_buffer/service/renderbuffer_manager.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 106 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 2 |
6 files changed, 160 insertions, 22 deletions
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 4022b3d..b8026c00 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -113,6 +113,11 @@ class RenderbufferAttachment return renderbuffer_.get(); } + virtual size_t GetSignatureSize( + TextureManager* texture_manager) const OVERRIDE { + return renderbuffer_->GetSignatureSize(); + } + virtual void AddToSignature( TextureManager* texture_manager, std::string* signature) const OVERRIDE { DCHECK(signature); @@ -239,6 +244,11 @@ class TextureAttachment return (need & have) != 0; } + virtual size_t GetSignatureSize( + TextureManager* texture_manager) const OVERRIDE { + return texture_manager->GetSignatureSize(); + } + virtual void AddToSignature( TextureManager* texture_manager, std::string* signature) const OVERRIDE { DCHECK(signature); @@ -508,14 +518,25 @@ GLenum Framebuffer::GetStatus( // Check if we have this combo already. std::string signature; if (allow_framebuffer_combo_complete_map_) { - signature = base::StringPrintf("|FBO|target=%04x", target); + size_t signature_size = sizeof(target); + for (AttachmentMap::const_iterator it = attachments_.begin(); + it != attachments_.end(); ++it) { + Attachment* attachment = it->second.get(); + signature_size += sizeof(it->first) + + attachment->GetSignatureSize(texture_manager); + } + + signature.reserve(signature_size); + signature.append(reinterpret_cast<const char*>(&target), sizeof(target)); + for (AttachmentMap::const_iterator it = attachments_.begin(); it != attachments_.end(); ++it) { Attachment* attachment = it->second.get(); - signature += - base::StringPrintf("|Attachment|attachmentpoint=%04x", it->first); + signature.append(reinterpret_cast<const char*>(&it->first), + sizeof(it->first)); attachment->AddToSignature(texture_manager, &signature); } + DCHECK(signature.size() == signature_size); if (!framebuffer_combo_complete_map_) { framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); @@ -565,8 +586,6 @@ void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { draw_buffers_[i] = bufs[i]; } - - bool Framebuffer::HasAlphaMRT() const { for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) { if (draw_buffers_[i] != GL_NONE) { diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index b68ab7d..96bf7fe 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -47,6 +47,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0; virtual bool ValidForAttachmentType( GLenum attachment_type, uint32 max_color_attachments) = 0; + virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0; virtual void AddToSignature( TextureManager* texture_manager, std::string* signature) const = 0; virtual void OnWillRenderTo() const = 0; diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc index 03c37cb..ff8ae7b 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.cc +++ b/gpu/command_buffer/service/renderbuffer_manager.cc @@ -14,6 +14,30 @@ namespace gpu { namespace gles2 { +// This should contain everything to uniquely identify a Renderbuffer. +static const char RenderbufferTag[] = "|Renderbuffer|"; +struct RenderbufferSignature { + GLenum internal_format_; + GLsizei samples_; + GLsizei width_; + GLsizei height_; + + // Since we will be hashing this signature structure, the padding must be + // zero initialized. Although the C++11 specifications specify that this is + // true, we will use a constructor with a memset to further enforce it instead + // of relying on compilers adhering to this deep dark corner specification. + RenderbufferSignature(GLenum internal_format, + GLsizei samples, + GLsizei width, + GLsizei height) { + memset(this, 0, sizeof(RenderbufferSignature)); + internal_format_ = internal_format; + samples_ = samples; + width_ = width; + height_ = height; + } +}; + RenderbufferManager::RenderbufferManager( MemoryTracker* memory_tracker, GLint max_renderbuffer_size, @@ -45,12 +69,21 @@ size_t Renderbuffer::EstimatedSize() { return size; } -void Renderbuffer::AddToSignature( - std::string* signature) const { + +size_t Renderbuffer::GetSignatureSize() const { + return sizeof(RenderbufferTag) + sizeof(RenderbufferSignature); +} + +void Renderbuffer::AddToSignature(std::string* signature) const { DCHECK(signature); - *signature += base::StringPrintf( - "|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d", - internal_format_, samples_, width_, height_); + RenderbufferSignature signature_data(internal_format_, + samples_, + width_, + height_); + + signature->append(RenderbufferTag, sizeof(RenderbufferTag)); + signature->append(reinterpret_cast<const char*>(&signature_data), + sizeof(signature_data)); } Renderbuffer::Renderbuffer(RenderbufferManager* manager, diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h index 707d263..71f830a 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.h +++ b/gpu/command_buffer/service/renderbuffer_manager.h @@ -69,6 +69,7 @@ class GPU_EXPORT Renderbuffer size_t EstimatedSize(); + size_t GetSignatureSize() const; void AddToSignature(std::string* signature) const; private: diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 9dc5cc9..bfbdcb1 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -21,6 +21,72 @@ namespace gpu { namespace gles2 { +// This should contain everything to uniquely identify a Texture. +static const char TextureTag[] = "|Texture|"; +struct TextureSignature { + GLenum target_; + GLint level_; + GLenum min_filter_; + GLenum mag_filter_; + GLenum wrap_s_; + GLenum wrap_t_; + GLenum usage_; + GLenum internal_format_; + GLsizei width_; + GLsizei height_; + GLsizei depth_; + GLint border_; + GLenum format_; + GLenum type_; + bool has_image_; + bool can_render_; + bool can_render_to_; + bool npot_; + + // Since we will be hashing this signature structure, the padding must be + // zero initialized. Although the C++11 specifications specify that this is + // true, we will use a constructor with a memset to further enforce it instead + // of relying on compilers adhering to this deep dark corner specification. + TextureSignature(GLenum target, + GLint level, + GLenum min_filter, + GLenum mag_filter, + GLenum wrap_s, + GLenum wrap_t, + GLenum usage, + GLenum internal_format, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + bool has_image, + bool can_render, + bool can_render_to, + bool npot) { + memset(this, 0, sizeof(TextureSignature)); + target_ = target; + level_ = level; + min_filter_ = min_filter; + mag_filter_ = mag_filter; + wrap_s_ = wrap_s; + wrap_t_ = wrap_t; + usage_ = usage; + internal_format_ = internal_format; + width_ = width; + height_ = height; + depth_ = depth; + border_ = border; + format_ = format; + type_ = type; + has_image_ = has_image; + can_render_ = can_render; + can_render_to_ = can_render_to; + npot_ = npot; + } +}; + TextureManager::DestructionObserver::DestructionObserver() {} TextureManager::DestructionObserver::~DestructionObserver() {} @@ -218,20 +284,32 @@ void Texture::AddToSignature( level_infos_.size()); DCHECK_LT(static_cast<size_t>(level), level_infos_[face_index].size()); + const Texture::LevelInfo& info = level_infos_[face_index][level]; - *signature += base::StringPrintf( - "|Texture|target=%04x|level=%d|internal_format=%04x" - "|width=%d|height=%d|depth=%d|border=%d|format=%04x|type=%04x" - "|image=%d|canrender=%d|canrenderto=%d|npot_=%d" - "|min_filter=%04x|mag_filter=%04x|wrap_s=%04x|wrap_t=%04x" - "|usage=%04x", - target, level, info.internal_format, - info.width, info.height, info.depth, info.border, - info.format, info.type, info.image.get() != NULL, - CanRender(feature_info), CanRenderTo(), npot_, - min_filter_, mag_filter_, wrap_s_, wrap_t_, - usage_); + + TextureSignature signature_data(target, + level, + min_filter_, + mag_filter_, + wrap_s_, + wrap_t_, + usage_, + info.internal_format, + info.width, + info.height, + info.depth, + info.border, + info.format, + info.type, + info.image.get() != NULL, + CanRender(feature_info), + CanRenderTo(), + npot_); + + signature->append(TextureTag, sizeof(TextureTag)); + signature->append(reinterpret_cast<const char*>(&signature_data), + sizeof(signature_data)); } void Texture::SetMailboxManager(MailboxManager* mailbox_manager) { @@ -1267,6 +1345,10 @@ void TextureManager::SetLevelImage( ref->texture()->SetLevelImage(feature_info_.get(), target, level, image); } +size_t TextureManager::GetSignatureSize() const { + return sizeof(TextureTag) + sizeof(TextureSignature); +} + void TextureManager::AddToSignature( TextureRef* ref, GLenum target, diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 0d464c3..df00607 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -680,6 +680,8 @@ class GPU_EXPORT TextureManager { GLint level, gfx::GLImage* image); + size_t GetSignatureSize() const; + void AddToSignature( TextureRef* ref, GLenum target, |