OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/compositor/buffer_queue.h" | 5 #include "content/browser/compositor/buffer_queue.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 |
9 #include <set> | 10 #include <set> |
10 #include <utility> | 11 #include <utility> |
11 | 12 |
| 13 #include "base/memory/ptr_util.h" |
12 #include "cc/test/test_context_provider.h" | 14 #include "cc/test/test_context_provider.h" |
13 #include "cc/test/test_web_graphics_context_3d.h" | 15 #include "cc/test/test_web_graphics_context_3d.h" |
14 #include "content/browser/compositor/gl_helper.h" | 16 #include "content/browser/compositor/gl_helper.h" |
15 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_s
urface.h" | 17 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_s
urface.h" |
16 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" | 18 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" |
17 #include "gpu/GLES2/gl2extchromium.h" | 19 #include "gpu/GLES2/gl2extchromium.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "third_party/khronos/GLES2/gl2ext.h" | 22 #include "third_party/khronos/GLES2/gl2ext.h" |
21 | 23 |
(...skipping 28 matching lines...) Expand all Loading... |
50 } | 52 } |
51 }; | 53 }; |
52 | 54 |
53 class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager { | 55 class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager { |
54 public: | 56 public: |
55 StubBrowserGpuMemoryBufferManager() | 57 StubBrowserGpuMemoryBufferManager() |
56 : BrowserGpuMemoryBufferManager(1, 1), allocate_succeeds_(true) {} | 58 : BrowserGpuMemoryBufferManager(1, 1), allocate_succeeds_(true) {} |
57 | 59 |
58 void set_allocate_succeeds(bool value) { allocate_succeeds_ = value; } | 60 void set_allocate_succeeds(bool value) { allocate_succeeds_ = value; } |
59 | 61 |
60 scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer( | 62 std::unique_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer( |
61 const gfx::Size& size, | 63 const gfx::Size& size, |
62 gfx::BufferFormat format, | 64 gfx::BufferFormat format, |
63 gfx::BufferUsage usage, | 65 gfx::BufferUsage usage, |
64 int32_t surface_id) override { | 66 int32_t surface_id) override { |
65 if (!surface_id) { | 67 if (!surface_id) { |
66 return BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer( | 68 return BrowserGpuMemoryBufferManager::AllocateGpuMemoryBuffer( |
67 size, format, usage, surface_id); | 69 size, format, usage, surface_id); |
68 } | 70 } |
69 if (allocate_succeeds_) | 71 if (allocate_succeeds_) |
70 return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl); | 72 return base::WrapUnique<gfx::GpuMemoryBuffer>( |
| 73 new StubGpuMemoryBufferImpl); |
71 return nullptr; | 74 return nullptr; |
72 } | 75 } |
73 | 76 |
74 private: | 77 private: |
75 bool allocate_succeeds_; | 78 bool allocate_succeeds_; |
76 }; | 79 }; |
77 | 80 |
78 class MockBufferQueue : public BufferQueue { | 81 class MockBufferQueue : public BufferQueue { |
79 public: | 82 public: |
80 MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider, | 83 MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider, |
(...skipping 11 matching lines...) Expand all Loading... |
92 }; | 95 }; |
93 | 96 |
94 class BufferQueueTest : public ::testing::Test { | 97 class BufferQueueTest : public ::testing::Test { |
95 public: | 98 public: |
96 BufferQueueTest() : doublebuffering_(true), first_frame_(true) {} | 99 BufferQueueTest() : doublebuffering_(true), first_frame_(true) {} |
97 | 100 |
98 void SetUp() override { | 101 void SetUp() override { |
99 InitWithContext(cc::TestWebGraphicsContext3D::Create()); | 102 InitWithContext(cc::TestWebGraphicsContext3D::Create()); |
100 } | 103 } |
101 | 104 |
102 void InitWithContext(scoped_ptr<cc::TestWebGraphicsContext3D> context) { | 105 void InitWithContext(std::unique_ptr<cc::TestWebGraphicsContext3D> context) { |
103 scoped_refptr<cc::TestContextProvider> context_provider = | 106 scoped_refptr<cc::TestContextProvider> context_provider = |
104 cc::TestContextProvider::Create(std::move(context)); | 107 cc::TestContextProvider::Create(std::move(context)); |
105 context_provider->BindToCurrentThread(); | 108 context_provider->BindToCurrentThread(); |
106 gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager); | 109 gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager); |
107 mock_output_surface_ = | 110 mock_output_surface_ = |
108 new MockBufferQueue(context_provider, gpu_memory_buffer_manager_.get(), | 111 new MockBufferQueue(context_provider, gpu_memory_buffer_manager_.get(), |
109 GL_TEXTURE_2D, GL_RGBA); | 112 GL_TEXTURE_2D, GL_RGBA); |
110 output_surface_.reset(mock_output_surface_); | 113 output_surface_.reset(mock_output_surface_); |
111 output_surface_->Initialize(); | 114 output_surface_->Initialize(); |
112 } | 115 } |
113 | 116 |
114 unsigned current_surface() { | 117 unsigned current_surface() { |
115 return output_surface_->current_surface_ | 118 return output_surface_->current_surface_ |
116 ? output_surface_->current_surface_->image | 119 ? output_surface_->current_surface_->image |
117 : 0; | 120 : 0; |
118 } | 121 } |
119 const std::vector<scoped_ptr<BufferQueue::AllocatedSurface>>& | 122 const std::vector<std::unique_ptr<BufferQueue::AllocatedSurface>>& |
120 available_surfaces() { | 123 available_surfaces() { |
121 return output_surface_->available_surfaces_; | 124 return output_surface_->available_surfaces_; |
122 } | 125 } |
123 std::deque<scoped_ptr<BufferQueue::AllocatedSurface>>& in_flight_surfaces() { | 126 std::deque<std::unique_ptr<BufferQueue::AllocatedSurface>>& |
| 127 in_flight_surfaces() { |
124 return output_surface_->in_flight_surfaces_; | 128 return output_surface_->in_flight_surfaces_; |
125 } | 129 } |
126 | 130 |
127 const BufferQueue::AllocatedSurface* displayed_frame() { | 131 const BufferQueue::AllocatedSurface* displayed_frame() { |
128 return output_surface_->displayed_surface_.get(); | 132 return output_surface_->displayed_surface_.get(); |
129 } | 133 } |
130 const BufferQueue::AllocatedSurface* current_frame() { | 134 const BufferQueue::AllocatedSurface* current_frame() { |
131 return output_surface_->current_surface_.get(); | 135 return output_surface_->current_surface_.get(); |
132 } | 136 } |
133 const BufferQueue::AllocatedSurface* next_frame() { | 137 const BufferQueue::AllocatedSurface* next_frame() { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 protected: | 180 protected: |
177 bool InsertUnique(std::set<unsigned>* set, unsigned value) { | 181 bool InsertUnique(std::set<unsigned>* set, unsigned value) { |
178 if (!value) | 182 if (!value) |
179 return true; | 183 return true; |
180 if (set->find(value) != set->end()) | 184 if (set->find(value) != set->end()) |
181 return false; | 185 return false; |
182 set->insert(value); | 186 set->insert(value); |
183 return true; | 187 return true; |
184 } | 188 } |
185 | 189 |
186 scoped_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_; | 190 std::unique_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_; |
187 scoped_ptr<BufferQueue> output_surface_; | 191 std::unique_ptr<BufferQueue> output_surface_; |
188 MockBufferQueue* mock_output_surface_; | 192 MockBufferQueue* mock_output_surface_; |
189 bool doublebuffering_; | 193 bool doublebuffering_; |
190 bool first_frame_; | 194 bool first_frame_; |
191 }; | 195 }; |
192 | 196 |
193 namespace { | 197 namespace { |
194 const gfx::Size screen_size = gfx::Size(30, 30); | 198 const gfx::Size screen_size = gfx::Size(30, 30); |
195 const gfx::Rect screen_rect = gfx::Rect(screen_size); | 199 const gfx::Rect screen_rect = gfx::Rect(screen_size); |
196 const gfx::Rect small_damage = gfx::Rect(gfx::Size(10, 10)); | 200 const gfx::Rect small_damage = gfx::Rect(gfx::Size(10, 10)); |
197 const gfx::Rect large_damage = gfx::Rect(gfx::Size(20, 20)); | 201 const gfx::Rect large_damage = gfx::Rect(gfx::Size(20, 20)); |
(...skipping 17 matching lines...) Expand all Loading... |
215 GLuint(ClientBuffer, GLsizei, GLsizei, GLenum)); | 219 GLuint(ClientBuffer, GLsizei, GLsizei, GLenum)); |
216 MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint)); | 220 MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint)); |
217 MOCK_METHOD5(framebufferTexture2D, | 221 MOCK_METHOD5(framebufferTexture2D, |
218 void(GLenum, GLenum, GLenum, GLuint, GLint)); | 222 void(GLenum, GLenum, GLenum, GLuint, GLint)); |
219 }; | 223 }; |
220 | 224 |
221 class BufferQueueMockedContextTest : public BufferQueueTest { | 225 class BufferQueueMockedContextTest : public BufferQueueTest { |
222 public: | 226 public: |
223 void SetUp() override { | 227 void SetUp() override { |
224 context_ = new MockedContext(); | 228 context_ = new MockedContext(); |
225 InitWithContext(scoped_ptr<cc::TestWebGraphicsContext3D>(context_)); | 229 InitWithContext(std::unique_ptr<cc::TestWebGraphicsContext3D>(context_)); |
226 } | 230 } |
227 | 231 |
228 protected: | 232 protected: |
229 MockedContext* context_; | 233 MockedContext* context_; |
230 }; | 234 }; |
231 | 235 |
232 scoped_ptr<BufferQueue> CreateOutputSurfaceWithMock( | 236 std::unique_ptr<BufferQueue> CreateOutputSurfaceWithMock( |
233 unsigned int target, | 237 unsigned int target, |
234 MockedContext** context, | 238 MockedContext** context, |
235 BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) { | 239 BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager) { |
236 *context = new MockedContext(); | 240 *context = new MockedContext(); |
237 scoped_refptr<cc::TestContextProvider> context_provider = | 241 scoped_refptr<cc::TestContextProvider> context_provider = |
238 cc::TestContextProvider::Create( | 242 cc::TestContextProvider::Create( |
239 scoped_ptr<cc::TestWebGraphicsContext3D>(*context)); | 243 std::unique_ptr<cc::TestWebGraphicsContext3D>(*context)); |
240 context_provider->BindToCurrentThread(); | 244 context_provider->BindToCurrentThread(); |
241 scoped_ptr<BufferQueue> buffer_queue( | 245 std::unique_ptr<BufferQueue> buffer_queue( |
242 new BufferQueue(context_provider, target, GL_RGBA, nullptr, | 246 new BufferQueue(context_provider, target, GL_RGBA, nullptr, |
243 gpu_memory_buffer_manager, 1)); | 247 gpu_memory_buffer_manager, 1)); |
244 buffer_queue->Initialize(); | 248 buffer_queue->Initialize(); |
245 return buffer_queue; | 249 return buffer_queue; |
246 } | 250 } |
247 | 251 |
248 TEST(BufferQueueStandaloneTest, FboInitialization) { | 252 TEST(BufferQueueStandaloneTest, FboInitialization) { |
249 MockedContext* context; | 253 MockedContext* context; |
250 scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( | 254 std::unique_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( |
251 new StubBrowserGpuMemoryBufferManager); | 255 new StubBrowserGpuMemoryBufferManager); |
252 scoped_ptr<BufferQueue> output_surface = CreateOutputSurfaceWithMock( | 256 std::unique_ptr<BufferQueue> output_surface = CreateOutputSurfaceWithMock( |
253 GL_TEXTURE_2D, &context, gpu_memory_buffer_manager.get()); | 257 GL_TEXTURE_2D, &context, gpu_memory_buffer_manager.get()); |
254 | 258 |
255 EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); | 259 EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); |
256 ON_CALL(*context, framebufferTexture2D(_, _, _, _, _)) | 260 ON_CALL(*context, framebufferTexture2D(_, _, _, _, _)) |
257 .WillByDefault(Return()); | 261 .WillByDefault(Return()); |
258 | 262 |
259 output_surface->Reshape(gfx::Size(10, 20), 1.0f); | 263 output_surface->Reshape(gfx::Size(10, 20), 1.0f); |
260 } | 264 } |
261 | 265 |
262 TEST(BufferQueueStandaloneTest, FboBinding) { | 266 TEST(BufferQueueStandaloneTest, FboBinding) { |
263 GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB }; | 267 GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB }; |
264 for (size_t i = 0; i < 2; ++i) { | 268 for (size_t i = 0; i < 2; ++i) { |
265 GLenum target = targets[i]; | 269 GLenum target = targets[i]; |
266 MockedContext* context; | 270 MockedContext* context; |
267 scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( | 271 std::unique_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager( |
268 new StubBrowserGpuMemoryBufferManager); | 272 new StubBrowserGpuMemoryBufferManager); |
269 scoped_ptr<BufferQueue> output_surface = CreateOutputSurfaceWithMock( | 273 std::unique_ptr<BufferQueue> output_surface = CreateOutputSurfaceWithMock( |
270 target, &context, gpu_memory_buffer_manager.get()); | 274 target, &context, gpu_memory_buffer_manager.get()); |
271 EXPECT_CALL(*context, bindTexture(target, Ne(0U))); | 275 EXPECT_CALL(*context, bindTexture(target, Ne(0U))); |
272 EXPECT_CALL(*context, destroyImageCHROMIUM(1)); | 276 EXPECT_CALL(*context, destroyImageCHROMIUM(1)); |
273 Expectation image = | 277 Expectation image = |
274 EXPECT_CALL(*context, createImageCHROMIUM(_, 0, 0, GL_RGBA)) | 278 EXPECT_CALL(*context, createImageCHROMIUM(_, 0, 0, GL_RGBA)) |
275 .WillOnce(Return(1)); | 279 .WillOnce(Return(1)); |
276 Expectation fb = | 280 Expectation fb = |
277 EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); | 281 EXPECT_CALL(*context, bindFramebuffer(GL_FRAMEBUFFER, Ne(0U))); |
278 Expectation tex = EXPECT_CALL(*context, bindTexture(target, Ne(0U))); | 282 Expectation tex = EXPECT_CALL(*context, bindTexture(target, Ne(0U))); |
279 Expectation bind_tex = | 283 Expectation bind_tex = |
280 EXPECT_CALL(*context, bindTexImage2DCHROMIUM(target, 1)) | 284 EXPECT_CALL(*context, bindTexImage2DCHROMIUM(target, 1)) |
281 .After(tex, image); | 285 .After(tex, image); |
282 EXPECT_CALL( | 286 EXPECT_CALL( |
283 *context, | 287 *context, |
284 framebufferTexture2D( | 288 framebufferTexture2D( |
285 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, Ne(0U), _)) | 289 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, Ne(0U), _)) |
286 .After(fb, bind_tex); | 290 .After(fb, bind_tex); |
287 | 291 |
288 output_surface->BindFramebuffer(); | 292 output_surface->BindFramebuffer(); |
289 } | 293 } |
290 } | 294 } |
291 | 295 |
292 TEST(BufferQueueStandaloneTest, CheckBoundFramebuffer) { | 296 TEST(BufferQueueStandaloneTest, CheckBoundFramebuffer) { |
293 scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager; | 297 std::unique_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager; |
294 scoped_ptr<BufferQueue> output_surface; | 298 std::unique_ptr<BufferQueue> output_surface; |
295 scoped_refptr<cc::TestContextProvider> context_provider = | 299 scoped_refptr<cc::TestContextProvider> context_provider = |
296 cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create()); | 300 cc::TestContextProvider::Create(cc::TestWebGraphicsContext3D::Create()); |
297 context_provider->BindToCurrentThread(); | 301 context_provider->BindToCurrentThread(); |
298 gpu_memory_buffer_manager.reset(new StubBrowserGpuMemoryBufferManager); | 302 gpu_memory_buffer_manager.reset(new StubBrowserGpuMemoryBufferManager); |
299 | 303 |
300 scoped_ptr<GLHelper> gl_helper; | 304 std::unique_ptr<GLHelper> gl_helper; |
301 gl_helper.reset(new GLHelper(context_provider->ContextGL(), | 305 gl_helper.reset(new GLHelper(context_provider->ContextGL(), |
302 context_provider->ContextSupport())); | 306 context_provider->ContextSupport())); |
303 | 307 |
304 output_surface.reset(new BufferQueue(context_provider, GL_TEXTURE_2D, GL_RGBA, | 308 output_surface.reset(new BufferQueue(context_provider, GL_TEXTURE_2D, GL_RGBA, |
305 gl_helper.get(), | 309 gl_helper.get(), |
306 gpu_memory_buffer_manager.get(), 1)); | 310 gpu_memory_buffer_manager.get(), 1)); |
307 output_surface->Initialize(); | 311 output_surface->Initialize(); |
308 output_surface->Reshape(screen_size, 1.0f); | 312 output_surface->Reshape(screen_size, 1.0f); |
309 // Trigger a sub-buffer copy to exercise all paths. | 313 // Trigger a sub-buffer copy to exercise all paths. |
310 output_surface->BindFramebuffer(); | 314 output_surface->BindFramebuffer(); |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 testing::Mock::VerifyAndClearExpectations(mock_output_surface_); | 623 testing::Mock::VerifyAndClearExpectations(mock_output_surface_); |
620 EXPECT_CALL(*mock_output_surface_, | 624 EXPECT_CALL(*mock_output_surface_, |
621 CopyBufferDamage(target_texture, source_texture, small_damage, _)) | 625 CopyBufferDamage(target_texture, source_texture, small_damage, _)) |
622 .Times(1); | 626 .Times(1); |
623 output_surface_->SwapBuffers(small_damage); | 627 output_surface_->SwapBuffers(small_damage); |
624 testing::Mock::VerifyAndClearExpectations(mock_output_surface_); | 628 testing::Mock::VerifyAndClearExpectations(mock_output_surface_); |
625 } | 629 } |
626 | 630 |
627 } // namespace | 631 } // namespace |
628 } // namespace content | 632 } // namespace content |
OLD | NEW |