layer_tree_host_unittest_context.cc revision 010d83a9304c5a91596085d917d248abff47903a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/content_layer.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/layers/delegated_frame_provider.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/layers/delegated_frame_resource_collection.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/heads_up_display_layer.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/io_surface_layer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/layers/painted_scrollbar_layer.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/picture_layer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/texture_layer.h"
17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "cc/layers/texture_layer_impl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_layer.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/video_layer_impl.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/output/filter_operations.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_content_layer.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_content_layer_client.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_content_layer_impl.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_delegated_renderer_layer.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_delegated_renderer_layer_impl.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/fake_layer_tree_host_client.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_output_surface.h"
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "cc/test/fake_output_surface_client.h"
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/test/fake_painted_scrollbar_layer.h"
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "cc/test/fake_scoped_ui_resource.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/test/fake_scrollbar.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_video_frame_provider.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/layer_tree_test.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/render_pass_test_common.h"
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "cc/test/test_context_provider.h"
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "cc/test/test_shared_bitmap_manager.h"
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "cc/test/test_web_graphics_context_3d.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host_impl.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using media::VideoFrame;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// These tests deal with losing the 3d graphics context.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LayerTreeHostContextTest : public LayerTreeTest {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostContextTest()
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : LayerTreeTest(),
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        context3d_(NULL),
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        times_to_fail_create_(0),
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        times_to_lose_during_commit_(0),
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        times_to_lose_during_draw_(0),
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        times_to_fail_recreate_(0),
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        times_to_expect_create_failed_(0),
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        times_create_failed_(0),
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        committed_at_least_once_(false),
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        context_should_support_io_surface_(false),
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        fallback_context_works_(false) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    media::InitializeMediaLibraryForTesting();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LoseContext() {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    GL_INNOCENT_CONTEXT_RESET_ARB);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context3d_ = NULL;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return TestWebGraphicsContext3D::Create();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      OVERRIDE {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (times_to_fail_create_) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      --times_to_fail_create_;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ExpectCreateToFail();
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return scoped_ptr<FakeOutputSurface>();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d();
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context3d_ = context3d.get();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (context_should_support_io_surface_) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      context3d_->set_have_extension_io_surface(true);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      context3d_->set_have_extension_egl_image(true);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (delegating_renderer())
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return FakeOutputSurface::CreateDelegating3d(context3d.Pass());
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return FakeOutputSurface::Create3d(context3d.Pass());
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl* host_impl,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl::FrameData* frame,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!times_to_lose_during_draw_)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return draw_result;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    --times_to_lose_during_draw_;
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LoseContext();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_fail_create_ = times_to_fail_recreate_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_fail_recreate_ = 0;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return draw_result;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    committed_at_least_once_ = true;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!times_to_lose_during_commit_)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    --times_to_lose_during_commit_;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoseContext();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_fail_create_ = times_to_fail_recreate_;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_fail_recreate_ = 0;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DidFailToInitializeOutputSurface() OVERRIDE {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++times_create_failed_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeTest::TearDown();
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(times_to_expect_create_failed_, times_create_failed_);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ExpectCreateToFail() { ++times_to_expect_create_failed_; }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestWebGraphicsContext3D* context3d_;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int times_to_fail_create_;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int times_to_lose_during_commit_;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int times_to_lose_during_draw_;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int times_to_fail_recreate_;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int times_to_expect_create_failed_;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int times_create_failed_;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool committed_at_least_once_;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool context_should_support_io_surface_;
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool fallback_context_works_;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestLostContextSucceeds
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTest {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostContextTestLostContextSucceeds()
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : LayerTreeHostContextTest(),
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_case_(0),
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_losses_(0),
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        num_losses_last_test_case_(-1),
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        recovered_context_(true),
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        first_initialized_(false) {}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (first_initialized_)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ++num_losses_;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      first_initialized_ = true;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    recovered_context_ = true;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void AfterTest() OVERRIDE { EXPECT_EQ(7u, test_case_); }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the last frame had a context loss, then we'll commit again to
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // recover.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!recovered_context_)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (times_to_lose_during_commit_)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (times_to_lose_during_draw_)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    recovered_context_ = false;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (NextTestCase())
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InvalidateAndSetNeedsCommit();
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EndTest();
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InvalidateAndSetNeedsCommit() {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Cause damage so we try to draw.
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host()->root_layer()->SetNeedsDisplay();
196558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    layer_tree_host()->SetNeedsCommit();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool NextTestCase() {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static const TestCase kTests[] = {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Losing the context and failing to recreate it (or losing it again
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // immediately) a small number of times should succeed.
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {1,      // times_to_lose_during_commit
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_lose_during_draw
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_fail_recreate
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {0,      // times_to_lose_during_commit
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         1,      // times_to_lose_during_draw
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_fail_recreate
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {1,      // times_to_lose_during_commit
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_lose_during_draw
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         3,      // times_to_fail_recreate
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {0,      // times_to_lose_during_commit
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         1,      // times_to_lose_during_draw
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         3,      // times_to_fail_recreate
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Losing the context and recreating it any number of times should
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // succeed.
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {10,     // times_to_lose_during_commit
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_lose_during_draw
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_fail_recreate
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {0,      // times_to_lose_during_commit
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         10,     // times_to_lose_during_draw
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,      // times_to_fail_recreate
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         false,  // fallback_context_works
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        },
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Losing the context, failing to reinitialize it, and making a fallback
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // context should work.
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        {0,     // times_to_lose_during_commit
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         1,     // times_to_lose_during_draw
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         0,     // times_to_fail_recreate
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         true,  // fallback_context_works
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }, };
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (test_case_ >= arraysize(kTests))
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Make sure that we lost our context at least once in the last test run so
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // the test did something.
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_GT(num_losses_, num_losses_last_test_case_);
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    num_losses_last_test_case_ = num_losses_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_lose_during_commit_ =
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kTests[test_case_].times_to_lose_during_commit;
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    times_to_lose_during_draw_ = kTests[test_case_].times_to_lose_during_draw;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate;
254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    fallback_context_works_ = kTests[test_case_].fallback_context_works;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++test_case_;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int times_to_lose_during_commit;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int times_to_lose_during_draw;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int times_to_fail_recreate;
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool fallback_context_works;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t test_case_;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_losses_;
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int num_losses_last_test_case_;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool recovered_context_;
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool first_initialized_;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostContextTest {
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerTreeHostClientNotReadyDoesNotCreateOutputSurface()
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : LayerTreeHostContextTest() {}
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void WillBeginTest() OVERRIDE {
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Override and do not signal SetLayerTreeHostClientReady.
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EndTest();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(false);
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return scoped_ptr<OutputSurface>();
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE { EXPECT_TRUE(false); }
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface);
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestLostContextSucceedsWithContent
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTestLostContextSucceeds {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_ = Layer::Create();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_->SetBounds(gfx::Size(10, 10));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_->SetAnchorPoint(gfx::PointF());
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_->SetIsDrawable(true);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_ = FakeContentLayer::Create(&client_);
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_->SetBounds(gfx::Size(10, 10));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_->SetAnchorPoint(gfx::PointF());
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_->SetIsDrawable(true);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_->AddChild(content_);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InvalidateAndSetNeedsCommit() OVERRIDE {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Invalidate the render surface so we don't try to use a cached copy of the
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // surface.  We want to make sure to test the drawing paths for drawing to
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // a child surface.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content_->SetNeedsDisplay();
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>(
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        host_impl->active_tree()->root_layer()->children()[0]);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Even though the context was lost, we should have a resource. The
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TestWebGraphicsContext3D ensures that this resource is created with
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the active context.
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0));
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Layer> root_;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<ContentLayer> content_;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This test uses TiledLayer to check for a working context.
3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    LayerTreeHostContextTestLostContextSucceedsWithContent);
351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostContextTestCreateOutputSurfaceFails
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostContextTest {
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run a test that initially fails OutputSurface creation |times_to_fail|
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // times. If |expect_fallback_attempt| is |true|, an attempt to create a
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // fallback/software OutputSurface is expected to occur.
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail,
3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                   bool expect_fallback_attempt)
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : times_to_fail_(times_to_fail),
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        expect_fallback_attempt_(expect_fallback_attempt),
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        did_attempt_fallback_(false),
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        times_initialized_(0) {}
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    times_to_fail_create_ = times_to_fail_;
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<FakeOutputSurface> surface =
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        LayerTreeHostContextTest::CreateFakeOutputSurface(fallback);
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (surface)
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(times_to_fail_, times_create_failed_);
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    did_attempt_fallback_ = fallback;
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return surface.Pass();
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE { times_initialized_++; }
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EndTest();
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(times_to_fail_, times_create_failed_);
3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_NE(0, times_initialized_);
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expect_fallback_attempt_, did_attempt_fallback_);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int times_to_fail_;
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool expect_fallback_attempt_;
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_attempt_fallback_;
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int times_initialized_;
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostContextTestCreateOutputSurfaceFails {
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerTreeHostContextTestCreateOutputSurfaceFailsOnce()
4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false) {}
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostContextTestCreateOutputSurfaceFailsOnce);
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// After 4 failures we expect an attempt to create a fallback/software
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// OutputSurface.
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostContextTestCreateOutputSurfaceFails {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback()
4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true) {}
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback);
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestLostContextAndEvictTextures
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTest {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostContextTestLostContextAndEvictTextures()
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : LayerTreeHostContextTest(),
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_(FakeContentLayer::Create(&client_)),
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        impl_host_(0),
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        num_commits_(0) {}
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_->SetBounds(gfx::Size(10, 20));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetRootLayer(layer_);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PostEvictTextures() {
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (HasImplThread()) {
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ImplThreadTaskRunner()->PostTask(
443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          FROM_HERE,
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&LayerTreeHostContextTestLostContextAndEvictTextures::
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          EvictTexturesOnImplThread,
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Unretained(this)));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DebugScopedSetImplThread impl(proxy());
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EvictTexturesOnImplThread();
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void EvictTexturesOnImplThread() {
454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    impl_host_->EvictTexturesForTesting();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (lose_after_evict_)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoseContext();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_commits_ > 1)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(layer_->HaveBackingAt(0, 0));
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PostEvictTextures();
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_commits_ > 1)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++num_commits_;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!lose_after_evict_)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LoseContext();
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_host_ = impl;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE { EndTest(); }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool lose_after_evict_;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeContentLayer> layer_;
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostImpl* impl_host_;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_commits_;
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseAfterEvict_SingleThread_DirectRenderer) {
490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = true;
491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(false, false, false);
492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseAfterEvict_SingleThread_DelegatingRenderer) {
496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = true;
497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(false, true, false);
498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
500a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
501a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint) {
502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = true;
503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, false, false);
504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
505a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
506a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
507a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lose_after_evict_ = true;
509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, true, false);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Flaky on all platforms, http://crbug.com/310979
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
5141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lose_after_evict_ = true;
516a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, true, true);
517a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
518a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
519a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
520a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_SingleThread_DirectRenderer) {
521a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = false;
522a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(false, false, false);
523a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
525a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
526a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_SingleThread_DelegatingRenderer) {
527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = false;
528a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(false, true, false);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint) {
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lose_after_evict_ = false;
534a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, false, false);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
538a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lose_after_evict_ = false;
540a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, false, true);
541a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
542a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
543a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
544a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
545a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = false;
546a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, true, false);
547a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
548a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
549a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
550a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
551a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  lose_after_evict_ = false;
552a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RunTest(true, true, true);
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostContextTestLostContextWhileUpdatingResources
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTest {
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LayerTreeHostContextTestLostContextWhileUpdatingResources()
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : parent_(FakeContentLayer::Create(&client_)),
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_children_(50),
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        times_to_lose_on_end_query_(3) {}
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() OVERRIDE {
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TestWebGraphicsContext3D> context =
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LayerTreeHostContextTest::CreateContext3d();
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (times_to_lose_on_end_query_) {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      --times_to_lose_on_end_query_;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context->set_times_end_query_succeeds(5);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return context.Pass();
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parent_->SetBounds(gfx::Size(num_children_, 1));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < num_children_; i++) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<FakeContentLayer> child =
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FakeContentLayer::Create(&client_);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      child->SetPosition(gfx::PointF(i, 0.f));
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      child->SetBounds(gfx::Size(1, 1));
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parent_->AddChild(child);
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetRootLayer(parent_);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(0, times_to_lose_on_end_query_);
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EndTest();
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, times_to_lose_on_end_query_);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeContentLayer> parent_;
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_children_;
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int times_to_lose_on_end_query_;
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostContextTestLostContextWhileUpdatingResources);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeHostContextTestLayersNotified()
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : LayerTreeHostContextTest(), num_commits_(0) {}
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_ = FakeContentLayer::Create(&client_);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    grandchild_ = FakeContentLayer::Create(&client_);
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_->AddChild(child_);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_->AddChild(grandchild_);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FakeContentLayerImpl* root = static_cast<FakeContentLayerImpl*>(
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        host_impl->active_tree()->root_layer());
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeContentLayerImpl* child =
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<FakeContentLayerImpl*>(root->children()[0]);
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeContentLayerImpl* grandchild =
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<FakeContentLayerImpl*>(child->children()[0]);
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++num_commits_;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (num_commits_) {
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case 1:
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(0u, root->lost_output_surface_count());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(0u, child->lost_output_surface_count());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(0u, grandchild->lost_output_surface_count());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Lose the context and struggle to recreate it.
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LoseContext();
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        times_to_fail_create_ = 1;
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case 2:
649a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_GE(1u, root->lost_output_surface_count());
650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_GE(1u, child->lost_output_surface_count());
651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_GE(1u, grandchild->lost_output_surface_count());
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EndTest();
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_commits_;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeContentLayer> child_;
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeContentLayer> grandchild_;
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified);
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestDontUseLostResources
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTest {
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerTreeHostContextTestDontUseLostResources() : lost_context_(false) {
6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    context_should_support_io_surface_ = true;
6778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    child_output_surface_ = FakeOutputSurface::Create3d();
6798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    child_output_surface_->BindToClient(&output_surface_client_);
68023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    child_resource_provider_ = ResourceProvider::Create(
682010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
683010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        false);
6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static void EmptyReleaseCallback(unsigned sync_point, bool lost) {}
6878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gpu::gles2::GLES2Interface* gl =
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        child_output_surface_->context_provider()->ContextGL();
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
6938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<TestRenderPass> pass_for_quad = TestRenderPass::Create();
6958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    pass_for_quad->SetNew(
6968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        // AppendOneOfEveryQuadType() makes a RenderPass quad with this id.
6978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        RenderPass::Id(2, 1),
6988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        gfx::Rect(0, 0, 10, 10),
6998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        gfx::Rect(0, 0, 10, 10),
7008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        gfx::Transform());
7018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
7038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    pass->SetNew(RenderPass::Id(1, 1),
7048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 gfx::Rect(0, 0, 10, 10),
7058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 gfx::Rect(0, 0, 10, 10),
7068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 gfx::Transform());
7078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    pass->AppendOneOfEveryQuadType(child_resource_provider_.get(),
7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                   RenderPass::Id(2, 1));
7098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    frame_data->render_pass_list.push_back(pass_for_quad.PassAs<RenderPass>());
7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    frame_data->render_pass_list.push_back(pass.PassAs<RenderPass>());
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delegated_resource_collection_ = new DelegatedFrameResourceCollection;
7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delegated_frame_provider_ = new DelegatedFrameProvider(
7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        delegated_resource_collection_.get(), frame_data.Pass());
7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ResourceProvider::ResourceId resource =
7188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        child_resource_provider_->CreateResource(
7198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            gfx::Size(4, 4),
7208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            GL_CLAMP_TO_EDGE,
7218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            ResourceProvider::TextureUsageAny,
7228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            RGBA_8888);
7238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(),
7248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                             resource);
7258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    gpu::Mailbox mailbox;
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gl->GenMailboxCHROMIUM(mailbox.name);
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<Layer> root = Layer::Create();
7318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    root->SetBounds(gfx::Size(10, 10));
7328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    root->SetAnchorPoint(gfx::PointF());
7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    root->SetIsDrawable(true);
7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<FakeDelegatedRendererLayer> delegated =
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FakeDelegatedRendererLayer::Create(delegated_frame_provider_.get());
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delegated->SetBounds(gfx::Size(10, 10));
7384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delegated->SetAnchorPoint(gfx::PointF());
7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    delegated->SetIsDrawable(true);
7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(delegated);
7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<ContentLayer> content = ContentLayer::Create(&client_);
7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content->SetBounds(gfx::Size(10, 10));
7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content->SetAnchorPoint(gfx::PointF());
7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content->SetIsDrawable(true);
7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(content);
7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<TextureLayer> texture = TextureLayer::CreateForMailbox(NULL);
7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    texture->SetBounds(gfx::Size(10, 10));
7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    texture->SetAnchorPoint(gfx::PointF());
7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    texture->SetIsDrawable(true);
7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    texture->SetTextureMailbox(
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SingleReleaseCallback::Create(
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::Bind(&LayerTreeHostContextTestDontUseLostResources::
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            EmptyReleaseCallback)));
7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(texture);
7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client_);
7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    mask->SetBounds(gfx::Size(10, 10));
7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    mask->SetAnchorPoint(gfx::PointF());
7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<ContentLayer> content_with_mask =
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ContentLayer::Create(&client_);
7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content_with_mask->SetBounds(gfx::Size(10, 10));
7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content_with_mask->SetAnchorPoint(gfx::PointF());
7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content_with_mask->SetIsDrawable(true);
7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content_with_mask->SetMaskLayer(mask.get());
7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(content_with_mask);
7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<VideoLayer> video_color =
7724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        VideoLayer::Create(&color_frame_provider_);
7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_color->SetBounds(gfx::Size(10, 10));
7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_color->SetAnchorPoint(gfx::PointF());
7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_color->SetIsDrawable(true);
7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(video_color);
7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<VideoLayer> video_hw =
7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        VideoLayer::Create(&hw_frame_provider_);
7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_hw->SetBounds(gfx::Size(10, 10));
7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_hw->SetAnchorPoint(gfx::PointF());
7824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_hw->SetIsDrawable(true);
7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(video_hw);
7844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<VideoLayer> video_scaled_hw =
7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        VideoLayer::Create(&scaled_hw_frame_provider_);
7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_scaled_hw->SetBounds(gfx::Size(10, 10));
7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_scaled_hw->SetAnchorPoint(gfx::PointF());
7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    video_scaled_hw->SetIsDrawable(true);
7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(video_scaled_hw);
791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
7928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    color_video_frame_ = VideoFrame::CreateColorFrame(
7938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    hw_video_frame_ =
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        VideoFrame::WrapNativeTexture(make_scoped_ptr(new gpu::MailboxHolder(
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          mailbox, GL_TEXTURE_2D, sync_point)),
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      media::VideoFrame::ReleaseMailboxCB(),
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Size(4, 4),
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Rect(0, 0, 4, 4),
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Size(4, 4),
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::TimeDelta(),
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      VideoFrame::ReadPixelsCB());
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scaled_hw_video_frame_ =
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        VideoFrame::WrapNativeTexture(make_scoped_ptr(new gpu::MailboxHolder(
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          mailbox, GL_TEXTURE_2D, sync_point)),
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      media::VideoFrame::ReleaseMailboxCB(),
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Size(4, 4),
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Rect(0, 0, 3, 2),
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      gfx::Size(4, 4),
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::TimeDelta(),
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      VideoFrame::ReadPixelsCB());
8128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    color_frame_provider_.set_frame(color_video_frame_);
8148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    hw_frame_provider_.set_frame(hw_video_frame_);
8158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scaled_hw_frame_provider_.set_frame(scaled_hw_video_frame_);
8168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!delegating_renderer()) {
818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      // TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_refptr<IOSurfaceLayer> io_surface = IOSurfaceLayer::Create();
8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      io_surface->SetBounds(gfx::Size(10, 10));
8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      io_surface->SetAnchorPoint(gfx::PointF());
8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      io_surface->SetIsDrawable(true);
8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      io_surface->SetIOSurfaceProperties(1, gfx::Size(10, 10));
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      root->AddChild(io_surface);
825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Enable the hud.
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeDebugState debug_state;
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    debug_state.show_property_changed_rects = true;
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetDebugState(debug_state);
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<PaintedScrollbarLayer> scrollbar =
8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        PaintedScrollbarLayer::Create(
8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            scoped_ptr<Scrollbar>(new FakeScrollbar).Pass(), content->id());
8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scrollbar->SetBounds(gfx::Size(10, 10));
8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scrollbar->SetAnchorPoint(gfx::PointF());
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scrollbar->SetIsDrawable(true);
8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    root->AddChild(scrollbar);
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host()->SetRootLayer(root);
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(host_impl);
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (host_impl->active_tree()->source_frame_number() == 3) {
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // On the third commit we're recovering from context loss. Hardware
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // video frames should not be reused by the VideoFrameProvider, but
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // software frames can be.
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hw_frame_provider_.set_frame(NULL);
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scaled_hw_frame_provider_.set_frame(NULL);
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl* host_impl,
8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl::FrameData* frame,
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (host_impl->active_tree()->source_frame_number() == 2) {
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Lose the context during draw on the second commit. This will cause
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // a third commit to recover.
8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      context3d_->set_times_bind_texture_succeeds(0);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return draw_result;
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This will get called twice:
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // First when we create the initial output surface...
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (layer_tree_host()->source_frame_number() > 0) {
875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // ... and then again after we forced the context to be lost.
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      lost_context_ = true;
8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return LayerTreeHostContextTest::CreateFakeOutputSurface(fallback);
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE {
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(layer_tree_host()->hud_layer());
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // End the test once we know the 3nd frame drew.
884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (layer_tree_host()->source_frame_number() < 5) {
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      layer_tree_host()->root_layer()->SetNeedsDisplay();
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host()->SetNeedsCommit();
8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      EndTest();
8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(lost_context_); }
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
8964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool lost_context_;
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FakeOutputSurfaceClient output_surface_client_;
8998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<FakeOutputSurface> child_output_surface_;
90023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
9018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<ResourceProvider> child_resource_provider_;
9028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
9034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<DelegatedFrameResourceCollection>
9044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      delegated_resource_collection_;
9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<DelegatedFrameProvider> delegated_frame_provider_;
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<VideoFrame> color_video_frame_;
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<VideoFrame> hw_video_frame_;
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<VideoFrame> scaled_hw_video_frame_;
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeVideoFrameProvider color_frame_provider_;
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeVideoFrameProvider hw_frame_provider_;
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeVideoFrameProvider scaled_hw_frame_provider_;
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources);
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public LayerTreeHostContextTest {
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void BeginTest() OVERRIDE {
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // This must be called immediately after creating LTH, before the first
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // OutputSurface is initialized.
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(layer_tree_host()->output_surface_lost());
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    times_output_surface_created_ = 0;
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Post the SetNeedsCommit before the readback to make sure it is run
9291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // on the main thread before the readback's replacement commit when
9301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // we have a threaded compositor.
9311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
9321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char pixels[4];
9345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool result =
9355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(1, 1));
936a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_EQ(!delegating_renderer(), result);
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, times_output_surface_created_);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE {
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++times_output_surface_created_;
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE { EndTest(); }
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Should not try to create output surface again after successfully
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // created by CompositeAndReadback.
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1, times_output_surface_created_);
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl* host_impl,
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl::FrameData* frame_data,
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
95658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_GE(host_impl->active_tree()->source_frame_number(), 0);
95758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_LE(host_impl->active_tree()->source_frame_number(), 1);
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return draw_result;
95958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
96058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
96158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
96258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only draw for the readback and the replacement commit.
96358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The replacement commit will also be the first commit after output
96458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // surface initialization.
96558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_GE(host_impl->active_tree()->source_frame_number(), 0);
96658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_LE(host_impl->active_tree()->source_frame_number(), 1);
96758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
96858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
96958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
97058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool result) OVERRIDE {
97158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only swap for the replacement commit.
97258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 1);
97358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EndTest();
97458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
97558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int times_output_surface_created_;
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit);
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
98358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This test verifies that losing an output surface during a
98458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// simultaneous readback and forced redraw works and does not deadlock.
98558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw
98658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : public LayerTreeHostContextTest {
98758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
98858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kFirstOutputSurfaceInitSourceFrameNumber = 0;
98958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kReadbackSourceFrameNumber = 1;
99058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kReadbackReplacementSourceFrameNumber = 2;
99158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kSecondOutputSurfaceInitSourceFrameNumber = 3;
99258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
99358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw()
99458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      : did_react_to_first_commit_(false) {}
99558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
99658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
99758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // This enables forced draws after a single prepare to draw failure.
99858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings->timeout_and_draw_when_animation_checkerboards = true;
99958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
100058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
100158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
100258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
100358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl* host_impl,
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl::FrameData* frame_data,
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
100858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
100958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kFirstOutputSurfaceInitSourceFrameNumber ||
101058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kSecondOutputSurfaceInitSourceFrameNumber ||
101158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kReadbackSourceFrameNumber)
101258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
101358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
101458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Before we react to the failed draw by initiating the forced draw
101558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // sequence, start a readback on the main thread and then lose the context
101658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // to start output surface initialization all at the same time.
101758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (sfn == kFirstOutputSurfaceInitSourceFrameNumber &&
101858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !did_react_to_first_commit_) {
101958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      did_react_to_first_commit_ = true;
102058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      PostReadbackToMainThread();
102158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      LoseContext();
102258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
102358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
102558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
102658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
102758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
102858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           bool success) OVERRIDE {
102958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // -1 is for the first output surface initialization.
103058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
103158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == -1 || sfn == kReadbackReplacementSourceFrameNumber)
103258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
103358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
103458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
103558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
103658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only draw the first commit after output surface initialization
103758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // and attempt to draw the readback commit (which will fail).
103858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // All others should abort because the output surface is lost.
103958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
104058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kSecondOutputSurfaceInitSourceFrameNumber ||
104158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kReadbackSourceFrameNumber)
104258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
104358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
104458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
104558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
104658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool result) OVERRIDE {
104758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only swap the first commit after the second output surface
104858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // initialization.
104958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
105058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kSecondOutputSurfaceInitSourceFrameNumber) << sfn;
105158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EndTest();
105258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
105358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
105458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
105558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
105658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int did_react_to_first_commit_;
105758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
105858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
105958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MULTI_THREAD_TEST_F(
106058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTestLoseOutputSurfaceDuringReadbackAndForcedDraw);
106158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
106258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This test verifies that losing an output surface right before a
106358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// simultaneous readback and forced redraw works and does not deadlock.
106458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit
106558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : public LayerTreeHostContextTest {
106658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
106758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kFirstOutputSurfaceInitSourceFrameNumber = 0;
106858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kReadbackSourceFrameNumber = 1;
106958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kForcedDrawCommitSourceFrameNumber = 2;
107058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const int kSecondOutputSurfaceInitSourceFrameNumber = 2;
107158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
107258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit()
107358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      : did_lose_context_(false) {}
107458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
107558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
107658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // This enables forced draws after a single prepare to draw failure.
107758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings->timeout_and_draw_when_animation_checkerboards = true;
107858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
107958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
108058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
108158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
108258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl* host_impl,
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostImpl::FrameData* frame_data,
10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
108758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
108858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kFirstOutputSurfaceInitSourceFrameNumber ||
108958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kSecondOutputSurfaceInitSourceFrameNumber ||
109058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kReadbackSourceFrameNumber)
109158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
109258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
109358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Before we react to the failed draw by initiating the forced draw
109458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // sequence, start a readback on the main thread and then lose the context
109558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // to start output surface initialization all at the same time.
109658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (sfn == kFirstOutputSurfaceInitSourceFrameNumber && !did_lose_context_) {
109758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      did_lose_context_ = true;
109858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      LoseContext();
109958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
110058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Returning false will result in a forced draw.
11025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
110358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
110458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE {
110658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (layer_tree_host()->source_frame_number() > 0) {
110758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Perform a readback right after the second output surface
110858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // initialization.
110958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      char pixels[4];
111058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
111158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
111258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
111358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
111458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
111558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           bool success) OVERRIDE {
111658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // -1 is for the first output surface initialization.
111758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
111858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == -1 || sfn == kFirstOutputSurfaceInitSourceFrameNumber)
111958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
112058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
112158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
112258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
112358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only draw the first commit after output surface initialization
112458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // and attempt to draw the readback commit (which will fail).
112558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // All others should abort because the output surface is lost.
112658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
112758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kForcedDrawCommitSourceFrameNumber ||
112858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                sfn == kReadbackSourceFrameNumber)
112958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        << sfn;
113058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
113158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
113258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
113358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   bool result) OVERRIDE {
113458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // We should only swap the first commit after the second output surface
113558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // initialization.
113658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int sfn = host_impl->active_tree()->source_frame_number();
113758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(sfn == kForcedDrawCommitSourceFrameNumber) << sfn;
113858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EndTest();
113958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
114058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
114158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
114258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
114358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int did_lose_context_;
114458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
114558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
114658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MULTI_THREAD_TEST_F(
114758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTestReadbackWithForcedDrawAndOutputSurfaceInit);
114858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ImplSidePaintingLayerTreeHostContextTest
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public LayerTreeHostContextTest {
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings->impl_side_painting = true;
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerTreeHostContextTestImplSidePainting
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public ImplSidePaintingLayerTreeHostContextTest {
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<Layer> root = Layer::Create();
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->SetBounds(gfx::Size(10, 10));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->SetAnchorPoint(gfx::PointF());
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->SetIsDrawable(true);
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<PictureLayer> picture = PictureLayer::Create(&client_);
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    picture->SetBounds(gfx::Size(10, 10));
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    picture->SetAnchorPoint(gfx::PointF());
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    picture->SetIsDrawable(true);
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->AddChild(picture);
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->SetRootLayer(root);
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BeginTest() OVERRIDE {
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    times_to_lose_during_commit_ = 1;
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PostSetNeedsCommitToMainThread();
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void DidInitializeOutputSurface() OVERRIDE { EndTest(); }
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeContentLayerClient client_;
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting);
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScrollbarLayerLostContext : public LayerTreeHostContextTest {
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollbarLayerLostContext() : commits_(0) {}
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BeginTest() OVERRIDE {
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<Layer> scroll_layer = Layer::Create();
11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scrollbar_layer_ =
11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FakePaintedScrollbarLayer::Create(false, true, scroll_layer->id());
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scrollbar_layer_->SetBounds(gfx::Size(10, 100));
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->root_layer()->AddChild(scrollbar_layer_);
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host()->root_layer()->AddChild(scroll_layer);
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PostSetNeedsCommitToMainThread();
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++commits_;
1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (commits_) {
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case 1:
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // First (regular) update, we should upload 2 resources (thumb, and
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // backtrack).
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(1, scrollbar_layer_->update_count());
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LoseContext();
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case 2:
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Second update, after the lost context, we should still upload 2
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // resources even if the contents haven't changed.
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(2, scrollbar_layer_->update_count());
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EndTest();
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
122458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 3:
122558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Single thread proxy issues extra commits after context lost.
122658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // http://crbug.com/287250
122758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (HasImplThread())
122858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          NOTREACHED();
122958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int commits_;
12373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext);
1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class UIResourceLostTest : public LayerTreeHostContextTest {
1243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
1244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UIResourceLostTest() : time_step_(0) {}
12450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
12460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    settings->texture_id_allocation_chunk_size = 1;
12470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
1250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
125158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is called on the main thread after each commit and
125258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // DidActivateTreeOnThread, with the value of time_step_ at the time
125358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // of the call to DidActivateTreeOnThread. Similar tests will do
125458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // work on the main thread in DidCommit but that is unsuitable because
125558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the main thread work for these tests must happen after
125658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // DidActivateTreeOnThread, which happens after DidCommit with impl-side
125758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // painting.
125858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnMainThread(int time_step) = 0;
125958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
126058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Called after DidActivateTreeOnThread. If this is done during the commit,
126158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the call to StepCompleteOnMainThread will not occur until after
126258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the commit completes, because the main thread is blocked.
126358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void PostStepCompleteToMainThread() {
126458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    proxy()->MainThreadTaskRunner()->PostTask(
126558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE,
12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&UIResourceLostTest::StepCompleteOnMainThreadInternal,
12675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this),
12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   time_step_));
126958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
127058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
127158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void PostLoseContextToImplThread() {
127258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
127358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::SingleThreadTaskRunner* task_runner =
127458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        HasImplThread() ? ImplThreadTaskRunner()
127558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        : base::MessageLoopProxy::current();
12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task_runner->PostTask(FROM_HERE,
12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          base::Bind(&LayerTreeHostContextTest::LoseContext,
12785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     base::Unretained(this)));
127958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
128058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) protected:
1282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int time_step_;
1283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<FakeScopedUIResource> ui_resource_;
128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void StepCompleteOnMainThreadInternal(int step) {
128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    StepCompleteOnMainThread(step);
128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
129258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class UIResourceLostTestSimple : public UIResourceLostTest {
1293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
129458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is called when the commit is complete and the new layer tree has been
129558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // activated.
129658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) = 0;
129758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
129958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!layer_tree_host()->settings().impl_side_painting) {
130058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      StepCompleteOnImplThread(impl);
130158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      PostStepCompleteToMainThread();
130258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ++time_step_;
130358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
130458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
130558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
130658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
130758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (layer_tree_host()->settings().impl_side_painting) {
130858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      StepCompleteOnImplThread(impl);
130958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      PostStepCompleteToMainThread();
131058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ++time_step_;
131158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
131258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
131358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
131458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
131558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Losing context after an UI resource has been created.
131658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class UIResourceLostAfterCommit : public UIResourceLostTestSimple {
131758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
131858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnMainThread(int step) OVERRIDE {
131958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
132058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (step) {
1321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 0:
1322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
1323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Expects a valid UIResourceId.
1324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_NE(0, ui_resource_->id());
1325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
132758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 4:
132858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Release resource before ending the test.
132958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ui_resource_.reset();
133058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EndTest();
133158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
133258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 5:
133358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Single thread proxy issues extra commits after context lost.
133458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // http://crbug.com/287250
133558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (HasImplThread())
133658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          NOTREACHED();
133758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
133858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 6:
133958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NOTREACHED();
134058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
134158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
134258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
134358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE {
134458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
134558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (time_step_) {
1346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 1:
1347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resource should have been created on LTHI after the commit.
134858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 2:
1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        LoseContext();
1353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 3:
1355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resources should have been recreated. The bitmap callback should
1356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // have been called once with the resource_lost flag set to true.
1357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(1, ui_resource_->lost_resource_count);
1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Resource Id on the impl-side have been recreated as well. Note
1359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // that the same UIResourceId persists after the context lost.
136058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
1361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit);
1368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Losing context before UI resource requests can be commited.  Three sequences
1370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// of creation/deletion are considered:
1371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 1. Create one resource -> Context Lost => Expect the resource to have been
1372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// created.
1373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 2. Delete an exisiting resource (test_id0_) -> create a second resource
1374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and
1375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// test_id1_ to have been created.
1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// 3. Create one resource -> Delete that same resource -> Context Lost => Expect
1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// the resource to not exist in the manager.
137858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
1379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
13805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UIResourceLostBeforeCommit() : test_id0_(0), test_id1_(0) {}
1381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
138258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnMainThread(int step) OVERRIDE {
138358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (step) {
1384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 0:
1385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
138658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Lose the context on the impl thread before the commit.
138758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostLoseContextToImplThread();
1388a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1389a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 2:
1390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Sequence 2:
1391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Currently one resource has been created.
1392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        test_id0_ = ui_resource_->id();
1393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Delete this resource.
1394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_.reset();
1395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Create another resource.
1396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
1397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        test_id1_ = ui_resource_->id();
1398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Sanity check that two resource creations return different ids.
1399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_NE(test_id0_, test_id1_);
140058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Lose the context on the impl thread before the commit.
140158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostLoseContextToImplThread();
1402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 3:
1404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Clear the manager of resources.
1405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_.reset();
1406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 4:
1409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Sequence 3:
1410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
1411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        test_id0_ = ui_resource_->id();
1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Sanity check the UIResourceId should not be 0.
1413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_NE(0, test_id0_);
1414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // Usually ScopedUIResource are deleted from the manager in their
1415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // destructor (so usually ui_resource_.reset()).  But here we need
1416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // ui_resource_ for the next step, so call DeleteUIResource directly.
1417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        layer_tree_host()->DeleteUIResource(test_id0_);
141858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Delete the resouce and then lose the context.
141958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostLoseContextToImplThread();
1420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 5:
142258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Release resource before ending the test.
1423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_.reset();
1424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EndTest();
1425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
142658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 6:
142758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Single thread proxy issues extra commits after context lost.
142858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // http://crbug.com/287250
142958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (HasImplThread())
143058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          NOTREACHED();
143158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
143258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 8:
143358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NOTREACHED();
1434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
143758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE {
143858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    switch (time_step_) {
1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 1:
144158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Sequence 1 (continued):
144258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The first context lost happens before the resources were created,
144358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // and because it resulted in no resources being destroyed, it does not
144458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // trigger resource re-creation.
144558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->resource_create_count);
144658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0, ui_resource_->lost_resource_count);
144758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Resource Id on the impl-side has been created.
144858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostSetNeedsCommitToMainThread();
1449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 3:
145158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Sequence 2 (continued):
145258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The previous resource should have been deleted.
145358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_));
145458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (HasImplThread()) {
145558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          // The second resource should have been created.
1456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_));
145758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else {
145858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          // The extra commit that happens at context lost in the single thread
145958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          // proxy changes the timing so that the resource has been destroyed.
146058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          // http://crbug.com/287250
146158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id1_));
1462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        }
146358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The second resource called the resource callback once and since the
146458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // context is lost, a "resource lost" callback was also issued.
146558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(2, ui_resource_->resource_create_count);
146658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->lost_resource_count);
1467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 5:
146958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Sequence 3 (continued):
147058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Expect the resource callback to have been called once.
147158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->resource_create_count);
147258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // No "resource lost" callbacks.
147358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0, ui_resource_->lost_resource_count);
147458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The UI resource id should not be valid
147558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_));
1476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
1481a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UIResourceId test_id0_;
1482a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UIResourceId test_id1_;
1483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1484a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1485a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit);
1486a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1487a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Losing UI resource before the pending trees is activated but after the
1488a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// commit.  Impl-side-painting only.
1489a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class UIResourceLostBeforeActivateTree : public UIResourceLostTest {
149058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnMainThread(int step) OVERRIDE {
149158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
149258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (step) {
1493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 0:
1494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
1495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 3:
1498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        test_id_ = ui_resource_->id();
1499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ui_resource_.reset();
1500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        PostSetNeedsCommitToMainThread();
1501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 5:
150358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Release resource before ending the test.
150458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ui_resource_.reset();
1505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EndTest();
1506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
150758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 6:
150858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Make sure no extra commits happened.
150958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NOTREACHED();
1510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
151358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
151458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
1515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    switch (time_step_) {
151658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 2:
151758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostSetNeedsCommitToMainThread();
1518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
151958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 4:
152058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostSetNeedsCommitToMainThread();
152158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
152258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
152358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
152458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
152558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
152658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (time_step_) {
1527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 1:
1528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resource creation callback has been called.
1529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(1, ui_resource_->resource_create_count);
1530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resource is not yet lost (sanity check).
1531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(0, ui_resource_->lost_resource_count);
1532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resource should not have been created yet on the impl-side.
1533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
1534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        LoseContext();
1535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 3:
1537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        LoseContext();
1538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    LayerTreeHostContextTest::DidActivateTreeOnThread(impl);
1544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    switch (time_step_) {
1545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 1:
1546a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The pending requests on the impl-side should have been processed.
1547a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
1548a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 2:
1550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The "lost resource" callback should have been called once.
1551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(1, ui_resource_->lost_resource_count);
1552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case 4:
1554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The resource is deleted and should not be in the manager.  Use
1555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // test_id_ since ui_resource_ has been deleted.
1556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id_));
1557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        break;
1558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
155958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
156058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PostStepCompleteToMainThread();
1561a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ++time_step_;
1562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
1565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UIResourceId test_id_;
1566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
1567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(UIResourceLostBeforeActivateTree,
1569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       RunMultiThread_DirectRenderer_ImplSidePaint) {
1570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunTest(true, false, true);
1571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(UIResourceLostBeforeActivateTree,
1574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       RunMultiThread_DelegatingRenderer_ImplSidePaint) {
1575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RunTest(true, true, true);
1576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
157858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Resources evicted explicitly and by visibility changes.
157958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class UIResourceLostEviction : public UIResourceLostTestSimple {
158058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
158158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnMainThread(int step) OVERRIDE {
158258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
158358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (step) {
158458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 0:
158558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
158658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0, ui_resource_->id());
158758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostSetNeedsCommitToMainThread();
158858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
158958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 2:
159058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Make the tree not visible.
159158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PostSetVisibleToMainThread(false);
159258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
159358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 3:
159458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Release resource before ending the test.
159558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ui_resource_.reset();
159658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EndTest();
159758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
159858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 4:
159958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        NOTREACHED();
160058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
160158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
160258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
160358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl,
160458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       bool visible) OVERRIDE {
16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TestWebGraphicsContext3D* context = TestContext();
160658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!visible) {
160758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // All resources should have been evicted.
160858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ASSERT_EQ(0u, context->NumTextures());
160958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
161058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_EQ(2, ui_resource_->resource_create_count);
161158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_EQ(1, ui_resource_->lost_resource_count);
161258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Drawing is disabled both because of the evicted resources and
161358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // because the renderer is not visible.
161458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_FALSE(impl->CanDraw());
161558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Make the renderer visible again.
161658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      PostSetVisibleToMainThread(true);
161758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
161858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
161958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
162058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE {
16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TestWebGraphicsContext3D* context = TestContext();
162258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
162358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    switch (time_step_) {
162458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 1:
162558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The resource should have been created on LTHI after the commit.
162658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ASSERT_EQ(1u, context->NumTextures());
162758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
162858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->resource_create_count);
162958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0, ui_resource_->lost_resource_count);
163058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_TRUE(impl->CanDraw());
163158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Evict all UI resources. This will trigger a commit.
163258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        impl->EvictAllUIResources();
163358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ASSERT_EQ(0u, context->NumTextures());
163458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
163558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->resource_create_count);
163658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(0, ui_resource_->lost_resource_count);
163758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_FALSE(impl->CanDraw());
163858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
163958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 2:
164058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The resource should have been recreated.
164158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ASSERT_EQ(1u, context->NumTextures());
164258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
164358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(2, ui_resource_->resource_create_count);
164458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(1, ui_resource_->lost_resource_count);
164558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_TRUE(impl->CanDraw());
164658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
164758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case 3:
164858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // The resource should have been recreated after visibility was
164958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // restored.
165058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ASSERT_EQ(1u, context->NumTextures());
165158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
165258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(3, ui_resource_->resource_create_count);
165358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_EQ(2, ui_resource_->lost_resource_count);
165458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        EXPECT_TRUE(impl->CanDraw());
165558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        break;
165658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
165758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
165858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
165958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
166058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction);
166158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class LayerTreeHostContextTestSurfaceCreateCallback
16634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : public LayerTreeHostContextTest {
16644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
16654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LayerTreeHostContextTestSurfaceCreateCallback()
16664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : LayerTreeHostContextTest(),
16675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_(FakeContentLayer::Create(&client_)) {}
16684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetupTree() OVERRIDE {
16704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_->SetBounds(gfx::Size(10, 20));
16714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host()->SetRootLayer(layer_);
16724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LayerTreeHostContextTest::SetupTree();
16734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
16744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
16764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void DidCommit() OVERRIDE {
16785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (layer_tree_host()->source_frame_number()) {
16794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 1:
16804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        EXPECT_EQ(1u, layer_->output_surface_created_count());
16814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        layer_tree_host()->SetNeedsCommit();
16824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
16834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 2:
16844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        EXPECT_EQ(1u, layer_->output_surface_created_count());
16855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_tree_host()->SetNeedsCommit();
16864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
16874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 3:
16885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(1u, layer_->output_surface_created_count());
16895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
16905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 4:
16914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        EXPECT_EQ(2u, layer_->output_surface_created_count());
16924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        layer_tree_host()->SetNeedsCommit();
16934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
16944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
16954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
16964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
16984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
16995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (LastCommittedSourceFrameNumber(impl)) {
17004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 0:
17014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
17024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 1:
17034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
17044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 2:
17054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        LoseContext();
17064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
17074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      case 3:
17084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        EndTest();
17094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        break;
17104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
17114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
17124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
17144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protected:
17164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeContentLayerClient client_;
17174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<FakeContentLayer> layer_;
17184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
17194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback);
17214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1724