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