Chromium Code Reviews| 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 FrameCount() { return frame_; } |
|
danakj
2013/03/22 21:44:12
frame_count()
ernstm
2013/03/22 22:15:52
Done.
| |
| 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_; | |
|
danakj
2013/03/22 21:44:12
indent 4 spaces (line continuation)
ernstm
2013/03/22 22:15:52
Done.
| |
| 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 fakeSize(1, 1); |
|
danakj
2013/03/22 21:44:12
fake_size
script is not perfect yet :(
ernstm
2013/03/22 22:15:52
Done.
| |
| 131 virtual void SetFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCou nt++; } | 134 return fakeSize; |
| 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 SetFullRootLayerDamageCount() const { | |
|
danakj
2013/03/22 21:44:12
set_full_root_layer_damage_count()
ernstm
2013/03/22 22:15:52
Done.
| |
| 162 return set_full_root_layer_damage_count_; | |
| 163 } | |
| 164 void SetLastCallWasSetVisibilityPointer(bool* last_call_was_set_visibility) { | |
|
danakj
2013/03/22 21:44:12
set_last_call_...
ernstm
2013/03/22 22:15:52
Done.
| |
| 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& RenderPassesInDrawOrder() { | |
|
danakj
2013/03/22 21:44:12
render_passes_in_draw_order()
this should return
ernstm
2013/03/22 22:15:52
Done.
| |
| 170 return render_passes_in_draw_order_; | |
| 171 } | |
| 172 | |
| 173 size_t MemoryAllocationLimitBytes() const { | |
|
danakj
2013/03/22 21:44:12
memory_allocation_limit_bytes()
ernstm
2013/03/22 22:15:52
Done.
| |
| 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() { |
|
danakj
2013/03/22 21:44:12
context()
ernstm
2013/03/22 22:15:52
Done.
| |
| 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_.SetFullRootLayerDamageCount()); |
| 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()->FrameCount()); |
| 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( |
| 221 { | 252 GLRendererTest, |
| 222 m_renderer.SetVisible(false); | 253 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerWhileNotVisible) { |
|
danakj
2013/03/22 21:44:12
there's no hope of 80 col here. put GLRendererTest
ernstm
2013/03/22 22:15:52
Done.
| |
| 223 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 254 renderer_.SetVisible(false); |
| 224 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 255 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 225 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 256 EXPECT_EQ(1, mock_client_.SetFullRootLayerDamageCount()); |
| 257 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); | |
| 226 } | 258 } |
| 227 | 259 |
| 228 // Test GLRenderer discardBackbuffer functionality: | 260 // Test GLRenderer discardBackbuffer functionality: |
| 229 // Suggest discarding framebuffer when one exists and the renderer is visible. | 261 // Suggest discarding framebuffer when one exists and the renderer is visible. |
| 230 // Expected: the allocation is ignored. | 262 // Expected: the allocation is ignored. |
| 231 TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) | 263 TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) { |
| 232 { | 264 renderer_.SetVisible(true); |
| 233 m_renderer.SetVisible(true); | 265 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 234 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 266 EXPECT_EQ(0, mock_client_.SetFullRootLayerDamageCount()); |
| 235 EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount()); | 267 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
| 236 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 268 } |
| 237 } | |
| 238 | |
| 239 | 269 |
| 240 // Test GLRenderer discardBackbuffer functionality: | 270 // Test GLRenderer discardBackbuffer functionality: |
| 241 // Suggest discarding framebuffer when one does not exist. | 271 // Suggest discarding framebuffer when one does not exist. |
| 242 // Expected: it does nothing. | 272 // Expected: it does nothing. |
| 243 TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) | 273 TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) { |
| 244 { | 274 renderer_.SetVisible(false); |
| 245 m_renderer.SetVisible(false); | 275 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 246 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 276 EXPECT_EQ(1, mock_client_.SetFullRootLayerDamageCount()); |
| 247 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 277 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
| 248 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 278 |
| 249 | 279 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 250 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 280 EXPECT_EQ(1, mock_client_.SetFullRootLayerDamageCount()); |
| 251 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 281 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
| 252 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | |
| 253 } | 282 } |
| 254 | 283 |
| 255 // Test GLRenderer discardBackbuffer functionality: | 284 // Test GLRenderer discardBackbuffer functionality: |
| 256 // Begin drawing a frame while a framebuffer is discarded. | 285 // Begin drawing a frame while a framebuffer is discarded. |
| 257 // Expected: will recreate framebuffer. | 286 // Expected: will recreate framebuffer. |
| 258 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) | 287 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) { |
| 259 { | 288 renderer_.SetVisible(false); |
| 260 m_renderer.SetVisible(false); | 289 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 261 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 290 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
| 262 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 291 EXPECT_EQ(1, mock_client_.SetFullRootLayerDamageCount()); |
| 263 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 292 |
| 264 | 293 renderer_.SetVisible(true); |
| 265 m_renderer.SetVisible(true); | 294 renderer_.DrawFrame(mock_client_.RenderPassesInDrawOrder()); |
| 266 m_renderer.DrawFrame(m_mockClient.renderPassesInDrawOrder()); | 295 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
| 267 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 296 |
| 268 | 297 SwapBuffers(); |
| 269 SwapBuffers(); | 298 EXPECT_EQ(1, Context()->FrameCount()); |
| 270 EXPECT_EQ(1, context()->frameCount()); | 299 } |
| 271 } | 300 |
| 272 | 301 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) { |
| 273 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) | 302 renderer_.SetVisible(false); |
| 274 { | 303 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); |
| 275 m_renderer.SetVisible(false); | 304 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
| 276 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 305 EXPECT_EQ(1, mock_client_.SetFullRootLayerDamageCount()); |
| 277 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | 306 |
| 278 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 307 char pixels[4]; |
| 279 | 308 renderer_.DrawFrame(mock_client_.RenderPassesInDrawOrder()); |
| 280 char pixels[4]; | 309 EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); |
| 281 m_renderer.DrawFrame(m_mockClient.renderPassesInDrawOrder()); | 310 |
| 282 EXPECT_FALSE(m_renderer.IsBackbufferDiscarded()); | 311 renderer_.GetFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); |
| 283 | 312 EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); |
| 284 m_renderer.GetFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); | 313 EXPECT_EQ(2, mock_client_.SetFullRootLayerDamageCount()); |
| 285 EXPECT_TRUE(m_renderer.IsBackbufferDiscarded()); | |
| 286 EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount()); | |
| 287 } | 314 } |
| 288 | 315 |
| 289 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { | 316 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { |
| 290 public: | 317 public: |
| 291 ForbidSynchronousCallContext() { } | 318 ForbidSynchronousCallContext() {} |
| 292 | 319 |
| 293 virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&) { ADD_FAILURE(); return false; } | 320 virtual bool GetActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&) { |
|
danakj
2013/03/22 21:44:12
need a variable name for all parameters
ernstm
2013/03/22 22:15:52
Done. Also changed all get* functions back to lowe
| |
| 294 virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&) { ADD_FAILURE(); return false; } | 321 ADD_FAILURE(); |
| 295 virtual void getAttachedShaders(WebGLId program, WGC3Dsizei maxCount, WGC3Ds izei* count, WebGLId* shaders) { ADD_FAILURE(); } | 322 return false; |
| 296 virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name) { ADD_FAILURE(); return 0; } | 323 } |
| 297 virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value) { ADD_FAILURE (); } | 324 virtual bool GetActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&) { |
|
danakj
2013/03/22 21:44:12
need a variable name for all parameters
ernstm
2013/03/22 22:15:52
Done.
| |
| 298 virtual void getBufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Din t* value) { ADD_FAILURE(); } | 325 ADD_FAILURE(); |
| 299 virtual Attributes getContextAttributes() { ADD_FAILURE(); return attributes _; } | 326 return false; |
| 300 virtual WGC3Denum getError() { ADD_FAILURE(); return 0; } | 327 } |
| 301 virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); } | 328 virtual void GetAttachedShaders(WebGLId program, |
| 302 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, WGC3Denum attachment, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); } | 329 WGC3Dsizei max_count, |
| 303 virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value) | 330 WGC3Dsizei* count, |
| 304 { | 331 WebGLId* shaders) { |
| 305 if (pname == GL_MAX_TEXTURE_SIZE) | 332 ADD_FAILURE(); |
| 306 *value = 1024; // MAX_TEXTURE_SIZE is cached client side, so it's OK to query. | 333 } |
| 307 else | 334 virtual WGC3Dint GetAttribLocation(WebGLId program, const WGC3Dchar* name) { |
| 308 ADD_FAILURE(); | 335 ADD_FAILURE(); |
| 336 return 0; | |
| 337 } | |
| 338 virtual void GetBooleanv(WGC3Denum pname, WGC3Dboolean* value) { | |
| 339 ADD_FAILURE(); | |
| 340 } | |
| 341 virtual void GetBufferParameteriv(WGC3Denum target, | |
| 342 WGC3Denum pname, | |
| 343 WGC3Dint* value) { | |
| 344 ADD_FAILURE(); | |
| 345 } | |
| 346 virtual Attributes GetContextAttributes() { | |
| 347 ADD_FAILURE(); | |
| 348 return attributes_; | |
| 349 } | |
| 350 virtual WGC3Denum GetError() { | |
| 351 ADD_FAILURE(); | |
| 352 return 0; | |
| 353 } | |
| 354 virtual void GetFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); } | |
| 355 virtual void GetFramebufferAttachmentParameteriv(WGC3Denum target, | |
| 356 WGC3Denum attachment, | |
| 357 WGC3Denum pname, | |
| 358 WGC3Dint* value) { | |
| 359 ADD_FAILURE(); | |
| 360 } | |
| 361 virtual void GetIntegerv(WGC3Denum pname, WGC3Dint* value) { | |
| 362 if (pname == GL_MAX_TEXTURE_SIZE) { | |
| 363 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query. | |
| 364 *value = 1024; | |
| 309 } | 365 } |
| 310 | 366 else { |
| 311 // We allow querying the shader compilation and program link status in debug mode, but not release. | 367 ADD_FAILURE(); |
| 312 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) | 368 } |
| 313 { | 369 } |
| 370 | |
| 371 // We allow querying the shader compilation and program link status in debug | |
| 372 // mode, but not release. | |
| 373 virtual void GetProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) { | |
| 314 #ifndef NDEBUG | 374 #ifndef NDEBUG |
| 315 *value = 1; | 375 *value = 1; |
| 316 #else | 376 #else |
| 317 ADD_FAILURE(); | 377 ADD_FAILURE(); |
| 318 #endif | 378 #endif |
| 319 } | 379 } |
| 320 | 380 |
| 321 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) | 381 virtual void GetShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) { |
| 322 { | |
| 323 #ifndef NDEBUG | 382 #ifndef NDEBUG |
| 324 *value = 1; | 383 *value = 1; |
| 325 #else | 384 #else |
| 326 ADD_FAILURE(); | 385 ADD_FAILURE(); |
| 327 #endif | 386 #endif |
| 328 } | 387 } |
| 329 | 388 |
| 330 virtual WebString getString(WGC3Denum name) | 389 virtual WebString GetString(WGC3Denum name) { |
| 331 { | 390 // We allow querying the extension string. |
| 332 // We allow querying the extension string. | 391 // 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) | 392 // other expensive work (like starting a compilation) |
| 334 if (name != GL_EXTENSIONS) | 393 if (name != GL_EXTENSIONS) |
| 335 ADD_FAILURE(); | 394 ADD_FAILURE(); |
| 336 return WebString(); | 395 return WebString(); |
| 337 } | 396 } |
| 338 | 397 |
| 339 virtual WebString getProgramInfoLog(WebGLId program) { ADD_FAILURE(); return WebString(); } | 398 virtual WebString GetProgramInfoLog(WebGLId program) { |
| 340 virtual void getRenderbufferParameteriv(WGC3Denum target, WGC3Denum pname, W GC3Dint* value) { ADD_FAILURE(); } | 399 ADD_FAILURE(); |
| 341 | 400 return WebString(); |
| 342 virtual WebString getShaderInfoLog(WebGLId shader) { ADD_FAILURE(); return W ebString(); } | 401 } |
| 343 virtual void getShaderPrecisionFormat(WGC3Denum shadertype, WGC3Denum precis iontype, WGC3Dint* range, WGC3Dint* precision) { ADD_FAILURE(); } | 402 virtual void GetRenderbufferParameteriv(WGC3Denum target, |
| 344 virtual WebString getShaderSource(WebGLId shader) { ADD_FAILURE(); return We bString(); } | 403 WGC3Denum pname, |
| 345 virtual void getTexParameterfv(WGC3Denum target, WGC3Denum pname, WGC3Dfloat * value) { ADD_FAILURE(); } | 404 WGC3Dint* value) { |
| 346 virtual void getTexParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); } | 405 ADD_FAILURE(); |
| 347 virtual void getUniformfv(WebGLId program, WGC3Dint location, WGC3Dfloat* va lue) { ADD_FAILURE(); } | 406 } |
| 348 virtual void getUniformiv(WebGLId program, WGC3Dint location, WGC3Dint* valu e) { ADD_FAILURE(); } | 407 |
| 349 virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name) { ADD_FAILURE(); return 0; } | 408 virtual WebString GetShaderInfoLog(WebGLId shader) { |
| 350 virtual void getVertexAttribfv(WGC3Duint index, WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); } | 409 ADD_FAILURE(); |
| 351 virtual void getVertexAttribiv(WGC3Duint index, WGC3Denum pname, WGC3Dint* v alue) { ADD_FAILURE(); } | 410 return WebString(); |
| 352 virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, WGC3Denum pname ) { ADD_FAILURE(); return 0; } | 411 } |
| 353 }; | 412 virtual void GetShaderPrecisionFormat(WGC3Denum shadertype, |
| 354 | 413 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. | 414 WGC3Dint* range, |
| 356 TEST(GLRendererTest2, initializationDoesNotMakeSynchronousCalls) | 415 WGC3Dint* precision) { |
| 357 { | 416 ADD_FAILURE(); |
| 358 FakeRendererClient mockClient; | 417 } |
| 359 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new ForbidSynchronousCallContext))); | 418 virtual WebString GetShaderSource(WebGLId shader) { |
| 360 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 419 ADD_FAILURE(); |
| 361 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 420 return WebString(); |
| 362 | 421 } |
| 363 EXPECT_TRUE(renderer.Initialize()); | 422 virtual void GetTexParameterfv(WGC3Denum target, |
| 423 WGC3Denum pname, | |
| 424 WGC3Dfloat* value) { | |
| 425 ADD_FAILURE(); | |
| 426 } | |
| 427 virtual void GetTexParameteriv(WGC3Denum target, | |
| 428 WGC3Denum pname, | |
| 429 WGC3Dint* value) { | |
| 430 ADD_FAILURE(); | |
| 431 } | |
| 432 virtual void GetUniformfv(WebGLId program, | |
| 433 WGC3Dint location, | |
| 434 WGC3Dfloat* value) { | |
| 435 ADD_FAILURE(); | |
| 436 } | |
| 437 virtual void GetUniformiv(WebGLId program, | |
| 438 WGC3Dint location, | |
| 439 WGC3Dint* value) { | |
| 440 ADD_FAILURE(); | |
| 441 } | |
| 442 virtual WGC3Dint GetUniformLocation(WebGLId program, const WGC3Dchar* name) { | |
| 443 ADD_FAILURE(); | |
| 444 return 0; | |
| 445 } | |
| 446 virtual void GetVertexAttribfv(WGC3Duint index, | |
| 447 WGC3Denum pname, | |
| 448 WGC3Dfloat* value) { | |
| 449 ADD_FAILURE(); | |
| 450 } | |
| 451 virtual void GetVertexAttribiv(WGC3Duint index, | |
| 452 WGC3Denum pname, | |
| 453 WGC3Dint* value) { | |
| 454 ADD_FAILURE(); | |
| 455 } | |
| 456 virtual WGC3Dsizeiptr GetVertexAttribOffset(WGC3Duint index, | |
| 457 WGC3Denum pname) { | |
| 458 ADD_FAILURE(); | |
| 459 return 0; | |
| 460 } | |
| 461 }; | |
| 462 | |
| 463 // This test isn't using the same fixture as GLRendererTest, and you can't mix | |
| 464 // TEST() and TEST_F() with the same name, Hence LRC2. | |
| 465 TEST(GLRendererTest2, InitializationDoesNotMakeSynchronousCalls) { | |
| 466 FakeRendererClient mock_client; | |
| 467 scoped_ptr<OutputSurface> output_surface( | |
| 468 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( | |
| 469 new ForbidSynchronousCallContext))); | |
| 470 scoped_ptr<ResourceProvider> resource_provider( | |
| 471 ResourceProvider::Create(output_surface.get())); | |
| 472 FakeRendererGL renderer( | |
| 473 &mock_client, output_surface.get(), resource_provider.get()); | |
| 474 | |
| 475 EXPECT_TRUE(renderer.Initialize()); | |
| 364 } | 476 } |
| 365 | 477 |
| 366 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { | 478 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { |
| 367 public: | 479 public: |
| 368 LoseContextOnFirstGetContext() | 480 LoseContextOnFirstGetContext() : context_lost_(false) {} |
| 369 : m_contextLost(false) | 481 |
| 370 { | 482 virtual bool makeContextCurrent() OVERRIDE { return !context_lost_; } |
| 371 } | 483 |
| 372 | 484 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) |
| 373 virtual bool makeContextCurrent() OVERRIDE | 485 OVERRIDE { |
| 374 { | 486 context_lost_ = true; |
| 375 return !m_contextLost; | 487 *value = 0; |
| 376 } | 488 } |
| 377 | 489 |
| 378 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) OVERRIDE | 490 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) |
| 379 { | 491 OVERRIDE { |
| 380 m_contextLost = true; | 492 context_lost_ = true; |
| 381 *value = 0; | 493 *value = 0; |
| 382 } | 494 } |
| 383 | 495 |
| 384 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) O VERRIDE | 496 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE { |
| 385 { | 497 return context_lost_ ? 1 : 0; |
| 386 m_contextLost = true; | 498 } |
| 387 *value = 0; | 499 |
| 388 } | 500 private: |
| 389 | 501 bool context_lost_; |
| 390 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE | 502 }; |
| 391 { | 503 |
| 392 return m_contextLost ? 1 : 0; | 504 TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) { |
| 393 } | 505 FakeRendererClient mock_client; |
| 394 | 506 scoped_ptr<OutputSurface> output_surface( |
| 395 private: | 507 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 396 bool m_contextLost; | 508 new LoseContextOnFirstGetContext))); |
| 397 }; | 509 scoped_ptr<ResourceProvider> resource_provider( |
| 398 | 510 ResourceProvider::Create(output_surface.get())); |
| 399 TEST(GLRendererTest2, initializationWithQuicklyLostContextDoesNotAssert) | 511 FakeRendererGL renderer( |
| 400 { | 512 &mock_client, output_surface.get(), resource_provider.get()); |
| 401 FakeRendererClient mockClient; | 513 |
| 402 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new LoseContextOnFirstGetContext))); | 514 renderer.Initialize(); |
| 403 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 515 } |
| 404 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 516 |
| 405 | 517 class ContextThatDoesNotSupportMemoryManagmentExtensions : |
| 406 renderer.Initialize(); | 518 public TestWebGraphicsContext3D { |
| 407 } | 519 public: |
| 408 | 520 ContextThatDoesNotSupportMemoryManagmentExtensions() {} |
| 409 class ContextThatDoesNotSupportMemoryManagmentExtensions : public TestWebGraphic sContext3D { | 521 |
| 410 public: | 522 // WebGraphicsContext3D methods. |
| 411 ContextThatDoesNotSupportMemoryManagmentExtensions() { } | 523 |
| 412 | 524 // This method would normally do a glSwapBuffers under the hood. |
| 413 // WebGraphicsContext3D methods. | 525 virtual void prepareTexture() {} |
| 414 | 526 virtual void setMemoryAllocationChangedCallbackCHROMIUM( |
| 415 // This method would normally do a glSwapBuffers under the hood. | 527 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {} |
| 416 virtual void prepareTexture() { } | 528 virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } |
| 417 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAll ocationChangedCallbackCHROMIUM* callback) { } | 529 }; |
| 418 virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } | 530 |
| 419 }; | 531 TEST( |
| 420 | 532 GLRendererTest2, |
| 421 TEST(GLRendererTest2, initializationWithoutGpuMemoryManagerExtensionSupportShoul dDefaultToNonZeroAllocation) | 533 InitializationWithoutGpuMemoryManagerExtensionSupportShouldDefaultToNonZeroA llocation) { |
| 422 { | 534 FakeRendererClient mock_client; |
| 423 FakeRendererClient mockClient; | 535 scoped_ptr<OutputSurface> output_surface( |
| 424 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new ContextThatDoesNotSupportMemoryManagmentExt ensions))); | 536 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 425 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 537 new ContextThatDoesNotSupportMemoryManagmentExtensions))); |
| 426 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 538 scoped_ptr<ResourceProvider> resource_provider( |
| 427 | 539 ResourceProvider::Create(output_surface.get())); |
| 428 renderer.Initialize(); | 540 FakeRendererGL renderer( |
| 429 | 541 &mock_client, output_surface.get(), resource_provider.get()); |
| 430 EXPECT_GT(mockClient.memoryAllocationLimitBytes(), 0ul); | 542 |
| 543 renderer.Initialize(); | |
| 544 | |
| 545 EXPECT_GT(mock_client.MemoryAllocationLimitBytes(), 0ul); | |
| 431 } | 546 } |
| 432 | 547 |
| 433 class ClearCountingContext : public TestWebGraphicsContext3D { | 548 class ClearCountingContext : public TestWebGraphicsContext3D { |
| 434 public: | 549 public: |
| 435 ClearCountingContext() : m_clear(0) { } | 550 ClearCountingContext() : clear_(0) {} |
| 436 | 551 |
| 437 virtual void clear(WGC3Dbitfield) | 552 virtual void clear(WGC3Dbitfield) { clear_++; } |
| 438 { | 553 |
| 439 m_clear++; | 554 int ClearCount() const { return clear_; } |
|
danakj
2013/03/22 21:44:12
clear_count()
ernstm
2013/03/22 22:15:52
Done.
| |
| 440 } | 555 |
| 441 | 556 private: |
| 442 int clearCount() const { return m_clear; } | 557 int clear_; |
| 443 | 558 }; |
| 444 private: | 559 |
| 445 int m_clear; | 560 TEST(GLRendererTest2, OpaqueBackground) { |
| 446 }; | 561 FakeRendererClient mock_client; |
| 447 | 562 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( |
| 448 TEST(GLRendererTest2, opaqueBackground) | 563 scoped_ptr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
| 449 { | 564 ClearCountingContext* context = |
| 450 FakeRendererClient mockClient; | 565 static_cast<ClearCountingContext*>(output_surface->context3d()); |
| 451 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 566 scoped_ptr<ResourceProvider> resource_provider( |
| 452 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur face->context3d()); | 567 ResourceProvider::Create(output_surface.get())); |
| 453 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 568 FakeRendererGL renderer( |
| 454 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 569 &mock_client, output_surface.get(), resource_provider.get()); |
| 455 | 570 |
| 456 mockClient.root_render_pass()->has_transparent_background = false; | 571 mock_client.root_render_pass()->has_transparent_background = false; |
| 457 | 572 |
| 458 EXPECT_TRUE(renderer.Initialize()); | 573 EXPECT_TRUE(renderer.Initialize()); |
| 459 | 574 |
| 460 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 575 renderer.DrawFrame(mock_client.RenderPassesInDrawOrder()); |
| 461 | 576 |
| 462 // On DEBUG builds, render passes with opaque background clear to blue to | 577 // On DEBUG builds, render passes with opaque background clear to blue to |
| 463 // easily see regions that were not drawn on the screen. | 578 // easily see regions that were not drawn on the screen. |
| 464 #ifdef NDEBUG | 579 #ifdef NDEBUG |
| 465 EXPECT_EQ(0, context->clearCount()); | 580 EXPECT_EQ(0, context->ClearCount()); |
| 466 #else | 581 #else |
| 467 EXPECT_EQ(1, context->clearCount()); | 582 EXPECT_EQ(1, context->ClearCount()); |
| 468 #endif | 583 #endif |
| 469 } | 584 } |
| 470 | 585 |
| 471 TEST(GLRendererTest2, transparentBackground) | 586 TEST(GLRendererTest2, TransparentBackground) { |
| 472 { | 587 FakeRendererClient mock_client; |
| 473 FakeRendererClient mockClient; | 588 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( |
| 474 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 589 scoped_ptr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
| 475 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur face->context3d()); | 590 ClearCountingContext* context = |
| 476 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 591 static_cast<ClearCountingContext*>(output_surface->context3d()); |
| 477 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 592 scoped_ptr<ResourceProvider> resource_provider( |
| 478 | 593 ResourceProvider::Create(output_surface.get())); |
| 479 mockClient.root_render_pass()->has_transparent_background = true; | 594 FakeRendererGL renderer( |
| 480 | 595 &mock_client, output_surface.get(), resource_provider.get()); |
| 481 EXPECT_TRUE(renderer.Initialize()); | 596 |
| 482 | 597 mock_client.root_render_pass()->has_transparent_background = true; |
| 483 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 598 |
| 484 | 599 EXPECT_TRUE(renderer.Initialize()); |
| 485 EXPECT_EQ(1, context->clearCount()); | 600 |
| 486 } | 601 renderer.DrawFrame(mock_client.RenderPassesInDrawOrder()); |
| 487 | 602 |
| 488 class VisibilityChangeIsLastCallTrackingContext : public TestWebGraphicsContext3 D { | 603 EXPECT_EQ(1, context->ClearCount()); |
| 489 public: | 604 } |
| 490 VisibilityChangeIsLastCallTrackingContext() | 605 |
| 491 : m_lastCallWasSetVisibility(0) | 606 class VisibilityChangeIsLastCallTrackingContext : |
| 492 { | 607 public TestWebGraphicsContext3D { |
| 493 } | 608 public: |
| 494 | 609 VisibilityChangeIsLastCallTrackingContext() |
| 495 // WebGraphicsContext3D methods. | 610 : last_call_was_set_visibility_(0) {} |
| 496 virtual void setVisibilityCHROMIUM(bool visible) { | 611 |
| 497 if (!m_lastCallWasSetVisibility) | 612 // WebGraphicsContext3D methods. |
| 498 return; | 613 virtual void setVisibilityCHROMIUM(bool visible) { |
| 499 DCHECK(*m_lastCallWasSetVisibility == false); | 614 if (!last_call_was_set_visibility_) |
| 500 *m_lastCallWasSetVisibility = true; | 615 return; |
| 501 } | 616 DCHECK(*last_call_was_set_visibility_ == false); |
| 502 virtual void flush() { if (m_lastCallWasSetVisibility) *m_lastCallWasSetVisi bility = false; } | 617 *last_call_was_set_visibility_ = true; |
| 503 virtual void deleteTexture(WebGLId) { if (m_lastCallWasSetVisibility) *m_las tCallWasSetVisibility = false; } | 618 } |
| 504 virtual void deleteFramebuffer(WebGLId) { if (m_lastCallWasSetVisibility) *m _lastCallWasSetVisibility = false; } | 619 virtual void flush() { |
| 505 virtual void deleteRenderbuffer(WebGLId) { if (m_lastCallWasSetVisibility) * m_lastCallWasSetVisibility = false; } | 620 if (last_call_was_set_visibility_) |
| 506 | 621 *last_call_was_set_visibility_ = false; |
| 507 // This method would normally do a glSwapBuffers under the hood. | 622 } |
| 508 virtual WebString getString(WebKit::WGC3Denum name) | 623 virtual void deleteTexture(WebGLId) { |
| 509 { | 624 if (last_call_was_set_visibility_) |
| 510 if (name == GL_EXTENSIONS) | 625 *last_call_was_set_visibility_ = false; |
| 511 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_ manager GL_CHROMIUM_discard_backbuffer"); | 626 } |
| 512 return WebString(); | 627 virtual void deleteFramebuffer(WebGLId) { |
| 513 } | 628 if (last_call_was_set_visibility_) |
| 514 | 629 *last_call_was_set_visibility_ = false; |
| 515 // Methods added for test. | 630 } |
| 516 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_ lastCallWasSetVisibility = lastCallWasSetVisibility; } | 631 virtual void deleteRenderbuffer(WebGLId) { |
| 517 | 632 if (last_call_was_set_visibility_) |
| 518 private: | 633 *last_call_was_set_visibility_ = false; |
| 519 bool* m_lastCallWasSetVisibility; | 634 } |
| 520 }; | 635 |
| 521 | 636 // This method would normally do a glSwapBuffers under the hood. |
| 522 TEST(GLRendererTest2, visibilityChangeIsLastCall) | 637 virtual WebString getString(WebKit::WGC3Denum name) { |
| 523 { | 638 if (name == GL_EXTENSIONS) |
| 524 FakeRendererClient mockClient; | 639 return WebString( |
| 525 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new VisibilityChangeIsLastCallTrackingContext)) ); | 640 "GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager " |
| 526 VisibilityChangeIsLastCallTrackingContext* context = static_cast<VisibilityC hangeIsLastCallTrackingContext*>(outputSurface->context3d()); | 641 "GL_CHROMIUM_discard_backbuffer"); |
| 527 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 642 return WebString(); |
| 528 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 643 } |
| 529 | 644 |
| 530 EXPECT_TRUE(renderer.Initialize()); | 645 // Methods added for test. |
| 531 | 646 void SetLastCallWasSetVisibilityPointer(bool* last_call_was_set_visibility) { |
|
danakj
2013/03/22 21:44:12
set_last_call_was..
ernstm
2013/03/22 22:15:52
Done.
| |
| 532 bool lastCallWasSetVisiblity = false; | 647 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 | 648 } |
| 534 // process, after glFlush is called, and after the RendererClient's enforceM anagedMemoryPolicy | 649 |
| 535 // is called. Plumb this tracking between both the RenderClient and the Cont ext by giving | 650 private: |
| 536 // them both a pointer to a variable on the stack. | 651 bool* last_call_was_set_visibility_; |
| 537 context->setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 652 }; |
| 538 mockClient.setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 653 |
| 539 renderer.SetVisible(true); | 654 TEST(GLRendererTest2, VisibilityChangeIsLastCall) { |
| 540 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 655 FakeRendererClient mock_client; |
| 541 renderer.SetVisible(false); | 656 scoped_ptr<OutputSurface> output_surface( |
| 542 EXPECT_TRUE(lastCallWasSetVisiblity); | 657 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 658 new VisibilityChangeIsLastCallTrackingContext))); | |
| 659 VisibilityChangeIsLastCallTrackingContext* context = | |
| 660 static_cast<VisibilityChangeIsLastCallTrackingContext*>( | |
| 661 output_surface->context3d()); | |
| 662 scoped_ptr<ResourceProvider> resource_provider( | |
| 663 ResourceProvider::Create(output_surface.get())); | |
| 664 FakeRendererGL renderer( | |
| 665 &mock_client, output_surface.get(), resource_provider.get()); | |
| 666 | |
| 667 EXPECT_TRUE(renderer.Initialize()); | |
| 668 | |
| 669 bool last_call_was_set_visiblity = false; | |
| 670 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to the | |
| 671 // GPU process, after glFlush is called, and after the RendererClient's | |
| 672 // enforceManagedMemoryPolicy is called. Plumb this tracking between both the | |
| 673 // RenderClient and the Context by giving them both a pointer to a variable on | |
| 674 // the stack. | |
| 675 context->SetLastCallWasSetVisibilityPointer(&last_call_was_set_visiblity); | |
| 676 mock_client.SetLastCallWasSetVisibilityPointer(&last_call_was_set_visiblity); | |
| 677 renderer.SetVisible(true); | |
| 678 renderer.DrawFrame(mock_client.RenderPassesInDrawOrder()); | |
| 679 renderer.SetVisible(false); | |
| 680 EXPECT_TRUE(last_call_was_set_visiblity); | |
| 543 } | 681 } |
| 544 | 682 |
| 545 class TextureStateTrackingContext : public TestWebGraphicsContext3D { | 683 class TextureStateTrackingContext : public TestWebGraphicsContext3D { |
| 546 public: | 684 public: |
| 547 TextureStateTrackingContext() | 685 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {} |
| 548 : m_activeTexture(GL_INVALID_ENUM) | 686 |
| 549 { | 687 virtual WebString getString(WGC3Denum name) { |
| 550 } | 688 if (name == GL_EXTENSIONS) |
| 551 | 689 return WebString("GL_OES_EGL_image_external"); |
| 552 virtual WebString getString(WGC3Denum name) | 690 return WebString(); |
| 553 { | 691 } |
| 554 if (name == GL_EXTENSIONS) | 692 |
| 555 return WebString("GL_OES_EGL_image_external"); | 693 MOCK_METHOD3(texParameteri, |
| 556 return WebString(); | 694 void(WGC3Denum target, WGC3Denum pname, WGC3Dint param)); |
| 557 } | 695 MOCK_METHOD4(drawElements, |
| 558 | 696 void(WGC3Denum mode, |
| 559 MOCK_METHOD3(texParameteri, void(WGC3Denum target, WGC3Denum pname, WGC3Dint param)); | 697 WGC3Dsizei count, |
| 560 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset)); | 698 WGC3Denum type, |
| 561 | 699 WGC3Dintptr offset)); |
| 562 virtual void activeTexture(WGC3Denum texture) | 700 |
| 563 { | 701 virtual void activeTexture(WGC3Denum texture) { |
| 564 EXPECT_NE(texture, m_activeTexture); | 702 EXPECT_NE(texture, active_texture_); |
| 565 m_activeTexture = texture; | 703 active_texture_ = texture; |
| 566 } | 704 } |
| 567 | 705 |
| 568 WGC3Denum activeTexture() const { return m_activeTexture; } | 706 WGC3Denum ActiveTexture() const { return active_texture_; } |
|
danakj
2013/03/22 21:44:12
active_texture()
ernstm
2013/03/22 22:15:52
Done.
| |
| 569 | 707 |
| 570 private: | 708 private: |
| 571 WGC3Denum m_activeTexture; | 709 WGC3Denum active_texture_; |
| 572 }; | 710 }; |
| 573 | 711 |
| 574 TEST(GLRendererTest2, activeTextureState) | 712 TEST(GLRendererTest2, ActiveTextureState) { |
| 575 { | 713 FakeRendererClient fake_client; |
| 576 FakeRendererClient fakeClient; | 714 scoped_ptr<OutputSurface> output_surface( |
| 577 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new TextureStateTrackingContext))); | 715 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 578 TextureStateTrackingContext* context = static_cast<TextureStateTrackingConte xt*>(outputSurface->context3d()); | 716 new TextureStateTrackingContext))); |
| 579 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 717 TextureStateTrackingContext* context = |
| 580 FakeRendererGL renderer(&fakeClient, outputSurface.get(), resourceProvider.g et()); | 718 static_cast<TextureStateTrackingContext*>(output_surface->context3d()); |
| 581 | 719 scoped_ptr<ResourceProvider> resource_provider( |
| 582 // During initialization we are allowed to set any texture parameters. | 720 ResourceProvider::Create(output_surface.get())); |
| 583 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber()); | 721 FakeRendererGL renderer( |
| 584 EXPECT_TRUE(renderer.Initialize()); | 722 &fake_client, output_surface.get(), resource_provider.get()); |
| 585 | 723 |
| 586 cc::RenderPass::Id id(1, 1); | 724 // During initialization we are allowed to set any texture parameters. |
| 587 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); | 725 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber()); |
| 588 pass->SetNew(id, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100), gfx:: Transform()); | 726 EXPECT_TRUE(renderer.Initialize()); |
| 589 pass->AppendOneOfEveryQuadType(resourceProvider.get(), RenderPass::Id(2, 1)) ; | 727 |
| 590 | 728 cc::RenderPass::Id id(1, 1); |
| 591 // Set up expected texture filter state transitions that match the quads | 729 scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); |
| 592 // created in AppendOneOfEveryQuadType(). | 730 pass->SetNew(id, |
| 593 Mock::VerifyAndClearExpectations(context); | 731 gfx::Rect(0, 0, 100, 100), |
| 594 { | 732 gfx::Rect(0, 0, 100, 100), |
| 595 InSequence sequence; | 733 gfx::Transform()); |
| 596 | 734 pass->AppendOneOfEveryQuadType(resource_provider.get(), RenderPass::Id(2, 1)); |
| 597 // yuv_quad is drawn with the default linear filter. | 735 |
| 598 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 736 // Set up expected texture filter state transitions that match the quads |
| 599 | 737 // created in AppendOneOfEveryQuadType(). |
| 600 // tile_quad is drawn with GL_NEAREST because it is not transformed or | 738 Mock::VerifyAndClearExpectations(context); |
| 601 // scaled. | 739 { |
| 602 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_NEAREST)); | 740 InSequence sequence; |
| 603 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_NEAREST)); | 741 |
| 604 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 742 // yuv_quad is drawn with the default linear filter. |
| 605 | 743 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
| 606 // transformed_tile_quad uses GL_LINEAR. | 744 |
| 607 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 745 // tile_quad is drawn with GL_NEAREST because it is not transformed or |
| 608 | 746 // scaled. |
| 609 // scaled_tile_quad also uses GL_LINEAR. | 747 EXPECT_CALL( |
| 610 EXPECT_CALL(*context, drawElements(_, _, _, _)); | 748 *context, |
| 611 | 749 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); |
| 612 // The remaining quads also use GL_LINEAR because nearest neighbor | 750 EXPECT_CALL( |
| 613 // filtering is currently only used with tile quads. | 751 *context, |
| 614 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); | 752 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); |
| 615 } | 753 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
| 616 | 754 |
| 617 cc::DirectRenderer::DrawingFrame drawingFrame; | 755 // transformed_tile_quad uses GL_LINEAR. |
| 618 renderer.BeginDrawingFrame(drawingFrame); | 756 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
| 619 EXPECT_EQ(context->activeTexture(), GL_TEXTURE0); | 757 |
| 620 | 758 // scaled_tile_quad also uses GL_LINEAR. |
| 621 for (cc::QuadList::backToFrontIterator it = pass->quad_list.backToFrontBegin (); | 759 EXPECT_CALL(*context, drawElements(_, _, _, _)); |
| 622 it != pass->quad_list.backToFrontEnd(); ++it) { | 760 |
| 623 renderer.DoDrawQuad(drawingFrame, *it); | 761 // The remaining quads also use GL_LINEAR because nearest neighbor |
| 624 } | 762 // filtering is currently only used with tile quads. |
| 625 renderer.FinishDrawingQuadList(); | 763 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); |
| 626 EXPECT_EQ(context->activeTexture(), GL_TEXTURE0); | 764 } |
| 627 Mock::VerifyAndClearExpectations(context); | 765 |
| 766 cc::DirectRenderer::DrawingFrame drawing_frame; | |
| 767 renderer.BeginDrawingFrame(drawing_frame); | |
| 768 EXPECT_EQ(context->ActiveTexture(), GL_TEXTURE0); | |
| 769 | |
| 770 for (cc::QuadList::backToFrontIterator | |
| 771 it = pass->quad_list.backToFrontBegin(); | |
| 772 it != pass->quad_list.backToFrontEnd(); | |
| 773 ++it) { | |
| 774 renderer.DoDrawQuad(drawing_frame, *it); | |
| 775 } | |
| 776 renderer.FinishDrawingQuadList(); | |
| 777 EXPECT_EQ(context->ActiveTexture(), GL_TEXTURE0); | |
| 778 Mock::VerifyAndClearExpectations(context); | |
| 628 } | 779 } |
| 629 | 780 |
| 630 class NoClearRootRenderPassFakeClient : public FakeRendererClient { | 781 class NoClearRootRenderPassFakeClient : public FakeRendererClient { |
| 631 public: | 782 public: |
| 632 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return false; } | 783 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return false; } |
| 633 }; | 784 }; |
| 634 | 785 |
| 635 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { | 786 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { |
| 636 public: | 787 public: |
| 637 MOCK_METHOD1(clear, void(WGC3Dbitfield mask)); | 788 MOCK_METHOD1(clear, void(WGC3Dbitfield mask)); |
| 638 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset)); | 789 MOCK_METHOD4(drawElements, |
| 639 }; | 790 void(WGC3Denum mode, |
| 640 | 791 WGC3Dsizei count, |
| 641 TEST(GLRendererTest2, shouldClearRootRenderPass) | 792 WGC3Denum type, |
| 642 { | 793 WGC3Dintptr offset)); |
| 643 NoClearRootRenderPassFakeClient mockClient; | 794 }; |
| 644 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new NoClearRootRenderPassMockContext))); | 795 |
| 645 NoClearRootRenderPassMockContext* mockContext = static_cast<NoClearRootRende rPassMockContext*>(outputSurface->context3d()); | 796 TEST(GLRendererTest2, ShouldClearRootRenderPass) { |
| 646 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 797 NoClearRootRenderPassFakeClient mock_client; |
| 647 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 798 scoped_ptr<OutputSurface> output_surface( |
| 648 EXPECT_TRUE(renderer.Initialize()); | 799 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 649 | 800 new NoClearRootRenderPassMockContext))); |
| 650 gfx::Rect viewportRect(mockClient.DeviceViewportSize()); | 801 NoClearRootRenderPassMockContext* mock_context = |
| 651 ScopedPtrVector<RenderPass>& renderPasses = mockClient.renderPassesInDrawOrd er(); | 802 static_cast<NoClearRootRenderPassMockContext*>( |
| 652 renderPasses.clear(); | 803 output_surface->context3d()); |
| 653 | 804 scoped_ptr<ResourceProvider> resource_provider( |
| 654 RenderPass::Id rootPassId(1, 0); | 805 ResourceProvider::Create(output_surface.get())); |
| 655 TestRenderPass* rootPass = addRenderPass(renderPasses, rootPassId, viewportR ect, gfx::Transform()); | 806 FakeRendererGL renderer( |
| 656 addQuad(rootPass, viewportRect, SK_ColorGREEN); | 807 &mock_client, output_surface.get(), resource_provider.get()); |
| 657 | 808 EXPECT_TRUE(renderer.Initialize()); |
| 658 RenderPass::Id childPassId(2, 0); | 809 |
| 659 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, viewpor tRect, gfx::Transform()); | 810 gfx::Rect viewport_rect(mock_client.DeviceViewportSize()); |
| 660 addQuad(childPass, viewportRect, SK_ColorBLUE); | 811 ScopedPtrVector<RenderPass>& render_passes = |
| 661 | 812 mock_client.RenderPassesInDrawOrder(); |
| 662 addRenderPassQuad(rootPass, childPass); | 813 render_passes.clear(); |
| 663 | 814 |
| 664 // First render pass is not the root one, clearing should happen. | 815 RenderPass::Id root_pass_id(1, 0); |
| 665 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 816 TestRenderPass* root_pass = addRenderPass( |
| 666 .Times(AtLeast(1)); | 817 render_passes, root_pass_id, viewport_rect, gfx::Transform()); |
| 667 | 818 addQuad(root_pass, viewport_rect, SK_ColorGREEN); |
| 668 Expectation firstRenderPass = EXPECT_CALL(*mockContext, drawElements(_, _, _ , _)) | 819 |
| 669 .Times(1); | 820 RenderPass::Id child_pass_id(2, 0); |
| 670 | 821 TestRenderPass* child_pass = addRenderPass( |
| 671 // The second render pass is the root one, clearing should be prevented. | 822 render_passes, child_pass_id, viewport_rect, gfx::Transform()); |
| 672 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 823 addQuad(child_pass, viewport_rect, SK_ColorBLUE); |
| 673 .Times(0) | 824 |
| 674 .After(firstRenderPass); | 825 addRenderPassQuad(root_pass, child_pass); |
| 675 | 826 |
| 676 EXPECT_CALL(*mockContext, drawElements(_, _, _, _)) | 827 // First render pass is not the root one, clearing should happen. |
| 677 .Times(AnyNumber()) | 828 EXPECT_CALL(*mock_context, clear(GL_COLOR_BUFFER_BIT)).Times(AtLeast(1)); |
| 678 .After(firstRenderPass); | 829 |
| 679 | 830 Expectation first_render_pass = |
| 680 renderer.DecideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr der()); | 831 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1); |
| 681 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 832 |
| 682 | 833 // 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. | 834 EXPECT_CALL(*mock_context, clear(GL_COLOR_BUFFER_BIT)).Times(0) |
| 684 Mock::VerifyAndClearExpectations(&mockContext); | 835 .After(first_render_pass); |
| 836 | |
| 837 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()) | |
| 838 .After(first_render_pass); | |
| 839 | |
| 840 renderer.DecideRenderPassAllocationsForFrame( | |
| 841 mock_client.RenderPassesInDrawOrder()); | |
| 842 renderer.DrawFrame(mock_client.RenderPassesInDrawOrder()); | |
| 843 | |
| 844 // In multiple render passes all but the root pass should clear the | |
| 845 // framebuffer. | |
| 846 Mock::VerifyAndClearExpectations(&mock_context); | |
| 685 } | 847 } |
| 686 | 848 |
| 687 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { | 849 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { |
| 688 public: | 850 public: |
| 689 ScissorTestOnClearCheckingContext() : m_scissorEnabled(false) { } | 851 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {} |
| 690 | 852 |
| 691 virtual void clear(WGC3Dbitfield) | 853 virtual void clear(WGC3Dbitfield) { EXPECT_FALSE(scissor_enabled_); } |
| 692 { | 854 |
| 693 EXPECT_FALSE(m_scissorEnabled); | 855 virtual void enable(WGC3Denum cap) { |
| 694 } | 856 if (cap == GL_SCISSOR_TEST) |
| 695 | 857 scissor_enabled_ = true; |
| 696 virtual void enable(WGC3Denum cap) | 858 } |
| 697 { | 859 |
| 698 if (cap == GL_SCISSOR_TEST) | 860 virtual void disable(WGC3Denum cap) { |
| 699 m_scissorEnabled = true; | 861 if (cap == GL_SCISSOR_TEST) |
| 700 } | 862 scissor_enabled_ = false; |
| 701 | 863 } |
| 702 virtual void disable(WGC3Denum cap) | 864 |
| 703 { | 865 private: |
| 704 if (cap == GL_SCISSOR_TEST) | 866 bool scissor_enabled_; |
| 705 m_scissorEnabled = false; | 867 }; |
| 706 } | 868 |
| 707 | 869 TEST(GLRendererTest2, ScissorTestWhenClearing) { |
| 708 private: | 870 FakeRendererClient mock_client; |
| 709 bool m_scissorEnabled; | 871 scoped_ptr<OutputSurface> output_surface( |
| 710 }; | 872 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 711 | 873 new ScissorTestOnClearCheckingContext))); |
| 712 TEST(GLRendererTest2, scissorTestWhenClearing) { | 874 scoped_ptr<ResourceProvider> resource_provider( |
| 713 FakeRendererClient mockClient; | 875 ResourceProvider::Create(output_surface.get())); |
| 714 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new ScissorTestOnClearCheckingContext))); | 876 FakeRendererGL renderer( |
| 715 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get())); | 877 &mock_client, output_surface.get(), resource_provider.get()); |
| 716 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g et()); | 878 EXPECT_TRUE(renderer.Initialize()); |
| 717 EXPECT_TRUE(renderer.Initialize()); | 879 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); |
| 718 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); | 880 |
| 719 | 881 gfx::Rect viewport_rect(mock_client.DeviceViewportSize()); |
| 720 gfx::Rect viewportRect(mockClient.DeviceViewportSize()); | 882 ScopedPtrVector<RenderPass>& render_passes = |
| 721 ScopedPtrVector<RenderPass>& renderPasses = mockClient.renderPassesInDrawOrd er(); | 883 mock_client.RenderPassesInDrawOrder(); |
| 722 renderPasses.clear(); | 884 render_passes.clear(); |
| 723 | 885 |
| 724 gfx::Rect grandChildRect(25, 25); | 886 gfx::Rect grand_child_rect(25, 25); |
| 725 RenderPass::Id grandChildPassId(3, 0); | 887 RenderPass::Id grand_child_pass_id(3, 0); |
| 726 TestRenderPass* grandChildPass = addRenderPass(renderPasses, grandChildPassI d, grandChildRect, gfx::Transform()); | 888 TestRenderPass* grand_child_pass = addRenderPass( |
| 727 addClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW); | 889 render_passes, grand_child_pass_id, grand_child_rect, gfx::Transform()); |
| 728 | 890 addClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW); |
| 729 gfx::Rect childRect(50, 50); | 891 |
| 730 RenderPass::Id childPassId(2, 0); | 892 gfx::Rect child_rect(50, 50); |
| 731 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, childRe ct, gfx::Transform()); | 893 RenderPass::Id child_pass_id(2, 0); |
| 732 addQuad(childPass, childRect, SK_ColorBLUE); | 894 TestRenderPass* child_pass = |
| 733 | 895 addRenderPass(render_passes, child_pass_id, child_rect, gfx::Transform()); |
| 734 RenderPass::Id rootPassId(1, 0); | 896 addQuad(child_pass, child_rect, SK_ColorBLUE); |
| 735 TestRenderPass* rootPass = addRenderPass(renderPasses, rootPassId, viewportR ect, gfx::Transform()); | 897 |
| 736 addQuad(rootPass, viewportRect, SK_ColorGREEN); | 898 RenderPass::Id root_pass_id(1, 0); |
| 737 | 899 TestRenderPass* root_pass = addRenderPass( |
| 738 addRenderPassQuad(rootPass, childPass); | 900 render_passes, root_pass_id, viewport_rect, gfx::Transform()); |
| 739 addRenderPassQuad(childPass, grandChildPass); | 901 addQuad(root_pass, viewport_rect, SK_ColorGREEN); |
| 740 | 902 |
| 741 renderer.DecideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr der()); | 903 addRenderPassQuad(root_pass, child_pass); |
| 742 renderer.DrawFrame(mockClient.renderPassesInDrawOrder()); | 904 addRenderPassQuad(child_pass, grand_child_pass); |
| 905 | |
| 906 renderer.DecideRenderPassAllocationsForFrame( | |
| 907 mock_client.RenderPassesInDrawOrder()); | |
| 908 renderer.DrawFrame(mock_client.RenderPassesInDrawOrder()); | |
| 743 } | 909 } |
| 744 | 910 |
| 745 class OutputSurfaceMockContext : public TestWebGraphicsContext3D { | 911 class OutputSurfaceMockContext : public TestWebGraphicsContext3D { |
| 746 public: | 912 public: |
| 747 // Specifically override methods even if they are unused (used in conjunctio n with StrictMock). | 913 // 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 | 914 // with StrictMock). We need to make sure that GLRenderer does not issue |
| 749 // are supposed to go through the OutputSurface abstraction. | 915 // framebuffer-related GL calls directly. Instead these are supposed to go |
| 750 MOCK_METHOD0(ensureBackbufferCHROMIUM, void()); | 916 // through the OutputSurface abstraction. |
| 751 MOCK_METHOD0(discardBackbufferCHROMIUM, void()); | 917 MOCK_METHOD0(ensureBackbufferCHROMIUM, void()); |
| 752 MOCK_METHOD2(bindFramebuffer, void(WGC3Denum target, WebGLId framebuffer)); | 918 MOCK_METHOD0(discardBackbufferCHROMIUM, void()); |
| 753 MOCK_METHOD0(prepareTexture, void()); | 919 MOCK_METHOD2(bindFramebuffer, void(WGC3Denum target, WebGLId framebuffer)); |
| 754 MOCK_METHOD2(reshape, void(int width, int height)); | 920 MOCK_METHOD0(prepareTexture, void()); |
| 755 MOCK_METHOD4(drawElements, void(WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset)); | 921 MOCK_METHOD2(reshape, void(int width, int height)); |
| 756 | 922 MOCK_METHOD4(drawElements, |
| 757 virtual WebString getString(WebKit::WGC3Denum name) | 923 void(WGC3Denum mode, |
| 758 { | 924 WGC3Dsizei count, |
| 759 if (name == GL_EXTENSIONS) | 925 WGC3Denum type, |
| 760 return WebString("GL_CHROMIUM_post_sub_buffer GL_CHROMIUM_discard_ba ckbuffer"); | 926 WGC3Dintptr offset)); |
| 761 return WebString(); | 927 |
| 762 } | 928 virtual WebString getString(WebKit::WGC3Denum name) { |
| 929 if (name == GL_EXTENSIONS) | |
| 930 return WebString( | |
| 931 "GL_CHROMIUM_post_sub_buffer GL_CHROMIUM_discard_backbuffer"); | |
| 932 return WebString(); | |
| 933 } | |
| 763 }; | 934 }; |
| 764 | 935 |
| 765 class MockOutputSurface : public OutputSurface { | 936 class MockOutputSurface : public OutputSurface { |
| 766 public: | 937 public: |
| 767 MockOutputSurface() | 938 MockOutputSurface() |
| 768 : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(new StrictMock< OutputSurfaceMockContext>)) { } | 939 : OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>( |
| 769 virtual ~MockOutputSurface() { } | 940 new StrictMock<OutputSurfaceMockContext>)) {} |
| 770 | 941 virtual ~MockOutputSurface() {} |
| 771 MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame)); | 942 |
| 772 MOCK_METHOD0(EnsureBackbuffer, void()); | 943 MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame)); |
| 773 MOCK_METHOD0(DiscardBackbuffer, void()); | 944 MOCK_METHOD0(EnsureBackbuffer, void()); |
| 774 MOCK_METHOD1(Reshape, void(gfx::Size size)); | 945 MOCK_METHOD0(DiscardBackbuffer, void()); |
| 775 MOCK_METHOD0(BindFramebuffer, void()); | 946 MOCK_METHOD1(Reshape, void(gfx::Size size)); |
| 776 MOCK_METHOD1(PostSubBuffer, void(gfx::Rect rect)); | 947 MOCK_METHOD0(BindFramebuffer, void()); |
| 777 MOCK_METHOD0(SwapBuffers, void()); | 948 MOCK_METHOD1(PostSubBuffer, void(gfx::Rect rect)); |
| 778 }; | 949 MOCK_METHOD0(SwapBuffers, void()); |
| 779 | 950 }; |
| 780 class MockOutputSurfaceTest : public testing::Test, | 951 |
| 781 public FakeRendererClient { | 952 class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient { |
| 782 protected: | 953 protected: |
| 783 MockOutputSurfaceTest() | 954 MockOutputSurfaceTest() |
| 784 : resource_provider_(ResourceProvider::Create(&m_outputSurface)) | 955 : resource_provider_(ResourceProvider::Create(&output_surface_)), |
| 785 , m_renderer(this, &m_outputSurface, resource_provider_.get()) | 956 renderer_(this, &output_surface_, resource_provider_.get()) {} |
| 786 { | 957 |
| 787 } | 958 virtual void SetUp() { EXPECT_TRUE(renderer_.Initialize()); } |
| 788 | 959 |
| 789 virtual void SetUp() | 960 void SwapBuffers() { renderer_.SwapBuffers(); } |
| 790 { | 961 |
| 791 EXPECT_TRUE(m_renderer.Initialize()); | 962 void DrawFrame() { |
| 792 } | 963 gfx::Rect viewport_rect(DeviceViewportSize()); |
| 793 | 964 ScopedPtrVector<RenderPass>& render_passes = RenderPassesInDrawOrder(); |
| 794 void SwapBuffers() | 965 render_passes.clear(); |
| 795 { | 966 |
| 796 m_renderer.SwapBuffers(); | 967 RenderPass::Id render_pass_id(1, 0); |
| 797 } | 968 TestRenderPass* render_pass = addRenderPass( |
| 798 | 969 render_passes, render_pass_id, viewport_rect, gfx::Transform()); |
| 799 void DrawFrame() | 970 addQuad(render_pass, viewport_rect, SK_ColorGREEN); |
| 800 { | 971 |
| 801 gfx::Rect viewportRect(DeviceViewportSize()); | 972 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return()); |
| 802 ScopedPtrVector<RenderPass>& renderPasses = renderPassesInDrawOrder(); | 973 |
| 803 renderPasses.clear(); | 974 EXPECT_CALL(output_surface_, Reshape(_)).Times(1); |
| 804 | 975 |
| 805 RenderPass::Id renderPassId(1, 0); | 976 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1); |
| 806 TestRenderPass* renderPass = addRenderPass(renderPasses, renderPassId, v iewportRect, gfx::Transform()); | 977 |
| 807 addQuad(renderPass, viewportRect, SK_ColorGREEN); | 978 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1); |
| 808 | 979 |
| 809 EXPECT_CALL(m_outputSurface, EnsureBackbuffer()) | 980 renderer_.DecideRenderPassAllocationsForFrame(RenderPassesInDrawOrder()); |
| 810 .WillRepeatedly(Return()); | 981 renderer_.DrawFrame(RenderPassesInDrawOrder()); |
| 811 | 982 } |
| 812 EXPECT_CALL(m_outputSurface, Reshape(_)) | 983 |
| 813 .Times(1); | 984 OutputSurfaceMockContext* Context() { |
|
danakj
2013/03/22 21:44:12
context()
| |
| 814 | 985 return static_cast<OutputSurfaceMockContext*>(output_surface_.context3d()); |
| 815 EXPECT_CALL(m_outputSurface, BindFramebuffer()) | 986 } |
| 816 .Times(1); | 987 |
| 817 | 988 StrictMock<MockOutputSurface> output_surface_; |
| 818 EXPECT_CALL(*context(), drawElements(_, _, _, _)) | 989 scoped_ptr<ResourceProvider> resource_provider_; |
| 819 .Times(1); | 990 FakeRendererGL renderer_; |
| 820 | 991 }; |
| 821 m_renderer.DecideRenderPassAllocationsForFrame(renderPassesInDrawOrder() ); | 992 |
| 822 m_renderer.DrawFrame(renderPassesInDrawOrder()); | 993 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) { |
| 823 } | 994 DrawFrame(); |
| 824 | 995 |
| 825 OutputSurfaceMockContext* context() { return static_cast<OutputSurfaceMockCo ntext*>(m_outputSurface.context3d()); } | 996 EXPECT_CALL(output_surface_, SwapBuffers()).Times(1); |
| 826 | 997 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 } | 998 } |
| 840 | 999 |
| 841 class MockOutputSurfaceTestWithPartialSwap : public MockOutputSurfaceTest { | 1000 class MockOutputSurfaceTestWithPartialSwap : public MockOutputSurfaceTest { |
| 842 public: | 1001 public: |
| 843 virtual const LayerTreeSettings& Settings() const OVERRIDE | 1002 virtual const LayerTreeSettings& Settings() const OVERRIDE { |
| 844 { | 1003 static LayerTreeSettings fake_settings; |
| 845 static LayerTreeSettings fakeSettings; | 1004 fake_settings.partial_swap_enabled = true; |
| 846 fakeSettings.partial_swap_enabled = true; | 1005 return fake_settings; |
| 847 return fakeSettings; | 1006 } |
| 848 } | 1007 }; |
| 849 }; | 1008 |
| 850 | 1009 TEST_F(MockOutputSurfaceTestWithPartialSwap, DrawFrameAndSwap) { |
| 851 TEST_F(MockOutputSurfaceTestWithPartialSwap, DrawFrameAndSwap) | 1010 DrawFrame(); |
| 852 { | 1011 |
| 853 DrawFrame(); | 1012 EXPECT_CALL(output_surface_, PostSubBuffer(_)).Times(1); |
| 854 | 1013 renderer_.SwapBuffers(); |
| 855 EXPECT_CALL(m_outputSurface, PostSubBuffer(_)) | 1014 } |
| 856 .Times(1); | 1015 |
| 857 m_renderer.SwapBuffers(); | 1016 class MockOutputSurfaceTestWithSendCompositorFrame : |
| 858 } | 1017 public MockOutputSurfaceTest { |
| 859 | 1018 public: |
| 860 class MockOutputSurfaceTestWithSendCompositorFrame : public MockOutputSurfaceTes t { | 1019 virtual const LayerTreeSettings& Settings() const OVERRIDE { |
| 861 public: | 1020 static LayerTreeSettings fake_settings; |
| 862 virtual const LayerTreeSettings& Settings() const OVERRIDE | 1021 fake_settings.compositor_frame_message = true; |
| 863 { | 1022 return fake_settings; |
| 864 static LayerTreeSettings fakeSettings; | 1023 } |
| 865 fakeSettings.compositor_frame_message = true; | 1024 }; |
| 866 return fakeSettings; | 1025 |
| 867 } | 1026 TEST_F(MockOutputSurfaceTestWithSendCompositorFrame, DrawFrame) { |
| 868 }; | 1027 EXPECT_CALL(output_surface_, SendFrameToParentCompositor(_)).Times(1); |
| 869 | 1028 DrawFrame(); |
| 870 TEST_F(MockOutputSurfaceTestWithSendCompositorFrame, DrawFrame) | |
| 871 { | |
| 872 EXPECT_CALL(m_outputSurface, SendFrameToParentCompositor(_)) | |
| 873 .Times(1); | |
| 874 DrawFrame(); | |
| 875 } | 1029 } |
| 876 | 1030 |
| 877 } // namespace | 1031 } // namespace |
| 878 } // namespace cc | 1032 } // namespace cc |
| OLD | NEW |