OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "cc/output/gl_renderer.h" | 5 #include "cc/output/gl_renderer.h" |
6 | 6 |
7 #include "cc/output/compositor_frame_metadata.h" | 7 #include "cc/output/compositor_frame_metadata.h" |
8 #include "cc/quads/draw_quad.h" | 8 #include "cc/quads/draw_quad.h" |
9 #include "cc/resources/prioritized_resource_manager.h" | 9 #include "cc/resources/prioritized_resource_manager.h" |
10 #include "cc/resources/resource_provider.h" | 10 #include "cc/resources/resource_provider.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 using testing::AnyNumber; | 26 using testing::AnyNumber; |
27 using testing::AtLeast; | 27 using testing::AtLeast; |
28 using testing::Expectation; | 28 using testing::Expectation; |
29 using testing::InSequence; | 29 using testing::InSequence; |
30 using testing::Mock; | 30 using testing::Mock; |
31 using testing::Return; | 31 using testing::Return; |
32 using testing::StrictMock; | 32 using testing::StrictMock; |
33 | 33 |
34 namespace cc { | 34 namespace cc { |
35 | 35 |
36 #define EXPECT_PROGRAM_VALID(program_binding) \ | 36 #define EXPECT_PROGRAM_VALID(program_binding) \ |
37 do { \ | 37 do { \ |
38 EXPECT_TRUE(program_binding->program()); \ | 38 EXPECT_TRUE(program_binding->program()); \ |
39 EXPECT_TRUE(program_binding->initialized()); \ | 39 EXPECT_TRUE(program_binding->initialized()); \ |
40 } while (false) | 40 } while (false) |
41 | 41 |
42 // Explicitly named to be a friend in GLRenderer for shader access. | 42 // Explicitly named to be a friend in GLRenderer for shader access. |
43 class GLRendererShaderTest : public PixelTest { | 43 class GLRendererShaderTest : public PixelTest { |
44 public: | 44 public: |
45 void TestShaders() { | 45 void TestShaders() { |
46 ASSERT_FALSE(renderer_->IsContextLost()); | 46 ASSERT_FALSE(renderer_->IsContextLost()); |
47 EXPECT_PROGRAM_VALID(renderer_->GetTileProgram()); | 47 EXPECT_PROGRAM_VALID(renderer_->GetTileProgram()); |
48 EXPECT_PROGRAM_VALID(renderer_->GetTileProgramOpaque()); | 48 EXPECT_PROGRAM_VALID(renderer_->GetTileProgramOpaque()); |
49 EXPECT_PROGRAM_VALID(renderer_->GetTileProgramAA()); | 49 EXPECT_PROGRAM_VALID(renderer_->GetTileProgramAA()); |
(...skipping 17 matching lines...) Expand all Loading... |
67 EXPECT_PROGRAM_VALID(renderer_->GetDebugBorderProgram()); | 67 EXPECT_PROGRAM_VALID(renderer_->GetDebugBorderProgram()); |
68 EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgram()); | 68 EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgram()); |
69 EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgramAA()); | 69 EXPECT_PROGRAM_VALID(renderer_->GetSolidColorProgramAA()); |
70 ASSERT_FALSE(renderer_->IsContextLost()); | 70 ASSERT_FALSE(renderer_->IsContextLost()); |
71 } | 71 } |
72 }; | 72 }; |
73 | 73 |
74 namespace { | 74 namespace { |
75 | 75 |
76 #if !defined(OS_ANDROID) | 76 #if !defined(OS_ANDROID) |
77 TEST_F(GLRendererShaderTest, AllShadersCompile) { | 77 TEST_F(GLRendererShaderTest, AllShadersCompile) { TestShaders(); } |
78 TestShaders(); | |
79 } | |
80 #endif | 78 #endif |
81 | 79 |
82 class FrameCountingMemoryAllocationSettingContext : public TestWebGraphicsContex
t3D { | 80 class FrameCountingMemoryAllocationSettingContext : |
83 public: | 81 public TestWebGraphicsContext3D { |
84 FrameCountingMemoryAllocationSettingContext() : m_frame(0) { } | 82 public: |
85 | 83 FrameCountingMemoryAllocationSettingContext() : frame_(0) {} |
86 // WebGraphicsContext3D methods. | 84 |
87 | 85 // WebGraphicsContext3D methods. |
88 // This method would normally do a glSwapBuffers under the hood. | 86 |
89 virtual void prepareTexture() { m_frame++; } | 87 // This method would normally do a glSwapBuffers under the hood. |
90 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAll
ocationChangedCallbackCHROMIUM* callback) { m_memoryAllocationChangedCallback =
callback; } | 88 virtual void prepareTexture() { frame_++; } |
91 virtual WebString getString(WebKit::WGC3Denum name) | 89 virtual void setMemoryAllocationChangedCallbackCHROMIUM( |
92 { | 90 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { |
93 if (name == GL_EXTENSIONS) | 91 memory_allocation_changed_callback_ = callback; |
94 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_
manager GL_CHROMIUM_discard_backbuffer"); | 92 } |
95 return WebString(); | 93 virtual WebString getString(WebKit::WGC3Denum name) { |
96 } | 94 if (name == GL_EXTENSIONS) |
97 | 95 return WebString( |
98 // Methods added for test. | 96 "GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager " |
99 int frameCount() { return m_frame; } | 97 "GL_CHROMIUM_discard_backbuffer"); |
100 void setMemoryAllocation(WebGraphicsMemoryAllocation allocation) | 98 return WebString(); |
101 { | 99 } |
102 m_memoryAllocationChangedCallback->onMemoryAllocationChanged(allocation)
; | 100 |
103 } | 101 // Methods added for test. |
104 | 102 int frame_count() { return frame_; } |
105 private: | 103 void SetMemoryAllocation(WebGraphicsMemoryAllocation allocation) { |
106 int m_frame; | 104 memory_allocation_changed_callback_->onMemoryAllocationChanged(allocation); |
107 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* m_memoryAllocationChange
dCallback; | 105 } |
| 106 |
| 107 private: |
| 108 int frame_; |
| 109 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* |
| 110 memory_allocation_changed_callback_; |
108 }; | 111 }; |
109 | 112 |
110 class FakeRendererClient : public RendererClient { | 113 class FakeRendererClient : public RendererClient { |
111 public: | 114 public: |
112 FakeRendererClient() | 115 FakeRendererClient() |
113 : m_hostImpl(&proxy_) | 116 : host_impl_(&proxy_), |
114 , m_setFullRootLayerDamageCount(0) | 117 set_full_root_layer_damage_count_(0), |
115 , m_lastCallWasSetVisibility(0) | 118 last_call_was_set_visibility_(0), |
116 , m_rootLayer(LayerImpl::Create(m_hostImpl.active_tree(), 1)) | 119 root_layer_(LayerImpl::Create(host_impl_.active_tree(), 1)), |
117 , m_memoryAllocationLimitBytes(PrioritizedResourceManager::DefaultMemory
AllocationLimit()) | 120 memory_allocation_limit_bytes_( |
118 { | 121 PrioritizedResourceManager::DefaultMemoryAllocationLimit()) { |
119 m_rootLayer->CreateRenderSurface(); | 122 root_layer_->CreateRenderSurface(); |
120 RenderPass::Id renderPassId = m_rootLayer->render_surface()->RenderPassI
d(); | 123 RenderPass::Id render_pass_id = |
121 scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); | 124 root_layer_->render_surface()->RenderPassId(); |
122 root_render_pass->SetNew(renderPassId, gfx::Rect(), gfx::Rect(), gfx::Tr
ansform()); | 125 scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); |
123 m_renderPassesInDrawOrder.push_back(root_render_pass.Pass()); | 126 root_render_pass->SetNew( |
124 } | 127 render_pass_id, gfx::Rect(), gfx::Rect(), gfx::Transform()); |
125 | 128 render_passes_in_draw_order_.push_back(root_render_pass.Pass()); |
126 // RendererClient methods. | 129 } |
127 virtual gfx::Size DeviceViewportSize() const OVERRIDE { static gfx::Size fak
eSize(1, 1); return fakeSize; } | 130 |
128 virtual const LayerTreeSettings& Settings() const OVERRIDE { static LayerTre
eSettings fakeSettings; return fakeSettings; } | 131 // RendererClient methods. |
129 virtual void DidLoseOutputSurface() OVERRIDE { } | 132 virtual gfx::Size DeviceViewportSize() const OVERRIDE { |
130 virtual void OnSwapBuffersComplete() OVERRIDE { } | 133 static gfx::Size fake_size(1, 1); |
131 virtual void SetFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCou
nt++; } | 134 return fake_size; |
132 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERR
IDE { m_memoryAllocationLimitBytes = policy.bytes_limit_when_visible; } | 135 } |
133 virtual void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) O
VERRIDE { if (m_lastCallWasSetVisibility) *m_lastCallWasSetVisibility = false; } | 136 virtual const LayerTreeSettings& Settings() const OVERRIDE { |
134 virtual bool HasImplThread() const OVERRIDE { return false; } | 137 static LayerTreeSettings fake_settings; |
135 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } | 138 return fake_settings; |
136 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const | 139 } |
137 OVERRIDE { return CompositorFrameMetadata(); } | 140 virtual void DidLoseOutputSurface() OVERRIDE {} |
138 | 141 virtual void OnSwapBuffersComplete() OVERRIDE {} |
139 // Methods added for test. | 142 virtual void SetFullRootLayerDamage() OVERRIDE { |
140 int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCou
nt; } | 143 set_full_root_layer_damage_count_++; |
141 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_
lastCallWasSetVisibility = lastCallWasSetVisibility; } | 144 } |
142 | 145 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) |
143 RenderPass* root_render_pass() { return m_renderPassesInDrawOrder.back(); } | 146 OVERRIDE { |
144 RenderPassList& renderPassesInDrawOrder() { return m_renderPassesInDrawOrder
; } | 147 memory_allocation_limit_bytes_ = policy.bytes_limit_when_visible; |
145 | 148 } |
146 size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBy
tes; } | 149 virtual void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) |
147 | 150 OVERRIDE { |
148 private: | 151 if (last_call_was_set_visibility_) |
149 FakeImplProxy proxy_; | 152 *last_call_was_set_visibility_ = false; |
150 FakeLayerTreeHostImpl m_hostImpl; | 153 } |
151 int m_setFullRootLayerDamageCount; | 154 virtual bool HasImplThread() const OVERRIDE { return false; } |
152 bool* m_lastCallWasSetVisibility; | 155 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } |
153 scoped_ptr<LayerImpl> m_rootLayer; | 156 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE { |
154 RenderPassList m_renderPassesInDrawOrder; | 157 return CompositorFrameMetadata(); |
155 size_t m_memoryAllocationLimitBytes; | 158 } |
| 159 |
| 160 // Methods added for test. |
| 161 int set_full_root_layer_damage_count() const { |
| 162 return set_full_root_layer_damage_count_; |
| 163 } |
| 164 void set_last_call_was_set_visibility_pointer(bool* last_call_was_set_visibili
ty) { |
| 165 last_call_was_set_visibility_ = last_call_was_set_visibility; |
| 166 } |
| 167 |
| 168 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); } |
| 169 RenderPassList* render_passes_in_draw_order() { |
| 170 return &render_passes_in_draw_order_; |
| 171 } |
| 172 |
| 173 size_t memory_allocation_limit_bytes() const { |
| 174 return memory_allocation_limit_bytes_; |
| 175 } |
| 176 |
| 177 private: |
| 178 FakeImplProxy proxy_; |
| 179 FakeLayerTreeHostImpl host_impl_; |
| 180 int set_full_root_layer_damage_count_; |
| 181 bool* last_call_was_set_visibility_; |
| 182 scoped_ptr<LayerImpl> root_layer_; |
| 183 RenderPassList render_passes_in_draw_order_; |
| 184 size_t memory_allocation_limit_bytes_; |
156 }; | 185 }; |
157 | 186 |
158 class FakeRendererGL : public GLRenderer { | 187 class FakeRendererGL : public GLRenderer { |
159 public: | 188 public: |
160 FakeRendererGL(RendererClient* client, OutputSurface* outputSurface, Resourc
eProvider* resourceProvider) : GLRenderer(client, outputSurface, resourceProvide
r) { } | 189 FakeRendererGL(RendererClient* client, |
161 | 190 OutputSurface* output_surface, |
162 // GLRenderer methods. | 191 ResourceProvider* resource_provider) |
163 | 192 : GLRenderer(client, output_surface, resource_provider) {} |
164 // Changing visibility to public. | 193 |
165 using GLRenderer::Initialize; | 194 // GLRenderer methods. |
166 using GLRenderer::IsBackbufferDiscarded; | 195 |
167 using GLRenderer::DoDrawQuad; | 196 // Changing visibility to public. |
168 using GLRenderer::BeginDrawingFrame; | 197 using GLRenderer::Initialize; |
169 using GLRenderer::FinishDrawingQuadList; | 198 using GLRenderer::IsBackbufferDiscarded; |
| 199 using GLRenderer::DoDrawQuad; |
| 200 using GLRenderer::BeginDrawingFrame; |
| 201 using GLRenderer::FinishDrawingQuadList; |
170 }; | 202 }; |
171 | 203 |
172 class GLRendererTest : public testing::Test { | 204 class GLRendererTest : public testing::Test { |
173 protected: | 205 protected: |
174 GLRendererTest() | 206 GLRendererTest() |
175 : m_suggestHaveBackbufferYes(1, true) | 207 : suggest_have_backbuffer_yes_(1, true), |
176 , m_suggestHaveBackbufferNo(1, false) | 208 suggest_have_backbuffer_no_(1, false), |
177 , m_outputSurface(FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGrap
hicsContext3D>(new FrameCountingMemoryAllocationSettingContext()))) | 209 output_surface_(FakeOutputSurface::Create3d( |
178 , resource_provider_(ResourceProvider::Create(m_outputSurface.get())) | 210 scoped_ptr<WebKit::WebGraphicsContext3D>( |
179 , m_renderer(&m_mockClient, m_outputSurface.get(), resource_provider_.ge
t()) | 211 new FrameCountingMemoryAllocationSettingContext()))), |
180 { | 212 resource_provider_(ResourceProvider::Create(output_surface_.get())), |
181 } | 213 renderer_(&mock_client_, |
182 | 214 output_surface_.get(), |
183 virtual void SetUp() | 215 resource_provider_.get()) {} |
184 { | 216 |
185 m_renderer.Initialize(); | 217 virtual void SetUp() { renderer_.Initialize(); } |
186 } | 218 |
187 | 219 void SwapBuffers() { renderer_.SwapBuffers(); } |
188 void SwapBuffers() | 220 |
189 { | 221 FrameCountingMemoryAllocationSettingContext* context() { |
190 m_renderer.SwapBuffers(); | 222 return static_cast<FrameCountingMemoryAllocationSettingContext*>( |
191 } | 223 output_surface_->context3d()); |
192 | 224 } |
193 FrameCountingMemoryAllocationSettingContext* context() { return static_cast<
FrameCountingMemoryAllocationSettingContext*>(m_outputSurface->context3d()); } | 225 |
194 | 226 WebGraphicsMemoryAllocation suggest_have_backbuffer_yes_; |
195 WebGraphicsMemoryAllocation m_suggestHaveBackbufferYes; | 227 WebGraphicsMemoryAllocation suggest_have_backbuffer_no_; |
196 WebGraphicsMemoryAllocation m_suggestHaveBackbufferNo; | 228 |
197 | 229 scoped_ptr<OutputSurface> output_surface_; |
198 scoped_ptr<OutputSurface> m_outputSurface; | 230 FakeRendererClient mock_client_; |
199 FakeRendererClient m_mockClient; | 231 scoped_ptr<ResourceProvider> resource_provider_; |
200 scoped_ptr<ResourceProvider> resource_provider_; | 232 FakeRendererGL renderer_; |
201 FakeRendererGL m_renderer; | |
202 }; | 233 }; |
203 | 234 |
204 // Test GLRenderer discardBackbuffer functionality: | 235 // Test GLRenderer discardBackbuffer functionality: |
205 // Suggest recreating framebuffer when one already exists. | 236 // Suggest recreating framebuffer when one already exists. |
206 // Expected: it does nothing. | 237 // Expected: it does nothing. |
207 TEST_F(GLRendererTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing) | 238 TEST_F(GLRendererTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing) { |
208 { | 239 context()->SetMemoryAllocation(suggest_have_backbuffer_yes_); |
209 context()->setMemoryAllocation(m_suggestHaveBackbufferYes); | 240 EXPECT_EQ(0, mock_client_.set_full_root_layer_damage_count()); |
210 EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount()); | 241 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
211 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 242 |
212 | 243 SwapBuffers(); |
213 SwapBuffers(); | 244 EXPECT_EQ(1, context()->frame_count()); |
214 EXPECT_EQ(1, context()->frameCount()); | |
215 } | 245 } |
216 | 246 |
217 // Test GLRenderer discardBackbuffer functionality: | 247 // Test GLRenderer discardBackbuffer functionality: |
218 // Suggest discarding framebuffer when one exists and the renderer is not visibl
e. | 248 // Suggest discarding framebuffer when one exists and the renderer is not |
| 249 // visible. |
219 // Expected: it is discarded and damage tracker is reset. | 250 // Expected: it is discarded and damage tracker is reset. |
220 TEST_F(GLRendererTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLa
yerWhileNotVisible) | 251 TEST_F(GLRendererTest, |
221 { | 252 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerWhileNotVisib
le) { |
222 m_renderer.SetVisible(false); | 253 renderer_.SetVisible(false); |
223 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 254 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
224 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 255 EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); |
225 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 256 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
226 } | 257 } |
227 | 258 |
228 // Test GLRenderer discardBackbuffer functionality: | 259 // Test GLRenderer discardBackbuffer functionality: |
229 // Suggest discarding framebuffer when one exists and the renderer is visible. | 260 // Suggest discarding framebuffer when one exists and the renderer is visible. |
230 // Expected: the allocation is ignored. | 261 // Expected: the allocation is ignored. |
231 TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) | 262 TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) { |
232 { | 263 renderer_.SetVisible(true); |
233 m_renderer.SetVisible(true); | 264 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
234 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 265 EXPECT_EQ(0, mock_client_.set_full_root_layer_damage_count()); |
235 EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount()); | 266 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
236 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 267 } |
237 } | |
238 | |
239 | 268 |
240 // Test GLRenderer discardBackbuffer functionality: | 269 // Test GLRenderer discardBackbuffer functionality: |
241 // Suggest discarding framebuffer when one does not exist. | 270 // Suggest discarding framebuffer when one does not exist. |
242 // Expected: it does nothing. | 271 // Expected: it does nothing. |
243 TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) | 272 TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) { |
244 { | 273 renderer_.SetVisible(false); |
245 m_renderer.SetVisible(false); | 274 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
246 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 275 EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); |
247 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 276 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
248 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 277 |
249 | 278 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
250 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 279 EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); |
251 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 280 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
252 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | |
253 } | 281 } |
254 | 282 |
255 // Test GLRenderer discardBackbuffer functionality: | 283 // Test GLRenderer discardBackbuffer functionality: |
256 // Begin drawing a frame while a framebuffer is discarded. | 284 // Begin drawing a frame while a framebuffer is discarded. |
257 // Expected: will recreate framebuffer. | 285 // Expected: will recreate framebuffer. |
258 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) | 286 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) { |
259 { | 287 renderer_.SetVisible(false); |
260 m_renderer.SetVisible(false); | 288 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
261 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 289 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
262 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 290 EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); |
263 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 291 |
264 | 292 renderer_.SetVisible(true); |
265 m_renderer.SetVisible(true); | 293 renderer_.DrawFrame(*mock_client_.render_passes_in_draw_order()); |
266 m_renderer.DrawFrame(m_mockClient.renderPassesInDrawOrder()); | 294 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
267 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 295 |
268 | 296 SwapBuffers(); |
269 SwapBuffers(); | 297 EXPECT_EQ(1, context()->frame_count()); |
270 EXPECT_EQ(1, context()->frameCount()); | 298 } |
271 } | 299 |
272 | 300 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) { |
273 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) | 301 renderer_.SetVisible(false); |
274 { | 302 context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
275 m_renderer.SetVisible(false); | 303 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
276 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 304 EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); |
277 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 305 |
278 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 306 char pixels[4]; |
279 | 307 renderer_.DrawFrame(*mock_client_.render_passes_in_draw_order()); |
280 char pixels[4]; | 308 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
281 m_renderer.DrawFrame(m_mockClient.renderPassesInDrawOrder()); | 309 |
282 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 310 renderer_.GetFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); |
283 | 311 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
284 m_renderer.GetFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); | 312 EXPECT_EQ(2, mock_client_.set_full_root_layer_damage_count()); |
285 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | |
286 EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount()); | |
287 } | 313 } |
288 | 314 |
289 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { | 315 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { |
290 public: | 316 public: |
291 ForbidSynchronousCallContext() { } | 317 ForbidSynchronousCallContext() {} |
292 | 318 |
293 virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&)
{ ADD_FAILURE(); return false; } | 319 virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo& inf
o) { |
294 virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&)
{ ADD_FAILURE(); return false; } | 320 ADD_FAILURE(); |
295 virtual void getAttachedShaders(WebGLId program, WGC3Dsizei maxCount, WGC3Ds
izei* count, WebGLId* shaders) { ADD_FAILURE(); } | 321 return false; |
296 virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name) {
ADD_FAILURE(); return 0; } | 322 } |
297 virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value) { ADD_FAILURE
(); } | 323 virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo& in
fo) { |
298 virtual void getBufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Din
t* value) { ADD_FAILURE(); } | 324 ADD_FAILURE(); |
299 virtual Attributes getContextAttributes() { ADD_FAILURE(); return attributes
_; } | 325 return false; |
300 virtual WGC3Denum getError() { ADD_FAILURE(); return 0; } | 326 } |
301 virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE();
} | 327 virtual void getAttachedShaders(WebGLId program, |
302 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, WGC3Denum
attachment, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); } | 328 WGC3Dsizei max_count, |
303 virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value) | 329 WGC3Dsizei* count, |
304 { | 330 WebGLId* shaders) { |
305 if (pname == GL_MAX_TEXTURE_SIZE) | 331 ADD_FAILURE(); |
306 *value = 1024; // MAX_TEXTURE_SIZE is cached client side, so it's OK
to query. | 332 } |
307 else | 333 virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name) { |
308 ADD_FAILURE(); | 334 ADD_FAILURE(); |
| 335 return 0; |
| 336 } |
| 337 virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value) { |
| 338 ADD_FAILURE(); |
| 339 } |
| 340 virtual void getBufferParameteriv(WGC3Denum target, |
| 341 WGC3Denum pname, |
| 342 WGC3Dint* value) { |
| 343 ADD_FAILURE(); |
| 344 } |
| 345 virtual Attributes getContextAttributes() { |
| 346 ADD_FAILURE(); |
| 347 return attributes_; |
| 348 } |
| 349 virtual WGC3Denum getError() { |
| 350 ADD_FAILURE(); |
| 351 return 0; |
| 352 } |
| 353 virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); } |
| 354 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, |
| 355 WGC3Denum attachment, |
| 356 WGC3Denum pname, |
| 357 WGC3Dint* value) { |
| 358 ADD_FAILURE(); |
| 359 } |
| 360 virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value) { |
| 361 if (pname == GL_MAX_TEXTURE_SIZE) { |
| 362 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query. |
| 363 *value = 1024; |
309 } | 364 } |
310 | 365 else { |
311 // We allow querying the shader compilation and program link status in debug
mode, but not release. | 366 ADD_FAILURE(); |
312 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) | 367 } |
313 { | 368 } |
| 369 |
| 370 // We allow querying the shader compilation and program link status in debug |
| 371 // mode, but not release. |
| 372 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) { |
314 #ifndef NDEBUG | 373 #ifndef NDEBUG |
315 *value = 1; | 374 *value = 1; |
316 #else | 375 #else |
317 ADD_FAILURE(); | 376 ADD_FAILURE(); |
318 #endif | 377 #endif |
319 } | 378 } |
320 | 379 |
321 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) | 380 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) { |
322 { | |
323 #ifndef NDEBUG | 381 #ifndef NDEBUG |
324 *value = 1; | 382 *value = 1; |
325 #else | 383 #else |
326 ADD_FAILURE(); | 384 ADD_FAILURE(); |
327 #endif | 385 #endif |
328 } | 386 } |
329 | 387 |
330 virtual WebString getString(WGC3Denum name) | 388 virtual WebString getString(WGC3Denum name) { |
331 { | 389 // We allow querying the extension string. |
332 // We allow querying the extension string. | 390 // FIXME: It'd be better to check that we only do this before starting any |
333 // FIXME: It'd be better to check that we only do this before starting a
ny other expensive work (like starting a compilation) | 391 // other expensive work (like starting a compilation) |
334 if (name != GL_EXTENSIONS) | 392 if (name != GL_EXTENSIONS) |
335 ADD_FAILURE(); | 393 ADD_FAILURE(); |
336 return WebString(); | 394 return WebString(); |
337 } | 395 } |
338 | 396 |
339 virtual WebString getProgramInfoLog(WebGLId program) { ADD_FAILURE(); return
WebString(); } | 397 virtual WebString getProgramInfoLog(WebGLId program) { |
340 virtual void getRenderbufferParameteriv(WGC3Denum target, WGC3Denum pname, W
GC3Dint* value) { ADD_FAILURE(); } | 398 ADD_FAILURE(); |
341 | 399 return WebString(); |
342 virtual WebString getShaderInfoLog(WebGLId shader) { ADD_FAILURE(); return W
ebString(); } | 400 } |
343 virtual void getShaderPrecisionFormat(WGC3Denum shadertype, WGC3Denum precis
iontype, WGC3Dint* range, WGC3Dint* precision) { ADD_FAILURE(); } | 401 virtual void getRenderbufferParameteriv(WGC3Denum target, |
344 virtual WebString getShaderSource(WebGLId shader) { ADD_FAILURE(); return We
bString(); } | 402 WGC3Denum pname, |
345 virtual void getTexParameterfv(WGC3Denum target, WGC3Denum pname, WGC3Dfloat
* value) { ADD_FAILURE(); } | 403 WGC3Dint* value) { |
346 virtual void getTexParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint*
value) { ADD_FAILURE(); } | 404 ADD_FAILURE(); |
347 virtual void getUniformfv(WebGLId program, WGC3Dint location, WGC3Dfloat* va
lue) { ADD_FAILURE(); } | 405 } |
348 virtual void getUniformiv(WebGLId program, WGC3Dint location, WGC3Dint* valu
e) { ADD_FAILURE(); } | 406 |
349 virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name)
{ ADD_FAILURE(); return 0; } | 407 virtual WebString getShaderInfoLog(WebGLId shader) { |
350 virtual void getVertexAttribfv(WGC3Duint index, WGC3Denum pname, WGC3Dfloat*
value) { ADD_FAILURE(); } | 408 ADD_FAILURE(); |
351 virtual void getVertexAttribiv(WGC3Duint index, WGC3Denum pname, WGC3Dint* v
alue) { ADD_FAILURE(); } | 409 return WebString(); |
352 virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, WGC3Denum pname
) { ADD_FAILURE(); return 0; } | 410 } |
353 }; | 411 virtual void getShaderPrecisionFormat(WGC3Denum shadertype, |
354 | 412 WGC3Denum precisiontype, |
355 // This test isn't using the same fixture as GLRendererTest, and you can't mix T
EST() and TEST_F() with the same name, hence LRC2. | 413 WGC3Dint* range, |
356 TEST(GLRendererTest2, initializationDoesNotMakeSynchronousCalls) | 414 WGC3Dint* precision) { |
357 { | 415 ADD_FAILURE(); |
358 FakeRendererClient mockClient; | 416 } |
359 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ForbidSynchronousCallContext))); | 417 virtual WebString getShaderSource(WebGLId shader) { |
360 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 418 ADD_FAILURE(); |
361 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 419 return WebString(); |
362 | 420 } |
363 EXPECT_TRUE(renderer.Initialize()); | 421 virtual void getTexParameterfv(WGC3Denum target, |
| 422 WGC3Denum pname, |
| 423 WGC3Dfloat* value) { |
| 424 ADD_FAILURE(); |
| 425 } |
| 426 virtual void getTexParameteriv(WGC3Denum target, |
| 427 WGC3Denum pname, |
| 428 WGC3Dint* value) { |
| 429 ADD_FAILURE(); |
| 430 } |
| 431 virtual void getUniformfv(WebGLId program, |
| 432 WGC3Dint location, |
| 433 WGC3Dfloat* value) { |
| 434 ADD_FAILURE(); |
| 435 } |
| 436 virtual void getUniformiv(WebGLId program, |
| 437 WGC3Dint location, |
| 438 WGC3Dint* value) { |
| 439 ADD_FAILURE(); |
| 440 } |
| 441 virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name) { |
| 442 ADD_FAILURE(); |
| 443 return 0; |
| 444 } |
| 445 virtual void getVertexAttribfv(WGC3Duint index, |
| 446 WGC3Denum pname, |
| 447 WGC3Dfloat* value) { |
| 448 ADD_FAILURE(); |
| 449 } |
| 450 virtual void getVertexAttribiv(WGC3Duint index, |
| 451 WGC3Denum pname, |
| 452 WGC3Dint* value) { |
| 453 ADD_FAILURE(); |
| 454 } |
| 455 virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, |
| 456 WGC3Denum pname) { |
| 457 ADD_FAILURE(); |
| 458 return 0; |
| 459 } |
| 460 }; |
| 461 |
| 462 // This test isn't using the same fixture as GLRendererTest, and you can't mix |
| 463 // TEST() and TEST_F() with the same name, Hence LRC2. |
| 464 TEST(GLRendererTest2, InitializationDoesNotMakeSynchronousCalls) { |
| 465 FakeRendererClient mock_client; |
| 466 scoped_ptr<OutputSurface> output_surface( |
| 467 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 468 new ForbidSynchronousCallContext))); |
| 469 scoped_ptr<ResourceProvider> resource_provider( |
| 470 ResourceProvider::Create(output_surface.get())); |
| 471 FakeRendererGL renderer( |
| 472 &mock_client, output_surface.get(), resource_provider.get()); |
| 473 |
| 474 EXPECT_TRUE(renderer.Initialize()); |
364 } | 475 } |
365 | 476 |
366 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { | 477 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { |
367 public: | 478 public: |
368 LoseContextOnFirstGetContext() | 479 LoseContextOnFirstGetContext() : context_lost_(false) {} |
369 : m_contextLost(false) | 480 |
370 { | 481 virtual bool makeContextCurrent() OVERRIDE { return !context_lost_; } |
371 } | 482 |
372 | 483 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) |
373 virtual bool makeContextCurrent() OVERRIDE | 484 OVERRIDE { |
374 { | 485 context_lost_ = true; |
375 return !m_contextLost; | 486 *value = 0; |
376 } | 487 } |
377 | 488 |
378 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value)
OVERRIDE | 489 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) |
379 { | 490 OVERRIDE { |
380 m_contextLost = true; | 491 context_lost_ = true; |
381 *value = 0; | 492 *value = 0; |
382 } | 493 } |
383 | 494 |
384 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) O
VERRIDE | 495 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE { |
385 { | 496 return context_lost_ ? 1 : 0; |
386 m_contextLost = true; | 497 } |
387 *value = 0; | 498 |
388 } | 499 private: |
389 | 500 bool context_lost_; |
390 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE | 501 }; |
391 { | 502 |
392 return m_contextLost ? 1 : 0; | 503 TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) { |
393 } | 504 FakeRendererClient mock_client; |
394 | 505 scoped_ptr<OutputSurface> output_surface( |
395 private: | 506 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
396 bool m_contextLost; | 507 new LoseContextOnFirstGetContext))); |
397 }; | 508 scoped_ptr<ResourceProvider> resource_provider( |
398 | 509 ResourceProvider::Create(output_surface.get())); |
399 TEST(GLRendererTest2, initializationWithQuicklyLostContextDoesNotAssert) | 510 FakeRendererGL renderer( |
400 { | 511 &mock_client, output_surface.get(), resource_provider.get()); |
401 FakeRendererClient mockClient; | 512 |
402 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new LoseContextOnFirstGetContext))); | 513 renderer.Initialize(); |
403 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 514 } |
404 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 515 |
405 | 516 class ContextThatDoesNotSupportMemoryManagmentExtensions : |
406 renderer.Initialize(); | 517 public TestWebGraphicsContext3D { |
407 } | 518 public: |
408 | 519 ContextThatDoesNotSupportMemoryManagmentExtensions() {} |
409 class ContextThatDoesNotSupportMemoryManagmentExtensions : public TestWebGraphic
sContext3D { | 520 |
410 public: | 521 // WebGraphicsContext3D methods. |
411 ContextThatDoesNotSupportMemoryManagmentExtensions() { } | 522 |
412 | 523 // This method would normally do a glSwapBuffers under the hood. |
413 // WebGraphicsContext3D methods. | 524 virtual void prepareTexture() {} |
414 | 525 virtual void setMemoryAllocationChangedCallbackCHROMIUM( |
415 // This method would normally do a glSwapBuffers under the hood. | 526 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {} |
416 virtual void prepareTexture() { } | 527 virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } |
417 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAll
ocationChangedCallbackCHROMIUM* callback) { } | 528 }; |
418 virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } | 529 |
419 }; | 530 TEST( |
420 | 531 GLRendererTest2, |
421 TEST(GLRendererTest2, initializationWithoutGpuMemoryManagerExtensionSupportShoul
dDefaultToNonZeroAllocation) | 532 InitializationWithoutGpuMemoryManagerExtensionSupportShouldDefaultToNonZeroA
llocation) { |
422 { | 533 FakeRendererClient mock_client; |
423 FakeRendererClient mockClient; | 534 scoped_ptr<OutputSurface> output_surface( |
424 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ContextThatDoesNotSupportMemoryManagmentExt
ensions))); | 535 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
425 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 536 new ContextThatDoesNotSupportMemoryManagmentExtensions))); |
426 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 537 scoped_ptr<ResourceProvider> resource_provider( |
427 | 538 ResourceProvider::Create(output_surface.get())); |
428 renderer.Initialize(); | 539 FakeRendererGL renderer( |
429 | 540 &mock_client, output_surface.get(), resource_provider.get()); |
430 EXPECT_GT(mockClient.memoryAllocationLimitBytes(), 0ul); | 541 |
| 542 renderer.Initialize(); |
| 543 |
| 544 EXPECT_GT(mock_client.memory_allocation_limit_bytes(), 0ul); |
431 } | 545 } |
432 | 546 |
433 class ClearCountingContext : public TestWebGraphicsContext3D { | 547 class ClearCountingContext : public TestWebGraphicsContext3D { |
434 public: | 548 public: |
435 ClearCountingContext() : m_clear(0) { } | 549 ClearCountingContext() : clear_(0) {} |
436 | 550 |
437 virtual void clear(WGC3Dbitfield) | 551 virtual void clear(WGC3Dbitfield) { clear_++; } |
438 { | 552 |
439 m_clear++; | 553 int clear_count() const { return clear_; } |
440 } | 554 |
441 | 555 private: |
442 int clearCount() const { return m_clear; } | 556 int clear_; |
443 | 557 }; |
444 private: | 558 |
445 int m_clear; | 559 TEST(GLRendererTest2, OpaqueBackground) { |
446 }; | 560 FakeRendererClient mock_client; |
447 | 561 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( |
448 TEST(GLRendererTest2, opaqueBackground) | 562 scoped_ptr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
449 { | 563 ClearCountingContext* context = |
450 FakeRendererClient mockClient; | 564 static_cast<ClearCountingContext*>(output_surface->context3d()); |
451 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 565 scoped_ptr<ResourceProvider> resource_provider( |
452 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->context3d()); | 566 ResourceProvider::Create(output_surface.get())); |
453 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 567 FakeRendererGL renderer( |
454 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 568 &mock_client, output_surface.get(), resource_provider.get()); |
455 | 569 |
456 mockClient.root_render_pass()->has_transparent_background = false; | 570 mock_client.root_render_pass()->has_transparent_background = false; |
457 | 571 |
458 EXPECT_TRUE(renderer.Initialize()); | 572 EXPECT_TRUE(renderer.Initialize()); |
459 | 573 |
460 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 574 renderer.DrawFrame(*mock_client.render_passes_in_draw_order()); |
461 | 575 |
462 // On DEBUG builds, render passes with opaque background clear to blue to | 576 // On DEBUG builds, render passes with opaque background clear to blue to |
463 // easily see regions that were not drawn on the screen. | 577 // easily see regions that were not drawn on the screen. |
464 #ifdef NDEBUG | 578 #ifdef NDEBUG |
465 EXPECT_EQ(0, context->clearCount()); | 579 EXPECT_EQ(0, context->clear_count()); |
466 #else | 580 #else |
467 EXPECT_EQ(1, context->clearCount()); | 581 EXPECT_EQ(1, context->clear_count()); |
468 #endif | 582 #endif |
469 } | 583 } |
470 | 584 |
471 TEST(GLRendererTest2, transparentBackground) | 585 TEST(GLRendererTest2, TransparentBackground) { |
472 { | 586 FakeRendererClient mock_client; |
473 FakeRendererClient mockClient; | 587 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( |
474 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 588 scoped_ptr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
475 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->context3d()); | 589 ClearCountingContext* context = |
476 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 590 static_cast<ClearCountingContext*>(output_surface->context3d()); |
477 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 591 scoped_ptr<ResourceProvider> resource_provider( |
478 | 592 ResourceProvider::Create(output_surface.get())); |
479 mockClient.root_render_pass()->has_transparent_background = true; | 593 FakeRendererGL renderer( |
480 | 594 &mock_client, output_surface.get(), resource_provider.get()); |
481 EXPECT_TRUE(renderer.Initialize()); | 595 |
482 | 596 mock_client.root_render_pass()->has_transparent_background = true; |
483 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 597 |
484 | 598 EXPECT_TRUE(renderer.Initialize()); |
485 EXPECT_EQ(1, context->clearCount()); | 599 |
486 } | 600 renderer.DrawFrame(*mock_client.render_passes_in_draw_order()); |
487 | 601 |
488 class VisibilityChangeIsLastCallTrackingContext : public TestWebGraphicsContext3
D { | 602 EXPECT_EQ(1, context->clear_count()); |
489 public: | 603 } |
490 VisibilityChangeIsLastCallTrackingContext() | 604 |
491 : m_lastCallWasSetVisibility(0) | 605 class VisibilityChangeIsLastCallTrackingContext : |
492 { | 606 public TestWebGraphicsContext3D { |
493 } | 607 public: |
494 | 608 VisibilityChangeIsLastCallTrackingContext() |
495 // WebGraphicsContext3D methods. | 609 : last_call_was_set_visibility_(0) {} |
496 virtual void setVisibilityCHROMIUM(bool visible) { | 610 |
497 if (!m_lastCallWasSetVisibility) | 611 // WebGraphicsContext3D methods. |
498 return; | 612 virtual void setVisibilityCHROMIUM(bool visible) { |
499 DCHECK(*m_lastCallWasSetVisibility == false); | 613 if (!last_call_was_set_visibility_) |
500 *m_lastCallWasSetVisibility = true; | 614 return; |
501 } | 615 DCHECK(*last_call_was_set_visibility_ == false); |
502 virtual void flush() { if (m_lastCallWasSetVisibility) *m_lastCallWasSetVisi
bility = false; } | 616 *last_call_was_set_visibility_ = true; |
503 virtual void deleteTexture(WebGLId) { if (m_lastCallWasSetVisibility) *m_las
tCallWasSetVisibility = false; } | 617 } |
504 virtual void deleteFramebuffer(WebGLId) { if (m_lastCallWasSetVisibility) *m
_lastCallWasSetVisibility = false; } | 618 virtual void flush() { |
505 virtual void deleteRenderbuffer(WebGLId) { if (m_lastCallWasSetVisibility) *
m_lastCallWasSetVisibility = false; } | 619 if (last_call_was_set_visibility_) |
506 | 620 *last_call_was_set_visibility_ = false; |
507 // This method would normally do a glSwapBuffers under the hood. | 621 } |
508 virtual WebString getString(WebKit::WGC3Denum name) | 622 virtual void deleteTexture(WebGLId) { |
509 { | 623 if (last_call_was_set_visibility_) |
510 if (name == GL_EXTENSIONS) | 624 *last_call_was_set_visibility_ = false; |
511 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_
manager GL_CHROMIUM_discard_backbuffer"); | 625 } |
512 return WebString(); | 626 virtual void deleteFramebuffer(WebGLId) { |
513 } | 627 if (last_call_was_set_visibility_) |
514 | 628 *last_call_was_set_visibility_ = false; |
515 // Methods added for test. | 629 } |
516 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_
lastCallWasSetVisibility = lastCallWasSetVisibility; } | 630 virtual void deleteRenderbuffer(WebGLId) { |
517 | 631 if (last_call_was_set_visibility_) |
518 private: | 632 *last_call_was_set_visibility_ = false; |
519 bool* m_lastCallWasSetVisibility; | 633 } |
520 }; | 634 |
521 | 635 // This method would normally do a glSwapBuffers under the hood. |
522 TEST(GLRendererTest2, visibilityChangeIsLastCall) | 636 virtual WebString getString(WebKit::WGC3Denum name) { |
523 { | 637 if (name == GL_EXTENSIONS) |
524 FakeRendererClient mockClient; | 638 return WebString( |
525 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new VisibilityChangeIsLastCallTrackingContext))
); | 639 "GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager " |
526 VisibilityChangeIsLastCallTrackingContext* context = static_cast<VisibilityC
hangeIsLastCallTrackingContext*>(outputSurface->context3d()); | 640 "GL_CHROMIUM_discard_backbuffer"); |
527 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 641 return WebString(); |
528 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 642 } |
529 | 643 |
530 EXPECT_TRUE(renderer.Initialize()); | 644 // Methods added for test. |
531 | 645 void set_last_call_was_set_visibility_pointer(bool* last_call_was_set_visibili
ty) { |
532 bool lastCallWasSetVisiblity = false; | 646 last_call_was_set_visibility_ = last_call_was_set_visibility; |
533 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to t
he GPU | 647 } |
534 // process, after glFlush is called, and after the RendererClient's enforceM
anagedMemoryPolicy | 648 |
535 // is called. Plumb this tracking between both the RenderClient and the Cont
ext by giving | 649 private: |
536 // them both a pointer to a variable on the stack. | 650 bool* last_call_was_set_visibility_; |
537 context->setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 651 }; |
538 mockClient.setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 652 |
539 renderer.SetVisible(true); | 653 TEST(GLRendererTest2, VisibilityChangeIsLastCall) { |
540 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 654 FakeRendererClient mock_client; |
541 renderer.SetVisible(false); | 655 scoped_ptr<OutputSurface> output_surface( |
542 EXPECT_TRUE(lastCallWasSetVisiblity); | 656 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 657 new VisibilityChangeIsLastCallTrackingContext))); |
| 658 VisibilityChangeIsLastCallTrackingContext* context = |
| 659 static_cast<VisibilityChangeIsLastCallTrackingContext*>( |
| 660 output_surface->context3d()); |
| 661 scoped_ptr<ResourceProvider> resource_provider( |
| 662 ResourceProvider::Create(output_surface.get())); |
| 663 FakeRendererGL renderer( |
| 664 &mock_client, output_surface.get(), resource_provider.get()); |
| 665 |
| 666 EXPECT_TRUE(renderer.Initialize()); |
| 667 |
| 668 bool last_call_was_set_visiblity = false; |
| 669 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to the |
| 670 // GPU process, after glFlush is called, and after the RendererClient's |
| 671 // enforceManagedMemoryPolicy is called. Plumb this tracking between both the |
| 672 // RenderClient and the Context by giving them both a pointer to a variable on |
| 673 // the stack. |
| 674 context->set_last_call_was_set_visibility_pointer(&last_call_was_set_visiblity
); |
| 675 mock_client.set_last_call_was_set_visibility_pointer(&last_call_was_set_visibl
ity); |
| 676 renderer.SetVisible(true); |
| 677 renderer.DrawFrame(*mock_client.render_passes_in_draw_order()); |
| 678 renderer.SetVisible(false); |
| 679 EXPECT_TRUE(last_call_was_set_visiblity); |
543 } | 680 } |
544 | 681 |
545 class TextureStateTrackingContext : public TestWebGraphicsContext3D { | 682 class TextureStateTrackingContext : public TestWebGraphicsContext3D { |
546 public: | 683 public: |
547 TextureStateTrackingContext() | 684 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {} |
548 : m_activeTexture(GL_INVALID_ENUM) | 685 |
549 { | 686 virtual WebString getString(WGC3Denum name) { |
550 } | 687 if (name == GL_EXTENSIONS) |
551 | 688 return WebString("GL_OES_EGL_image_external"); |
552 virtual WebString getString(WGC3Denum name) | 689 return WebString(); |
553 { | 690 } |
554 if (name == GL_EXTENSIONS) | 691 |
555 return WebString("GL_OES_EGL_image_external"); | 692 MOCK_METHOD3(texParameteri, |
556 return WebString(); | 693 void(WGC3Denum target, WGC3Denum pname, WGC3Dint param)); |
557 } | 694 MOCK_METHOD4(drawElements, |
558 | 695 void(WGC3Denum mode, |
559 MOCK_METHOD3(texParameteri, void(WGC3Denum target, WGC3Denum pname, WGC3Dint
param)); | 696 WGC3Dsizei count, |
560 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum
type, WGC3Dintptr offset)); | 697 WGC3Denum type, |
561 | 698 WGC3Dintptr offset)); |
562 virtual void activeTexture(WGC3Denum texture) | 699 |
563 { | 700 virtual void activeTexture(WGC3Denum texture) { |
564 EXPECT_NE(texture, m_activeTexture); | 701 EXPECT_NE(texture, active_texture_); |
565 m_activeTexture = texture; | 702 active_texture_ = texture; |
566 } | 703 } |
567 | 704 |
568 WGC3Denum activeTexture() const { return m_activeTexture; } | 705 WGC3Denum active_texture() const { return active_texture_; } |
569 | 706 |
570 private: | 707 private: |
571 WGC3Denum m_activeTexture; | 708 WGC3Denum active_texture_; |
572 }; | 709 }; |
573 | 710 |
574 TEST(GLRendererTest2, activeTextureState) | 711 TEST(GLRendererTest2, ActiveTextureState) { |
575 { | 712 FakeRendererClient fake_client; |
576 FakeRendererClient fakeClient; | 713 scoped_ptr<OutputSurface> output_surface( |
577 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new TextureStateTrackingContext))); | 714 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
578 TextureStateTrackingContext* context = static_cast<TextureStateTrackingConte
xt*>(outputSurface->context3d()); | 715 new TextureStateTrackingContext))); |
579 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 716 TextureStateTrackingContext* context = |
580 FakeRendererGL renderer(&fakeClient, outputSurface.get(), resourceProvider.g
et()); | 717 static_cast<TextureStateTrackingContext*>(output_surface->context3d()); |
581 | 718 scoped_ptr<ResourceProvider> resource_provider( |
582 // During initialization we are allowed to set any texture parameters. | 719 ResourceProvider::Create(output_surface.get())); |
583 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber()); | 720 FakeRendererGL renderer( |
584 EXPECT_TRUE(renderer.Initialize()); | 721 &fake_client, output_surface.get(), resource_provider.get()); |
585 | 722 |
586 cc::RenderPass::Id id(1, 1); | 723 // During initialization we are allowed to set any texture parameters. |
587 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); | 724 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber()); |
588 pass->SetNew(id, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100), gfx::
Transform()); | 725 EXPECT_TRUE(renderer.Initialize()); |
589 pass->AppendOneOfEveryQuadType(resourceProvider.get(), RenderPass::Id(2, 1))
; | 726 |
590 | 727 cc::RenderPass::Id id(1, 1); |
591 // Set up expected texture filter state transitions that match the quads | 728 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); |
592 // created in AppendOneOfEveryQuadType(). | 729 pass->SetNew(id, |
593 Mock::VerifyAndClearExpectations(context); | 730 gfx::Rect(0, 0, 100, 100), |
594 { | 731 gfx::Rect(0, 0, 100, 100), |
595 InSequence sequence; | 732 gfx::Transform()); |
596 | 733 pass->AppendOneOfEveryQuadType(resource_provider.get(), RenderPass::Id(2, 1)); |
597 // yuv_quad is drawn with the default linear filter. | 734 |
598 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 735 // Set up expected texture filter state transitions that match the quads |
599 | 736 // created in AppendOneOfEveryQuadType(). |
600 // tile_quad is drawn with GL_NEAREST because it is not transformed or | 737 Mock::VerifyAndClearExpectations(context); |
601 // scaled. | 738 { |
602 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER
, GL_NEAREST)); | 739 InSequence sequence; |
603 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER
, GL_NEAREST)); | 740 |
604 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 741 // yuv_quad is drawn with the default linear filter. |
605 | 742 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
606 // transformed_tile_quad uses GL_LINEAR. | 743 |
607 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 744 // tile_quad is drawn with GL_NEAREST because it is not transformed or |
608 | 745 // scaled. |
609 // scaled_tile_quad also uses GL_LINEAR. | 746 EXPECT_CALL( |
610 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 747 *context, |
611 | 748 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
612 // The remaining quads also use GL_LINEAR because nearest neighbor | 749 EXPECT_CALL( |
613 // filtering is currently only used with tile quads. | 750 *context, |
614 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); | 751 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
615 } | 752 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
616 | 753 |
617 cc::DirectRenderer::DrawingFrame drawingFrame; | 754 // transformed_tile_quad uses GL_LINEAR. |
618 renderer.BeginDrawingFrame(drawingFrame); | 755 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
619 EXPECT_EQ(context->activeTexture(), GL_TEXTURE0); | 756 |
620 | 757 // scaled_tile_quad also uses GL_LINEAR. |
621 for (cc::QuadList::backToFrontIterator it = pass->quad_list.backToFrontBegin
(); | 758 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
622 it != pass->quad_list.backToFrontEnd(); ++it) { | 759 |
623 renderer.DoDrawQuad(drawingFrame, *it); | 760 // The remaining quads also use GL_LINEAR because nearest neighbor |
624 } | 761 // filtering is currently only used with tile quads. |
625 renderer.FinishDrawingQuadList(); | 762 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); |
626 EXPECT_EQ(context->activeTexture(), GL_TEXTURE0); | 763 } |
627 Mock::VerifyAndClearExpectations(context); | 764 |
| 765 cc::DirectRenderer::DrawingFrame drawing_frame; |
| 766 renderer.BeginDrawingFrame(drawing_frame); |
| 767 EXPECT_EQ(context->active_texture(), GL_TEXTURE0); |
| 768 |
| 769 for (cc::QuadList::backToFrontIterator |
| 770 it = pass->quad_list.backToFrontBegin(); |
| 771 it != pass->quad_list.backToFrontEnd(); |
| 772 ++it) { |
| 773 renderer.DoDrawQuad(drawing_frame, *it); |
| 774 } |
| 775 renderer.FinishDrawingQuadList(); |
| 776 EXPECT_EQ(context->active_texture(), GL_TEXTURE0); |
| 777 Mock::VerifyAndClearExpectations(context); |
628 } | 778 } |
629 | 779 |
630 class NoClearRootRenderPassFakeClient : public FakeRendererClient { | 780 class NoClearRootRenderPassFakeClient : public FakeRendererClient { |
631 public: | 781 public: |
632 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return false; } | 782 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return false; } |
633 }; | 783 }; |
634 | 784 |
635 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { | 785 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { |
636 public: | 786 public: |
637 MOCK_METHOD1(clear, void(WGC3Dbitfield mask)); | 787 MOCK_METHOD1(clear, void(WGC3Dbitfield mask)); |
638 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum
type, WGC3Dintptr offset)); | 788 MOCK_METHOD4(drawElements, |
639 }; | 789 void(WGC3Denum mode, |
640 | 790 WGC3Dsizei count, |
641 TEST(GLRendererTest2, shouldClearRootRenderPass) | 791 WGC3Denum type, |
642 { | 792 WGC3Dintptr offset)); |
643 NoClearRootRenderPassFakeClient mockClient; | 793 }; |
644 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new NoClearRootRenderPassMockContext))); | 794 |
645 NoClearRootRenderPassMockContext* mockContext = static_cast<NoClearRootRende
rPassMockContext*>(outputSurface->context3d()); | 795 TEST(GLRendererTest2, ShouldClearRootRenderPass) { |
646 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 796 NoClearRootRenderPassFakeClient mock_client; |
647 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 797 scoped_ptr<OutputSurface> output_surface( |
648 EXPECT_TRUE(renderer.Initialize()); | 798 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
649 | 799 new NoClearRootRenderPassMockContext))); |
650 gfx::Rect viewportRect(mockClient.DeviceViewportSize()); | 800 NoClearRootRenderPassMockContext* mock_context = |
651 ScopedPtrVector<RenderPass>& renderPasses = mockClient.renderPassesInDrawOrd
er(); | 801 static_cast<NoClearRootRenderPassMockContext*>( |
652 renderPasses.clear(); | 802 output_surface->context3d()); |
653 | 803 scoped_ptr<ResourceProvider> resource_provider( |
654 RenderPass::Id rootPassId(1, 0); | 804 ResourceProvider::Create(output_surface.get())); |
655 TestRenderPass* rootPass = addRenderPass(renderPasses, rootPassId, viewportR
ect, gfx::Transform()); | 805 FakeRendererGL renderer( |
656 addQuad(rootPass, viewportRect, SK_ColorGREEN); | 806 &mock_client, output_surface.get(), resource_provider.get()); |
657 | 807 EXPECT_TRUE(renderer.Initialize()); |
658 RenderPass::Id childPassId(2, 0); | 808 |
659 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, viewpor
tRect, gfx::Transform()); | 809 gfx::Rect viewport_rect(mock_client.DeviceViewportSize()); |
660 addQuad(childPass, viewportRect, SK_ColorBLUE); | 810 ScopedPtrVector<RenderPass>& render_passes = |
661 | 811 *mock_client.render_passes_in_draw_order(); |
662 addRenderPassQuad(rootPass, childPass); | 812 render_passes.clear(); |
663 | 813 |
664 // First render pass is not the root one, clearing should happen. | 814 RenderPass::Id root_pass_id(1, 0); |
665 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 815 TestRenderPass* root_pass = addRenderPass( |
666 .Times(AtLeast(1)); | 816 render_passes, root_pass_id, viewport_rect, gfx::Transform()); |
667 | 817 addQuad(root_pass, viewport_rect, SK_ColorGREEN); |
668 Expectation firstRenderPass = EXPECT_CALL(*mockContext, drawElements(_, _, _
, _)) | 818 |
669 .Times(1); | 819 RenderPass::Id child_pass_id(2, 0); |
670 | 820 TestRenderPass* child_pass = addRenderPass( |
671 // The second render pass is the root one, clearing should be prevented. | 821 render_passes, child_pass_id, viewport_rect, gfx::Transform()); |
672 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 822 addQuad(child_pass, viewport_rect, SK_ColorBLUE); |
673 .Times(0) | 823 |
674 .After(firstRenderPass); | 824 addRenderPassQuad(root_pass, child_pass); |
675 | 825 |
676 EXPECT_CALL(*mockContext, drawElements(_, _, _, _)) | 826 // First render pass is not the root one, clearing should happen. |
677 .Times(AnyNumber()) | 827 EXPECT_CALL(*mock_context, clear(GL_COLOR_BUFFER_BIT)).Times(AtLeast(1)); |
678 .After(firstRenderPass); | 828 |
679 | 829 Expectation first_render_pass = |
680 renderer.DecideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr
der()); | 830 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1); |
681 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 831 |
682 | 832 // The second render pass is the root one, clearing should be prevented. |
683 // In multiple render passes all but the root pass should clear the framebuf
fer. | 833 EXPECT_CALL(*mock_context, clear(GL_COLOR_BUFFER_BIT)).Times(0) |
684 Mock::VerifyAndClearExpectations(&mockContext); | 834 .After(first_render_pass); |
| 835 |
| 836 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()) |
| 837 .After(first_render_pass); |
| 838 |
| 839 renderer.DecideRenderPassAllocationsForFrame( |
| 840 *mock_client.render_passes_in_draw_order()); |
| 841 renderer.DrawFrame(*mock_client.render_passes_in_draw_order()); |
| 842 |
| 843 // In multiple render passes all but the root pass should clear the |
| 844 // framebuffer. |
| 845 Mock::VerifyAndClearExpectations(&mock_context); |
685 } | 846 } |
686 | 847 |
687 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { | 848 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { |
688 public: | 849 public: |
689 ScissorTestOnClearCheckingContext() : m_scissorEnabled(false) { } | 850 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {} |
690 | 851 |
691 virtual void clear(WGC3Dbitfield) | 852 virtual void clear(WGC3Dbitfield) { EXPECT_FALSE(scissor_enabled_); } |
692 { | 853 |
693 EXPECT_FALSE(m_scissorEnabled); | 854 virtual void enable(WGC3Denum cap) { |
694 } | 855 if (cap == GL_SCISSOR_TEST) |
695 | 856 scissor_enabled_ = true; |
696 virtual void enable(WGC3Denum cap) | 857 } |
697 { | 858 |
698 if (cap == GL_SCISSOR_TEST) | 859 virtual void disable(WGC3Denum cap) { |
699 m_scissorEnabled = true; | 860 if (cap == GL_SCISSOR_TEST) |
700 } | 861 scissor_enabled_ = false; |
701 | 862 } |
702 virtual void disable(WGC3Denum cap) | 863 |
703 { | 864 private: |
704 if (cap == GL_SCISSOR_TEST) | 865 bool scissor_enabled_; |
705 m_scissorEnabled = false; | 866 }; |
706 } | 867 |
707 | 868 TEST(GLRendererTest2, ScissorTestWhenClearing) { |
708 private: | 869 FakeRendererClient mock_client; |
709 bool m_scissorEnabled; | 870 scoped_ptr<OutputSurface> output_surface( |
710 }; | 871 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
711 | 872 new ScissorTestOnClearCheckingContext))); |
712 TEST(GLRendererTest2, scissorTestWhenClearing) { | 873 scoped_ptr<ResourceProvider> resource_provider( |
713 FakeRendererClient mockClient; | 874 ResourceProvider::Create(output_surface.get())); |
714 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ScissorTestOnClearCheckingContext))); | 875 FakeRendererGL renderer( |
715 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu
tSurface.get())); | 876 &mock_client, output_surface.get(), resource_provider.get()); |
716 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 877 EXPECT_TRUE(renderer.Initialize()); |
717 EXPECT_TRUE(renderer.Initialize()); | 878 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); |
718 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); | 879 |
719 | 880 gfx::Rect viewport_rect(mock_client.DeviceViewportSize()); |
720 gfx::Rect viewportRect(mockClient.DeviceViewportSize()); | 881 ScopedPtrVector<RenderPass>& render_passes = |
721 ScopedPtrVector<RenderPass>& renderPasses = mockClient.renderPassesInDrawOrd
er(); | 882 *mock_client.render_passes_in_draw_order(); |
722 renderPasses.clear(); | 883 render_passes.clear(); |
723 | 884 |
724 gfx::Rect grandChildRect(25, 25); | 885 gfx::Rect grand_child_rect(25, 25); |
725 RenderPass::Id grandChildPassId(3, 0); | 886 RenderPass::Id grand_child_pass_id(3, 0); |
726 TestRenderPass* grandChildPass = addRenderPass(renderPasses, grandChildPassI
d, grandChildRect, gfx::Transform()); | 887 TestRenderPass* grand_child_pass = addRenderPass( |
727 addClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW); | 888 render_passes, grand_child_pass_id, grand_child_rect, gfx::Transform()); |
728 | 889 addClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW); |
729 gfx::Rect childRect(50, 50); | 890 |
730 RenderPass::Id childPassId(2, 0); | 891 gfx::Rect child_rect(50, 50); |
731 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, childRe
ct, gfx::Transform()); | 892 RenderPass::Id child_pass_id(2, 0); |
732 addQuad(childPass, childRect, SK_ColorBLUE); | 893 TestRenderPass* child_pass = |
733 | 894 addRenderPass(render_passes, child_pass_id, child_rect, gfx::Transform()); |
734 RenderPass::Id rootPassId(1, 0); | 895 addQuad(child_pass, child_rect, SK_ColorBLUE); |
735 TestRenderPass* rootPass = addRenderPass(renderPasses, rootPassId, viewportR
ect, gfx::Transform()); | 896 |
736 addQuad(rootPass, viewportRect, SK_ColorGREEN); | 897 RenderPass::Id root_pass_id(1, 0); |
737 | 898 TestRenderPass* root_pass = addRenderPass( |
738 addRenderPassQuad(rootPass, childPass); | 899 render_passes, root_pass_id, viewport_rect, gfx::Transform()); |
739 addRenderPassQuad(childPass, grandChildPass); | 900 addQuad(root_pass, viewport_rect, SK_ColorGREEN); |
740 | 901 |
741 renderer.DecideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr
der()); | 902 addRenderPassQuad(root_pass, child_pass); |
742 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 903 addRenderPassQuad(child_pass, grand_child_pass); |
| 904 |
| 905 renderer.DecideRenderPassAllocationsForFrame( |
| 906 *mock_client.render_passes_in_draw_order()); |
| 907 renderer.DrawFrame(*mock_client.render_passes_in_draw_order()); |
743 } | 908 } |
744 | 909 |
745 class OutputSurfaceMockContext : public TestWebGraphicsContext3D { | 910 class OutputSurfaceMockContext : public TestWebGraphicsContext3D { |
746 public: | 911 public: |
747 // Specifically override methods even if they are unused (used in conjunctio
n with StrictMock). | 912 // Specifically override methods even if they are unused (used in conjunction |
748 // We need to make sure that GLRenderer does not issue framebuffer-related G
L calls directly. Instead these | 913 // with StrictMock). We need to make sure that GLRenderer does not issue |
749 // are supposed to go through the OutputSurface abstraction. | 914 // framebuffer-related GL calls directly. Instead these are supposed to go |
750 MOCK_METHOD0(ensureBackbufferCHROMIUM, void()); | 915 // through the OutputSurface abstraction. |
751 MOCK_METHOD0(discardBackbufferCHROMIUM, void()); | 916 MOCK_METHOD0(ensureBackbufferCHROMIUM, void()); |
752 MOCK_METHOD2(bindFramebuffer, void(WGC3Denum target, WebGLId framebuffer)); | 917 MOCK_METHOD0(discardBackbufferCHROMIUM, void()); |
753 MOCK_METHOD0(prepareTexture, void()); | 918 MOCK_METHOD2(bindFramebuffer, void(WGC3Denum target, WebGLId framebuffer)); |
754 MOCK_METHOD2(reshape, void(int width, int height)); | 919 MOCK_METHOD0(prepareTexture, void()); |
755 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum
type, WGC3Dintptr offset)); | 920 MOCK_METHOD2(reshape, void(int width, int height)); |
756 | 921 MOCK_METHOD4(drawElements, |
757 virtual WebString getString(WebKit::WGC3Denum name) | 922 void(WGC3Denum mode, |
758 { | 923 WGC3Dsizei count, |
759 if (name == GL_EXTENSIONS) | 924 WGC3Denum type, |
760 return WebString("GL_CHROMIUM_post_sub_buffer GL_CHROMIUM_discard_ba
ckbuffer"); | 925 WGC3Dintptr offset)); |
761 return WebString(); | 926 |
762 } | 927 virtual WebString getString(WebKit::WGC3Denum name) { |
| 928 if (name == GL_EXTENSIONS) |
| 929 return WebString( |
| 930 "GL_CHROMIUM_post_sub_buffer GL_CHROMIUM_discard_backbuffer"); |
| 931 return WebString(); |
| 932 } |
763 }; | 933 }; |
764 | 934 |
765 class MockOutputSurface : public OutputSurface { | 935 class MockOutputSurface : public OutputSurface { |
766 public: | 936 public: |
767 MockOutputSurface() | 937 MockOutputSurface() |
768 : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(new StrictMock<
OutputSurfaceMockContext>)) { } | 938 : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>( |
769 virtual ~MockOutputSurface() { } | 939 new StrictMock<OutputSurfaceMockContext>)) {} |
770 | 940 virtual ~MockOutputSurface() {} |
771 MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame)); | 941 |
772 MOCK_METHOD0(EnsureBackbuffer, void()); | 942 MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame)); |
773 MOCK_METHOD0(DiscardBackbuffer, void()); | 943 MOCK_METHOD0(EnsureBackbuffer, void()); |
774 MOCK_METHOD1(Reshape, void(gfx::Size size)); | 944 MOCK_METHOD0(DiscardBackbuffer, void()); |
775 MOCK_METHOD0(BindFramebuffer, void()); | 945 MOCK_METHOD1(Reshape, void(gfx::Size size)); |
776 MOCK_METHOD1(PostSubBuffer, void(gfx::Rect rect)); | 946 MOCK_METHOD0(BindFramebuffer, void()); |
777 MOCK_METHOD0(SwapBuffers, void()); | 947 MOCK_METHOD1(PostSubBuffer, void(gfx::Rect rect)); |
778 }; | 948 MOCK_METHOD0(SwapBuffers, void()); |
779 | 949 }; |
780 class MockOutputSurfaceTest : public testing::Test, | 950 |
781 public FakeRendererClient { | 951 class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { |
782 protected: | 952 protected: |
783 MockOutputSurfaceTest() | 953 MockOutputSurfaceTest() |
784 : resource_provider_(ResourceProvider::Create(&m_outputSurface)) | 954 : resource_provider_(ResourceProvider::Create(&output_surface_)), |
785 , m_renderer(this, &m_outputSurface, resource_provider_.get()) | 955 renderer_(this, &output_surface_, resource_provider_.get()) {} |
786 { | 956 |
787 } | 957 virtual void SetUp() { EXPECT_TRUE(renderer_.Initialize()); } |
788 | 958 |
789 virtual void SetUp() | 959 void SwapBuffers() { renderer_.SwapBuffers(); } |
790 { | 960 |
791 EXPECT_TRUE(m_renderer.Initialize()); | 961 void DrawFrame() { |
792 } | 962 gfx::Rect viewport_rect(DeviceViewportSize()); |
793 | 963 ScopedPtrVector<RenderPass>* render_passes = render_passes_in_draw_order(); |
794 void SwapBuffers() | 964 render_passes->clear(); |
795 { | 965 |
796 m_renderer.SwapBuffers(); | 966 RenderPass::Id render_pass_id(1, 0); |
797 } | 967 TestRenderPass* render_pass = addRenderPass( |
798 | 968 *render_passes, render_pass_id, viewport_rect, gfx::Transform()); |
799 void DrawFrame() | 969 addQuad(render_pass, viewport_rect, SK_ColorGREEN); |
800 { | 970 |
801 gfx::Rect viewportRect(DeviceViewportSize()); | 971 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return()); |
802 ScopedPtrVector<RenderPass>& renderPasses = renderPassesInDrawOrder(); | 972 |
803 renderPasses.clear(); | 973 EXPECT_CALL(output_surface_, Reshape(_)).Times(1); |
804 | 974 |
805 RenderPass::Id renderPassId(1, 0); | 975 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1); |
806 TestRenderPass* renderPass = addRenderPass(renderPasses, renderPassId, v
iewportRect, gfx::Transform()); | 976 |
807 addQuad(renderPass, viewportRect, SK_ColorGREEN); | 977 EXPECT_CALL(*context(), drawElements(_, _, _, _)).Times(1); |
808 | 978 |
809 EXPECT_CALL(m_outputSurface, EnsureBackbuffer()) | 979 renderer_.DecideRenderPassAllocationsForFrame(*render_passes_in_draw_order()
); |
810 .WillRepeatedly(Return()); | 980 renderer_.DrawFrame(*render_passes_in_draw_order()); |
811 | 981 } |
812 EXPECT_CALL(m_outputSurface, Reshape(_)) | 982 |
813 .Times(1); | 983 OutputSurfaceMockContext* context() { |
814 | 984 return static_cast<OutputSurfaceMockContext*>(output_surface_.context3d()); |
815 EXPECT_CALL(m_outputSurface, BindFramebuffer()) | 985 } |
816 .Times(1); | 986 |
817 | 987 StrictMock<MockOutputSurface> output_surface_; |
818 EXPECT_CALL(*context(), drawElements(_, _, _, _)) | 988 scoped_ptr<ResourceProvider> resource_provider_; |
819 .Times(1); | 989 FakeRendererGL renderer_; |
820 | 990 }; |
821 m_renderer.DecideRenderPassAllocationsForFrame(renderPassesInDrawOrder()
); | 991 |
822 m_renderer.DrawFrame(renderPassesInDrawOrder()); | 992 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) { |
823 } | 993 DrawFrame(); |
824 | 994 |
825 OutputSurfaceMockContext* context() { return static_cast<OutputSurfaceMockCo
ntext*>(m_outputSurface.context3d()); } | 995 EXPECT_CALL(output_surface_, SwapBuffers()).Times(1); |
826 | 996 renderer_.SwapBuffers(); |
827 StrictMock<MockOutputSurface> m_outputSurface; | |
828 scoped_ptr<ResourceProvider> resource_provider_; | |
829 FakeRendererGL m_renderer; | |
830 }; | |
831 | |
832 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) | |
833 { | |
834 DrawFrame(); | |
835 | |
836 EXPECT_CALL(m_outputSurface, SwapBuffers()) | |
837 .Times(1); | |
838 m_renderer.SwapBuffers(); | |
839 } | 997 } |
840 | 998 |
841 class MockOutputSurfaceTestWithPartialSwap : public MockOutputSurfaceTest { | 999 class MockOutputSurfaceTestWithPartialSwap : public MockOutputSurfaceTest { |
842 public: | 1000 public: |
843 virtual const LayerTreeSettings& Settings() const OVERRIDE | 1001 virtual const LayerTreeSettings& Settings() const OVERRIDE { |
844 { | 1002 static LayerTreeSettings fake_settings; |
845 static LayerTreeSettings fakeSettings; | 1003 fake_settings.partial_swap_enabled = true; |
846 fakeSettings.partial_swap_enabled = true; | 1004 return fake_settings; |
847 return fakeSettings; | 1005 } |
848 } | 1006 }; |
849 }; | 1007 |
850 | 1008 TEST_F(MockOutputSurfaceTestWithPartialSwap, DrawFrameAndSwap) { |
851 TEST_F(MockOutputSurfaceTestWithPartialSwap, DrawFrameAndSwap) | 1009 DrawFrame(); |
852 { | 1010 |
853 DrawFrame(); | 1011 EXPECT_CALL(output_surface_, PostSubBuffer(_)).Times(1); |
854 | 1012 renderer_.SwapBuffers(); |
855 EXPECT_CALL(m_outputSurface, PostSubBuffer(_)) | 1013 } |
856 .Times(1); | 1014 |
857 m_renderer.SwapBuffers(); | 1015 class MockOutputSurfaceTestWithSendCompositorFrame : |
858 } | 1016 public MockOutputSurfaceTest { |
859 | 1017 public: |
860 class MockOutputSurfaceTestWithSendCompositorFrame : public MockOutputSurfaceTes
t { | 1018 virtual const LayerTreeSettings& Settings() const OVERRIDE { |
861 public: | 1019 static LayerTreeSettings fake_settings; |
862 virtual const LayerTreeSettings& Settings() const OVERRIDE | 1020 fake_settings.compositor_frame_message = true; |
863 { | 1021 return fake_settings; |
864 static LayerTreeSettings fakeSettings; | 1022 } |
865 fakeSettings.compositor_frame_message = true; | 1023 }; |
866 return fakeSettings; | 1024 |
867 } | 1025 TEST_F(MockOutputSurfaceTestWithSendCompositorFrame, DrawFrame) { |
868 }; | 1026 EXPECT_CALL(output_surface_, SendFrameToParentCompositor(_)).Times(1); |
869 | 1027 DrawFrame(); |
870 TEST_F(MockOutputSurfaceTestWithSendCompositorFrame, DrawFrame) | |
871 { | |
872 EXPECT_CALL(m_outputSurface, SendFrameToParentCompositor(_)) | |
873 .Times(1); | |
874 DrawFrame(); | |
875 } | 1028 } |
876 | 1029 |
877 } // namespace | 1030 } // namespace |
878 } // namespace cc | 1031 } // namespace cc |
OLD | NEW |