texture_manager_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "gpu/command_buffer/service/texture_manager.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "gpu/command_buffer/service/feature_info.h" 9#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" 10#include "gpu/command_buffer/service/memory_tracking.h" 11#include "gpu/command_buffer/service/mocks.h" 12#include "gpu/command_buffer/service/test_helper.h" 13#include "gpu/command_buffer/service/texture_definition.h" 14#include "testing/gtest/include/gtest/gtest.h" 15#include "ui/gl/gl_mock.h" 16 17using ::testing::AtLeast; 18using ::testing::Pointee; 19using ::testing::Return; 20using ::testing::SetArgumentPointee; 21using ::testing::StrictMock; 22using ::testing::_; 23 24namespace gpu { 25namespace gles2 { 26 27class TextureManagerTest : public testing::Test { 28 public: 29 static const GLint kMaxTextureSize = 16; 30 static const GLint kMaxCubeMapTextureSize = 8; 31 static const GLint kMaxExternalTextureSize = 16; 32 static const GLint kMax2dLevels = 5; 33 static const GLint kMaxCubeMapLevels = 4; 34 static const GLint kMaxExternalLevels = 1; 35 36 TextureManagerTest() 37 : feature_info_(new FeatureInfo()) { 38 } 39 40 virtual ~TextureManagerTest() { 41 } 42 43 protected: 44 virtual void SetUp() { 45 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 46 ::gfx::GLInterface::SetGLInterface(gl_.get()); 47 48 manager_.reset(new TextureManager( 49 NULL, feature_info_.get(), 50 kMaxTextureSize, kMaxCubeMapTextureSize)); 51 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 52 manager_->Initialize(); 53 decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); 54 } 55 56 virtual void TearDown() { 57 manager_->Destroy(false); 58 manager_.reset(); 59 ::gfx::GLInterface::SetGLInterface(NULL); 60 gl_.reset(); 61 } 62 63 void SetParameter( 64 Texture* texture, GLenum pname, GLint value, GLenum error) { 65 TestHelper::SetTexParameterWithExpectations( 66 gl_.get(), decoder_.get(), manager_.get(), 67 texture, pname, value, error); 68 } 69 70 // Use StrictMock to make 100% sure we know how GL will be called. 71 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 72 scoped_refptr<FeatureInfo> feature_info_; 73 scoped_ptr<TextureManager> manager_; 74 scoped_ptr<MockGLES2Decoder> decoder_; 75}; 76 77// GCC requires these declarations, but MSVC requires they not be present 78#ifndef COMPILER_MSVC 79const GLint TextureManagerTest::kMaxTextureSize; 80const GLint TextureManagerTest::kMaxCubeMapTextureSize; 81const GLint TextureManagerTest::kMaxExternalTextureSize; 82const GLint TextureManagerTest::kMax2dLevels; 83const GLint TextureManagerTest::kMaxCubeMapLevels; 84const GLint TextureManagerTest::kMaxExternalLevels; 85#endif 86 87TEST_F(TextureManagerTest, Basic) { 88 const GLuint kClient1Id = 1; 89 const GLuint kService1Id = 11; 90 const GLuint kClient2Id = 2; 91 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 92 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 93 EXPECT_FALSE(manager_->HaveUnclearedMips()); 94 // Check we can create texture. 95 manager_->CreateTexture(kClient1Id, kService1Id); 96 // Check texture got created. 97 Texture* texture = manager_->GetTexture(kClient1Id); 98 ASSERT_TRUE(texture != NULL); 99 EXPECT_EQ(kService1Id, texture->service_id()); 100 GLuint client_id = 0; 101 EXPECT_TRUE(manager_->GetClientId(texture->service_id(), &client_id)); 102 EXPECT_EQ(kClient1Id, client_id); 103 // Check we get nothing for a non-existent texture. 104 EXPECT_TRUE(manager_->GetTexture(kClient2Id) == NULL); 105 // Check trying to a remove non-existent textures does not crash. 106 manager_->RemoveTexture(kClient2Id); 107 // Check that it gets deleted when the last reference is released. 108 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) 109 .Times(1) 110 .RetiresOnSaturation(); 111 // Check we can't get the texture after we remove it. 112 manager_->RemoveTexture(kClient1Id); 113 EXPECT_TRUE(manager_->GetTexture(kClient1Id) == NULL); 114} 115 116TEST_F(TextureManagerTest, SetParameter) { 117 const GLuint kClient1Id = 1; 118 const GLuint kService1Id = 11; 119 // Check we can create texture. 120 manager_->CreateTexture(kClient1Id, kService1Id); 121 // Check texture got created. 122 Texture* texture = manager_->GetTexture(kClient1Id); 123 manager_->SetTarget(texture, GL_TEXTURE_2D); 124 ASSERT_TRUE(texture != NULL); 125 SetParameter(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST, GL_NO_ERROR); 126 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 127 SetParameter(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 128 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->mag_filter()); 129 SetParameter(texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 130 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_s()); 131 SetParameter(texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 132 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_t()); 133 SetParameter(texture, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1, GL_NO_ERROR); 134 SetParameter(texture, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2, GL_NO_ERROR); 135 SetParameter( 136 texture, GL_TEXTURE_MIN_FILTER, GL_CLAMP_TO_EDGE, GL_INVALID_ENUM); 137 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 138 SetParameter( 139 texture, GL_TEXTURE_MAG_FILTER, GL_CLAMP_TO_EDGE, GL_INVALID_ENUM); 140 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 141 SetParameter(texture, GL_TEXTURE_WRAP_S, GL_NEAREST, GL_INVALID_ENUM); 142 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_s()); 143 SetParameter(texture, GL_TEXTURE_WRAP_T, GL_NEAREST, GL_INVALID_ENUM); 144 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_t()); 145 SetParameter(texture, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0, GL_INVALID_VALUE); 146} 147 148TEST_F(TextureManagerTest, TextureUsageExt) { 149 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), 150 "GL_ANGLE_texture_usage"); 151 TextureManager manager( 152 NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 153 manager.Initialize(); 154 const GLuint kClient1Id = 1; 155 const GLuint kService1Id = 11; 156 // Check we can create texture. 157 manager.CreateTexture(kClient1Id, kService1Id); 158 // Check texture got created. 159 Texture* texture = manager.GetTexture(kClient1Id); 160 ASSERT_TRUE(texture != NULL); 161 TestHelper::SetTexParameterWithExpectations( 162 gl_.get(), decoder_.get(), &manager, texture, 163 GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE,GL_NO_ERROR); 164 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_ATTACHMENT_ANGLE), 165 texture->usage()); 166 manager.Destroy(false); 167} 168 169TEST_F(TextureManagerTest, Destroy) { 170 const GLuint kClient1Id = 1; 171 const GLuint kService1Id = 11; 172 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 173 TextureManager manager( 174 NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 175 manager.Initialize(); 176 // Check we can create texture. 177 manager.CreateTexture(kClient1Id, kService1Id); 178 // Check texture got created. 179 Texture* texture = manager.GetTexture(kClient1Id); 180 ASSERT_TRUE(texture != NULL); 181 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) 182 .Times(1) 183 .RetiresOnSaturation(); 184 TestHelper::SetupTextureManagerDestructionExpectations(gl_.get(), ""); 185 manager.Destroy(true); 186 // Check that resources got freed. 187 texture = manager.GetTexture(kClient1Id); 188 ASSERT_TRUE(texture == NULL); 189} 190 191TEST_F(TextureManagerTest, DestroyUnowned) { 192 const GLuint kClient1Id = 1; 193 const GLuint kService1Id = 11; 194 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 195 TextureManager manager( 196 NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 197 manager.Initialize(); 198 // Check we can create texture. 199 Texture* created_texture = 200 manager.CreateTexture(kClient1Id, kService1Id); 201 created_texture->SetNotOwned(); 202 203 // Check texture got created. 204 Texture* texture = manager.GetTexture(kClient1Id); 205 ASSERT_TRUE(texture != NULL); 206 207 // Check that it is not freed if it is not owned. 208 TestHelper::SetupTextureManagerDestructionExpectations(gl_.get(), ""); 209 manager.Destroy(true); 210 texture = manager.GetTexture(kClient1Id); 211 ASSERT_TRUE(texture == NULL); 212} 213 214TEST_F(TextureManagerTest, MaxValues) { 215 // Check we get the right values for the max sizes. 216 EXPECT_EQ(kMax2dLevels, manager_->MaxLevelsForTarget(GL_TEXTURE_2D)); 217 EXPECT_EQ(kMaxCubeMapLevels, 218 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP)); 219 EXPECT_EQ(kMaxCubeMapLevels, 220 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X)); 221 EXPECT_EQ(kMaxCubeMapLevels, 222 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)); 223 EXPECT_EQ(kMaxCubeMapLevels, 224 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)); 225 EXPECT_EQ(kMaxCubeMapLevels, 226 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)); 227 EXPECT_EQ(kMaxCubeMapLevels, 228 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)); 229 EXPECT_EQ(kMaxCubeMapLevels, 230 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)); 231 EXPECT_EQ(kMaxExternalLevels, 232 manager_->MaxLevelsForTarget(GL_TEXTURE_EXTERNAL_OES)); 233 EXPECT_EQ(kMaxTextureSize, manager_->MaxSizeForTarget(GL_TEXTURE_2D)); 234 EXPECT_EQ(kMaxCubeMapTextureSize, 235 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP)); 236 EXPECT_EQ(kMaxCubeMapTextureSize, 237 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X)); 238 EXPECT_EQ(kMaxCubeMapTextureSize, 239 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)); 240 EXPECT_EQ(kMaxCubeMapTextureSize, 241 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)); 242 EXPECT_EQ(kMaxCubeMapTextureSize, 243 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)); 244 EXPECT_EQ(kMaxCubeMapTextureSize, 245 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)); 246 EXPECT_EQ(kMaxCubeMapTextureSize, 247 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)); 248 EXPECT_EQ(kMaxExternalTextureSize, 249 manager_->MaxSizeForTarget(GL_TEXTURE_EXTERNAL_OES)); 250} 251 252TEST_F(TextureManagerTest, ValidForTarget) { 253 // check 2d 254 EXPECT_TRUE(manager_->ValidForTarget( 255 GL_TEXTURE_2D, 0, kMaxTextureSize, kMaxTextureSize, 1)); 256 EXPECT_TRUE(manager_->ValidForTarget( 257 GL_TEXTURE_2D, kMax2dLevels - 1, 1, 1, 1)); 258 EXPECT_FALSE(manager_->ValidForTarget( 259 GL_TEXTURE_2D, kMax2dLevels - 1, 1, 2, 1)); 260 EXPECT_FALSE(manager_->ValidForTarget( 261 GL_TEXTURE_2D, kMax2dLevels - 1, 2, 1, 1)); 262 // check level out of range. 263 EXPECT_FALSE(manager_->ValidForTarget( 264 GL_TEXTURE_2D, kMax2dLevels, kMaxTextureSize, 1, 1)); 265 // check has depth. 266 EXPECT_FALSE(manager_->ValidForTarget( 267 GL_TEXTURE_2D, kMax2dLevels, kMaxTextureSize, 1, 2)); 268 // Check NPOT width on level 0 269 EXPECT_TRUE(manager_->ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); 270 // Check NPOT height on level 0 271 EXPECT_TRUE(manager_->ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1)); 272 // Check NPOT width on level 1 273 EXPECT_FALSE(manager_->ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1)); 274 // Check NPOT height on level 1 275 EXPECT_FALSE(manager_->ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1)); 276 277 // check cube 278 EXPECT_TRUE(manager_->ValidForTarget( 279 GL_TEXTURE_CUBE_MAP, 0, 280 kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1)); 281 EXPECT_TRUE(manager_->ValidForTarget( 282 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1, 1, 1, 1)); 283 EXPECT_FALSE(manager_->ValidForTarget( 284 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1, 2, 2, 1)); 285 // check level out of range. 286 EXPECT_FALSE(manager_->ValidForTarget( 287 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 288 kMaxCubeMapTextureSize, 1, 1)); 289 // check not square. 290 EXPECT_FALSE(manager_->ValidForTarget( 291 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 292 kMaxCubeMapTextureSize, 1, 1)); 293 // check has depth. 294 EXPECT_FALSE(manager_->ValidForTarget( 295 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 296 kMaxCubeMapTextureSize, 1, 2)); 297 298 for (GLint level = 0; level < kMax2dLevels; ++level) { 299 EXPECT_TRUE(manager_->ValidForTarget( 300 GL_TEXTURE_2D, level, kMaxTextureSize >> level, 1, 1)); 301 EXPECT_TRUE(manager_->ValidForTarget( 302 GL_TEXTURE_2D, level, 1, kMaxTextureSize >> level, 1)); 303 EXPECT_FALSE(manager_->ValidForTarget( 304 GL_TEXTURE_2D, level, (kMaxTextureSize >> level) + 1, 1, 1)); 305 EXPECT_FALSE(manager_->ValidForTarget( 306 GL_TEXTURE_2D, level, 1, (kMaxTextureSize >> level) + 1, 1)); 307 } 308 309 for (GLint level = 0; level < kMaxCubeMapLevels; ++level) { 310 EXPECT_TRUE(manager_->ValidForTarget( 311 GL_TEXTURE_CUBE_MAP, level, 312 kMaxCubeMapTextureSize >> level, 313 kMaxCubeMapTextureSize >> level, 314 1)); 315 EXPECT_FALSE(manager_->ValidForTarget( 316 GL_TEXTURE_CUBE_MAP, level, 317 (kMaxCubeMapTextureSize >> level) * 2, 318 (kMaxCubeMapTextureSize >> level) * 2, 319 1)); 320 } 321} 322 323TEST_F(TextureManagerTest, ValidForTargetNPOT) { 324 TestHelper::SetupFeatureInfoInitExpectations( 325 gl_.get(), "GL_OES_texture_npot"); 326 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 327 feature_info->Initialize(NULL); 328 TextureManager manager( 329 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 330 // Check NPOT width on level 0 331 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); 332 // Check NPOT height on level 0 333 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1)); 334 // Check NPOT width on level 1 335 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1)); 336 // Check NPOT height on level 1 337 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1)); 338 manager.Destroy(false); 339} 340 341class TextureTestBase : public testing::Test { 342 public: 343 static const GLint kMaxTextureSize = 16; 344 static const GLint kMaxCubeMapTextureSize = 8; 345 static const GLint kMax2dLevels = 5; 346 static const GLint kMaxCubeMapLevels = 4; 347 static const GLuint kClient1Id = 1; 348 static const GLuint kService1Id = 11; 349 350 TextureTestBase() 351 : feature_info_(new FeatureInfo()) { 352 } 353 virtual ~TextureTestBase() { 354 texture_ = NULL; 355 } 356 357 protected: 358 void SetUpBase(MemoryTracker* memory_tracker) { 359 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 360 ::gfx::GLInterface::SetGLInterface(gl_.get()); 361 manager_.reset(new TextureManager( 362 memory_tracker, feature_info_.get(), 363 kMaxTextureSize, kMaxCubeMapTextureSize)); 364 decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); 365 manager_->CreateTexture(kClient1Id, kService1Id); 366 texture_ = manager_->GetTexture(kClient1Id); 367 ASSERT_TRUE(texture_.get() != NULL); 368 } 369 370 virtual void TearDown() { 371 if (texture_.get()) { 372 GLuint client_id = 0; 373 // If it's not in the manager then setting texture_ to NULL will 374 // delete the texture. 375 if (!manager_->GetClientId(texture_->service_id(), &client_id)) { 376 // Check that it gets deleted when the last reference is released. 377 EXPECT_CALL(*gl_, 378 DeleteTextures(1, ::testing::Pointee(texture_->service_id()))) 379 .Times(1) 380 .RetiresOnSaturation(); 381 } 382 texture_ = NULL; 383 } 384 manager_->Destroy(false); 385 manager_.reset(); 386 ::gfx::GLInterface::SetGLInterface(NULL); 387 gl_.reset(); 388 } 389 390 void SetParameter( 391 Texture* texture, GLenum pname, GLint value, GLenum error) { 392 TestHelper::SetTexParameterWithExpectations( 393 gl_.get(), decoder_.get(), manager_.get(), 394 texture, pname, value, error); 395 } 396 397 // Use StrictMock to make 100% sure we know how GL will be called. 398 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 399 scoped_refptr<FeatureInfo> feature_info_; 400 scoped_ptr<TextureManager> manager_; 401 scoped_ptr<MockGLES2Decoder> decoder_; 402 scoped_refptr<Texture> texture_; 403}; 404 405class TextureTest : public TextureTestBase { 406 protected: 407 virtual void SetUp() { 408 SetUpBase(NULL); 409 } 410}; 411 412class TextureMemoryTrackerTest : public TextureTestBase { 413 protected: 414 virtual void SetUp() { 415 mock_memory_tracker_ = new StrictMock<MockMemoryTracker>(); 416 SetUpBase(mock_memory_tracker_.get()); 417 } 418 419 scoped_refptr<MockMemoryTracker> mock_memory_tracker_; 420}; 421 422#define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size, pool) \ 423 EXPECT_CALL(*mock_memory_tracker_, \ 424 TrackMemoryAllocatedChange(old_size, new_size, pool)) \ 425 .Times(1) \ 426 .RetiresOnSaturation() \ 427 428TEST_F(TextureTest, Basic) { 429 EXPECT_EQ(0u, texture_->target()); 430 EXPECT_FALSE(texture_->texture_complete()); 431 EXPECT_FALSE(texture_->cube_complete()); 432 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 433 EXPECT_FALSE(texture_->npot()); 434 EXPECT_EQ(0, texture_->num_uncleared_mips()); 435 EXPECT_FALSE(manager_->CanRender(texture_)); 436 EXPECT_TRUE(texture_->SafeToRenderFrom()); 437 EXPECT_FALSE(texture_->IsImmutable()); 438 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST_MIPMAP_LINEAR), 439 texture_->min_filter()); 440 EXPECT_EQ(static_cast<GLenum>(GL_LINEAR), texture_->mag_filter()); 441 EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), texture_->wrap_s()); 442 EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), texture_->wrap_t()); 443 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 444 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 445 EXPECT_EQ(0u, texture_->estimated_size()); 446} 447 448TEST_F(TextureTest, EstimatedSize) { 449 manager_->SetTarget(texture_, GL_TEXTURE_2D); 450 manager_->SetLevelInfo(texture_, 451 GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 452 EXPECT_EQ(8u * 4u * 4u, texture_->estimated_size()); 453 manager_->SetLevelInfo(texture_, 454 GL_TEXTURE_2D, 2, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 455 EXPECT_EQ(8u * 4u * 4u * 2u, texture_->estimated_size()); 456} 457 458TEST_F(TextureMemoryTrackerTest, EstimatedSize) { 459 manager_->SetTarget(texture_, GL_TEXTURE_2D); 460 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kUnmanaged); 461 manager_->SetLevelInfo(texture_, 462 GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 463 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kUnmanaged); 464 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 256, MemoryTracker::kUnmanaged); 465 manager_->SetLevelInfo(texture_, 466 GL_TEXTURE_2D, 2, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 467 // Add expectation for texture deletion. 468 EXPECT_MEMORY_ALLOCATION_CHANGE(256, 0, MemoryTracker::kUnmanaged); 469 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 470} 471 472TEST_F(TextureMemoryTrackerTest, SetParameterPool) { 473 manager_->SetTarget(texture_, GL_TEXTURE_2D); 474 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kUnmanaged); 475 manager_->SetLevelInfo(texture_, 476 GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 477 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kUnmanaged); 478 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kManaged); 479 SetParameter( 480 texture_, GL_TEXTURE_POOL_CHROMIUM, GL_TEXTURE_POOL_MANAGED_CHROMIUM, 481 GL_NO_ERROR); 482 // Add expectation for texture deletion. 483 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kManaged); 484 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 485 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kManaged); 486} 487 488TEST_F(TextureTest, POT2D) { 489 manager_->SetTarget(texture_, GL_TEXTURE_2D); 490 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture_->target()); 491 // Check Setting level 0 to POT 492 manager_->SetLevelInfo(texture_, 493 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 494 EXPECT_FALSE(texture_->npot()); 495 EXPECT_FALSE(texture_->texture_complete()); 496 EXPECT_FALSE(manager_->CanRender(texture_)); 497 EXPECT_EQ(0, texture_->num_uncleared_mips()); 498 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 499 // Set filters to something that will work with a single mip. 500 SetParameter(texture_, GL_TEXTURE_MIN_FILTER, GL_LINEAR, GL_NO_ERROR); 501 EXPECT_TRUE(manager_->CanRender(texture_)); 502 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 503 // Set them back. 504 SetParameter( 505 texture_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR, GL_NO_ERROR); 506 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 507 508 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 509 // Make mips. 510 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 511 EXPECT_TRUE(texture_->texture_complete()); 512 EXPECT_TRUE(manager_->CanRender(texture_)); 513 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 514 // Change a mip. 515 manager_->SetLevelInfo(texture_, 516 GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 517 EXPECT_FALSE(texture_->npot()); 518 EXPECT_FALSE(texture_->texture_complete()); 519 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 520 EXPECT_FALSE(manager_->CanRender(texture_)); 521 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 522 // Set a level past the number of mips that would get generated. 523 manager_->SetLevelInfo(texture_, 524 GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 525 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 526 // Make mips. 527 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 528 EXPECT_TRUE(manager_->CanRender(texture_)); 529 EXPECT_TRUE(texture_->texture_complete()); 530 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 531} 532 533TEST_F(TextureMemoryTrackerTest, MarkMipmapsGenerated) { 534 manager_->SetTarget(texture_, GL_TEXTURE_2D); 535 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 64, MemoryTracker::kUnmanaged); 536 manager_->SetLevelInfo(texture_, 537 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 538 EXPECT_MEMORY_ALLOCATION_CHANGE(64, 0, MemoryTracker::kUnmanaged); 539 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 84, MemoryTracker::kUnmanaged); 540 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 541 EXPECT_MEMORY_ALLOCATION_CHANGE(84, 0, MemoryTracker::kUnmanaged); 542 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 543} 544 545TEST_F(TextureTest, UnusedMips) { 546 manager_->SetTarget(texture_, GL_TEXTURE_2D); 547 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture_->target()); 548 // Set level zero to large size. 549 manager_->SetLevelInfo(texture_, 550 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 551 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 552 EXPECT_FALSE(texture_->npot()); 553 EXPECT_TRUE(texture_->texture_complete()); 554 EXPECT_TRUE(manager_->CanRender(texture_)); 555 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 556 // Set level zero to large smaller (levels unused mips) 557 manager_->SetLevelInfo(texture_, 558 GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 559 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 560 EXPECT_FALSE(texture_->npot()); 561 EXPECT_TRUE(texture_->texture_complete()); 562 EXPECT_TRUE(manager_->CanRender(texture_)); 563 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 564 // Set an unused level to some size 565 manager_->SetLevelInfo(texture_, 566 GL_TEXTURE_2D, 4, GL_RGBA, 16, 16, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 567 EXPECT_FALSE(texture_->npot()); 568 EXPECT_TRUE(texture_->texture_complete()); 569 EXPECT_TRUE(manager_->CanRender(texture_)); 570 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 571} 572 573TEST_F(TextureTest, NPOT2D) { 574 manager_->SetTarget(texture_, GL_TEXTURE_2D); 575 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture_->target()); 576 // Check Setting level 0 to NPOT 577 manager_->SetLevelInfo(texture_, 578 GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 579 EXPECT_TRUE(texture_->npot()); 580 EXPECT_FALSE(texture_->texture_complete()); 581 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 582 EXPECT_FALSE(manager_->CanRender(texture_)); 583 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 584 SetParameter(texture_, GL_TEXTURE_MIN_FILTER, GL_LINEAR, GL_NO_ERROR); 585 EXPECT_FALSE(manager_->CanRender(texture_)); 586 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 587 SetParameter(texture_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 588 EXPECT_FALSE(manager_->CanRender(texture_)); 589 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 590 SetParameter(texture_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 591 EXPECT_TRUE(manager_->CanRender(texture_)); 592 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 593 // Change it to POT. 594 manager_->SetLevelInfo(texture_, 595 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 596 EXPECT_FALSE(texture_->npot()); 597 EXPECT_FALSE(texture_->texture_complete()); 598 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 599 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 600} 601 602TEST_F(TextureTest, NPOT2DNPOTOK) { 603 TestHelper::SetupFeatureInfoInitExpectations( 604 gl_.get(), "GL_OES_texture_npot"); 605 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 606 feature_info->Initialize(NULL); 607 TextureManager manager( 608 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 609 manager.CreateTexture(kClient1Id, kService1Id); 610 Texture* texture = manager.GetTexture(kClient1Id); 611 ASSERT_TRUE(texture != NULL); 612 613 manager.SetTarget(texture, GL_TEXTURE_2D); 614 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 615 // Check Setting level 0 to NPOT 616 manager.SetLevelInfo(texture, 617 GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 618 EXPECT_TRUE(texture->npot()); 619 EXPECT_FALSE(texture->texture_complete()); 620 EXPECT_TRUE(manager.CanGenerateMipmaps(texture)); 621 EXPECT_FALSE(manager.CanRender(texture)); 622 EXPECT_TRUE(manager.HaveUnrenderableTextures()); 623 EXPECT_TRUE(manager.MarkMipmapsGenerated(texture)); 624 EXPECT_TRUE(texture->texture_complete()); 625 EXPECT_TRUE(manager.CanRender(texture)); 626 EXPECT_FALSE(manager.HaveUnrenderableTextures()); 627 manager.Destroy(false); 628} 629 630TEST_F(TextureTest, POTCubeMap) { 631 manager_->SetTarget(texture_, GL_TEXTURE_CUBE_MAP); 632 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), texture_->target()); 633 // Check Setting level 0 each face to POT 634 manager_->SetLevelInfo(texture_, 635 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 636 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 637 EXPECT_FALSE(texture_->npot()); 638 EXPECT_FALSE(texture_->texture_complete()); 639 EXPECT_FALSE(texture_->cube_complete()); 640 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 641 EXPECT_FALSE(manager_->CanRender(texture_)); 642 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 643 manager_->SetLevelInfo(texture_, 644 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 645 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 646 EXPECT_FALSE(texture_->npot()); 647 EXPECT_FALSE(texture_->texture_complete()); 648 EXPECT_FALSE(texture_->cube_complete()); 649 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 650 EXPECT_FALSE(manager_->CanRender(texture_)); 651 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 652 manager_->SetLevelInfo(texture_, 653 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 654 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 655 EXPECT_FALSE(texture_->npot()); 656 EXPECT_FALSE(texture_->texture_complete()); 657 EXPECT_FALSE(texture_->cube_complete()); 658 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 659 EXPECT_FALSE(manager_->CanRender(texture_)); 660 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 661 manager_->SetLevelInfo(texture_, 662 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 663 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 664 EXPECT_FALSE(texture_->npot()); 665 EXPECT_FALSE(texture_->texture_complete()); 666 EXPECT_FALSE(texture_->cube_complete()); 667 EXPECT_FALSE(manager_->CanRender(texture_)); 668 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 669 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 670 manager_->SetLevelInfo(texture_, 671 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 672 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 673 EXPECT_FALSE(texture_->npot()); 674 EXPECT_FALSE(texture_->texture_complete()); 675 EXPECT_FALSE(texture_->cube_complete()); 676 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_)); 677 EXPECT_FALSE(manager_->CanRender(texture_)); 678 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 679 manager_->SetLevelInfo(texture_, 680 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 681 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 682 EXPECT_FALSE(texture_->npot()); 683 EXPECT_FALSE(texture_->texture_complete()); 684 EXPECT_TRUE(texture_->cube_complete()); 685 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 686 EXPECT_FALSE(manager_->CanRender(texture_)); 687 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 688 689 // Make mips. 690 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 691 EXPECT_TRUE(texture_->texture_complete()); 692 EXPECT_TRUE(texture_->cube_complete()); 693 EXPECT_TRUE(manager_->CanRender(texture_)); 694 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 695 696 // Change a mip. 697 manager_->SetLevelInfo(texture_, 698 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 699 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 700 EXPECT_FALSE(texture_->npot()); 701 EXPECT_FALSE(texture_->texture_complete()); 702 EXPECT_TRUE(texture_->cube_complete()); 703 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 704 // Set a level past the number of mips that would get generated. 705 manager_->SetLevelInfo(texture_, 706 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 707 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 708 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_)); 709 // Make mips. 710 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 711 EXPECT_TRUE(texture_->texture_complete()); 712 EXPECT_TRUE(texture_->cube_complete()); 713} 714 715TEST_F(TextureTest, GetLevelSize) { 716 manager_->SetTarget(texture_, GL_TEXTURE_2D); 717 manager_->SetLevelInfo(texture_, 718 GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 719 GLsizei width = -1; 720 GLsizei height = -1; 721 EXPECT_FALSE(texture_->GetLevelSize(GL_TEXTURE_2D, -1, &width, &height)); 722 EXPECT_FALSE(texture_->GetLevelSize(GL_TEXTURE_2D, 1000, &width, &height)); 723 EXPECT_FALSE(texture_->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); 724 EXPECT_TRUE(texture_->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); 725 EXPECT_EQ(4, width); 726 EXPECT_EQ(5, height); 727 manager_->RemoveTexture(kClient1Id); 728 EXPECT_TRUE(texture_->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); 729 EXPECT_EQ(4, width); 730 EXPECT_EQ(5, height); 731} 732 733TEST_F(TextureTest, GetLevelType) { 734 manager_->SetTarget(texture_, GL_TEXTURE_2D); 735 manager_->SetLevelInfo(texture_, 736 GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 737 GLenum type = -1; 738 GLenum format = -1; 739 EXPECT_FALSE(texture_->GetLevelType(GL_TEXTURE_2D, -1, &type, &format)); 740 EXPECT_FALSE(texture_->GetLevelType(GL_TEXTURE_2D, 1000, &type, &format)); 741 EXPECT_FALSE(texture_->GetLevelType(GL_TEXTURE_2D, 0, &type, &format)); 742 EXPECT_TRUE(texture_->GetLevelType(GL_TEXTURE_2D, 1, &type, &format)); 743 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); 744 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format); 745 manager_->RemoveTexture(kClient1Id); 746 EXPECT_TRUE(texture_->GetLevelType(GL_TEXTURE_2D, 1, &type, &format)); 747 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); 748 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format); 749} 750 751TEST_F(TextureTest, ValidForTexture) { 752 manager_->SetTarget(texture_, GL_TEXTURE_2D); 753 manager_->SetLevelInfo(texture_, 754 GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 755 // Check bad face. 756 EXPECT_FALSE(texture_->ValidForTexture( 757 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 758 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 759 // Check bad level. 760 EXPECT_FALSE(texture_->ValidForTexture( 761 GL_TEXTURE_2D, 0, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 762 // Check bad xoffset. 763 EXPECT_FALSE(texture_->ValidForTexture( 764 GL_TEXTURE_2D, 1, -1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 765 // Check bad xoffset + width > width. 766 EXPECT_FALSE(texture_->ValidForTexture( 767 GL_TEXTURE_2D, 1, 1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 768 // Check bad yoffset. 769 EXPECT_FALSE(texture_->ValidForTexture( 770 GL_TEXTURE_2D, 1, 0, -1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 771 // Check bad yoffset + height > height. 772 EXPECT_FALSE(texture_->ValidForTexture( 773 GL_TEXTURE_2D, 1, 0, 1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 774 // Check bad width. 775 EXPECT_FALSE(texture_->ValidForTexture( 776 GL_TEXTURE_2D, 1, 0, 0, 5, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 777 // Check bad height. 778 EXPECT_FALSE(texture_->ValidForTexture( 779 GL_TEXTURE_2D, 1, 0, 0, 4, 6, GL_RGBA, GL_UNSIGNED_BYTE)); 780 // Check bad format. 781 EXPECT_FALSE(texture_->ValidForTexture( 782 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGB, GL_UNSIGNED_BYTE)); 783 // Check bad type. 784 EXPECT_FALSE(texture_->ValidForTexture( 785 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)); 786 // Check valid full size 787 EXPECT_TRUE(texture_->ValidForTexture( 788 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 789 // Check valid particial size. 790 EXPECT_TRUE(texture_->ValidForTexture( 791 GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_RGBA, GL_UNSIGNED_BYTE)); 792 manager_->RemoveTexture(kClient1Id); 793 EXPECT_TRUE(texture_->ValidForTexture( 794 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 795} 796 797TEST_F(TextureTest, FloatNotLinear) { 798 TestHelper::SetupFeatureInfoInitExpectations( 799 gl_.get(), "GL_OES_texture_float"); 800 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 801 feature_info->Initialize(NULL); 802 TextureManager manager( 803 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 804 manager.CreateTexture(kClient1Id, kService1Id); 805 Texture* texture = manager.GetTexture(kClient1Id); 806 ASSERT_TRUE(texture != NULL); 807 manager.SetTarget(texture, GL_TEXTURE_2D); 808 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 809 manager.SetLevelInfo(texture, 810 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT, true); 811 EXPECT_FALSE(texture->texture_complete()); 812 TestHelper::SetTexParameterWithExpectations( 813 gl_.get(), decoder_.get(), &manager, 814 texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 815 EXPECT_FALSE(texture->texture_complete()); 816 TestHelper::SetTexParameterWithExpectations( 817 gl_.get(), decoder_.get(), &manager, 818 texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); 819 EXPECT_TRUE(texture->texture_complete()); 820 manager.Destroy(false); 821} 822 823TEST_F(TextureTest, FloatLinear) { 824 TestHelper::SetupFeatureInfoInitExpectations( 825 gl_.get(), "GL_OES_texture_float GL_OES_texture_float_linear"); 826 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 827 feature_info->Initialize(NULL); 828 TextureManager manager( 829 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 830 manager.CreateTexture(kClient1Id, kService1Id); 831 Texture* texture = manager.GetTexture(kClient1Id); 832 ASSERT_TRUE(texture != NULL); 833 manager.SetTarget(texture, GL_TEXTURE_2D); 834 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 835 manager.SetLevelInfo(texture, 836 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT, true); 837 EXPECT_TRUE(texture->texture_complete()); 838 manager.Destroy(false); 839} 840 841TEST_F(TextureTest, HalfFloatNotLinear) { 842 TestHelper::SetupFeatureInfoInitExpectations( 843 gl_.get(), "GL_OES_texture_half_float"); 844 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 845 feature_info->Initialize(NULL); 846 TextureManager manager( 847 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 848 manager.CreateTexture(kClient1Id, kService1Id); 849 Texture* texture = manager.GetTexture(kClient1Id); 850 ASSERT_TRUE(texture != NULL); 851 manager.SetTarget(texture, GL_TEXTURE_2D); 852 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 853 manager.SetLevelInfo(texture, 854 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES, true); 855 EXPECT_FALSE(texture->texture_complete()); 856 TestHelper::SetTexParameterWithExpectations( 857 gl_.get(), decoder_.get(), &manager, 858 texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 859 EXPECT_FALSE(texture->texture_complete()); 860 TestHelper::SetTexParameterWithExpectations( 861 gl_.get(), decoder_.get(), &manager, 862 texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); 863 EXPECT_TRUE(texture->texture_complete()); 864 manager.Destroy(false); 865} 866 867TEST_F(TextureTest, HalfFloatLinear) { 868 TestHelper::SetupFeatureInfoInitExpectations( 869 gl_.get(), "GL_OES_texture_half_float GL_OES_texture_half_float_linear"); 870 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 871 feature_info->Initialize(NULL); 872 TextureManager manager( 873 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 874 manager.CreateTexture(kClient1Id, kService1Id); 875 Texture* texture = manager.GetTexture(kClient1Id); 876 ASSERT_TRUE(texture != NULL); 877 manager.SetTarget(texture, GL_TEXTURE_2D); 878 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 879 manager.SetLevelInfo(texture, 880 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES, true); 881 EXPECT_TRUE(texture->texture_complete()); 882 manager.Destroy(false); 883} 884 885TEST_F(TextureTest, EGLImageExternal) { 886 TestHelper::SetupFeatureInfoInitExpectations( 887 gl_.get(), "GL_OES_EGL_image_external"); 888 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 889 feature_info->Initialize(NULL); 890 TextureManager manager( 891 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 892 manager.CreateTexture(kClient1Id, kService1Id); 893 Texture* texture = manager.GetTexture(kClient1Id); 894 ASSERT_TRUE(texture != NULL); 895 manager.SetTarget(texture, GL_TEXTURE_EXTERNAL_OES); 896 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), texture->target()); 897 EXPECT_FALSE(manager.CanGenerateMipmaps(texture)); 898 manager.Destroy(false); 899} 900 901TEST_F(TextureTest, DepthTexture) { 902 TestHelper::SetupFeatureInfoInitExpectations( 903 gl_.get(), "GL_ANGLE_depth_texture"); 904 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 905 feature_info->Initialize(NULL); 906 TextureManager manager( 907 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 908 manager.CreateTexture(kClient1Id, kService1Id); 909 Texture* texture = manager.GetTexture(kClient1Id); 910 ASSERT_TRUE(texture != NULL); 911 manager.SetTarget(texture, GL_TEXTURE_2D); 912 manager.SetLevelInfo( 913 texture, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 4, 4, 1, 0, 914 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false); 915 EXPECT_FALSE(manager.CanGenerateMipmaps(texture)); 916 manager.Destroy(false); 917} 918 919TEST_F(TextureTest, SafeUnsafe) { 920 static const GLuint kClient2Id = 2; 921 static const GLuint kService2Id = 12; 922 static const GLuint kClient3Id = 3; 923 static const GLuint kService3Id = 13; 924 EXPECT_FALSE(manager_->HaveUnclearedMips()); 925 EXPECT_EQ(0, texture_->num_uncleared_mips()); 926 manager_->SetTarget(texture_, GL_TEXTURE_2D); 927 manager_->SetLevelInfo(texture_, 928 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 929 EXPECT_FALSE(texture_->SafeToRenderFrom()); 930 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 931 EXPECT_TRUE(manager_->HaveUnclearedMips()); 932 EXPECT_EQ(1, texture_->num_uncleared_mips()); 933 manager_->SetLevelCleared(texture_, GL_TEXTURE_2D, 0, true); 934 EXPECT_TRUE(texture_->SafeToRenderFrom()); 935 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 936 EXPECT_FALSE(manager_->HaveUnclearedMips()); 937 EXPECT_EQ(0, texture_->num_uncleared_mips()); 938 manager_->SetLevelInfo(texture_, 939 GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 940 EXPECT_FALSE(texture_->SafeToRenderFrom()); 941 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 942 EXPECT_TRUE(manager_->HaveUnclearedMips()); 943 EXPECT_EQ(1, texture_->num_uncleared_mips()); 944 manager_->SetLevelCleared(texture_, GL_TEXTURE_2D, 1, true); 945 EXPECT_TRUE(texture_->SafeToRenderFrom()); 946 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 947 EXPECT_FALSE(manager_->HaveUnclearedMips()); 948 EXPECT_EQ(0, texture_->num_uncleared_mips()); 949 manager_->SetLevelInfo(texture_, 950 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 951 manager_->SetLevelInfo(texture_, 952 GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 953 EXPECT_FALSE(texture_->SafeToRenderFrom()); 954 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 955 EXPECT_TRUE(manager_->HaveUnclearedMips()); 956 EXPECT_EQ(2, texture_->num_uncleared_mips()); 957 manager_->SetLevelCleared(texture_, GL_TEXTURE_2D, 0, true); 958 EXPECT_FALSE(texture_->SafeToRenderFrom()); 959 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 960 EXPECT_TRUE(manager_->HaveUnclearedMips()); 961 EXPECT_EQ(1, texture_->num_uncleared_mips()); 962 manager_->SetLevelCleared(texture_, GL_TEXTURE_2D, 1, true); 963 EXPECT_TRUE(texture_->SafeToRenderFrom()); 964 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 965 EXPECT_FALSE(manager_->HaveUnclearedMips()); 966 EXPECT_EQ(0, texture_->num_uncleared_mips()); 967 manager_->SetLevelInfo(texture_, 968 GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 969 EXPECT_FALSE(texture_->SafeToRenderFrom()); 970 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 971 EXPECT_TRUE(manager_->HaveUnclearedMips()); 972 EXPECT_EQ(1, texture_->num_uncleared_mips()); 973 manager_->MarkMipmapsGenerated(texture_); 974 EXPECT_TRUE(texture_->SafeToRenderFrom()); 975 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 976 EXPECT_FALSE(manager_->HaveUnclearedMips()); 977 EXPECT_EQ(0, texture_->num_uncleared_mips()); 978 979 manager_->CreateTexture(kClient2Id, kService2Id); 980 scoped_refptr<Texture> texture2( 981 manager_->GetTexture(kClient2Id)); 982 ASSERT_TRUE(texture2.get() != NULL); 983 manager_->SetTarget(texture2, GL_TEXTURE_2D); 984 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 985 EXPECT_FALSE(manager_->HaveUnclearedMips()); 986 EXPECT_EQ(0, texture2->num_uncleared_mips()); 987 manager_->SetLevelInfo(texture2, 988 GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 989 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 990 EXPECT_FALSE(manager_->HaveUnclearedMips()); 991 EXPECT_EQ(0, texture2->num_uncleared_mips()); 992 manager_->SetLevelInfo(texture2, 993 GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 994 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 995 EXPECT_TRUE(manager_->HaveUnclearedMips()); 996 EXPECT_EQ(1, texture2->num_uncleared_mips()); 997 998 manager_->CreateTexture(kClient3Id, kService3Id); 999 scoped_refptr<Texture> texture3( 1000 manager_->GetTexture(kClient3Id)); 1001 ASSERT_TRUE(texture3.get() != NULL); 1002 manager_->SetTarget(texture3, GL_TEXTURE_2D); 1003 manager_->SetLevelInfo(texture3, 1004 GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1005 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1006 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1007 EXPECT_EQ(1, texture3->num_uncleared_mips()); 1008 manager_->SetLevelCleared(texture2, GL_TEXTURE_2D, 0, true); 1009 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1010 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1011 EXPECT_EQ(0, texture2->num_uncleared_mips()); 1012 manager_->SetLevelCleared(texture3, GL_TEXTURE_2D, 0, true); 1013 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1014 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1015 EXPECT_EQ(0, texture3->num_uncleared_mips()); 1016 1017 manager_->SetLevelInfo(texture2, 1018 GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1019 manager_->SetLevelInfo(texture3, 1020 GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1021 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1022 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1023 EXPECT_EQ(1, texture2->num_uncleared_mips()); 1024 EXPECT_EQ(1, texture3->num_uncleared_mips()); 1025 manager_->RemoveTexture(kClient3Id); 1026 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1027 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1028 manager_->RemoveTexture(kClient2Id); 1029 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1030 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1031 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService2Id))) 1032 .Times(1) 1033 .RetiresOnSaturation(); 1034 texture2 = NULL; 1035 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1036 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1037 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService3Id))) 1038 .Times(1) 1039 .RetiresOnSaturation(); 1040 texture3 = NULL; 1041 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1042 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1043} 1044 1045TEST_F(TextureTest, ClearTexture) { 1046 EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) 1047 .WillRepeatedly(Return(true)); 1048 manager_->SetTarget(texture_, GL_TEXTURE_2D); 1049 manager_->SetLevelInfo(texture_, 1050 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1051 manager_->SetLevelInfo(texture_, 1052 GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1053 EXPECT_FALSE(texture_->SafeToRenderFrom()); 1054 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1055 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1056 EXPECT_EQ(2, texture_->num_uncleared_mips()); 1057 manager_->ClearRenderableLevels(decoder_.get(), texture_); 1058 EXPECT_TRUE(texture_->SafeToRenderFrom()); 1059 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1060 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1061 EXPECT_EQ(0, texture_->num_uncleared_mips()); 1062 manager_->SetLevelInfo(texture_, 1063 GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1064 manager_->SetLevelInfo(texture_, 1065 GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1066 EXPECT_FALSE(texture_->SafeToRenderFrom()); 1067 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1068 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1069 EXPECT_EQ(2, texture_->num_uncleared_mips()); 1070 manager_->ClearTextureLevel(decoder_.get(), texture_, GL_TEXTURE_2D, 0); 1071 EXPECT_FALSE(texture_->SafeToRenderFrom()); 1072 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1073 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1074 EXPECT_EQ(1, texture_->num_uncleared_mips()); 1075 manager_->ClearTextureLevel(decoder_.get(), texture_, GL_TEXTURE_2D, 1); 1076 EXPECT_TRUE(texture_->SafeToRenderFrom()); 1077 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1078 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1079 EXPECT_EQ(0, texture_->num_uncleared_mips()); 1080} 1081 1082TEST_F(TextureTest, UseDeletedTexture) { 1083 static const GLuint kClient2Id = 2; 1084 static const GLuint kService2Id = 12; 1085 // Make the default texture renderable 1086 manager_->SetTarget(texture_, GL_TEXTURE_2D); 1087 manager_->SetLevelInfo(texture_, 1088 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1089 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 1090 // Make a new texture 1091 manager_->CreateTexture(kClient2Id, kService2Id); 1092 scoped_refptr<Texture> texture( 1093 manager_->GetTexture(kClient2Id)); 1094 manager_->SetTarget(texture, GL_TEXTURE_2D); 1095 EXPECT_FALSE(manager_->CanRender(texture)); 1096 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 1097 // Remove it. 1098 manager_->RemoveTexture(kClient2Id); 1099 EXPECT_FALSE(manager_->CanRender(texture)); 1100 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 1101 // Check that we can still manipulate it and it effects the manager. 1102 manager_->SetLevelInfo(texture, 1103 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1104 EXPECT_TRUE(manager_->CanRender(texture)); 1105 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 1106 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService2Id))) 1107 .Times(1) 1108 .RetiresOnSaturation(); 1109 texture = NULL; 1110} 1111 1112TEST_F(TextureTest, GetLevelImage) { 1113 manager_->SetTarget(texture_, GL_TEXTURE_2D); 1114 manager_->SetLevelInfo(texture_, 1115 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 1116 EXPECT_TRUE(texture_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1117 // Set image. 1118 manager_->SetLevelImage(texture_, 1119 GL_TEXTURE_2D, 1, gfx::GLImage::CreateGLImage(0)); 1120 EXPECT_FALSE(texture_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1121 // Remove it. 1122 manager_->SetLevelImage(texture_, GL_TEXTURE_2D, 1, NULL); 1123 EXPECT_TRUE(texture_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1124 manager_->SetLevelImage(texture_, 1125 GL_TEXTURE_2D, 1, gfx::GLImage::CreateGLImage(0)); 1126 // Image should be reset when SetLevelInfo is called. 1127 manager_->SetLevelInfo(texture_, 1128 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 1129 EXPECT_TRUE(texture_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1130} 1131 1132namespace { 1133 1134bool InSet(std::set<std::string>* string_set, const std::string& str) { 1135 std::pair<std::set<std::string>::iterator, bool> result = 1136 string_set->insert(str); 1137 return !result.second; 1138} 1139 1140} // anonymous namespace 1141 1142TEST_F(TextureTest, AddToSignature) { 1143 manager_->SetTarget(texture_, GL_TEXTURE_2D); 1144 manager_->SetLevelInfo(texture_, 1145 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 1146 std::string signature1; 1147 std::string signature2; 1148 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature1); 1149 1150 std::set<std::string> string_set; 1151 EXPECT_FALSE(InSet(&string_set, signature1)); 1152 1153 // check changing 1 thing makes a different signature. 1154 manager_->SetLevelInfo(texture_, 1155 GL_TEXTURE_2D, 1, GL_RGBA, 4, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 1156 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1157 EXPECT_FALSE(InSet(&string_set, signature2)); 1158 1159 // check putting it back makes the same signature. 1160 manager_->SetLevelInfo(texture_, 1161 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 1162 signature2.clear(); 1163 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1164 EXPECT_EQ(signature1, signature2); 1165 1166 // Check setting cleared status does not change signature. 1167 manager_->SetLevelInfo(texture_, 1168 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1169 signature2.clear(); 1170 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1171 EXPECT_EQ(signature1, signature2); 1172 1173 // Check changing other settings changes signature. 1174 manager_->SetLevelInfo(texture_, 1175 GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1176 signature2.clear(); 1177 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1178 EXPECT_FALSE(InSet(&string_set, signature2)); 1179 1180 manager_->SetLevelInfo(texture_, 1181 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, false); 1182 signature2.clear(); 1183 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1184 EXPECT_FALSE(InSet(&string_set, signature2)); 1185 1186 manager_->SetLevelInfo(texture_, 1187 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, false); 1188 signature2.clear(); 1189 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1190 EXPECT_FALSE(InSet(&string_set, signature2)); 1191 1192 manager_->SetLevelInfo(texture_, 1193 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, false); 1194 signature2.clear(); 1195 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1196 EXPECT_FALSE(InSet(&string_set, signature2)); 1197 1198 manager_->SetLevelInfo(texture_, 1199 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_FLOAT, 1200 false); 1201 signature2.clear(); 1202 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1203 EXPECT_FALSE(InSet(&string_set, signature2)); 1204 1205 // put it back 1206 manager_->SetLevelInfo(texture_, 1207 GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 1208 false); 1209 signature2.clear(); 1210 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1211 EXPECT_EQ(signature1, signature2); 1212 1213 // check changing parameters changes signature. 1214 SetParameter(texture_, GL_TEXTURE_MIN_FILTER, GL_NEAREST, GL_NO_ERROR); 1215 signature2.clear(); 1216 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1217 EXPECT_FALSE(InSet(&string_set, signature2)); 1218 1219 SetParameter( 1220 texture_, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR, GL_NO_ERROR); 1221 SetParameter(texture_, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 1222 signature2.clear(); 1223 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1224 EXPECT_FALSE(InSet(&string_set, signature2)); 1225 1226 SetParameter(texture_, GL_TEXTURE_MAG_FILTER, GL_LINEAR, GL_NO_ERROR); 1227 SetParameter(texture_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 1228 signature2.clear(); 1229 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1230 EXPECT_FALSE(InSet(&string_set, signature2)); 1231 1232 SetParameter(texture_, GL_TEXTURE_WRAP_S, GL_REPEAT, GL_NO_ERROR); 1233 SetParameter(texture_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 1234 signature2.clear(); 1235 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1236 EXPECT_FALSE(InSet(&string_set, signature2)); 1237 1238 // Check putting it back genenerates the same signature 1239 SetParameter(texture_, GL_TEXTURE_WRAP_T, GL_REPEAT, GL_NO_ERROR); 1240 signature2.clear(); 1241 manager_->AddToSignature(texture_, GL_TEXTURE_2D, 1, &signature2); 1242 EXPECT_EQ(signature1, signature2); 1243 1244 // Check the set was acutally getting different signatures. 1245 EXPECT_EQ(11u, string_set.size()); 1246} 1247 1248class SaveRestoreTextureTest : public TextureTest { 1249 public: 1250 virtual void SetUp() { 1251 TextureTest::SetUp(); 1252 manager_->CreateTexture(kClient2Id, kService2Id); 1253 texture2_ = manager_->GetTexture(kClient2Id); 1254 } 1255 1256 virtual void TearDown() { 1257 if (texture2_.get()) { 1258 GLuint client_id = 0; 1259 // If it's not in the manager then setting texture2_ to NULL will 1260 // delete the texture. 1261 if (!manager_->GetClientId(texture2_->service_id(), &client_id)) { 1262 // Check that it gets deleted when the last reference is released. 1263 EXPECT_CALL( 1264 *gl_, 1265 DeleteTextures(1, ::testing::Pointee(texture2_->service_id()))) 1266 .Times(1).RetiresOnSaturation(); 1267 } 1268 texture2_ = NULL; 1269 } 1270 TextureTest::TearDown(); 1271 } 1272 1273 protected: 1274 struct LevelInfo { 1275 LevelInfo(GLenum target, 1276 GLenum format, 1277 GLsizei width, 1278 GLsizei height, 1279 GLsizei depth, 1280 GLint border, 1281 GLenum type, 1282 bool cleared) 1283 : target(target), 1284 format(format), 1285 width(width), 1286 height(height), 1287 depth(depth), 1288 border(border), 1289 type(type), 1290 cleared(cleared) {} 1291 1292 LevelInfo() 1293 : target(0), 1294 format(0), 1295 width(-1), 1296 height(-1), 1297 depth(1), 1298 border(0), 1299 type(0), 1300 cleared(false) {} 1301 1302 bool operator==(const LevelInfo& other) const { 1303 return target == other.target && format == other.format && 1304 width == other.width && height == other.height && 1305 depth == other.depth && border == other.border && 1306 type == other.type && cleared == other.cleared; 1307 } 1308 1309 GLenum target; 1310 GLenum format; 1311 GLsizei width; 1312 GLsizei height; 1313 GLsizei depth; 1314 GLint border; 1315 GLenum type; 1316 bool cleared; 1317 }; 1318 1319 void SetLevelInfo(Texture* texture, GLint level, const LevelInfo& info) { 1320 manager_->SetLevelInfo(texture, 1321 info.target, 1322 level, 1323 info.format, 1324 info.width, 1325 info.height, 1326 info.depth, 1327 info.border, 1328 info.format, 1329 info.type, 1330 info.cleared); 1331 } 1332 1333 static LevelInfo GetLevelInfo(const Texture* texture, 1334 GLint target, 1335 GLint level) { 1336 LevelInfo info; 1337 info.target = target; 1338 EXPECT_TRUE(texture->GetLevelSize(target, level, &info.width, 1339 &info.height)); 1340 EXPECT_TRUE(texture->GetLevelType(target, level, &info.type, 1341 &info.format)); 1342 info.cleared = texture->IsLevelCleared(target, level); 1343 return info; 1344 } 1345 1346 TextureDefinition* Save(Texture* texture) { 1347 EXPECT_CALL(*gl_, GenTextures(_, _)) 1348 .WillOnce(SetArgumentPointee<1>(kService2Id)); 1349 TextureDefinition* definition = manager_->Save(texture); 1350 EXPECT_TRUE(definition != NULL); 1351 return definition; 1352 } 1353 1354 void Restore(Texture* texture, TextureDefinition* definition) { 1355 EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(texture->service_id()))) 1356 .Times(1).RetiresOnSaturation(); 1357 EXPECT_CALL(*gl_, 1358 BindTexture(definition->target(), definition->service_id())) 1359 .Times(1).RetiresOnSaturation(); 1360 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(AtLeast(1)); 1361 1362 EXPECT_TRUE( 1363 manager_->Restore("TextureTest", decoder_.get(), texture, definition)); 1364 } 1365 1366 scoped_refptr<Texture> texture2_; 1367 1368 private: 1369 static const GLuint kEmptyTextureServiceId; 1370 static const GLuint kClient2Id; 1371 static const GLuint kService2Id; 1372}; 1373 1374const GLuint SaveRestoreTextureTest::kClient2Id = 2; 1375const GLuint SaveRestoreTextureTest::kService2Id = 12; 1376const GLuint SaveRestoreTextureTest::kEmptyTextureServiceId = 13; 1377 1378TEST_F(SaveRestoreTextureTest, SaveRestore2D) { 1379 manager_->SetTarget(texture_, GL_TEXTURE_2D); 1380 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture_->target()); 1381 LevelInfo level0( 1382 GL_TEXTURE_2D, GL_RGBA, 4, 4, 1, 0, GL_UNSIGNED_BYTE, true); 1383 SetLevelInfo(texture_, 0, level0); 1384 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_)); 1385 EXPECT_TRUE(texture_->texture_complete()); 1386 LevelInfo level1 = GetLevelInfo(texture_.get(), GL_TEXTURE_2D, 1); 1387 LevelInfo level2 = GetLevelInfo(texture_.get(), GL_TEXTURE_2D, 2); 1388 scoped_ptr<TextureDefinition> definition(Save(texture_)); 1389 const TextureDefinition::LevelInfos& infos = definition->level_infos(); 1390 EXPECT_EQ(1U, infos.size()); 1391 EXPECT_EQ(3U, infos[0].size()); 1392 1393 // Make this texture bigger with more levels, and make sure they get 1394 // clobbered correctly during Restore(). 1395 manager_->SetTarget(texture2_, GL_TEXTURE_2D); 1396 SetLevelInfo( 1397 texture2_, 1398 0, 1399 LevelInfo(GL_TEXTURE_2D, GL_RGBA, 16, 16, 1, 0, GL_UNSIGNED_BYTE, false)); 1400 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture2_)); 1401 EXPECT_TRUE(texture2_->texture_complete()); 1402 EXPECT_EQ(1024U + 256U + 64U + 16U + 4U, texture2_->estimated_size()); 1403 Restore(texture2_, definition.release()); 1404 EXPECT_EQ(level0, GetLevelInfo(texture2_.get(), GL_TEXTURE_2D, 0)); 1405 EXPECT_EQ(level1, GetLevelInfo(texture2_.get(), GL_TEXTURE_2D, 1)); 1406 EXPECT_EQ(level2, GetLevelInfo(texture2_.get(), GL_TEXTURE_2D, 2)); 1407 EXPECT_EQ(64U + 16U + 4U, texture2_->estimated_size()); 1408 GLint w, h; 1409 EXPECT_TRUE(texture2_->GetLevelSize(GL_TEXTURE_2D, 3, &w, &h)); 1410 EXPECT_EQ(0, w); 1411 EXPECT_EQ(0, h); 1412} 1413 1414TEST_F(SaveRestoreTextureTest, SaveRestoreClearRectangle) { 1415 manager_->SetTarget(texture_, GL_TEXTURE_RECTANGLE_ARB); 1416 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), texture_->target()); 1417 LevelInfo level0( 1418 GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, 1, 1, 1, 0, GL_UNSIGNED_BYTE, false); 1419 SetLevelInfo(texture_, 0, level0); 1420 EXPECT_TRUE(texture_->texture_complete()); 1421 scoped_ptr<TextureDefinition> definition(Save(texture_)); 1422 const TextureDefinition::LevelInfos& infos = definition->level_infos(); 1423 EXPECT_EQ(1U, infos.size()); 1424 EXPECT_EQ(1U, infos[0].size()); 1425 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), infos[0][0].target); 1426 manager_->SetTarget(texture2_, GL_TEXTURE_RECTANGLE_ARB); 1427 Restore(texture2_, definition.release()); 1428 1429 // See if we can clear the previously uncleared level now. 1430 EXPECT_EQ(level0, GetLevelInfo(texture2_.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); 1431 EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) 1432 .WillRepeatedly(Return(true)); 1433 EXPECT_TRUE(manager_->ClearTextureLevel( 1434 decoder_.get(), texture2_, GL_TEXTURE_RECTANGLE_ARB, 0)); 1435} 1436 1437TEST_F(SaveRestoreTextureTest, SaveRestoreCube) { 1438 manager_->SetTarget(texture_, GL_TEXTURE_CUBE_MAP); 1439 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), texture_->target()); 1440 LevelInfo face0(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1441 GL_RGBA, 1442 1, 1443 1, 1444 1, 1445 0, 1446 GL_UNSIGNED_BYTE, 1447 true); 1448 LevelInfo face5(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1449 GL_RGBA, 1450 3, 1451 3, 1452 1, 1453 0, 1454 GL_UNSIGNED_BYTE, 1455 true); 1456 SetLevelInfo(texture_, 0, face0); 1457 SetLevelInfo(texture_, 0, face5); 1458 EXPECT_TRUE(texture_->texture_complete()); 1459 scoped_ptr<TextureDefinition> definition(Save(texture_)); 1460 const TextureDefinition::LevelInfos& infos = definition->level_infos(); 1461 EXPECT_EQ(6U, infos.size()); 1462 EXPECT_EQ(1U, infos[0].size()); 1463 manager_->SetTarget(texture2_, GL_TEXTURE_CUBE_MAP); 1464 Restore(texture2_, definition.release()); 1465 EXPECT_EQ(face0, 1466 GetLevelInfo(texture2_.get(), GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)); 1467 EXPECT_EQ(face5, 1468 GetLevelInfo(texture2_.get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0)); 1469} 1470 1471} // namespace gles2 1472} // namespace gpu 1473 1474 1475