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