summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyen <dyen@chromium.org>2014-09-29 11:16:20 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-29 18:16:48 +0000
commitcb0173111c9234f9718ed14cca6fbf45841deac7 (patch)
treee60d60113483d270dcf45f74a9212a28cb945e4e
parenta4dcff92312b99670e9a19657f881b00a0404e69 (diff)
downloadchromium_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.cc29
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h1
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.cc43
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.h1
-rw-r--r--gpu/command_buffer/service/texture_manager.cc106
-rw-r--r--gpu/command_buffer/service/texture_manager.h2
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,