summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-09 05:50:20 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-09 05:50:20 +0000
commit73276523fc5c0d811beade0a6d010727cdea4f01 (patch)
treea8ac23dc923e8c86a73f62bc3f45dbca32021282 /gpu
parent0985a93e3f15397f69d14359201f22198af5376b (diff)
downloadchromium_src-73276523fc5c0d811beade0a6d010727cdea4f01.zip
chromium_src-73276523fc5c0d811beade0a6d010727cdea4f01.tar.gz
chromium_src-73276523fc5c0d811beade0a6d010727cdea4f01.tar.bz2
cache fbo combos
BUG=159991 Review URL: https://chromiumcodereview.appspot.com/11365145 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc51
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h12
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc80
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc8
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc1
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.cc10
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager.h3
-rw-r--r--gpu/command_buffer/service/renderbuffer_manager_unittest.cc60
-rw-r--r--gpu/command_buffer/service/texture_manager.cc37
-rw-r--r--gpu/command_buffer/service/texture_manager.h12
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc115
11 files changed, 386 insertions, 3 deletions
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 0dab745..0d73f96 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -4,11 +4,22 @@
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "base/logging.h"
+#include "base/stringprintf.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "ui/gl/gl_bindings.h"
namespace gpu {
namespace gles2 {
+FramebufferManager::FramebufferInfo::FramebufferComboCompleteMap*
+ FramebufferManager::FramebufferInfo::framebuffer_combo_complete_map_;
+
+void FramebufferManager::FramebufferInfo::ClearFramebufferCompleteComboMap() {
+ if (framebuffer_combo_complete_map_) {
+ framebuffer_combo_complete_map_->clear();
+ }
+}
+
class RenderbufferAttachment
: public FramebufferManager::FramebufferInfo::Attachment {
public:
@@ -72,6 +83,12 @@ class RenderbufferAttachment
return renderbuffer_.get();
}
+ virtual void AddToSignature(
+ TextureManager* texture_manager, std::string* signature) const OVERRIDE {
+ DCHECK(signature);
+ renderbuffer_->AddToSignature(signature);
+ }
+
protected:
virtual ~RenderbufferAttachment() { }
@@ -160,6 +177,12 @@ class TextureAttachment
return (need & have) != 0;
}
+ virtual void AddToSignature(
+ TextureManager* texture_manager, std::string* signature) const OVERRIDE {
+ DCHECK(signature);
+ texture_manager->AddToSignature(texture_, target_, level_, signature);
+ }
+
protected:
virtual ~TextureAttachment() {}
@@ -317,6 +340,34 @@ GLenum FramebufferManager::FramebufferInfo::IsPossiblyComplete() const {
return GL_FRAMEBUFFER_COMPLETE;
}
+GLenum FramebufferManager::FramebufferInfo::GetStatus(
+ TextureManager* texture_manager, GLenum target) const {
+ // Check if we have this combo already.
+ std::string signature(base::StringPrintf("|FBO|target=%04x", target));
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ Attachment* attachment = it->second;
+ signature += base::StringPrintf(
+ "|Attachment|attachmentpoint=%04x", it->first);
+ attachment->AddToSignature(texture_manager, &signature);
+ }
+
+ if (!framebuffer_combo_complete_map_) {
+ framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap();
+ }
+
+ FramebufferComboCompleteMap::const_iterator it =
+ framebuffer_combo_complete_map_->find(signature);
+ if (it != framebuffer_combo_complete_map_->end()) {
+ return GL_FRAMEBUFFER_COMPLETE;
+ }
+ GLenum result = glCheckFramebufferStatusEXT(target);
+ if (result == GL_FRAMEBUFFER_COMPLETE) {
+ framebuffer_combo_complete_map_->insert(std::make_pair(signature, true));
+ }
+ return result;
+}
+
bool FramebufferManager::FramebufferInfo::IsCleared() const {
// are all the attachments cleaared?
for (AttachmentMap::const_iterator it = attachments_.begin();
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index cc2cefb..80cf428 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -44,6 +44,8 @@ class GPU_EXPORT FramebufferManager {
virtual bool CanRenderTo() const = 0;
virtual void DetachFromFramebuffer() = 0;
virtual bool ValidForAttachmentType(GLenum attachment_type) = 0;
+ virtual void AddToSignature(
+ TextureManager* texture_manager, std::string* signature) const = 0;
protected:
friend class base::RefCounted<Attachment>;
@@ -103,9 +105,14 @@ class GPU_EXPORT FramebufferManager {
// means it passed our tests.
GLenum IsPossiblyComplete() const;
+ // Implements optimized glGetFramebufferStatus.
+ GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
+
// Check all attachments are cleared
bool IsCleared() const;
+ static void ClearFramebufferCompleteComboMap();
+
private:
friend class FramebufferManager;
friend class base::RefCounted<FramebufferInfo>;
@@ -144,6 +151,11 @@ class GPU_EXPORT FramebufferManager {
typedef base::hash_map<GLenum, Attachment::Ref> AttachmentMap;
AttachmentMap attachments_;
+ // A map of successful frame buffer combos. If it's in the map
+ // it should be FRAMEBUFFER_COMPLETE.
+ typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
+ static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
+
DISALLOW_COPY_AND_ASSIGN(FramebufferInfo);
};
diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index 7727ebe..31261ea 100644
--- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -8,6 +8,8 @@
#include "gpu/command_buffer/common/gl_mock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::Return;
+
namespace gpu {
namespace gles2 {
@@ -630,6 +632,84 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
EXPECT_FALSE(manager_.IsComplete(info_));
}
+TEST_F(FramebufferInfoTest, Gettatus) {
+ const GLuint kRenderbufferClient1Id = 33;
+ const GLuint kRenderbufferService1Id = 333;
+ const GLuint kTextureClient2Id = 34;
+ const GLuint kTextureService2Id = 334;
+ const GLenum kTarget1 = GL_TEXTURE_2D;
+ const GLint kLevel1 = 0;
+
+ renderbuffer_manager_.CreateRenderbufferInfo(
+ kRenderbufferClient1Id, kRenderbufferService1Id);
+ RenderbufferManager::RenderbufferInfo* rb_info1 =
+ renderbuffer_manager_.GetRenderbufferInfo(kRenderbufferClient1Id);
+ ASSERT_TRUE(rb_info1 != NULL);
+ texture_manager_.CreateTextureInfo(kTextureClient2Id, kTextureService2Id);
+ TextureManager::TextureInfo::Ref tex_info2 =
+ texture_manager_.GetTextureInfo(kTextureClient2Id);
+ ASSERT_TRUE(tex_info2 != NULL);
+ texture_manager_.SetInfoTarget(tex_info2, GL_TEXTURE_2D);
+
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ info_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+
+ // Check a second call for the same type does not call anything
+ info_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+
+ // Check changing the attachments calls CheckFramebufferStatus.
+ info_->AttachTexture(GL_COLOR_ATTACHMENT0, tex_info2, kTarget1, kLevel1);
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ info_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+
+ // Check a second call for the same type does not call anything.
+ info_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+
+ // Check a second call with a different target calls CheckFramebufferStatus.
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check a second call for the same type does not call anything.
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check adding another attachment calls CheckFramebufferStatus.
+ info_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, rb_info1);
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check a second call for the same type does not call anything.
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check changing the format calls CheckFramebuffferStatus.
+ texture_manager_.SetParameter(tex_info2, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+
+ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check since it did not return FRAMEBUFFER_COMPLETE that it calls
+ // CheckFramebufferStatus
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check putting it back does not call CheckFramebufferStatus.
+ texture_manager_.SetParameter(tex_info2, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+
+ // Check Unbinding does not call CheckFramebufferStatus
+ info_->UnbindRenderbuffer(GL_RENDERBUFFER, rb_info1);
+ info_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 6b2194f..075bb6b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2615,7 +2615,8 @@ bool GLES2DecoderImpl::CheckFramebufferValid(
texture_manager()->HaveUnclearedMips()) {
if (!framebuffer->IsCleared()) {
// Can we clear them?
- if (glCheckFramebufferStatusEXT(target) != GL_FRAMEBUFFER_COMPLETE) {
+ if (framebuffer->GetStatus(texture_manager(), target) !=
+ GL_FRAMEBUFFER_COMPLETE) {
SetGLError(
GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
"framebuffer incomplete (clear)");
@@ -2626,7 +2627,8 @@ bool GLES2DecoderImpl::CheckFramebufferValid(
}
if (!framebuffer_manager()->IsComplete(framebuffer)) {
- if (glCheckFramebufferStatusEXT(target) != GL_FRAMEBUFFER_COMPLETE) {
+ if (framebuffer->GetStatus(texture_manager(), target) !=
+ GL_FRAMEBUFFER_COMPLETE) {
SetGLError(
GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
"framebuffer incomplete (check)");
@@ -4371,7 +4373,7 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
if (completeness != GL_FRAMEBUFFER_COMPLETE) {
return completeness;
}
- return glCheckFramebufferStatusEXT(target);
+ return framebuffer->GetStatus(texture_manager(), target);
}
void GLES2DecoderImpl::DoFramebufferTexture2D(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 83c7e44..1b0697a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -84,6 +84,7 @@ void GLES2DecoderTestBase::InitDecoder(
bool request_depth,
bool request_stencil,
bool bind_generates_resource) {
+ FramebufferManager::FramebufferInfo::ClearFramebufferCompleteComboMap();
gl_.reset(new StrictMock<MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
group_ = ContextGroup::Ref(new ContextGroup(NULL,
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc
index 7169027..496b746 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -5,6 +5,7 @@
#include "gpu/command_buffer/service/renderbuffer_manager.h"
#include "base/logging.h"
#include "base/debug/trace_event.h"
+#include "base/stringprintf.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/memory_tracking.h"
@@ -40,6 +41,14 @@ size_t RenderbufferManager::RenderbufferInfo::EstimatedSize() {
GLES2Util::RenderbufferBytesPerPixel(internal_format_);
}
+void RenderbufferManager::RenderbufferInfo::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_);
+}
+
RenderbufferManager::RenderbufferInfo::~RenderbufferInfo() {
if (manager_) {
if (manager_->have_context_) {
@@ -51,6 +60,7 @@ RenderbufferManager::RenderbufferInfo::~RenderbufferInfo() {
}
}
+
void RenderbufferManager::UpdateMemRepresented() {
renderbuffer_memory_tracker_->UpdateMemRepresented(mem_represented_);
}
diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h
index c562185..2edfc34 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.h
+++ b/gpu/command_buffer/service/renderbuffer_manager.h
@@ -5,6 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
+#include <string>
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
@@ -79,6 +80,8 @@ class GPU_EXPORT RenderbufferManager {
size_t EstimatedSize();
+ void AddToSignature(std::string* signature) const;
+
private:
friend class RenderbufferManager;
friend class base::RefCounted<RenderbufferInfo>;
diff --git a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
index 8e13ac9..1ac8bcb 100644
--- a/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager_unittest.cc
@@ -4,6 +4,7 @@
#include "gpu/command_buffer/service/renderbuffer_manager.h"
+#include <set>
#include "gpu/command_buffer/common/gl_mock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -165,6 +166,65 @@ TEST_F(RenderbufferManagerTest, UseDeletedRenderbufferInfo) {
info1 = NULL;
}
+namespace {
+
+bool InSet(std::set<std::string>* string_set, const std::string& str) {
+ std::pair<std::set<std::string>::iterator, bool> result =
+ string_set->insert(str);
+ return !result.second;
+}
+
+} // anonymous namespace
+
+TEST_F(RenderbufferManagerTest, AddToSignature) {
+ const GLuint kClient1Id = 1;
+ const GLuint kService1Id = 11;
+ manager_.CreateRenderbufferInfo(kClient1Id, kService1Id);
+ RenderbufferManager::RenderbufferInfo::Ref info1(
+ manager_.GetRenderbufferInfo(kClient1Id));
+ ASSERT_TRUE(info1 != NULL);
+ const GLsizei kSamples = 4;
+ const GLenum kFormat = GL_RGBA4;
+ const GLsizei kWidth = 128;
+ const GLsizei kHeight = 64;
+ manager_.SetInfo(info1, kSamples, kFormat, kWidth, kHeight);
+ std::string signature1;
+ std::string signature2;
+ info1->AddToSignature(&signature1);
+
+ std::set<std::string> string_set;
+ EXPECT_FALSE(InSet(&string_set, signature1));
+
+ // change things and see that the signatures change.
+ manager_.SetInfo(info1, kSamples + 1, kFormat, kWidth, kHeight);
+ info1->AddToSignature(&signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetInfo(info1, kSamples, kFormat + 1, kWidth, kHeight);
+ signature2.clear();
+ info1->AddToSignature(&signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetInfo(info1, kSamples, kFormat, kWidth + 1, kHeight);
+ signature2.clear();
+ info1->AddToSignature(&signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetInfo(info1, kSamples, kFormat, kWidth, kHeight + 1);
+ signature2.clear();
+ info1->AddToSignature(&signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ // put it back to the same and it should be the same.
+ manager_.SetInfo(info1, kSamples, kFormat, kWidth, kHeight);
+ signature2.clear();
+ info1->AddToSignature(&signature2);
+ EXPECT_EQ(signature1, signature2);
+
+ // Check the set was acutally getting different signatures.
+ EXPECT_EQ(5u, string_set.size());
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 3206281..8573f33 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -4,6 +4,7 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "base/bits.h"
+#include "base/stringprintf.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
@@ -180,6 +181,34 @@ bool TextureManager::TextureInfo::CanRender(
}
}
+void TextureManager::TextureInfo::AddToSignature(
+ const FeatureInfo* feature_info,
+ GLenum target,
+ GLint level,
+ std::string* signature) const {
+ DCHECK(feature_info);
+ DCHECK(signature);
+ DCHECK_GE(level, 0);
+ DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
+ level_infos_.size());
+ DCHECK_LT(static_cast<size_t>(level),
+ level_infos_[GLTargetToFaceIndex(target)].size());
+ const TextureInfo::LevelInfo& info =
+ level_infos_[GLTargetToFaceIndex(target)][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_);
+}
+
bool TextureManager::TextureInfo::MarkMipmapsGenerated(
const FeatureInfo* feature_info) {
if (!CanGenerateMipmaps(feature_info)) {
@@ -1129,5 +1158,13 @@ void TextureManager::SetLevelImage(
}
}
+void TextureManager::AddToSignature(
+ TextureInfo* info,
+ GLenum target,
+ GLint level,
+ std::string* signature) const {
+ info->AddToSignature(feature_info_.get(), target, level, signature);
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index ef9e020..ed4c8c9 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -5,6 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
+#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/hash_tables.h"
@@ -279,6 +280,11 @@ class GPU_EXPORT TextureManager {
GLint level,
gfx::GLImage* image);
+ // Appends a signature for the given level.
+ void AddToSignature(
+ const FeatureInfo* feature_info,
+ GLenum target, GLint level, std::string* signature) const;
+
// Info about each face and level of texture.
std::vector<std::vector<LevelInfo> > level_infos_;
@@ -510,6 +516,12 @@ class GPU_EXPORT TextureManager {
GLint level,
gfx::GLImage* image);
+ void AddToSignature(
+ TextureInfo* info,
+ GLenum target,
+ GLint level,
+ std::string* signature) const;
+
private:
// Helper for Initialize().
TextureInfo::Ref CreateDefaultAndBlackTextures(
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 487bde7..da56669 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -1019,6 +1019,121 @@ TEST_F(TextureInfoTest, GetLevelImage) {
EXPECT_TRUE(info_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
}
+namespace {
+
+bool InSet(std::set<std::string>* string_set, const std::string& str) {
+ std::pair<std::set<std::string>::iterator, bool> result =
+ string_set->insert(str);
+ return !result.second;
+}
+
+} // anonymous namespace
+
+TEST_F(TextureInfoTest, AddToSignature) {
+ manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+ std::string signature1;
+ std::string signature2;
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature1);
+
+ std::set<std::string> string_set;
+ EXPECT_FALSE(InSet(&string_set, signature1));
+
+ // check changing 1 thing makes a different signature.
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 4, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ // check putting it back makes the same signature.
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_EQ(signature1, signature2);
+
+ // Check setting cleared status does not change signature.
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_EQ(signature1, signature2);
+
+ // Check changing other settings changes signature.
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_FLOAT,
+ false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ // put it back
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ false);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_EQ(signature1, signature2);
+
+ // check changing parameters changes signature.
+ manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ manager_.SetParameter(info_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetParameter(info_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ manager_.SetParameter(info_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ manager_.SetParameter(info_, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ manager_.SetParameter(info_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_FALSE(InSet(&string_set, signature2));
+
+ // Check putting it back genenerates the same signature
+ manager_.SetParameter(info_, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ signature2.clear();
+ manager_.AddToSignature(info_, GL_TEXTURE_2D, 1, &signature2);
+ EXPECT_EQ(signature1, signature2);
+
+ // Check the set was acutally getting different signatures.
+ EXPECT_EQ(11u, string_set.size());
+}
+
} // namespace gles2
} // namespace gpu