Commit cb017311 authored by dyen's avatar dyen Committed by Commit bot

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}
parent a4dcff92
...@@ -113,6 +113,11 @@ class RenderbufferAttachment ...@@ -113,6 +113,11 @@ class RenderbufferAttachment
return renderbuffer_.get(); return renderbuffer_.get();
} }
virtual size_t GetSignatureSize(
TextureManager* texture_manager) const OVERRIDE {
return renderbuffer_->GetSignatureSize();
}
virtual void AddToSignature( virtual void AddToSignature(
TextureManager* texture_manager, std::string* signature) const OVERRIDE { TextureManager* texture_manager, std::string* signature) const OVERRIDE {
DCHECK(signature); DCHECK(signature);
...@@ -239,6 +244,11 @@ class TextureAttachment ...@@ -239,6 +244,11 @@ class TextureAttachment
return (need & have) != 0; return (need & have) != 0;
} }
virtual size_t GetSignatureSize(
TextureManager* texture_manager) const OVERRIDE {
return texture_manager->GetSignatureSize();
}
virtual void AddToSignature( virtual void AddToSignature(
TextureManager* texture_manager, std::string* signature) const OVERRIDE { TextureManager* texture_manager, std::string* signature) const OVERRIDE {
DCHECK(signature); DCHECK(signature);
...@@ -508,14 +518,25 @@ GLenum Framebuffer::GetStatus( ...@@ -508,14 +518,25 @@ GLenum Framebuffer::GetStatus(
// Check if we have this combo already. // Check if we have this combo already.
std::string signature; std::string signature;
if (allow_framebuffer_combo_complete_map_) { 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(); for (AttachmentMap::const_iterator it = attachments_.begin();
it != attachments_.end(); ++it) { it != attachments_.end(); ++it) {
Attachment* attachment = it->second.get(); Attachment* attachment = it->second.get();
signature += signature.append(reinterpret_cast<const char*>(&it->first),
base::StringPrintf("|Attachment|attachmentpoint=%04x", it->first); sizeof(it->first));
attachment->AddToSignature(texture_manager, &signature); attachment->AddToSignature(texture_manager, &signature);
} }
DCHECK(signature.size() == signature_size);
if (!framebuffer_combo_complete_map_) { if (!framebuffer_combo_complete_map_) {
framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap(); framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap();
...@@ -565,8 +586,6 @@ void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) { ...@@ -565,8 +586,6 @@ void Framebuffer::SetDrawBuffers(GLsizei n, const GLenum* bufs) {
draw_buffers_[i] = bufs[i]; draw_buffers_[i] = bufs[i];
} }
bool Framebuffer::HasAlphaMRT() const { bool Framebuffer::HasAlphaMRT() const {
for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) { for (uint32 i = 0; i < manager_->max_draw_buffers_; ++i) {
if (draw_buffers_[i] != GL_NONE) { if (draw_buffers_[i] != GL_NONE) {
......
...@@ -47,6 +47,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { ...@@ -47,6 +47,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0; virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0;
virtual bool ValidForAttachmentType( virtual bool ValidForAttachmentType(
GLenum attachment_type, uint32 max_color_attachments) = 0; GLenum attachment_type, uint32 max_color_attachments) = 0;
virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
virtual void AddToSignature( virtual void AddToSignature(
TextureManager* texture_manager, std::string* signature) const = 0; TextureManager* texture_manager, std::string* signature) const = 0;
virtual void OnWillRenderTo() const = 0; virtual void OnWillRenderTo() const = 0;
......
...@@ -14,6 +14,30 @@ ...@@ -14,6 +14,30 @@
namespace gpu { namespace gpu {
namespace gles2 { 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( RenderbufferManager::RenderbufferManager(
MemoryTracker* memory_tracker, MemoryTracker* memory_tracker,
GLint max_renderbuffer_size, GLint max_renderbuffer_size,
...@@ -45,12 +69,21 @@ size_t Renderbuffer::EstimatedSize() { ...@@ -45,12 +69,21 @@ size_t Renderbuffer::EstimatedSize() {
return size; 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); DCHECK(signature);
*signature += base::StringPrintf( RenderbufferSignature signature_data(internal_format_,
"|Renderbuffer|internal_format=%04x|samples=%d|width=%d|height=%d", samples_,
internal_format_, samples_, width_, height_); width_,
height_);
signature->append(RenderbufferTag, sizeof(RenderbufferTag));
signature->append(reinterpret_cast<const char*>(&signature_data),
sizeof(signature_data));
} }
Renderbuffer::Renderbuffer(RenderbufferManager* manager, Renderbuffer::Renderbuffer(RenderbufferManager* manager,
......
...@@ -69,6 +69,7 @@ class GPU_EXPORT Renderbuffer ...@@ -69,6 +69,7 @@ class GPU_EXPORT Renderbuffer
size_t EstimatedSize(); size_t EstimatedSize();
size_t GetSignatureSize() const;
void AddToSignature(std::string* signature) const; void AddToSignature(std::string* signature) const;
private: private:
......
...@@ -21,6 +21,72 @@ ...@@ -21,6 +21,72 @@
namespace gpu { namespace gpu {
namespace gles2 { 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() {}
TextureManager::DestructionObserver::~DestructionObserver() {} TextureManager::DestructionObserver::~DestructionObserver() {}
...@@ -218,20 +284,32 @@ void Texture::AddToSignature( ...@@ -218,20 +284,32 @@ void Texture::AddToSignature(
level_infos_.size()); level_infos_.size());
DCHECK_LT(static_cast<size_t>(level), DCHECK_LT(static_cast<size_t>(level),
level_infos_[face_index].size()); level_infos_[face_index].size());
const Texture::LevelInfo& info = const Texture::LevelInfo& info =
level_infos_[face_index][level]; level_infos_[face_index][level];
*signature += base::StringPrintf(
"|Texture|target=%04x|level=%d|internal_format=%04x" TextureSignature signature_data(target,
"|width=%d|height=%d|depth=%d|border=%d|format=%04x|type=%04x" level,
"|image=%d|canrender=%d|canrenderto=%d|npot_=%d" min_filter_,
"|min_filter=%04x|mag_filter=%04x|wrap_s=%04x|wrap_t=%04x" mag_filter_,
"|usage=%04x", wrap_s_,
target, level, info.internal_format, wrap_t_,
info.width, info.height, info.depth, info.border, usage_,
info.format, info.type, info.image.get() != NULL, info.internal_format,
CanRender(feature_info), CanRenderTo(), npot_, info.width,
min_filter_, mag_filter_, wrap_s_, wrap_t_, info.height,
usage_); 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) { void Texture::SetMailboxManager(MailboxManager* mailbox_manager) {
...@@ -1267,6 +1345,10 @@ void TextureManager::SetLevelImage( ...@@ -1267,6 +1345,10 @@ void TextureManager::SetLevelImage(
ref->texture()->SetLevelImage(feature_info_.get(), target, level, image); ref->texture()->SetLevelImage(feature_info_.get(), target, level, image);
} }
size_t TextureManager::GetSignatureSize() const {
return sizeof(TextureTag) + sizeof(TextureSignature);
}
void TextureManager::AddToSignature( void TextureManager::AddToSignature(
TextureRef* ref, TextureRef* ref,
GLenum target, GLenum target,
......
...@@ -680,6 +680,8 @@ class GPU_EXPORT TextureManager { ...@@ -680,6 +680,8 @@ class GPU_EXPORT TextureManager {
GLint level, GLint level,
gfx::GLImage* image); gfx::GLImage* image);
size_t GetSignatureSize() const;
void AddToSignature( void AddToSignature(
TextureRef* ref, TextureRef* ref,
GLenum target, GLenum target,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment