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.
5 #include "gpu/command_buffer/service/renderbuffer_manager.h"
8 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
9 #include "gpu/command_buffer/service/gpu_service_test.h"
10 #include "gpu/command_buffer/service/mocks.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gl/gl_implementation.h"
13 #include "ui/gl/gl_mock.h"
15 using ::testing::StrictMock
;
20 class RenderbufferManagerTestBase
: public GpuServiceTest
{
22 static const GLint kMaxSize
= 128;
23 static const GLint kMaxSamples
= 4;
26 void SetUpBase(MemoryTracker
* memory_tracker
, bool depth24_supported
) {
27 GpuServiceTest::SetUp();
28 manager_
.reset(new RenderbufferManager(
29 memory_tracker
, kMaxSize
, kMaxSamples
, depth24_supported
));
32 virtual void TearDown() {
33 manager_
->Destroy(true);
35 GpuServiceTest::TearDown();
38 scoped_ptr
<RenderbufferManager
> manager_
;
41 class RenderbufferManagerTest
: public RenderbufferManagerTestBase
{
43 virtual void SetUp() {
44 bool depth24_supported
= false;
45 SetUpBase(NULL
, depth24_supported
);
49 class RenderbufferManagerMemoryTrackerTest
50 : public RenderbufferManagerTestBase
{
52 virtual void SetUp() {
53 mock_memory_tracker_
= new StrictMock
<MockMemoryTracker
>();
54 bool depth24_supported
= false;
55 SetUpBase(mock_memory_tracker_
.get(), depth24_supported
);
58 scoped_refptr
<MockMemoryTracker
> mock_memory_tracker_
;
61 #define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size, pool) \
62 EXPECT_CALL(*mock_memory_tracker_.get(), \
63 TrackMemoryAllocatedChange(old_size, new_size, pool)) \
64 .Times(1).RetiresOnSaturation()
66 // GCC requires these declarations, but MSVC requires they not be present
68 const GLint
RenderbufferManagerTestBase::kMaxSize
;
69 const GLint
RenderbufferManagerTestBase::kMaxSamples
;
72 TEST_F(RenderbufferManagerTest
, Basic
) {
73 const GLuint kClient1Id
= 1;
74 const GLuint kService1Id
= 11;
75 const GLuint kClient2Id
= 2;
76 EXPECT_EQ(kMaxSize
, manager_
->max_renderbuffer_size());
77 EXPECT_EQ(kMaxSamples
, manager_
->max_samples());
78 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
79 // Check we can create renderbuffer.
80 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
81 // Check renderbuffer got created.
82 scoped_refptr
<Renderbuffer
> renderbuffer1
=
83 manager_
->GetRenderbuffer(kClient1Id
);
84 ASSERT_TRUE(renderbuffer1
.get() != NULL
);
85 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
86 EXPECT_EQ(kClient1Id
, renderbuffer1
->client_id());
87 // Check we get nothing for a non-existent renderbuffer.
88 EXPECT_TRUE(manager_
->GetRenderbuffer(kClient2Id
) == NULL
);
89 // Check trying to a remove non-existent renderbuffers does not crash.
90 manager_
->RemoveRenderbuffer(kClient2Id
);
91 // Check that the renderbuffer is deleted when the last ref is released.
92 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
94 .RetiresOnSaturation();
95 // Check we can't get the renderbuffer after we remove it.
96 manager_
->RemoveRenderbuffer(kClient1Id
);
97 EXPECT_TRUE(manager_
->GetRenderbuffer(kClient1Id
) == NULL
);
98 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
99 EXPECT_EQ(0u, renderbuffer1
->client_id());
102 TEST_F(RenderbufferManagerTest
, Destroy
) {
103 const GLuint kClient1Id
= 1;
104 const GLuint kService1Id
= 11;
105 // Check we can create renderbuffer.
106 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
107 // Check renderbuffer got created.
108 Renderbuffer
* renderbuffer1
=
109 manager_
->GetRenderbuffer(kClient1Id
);
110 ASSERT_TRUE(renderbuffer1
!= NULL
);
111 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
113 .RetiresOnSaturation();
114 manager_
->Destroy(true);
115 renderbuffer1
= manager_
->GetRenderbuffer(kClient1Id
);
116 ASSERT_TRUE(renderbuffer1
== NULL
);
119 TEST_F(RenderbufferManagerTest
, Renderbuffer
) {
120 const GLuint kClient1Id
= 1;
121 const GLuint kService1Id
= 11;
122 // Check we can create renderbuffer.
123 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
124 // Check renderbuffer got created.
125 Renderbuffer
* renderbuffer1
=
126 manager_
->GetRenderbuffer(kClient1Id
);
127 ASSERT_TRUE(renderbuffer1
!= NULL
);
128 EXPECT_EQ(kService1Id
, renderbuffer1
->service_id());
129 EXPECT_EQ(0, renderbuffer1
->samples());
130 EXPECT_EQ(static_cast<GLenum
>(GL_RGBA4
), renderbuffer1
->internal_format());
131 EXPECT_EQ(0, renderbuffer1
->width());
132 EXPECT_EQ(0, renderbuffer1
->height());
133 EXPECT_TRUE(renderbuffer1
->cleared());
134 EXPECT_EQ(0u, renderbuffer1
->EstimatedSize());
136 // Check if we set the info it gets marked as not cleared.
137 const GLsizei kSamples
= 4;
138 const GLenum kFormat
= GL_RGBA4
;
139 const GLsizei kWidth
= 128;
140 const GLsizei kHeight
= 64;
141 manager_
->SetInfo(renderbuffer1
, kSamples
, kFormat
, kWidth
, kHeight
);
142 EXPECT_EQ(kSamples
, renderbuffer1
->samples());
143 EXPECT_EQ(kFormat
, renderbuffer1
->internal_format());
144 EXPECT_EQ(kWidth
, renderbuffer1
->width());
145 EXPECT_EQ(kHeight
, renderbuffer1
->height());
146 EXPECT_FALSE(renderbuffer1
->cleared());
147 EXPECT_FALSE(renderbuffer1
->IsDeleted());
148 EXPECT_TRUE(manager_
->HaveUnclearedRenderbuffers());
149 EXPECT_EQ(kWidth
* kHeight
* 4u * 4u, renderbuffer1
->EstimatedSize());
151 manager_
->SetCleared(renderbuffer1
, true);
152 EXPECT_TRUE(renderbuffer1
->cleared());
153 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
155 manager_
->SetInfo(renderbuffer1
, kSamples
, kFormat
, kWidth
, kHeight
);
156 EXPECT_TRUE(manager_
->HaveUnclearedRenderbuffers());
158 // Check that the renderbuffer is deleted when the last ref is released.
159 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
161 .RetiresOnSaturation();
162 manager_
->RemoveRenderbuffer(kClient1Id
);
163 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
166 TEST_F(RenderbufferManagerMemoryTrackerTest
, Basic
) {
167 const GLuint kClient1Id
= 1;
168 const GLuint kService1Id
= 11;
169 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kUnmanaged
);
170 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
171 Renderbuffer
* renderbuffer1
=
172 manager_
->GetRenderbuffer(kClient1Id
);
173 ASSERT_TRUE(renderbuffer1
!= NULL
);
175 const GLsizei kSamples
= 4;
176 const GLenum kFormat
= GL_RGBA4
;
177 const GLsizei kWidth
= 128;
178 const GLsizei kHeight1
= 64;
179 const GLsizei kHeight2
= 32;
180 uint32 expected_size_1
= 0;
181 uint32 expected_size_2
= 0;
182 manager_
->ComputeEstimatedRenderbufferSize(
183 kWidth
, kHeight1
, kSamples
, kFormat
, &expected_size_1
);
184 manager_
->ComputeEstimatedRenderbufferSize(
185 kWidth
, kHeight2
, kSamples
, kFormat
, &expected_size_2
);
186 EXPECT_MEMORY_ALLOCATION_CHANGE(
187 0, expected_size_1
, MemoryTracker::kUnmanaged
);
188 manager_
->SetInfo(renderbuffer1
, kSamples
, kFormat
, kWidth
, kHeight1
);
189 EXPECT_MEMORY_ALLOCATION_CHANGE(
190 expected_size_1
, 0, MemoryTracker::kUnmanaged
);
191 EXPECT_MEMORY_ALLOCATION_CHANGE(
192 0, expected_size_2
, MemoryTracker::kUnmanaged
);
193 manager_
->SetInfo(renderbuffer1
, kSamples
, kFormat
, kWidth
, kHeight2
);
194 EXPECT_MEMORY_ALLOCATION_CHANGE(
195 expected_size_2
, 0, MemoryTracker::kUnmanaged
);
196 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
198 .RetiresOnSaturation();
201 TEST_F(RenderbufferManagerTest
, UseDeletedRenderbufferInfo
) {
202 const GLuint kClient1Id
= 1;
203 const GLuint kService1Id
= 11;
204 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
205 scoped_refptr
<Renderbuffer
> renderbuffer1(
206 manager_
->GetRenderbuffer(kClient1Id
));
207 ASSERT_TRUE(renderbuffer1
.get() != NULL
);
209 manager_
->RemoveRenderbuffer(kClient1Id
);
210 // Use after removing.
211 const GLsizei kSamples
= 4;
212 const GLenum kFormat
= GL_RGBA4
;
213 const GLsizei kWidth
= 128;
214 const GLsizei kHeight
= 64;
215 manager_
->SetInfo(renderbuffer1
.get(), kSamples
, kFormat
, kWidth
, kHeight
);
216 // See that it still affects manager.
217 EXPECT_TRUE(manager_
->HaveUnclearedRenderbuffers());
218 manager_
->SetCleared(renderbuffer1
.get(), true);
219 EXPECT_FALSE(manager_
->HaveUnclearedRenderbuffers());
220 // Check that the renderbuffer is deleted when the last ref is released.
221 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
223 .RetiresOnSaturation();
224 renderbuffer1
= NULL
;
229 bool InSet(std::set
<std::string
>* string_set
, const std::string
& str
) {
230 std::pair
<std::set
<std::string
>::iterator
, bool> result
=
231 string_set
->insert(str
);
232 return !result
.second
;
235 } // anonymous namespace
237 TEST_F(RenderbufferManagerTest
, AddToSignature
) {
238 const GLuint kClient1Id
= 1;
239 const GLuint kService1Id
= 11;
240 manager_
->CreateRenderbuffer(kClient1Id
, kService1Id
);
241 scoped_refptr
<Renderbuffer
> renderbuffer1(
242 manager_
->GetRenderbuffer(kClient1Id
));
243 ASSERT_TRUE(renderbuffer1
.get() != NULL
);
244 const GLsizei kSamples
= 4;
245 const GLenum kFormat
= GL_RGBA4
;
246 const GLsizei kWidth
= 128;
247 const GLsizei kHeight
= 64;
248 manager_
->SetInfo(renderbuffer1
.get(), kSamples
, kFormat
, kWidth
, kHeight
);
249 std::string signature1
;
250 std::string signature2
;
251 renderbuffer1
->AddToSignature(&signature1
);
253 std::set
<std::string
> string_set
;
254 EXPECT_FALSE(InSet(&string_set
, signature1
));
256 // change things and see that the signatures change.
258 renderbuffer1
.get(), kSamples
+ 1, kFormat
, kWidth
, kHeight
);
259 renderbuffer1
->AddToSignature(&signature2
);
260 EXPECT_FALSE(InSet(&string_set
, signature2
));
263 renderbuffer1
.get(), kSamples
, kFormat
+ 1, kWidth
, kHeight
);
265 renderbuffer1
->AddToSignature(&signature2
);
266 EXPECT_FALSE(InSet(&string_set
, signature2
));
269 renderbuffer1
.get(), kSamples
, kFormat
, kWidth
+ 1, kHeight
);
271 renderbuffer1
->AddToSignature(&signature2
);
272 EXPECT_FALSE(InSet(&string_set
, signature2
));
275 renderbuffer1
.get(), kSamples
, kFormat
, kWidth
, kHeight
+ 1);
277 renderbuffer1
->AddToSignature(&signature2
);
278 EXPECT_FALSE(InSet(&string_set
, signature2
));
280 // put it back to the same and it should be the same.
281 manager_
->SetInfo(renderbuffer1
.get(), kSamples
, kFormat
, kWidth
, kHeight
);
283 renderbuffer1
->AddToSignature(&signature2
);
284 EXPECT_EQ(signature1
, signature2
);
286 // Check the set was acutally getting different signatures.
287 EXPECT_EQ(5u, string_set
.size());
289 EXPECT_CALL(*gl_
, DeleteRenderbuffersEXT(1, ::testing::Pointee(kService1Id
)))
291 .RetiresOnSaturation();
294 class RenderbufferManagerFormatTest
: public RenderbufferManagerTestBase
{
296 virtual void SetUp() {
297 bool depth24_supported
= true;
298 SetUpBase(NULL
, depth24_supported
);
302 TEST_F(RenderbufferManagerFormatTest
, UpgradeDepthFormatOnGLES
) {
303 gfx::GLImplementation prev_impl
= gfx::GetGLImplementation();
304 gfx::SetGLImplementation(gfx::kGLImplementationEGLGLES2
);
306 manager_
->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16
);
307 gfx::SetGLImplementation(prev_impl
);
308 EXPECT_EQ(static_cast<GLenum
>(GL_DEPTH_COMPONENT24
), impl_format
);
311 TEST_F(RenderbufferManagerFormatTest
, UseUnsizedDepthFormatOnNonGLES
) {
312 gfx::GLImplementation prev_impl
= gfx::GetGLImplementation();
313 gfx::SetGLImplementation(gfx::kGLImplementationDesktopGL
);
315 manager_
->InternalRenderbufferFormatToImplFormat(GL_DEPTH_COMPONENT16
);
316 gfx::SetGLImplementation(prev_impl
);
317 EXPECT_EQ(static_cast<GLenum
>(GL_DEPTH_COMPONENT
), impl_format
);