| 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/layer_tree_host.h" | 5 #include "cc/layer_tree_host.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "cc/content_layer.h" | 8 #include "cc/content_layer.h" |
| 9 #include "cc/delegated_renderer_layer.h" | 9 #include "cc/delegated_renderer_layer.h" |
| 10 #include "cc/delegated_renderer_layer_impl.h" | 10 #include "cc/delegated_renderer_layer_impl.h" |
| 11 #include "cc/heads_up_display_layer.h" | 11 #include "cc/heads_up_display_layer.h" |
| 12 #include "cc/io_surface_layer.h" | 12 #include "cc/io_surface_layer.h" |
| 13 #include "cc/layer_impl.h" | 13 #include "cc/layer_impl.h" |
| 14 #include "cc/layer_tree_host_impl.h" | 14 #include "cc/layer_tree_host_impl.h" |
| 15 #include "cc/layer_tree_impl.h" | 15 #include "cc/layer_tree_impl.h" |
| 16 #include "cc/picture_layer.h" | 16 #include "cc/picture_layer.h" |
| 17 #include "cc/scrollbar_layer.h" | 17 #include "cc/scrollbar_layer.h" |
| 18 #include "cc/single_thread_proxy.h" | 18 #include "cc/single_thread_proxy.h" |
| 19 #include "cc/test/fake_content_layer.h" | 19 #include "cc/test/fake_content_layer.h" |
| 20 #include "cc/test/fake_content_layer_client.h" | 20 #include "cc/test/fake_content_layer_client.h" |
| 21 #include "cc/test/fake_content_layer_impl.h" | 21 #include "cc/test/fake_content_layer_impl.h" |
| 22 #include "cc/test/fake_context_provider.h" |
| 22 #include "cc/test/fake_output_surface.h" | 23 #include "cc/test/fake_output_surface.h" |
| 23 #include "cc/test/fake_scrollbar_layer.h" | 24 #include "cc/test/fake_scrollbar_layer.h" |
| 24 #include "cc/test/fake_scrollbar_theme_painter.h" | 25 #include "cc/test/fake_scrollbar_theme_painter.h" |
| 25 #include "cc/test/fake_video_frame_provider.h" | 26 #include "cc/test/fake_video_frame_provider.h" |
| 26 #include "cc/test/fake_web_scrollbar.h" | 27 #include "cc/test/fake_web_scrollbar.h" |
| 27 #include "cc/test/fake_web_scrollbar_theme_geometry.h" | 28 #include "cc/test/fake_web_scrollbar_theme_geometry.h" |
| 28 #include "cc/test/layer_tree_test_common.h" | 29 #include "cc/test/layer_tree_test_common.h" |
| 29 #include "cc/test/render_pass_test_common.h" | 30 #include "cc/test/render_pass_test_common.h" |
| 30 #include "cc/test/test_web_graphics_context_3d.h" | 31 #include "cc/test/test_web_graphics_context_3d.h" |
| 31 #include "cc/texture_layer.h" | 32 #include "cc/texture_layer.h" |
| 32 #include "cc/video_layer.h" | 33 #include "cc/video_layer.h" |
| 33 #include "cc/video_layer_impl.h" | 34 #include "cc/video_layer_impl.h" |
| 34 #include "gpu/GLES2/gl2extchromium.h" | 35 #include "gpu/GLES2/gl2extchromium.h" |
| 35 #include "media/base/media.h" | 36 #include "media/base/media.h" |
| 37 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations
.h" |
| 36 | 38 |
| 37 using media::VideoFrame; | 39 using media::VideoFrame; |
| 38 using WebKit::WebGraphicsContext3D; | 40 using WebKit::WebGraphicsContext3D; |
| 39 | 41 |
| 40 namespace cc { | 42 namespace cc { |
| 41 namespace { | 43 namespace { |
| 42 | 44 |
| 43 // These tests deal with losing the 3d graphics context. | 45 // These tests deal with losing the 3d graphics context. |
| 44 class LayerTreeHostContextTest : public ThreadedTest { | 46 class LayerTreeHostContextTest : public ThreadedTest { |
| 45 public: | 47 public: |
| 46 LayerTreeHostContextTest() | 48 LayerTreeHostContextTest() |
| 47 : ThreadedTest(), | 49 : ThreadedTest(), |
| 48 context3d_(NULL), | 50 context3d_(NULL), |
| 49 times_to_fail_create_(0), | 51 times_to_fail_create_(0), |
| 50 times_to_fail_initialize_(0), | 52 times_to_fail_initialize_(0), |
| 51 times_to_lose_on_create_(0), | 53 times_to_lose_on_create_(0), |
| 52 times_to_lose_during_commit_(0), | 54 times_to_lose_during_commit_(0), |
| 53 times_to_lose_during_draw_(0), | 55 times_to_lose_during_draw_(0), |
| 54 times_to_fail_recreate_(0), | 56 times_to_fail_recreate_(0), |
| 55 times_to_fail_reinitialize_(0), | 57 times_to_fail_reinitialize_(0), |
| 56 times_to_lose_on_recreate_(0) { | 58 times_to_lose_on_recreate_(0), |
| 59 times_to_fail_create_offscreen_(0), |
| 60 times_to_fail_recreate_offscreen_(0), |
| 61 times_to_expect_recreate_retried_(0), |
| 62 times_recreate_retried_(0), |
| 63 times_offscreen_created_(0), |
| 64 committed_at_least_once_(false) { |
| 57 media::InitializeMediaLibraryForTesting(); | 65 media::InitializeMediaLibraryForTesting(); |
| 58 } | 66 } |
| 59 | 67 |
| 60 void LoseContext() { | 68 void LoseContext() { |
| 61 context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, | 69 context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, |
| 62 GL_INNOCENT_CONTEXT_RESET_ARB); | 70 GL_INNOCENT_CONTEXT_RESET_ARB); |
| 63 context3d_ = NULL; | 71 context3d_ = NULL; |
| 64 } | 72 } |
| 65 | 73 |
| 66 virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() { | 74 virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() { |
| 67 return TestWebGraphicsContext3D::Create(); | 75 return TestWebGraphicsContext3D::Create(); |
| 68 } | 76 } |
| 69 | 77 |
| 70 virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE { | 78 virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE { |
| 71 if (times_to_fail_create_) { | 79 if (times_to_fail_create_) { |
| 72 --times_to_fail_create_; | 80 --times_to_fail_create_; |
| 81 ExpectRecreateToRetry(); |
| 73 return scoped_ptr<OutputSurface>(); | 82 return scoped_ptr<OutputSurface>(); |
| 74 } | 83 } |
| 75 | 84 |
| 76 scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); | 85 scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); |
| 77 context3d_ = context3d.get(); | 86 context3d_ = context3d.get(); |
| 78 | 87 |
| 79 if (times_to_fail_initialize_) { | 88 if (times_to_fail_initialize_) { |
| 80 --times_to_fail_initialize_; | 89 --times_to_fail_initialize_; |
| 81 // Make the context get lost during reinitialization. | 90 // Make the context get lost during reinitialization. |
| 82 // The number of times MakeCurrent succeeds is not important, and | 91 // The number of times MakeCurrent succeeds is not important, and |
| 83 // can be changed if needed to make this pass with future changes. | 92 // can be changed if needed to make this pass with future changes. |
| 84 context3d_->set_times_make_current_succeeds(2); | 93 context3d_->set_times_make_current_succeeds(2); |
| 94 ExpectRecreateToRetry(); |
| 85 } else if (times_to_lose_on_create_) { | 95 } else if (times_to_lose_on_create_) { |
| 86 --times_to_lose_on_create_; | 96 --times_to_lose_on_create_; |
| 87 LoseContext(); | 97 LoseContext(); |
| 98 ExpectRecreateToRetry(); |
| 88 } | 99 } |
| 89 | 100 |
| 90 return FakeOutputSurface::Create3d( | 101 return FakeOutputSurface::Create3d( |
| 91 context3d.PassAs<WebGraphicsContext3D>()).PassAs<OutputSurface>(); | 102 context3d.PassAs<WebGraphicsContext3D>()).PassAs<OutputSurface>(); |
| 92 } | 103 } |
| 93 | 104 |
| 94 virtual bool prepareToDrawOnThread( | 105 scoped_ptr<TestWebGraphicsContext3D> CreateOffscreenContext3d() { |
| 95 LayerTreeHostImpl*, LayerTreeHostImpl::FrameData&, bool result) | 106 if (!context3d_) |
| 96 OVERRIDE { | 107 return scoped_ptr<TestWebGraphicsContext3D>(); |
| 97 EXPECT_TRUE(result); | |
| 98 if (!times_to_lose_during_draw_) | |
| 99 return result; | |
| 100 | 108 |
| 101 --times_to_lose_during_draw_; | 109 ++times_offscreen_created_; |
| 102 if (context3d_) | 110 |
| 103 context3d_->set_times_make_current_succeeds(0); | 111 if (times_to_fail_create_offscreen_) { |
| 104 return result; | 112 --times_to_fail_create_offscreen_; |
| 113 ExpectRecreateToRetry(); |
| 114 return scoped_ptr<TestWebGraphicsContext3D>(); |
| 105 } | 115 } |
| 106 | 116 |
| 117 scoped_ptr<TestWebGraphicsContext3D> offscreen_context3d = |
| 118 TestWebGraphicsContext3D::Create().Pass(); |
| 119 DCHECK(offscreen_context3d); |
| 120 context3d_->add_share_group_context(offscreen_context3d.get()); |
| 121 |
| 122 return offscreen_context3d.Pass(); |
| 123 } |
| 124 |
| 125 virtual scoped_refptr<ui::ContextProvider> |
| 126 OffscreenContextProviderForMainThread() OVERRIDE { |
| 127 DCHECK(!implThread()); |
| 128 |
| 129 if (!offscreen_contexts_main_thread_ || |
| 130 offscreen_contexts_main_thread_->destroyed()) { |
| 131 offscreen_contexts_main_thread_ = new FakeContextProvider( |
| 132 base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d, |
| 133 base::Unretained(this))); |
| 134 } |
| 135 return offscreen_contexts_main_thread_; |
| 136 } |
| 137 |
| 138 virtual scoped_refptr<ui::ContextProvider> |
| 139 OffscreenContextProviderForCompositorThread() OVERRIDE { |
| 140 DCHECK(implThread()); |
| 141 |
| 142 if (!offscreen_contexts_compositor_thread_ || |
| 143 offscreen_contexts_compositor_thread_->destroyed()) { |
| 144 offscreen_contexts_compositor_thread_ = new FakeContextProvider( |
| 145 base::Bind(&LayerTreeHostContextTest::CreateOffscreenContext3d, |
| 146 base::Unretained(this))); |
| 147 } |
| 148 return offscreen_contexts_compositor_thread_; |
| 149 } |
| 150 |
| 151 virtual bool prepareToDrawOnThread( |
| 152 LayerTreeHostImpl*, LayerTreeHostImpl::FrameData&, bool result) |
| 153 OVERRIDE { |
| 154 EXPECT_TRUE(result); |
| 155 if (!times_to_lose_during_draw_) |
| 156 return result; |
| 157 |
| 158 --times_to_lose_during_draw_; |
| 159 context3d_->set_times_make_current_succeeds(0); |
| 160 |
| 161 times_to_fail_create_ = times_to_fail_recreate_; |
| 162 times_to_fail_recreate_ = 0; |
| 163 times_to_fail_initialize_ = times_to_fail_reinitialize_; |
| 164 times_to_fail_reinitialize_ = 0; |
| 165 times_to_lose_on_create_ = times_to_lose_on_recreate_; |
| 166 times_to_lose_on_recreate_ = 0; |
| 167 times_to_fail_create_offscreen_ = times_to_fail_recreate_offscreen_; |
| 168 times_to_fail_recreate_offscreen_ = 0; |
| 169 |
| 170 return result; |
| 171 } |
| 172 |
| 107 virtual void commitCompleteOnThread(LayerTreeHostImpl *host_impl) OVERRIDE { | 173 virtual void commitCompleteOnThread(LayerTreeHostImpl *host_impl) OVERRIDE { |
| 174 committed_at_least_once_ = true; |
| 175 |
| 108 if (!times_to_lose_during_commit_) | 176 if (!times_to_lose_during_commit_) |
| 109 return; | 177 return; |
| 110 --times_to_lose_during_commit_; | 178 --times_to_lose_during_commit_; |
| 111 LoseContext(); | 179 LoseContext(); |
| 112 | 180 |
| 113 times_to_fail_create_ = times_to_fail_recreate_; | 181 times_to_fail_create_ = times_to_fail_recreate_; |
| 114 times_to_fail_recreate_ = 0; | 182 times_to_fail_recreate_ = 0; |
| 115 times_to_fail_initialize_ = times_to_fail_reinitialize_; | 183 times_to_fail_initialize_ = times_to_fail_reinitialize_; |
| 116 times_to_fail_reinitialize_ = 0; | 184 times_to_fail_reinitialize_ = 0; |
| 117 times_to_lose_on_create_ = times_to_lose_on_recreate_; | 185 times_to_lose_on_create_ = times_to_lose_on_recreate_; |
| 118 times_to_lose_on_recreate_ = 0; | 186 times_to_lose_on_recreate_ = 0; |
| 187 times_to_fail_create_offscreen_ = times_to_fail_recreate_offscreen_; |
| 188 times_to_fail_recreate_offscreen_ = 0; |
| 189 } |
| 190 |
| 191 virtual void willRetryRecreateOutputSurface() OVERRIDE { |
| 192 ++times_recreate_retried_; |
| 193 } |
| 194 |
| 195 virtual void TearDown() OVERRIDE { |
| 196 ThreadedTest::TearDown(); |
| 197 EXPECT_EQ(times_to_expect_recreate_retried_, times_recreate_retried_); |
| 198 } |
| 199 |
| 200 void ExpectRecreateToRetry() { |
| 201 if (committed_at_least_once_) |
| 202 ++times_to_expect_recreate_retried_; |
| 119 } | 203 } |
| 120 | 204 |
| 121 protected: | 205 protected: |
| 122 TestWebGraphicsContext3D* context3d_; | 206 TestWebGraphicsContext3D* context3d_; |
| 123 int times_to_fail_create_; | 207 int times_to_fail_create_; |
| 124 int times_to_fail_initialize_; | 208 int times_to_fail_initialize_; |
| 125 int times_to_lose_on_create_; | 209 int times_to_lose_on_create_; |
| 126 int times_to_lose_during_commit_; | 210 int times_to_lose_during_commit_; |
| 127 int times_to_lose_during_draw_; | 211 int times_to_lose_during_draw_; |
| 128 int times_to_fail_reinitialize_; | 212 int times_to_fail_reinitialize_; |
| 129 int times_to_fail_recreate_; | 213 int times_to_fail_recreate_; |
| 130 int times_to_lose_on_recreate_; | 214 int times_to_lose_on_recreate_; |
| 215 int times_to_fail_create_offscreen_; |
| 216 int times_to_fail_recreate_offscreen_; |
| 217 int times_to_expect_recreate_retried_; |
| 218 int times_recreate_retried_; |
| 219 int times_offscreen_created_; |
| 220 bool committed_at_least_once_; |
| 221 |
| 222 scoped_refptr<FakeContextProvider> offscreen_contexts_main_thread_; |
| 223 scoped_refptr<FakeContextProvider> offscreen_contexts_compositor_thread_; |
| 131 }; | 224 }; |
| 132 | 225 |
| 133 class LayerTreeHostContextTestLostContextSucceeds : | 226 class LayerTreeHostContextTestLostContextSucceeds : |
| 134 public LayerTreeHostContextTest { | 227 public LayerTreeHostContextTest { |
| 135 public: | 228 public: |
| 136 LayerTreeHostContextTestLostContextSucceeds() | 229 LayerTreeHostContextTestLostContextSucceeds() |
| 137 : LayerTreeHostContextTest(), | 230 : LayerTreeHostContextTest(), |
| 138 test_case_(0), | 231 test_case_(0), |
| 139 num_losses_(0), | 232 num_losses_(0), |
| 140 recovered_context_(true) { | 233 recovered_context_(true) { |
| 141 } | 234 } |
| 142 | 235 |
| 143 virtual void beginTest() OVERRIDE { | 236 virtual void beginTest() OVERRIDE { |
| 144 postSetNeedsCommitToMainThread(); | 237 postSetNeedsCommitToMainThread(); |
| 145 } | 238 } |
| 146 | 239 |
| 147 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { | 240 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { |
| 148 EXPECT_TRUE(succeeded); | 241 EXPECT_TRUE(succeeded); |
| 149 ++num_losses_; | 242 ++num_losses_; |
| 150 recovered_context_ = true; | 243 recovered_context_ = true; |
| 151 } | 244 } |
| 152 | 245 |
| 153 virtual void afterTest() OVERRIDE { | 246 virtual void afterTest() OVERRIDE { |
| 154 EXPECT_EQ(8, test_case_); | 247 EXPECT_EQ(10, test_case_); |
| 155 EXPECT_EQ(6 + 10 + 10, num_losses_); | 248 EXPECT_EQ(8 + 10 + 10, num_losses_); |
| 156 } | 249 } |
| 157 | 250 |
| 158 virtual void didCommitAndDrawFrame() OVERRIDE { | 251 virtual void didCommitAndDrawFrame() OVERRIDE { |
| 159 // If the last frame had a context loss, then we'll commit again to | 252 // If the last frame had a context loss, then we'll commit again to |
| 160 // recover. | 253 // recover. |
| 161 if (!recovered_context_) | 254 if (!recovered_context_) |
| 162 return; | 255 return; |
| 163 if (times_to_lose_during_commit_) | 256 if (times_to_lose_during_commit_) |
| 164 return; | 257 return; |
| 165 if (times_to_lose_during_draw_) | 258 if (times_to_lose_during_draw_) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 178 | 271 |
| 179 bool NextTestCase() { | 272 bool NextTestCase() { |
| 180 static const TestCase kTests[] = { | 273 static const TestCase kTests[] = { |
| 181 // Losing the context and failing to recreate it (or losing it again | 274 // Losing the context and failing to recreate it (or losing it again |
| 182 // immediately) a small number of times should succeed. | 275 // immediately) a small number of times should succeed. |
| 183 { 1, // times_to_lose_during_commit | 276 { 1, // times_to_lose_during_commit |
| 184 0, // times_to_lose_during_draw | 277 0, // times_to_lose_during_draw |
| 185 3, // times_to_fail_reinitialize | 278 3, // times_to_fail_reinitialize |
| 186 0, // times_to_fail_recreate | 279 0, // times_to_fail_recreate |
| 187 0, // times_to_lose_on_recreate | 280 0, // times_to_lose_on_recreate |
| 281 0, // times_to_fail_recreate_offscreen |
| 188 }, | 282 }, |
| 189 { 0, // times_to_lose_during_commit | 283 { 0, // times_to_lose_during_commit |
| 190 1, // times_to_lose_during_draw | 284 1, // times_to_lose_during_draw |
| 191 3, // times_to_fail_reinitialize | 285 3, // times_to_fail_reinitialize |
| 192 0, // times_to_fail_recreate | 286 0, // times_to_fail_recreate |
| 193 0, // times_to_lose_on_recreate | 287 0, // times_to_lose_on_recreate |
| 288 0, // times_to_fail_recreate_offscreen |
| 194 }, | 289 }, |
| 195 { 1, // times_to_lose_during_commit | 290 { 1, // times_to_lose_during_commit |
| 196 0, // times_to_lose_during_draw | 291 0, // times_to_lose_during_draw |
| 197 0, // times_to_fail_reinitialize | 292 0, // times_to_fail_reinitialize |
| 198 3, // times_to_fail_recreate | 293 3, // times_to_fail_recreate |
| 199 0, // times_to_lose_on_recreate | 294 0, // times_to_lose_on_recreate |
| 295 0, // times_to_fail_recreate_offscreen |
| 200 }, | 296 }, |
| 201 { 0, // times_to_lose_during_commit | 297 { 0, // times_to_lose_during_commit |
| 202 1, // times_to_lose_during_draw | 298 1, // times_to_lose_during_draw |
| 203 0, // times_to_fail_reinitialize | 299 0, // times_to_fail_reinitialize |
| 204 3, // times_to_fail_recreate | 300 3, // times_to_fail_recreate |
| 205 0, // times_to_lose_on_recreate | 301 0, // times_to_lose_on_recreate |
| 302 0, // times_to_fail_recreate_offscreen |
| 206 }, | 303 }, |
| 207 { 1, // times_to_lose_during_commit | 304 { 1, // times_to_lose_during_commit |
| 208 0, // times_to_lose_during_draw | 305 0, // times_to_lose_during_draw |
| 209 0, // times_to_fail_reinitialize | 306 0, // times_to_fail_reinitialize |
| 210 0, // times_to_fail_recreate | 307 0, // times_to_fail_recreate |
| 211 3, // times_to_lose_on_recreate | 308 3, // times_to_lose_on_recreate |
| 309 0, // times_to_fail_recreate_offscreen |
| 212 }, | 310 }, |
| 213 { 0, // times_to_lose_during_commit | 311 { 0, // times_to_lose_during_commit |
| 214 1, // times_to_lose_during_draw | 312 1, // times_to_lose_during_draw |
| 215 0, // times_to_fail_reinitialize | 313 0, // times_to_fail_reinitialize |
| 216 0, // times_to_fail_recreate | 314 0, // times_to_fail_recreate |
| 217 3, // times_to_lose_on_recreate | 315 3, // times_to_lose_on_recreate |
| 316 0, // times_to_fail_recreate_offscreen |
| 317 }, |
| 318 { 1, // times_to_lose_during_commit |
| 319 0, // times_to_lose_during_draw |
| 320 0, // times_to_fail_reinitialize |
| 321 0, // times_to_fail_recreate |
| 322 0, // times_to_lose_on_recreate |
| 323 3, // times_to_fail_recreate_offscreen |
| 324 }, |
| 325 { 0, // times_to_lose_during_commit |
| 326 1, // times_to_lose_during_draw |
| 327 0, // times_to_fail_reinitialize |
| 328 0, // times_to_fail_recreate |
| 329 0, // times_to_lose_on_recreate |
| 330 3, // times_to_fail_recreate_offscreen |
| 218 }, | 331 }, |
| 219 // Losing the context and recreating it any number of times should | 332 // Losing the context and recreating it any number of times should |
| 220 // succeed. | 333 // succeed. |
| 221 { 10, // times_to_lose_during_commit | 334 { 10, // times_to_lose_during_commit |
| 222 0, // times_to_lose_during_draw | 335 0, // times_to_lose_during_draw |
| 223 0, // times_to_fail_reinitialize | 336 0, // times_to_fail_reinitialize |
| 224 0, // times_to_fail_recreate | 337 0, // times_to_fail_recreate |
| 225 0, // times_to_lose_on_recreate | 338 0, // times_to_lose_on_recreate |
| 339 0, // times_to_fail_recreate_offscreen |
| 226 }, | 340 }, |
| 227 { 0, // times_to_lose_during_commit | 341 { 0, // times_to_lose_during_commit |
| 228 10, // times_to_lose_during_draw | 342 10, // times_to_lose_during_draw |
| 229 0, // times_to_fail_reinitialize | 343 0, // times_to_fail_reinitialize |
| 230 0, // times_to_fail_recreate | 344 0, // times_to_fail_recreate |
| 231 0, // times_to_lose_on_recreate | 345 0, // times_to_lose_on_recreate |
| 346 0, // times_to_fail_recreate_offscreen |
| 232 }, | 347 }, |
| 233 }; | 348 }; |
| 234 | 349 |
| 235 if (test_case_ >= arraysize(kTests)) | 350 if (test_case_ >= arraysize(kTests)) |
| 236 return false; | 351 return false; |
| 237 | 352 |
| 238 times_to_lose_during_commit_ = | 353 times_to_lose_during_commit_ = |
| 239 kTests[test_case_].times_to_lose_during_commit; | 354 kTests[test_case_].times_to_lose_during_commit; |
| 240 times_to_lose_during_draw_ = | 355 times_to_lose_during_draw_ = |
| 241 kTests[test_case_].times_to_lose_during_draw; | 356 kTests[test_case_].times_to_lose_during_draw; |
| 242 times_to_fail_reinitialize_ = kTests[test_case_].times_to_fail_reinitialize; | 357 times_to_fail_reinitialize_ = kTests[test_case_].times_to_fail_reinitialize; |
| 243 times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate; | 358 times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate; |
| 244 times_to_lose_on_recreate_ = kTests[test_case_].times_to_lose_on_recreate; | 359 times_to_lose_on_recreate_ = kTests[test_case_].times_to_lose_on_recreate; |
| 360 times_to_fail_recreate_offscreen_ = |
| 361 kTests[test_case_].times_to_fail_recreate_offscreen; |
| 245 ++test_case_; | 362 ++test_case_; |
| 246 return true; | 363 return true; |
| 247 } | 364 } |
| 248 | 365 |
| 249 struct TestCase { | 366 struct TestCase { |
| 250 int times_to_lose_during_commit; | 367 int times_to_lose_during_commit; |
| 251 int times_to_lose_during_draw; | 368 int times_to_lose_during_draw; |
| 252 int times_to_fail_reinitialize; | 369 int times_to_fail_reinitialize; |
| 253 int times_to_fail_recreate; | 370 int times_to_fail_recreate; |
| 254 int times_to_lose_on_recreate; | 371 int times_to_lose_on_recreate; |
| 372 int times_to_fail_recreate_offscreen; |
| 255 }; | 373 }; |
| 256 | 374 |
| 257 private: | 375 protected: |
| 258 size_t test_case_; | 376 size_t test_case_; |
| 259 int num_losses_; | 377 int num_losses_; |
| 260 bool recovered_context_; | 378 bool recovered_context_; |
| 261 }; | 379 }; |
| 262 | 380 |
| 263 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds) | 381 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds) |
| 264 | 382 |
| 265 class LayerTreeHostContextTestLostContextSucceedsWithContent : | 383 class LayerTreeHostContextTestLostContextSucceedsWithContent : |
| 266 public LayerTreeHostContextTestLostContextSucceeds { | 384 public LayerTreeHostContextTestLostContextSucceeds { |
| 267 public: | 385 public: |
| 268 | 386 |
| 269 LayerTreeHostContextTestLostContextSucceedsWithContent() | 387 LayerTreeHostContextTestLostContextSucceedsWithContent() |
| 270 : LayerTreeHostContextTestLostContextSucceeds() { | 388 : LayerTreeHostContextTestLostContextSucceeds() { |
| 271 } | 389 } |
| 272 | 390 |
| 273 virtual void setupTree() OVERRIDE { | 391 virtual void setupTree() OVERRIDE { |
| 274 root_ = Layer::create(); | 392 root_ = Layer::create(); |
| 275 root_->setBounds(gfx::Size(10, 10)); | 393 root_->setBounds(gfx::Size(10, 10)); |
| 276 root_->setAnchorPoint(gfx::PointF()); | 394 root_->setAnchorPoint(gfx::PointF()); |
| 277 root_->setIsDrawable(true); | 395 root_->setIsDrawable(true); |
| 278 | 396 |
| 279 content_ = FakeContentLayer::Create(&client_); | 397 content_ = FakeContentLayer::Create(&client_); |
| 280 content_->setBounds(gfx::Size(10, 10)); | 398 content_->setBounds(gfx::Size(10, 10)); |
| 281 content_->setAnchorPoint(gfx::PointF()); | 399 content_->setAnchorPoint(gfx::PointF()); |
| 282 content_->setIsDrawable(true); | 400 content_->setIsDrawable(true); |
| 283 if (use_surface_) { | 401 if (use_surface_) { |
| 284 // TODO(danakj): Give the surface a filter to test more code when we can | |
| 285 // do so without crashing in the shared context creation. | |
| 286 content_->setForceRenderSurface(true); | 402 content_->setForceRenderSurface(true); |
| 403 // Filters require us to create an offscreen context. |
| 404 WebKit::WebFilterOperations filters; |
| 405 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f)); |
| 406 content_->setFilters(filters); |
| 407 content_->setBackgroundFilters(filters); |
| 287 } | 408 } |
| 288 | 409 |
| 289 root_->addChild(content_); | 410 root_->addChild(content_); |
| 290 | 411 |
| 291 m_layerTreeHost->setRootLayer(root_); | 412 m_layerTreeHost->setRootLayer(root_); |
| 292 LayerTreeHostContextTest::setupTree(); | 413 LayerTreeHostContextTest::setupTree(); |
| 293 } | 414 } |
| 294 | 415 |
| 295 virtual void InvalidateAndSetNeedsCommit() OVERRIDE { | 416 virtual void InvalidateAndSetNeedsCommit() OVERRIDE { |
| 296 // Invalidate the render surface so we don't try to use a cached copy of the | 417 // Invalidate the render surface so we don't try to use a cached copy of the |
| 297 // surface. We want to make sure to test the drawing paths for drawing to | 418 // surface. We want to make sure to test the drawing paths for drawing to |
| 298 // a child surface. | 419 // a child surface. |
| 299 content_->setNeedsDisplay(); | 420 content_->setNeedsDisplay(); |
| 300 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit(); | 421 LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit(); |
| 301 } | 422 } |
| 302 | 423 |
| 303 virtual void drawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { | 424 virtual void drawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { |
| 304 FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>( | 425 FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>( |
| 305 host_impl->rootLayer()->children()[0]); | 426 host_impl->rootLayer()->children()[0]); |
| 306 // Even though the context was lost, we should have a resource. The | 427 // Even though the context was lost, we should have a resource. The |
| 307 // TestWebGraphicsContext3D ensures that this resource is created with | 428 // TestWebGraphicsContext3D ensures that this resource is created with |
| 308 // the active context. | 429 // the active context. |
| 309 EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0)); | 430 EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0)); |
| 431 |
| 432 ui::ContextProvider* contexts = |
| 433 host_impl->resourceProvider()->offscreenContextProvider(); |
| 434 if (use_surface_) { |
| 435 EXPECT_TRUE(contexts->Context3d()); |
| 436 // TODO(danakj): Make a fake GrContext. |
| 437 //EXPECT_TRUE(contexts->GrContext()); |
| 438 } else { |
| 439 EXPECT_FALSE(contexts); |
| 440 } |
| 441 } |
| 442 |
| 443 virtual void afterTest() OVERRIDE { |
| 444 LayerTreeHostContextTestLostContextSucceeds::afterTest(); |
| 445 if (use_surface_) |
| 446 EXPECT_EQ(6 + 3 + num_losses_, times_offscreen_created_); |
| 447 else |
| 448 EXPECT_EQ(0, times_offscreen_created_); |
| 310 } | 449 } |
| 311 | 450 |
| 312 protected: | 451 protected: |
| 313 bool use_surface_; | 452 bool use_surface_; |
| 314 FakeContentLayerClient client_; | 453 FakeContentLayerClient client_; |
| 315 scoped_refptr<Layer> root_; | 454 scoped_refptr<Layer> root_; |
| 316 scoped_refptr<ContentLayer> content_; | 455 scoped_refptr<ContentLayer> content_; |
| 317 }; | 456 }; |
| 318 | 457 |
| 319 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent, | 458 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 333 use_surface_ = true; | 472 use_surface_ = true; |
| 334 runTest(false); | 473 runTest(false); |
| 335 } | 474 } |
| 336 | 475 |
| 337 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent, | 476 TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent, |
| 338 WithSurface_MultiThread) { | 477 WithSurface_MultiThread) { |
| 339 use_surface_ = true; | 478 use_surface_ = true; |
| 340 runTest(true); | 479 runTest(true); |
| 341 } | 480 } |
| 342 | 481 |
| 482 class LayerTreeHostContextTestOffscreenContextFails |
| 483 : public LayerTreeHostContextTest { |
| 484 public: |
| 485 virtual void setupTree() OVERRIDE { |
| 486 root_ = Layer::create(); |
| 487 root_->setBounds(gfx::Size(10, 10)); |
| 488 root_->setAnchorPoint(gfx::PointF()); |
| 489 root_->setIsDrawable(true); |
| 490 |
| 491 content_ = FakeContentLayer::Create(&client_); |
| 492 content_->setBounds(gfx::Size(10, 10)); |
| 493 content_->setAnchorPoint(gfx::PointF()); |
| 494 content_->setIsDrawable(true); |
| 495 content_->setForceRenderSurface(true); |
| 496 // Filters require us to create an offscreen context. |
| 497 WebKit::WebFilterOperations filters; |
| 498 filters.append(WebKit::WebFilterOperation::createGrayscaleFilter(0.5f)); |
| 499 content_->setFilters(filters); |
| 500 content_->setBackgroundFilters(filters); |
| 501 |
| 502 root_->addChild(content_); |
| 503 |
| 504 m_layerTreeHost->setRootLayer(root_); |
| 505 LayerTreeHostContextTest::setupTree(); |
| 506 } |
| 507 |
| 508 virtual void beginTest() OVERRIDE { |
| 509 times_to_fail_create_offscreen_ = 1; |
| 510 postSetNeedsCommitToMainThread(); |
| 511 } |
| 512 |
| 513 virtual void drawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { |
| 514 ui::ContextProvider* contexts = |
| 515 host_impl->resourceProvider()->offscreenContextProvider(); |
| 516 EXPECT_FALSE(contexts); |
| 517 endTest(); |
| 518 } |
| 519 |
| 520 virtual void afterTest() OVERRIDE {} |
| 521 |
| 522 protected: |
| 523 FakeContentLayerClient client_; |
| 524 scoped_refptr<Layer> root_; |
| 525 scoped_refptr<ContentLayer> content_; |
| 526 }; |
| 527 |
| 528 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestOffscreenContextFails) |
| 529 |
| 343 class LayerTreeHostContextTestLostContextFails : | 530 class LayerTreeHostContextTestLostContextFails : |
| 344 public LayerTreeHostContextTest { | 531 public LayerTreeHostContextTest { |
| 345 public: | 532 public: |
| 346 LayerTreeHostContextTestLostContextFails() | 533 LayerTreeHostContextTestLostContextFails() |
| 347 : LayerTreeHostContextTest(), | 534 : LayerTreeHostContextTest(), |
| 348 num_commits_(0) { | 535 num_commits_(0) { |
| 349 times_to_lose_during_commit_ = 1; | 536 times_to_lose_during_commit_ = 1; |
| 350 } | 537 } |
| 351 | 538 |
| 352 virtual void beginTest() OVERRIDE { | 539 virtual void beginTest() OVERRIDE { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 } | 673 } |
| 487 | 674 |
| 488 virtual void didCommitAndDrawFrame() OVERRIDE { | 675 virtual void didCommitAndDrawFrame() OVERRIDE { |
| 489 if (num_commits_ > 1) | 676 if (num_commits_ > 1) |
| 490 return; | 677 return; |
| 491 EXPECT_TRUE(layer_->HaveBackingAt(0, 0)); | 678 EXPECT_TRUE(layer_->HaveBackingAt(0, 0)); |
| 492 PostEvictTextures(); | 679 PostEvictTextures(); |
| 493 } | 680 } |
| 494 | 681 |
| 495 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { | 682 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 683 LayerTreeHostContextTest::commitCompleteOnThread(impl); |
| 496 if (num_commits_ > 1) | 684 if (num_commits_ > 1) |
| 497 return; | 685 return; |
| 498 ++num_commits_; | 686 ++num_commits_; |
| 499 if (!lose_after_evict_) | 687 if (!lose_after_evict_) |
| 500 LoseContext(); | 688 LoseContext(); |
| 501 impl_host_ = impl; | 689 impl_host_ = impl; |
| 502 } | 690 } |
| 503 | 691 |
| 504 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { | 692 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { |
| 505 EXPECT_TRUE(succeeded); | 693 EXPECT_TRUE(succeeded); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 | 760 |
| 573 m_layerTreeHost->setRootLayer(parent_); | 761 m_layerTreeHost->setRootLayer(parent_); |
| 574 LayerTreeHostContextTest::setupTree(); | 762 LayerTreeHostContextTest::setupTree(); |
| 575 } | 763 } |
| 576 | 764 |
| 577 virtual void beginTest() OVERRIDE { | 765 virtual void beginTest() OVERRIDE { |
| 578 postSetNeedsCommitToMainThread(); | 766 postSetNeedsCommitToMainThread(); |
| 579 } | 767 } |
| 580 | 768 |
| 581 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { | 769 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 770 LayerTreeHostContextTest::commitCompleteOnThread(impl); |
| 582 endTest(); | 771 endTest(); |
| 583 } | 772 } |
| 584 | 773 |
| 585 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { | 774 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE { |
| 586 EXPECT_TRUE(succeeded); | 775 EXPECT_TRUE(succeeded); |
| 587 } | 776 } |
| 588 | 777 |
| 589 virtual void afterTest() OVERRIDE { | 778 virtual void afterTest() OVERRIDE { |
| 590 EXPECT_EQ(0, times_to_lose_on_end_query_); | 779 EXPECT_EQ(0, times_to_lose_on_end_query_); |
| 591 } | 780 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 618 | 807 |
| 619 m_layerTreeHost->setRootLayer(root_); | 808 m_layerTreeHost->setRootLayer(root_); |
| 620 LayerTreeHostContextTest::setupTree(); | 809 LayerTreeHostContextTest::setupTree(); |
| 621 } | 810 } |
| 622 | 811 |
| 623 virtual void beginTest() OVERRIDE { | 812 virtual void beginTest() OVERRIDE { |
| 624 postSetNeedsCommitToMainThread(); | 813 postSetNeedsCommitToMainThread(); |
| 625 } | 814 } |
| 626 | 815 |
| 627 virtual void commitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { | 816 virtual void commitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { |
| 817 LayerTreeHostContextTest::commitCompleteOnThread(host_impl); |
| 818 |
| 628 FakeContentLayerImpl* root = static_cast<FakeContentLayerImpl*>( | 819 FakeContentLayerImpl* root = static_cast<FakeContentLayerImpl*>( |
| 629 host_impl->rootLayer()); | 820 host_impl->rootLayer()); |
| 630 FakeContentLayerImpl* child = static_cast<FakeContentLayerImpl*>( | 821 FakeContentLayerImpl* child = static_cast<FakeContentLayerImpl*>( |
| 631 root->children()[0]); | 822 root->children()[0]); |
| 632 FakeContentLayerImpl* grandchild = static_cast<FakeContentLayerImpl*>( | 823 FakeContentLayerImpl* grandchild = static_cast<FakeContentLayerImpl*>( |
| 633 child->children()[0]); | 824 child->children()[0]); |
| 634 | 825 |
| 635 ++num_commits_; | 826 ++num_commits_; |
| 636 switch (num_commits_) { | 827 switch (num_commits_) { |
| 637 case 1: | 828 case 1: |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 | 971 |
| 781 m_layerTreeHost->setRootLayer(root_); | 972 m_layerTreeHost->setRootLayer(root_); |
| 782 LayerTreeHostContextTest::setupTree(); | 973 LayerTreeHostContextTest::setupTree(); |
| 783 } | 974 } |
| 784 | 975 |
| 785 virtual void beginTest() OVERRIDE { | 976 virtual void beginTest() OVERRIDE { |
| 786 postSetNeedsCommitToMainThread(); | 977 postSetNeedsCommitToMainThread(); |
| 787 } | 978 } |
| 788 | 979 |
| 789 virtual void commitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { | 980 virtual void commitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { |
| 981 LayerTreeHostContextTest::commitCompleteOnThread(host_impl); |
| 982 |
| 790 ResourceProvider* resource_provider = host_impl->resourceProvider(); | 983 ResourceProvider* resource_provider = host_impl->resourceProvider(); |
| 791 | 984 |
| 792 if (host_impl->activeTree()->source_frame_number() == 0) { | 985 if (host_impl->activeTree()->source_frame_number() == 0) { |
| 793 // Set up impl resources on the first commit. | 986 // Set up impl resources on the first commit. |
| 794 | 987 |
| 795 scoped_ptr<TestRenderPass> pass_for_quad = TestRenderPass::Create(); | 988 scoped_ptr<TestRenderPass> pass_for_quad = TestRenderPass::Create(); |
| 796 pass_for_quad->SetNew( | 989 pass_for_quad->SetNew( |
| 797 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id. | 990 // AppendOneOfEveryQuadType() makes a RenderPass quad with this id. |
| 798 RenderPass::Id(1, 1), | 991 RenderPass::Id(1, 1), |
| 799 gfx::Rect(0, 0, 10, 10), | 992 gfx::Rect(0, 0, 10, 10), |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 scrollbar_layer_->setBounds(gfx::Size(10, 100)); | 1181 scrollbar_layer_->setBounds(gfx::Size(10, 100)); |
| 989 m_layerTreeHost->rootLayer()->addChild(scrollbar_layer_); | 1182 m_layerTreeHost->rootLayer()->addChild(scrollbar_layer_); |
| 990 m_layerTreeHost->rootLayer()->addChild(scroll_layer); | 1183 m_layerTreeHost->rootLayer()->addChild(scroll_layer); |
| 991 postSetNeedsCommitToMainThread(); | 1184 postSetNeedsCommitToMainThread(); |
| 992 } | 1185 } |
| 993 | 1186 |
| 994 virtual void afterTest() OVERRIDE { | 1187 virtual void afterTest() OVERRIDE { |
| 995 } | 1188 } |
| 996 | 1189 |
| 997 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { | 1190 virtual void commitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { |
| 1191 LayerTreeHostContextTest::commitCompleteOnThread(impl); |
| 1192 |
| 998 ++commits_; | 1193 ++commits_; |
| 999 size_t upload_count = scrollbar_layer_->last_update_full_upload_size() + | 1194 size_t upload_count = scrollbar_layer_->last_update_full_upload_size() + |
| 1000 scrollbar_layer_->last_update_partial_upload_size(); | 1195 scrollbar_layer_->last_update_partial_upload_size(); |
| 1001 switch(commits_) { | 1196 switch(commits_) { |
| 1002 case 1: | 1197 case 1: |
| 1003 // First (regular) update, we should upload 2 resources (thumb, and | 1198 // First (regular) update, we should upload 2 resources (thumb, and |
| 1004 // backtrack). | 1199 // backtrack). |
| 1005 EXPECT_EQ(1, scrollbar_layer_->update_count()); | 1200 EXPECT_EQ(1, scrollbar_layer_->update_count()); |
| 1006 EXPECT_EQ(2, upload_count); | 1201 EXPECT_EQ(2, upload_count); |
| 1007 LoseContext(); | 1202 LoseContext(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1020 | 1215 |
| 1021 private: | 1216 private: |
| 1022 int commits_; | 1217 int commits_; |
| 1023 scoped_refptr<FakeScrollbarLayer> scrollbar_layer_; | 1218 scoped_refptr<FakeScrollbarLayer> scrollbar_layer_; |
| 1024 }; | 1219 }; |
| 1025 | 1220 |
| 1026 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext) | 1221 SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext) |
| 1027 | 1222 |
| 1028 } // namespace | 1223 } // namespace |
| 1029 } // namespace cc | 1224 } // namespace cc |
| OLD | NEW |