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/error_state_mock.h" 9 #include "gpu/command_buffer/service/feature_info.h" 10 #include "gpu/command_buffer/service/framebuffer_manager.h" 11 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" 12 #include "gpu/command_buffer/service/mailbox_manager.h" 13 #include "gpu/command_buffer/service/memory_tracking.h" 14 #include "gpu/command_buffer/service/mocks.h" 15 #include "gpu/command_buffer/service/test_helper.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "ui/gl/gl_mock.h" 18 19 using ::testing::AtLeast; 20 using ::testing::Pointee; 21 using ::testing::Return; 22 using ::testing::SetArgumentPointee; 23 using ::testing::StrictMock; 24 using ::testing::_; 25 26 namespace gpu { 27 namespace gles2 { 28 29 class TextureTestHelper { 30 public: 31 static bool IsNPOT(const Texture* texture) { 32 return texture->npot(); 33 } 34 static bool IsTextureComplete(const Texture* texture) { 35 return texture->texture_complete(); 36 } 37 static bool IsCubeComplete(const Texture* texture) { 38 return texture->cube_complete(); 39 } 40 }; 41 42 class TextureManagerTest : public testing::Test { 43 public: 44 static const GLint kMaxTextureSize = 16; 45 static const GLint kMaxCubeMapTextureSize = 8; 46 static const GLint kMaxExternalTextureSize = 16; 47 static const GLint kMax2dLevels = 5; 48 static const GLint kMaxCubeMapLevels = 4; 49 static const GLint kMaxExternalLevels = 1; 50 51 TextureManagerTest() 52 : feature_info_(new FeatureInfo()) { 53 } 54 55 virtual ~TextureManagerTest() { 56 } 57 58 protected: 59 virtual void SetUp() { 60 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 61 ::gfx::GLInterface::SetGLInterface(gl_.get()); 62 63 manager_.reset(new TextureManager( 64 NULL, feature_info_.get(), 65 kMaxTextureSize, kMaxCubeMapTextureSize)); 66 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 67 manager_->Initialize(); 68 error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); 69 } 70 71 virtual void TearDown() { 72 manager_->Destroy(false); 73 manager_.reset(); 74 ::gfx::GLInterface::SetGLInterface(NULL); 75 gl_.reset(); 76 } 77 78 void SetParameter( 79 TextureRef* texture_ref, GLenum pname, GLint value, GLenum error) { 80 TestHelper::SetTexParameterWithExpectations( 81 gl_.get(), error_state_.get(), manager_.get(), 82 texture_ref, pname, value, error); 83 } 84 85 // Use StrictMock to make 100% sure we know how GL will be called. 86 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 87 scoped_refptr<FeatureInfo> feature_info_; 88 scoped_ptr<TextureManager> manager_; 89 scoped_ptr<MockErrorState> error_state_; 90 }; 91 92 // GCC requires these declarations, but MSVC requires they not be present 93 #ifndef COMPILER_MSVC 94 const GLint TextureManagerTest::kMaxTextureSize; 95 const GLint TextureManagerTest::kMaxCubeMapTextureSize; 96 const GLint TextureManagerTest::kMaxExternalTextureSize; 97 const GLint TextureManagerTest::kMax2dLevels; 98 const GLint TextureManagerTest::kMaxCubeMapLevels; 99 const GLint TextureManagerTest::kMaxExternalLevels; 100 #endif 101 102 TEST_F(TextureManagerTest, Basic) { 103 const GLuint kClient1Id = 1; 104 const GLuint kService1Id = 11; 105 const GLuint kClient2Id = 2; 106 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 107 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 108 EXPECT_FALSE(manager_->HaveUnclearedMips()); 109 // Check we can create texture. 110 manager_->CreateTexture(kClient1Id, kService1Id); 111 // Check texture got created. 112 scoped_refptr<TextureRef> texture = manager_->GetTexture(kClient1Id); 113 ASSERT_TRUE(texture.get() != NULL); 114 EXPECT_EQ(kService1Id, texture->service_id()); 115 EXPECT_EQ(kClient1Id, texture->client_id()); 116 EXPECT_EQ(texture->texture(), manager_->GetTextureForServiceId( 117 texture->service_id())); 118 // Check we get nothing for a non-existent texture. 119 EXPECT_TRUE(manager_->GetTexture(kClient2Id) == NULL); 120 // Check trying to a remove non-existent textures does not crash. 121 manager_->RemoveTexture(kClient2Id); 122 // Check that it gets deleted when the last reference is released. 123 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) 124 .Times(1) 125 .RetiresOnSaturation(); 126 // Check we can't get the texture after we remove it. 127 manager_->RemoveTexture(kClient1Id); 128 EXPECT_TRUE(manager_->GetTexture(kClient1Id) == NULL); 129 EXPECT_EQ(0u, texture->client_id()); 130 } 131 132 TEST_F(TextureManagerTest, SetParameter) { 133 const GLuint kClient1Id = 1; 134 const GLuint kService1Id = 11; 135 // Check we can create texture. 136 manager_->CreateTexture(kClient1Id, kService1Id); 137 // Check texture got created. 138 TextureRef* texture_ref = manager_->GetTexture(kClient1Id); 139 ASSERT_TRUE(texture_ref != NULL); 140 Texture* texture = texture_ref->texture(); 141 manager_->SetTarget(texture_ref, GL_TEXTURE_2D); 142 SetParameter(texture_ref, GL_TEXTURE_MIN_FILTER, GL_NEAREST, GL_NO_ERROR); 143 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 144 SetParameter(texture_ref, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 145 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->mag_filter()); 146 SetParameter(texture_ref, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 147 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_s()); 148 SetParameter(texture_ref, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 149 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_t()); 150 SetParameter(texture_ref, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1, GL_NO_ERROR); 151 SetParameter(texture_ref, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2, GL_NO_ERROR); 152 SetParameter( 153 texture_ref, GL_TEXTURE_MIN_FILTER, GL_CLAMP_TO_EDGE, GL_INVALID_ENUM); 154 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 155 SetParameter( 156 texture_ref, GL_TEXTURE_MAG_FILTER, GL_CLAMP_TO_EDGE, GL_INVALID_ENUM); 157 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST), texture->min_filter()); 158 SetParameter(texture_ref, GL_TEXTURE_WRAP_S, GL_NEAREST, GL_INVALID_ENUM); 159 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_s()); 160 SetParameter(texture_ref, GL_TEXTURE_WRAP_T, GL_NEAREST, GL_INVALID_ENUM); 161 EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), texture->wrap_t()); 162 SetParameter(texture_ref, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0, GL_INVALID_VALUE); 163 } 164 165 TEST_F(TextureManagerTest, TextureUsageExt) { 166 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), 167 "GL_ANGLE_texture_usage"); 168 TextureManager manager( 169 NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 170 manager.Initialize(); 171 const GLuint kClient1Id = 1; 172 const GLuint kService1Id = 11; 173 // Check we can create texture. 174 manager.CreateTexture(kClient1Id, kService1Id); 175 // Check texture got created. 176 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 177 ASSERT_TRUE(texture_ref != NULL); 178 TestHelper::SetTexParameterWithExpectations( 179 gl_.get(), error_state_.get(), &manager, texture_ref, 180 GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE,GL_NO_ERROR); 181 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_ATTACHMENT_ANGLE), 182 texture_ref->texture()->usage()); 183 manager.Destroy(false); 184 } 185 186 TEST_F(TextureManagerTest, Destroy) { 187 const GLuint kClient1Id = 1; 188 const GLuint kService1Id = 11; 189 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 190 TextureManager manager( 191 NULL, feature_info_.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 192 manager.Initialize(); 193 // Check we can create texture. 194 manager.CreateTexture(kClient1Id, kService1Id); 195 // Check texture got created. 196 TextureRef* texture = manager.GetTexture(kClient1Id); 197 ASSERT_TRUE(texture != NULL); 198 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id))) 199 .Times(1) 200 .RetiresOnSaturation(); 201 TestHelper::SetupTextureManagerDestructionExpectations(gl_.get(), ""); 202 manager.Destroy(true); 203 // Check that resources got freed. 204 texture = manager.GetTexture(kClient1Id); 205 ASSERT_TRUE(texture == NULL); 206 } 207 208 TEST_F(TextureManagerTest, MaxValues) { 209 // Check we get the right values for the max sizes. 210 EXPECT_EQ(kMax2dLevels, manager_->MaxLevelsForTarget(GL_TEXTURE_2D)); 211 EXPECT_EQ(kMaxCubeMapLevels, 212 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP)); 213 EXPECT_EQ(kMaxCubeMapLevels, 214 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X)); 215 EXPECT_EQ(kMaxCubeMapLevels, 216 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)); 217 EXPECT_EQ(kMaxCubeMapLevels, 218 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)); 219 EXPECT_EQ(kMaxCubeMapLevels, 220 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)); 221 EXPECT_EQ(kMaxCubeMapLevels, 222 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)); 223 EXPECT_EQ(kMaxCubeMapLevels, 224 manager_->MaxLevelsForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)); 225 EXPECT_EQ(kMaxExternalLevels, 226 manager_->MaxLevelsForTarget(GL_TEXTURE_EXTERNAL_OES)); 227 EXPECT_EQ(kMaxTextureSize, manager_->MaxSizeForTarget(GL_TEXTURE_2D)); 228 EXPECT_EQ(kMaxCubeMapTextureSize, 229 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP)); 230 EXPECT_EQ(kMaxCubeMapTextureSize, 231 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X)); 232 EXPECT_EQ(kMaxCubeMapTextureSize, 233 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)); 234 EXPECT_EQ(kMaxCubeMapTextureSize, 235 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)); 236 EXPECT_EQ(kMaxCubeMapTextureSize, 237 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)); 238 EXPECT_EQ(kMaxCubeMapTextureSize, 239 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)); 240 EXPECT_EQ(kMaxCubeMapTextureSize, 241 manager_->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)); 242 EXPECT_EQ(kMaxExternalTextureSize, 243 manager_->MaxSizeForTarget(GL_TEXTURE_EXTERNAL_OES)); 244 } 245 246 TEST_F(TextureManagerTest, ValidForTarget) { 247 // check 2d 248 EXPECT_TRUE(manager_->ValidForTarget( 249 GL_TEXTURE_2D, 0, kMaxTextureSize, kMaxTextureSize, 1)); 250 EXPECT_TRUE(manager_->ValidForTarget( 251 GL_TEXTURE_2D, kMax2dLevels - 1, 1, 1, 1)); 252 EXPECT_FALSE(manager_->ValidForTarget( 253 GL_TEXTURE_2D, kMax2dLevels - 1, 1, 2, 1)); 254 EXPECT_FALSE(manager_->ValidForTarget( 255 GL_TEXTURE_2D, kMax2dLevels - 1, 2, 1, 1)); 256 // check level out of range. 257 EXPECT_FALSE(manager_->ValidForTarget( 258 GL_TEXTURE_2D, kMax2dLevels, kMaxTextureSize, 1, 1)); 259 // check has depth. 260 EXPECT_FALSE(manager_->ValidForTarget( 261 GL_TEXTURE_2D, kMax2dLevels, kMaxTextureSize, 1, 2)); 262 // Check NPOT width on level 0 263 EXPECT_TRUE(manager_->ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); 264 // Check NPOT height on level 0 265 EXPECT_TRUE(manager_->ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1)); 266 // Check NPOT width on level 1 267 EXPECT_FALSE(manager_->ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1)); 268 // Check NPOT height on level 1 269 EXPECT_FALSE(manager_->ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1)); 270 271 // check cube 272 EXPECT_TRUE(manager_->ValidForTarget( 273 GL_TEXTURE_CUBE_MAP, 0, 274 kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1)); 275 EXPECT_TRUE(manager_->ValidForTarget( 276 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1, 1, 1, 1)); 277 EXPECT_FALSE(manager_->ValidForTarget( 278 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1, 2, 2, 1)); 279 // check level out of range. 280 EXPECT_FALSE(manager_->ValidForTarget( 281 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 282 kMaxCubeMapTextureSize, 1, 1)); 283 // check not square. 284 EXPECT_FALSE(manager_->ValidForTarget( 285 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 286 kMaxCubeMapTextureSize, 1, 1)); 287 // check has depth. 288 EXPECT_FALSE(manager_->ValidForTarget( 289 GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels, 290 kMaxCubeMapTextureSize, 1, 2)); 291 292 for (GLint level = 0; level < kMax2dLevels; ++level) { 293 EXPECT_TRUE(manager_->ValidForTarget( 294 GL_TEXTURE_2D, level, kMaxTextureSize >> level, 1, 1)); 295 EXPECT_TRUE(manager_->ValidForTarget( 296 GL_TEXTURE_2D, level, 1, kMaxTextureSize >> level, 1)); 297 EXPECT_FALSE(manager_->ValidForTarget( 298 GL_TEXTURE_2D, level, (kMaxTextureSize >> level) + 1, 1, 1)); 299 EXPECT_FALSE(manager_->ValidForTarget( 300 GL_TEXTURE_2D, level, 1, (kMaxTextureSize >> level) + 1, 1)); 301 } 302 303 for (GLint level = 0; level < kMaxCubeMapLevels; ++level) { 304 EXPECT_TRUE(manager_->ValidForTarget( 305 GL_TEXTURE_CUBE_MAP, level, 306 kMaxCubeMapTextureSize >> level, 307 kMaxCubeMapTextureSize >> level, 308 1)); 309 EXPECT_FALSE(manager_->ValidForTarget( 310 GL_TEXTURE_CUBE_MAP, level, 311 (kMaxCubeMapTextureSize >> level) * 2, 312 (kMaxCubeMapTextureSize >> level) * 2, 313 1)); 314 } 315 } 316 317 TEST_F(TextureManagerTest, ValidForTargetNPOT) { 318 TestHelper::SetupFeatureInfoInitExpectations( 319 gl_.get(), "GL_OES_texture_npot"); 320 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 321 feature_info->Initialize(NULL); 322 TextureManager manager( 323 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 324 // Check NPOT width on level 0 325 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1)); 326 // Check NPOT height on level 0 327 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1)); 328 // Check NPOT width on level 1 329 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1)); 330 // Check NPOT height on level 1 331 EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1)); 332 manager.Destroy(false); 333 } 334 335 class TextureTestBase : public testing::Test { 336 public: 337 static const GLint kMaxTextureSize = 16; 338 static const GLint kMaxCubeMapTextureSize = 8; 339 static const GLint kMax2dLevels = 5; 340 static const GLint kMaxCubeMapLevels = 4; 341 static const GLuint kClient1Id = 1; 342 static const GLuint kService1Id = 11; 343 344 TextureTestBase() 345 : feature_info_(new FeatureInfo()) { 346 } 347 virtual ~TextureTestBase() { 348 texture_ref_ = NULL; 349 } 350 351 protected: 352 void SetUpBase(MemoryTracker* memory_tracker, std::string extensions) { 353 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 354 ::gfx::GLInterface::SetGLInterface(gl_.get()); 355 356 if (!extensions.empty()) { 357 TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), 358 extensions.c_str()); 359 feature_info_->Initialize(NULL); 360 } 361 362 manager_.reset(new TextureManager( 363 memory_tracker, feature_info_.get(), 364 kMaxTextureSize, kMaxCubeMapTextureSize)); 365 decoder_.reset(new ::testing::StrictMock<gles2::MockGLES2Decoder>()); 366 error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); 367 manager_->CreateTexture(kClient1Id, kService1Id); 368 texture_ref_ = manager_->GetTexture(kClient1Id); 369 ASSERT_TRUE(texture_ref_.get() != NULL); 370 } 371 372 virtual void TearDown() { 373 if (texture_ref_.get()) { 374 // If it's not in the manager then setting texture_ref_ to NULL will 375 // delete the texture. 376 if (!texture_ref_->client_id()) { 377 // Check that it gets deleted when the last reference is released. 378 EXPECT_CALL(*gl_, 379 DeleteTextures(1, ::testing::Pointee(texture_ref_->service_id()))) 380 .Times(1) 381 .RetiresOnSaturation(); 382 } 383 texture_ref_ = NULL; 384 } 385 manager_->Destroy(false); 386 manager_.reset(); 387 ::gfx::GLInterface::SetGLInterface(NULL); 388 gl_.reset(); 389 } 390 391 void SetParameter( 392 TextureRef* texture_ref, GLenum pname, GLint value, GLenum error) { 393 TestHelper::SetTexParameterWithExpectations( 394 gl_.get(), error_state_.get(), manager_.get(), 395 texture_ref, pname, value, error); 396 } 397 398 scoped_ptr<MockGLES2Decoder> decoder_; 399 scoped_ptr<MockErrorState> error_state_; 400 // Use StrictMock to make 100% sure we know how GL will be called. 401 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 402 scoped_refptr<FeatureInfo> feature_info_; 403 scoped_ptr<TextureManager> manager_; 404 scoped_refptr<TextureRef> texture_ref_; 405 }; 406 407 class TextureTest : public TextureTestBase { 408 protected: 409 virtual void SetUp() { 410 SetUpBase(NULL, std::string()); 411 } 412 }; 413 414 class TextureMemoryTrackerTest : public TextureTestBase { 415 protected: 416 virtual void SetUp() { 417 mock_memory_tracker_ = new StrictMock<MockMemoryTracker>(); 418 SetUpBase(mock_memory_tracker_.get(), std::string()); 419 } 420 421 scoped_refptr<MockMemoryTracker> mock_memory_tracker_; 422 }; 423 424 #define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size, pool) \ 425 EXPECT_CALL(*mock_memory_tracker_.get(), \ 426 TrackMemoryAllocatedChange(old_size, new_size, pool)) \ 427 .Times(1).RetiresOnSaturation() 428 429 TEST_F(TextureTest, Basic) { 430 Texture* texture = texture_ref_->texture(); 431 EXPECT_EQ(0u, texture->target()); 432 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 433 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 434 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 435 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 436 EXPECT_EQ(0, texture->num_uncleared_mips()); 437 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 438 EXPECT_TRUE(texture->SafeToRenderFrom()); 439 EXPECT_FALSE(texture->IsImmutable()); 440 EXPECT_EQ(static_cast<GLenum>(GL_NEAREST_MIPMAP_LINEAR), 441 texture->min_filter()); 442 EXPECT_EQ(static_cast<GLenum>(GL_LINEAR), texture->mag_filter()); 443 EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), texture->wrap_s()); 444 EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), texture->wrap_t()); 445 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 446 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 447 EXPECT_EQ(0u, texture->estimated_size()); 448 } 449 450 TEST_F(TextureTest, SetTargetTexture2D) { 451 Texture* texture = texture_ref_->texture(); 452 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 453 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 454 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 455 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 456 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 457 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 458 EXPECT_TRUE(texture->SafeToRenderFrom()); 459 EXPECT_FALSE(texture->IsImmutable()); 460 } 461 462 TEST_F(TextureTest, SetTargetTextureExternalOES) { 463 Texture* texture = texture_ref_->texture(); 464 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); 465 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 466 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 467 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 468 EXPECT_TRUE(TextureTestHelper::IsNPOT(texture)); 469 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 470 EXPECT_TRUE(texture->SafeToRenderFrom()); 471 EXPECT_TRUE(texture->IsImmutable()); 472 manager_->SetStreamTexture(texture_ref_.get(), true); 473 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 474 } 475 476 TEST_F(TextureTest, ZeroSizeCanNotRender) { 477 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 478 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 479 manager_->SetLevelInfo(texture_ref_.get(), 480 GL_TEXTURE_2D, 481 0, 482 GL_RGBA, 483 1, 484 1, 485 1, 486 0, 487 GL_RGBA, 488 GL_UNSIGNED_BYTE, 489 true); 490 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 491 manager_->SetLevelInfo(texture_ref_.get(), 492 GL_TEXTURE_2D, 493 0, 494 GL_RGBA, 495 0, 496 0, 497 1, 498 0, 499 GL_RGBA, 500 GL_UNSIGNED_BYTE, 501 true); 502 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 503 } 504 505 TEST_F(TextureTest, EstimatedSize) { 506 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 507 manager_->SetLevelInfo(texture_ref_.get(), 508 GL_TEXTURE_2D, 509 0, 510 GL_RGBA, 511 8, 512 4, 513 1, 514 0, 515 GL_RGBA, 516 GL_UNSIGNED_BYTE, 517 true); 518 EXPECT_EQ(8u * 4u * 4u, texture_ref_->texture()->estimated_size()); 519 manager_->SetLevelInfo(texture_ref_.get(), 520 GL_TEXTURE_2D, 521 2, 522 GL_RGBA, 523 8, 524 4, 525 1, 526 0, 527 GL_RGBA, 528 GL_UNSIGNED_BYTE, 529 true); 530 EXPECT_EQ(8u * 4u * 4u * 2u, texture_ref_->texture()->estimated_size()); 531 } 532 533 TEST_F(TextureMemoryTrackerTest, EstimatedSize) { 534 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 535 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kUnmanaged); 536 manager_->SetLevelInfo(texture_ref_.get(), 537 GL_TEXTURE_2D, 538 0, 539 GL_RGBA, 540 8, 541 4, 542 1, 543 0, 544 GL_RGBA, 545 GL_UNSIGNED_BYTE, 546 true); 547 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kUnmanaged); 548 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 256, MemoryTracker::kUnmanaged); 549 manager_->SetLevelInfo(texture_ref_.get(), 550 GL_TEXTURE_2D, 551 2, 552 GL_RGBA, 553 8, 554 4, 555 1, 556 0, 557 GL_RGBA, 558 GL_UNSIGNED_BYTE, 559 true); 560 // Add expectation for texture deletion. 561 EXPECT_MEMORY_ALLOCATION_CHANGE(256, 0, MemoryTracker::kUnmanaged); 562 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 563 } 564 565 TEST_F(TextureMemoryTrackerTest, SetParameterPool) { 566 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 567 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kUnmanaged); 568 manager_->SetLevelInfo(texture_ref_.get(), 569 GL_TEXTURE_2D, 570 0, 571 GL_RGBA, 572 8, 573 4, 574 1, 575 0, 576 GL_RGBA, 577 GL_UNSIGNED_BYTE, 578 true); 579 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kUnmanaged); 580 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 128, MemoryTracker::kManaged); 581 SetParameter(texture_ref_.get(), 582 GL_TEXTURE_POOL_CHROMIUM, 583 GL_TEXTURE_POOL_MANAGED_CHROMIUM, 584 GL_NO_ERROR); 585 // Add expectation for texture deletion. 586 EXPECT_MEMORY_ALLOCATION_CHANGE(128, 0, MemoryTracker::kManaged); 587 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 588 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kManaged); 589 } 590 591 TEST_F(TextureTest, POT2D) { 592 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 593 Texture* texture = texture_ref_->texture(); 594 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 595 // Check Setting level 0 to POT 596 manager_->SetLevelInfo(texture_ref_.get(), 597 GL_TEXTURE_2D, 598 0, 599 GL_RGBA, 600 4, 601 4, 602 1, 603 0, 604 GL_RGBA, 605 GL_UNSIGNED_BYTE, 606 true); 607 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 608 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 609 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 610 EXPECT_EQ(0, texture->num_uncleared_mips()); 611 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 612 // Set filters to something that will work with a single mip. 613 SetParameter( 614 texture_ref_.get(), GL_TEXTURE_MIN_FILTER, GL_LINEAR, GL_NO_ERROR); 615 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 616 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 617 // Set them back. 618 SetParameter(texture_ref_.get(), 619 GL_TEXTURE_MIN_FILTER, 620 GL_LINEAR_MIPMAP_LINEAR, 621 GL_NO_ERROR); 622 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 623 624 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 625 // Make mips. 626 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 627 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 628 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 629 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 630 // Change a mip. 631 manager_->SetLevelInfo(texture_ref_.get(), 632 GL_TEXTURE_2D, 633 1, 634 GL_RGBA, 635 4, 636 4, 637 1, 638 0, 639 GL_RGBA, 640 GL_UNSIGNED_BYTE, 641 true); 642 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 643 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 644 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 645 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 646 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 647 // Set a level past the number of mips that would get generated. 648 manager_->SetLevelInfo(texture_ref_.get(), 649 GL_TEXTURE_2D, 650 3, 651 GL_RGBA, 652 4, 653 4, 654 1, 655 0, 656 GL_RGBA, 657 GL_UNSIGNED_BYTE, 658 true); 659 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 660 // Make mips. 661 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 662 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 663 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 664 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 665 } 666 667 TEST_F(TextureMemoryTrackerTest, MarkMipmapsGenerated) { 668 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 669 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 64, MemoryTracker::kUnmanaged); 670 manager_->SetLevelInfo(texture_ref_.get(), 671 GL_TEXTURE_2D, 672 0, 673 GL_RGBA, 674 4, 675 4, 676 1, 677 0, 678 GL_RGBA, 679 GL_UNSIGNED_BYTE, 680 true); 681 EXPECT_MEMORY_ALLOCATION_CHANGE(64, 0, MemoryTracker::kUnmanaged); 682 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 84, MemoryTracker::kUnmanaged); 683 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 684 EXPECT_MEMORY_ALLOCATION_CHANGE(84, 0, MemoryTracker::kUnmanaged); 685 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged); 686 } 687 688 TEST_F(TextureTest, UnusedMips) { 689 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 690 Texture* texture = texture_ref_->texture(); 691 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 692 // Set level zero to large size. 693 manager_->SetLevelInfo(texture_ref_.get(), 694 GL_TEXTURE_2D, 695 0, 696 GL_RGBA, 697 4, 698 4, 699 1, 700 0, 701 GL_RGBA, 702 GL_UNSIGNED_BYTE, 703 true); 704 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 705 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 706 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 707 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 708 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 709 // Set level zero to large smaller (levels unused mips) 710 manager_->SetLevelInfo(texture_ref_.get(), 711 GL_TEXTURE_2D, 712 0, 713 GL_RGBA, 714 2, 715 2, 716 1, 717 0, 718 GL_RGBA, 719 GL_UNSIGNED_BYTE, 720 true); 721 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 722 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 723 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 724 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 725 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 726 // Set an unused level to some size 727 manager_->SetLevelInfo(texture_ref_.get(), 728 GL_TEXTURE_2D, 729 4, 730 GL_RGBA, 731 16, 732 16, 733 1, 734 0, 735 GL_RGBA, 736 GL_UNSIGNED_BYTE, 737 true); 738 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 739 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 740 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 741 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 742 } 743 744 TEST_F(TextureTest, NPOT2D) { 745 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 746 Texture* texture = texture_ref_->texture(); 747 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 748 // Check Setting level 0 to NPOT 749 manager_->SetLevelInfo(texture_ref_.get(), 750 GL_TEXTURE_2D, 751 0, 752 GL_RGBA, 753 4, 754 5, 755 1, 756 0, 757 GL_RGBA, 758 GL_UNSIGNED_BYTE, 759 true); 760 EXPECT_TRUE(TextureTestHelper::IsNPOT(texture)); 761 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 762 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 763 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 764 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 765 SetParameter( 766 texture_ref_.get(), GL_TEXTURE_MIN_FILTER, GL_LINEAR, GL_NO_ERROR); 767 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 768 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 769 SetParameter( 770 texture_ref_.get(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 771 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 772 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 773 SetParameter( 774 texture_ref_.get(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 775 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 776 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 777 // Change it to POT. 778 manager_->SetLevelInfo(texture_ref_.get(), 779 GL_TEXTURE_2D, 780 0, 781 GL_RGBA, 782 4, 783 4, 784 1, 785 0, 786 GL_RGBA, 787 GL_UNSIGNED_BYTE, 788 true); 789 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 790 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 791 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 792 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 793 } 794 795 TEST_F(TextureTest, NPOT2DNPOTOK) { 796 TestHelper::SetupFeatureInfoInitExpectations( 797 gl_.get(), "GL_OES_texture_npot"); 798 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 799 feature_info->Initialize(NULL); 800 TextureManager manager( 801 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 802 manager.CreateTexture(kClient1Id, kService1Id); 803 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 804 ASSERT_TRUE(texture_ref != NULL); 805 Texture* texture = texture_ref->texture(); 806 807 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 808 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 809 // Check Setting level 0 to NPOT 810 manager.SetLevelInfo(texture_ref, 811 GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 812 EXPECT_TRUE(TextureTestHelper::IsNPOT(texture)); 813 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 814 EXPECT_TRUE(manager.CanGenerateMipmaps(texture_ref)); 815 EXPECT_FALSE(manager.CanRender(texture_ref)); 816 EXPECT_TRUE(manager.HaveUnrenderableTextures()); 817 EXPECT_TRUE(manager.MarkMipmapsGenerated(texture_ref)); 818 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 819 EXPECT_TRUE(manager.CanRender(texture_ref)); 820 EXPECT_FALSE(manager.HaveUnrenderableTextures()); 821 manager.Destroy(false); 822 } 823 824 TEST_F(TextureTest, POTCubeMap) { 825 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_CUBE_MAP); 826 Texture* texture = texture_ref_->texture(); 827 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), texture->target()); 828 // Check Setting level 0 each face to POT 829 manager_->SetLevelInfo(texture_ref_.get(), 830 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 831 0, 832 GL_RGBA, 833 4, 834 4, 835 1, 836 0, 837 GL_RGBA, 838 GL_UNSIGNED_BYTE, 839 true); 840 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 841 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 842 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 843 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 844 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 845 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 846 manager_->SetLevelInfo(texture_ref_.get(), 847 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 848 0, 849 GL_RGBA, 850 4, 851 4, 852 1, 853 0, 854 GL_RGBA, 855 GL_UNSIGNED_BYTE, 856 true); 857 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 858 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 859 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 860 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 861 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 862 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 863 manager_->SetLevelInfo(texture_ref_.get(), 864 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 865 0, 866 GL_RGBA, 867 4, 868 4, 869 1, 870 0, 871 GL_RGBA, 872 GL_UNSIGNED_BYTE, 873 true); 874 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 875 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 876 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 877 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 878 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 879 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 880 manager_->SetLevelInfo(texture_ref_.get(), 881 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 882 0, 883 GL_RGBA, 884 4, 885 4, 886 1, 887 0, 888 GL_RGBA, 889 GL_UNSIGNED_BYTE, 890 true); 891 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 892 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 893 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 894 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 895 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 896 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 897 manager_->SetLevelInfo(texture_ref_.get(), 898 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 899 0, 900 GL_RGBA, 901 4, 902 4, 903 1, 904 0, 905 GL_RGBA, 906 GL_UNSIGNED_BYTE, 907 true); 908 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 909 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 910 EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); 911 EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); 912 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 913 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 914 manager_->SetLevelInfo(texture_ref_.get(), 915 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 916 0, 917 GL_RGBA, 918 4, 919 4, 920 1, 921 0, 922 GL_RGBA, 923 GL_UNSIGNED_BYTE, 924 true); 925 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 926 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 927 EXPECT_TRUE(TextureTestHelper::IsCubeComplete(texture)); 928 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 929 EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); 930 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 931 932 // Make mips. 933 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 934 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 935 EXPECT_TRUE(TextureTestHelper::IsCubeComplete(texture)); 936 EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); 937 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 938 939 // Change a mip. 940 manager_->SetLevelInfo(texture_ref_.get(), 941 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 942 1, 943 GL_RGBA, 944 4, 945 4, 946 1, 947 0, 948 GL_RGBA, 949 GL_UNSIGNED_BYTE, 950 true); 951 EXPECT_FALSE(TextureTestHelper::IsNPOT(texture)); 952 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 953 EXPECT_TRUE(TextureTestHelper::IsCubeComplete(texture)); 954 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 955 // Set a level past the number of mips that would get generated. 956 manager_->SetLevelInfo(texture_ref_.get(), 957 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 958 3, 959 GL_RGBA, 960 4, 961 4, 962 1, 963 0, 964 GL_RGBA, 965 GL_UNSIGNED_BYTE, 966 true); 967 EXPECT_TRUE(manager_->CanGenerateMipmaps(texture_ref_.get())); 968 // Make mips. 969 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 970 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 971 EXPECT_TRUE(TextureTestHelper::IsCubeComplete(texture)); 972 } 973 974 TEST_F(TextureTest, GetLevelSize) { 975 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 976 manager_->SetLevelInfo(texture_ref_.get(), 977 GL_TEXTURE_2D, 978 1, 979 GL_RGBA, 980 4, 981 5, 982 1, 983 0, 984 GL_RGBA, 985 GL_UNSIGNED_BYTE, 986 true); 987 GLsizei width = -1; 988 GLsizei height = -1; 989 Texture* texture = texture_ref_->texture(); 990 EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, -1, &width, &height)); 991 EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 1000, &width, &height)); 992 EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); 993 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); 994 EXPECT_EQ(4, width); 995 EXPECT_EQ(5, height); 996 manager_->RemoveTexture(kClient1Id); 997 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); 998 EXPECT_EQ(4, width); 999 EXPECT_EQ(5, height); 1000 } 1001 1002 TEST_F(TextureTest, GetLevelType) { 1003 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1004 manager_->SetLevelInfo(texture_ref_.get(), 1005 GL_TEXTURE_2D, 1006 1, 1007 GL_RGBA, 1008 4, 1009 5, 1010 1, 1011 0, 1012 GL_RGBA, 1013 GL_UNSIGNED_BYTE, 1014 true); 1015 GLenum type = -1; 1016 GLenum format = -1; 1017 Texture* texture = texture_ref_->texture(); 1018 EXPECT_FALSE(texture->GetLevelType(GL_TEXTURE_2D, -1, &type, &format)); 1019 EXPECT_FALSE(texture->GetLevelType(GL_TEXTURE_2D, 1000, &type, &format)); 1020 EXPECT_FALSE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &format)); 1021 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &format)); 1022 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); 1023 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format); 1024 manager_->RemoveTexture(kClient1Id); 1025 EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &format)); 1026 EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); 1027 EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format); 1028 } 1029 1030 TEST_F(TextureTest, ValidForTexture) { 1031 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1032 manager_->SetLevelInfo(texture_ref_.get(), 1033 GL_TEXTURE_2D, 1034 1, 1035 GL_RGBA, 1036 4, 1037 5, 1038 1, 1039 0, 1040 GL_RGBA, 1041 GL_UNSIGNED_BYTE, 1042 true); 1043 // Check bad face. 1044 Texture* texture = texture_ref_->texture(); 1045 EXPECT_FALSE(texture->ValidForTexture( 1046 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1047 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1048 // Check bad level. 1049 EXPECT_FALSE(texture->ValidForTexture( 1050 GL_TEXTURE_2D, 0, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1051 // Check bad xoffset. 1052 EXPECT_FALSE(texture->ValidForTexture( 1053 GL_TEXTURE_2D, 1, -1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1054 // Check bad xoffset + width > width. 1055 EXPECT_FALSE(texture->ValidForTexture( 1056 GL_TEXTURE_2D, 1, 1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1057 // Check bad yoffset. 1058 EXPECT_FALSE(texture->ValidForTexture( 1059 GL_TEXTURE_2D, 1, 0, -1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1060 // Check bad yoffset + height > height. 1061 EXPECT_FALSE(texture->ValidForTexture( 1062 GL_TEXTURE_2D, 1, 0, 1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1063 // Check bad width. 1064 EXPECT_FALSE(texture->ValidForTexture( 1065 GL_TEXTURE_2D, 1, 0, 0, 5, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1066 // Check bad height. 1067 EXPECT_FALSE(texture->ValidForTexture( 1068 GL_TEXTURE_2D, 1, 0, 0, 4, 6, GL_RGBA, GL_UNSIGNED_BYTE)); 1069 // Check bad format. 1070 EXPECT_FALSE(texture->ValidForTexture( 1071 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGB, GL_UNSIGNED_BYTE)); 1072 // Check bad type. 1073 EXPECT_FALSE(texture->ValidForTexture( 1074 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)); 1075 // Check valid full size 1076 EXPECT_TRUE(texture->ValidForTexture( 1077 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1078 // Check valid particial size. 1079 EXPECT_TRUE(texture->ValidForTexture( 1080 GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_RGBA, GL_UNSIGNED_BYTE)); 1081 manager_->RemoveTexture(kClient1Id); 1082 EXPECT_TRUE(texture->ValidForTexture( 1083 GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE)); 1084 } 1085 1086 TEST_F(TextureTest, FloatNotLinear) { 1087 TestHelper::SetupFeatureInfoInitExpectations( 1088 gl_.get(), "GL_OES_texture_float"); 1089 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1090 feature_info->Initialize(NULL); 1091 TextureManager manager( 1092 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1093 manager.CreateTexture(kClient1Id, kService1Id); 1094 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1095 ASSERT_TRUE(texture_ref != NULL); 1096 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 1097 Texture* texture = texture_ref->texture(); 1098 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 1099 manager.SetLevelInfo(texture_ref, 1100 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT, true); 1101 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 1102 TestHelper::SetTexParameterWithExpectations( 1103 gl_.get(), error_state_.get(), &manager, 1104 texture_ref, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 1105 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 1106 TestHelper::SetTexParameterWithExpectations( 1107 gl_.get(), error_state_.get(), &manager, texture_ref, 1108 GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); 1109 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1110 manager.Destroy(false); 1111 } 1112 1113 TEST_F(TextureTest, FloatLinear) { 1114 TestHelper::SetupFeatureInfoInitExpectations( 1115 gl_.get(), "GL_OES_texture_float GL_OES_texture_float_linear"); 1116 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1117 feature_info->Initialize(NULL); 1118 TextureManager manager( 1119 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1120 manager.CreateTexture(kClient1Id, kService1Id); 1121 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1122 ASSERT_TRUE(texture_ref != NULL); 1123 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 1124 Texture* texture = texture_ref->texture(); 1125 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 1126 manager.SetLevelInfo(texture_ref, 1127 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT, true); 1128 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1129 manager.Destroy(false); 1130 } 1131 1132 TEST_F(TextureTest, HalfFloatNotLinear) { 1133 TestHelper::SetupFeatureInfoInitExpectations( 1134 gl_.get(), "GL_OES_texture_half_float"); 1135 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1136 feature_info->Initialize(NULL); 1137 TextureManager manager( 1138 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1139 manager.CreateTexture(kClient1Id, kService1Id); 1140 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1141 ASSERT_TRUE(texture_ref != NULL); 1142 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 1143 Texture* texture = texture_ref->texture(); 1144 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 1145 manager.SetLevelInfo(texture_ref, 1146 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES, true); 1147 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 1148 TestHelper::SetTexParameterWithExpectations( 1149 gl_.get(), error_state_.get(), &manager, 1150 texture_ref, GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 1151 EXPECT_FALSE(TextureTestHelper::IsTextureComplete(texture)); 1152 TestHelper::SetTexParameterWithExpectations( 1153 gl_.get(), error_state_.get(), &manager, texture_ref, 1154 GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST, GL_NO_ERROR); 1155 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1156 manager.Destroy(false); 1157 } 1158 1159 TEST_F(TextureTest, HalfFloatLinear) { 1160 TestHelper::SetupFeatureInfoInitExpectations( 1161 gl_.get(), "GL_OES_texture_half_float GL_OES_texture_half_float_linear"); 1162 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1163 feature_info->Initialize(NULL); 1164 TextureManager manager( 1165 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1166 manager.CreateTexture(kClient1Id, kService1Id); 1167 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1168 ASSERT_TRUE(texture_ref != NULL); 1169 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 1170 Texture* texture = texture_ref->texture(); 1171 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 1172 manager.SetLevelInfo(texture_ref, 1173 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES, true); 1174 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1175 manager.Destroy(false); 1176 } 1177 1178 TEST_F(TextureTest, EGLImageExternal) { 1179 TestHelper::SetupFeatureInfoInitExpectations( 1180 gl_.get(), "GL_OES_EGL_image_external"); 1181 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1182 feature_info->Initialize(NULL); 1183 TextureManager manager( 1184 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1185 manager.CreateTexture(kClient1Id, kService1Id); 1186 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1187 ASSERT_TRUE(texture_ref != NULL); 1188 manager.SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES); 1189 Texture* texture = texture_ref->texture(); 1190 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), texture->target()); 1191 EXPECT_FALSE(manager.CanGenerateMipmaps(texture_ref)); 1192 manager.Destroy(false); 1193 } 1194 1195 TEST_F(TextureTest, DepthTexture) { 1196 TestHelper::SetupFeatureInfoInitExpectations( 1197 gl_.get(), "GL_ANGLE_depth_texture"); 1198 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo()); 1199 feature_info->Initialize(NULL); 1200 TextureManager manager( 1201 NULL, feature_info.get(), kMaxTextureSize, kMaxCubeMapTextureSize); 1202 manager.CreateTexture(kClient1Id, kService1Id); 1203 TextureRef* texture_ref = manager.GetTexture(kClient1Id); 1204 ASSERT_TRUE(texture_ref != NULL); 1205 manager.SetTarget(texture_ref, GL_TEXTURE_2D); 1206 manager.SetLevelInfo( 1207 texture_ref, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 4, 4, 1, 0, 1208 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false); 1209 EXPECT_FALSE(manager.CanGenerateMipmaps(texture_ref)); 1210 manager.Destroy(false); 1211 } 1212 1213 TEST_F(TextureTest, SafeUnsafe) { 1214 static const GLuint kClient2Id = 2; 1215 static const GLuint kService2Id = 12; 1216 static const GLuint kClient3Id = 3; 1217 static const GLuint kService3Id = 13; 1218 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1219 Texture* texture = texture_ref_->texture(); 1220 EXPECT_EQ(0, texture->num_uncleared_mips()); 1221 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1222 manager_->SetLevelInfo(texture_ref_.get(), 1223 GL_TEXTURE_2D, 1224 0, 1225 GL_RGBA, 1226 4, 1227 4, 1228 1, 1229 0, 1230 GL_RGBA, 1231 GL_UNSIGNED_BYTE, 1232 false); 1233 EXPECT_FALSE(texture->SafeToRenderFrom()); 1234 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1235 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1236 EXPECT_EQ(1, texture->num_uncleared_mips()); 1237 manager_->SetLevelCleared(texture_ref_.get(), GL_TEXTURE_2D, 0, true); 1238 EXPECT_TRUE(texture->SafeToRenderFrom()); 1239 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1240 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1241 EXPECT_EQ(0, texture->num_uncleared_mips()); 1242 manager_->SetLevelInfo(texture_ref_.get(), 1243 GL_TEXTURE_2D, 1244 1, 1245 GL_RGBA, 1246 8, 1247 8, 1248 1, 1249 0, 1250 GL_RGBA, 1251 GL_UNSIGNED_BYTE, 1252 false); 1253 EXPECT_FALSE(texture->SafeToRenderFrom()); 1254 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1255 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1256 EXPECT_EQ(1, texture->num_uncleared_mips()); 1257 manager_->SetLevelCleared(texture_ref_.get(), GL_TEXTURE_2D, 1, true); 1258 EXPECT_TRUE(texture->SafeToRenderFrom()); 1259 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1260 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1261 EXPECT_EQ(0, texture->num_uncleared_mips()); 1262 manager_->SetLevelInfo(texture_ref_.get(), 1263 GL_TEXTURE_2D, 1264 0, 1265 GL_RGBA, 1266 4, 1267 4, 1268 1, 1269 0, 1270 GL_RGBA, 1271 GL_UNSIGNED_BYTE, 1272 false); 1273 manager_->SetLevelInfo(texture_ref_.get(), 1274 GL_TEXTURE_2D, 1275 1, 1276 GL_RGBA, 1277 8, 1278 8, 1279 1, 1280 0, 1281 GL_RGBA, 1282 GL_UNSIGNED_BYTE, 1283 false); 1284 EXPECT_FALSE(texture->SafeToRenderFrom()); 1285 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1286 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1287 EXPECT_EQ(2, texture->num_uncleared_mips()); 1288 manager_->SetLevelCleared(texture_ref_.get(), GL_TEXTURE_2D, 0, true); 1289 EXPECT_FALSE(texture->SafeToRenderFrom()); 1290 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1291 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1292 EXPECT_EQ(1, texture->num_uncleared_mips()); 1293 manager_->SetLevelCleared(texture_ref_.get(), GL_TEXTURE_2D, 1, true); 1294 EXPECT_TRUE(texture->SafeToRenderFrom()); 1295 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1296 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1297 EXPECT_EQ(0, texture->num_uncleared_mips()); 1298 manager_->SetLevelInfo(texture_ref_.get(), 1299 GL_TEXTURE_2D, 1300 1, 1301 GL_RGBA, 1302 8, 1303 8, 1304 1, 1305 0, 1306 GL_RGBA, 1307 GL_UNSIGNED_BYTE, 1308 false); 1309 EXPECT_FALSE(texture->SafeToRenderFrom()); 1310 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1311 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1312 EXPECT_EQ(1, texture->num_uncleared_mips()); 1313 manager_->MarkMipmapsGenerated(texture_ref_.get()); 1314 EXPECT_TRUE(texture->SafeToRenderFrom()); 1315 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1316 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1317 EXPECT_EQ(0, texture->num_uncleared_mips()); 1318 1319 manager_->CreateTexture(kClient2Id, kService2Id); 1320 scoped_refptr<TextureRef> texture_ref2( 1321 manager_->GetTexture(kClient2Id)); 1322 ASSERT_TRUE(texture_ref2.get() != NULL); 1323 manager_->SetTarget(texture_ref2.get(), GL_TEXTURE_2D); 1324 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1325 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1326 Texture* texture2 = texture_ref2->texture(); 1327 EXPECT_EQ(0, texture2->num_uncleared_mips()); 1328 manager_->SetLevelInfo(texture_ref2.get(), 1329 GL_TEXTURE_2D, 1330 0, 1331 GL_RGBA, 1332 8, 1333 8, 1334 1, 1335 0, 1336 GL_RGBA, 1337 GL_UNSIGNED_BYTE, 1338 true); 1339 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1340 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1341 EXPECT_EQ(0, texture2->num_uncleared_mips()); 1342 manager_->SetLevelInfo(texture_ref2.get(), 1343 GL_TEXTURE_2D, 1344 0, 1345 GL_RGBA, 1346 8, 1347 8, 1348 1, 1349 0, 1350 GL_RGBA, 1351 GL_UNSIGNED_BYTE, 1352 false); 1353 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1354 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1355 EXPECT_EQ(1, texture2->num_uncleared_mips()); 1356 1357 manager_->CreateTexture(kClient3Id, kService3Id); 1358 scoped_refptr<TextureRef> texture_ref3( 1359 manager_->GetTexture(kClient3Id)); 1360 ASSERT_TRUE(texture_ref3.get() != NULL); 1361 manager_->SetTarget(texture_ref3.get(), GL_TEXTURE_2D); 1362 manager_->SetLevelInfo(texture_ref3.get(), 1363 GL_TEXTURE_2D, 1364 0, 1365 GL_RGBA, 1366 8, 1367 8, 1368 1, 1369 0, 1370 GL_RGBA, 1371 GL_UNSIGNED_BYTE, 1372 false); 1373 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1374 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1375 Texture* texture3 = texture_ref3->texture(); 1376 EXPECT_EQ(1, texture3->num_uncleared_mips()); 1377 manager_->SetLevelCleared(texture_ref2.get(), GL_TEXTURE_2D, 0, true); 1378 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1379 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1380 EXPECT_EQ(0, texture2->num_uncleared_mips()); 1381 manager_->SetLevelCleared(texture_ref3.get(), GL_TEXTURE_2D, 0, true); 1382 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1383 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1384 EXPECT_EQ(0, texture3->num_uncleared_mips()); 1385 1386 manager_->SetLevelInfo(texture_ref2.get(), 1387 GL_TEXTURE_2D, 1388 0, 1389 GL_RGBA, 1390 8, 1391 8, 1392 1, 1393 0, 1394 GL_RGBA, 1395 GL_UNSIGNED_BYTE, 1396 false); 1397 manager_->SetLevelInfo(texture_ref3.get(), 1398 GL_TEXTURE_2D, 1399 0, 1400 GL_RGBA, 1401 8, 1402 8, 1403 1, 1404 0, 1405 GL_RGBA, 1406 GL_UNSIGNED_BYTE, 1407 false); 1408 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1409 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1410 EXPECT_EQ(1, texture2->num_uncleared_mips()); 1411 EXPECT_EQ(1, texture3->num_uncleared_mips()); 1412 manager_->RemoveTexture(kClient3Id); 1413 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1414 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1415 manager_->RemoveTexture(kClient2Id); 1416 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1417 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1418 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService2Id))) 1419 .Times(1) 1420 .RetiresOnSaturation(); 1421 texture_ref2 = NULL; 1422 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1423 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1424 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService3Id))) 1425 .Times(1) 1426 .RetiresOnSaturation(); 1427 texture_ref3 = NULL; 1428 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1429 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1430 } 1431 1432 TEST_F(TextureTest, ClearTexture) { 1433 EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) 1434 .WillRepeatedly(Return(true)); 1435 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1436 manager_->SetLevelInfo(texture_ref_.get(), 1437 GL_TEXTURE_2D, 1438 0, 1439 GL_RGBA, 1440 4, 1441 4, 1442 1, 1443 0, 1444 GL_RGBA, 1445 GL_UNSIGNED_BYTE, 1446 false); 1447 manager_->SetLevelInfo(texture_ref_.get(), 1448 GL_TEXTURE_2D, 1449 1, 1450 GL_RGBA, 1451 4, 1452 4, 1453 1, 1454 0, 1455 GL_RGBA, 1456 GL_UNSIGNED_BYTE, 1457 false); 1458 Texture* texture = texture_ref_->texture(); 1459 EXPECT_FALSE(texture->SafeToRenderFrom()); 1460 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1461 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1462 EXPECT_EQ(2, texture->num_uncleared_mips()); 1463 manager_->ClearRenderableLevels(decoder_.get(), texture_ref_.get()); 1464 EXPECT_TRUE(texture->SafeToRenderFrom()); 1465 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1466 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1467 EXPECT_EQ(0, texture->num_uncleared_mips()); 1468 manager_->SetLevelInfo(texture_ref_.get(), 1469 GL_TEXTURE_2D, 1470 0, 1471 GL_RGBA, 1472 4, 1473 4, 1474 1, 1475 0, 1476 GL_RGBA, 1477 GL_UNSIGNED_BYTE, 1478 false); 1479 manager_->SetLevelInfo(texture_ref_.get(), 1480 GL_TEXTURE_2D, 1481 1, 1482 GL_RGBA, 1483 4, 1484 4, 1485 1, 1486 0, 1487 GL_RGBA, 1488 GL_UNSIGNED_BYTE, 1489 false); 1490 EXPECT_FALSE(texture->SafeToRenderFrom()); 1491 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1492 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1493 EXPECT_EQ(2, texture->num_uncleared_mips()); 1494 manager_->ClearTextureLevel( 1495 decoder_.get(), texture_ref_.get(), GL_TEXTURE_2D, 0); 1496 EXPECT_FALSE(texture->SafeToRenderFrom()); 1497 EXPECT_TRUE(manager_->HaveUnsafeTextures()); 1498 EXPECT_TRUE(manager_->HaveUnclearedMips()); 1499 EXPECT_EQ(1, texture->num_uncleared_mips()); 1500 manager_->ClearTextureLevel( 1501 decoder_.get(), texture_ref_.get(), GL_TEXTURE_2D, 1); 1502 EXPECT_TRUE(texture->SafeToRenderFrom()); 1503 EXPECT_FALSE(manager_->HaveUnsafeTextures()); 1504 EXPECT_FALSE(manager_->HaveUnclearedMips()); 1505 EXPECT_EQ(0, texture->num_uncleared_mips()); 1506 } 1507 1508 TEST_F(TextureTest, UseDeletedTexture) { 1509 static const GLuint kClient2Id = 2; 1510 static const GLuint kService2Id = 12; 1511 // Make the default texture renderable 1512 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1513 manager_->SetLevelInfo(texture_ref_.get(), 1514 GL_TEXTURE_2D, 1515 0, 1516 GL_RGBA, 1517 1, 1518 1, 1519 1, 1520 0, 1521 GL_RGBA, 1522 GL_UNSIGNED_BYTE, 1523 false); 1524 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 1525 // Make a new texture 1526 manager_->CreateTexture(kClient2Id, kService2Id); 1527 scoped_refptr<TextureRef> texture_ref( 1528 manager_->GetTexture(kClient2Id)); 1529 manager_->SetTarget(texture_ref.get(), GL_TEXTURE_2D); 1530 EXPECT_FALSE(manager_->CanRender(texture_ref.get())); 1531 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 1532 // Remove it. 1533 manager_->RemoveTexture(kClient2Id); 1534 EXPECT_FALSE(manager_->CanRender(texture_ref.get())); 1535 EXPECT_TRUE(manager_->HaveUnrenderableTextures()); 1536 // Check that we can still manipulate it and it effects the manager. 1537 manager_->SetLevelInfo(texture_ref.get(), 1538 GL_TEXTURE_2D, 1539 0, 1540 GL_RGBA, 1541 1, 1542 1, 1543 1, 1544 0, 1545 GL_RGBA, 1546 GL_UNSIGNED_BYTE, 1547 false); 1548 EXPECT_TRUE(manager_->CanRender(texture_ref.get())); 1549 EXPECT_FALSE(manager_->HaveUnrenderableTextures()); 1550 EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService2Id))) 1551 .Times(1) 1552 .RetiresOnSaturation(); 1553 texture_ref = NULL; 1554 } 1555 1556 TEST_F(TextureTest, GetLevelImage) { 1557 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1558 manager_->SetLevelInfo(texture_ref_.get(), 1559 GL_TEXTURE_2D, 1560 1, 1561 GL_RGBA, 1562 2, 1563 2, 1564 1, 1565 0, 1566 GL_RGBA, 1567 GL_UNSIGNED_BYTE, 1568 true); 1569 Texture* texture = texture_ref_->texture(); 1570 EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1571 // Set image. 1572 manager_->SetLevelImage(texture_ref_.get(), 1573 GL_TEXTURE_2D, 1574 1, 1575 gfx::GLImage::CreateGLImage(0).get()); 1576 EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1577 // Remove it. 1578 manager_->SetLevelImage(texture_ref_.get(), GL_TEXTURE_2D, 1, NULL); 1579 EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1580 manager_->SetLevelImage(texture_ref_.get(), 1581 GL_TEXTURE_2D, 1582 1, 1583 gfx::GLImage::CreateGLImage(0).get()); 1584 // Image should be reset when SetLevelInfo is called. 1585 manager_->SetLevelInfo(texture_ref_.get(), 1586 GL_TEXTURE_2D, 1587 1, 1588 GL_RGBA, 1589 2, 1590 2, 1591 1, 1592 0, 1593 GL_RGBA, 1594 GL_UNSIGNED_BYTE, 1595 true); 1596 EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 1) == NULL); 1597 } 1598 1599 namespace { 1600 1601 bool InSet(std::set<std::string>* string_set, const std::string& str) { 1602 std::pair<std::set<std::string>::iterator, bool> result = 1603 string_set->insert(str); 1604 return !result.second; 1605 } 1606 1607 } // anonymous namespace 1608 1609 TEST_F(TextureTest, AddToSignature) { 1610 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1611 manager_->SetLevelInfo(texture_ref_.get(), 1612 GL_TEXTURE_2D, 1613 1, 1614 GL_RGBA, 1615 2, 1616 2, 1617 1, 1618 0, 1619 GL_RGBA, 1620 GL_UNSIGNED_BYTE, 1621 true); 1622 std::string signature1; 1623 std::string signature2; 1624 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature1); 1625 1626 std::set<std::string> string_set; 1627 EXPECT_FALSE(InSet(&string_set, signature1)); 1628 1629 // check changing 1 thing makes a different signature. 1630 manager_->SetLevelInfo(texture_ref_.get(), 1631 GL_TEXTURE_2D, 1632 1, 1633 GL_RGBA, 1634 4, 1635 2, 1636 1, 1637 0, 1638 GL_RGBA, 1639 GL_UNSIGNED_BYTE, 1640 true); 1641 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1642 EXPECT_FALSE(InSet(&string_set, signature2)); 1643 1644 // check putting it back makes the same signature. 1645 manager_->SetLevelInfo(texture_ref_.get(), 1646 GL_TEXTURE_2D, 1647 1, 1648 GL_RGBA, 1649 2, 1650 2, 1651 1, 1652 0, 1653 GL_RGBA, 1654 GL_UNSIGNED_BYTE, 1655 true); 1656 signature2.clear(); 1657 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1658 EXPECT_EQ(signature1, signature2); 1659 1660 // Check setting cleared status does not change signature. 1661 manager_->SetLevelInfo(texture_ref_.get(), 1662 GL_TEXTURE_2D, 1663 1, 1664 GL_RGBA, 1665 2, 1666 2, 1667 1, 1668 0, 1669 GL_RGBA, 1670 GL_UNSIGNED_BYTE, 1671 false); 1672 signature2.clear(); 1673 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1674 EXPECT_EQ(signature1, signature2); 1675 1676 // Check changing other settings changes signature. 1677 manager_->SetLevelInfo(texture_ref_.get(), 1678 GL_TEXTURE_2D, 1679 1, 1680 GL_RGBA, 1681 2, 1682 4, 1683 1, 1684 0, 1685 GL_RGBA, 1686 GL_UNSIGNED_BYTE, 1687 false); 1688 signature2.clear(); 1689 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1690 EXPECT_FALSE(InSet(&string_set, signature2)); 1691 1692 manager_->SetLevelInfo(texture_ref_.get(), 1693 GL_TEXTURE_2D, 1694 1, 1695 GL_RGBA, 1696 2, 1697 2, 1698 2, 1699 0, 1700 GL_RGBA, 1701 GL_UNSIGNED_BYTE, 1702 false); 1703 signature2.clear(); 1704 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1705 EXPECT_FALSE(InSet(&string_set, signature2)); 1706 1707 manager_->SetLevelInfo(texture_ref_.get(), 1708 GL_TEXTURE_2D, 1709 1, 1710 GL_RGBA, 1711 2, 1712 2, 1713 1, 1714 1, 1715 GL_RGBA, 1716 GL_UNSIGNED_BYTE, 1717 false); 1718 signature2.clear(); 1719 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1720 EXPECT_FALSE(InSet(&string_set, signature2)); 1721 1722 manager_->SetLevelInfo(texture_ref_.get(), 1723 GL_TEXTURE_2D, 1724 1, 1725 GL_RGBA, 1726 2, 1727 2, 1728 1, 1729 0, 1730 GL_RGB, 1731 GL_UNSIGNED_BYTE, 1732 false); 1733 signature2.clear(); 1734 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1735 EXPECT_FALSE(InSet(&string_set, signature2)); 1736 1737 manager_->SetLevelInfo(texture_ref_.get(), 1738 GL_TEXTURE_2D, 1739 1, 1740 GL_RGBA, 1741 2, 1742 2, 1743 1, 1744 0, 1745 GL_RGBA, 1746 GL_FLOAT, 1747 false); 1748 signature2.clear(); 1749 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1750 EXPECT_FALSE(InSet(&string_set, signature2)); 1751 1752 // put it back 1753 manager_->SetLevelInfo(texture_ref_.get(), 1754 GL_TEXTURE_2D, 1755 1, 1756 GL_RGBA, 1757 2, 1758 2, 1759 1, 1760 0, 1761 GL_RGBA, 1762 GL_UNSIGNED_BYTE, 1763 false); 1764 signature2.clear(); 1765 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1766 EXPECT_EQ(signature1, signature2); 1767 1768 // check changing parameters changes signature. 1769 SetParameter( 1770 texture_ref_.get(), GL_TEXTURE_MIN_FILTER, GL_NEAREST, GL_NO_ERROR); 1771 signature2.clear(); 1772 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1773 EXPECT_FALSE(InSet(&string_set, signature2)); 1774 1775 SetParameter(texture_ref_.get(), 1776 GL_TEXTURE_MIN_FILTER, 1777 GL_NEAREST_MIPMAP_LINEAR, 1778 GL_NO_ERROR); 1779 SetParameter( 1780 texture_ref_.get(), GL_TEXTURE_MAG_FILTER, GL_NEAREST, GL_NO_ERROR); 1781 signature2.clear(); 1782 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1783 EXPECT_FALSE(InSet(&string_set, signature2)); 1784 1785 SetParameter( 1786 texture_ref_.get(), GL_TEXTURE_MAG_FILTER, GL_LINEAR, GL_NO_ERROR); 1787 SetParameter( 1788 texture_ref_.get(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 1789 signature2.clear(); 1790 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1791 EXPECT_FALSE(InSet(&string_set, signature2)); 1792 1793 SetParameter(texture_ref_.get(), GL_TEXTURE_WRAP_S, GL_REPEAT, GL_NO_ERROR); 1794 SetParameter( 1795 texture_ref_.get(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE, GL_NO_ERROR); 1796 signature2.clear(); 1797 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1798 EXPECT_FALSE(InSet(&string_set, signature2)); 1799 1800 // Check putting it back genenerates the same signature 1801 SetParameter(texture_ref_.get(), GL_TEXTURE_WRAP_T, GL_REPEAT, GL_NO_ERROR); 1802 signature2.clear(); 1803 manager_->AddToSignature(texture_ref_.get(), GL_TEXTURE_2D, 1, &signature2); 1804 EXPECT_EQ(signature1, signature2); 1805 1806 // Check the set was acutally getting different signatures. 1807 EXPECT_EQ(11u, string_set.size()); 1808 } 1809 1810 class ProduceConsumeTextureTest : public TextureTest { 1811 public: 1812 virtual void SetUp() { 1813 TextureTest::SetUpBase(NULL, "GL_OES_EGL_image_external"); 1814 manager_->CreateTexture(kClient2Id, kService2Id); 1815 texture2_ = manager_->GetTexture(kClient2Id); 1816 1817 EXPECT_CALL(*decoder_.get(), GetErrorState()) 1818 .WillRepeatedly(Return(error_state_.get())); 1819 } 1820 1821 virtual void TearDown() { 1822 if (texture2_.get()) { 1823 // If it's not in the manager then setting texture2_ to NULL will 1824 // delete the texture. 1825 if (!texture2_->client_id()) { 1826 // Check that it gets deleted when the last reference is released. 1827 EXPECT_CALL( 1828 *gl_, 1829 DeleteTextures(1, ::testing::Pointee(texture2_->service_id()))) 1830 .Times(1).RetiresOnSaturation(); 1831 } 1832 texture2_ = NULL; 1833 } 1834 TextureTest::TearDown(); 1835 } 1836 1837 protected: 1838 struct LevelInfo { 1839 LevelInfo(GLenum target, 1840 GLenum format, 1841 GLsizei width, 1842 GLsizei height, 1843 GLsizei depth, 1844 GLint border, 1845 GLenum type, 1846 bool cleared) 1847 : target(target), 1848 format(format), 1849 width(width), 1850 height(height), 1851 depth(depth), 1852 border(border), 1853 type(type), 1854 cleared(cleared) {} 1855 1856 LevelInfo() 1857 : target(0), 1858 format(0), 1859 width(-1), 1860 height(-1), 1861 depth(1), 1862 border(0), 1863 type(0), 1864 cleared(false) {} 1865 1866 bool operator==(const LevelInfo& other) const { 1867 return target == other.target && format == other.format && 1868 width == other.width && height == other.height && 1869 depth == other.depth && border == other.border && 1870 type == other.type && cleared == other.cleared; 1871 } 1872 1873 GLenum target; 1874 GLenum format; 1875 GLsizei width; 1876 GLsizei height; 1877 GLsizei depth; 1878 GLint border; 1879 GLenum type; 1880 bool cleared; 1881 }; 1882 1883 void SetLevelInfo(TextureRef* texture_ref, 1884 GLint level, 1885 const LevelInfo& info) { 1886 manager_->SetLevelInfo(texture_ref, 1887 info.target, 1888 level, 1889 info.format, 1890 info.width, 1891 info.height, 1892 info.depth, 1893 info.border, 1894 info.format, 1895 info.type, 1896 info.cleared); 1897 } 1898 1899 static LevelInfo GetLevelInfo(const TextureRef* texture_ref, 1900 GLint target, 1901 GLint level) { 1902 const Texture* texture = texture_ref->texture(); 1903 LevelInfo info; 1904 info.target = target; 1905 EXPECT_TRUE(texture->GetLevelSize(target, level, &info.width, 1906 &info.height)); 1907 EXPECT_TRUE(texture->GetLevelType(target, level, &info.type, 1908 &info.format)); 1909 info.cleared = texture->IsLevelCleared(target, level); 1910 return info; 1911 } 1912 1913 Texture* Produce(TextureRef* texture_ref) { 1914 Texture* texture = manager_->Produce(texture_ref); 1915 EXPECT_TRUE(texture != NULL); 1916 return texture; 1917 } 1918 1919 void Consume(GLuint client_id, Texture* texture) { 1920 EXPECT_TRUE(manager_->Consume(client_id, texture)); 1921 } 1922 1923 scoped_refptr<TextureRef> texture2_; 1924 1925 private: 1926 static const GLuint kClient2Id; 1927 static const GLuint kService2Id; 1928 }; 1929 1930 const GLuint ProduceConsumeTextureTest::kClient2Id = 2; 1931 const GLuint ProduceConsumeTextureTest::kService2Id = 12; 1932 1933 TEST_F(ProduceConsumeTextureTest, ProduceConsume2D) { 1934 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); 1935 Texture* texture = texture_ref_->texture(); 1936 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), texture->target()); 1937 LevelInfo level0( 1938 GL_TEXTURE_2D, GL_RGBA, 4, 4, 1, 0, GL_UNSIGNED_BYTE, true); 1939 SetLevelInfo(texture_ref_.get(), 0, level0); 1940 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture_ref_.get())); 1941 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1942 LevelInfo level1 = GetLevelInfo(texture_ref_.get(), GL_TEXTURE_2D, 1); 1943 LevelInfo level2 = GetLevelInfo(texture_ref_.get(), GL_TEXTURE_2D, 2); 1944 Texture* produced_texture = Produce(texture_ref_.get()); 1945 EXPECT_EQ(produced_texture, texture); 1946 1947 // Make this texture bigger with more levels, and make sure they get 1948 // clobbered correctly during Consume(). 1949 manager_->SetTarget(texture2_.get(), GL_TEXTURE_2D); 1950 SetLevelInfo( 1951 texture2_.get(), 1952 0, 1953 LevelInfo(GL_TEXTURE_2D, GL_RGBA, 16, 16, 1, 0, GL_UNSIGNED_BYTE, false)); 1954 EXPECT_TRUE(manager_->MarkMipmapsGenerated(texture2_.get())); 1955 texture = texture2_->texture(); 1956 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1957 EXPECT_EQ(1024U + 256U + 64U + 16U + 4U, texture->estimated_size()); 1958 1959 GLuint client_id = texture2_->client_id(); 1960 manager_->RemoveTexture(client_id); 1961 Consume(client_id, produced_texture); 1962 scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); 1963 EXPECT_EQ(produced_texture, restored_texture->texture()); 1964 EXPECT_EQ(level0, GetLevelInfo(restored_texture.get(), GL_TEXTURE_2D, 0)); 1965 EXPECT_EQ(level1, GetLevelInfo(restored_texture.get(), GL_TEXTURE_2D, 1)); 1966 EXPECT_EQ(level2, GetLevelInfo(restored_texture.get(), GL_TEXTURE_2D, 2)); 1967 texture = restored_texture->texture(); 1968 EXPECT_EQ(64U + 16U + 4U, texture->estimated_size()); 1969 GLint w, h; 1970 EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 3, &w, &h)); 1971 1972 // However the old texture ref still exists if it was referenced somewhere. 1973 EXPECT_EQ(1024U + 256U + 64U + 16U + 4U, 1974 texture2_->texture()->estimated_size()); 1975 } 1976 1977 TEST_F(ProduceConsumeTextureTest, ProduceConsumeClearRectangle) { 1978 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_RECTANGLE_ARB); 1979 Texture* texture = texture_ref_->texture(); 1980 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), texture->target()); 1981 LevelInfo level0( 1982 GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, 1, 1, 1, 0, GL_UNSIGNED_BYTE, false); 1983 SetLevelInfo(texture_ref_.get(), 0, level0); 1984 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 1985 Texture* produced_texture = Produce(texture_ref_.get()); 1986 EXPECT_EQ(produced_texture, texture); 1987 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB), 1988 produced_texture->target()); 1989 1990 GLuint client_id = texture2_->client_id(); 1991 manager_->RemoveTexture(client_id); 1992 Consume(client_id, produced_texture); 1993 scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); 1994 EXPECT_EQ(produced_texture, restored_texture->texture()); 1995 1996 // See if we can clear the previously uncleared level now. 1997 EXPECT_EQ(level0, 1998 GetLevelInfo(restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); 1999 EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) 2000 .WillRepeatedly(Return(true)); 2001 EXPECT_TRUE(manager_->ClearTextureLevel( 2002 decoder_.get(), restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); 2003 } 2004 2005 TEST_F(ProduceConsumeTextureTest, ProduceConsumeStreamTexture) { 2006 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); 2007 Texture* texture = texture_ref_->texture(); 2008 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), texture->target()); 2009 manager_->SetStreamTexture(texture_ref_.get(), true); 2010 GLuint service_id = texture->service_id(); 2011 Texture* produced_texture = Produce(texture_ref_.get()); 2012 EXPECT_TRUE(texture->IsStreamTexture()); 2013 2014 GLuint client_id = texture2_->client_id(); 2015 manager_->RemoveTexture(client_id); 2016 Consume(client_id, produced_texture); 2017 scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); 2018 EXPECT_EQ(produced_texture, restored_texture->texture()); 2019 EXPECT_TRUE(restored_texture->texture()->IsStreamTexture()); 2020 EXPECT_TRUE(restored_texture->texture()->IsImmutable()); 2021 EXPECT_EQ(service_id, restored_texture->service_id()); 2022 } 2023 2024 TEST_F(ProduceConsumeTextureTest, ProduceConsumeCube) { 2025 manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_CUBE_MAP); 2026 Texture* texture = texture_ref_->texture(); 2027 EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), texture->target()); 2028 LevelInfo face0(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 2029 GL_RGBA, 2030 1, 2031 1, 2032 1, 2033 0, 2034 GL_UNSIGNED_BYTE, 2035 true); 2036 LevelInfo face5(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 2037 GL_RGBA, 2038 3, 2039 3, 2040 1, 2041 0, 2042 GL_UNSIGNED_BYTE, 2043 true); 2044 SetLevelInfo(texture_ref_.get(), 0, face0); 2045 SetLevelInfo(texture_ref_.get(), 0, face5); 2046 EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); 2047 Texture* produced_texture = Produce(texture_ref_.get()); 2048 EXPECT_EQ(produced_texture, texture); 2049 2050 GLuint client_id = texture2_->client_id(); 2051 manager_->RemoveTexture(client_id); 2052 Consume(client_id, produced_texture); 2053 scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); 2054 EXPECT_EQ(produced_texture, restored_texture->texture()); 2055 EXPECT_EQ( 2056 face0, 2057 GetLevelInfo(restored_texture.get(), GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)); 2058 EXPECT_EQ( 2059 face5, 2060 GetLevelInfo(restored_texture.get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0)); 2061 } 2062 2063 class CountingMemoryTracker : public MemoryTracker { 2064 public: 2065 CountingMemoryTracker() { 2066 current_size_[0] = 0; 2067 current_size_[1] = 0; 2068 } 2069 2070 virtual void TrackMemoryAllocatedChange(size_t old_size, 2071 size_t new_size, 2072 Pool pool) OVERRIDE { 2073 DCHECK_LT(static_cast<size_t>(pool), arraysize(current_size_)); 2074 current_size_[pool] += new_size - old_size; 2075 } 2076 2077 virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE { 2078 return true; 2079 } 2080 2081 size_t GetSize(Pool pool) { 2082 DCHECK_LT(static_cast<size_t>(pool), arraysize(current_size_)); 2083 return current_size_[pool]; 2084 } 2085 2086 private: 2087 virtual ~CountingMemoryTracker() {} 2088 2089 size_t current_size_[2]; 2090 DISALLOW_COPY_AND_ASSIGN(CountingMemoryTracker); 2091 }; 2092 2093 class SharedTextureTest : public testing::Test { 2094 public: 2095 SharedTextureTest() 2096 : feature_info_(new FeatureInfo()) { 2097 } 2098 2099 virtual ~SharedTextureTest() { 2100 } 2101 2102 virtual void SetUp() { 2103 gl_.reset(new ::gfx::MockGLInterface()); 2104 ::gfx::GLInterface::SetGLInterface(gl_.get()); 2105 2106 memory_tracker1_ = new CountingMemoryTracker; 2107 texture_manager1_.reset( 2108 new TextureManager(memory_tracker1_.get(), 2109 feature_info_.get(), 2110 TextureManagerTest::kMaxTextureSize, 2111 TextureManagerTest::kMaxCubeMapTextureSize)); 2112 memory_tracker2_ = new CountingMemoryTracker; 2113 texture_manager2_.reset( 2114 new TextureManager(memory_tracker2_.get(), 2115 feature_info_.get(), 2116 TextureManagerTest::kMaxTextureSize, 2117 TextureManagerTest::kMaxCubeMapTextureSize)); 2118 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 2119 texture_manager1_->Initialize(); 2120 TestHelper::SetupTextureManagerInitExpectations(gl_.get(), ""); 2121 texture_manager2_->Initialize(); 2122 } 2123 2124 virtual void TearDown() { 2125 texture_manager2_->Destroy(false); 2126 texture_manager2_.reset(); 2127 texture_manager1_->Destroy(false); 2128 texture_manager1_.reset(); 2129 ::gfx::GLInterface::SetGLInterface(NULL); 2130 gl_.reset(); 2131 } 2132 2133 protected: 2134 scoped_ptr< ::gfx::MockGLInterface > gl_; 2135 scoped_refptr<FeatureInfo> feature_info_; 2136 scoped_refptr<CountingMemoryTracker> memory_tracker1_; 2137 scoped_ptr<TextureManager> texture_manager1_; 2138 scoped_refptr<CountingMemoryTracker> memory_tracker2_; 2139 scoped_ptr<TextureManager> texture_manager2_; 2140 }; 2141 2142 TEST_F(SharedTextureTest, DeleteTextures) { 2143 scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); 2144 scoped_refptr<TextureRef> ref2 = 2145 texture_manager2_->Consume(20, ref1->texture()); 2146 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2147 .Times(0); 2148 ref1 = NULL; 2149 texture_manager1_->RemoveTexture(10); 2150 testing::Mock::VerifyAndClearExpectations(gl_.get()); 2151 2152 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2153 .Times(1) 2154 .RetiresOnSaturation(); 2155 ref2 = NULL; 2156 texture_manager2_->RemoveTexture(20); 2157 testing::Mock::VerifyAndClearExpectations(gl_.get()); 2158 } 2159 2160 TEST_F(SharedTextureTest, TextureSafetyAccounting) { 2161 EXPECT_FALSE(texture_manager1_->HaveUnrenderableTextures()); 2162 EXPECT_FALSE(texture_manager1_->HaveUnsafeTextures()); 2163 EXPECT_FALSE(texture_manager1_->HaveUnclearedMips()); 2164 EXPECT_FALSE(texture_manager2_->HaveUnrenderableTextures()); 2165 EXPECT_FALSE(texture_manager2_->HaveUnsafeTextures()); 2166 EXPECT_FALSE(texture_manager2_->HaveUnclearedMips()); 2167 2168 // Newly created texture is renderable. 2169 scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); 2170 EXPECT_FALSE(texture_manager1_->HaveUnrenderableTextures()); 2171 EXPECT_FALSE(texture_manager1_->HaveUnsafeTextures()); 2172 EXPECT_FALSE(texture_manager1_->HaveUnclearedMips()); 2173 2174 // Associate new texture ref to other texture manager, should account for it 2175 // too. 2176 scoped_refptr<TextureRef> ref2 = 2177 texture_manager2_->Consume(20, ref1->texture()); 2178 EXPECT_FALSE(texture_manager2_->HaveUnrenderableTextures()); 2179 EXPECT_FALSE(texture_manager2_->HaveUnsafeTextures()); 2180 EXPECT_FALSE(texture_manager2_->HaveUnclearedMips()); 2181 2182 // Make texture renderable but uncleared on one texture manager, should affect 2183 // other one. 2184 texture_manager1_->SetTarget(ref1.get(), GL_TEXTURE_2D); 2185 EXPECT_TRUE(texture_manager1_->HaveUnrenderableTextures()); 2186 EXPECT_FALSE(texture_manager1_->HaveUnsafeTextures()); 2187 EXPECT_FALSE(texture_manager1_->HaveUnclearedMips()); 2188 EXPECT_TRUE(texture_manager2_->HaveUnrenderableTextures()); 2189 EXPECT_FALSE(texture_manager2_->HaveUnsafeTextures()); 2190 EXPECT_FALSE(texture_manager2_->HaveUnclearedMips()); 2191 2192 texture_manager1_->SetLevelInfo(ref1.get(), 2193 GL_TEXTURE_2D, 2194 0, 2195 GL_RGBA, 2196 1, 2197 1, 2198 1, 2199 0, 2200 GL_RGBA, 2201 GL_UNSIGNED_BYTE, 2202 false); 2203 EXPECT_FALSE(texture_manager1_->HaveUnrenderableTextures()); 2204 EXPECT_TRUE(texture_manager1_->HaveUnsafeTextures()); 2205 EXPECT_TRUE(texture_manager1_->HaveUnclearedMips()); 2206 EXPECT_FALSE(texture_manager2_->HaveUnrenderableTextures()); 2207 EXPECT_TRUE(texture_manager2_->HaveUnsafeTextures()); 2208 EXPECT_TRUE(texture_manager2_->HaveUnclearedMips()); 2209 2210 // Make texture cleared on one texture manager, should affect other one. 2211 texture_manager1_->SetLevelCleared(ref1.get(), GL_TEXTURE_2D, 0, true); 2212 EXPECT_FALSE(texture_manager1_->HaveUnsafeTextures()); 2213 EXPECT_FALSE(texture_manager1_->HaveUnclearedMips()); 2214 EXPECT_FALSE(texture_manager2_->HaveUnsafeTextures()); 2215 EXPECT_FALSE(texture_manager2_->HaveUnclearedMips()); 2216 2217 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2218 .Times(1) 2219 .RetiresOnSaturation(); 2220 texture_manager1_->RemoveTexture(10); 2221 texture_manager2_->RemoveTexture(20); 2222 } 2223 2224 TEST_F(SharedTextureTest, FBOCompletenessCheck) { 2225 const GLenum kCompleteValue = GL_FRAMEBUFFER_COMPLETE; 2226 FramebufferManager framebuffer_manager1(1, 1); 2227 texture_manager1_->set_framebuffer_manager(&framebuffer_manager1); 2228 FramebufferManager framebuffer_manager2(1, 1); 2229 texture_manager2_->set_framebuffer_manager(&framebuffer_manager2); 2230 2231 scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); 2232 framebuffer_manager1.CreateFramebuffer(10, 10); 2233 scoped_refptr<Framebuffer> framebuffer1 = 2234 framebuffer_manager1.GetFramebuffer(10); 2235 framebuffer1->AttachTexture( 2236 GL_COLOR_ATTACHMENT0, ref1.get(), GL_TEXTURE_2D, 0, 0); 2237 EXPECT_FALSE(framebuffer_manager1.IsComplete(framebuffer1.get())); 2238 EXPECT_NE(kCompleteValue, framebuffer1->IsPossiblyComplete()); 2239 2240 // Make FBO complete in manager 1. 2241 texture_manager1_->SetTarget(ref1.get(), GL_TEXTURE_2D); 2242 texture_manager1_->SetLevelInfo(ref1.get(), 2243 GL_TEXTURE_2D, 2244 0, 2245 GL_RGBA, 2246 1, 2247 1, 2248 1, 2249 0, 2250 GL_RGBA, 2251 GL_UNSIGNED_BYTE, 2252 true); 2253 EXPECT_EQ(kCompleteValue, framebuffer1->IsPossiblyComplete()); 2254 framebuffer_manager1.MarkAsComplete(framebuffer1.get()); 2255 EXPECT_TRUE(framebuffer_manager1.IsComplete(framebuffer1.get())); 2256 2257 // Share texture with manager 2. 2258 scoped_refptr<TextureRef> ref2 = 2259 texture_manager2_->Consume(20, ref1->texture()); 2260 framebuffer_manager2.CreateFramebuffer(20, 20); 2261 scoped_refptr<Framebuffer> framebuffer2 = 2262 framebuffer_manager2.GetFramebuffer(20); 2263 framebuffer2->AttachTexture( 2264 GL_COLOR_ATTACHMENT0, ref2.get(), GL_TEXTURE_2D, 0, 0); 2265 EXPECT_FALSE(framebuffer_manager2.IsComplete(framebuffer2.get())); 2266 EXPECT_EQ(kCompleteValue, framebuffer2->IsPossiblyComplete()); 2267 framebuffer_manager2.MarkAsComplete(framebuffer2.get()); 2268 EXPECT_TRUE(framebuffer_manager2.IsComplete(framebuffer2.get())); 2269 2270 // Change level for texture, both FBOs should be marked incomplete 2271 texture_manager1_->SetLevelInfo(ref1.get(), 2272 GL_TEXTURE_2D, 2273 0, 2274 GL_RGBA, 2275 1, 2276 1, 2277 1, 2278 0, 2279 GL_RGBA, 2280 GL_UNSIGNED_BYTE, 2281 true); 2282 EXPECT_FALSE(framebuffer_manager1.IsComplete(framebuffer1.get())); 2283 EXPECT_EQ(kCompleteValue, framebuffer1->IsPossiblyComplete()); 2284 framebuffer_manager1.MarkAsComplete(framebuffer1.get()); 2285 EXPECT_TRUE(framebuffer_manager1.IsComplete(framebuffer1.get())); 2286 EXPECT_FALSE(framebuffer_manager2.IsComplete(framebuffer2.get())); 2287 EXPECT_EQ(kCompleteValue, framebuffer2->IsPossiblyComplete()); 2288 framebuffer_manager2.MarkAsComplete(framebuffer2.get()); 2289 EXPECT_TRUE(framebuffer_manager2.IsComplete(framebuffer2.get())); 2290 2291 EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _)) 2292 .Times(2) 2293 .RetiresOnSaturation(); 2294 framebuffer_manager1.RemoveFramebuffer(10); 2295 framebuffer_manager2.RemoveFramebuffer(20); 2296 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2297 .Times(1) 2298 .RetiresOnSaturation(); 2299 texture_manager1_->RemoveTexture(10); 2300 texture_manager2_->RemoveTexture(20); 2301 } 2302 2303 TEST_F(SharedTextureTest, Memory) { 2304 size_t initial_memory1 = memory_tracker1_->GetSize(MemoryTracker::kUnmanaged); 2305 size_t initial_memory2 = memory_tracker2_->GetSize(MemoryTracker::kUnmanaged); 2306 2307 // Newly created texture is unrenderable. 2308 scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); 2309 texture_manager1_->SetTarget(ref1.get(), GL_TEXTURE_2D); 2310 texture_manager1_->SetLevelInfo(ref1.get(), 2311 GL_TEXTURE_2D, 2312 0, 2313 GL_RGBA, 2314 10, 2315 10, 2316 1, 2317 0, 2318 GL_RGBA, 2319 GL_UNSIGNED_BYTE, 2320 false); 2321 2322 EXPECT_LT(0u, ref1->texture()->estimated_size()); 2323 EXPECT_EQ(initial_memory1 + ref1->texture()->estimated_size(), 2324 memory_tracker1_->GetSize(MemoryTracker::kUnmanaged)); 2325 2326 // Associate new texture ref to other texture manager, it doesn't account for 2327 // the texture memory, the first memory tracker still has it. 2328 scoped_refptr<TextureRef> ref2 = 2329 texture_manager2_->Consume(20, ref1->texture()); 2330 EXPECT_EQ(initial_memory1 + ref1->texture()->estimated_size(), 2331 memory_tracker1_->GetSize(MemoryTracker::kUnmanaged)); 2332 EXPECT_EQ(initial_memory2, 2333 memory_tracker2_->GetSize(MemoryTracker::kUnmanaged)); 2334 2335 // Delete the texture, memory should go to the remaining tracker. 2336 texture_manager1_->RemoveTexture(10); 2337 ref1 = NULL; 2338 EXPECT_EQ(initial_memory1, 2339 memory_tracker1_->GetSize(MemoryTracker::kUnmanaged)); 2340 EXPECT_EQ(initial_memory2 + ref2->texture()->estimated_size(), 2341 memory_tracker2_->GetSize(MemoryTracker::kUnmanaged)); 2342 2343 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2344 .Times(1) 2345 .RetiresOnSaturation(); 2346 ref2 = NULL; 2347 texture_manager2_->RemoveTexture(20); 2348 EXPECT_EQ(initial_memory2, 2349 memory_tracker2_->GetSize(MemoryTracker::kUnmanaged)); 2350 } 2351 2352 TEST_F(SharedTextureTest, Images) { 2353 scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10); 2354 scoped_refptr<TextureRef> ref2 = 2355 texture_manager2_->Consume(20, ref1->texture()); 2356 2357 texture_manager1_->SetTarget(ref1.get(), GL_TEXTURE_2D); 2358 texture_manager1_->SetLevelInfo(ref1.get(), 2359 GL_TEXTURE_2D, 2360 1, 2361 GL_RGBA, 2362 2, 2363 2, 2364 1, 2365 0, 2366 GL_RGBA, 2367 GL_UNSIGNED_BYTE, 2368 true); 2369 EXPECT_FALSE(ref1->texture()->HasImages()); 2370 EXPECT_FALSE(ref2->texture()->HasImages()); 2371 EXPECT_FALSE(texture_manager1_->HaveImages()); 2372 EXPECT_FALSE(texture_manager2_->HaveImages()); 2373 texture_manager1_->SetLevelImage(ref1.get(), 2374 GL_TEXTURE_2D, 2375 1, 2376 gfx::GLImage::CreateGLImage(0).get()); 2377 EXPECT_TRUE(ref1->texture()->HasImages()); 2378 EXPECT_TRUE(ref2->texture()->HasImages()); 2379 EXPECT_TRUE(texture_manager1_->HaveImages()); 2380 EXPECT_TRUE(texture_manager2_->HaveImages()); 2381 texture_manager1_->SetLevelImage(ref1.get(), 2382 GL_TEXTURE_2D, 2383 1, 2384 gfx::GLImage::CreateGLImage(0).get()); 2385 EXPECT_TRUE(ref1->texture()->HasImages()); 2386 EXPECT_TRUE(ref2->texture()->HasImages()); 2387 EXPECT_TRUE(texture_manager1_->HaveImages()); 2388 EXPECT_TRUE(texture_manager2_->HaveImages()); 2389 texture_manager1_->SetLevelInfo(ref1.get(), 2390 GL_TEXTURE_2D, 2391 1, 2392 GL_RGBA, 2393 2, 2394 2, 2395 1, 2396 0, 2397 GL_RGBA, 2398 GL_UNSIGNED_BYTE, 2399 true); 2400 EXPECT_FALSE(ref1->texture()->HasImages()); 2401 EXPECT_FALSE(ref2->texture()->HasImages()); 2402 EXPECT_FALSE(texture_manager1_->HaveImages()); 2403 EXPECT_FALSE(texture_manager1_->HaveImages()); 2404 2405 EXPECT_CALL(*gl_, DeleteTextures(1, _)) 2406 .Times(1) 2407 .RetiresOnSaturation(); 2408 texture_manager1_->RemoveTexture(10); 2409 texture_manager2_->RemoveTexture(20); 2410 } 2411 2412 } // namespace gles2 2413 } // namespace gpu 2414