diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 03:31:08 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 03:31:08 +0000 |
commit | c32ff8bbd61875d2ab6b291fed12ccdfc2adad72 (patch) | |
tree | 320c702ae50965e62b2adb0e507a9ff15e008b44 /gpu/command_buffer | |
parent | cca88c33afbeccf2af7e1dfb2bb96815abbd0511 (diff) | |
download | chromium_src-c32ff8bbd61875d2ab6b291fed12ccdfc2adad72.zip chromium_src-c32ff8bbd61875d2ab6b291fed12ccdfc2adad72.tar.gz chromium_src-c32ff8bbd61875d2ab6b291fed12ccdfc2adad72.tar.bz2 |
Fix a few issues with texture memory tracking.
TEST=unit tests
BUG=79762
R=apatrick@chromium.org
Review URL: http://codereview.chromium.org/9027014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115680 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 48 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 37 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager_unittest.cc | 59 |
3 files changed, 85 insertions, 59 deletions
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index b9789b9..1ee041f 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -62,8 +62,9 @@ TextureManager::~TextureManager() { void TextureManager::Destroy(bool have_context) { while (!texture_infos_.empty()) { + TextureInfo* info = texture_infos_.begin()->second; + mem_represented_ -= info->estimated_size(); if (have_context) { - TextureInfo* info = texture_infos_.begin()->second; if (!info->IsDeleted() && info->owned_) { GLuint service_id = info->service_id(); glDeleteTextures(1, &service_id); @@ -72,15 +73,20 @@ void TextureManager::Destroy(bool have_context) { } texture_infos_.erase(texture_infos_.begin()); } + GLuint ids[kNumDefaultTextures * 2]; + for (int ii = 0; ii < kNumDefaultTextures; ++ii) { + TextureInfo* texture = default_textures_[ii].get(); + mem_represented_ -= texture ? texture->estimated_size() : 0; + ids[ii * 2 + 0] = texture ? texture->service_id() : 0; + ids[ii * 2 + 1] = black_texture_ids_[ii]; + } + if (have_context) { - GLuint ids[] = { - black_2d_texture_id_, - black_cube_texture_id_, - default_texture_2d_->service_id(), - default_texture_cube_map_->service_id(), - }; glDeleteTextures(arraysize(ids), ids); } + + DCHECK_EQ(0u, mem_represented_); + UpdateMemRepresented(); } bool TextureManager::TextureInfo::CanRender( @@ -552,11 +558,10 @@ TextureManager::TextureManager( num_unsafe_textures_(0), num_uncleared_mips_(0), mem_represented_(0), - last_reported_mem_represented_(1), - black_2d_texture_id_(0), - black_cube_texture_id_(0), - black_oes_external_texture_id_(0), - black_arb_texture_rectangle_id_(0) { + last_reported_mem_represented_(1) { + for (int ii = 0; ii < kNumDefaultTextures; ++ii) { + black_texture_ids_[ii] = 0; + } } void TextureManager::UpdateMemRepresented() { @@ -574,22 +579,21 @@ bool TextureManager::Initialize(const FeatureInfo* feature_info) { // texture because we simulate non shared resources on top of shared // resources and all contexts that share resource share the same default // texture. - - default_texture_2d_ = CreateDefaultAndBlackTextures( - feature_info, GL_TEXTURE_2D, &black_2d_texture_id_); - default_texture_cube_map_ = CreateDefaultAndBlackTextures( - feature_info, GL_TEXTURE_CUBE_MAP, &black_cube_texture_id_); + default_textures_[kTexture2D] = CreateDefaultAndBlackTextures( + feature_info, GL_TEXTURE_2D, &black_texture_ids_[kTexture2D]); + default_textures_[kCubeMap] = CreateDefaultAndBlackTextures( + feature_info, GL_TEXTURE_CUBE_MAP, &black_texture_ids_[kCubeMap]); if (feature_info->feature_flags().oes_egl_image_external) { - default_texture_external_oes_ = CreateDefaultAndBlackTextures( + default_textures_[kExternalOES] = CreateDefaultAndBlackTextures( feature_info, GL_TEXTURE_EXTERNAL_OES, - &black_oes_external_texture_id_); + &black_texture_ids_[kExternalOES]); } if (feature_info->feature_flags().arb_texture_rectangle) { - default_texture_rectangle_arb_ = CreateDefaultAndBlackTextures( + default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures( feature_info, GL_TEXTURE_RECTANGLE_ARB, - &black_arb_texture_rectangle_id_); + &black_texture_ids_[kRectangleARB]); } return true; @@ -879,7 +883,7 @@ void TextureManager::RemoveTextureInfo( // TODO(gman): Unforunately the memory does not get de-allocated here as // resources are ref counted but for now there's no easy way to track this // info past this point. - mem_represented_ += info->estimated_size(); + mem_represented_ -= info->estimated_size(); UpdateMemRepresented(); texture_infos_.erase(it); } diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 6226f92..b98014e 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -25,6 +25,14 @@ class GLES2Decoder; // shared by multiple GLES2Decoders. class TextureManager { public: + enum DefaultAndBlackTextures { + kTexture2D, + kCubeMap, + kExternalOES, + kRectangleARB, + kNumDefaultTextures + }; + // Info about Textures currently in the system. class TextureInfo : public base::RefCounted<TextureInfo> { public: @@ -49,7 +57,8 @@ class TextureManager { framebuffer_attachment_count_(0), owned_(true), stream_texture_(false), - immutable_(false) { + immutable_(false), + estimated_size_(0) { } GLenum min_filter() const { @@ -444,13 +453,13 @@ class TextureManager { TextureInfo* GetDefaultTextureInfo(GLenum target) { switch (target) { case GL_TEXTURE_2D: - return default_texture_2d_; + return default_textures_[kTexture2D]; case GL_TEXTURE_CUBE_MAP: - return default_texture_cube_map_; + return default_textures_[kCubeMap]; case GL_TEXTURE_EXTERNAL_OES: - return default_texture_external_oes_; + return default_textures_[kExternalOES]; case GL_TEXTURE_RECTANGLE_ARB: - return default_texture_rectangle_arb_; + return default_textures_[kRectangleARB]; default: NOTREACHED(); return NULL; @@ -472,13 +481,13 @@ class TextureManager { GLuint black_texture_id(GLenum target) const { switch (target) { case GL_SAMPLER_2D: - return black_2d_texture_id_; + return black_texture_ids_[kTexture2D]; case GL_SAMPLER_CUBE: - return black_cube_texture_id_; + return black_texture_ids_[kCubeMap]; case GL_SAMPLER_EXTERNAL_OES: - return black_oes_external_texture_id_; + return black_texture_ids_[kExternalOES]; case GL_SAMPLER_2D_RECT_ARB: - return black_arb_texture_rectangle_id_; + return black_texture_ids_[kRectangleARB]; default: NOTREACHED(); return 0; @@ -513,16 +522,10 @@ class TextureManager { // Black (0,0,0,1) textures for when non-renderable textures are used. // NOTE: There is no corresponding TextureInfo for these textures. // TextureInfos are only for textures the client side can access. - GLuint black_2d_texture_id_; - GLuint black_cube_texture_id_; - GLuint black_oes_external_texture_id_; - GLuint black_arb_texture_rectangle_id_; + GLuint black_texture_ids_[kNumDefaultTextures]; // The default textures for each target (texture name = 0) - TextureInfo::Ref default_texture_2d_; - TextureInfo::Ref default_texture_cube_map_; - TextureInfo::Ref default_texture_external_oes_; - TextureInfo::Ref default_texture_rectangle_arb_; + TextureInfo::Ref default_textures_[kNumDefaultTextures]; DISALLOW_COPY_AND_ASSIGN(TextureManager); }; diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 9e911c6..3144665 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -127,59 +127,67 @@ TEST_F(TextureManagerTest, SetParameter) { TEST_F(TextureManagerTest, TextureUsageExt) { TestHelper::SetupTextureManagerInitExpectations(gl_.get(), "GL_ANGLE_texture_usage"); - manager_.Initialize(&feature_info_); + TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize); + manager.Initialize(&feature_info_); const GLuint kClient1Id = 1; const GLuint kService1Id = 11; // Check we can create texture. - manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); + manager.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); // Check texture got created. - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - EXPECT_TRUE(manager_.SetParameter( + EXPECT_TRUE(manager.SetParameter( &feature_info_, info, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_ATTACHMENT_ANGLE), info->usage()); + manager.Destroy(false); } TEST_F(TextureManagerTest, Destroy) { const GLuint kClient1Id = 1; const GLuint kService1Id = 11; + TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); + TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize); + manager.Initialize(&feature_info_); // Check we can create texture. - manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); + manager.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); // Check texture got created. - TextureManager::TextureInfo* info1 = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info1 = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info1 != NULL); EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) .Times(1) .RetiresOnSaturation(); - EXPECT_CALL(*gl_, DeleteTextures(4, _)) + EXPECT_CALL(*gl_, DeleteTextures(8, _)) .Times(1) .RetiresOnSaturation(); - manager_.Destroy(true); + manager.Destroy(true); // Check that resources got freed. - info1 = manager_.GetTextureInfo(kClient1Id); + info1 = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info1 == NULL); } TEST_F(TextureManagerTest, DestroyUnowned) { const GLuint kClient1Id = 1; const GLuint kService1Id = 11; + TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); + TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize); + manager.Initialize(&feature_info_); // Check we can create texture. TextureManager::TextureInfo* created_info = - manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); + manager.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id); created_info->SetNotOwned(); // Check texture got created. - TextureManager::TextureInfo* info1 = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info1 = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info1 != NULL); - EXPECT_CALL(*gl_, DeleteTextures(4, _)) + EXPECT_CALL(*gl_, DeleteTextures(8, _)) .Times(1) .RetiresOnSaturation(); // Check that it is not freed if it is not owned. - manager_.Destroy(true); - info1 = manager_.GetTextureInfo(kClient1Id); + manager.Destroy(true); + info1 = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info1 == NULL); } @@ -348,6 +356,17 @@ TEST_F(TextureInfoTest, Basic) { EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), info_->wrap_t()); EXPECT_TRUE(manager_.HaveUnrenderableTextures()); EXPECT_FALSE(manager_.HaveUnsafeTextures()); + EXPECT_EQ(0u, info_->estimated_size()); +} + +TEST_F(TextureInfoTest, EstimatedSize) { + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); + manager_.SetLevelInfo(&feature_info_, info_, + GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); + EXPECT_EQ(8u * 4u * 4u, info_->estimated_size()); + manager_.SetLevelInfo(&feature_info_, info_, + GL_TEXTURE_2D, 2, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); + EXPECT_EQ(8u * 4u * 4u * 2u, info_->estimated_size()); } TEST_F(TextureInfoTest, POT2D) { @@ -463,7 +482,7 @@ TEST_F(TextureInfoTest, NPOT2DNPOTOK) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info_ != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); @@ -657,7 +676,7 @@ TEST_F(TextureInfoTest, FloatNotLinear) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); @@ -679,7 +698,7 @@ TEST_F(TextureInfoTest, FloatLinear) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); @@ -696,7 +715,7 @@ TEST_F(TextureInfoTest, HalfFloatNotLinear) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); @@ -718,7 +737,7 @@ TEST_F(TextureInfoTest, HalfFloatLinear) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); @@ -735,7 +754,7 @@ TEST_F(TextureInfoTest, EGLImageExternal) { FeatureInfo feature_info; feature_info.Initialize(NULL); manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); - TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); + TextureManager::TextureInfo* info = manager.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_EXTERNAL_OES); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), info->target()); |