// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include "base/bind.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/texture_layer.h"
#include "cc/layers/texture_layer_impl.h"
#include "cc/layers/video_layer.h"
#include "cc/layers/video_layer_impl.h"
#include "cc/paint/filter_operations.h"
#include "cc/paint/paint_flags.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_painted_scrollbar_layer.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_scoped_ui_resource.h"
#include "cc/test/fake_scrollbar.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "media/base/media.h"

using media::VideoFrame;

namespace cc {
namespace {

// Returns a fake TimeTicks based on the given microsecond offset.
base::TimeTicks TicksFromMicroseconds(int64_t micros) {
  return base::TimeTicks() + base::TimeDelta::FromMicroseconds(micros);
}

// These tests deal with losing the 3d graphics context.
class LayerTreeHostContextTest : public LayerTreeTest {
 public:
  LayerTreeHostContextTest()
      : LayerTreeTest(),
        times_to_fail_create_(0),
        times_to_lose_during_commit_(0),
        times_to_lose_during_draw_(0),
        times_to_fail_recreate_(0),
        times_to_expect_create_failed_(0),
        times_create_failed_(0),
        committed_at_least_once_(false),
        context_should_support_io_surface_(false),
        fallback_context_works_(false),
        async_layer_tree_frame_sink_creation_(false) {
    media::InitializeMediaLibrary();
  }

  void LoseContext() {
    // CreateDisplayLayerTreeFrameSink happens on a different thread, so lock
    // gl_ to make sure we don't set it to null after recreating it
    // there.
    base::AutoLock lock(gl_lock_);
    // For sanity-checking tests, they should only call this when the
    // context is not lost.
    CHECK(gl_);
    gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                             GL_INNOCENT_CONTEXT_RESET_ARB);
    gl_ = nullptr;
  }

  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
      const viz::RendererSettings& renderer_settings,
      double refresh_rate,
      scoped_refptr<viz::ContextProvider> compositor_context_provider,
      scoped_refptr<viz::RasterContextProvider> worker_context_provider)
      override {
    base::AutoLock lock(gl_lock_);

    auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
    if (context_should_support_io_surface_) {
      gl_owned->set_have_extension_io_surface(true);
      gl_owned->set_have_extension_egl_image(true);
    }

    gl_ = gl_owned.get();

    auto provider = viz::TestContextProvider::Create(std::move(gl_owned));
    if (times_to_fail_create_) {
      --times_to_fail_create_;
      ExpectCreateToFail();
      gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                               GL_INNOCENT_CONTEXT_RESET_ARB);
    }

    sii_ = provider->SharedImageInterface();

    return LayerTreeTest::CreateLayerTreeFrameSink(
        renderer_settings, refresh_rate, std::move(provider),
        std::move(worker_context_provider));
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame,
                                   DrawResult draw_result) override {
    if (draw_result == DRAW_ABORTED_MISSING_HIGH_RES_CONTENT) {
      // Only valid for single-threaded compositing, which activates
      // immediately and will try to draw again when content has finished.
      DCHECK(!host_impl->task_runner_provider()->HasImplThread());
      return draw_result;
    }
    EXPECT_EQ(DRAW_SUCCESS, draw_result);
    if (!times_to_lose_during_draw_)
      return draw_result;

    --times_to_lose_during_draw_;
    LoseContext();

    times_to_fail_create_ = times_to_fail_recreate_;
    times_to_fail_recreate_ = 0;

    return draw_result;
  }

  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
    committed_at_least_once_ = true;

    if (!times_to_lose_during_commit_)
      return;
    --times_to_lose_during_commit_;
    LoseContext();

    times_to_fail_create_ = times_to_fail_recreate_;
    times_to_fail_recreate_ = 0;
  }

  void DidFailToInitializeLayerTreeFrameSink() override {
    ++times_create_failed_;
  }

  void TearDown() override {
    LayerTreeTest::TearDown();
    EXPECT_EQ(times_to_expect_create_failed_, times_create_failed_);
  }

  void ExpectCreateToFail() { ++times_to_expect_create_failed_; }

 protected:
  // Protects use of gl_ so LoseContext and
  // CreateDisplayLayerTreeFrameSink can both use it on different threads.
  base::Lock gl_lock_;
  viz::TestGLES2Interface* gl_ = nullptr;
  viz::TestSharedImageInterface* sii_ = nullptr;

  int times_to_fail_create_;
  int times_to_lose_during_commit_;
  int times_to_lose_during_draw_;
  int times_to_fail_recreate_;
  int times_to_expect_create_failed_;
  int times_create_failed_;
  bool committed_at_least_once_;
  bool context_should_support_io_surface_;
  bool fallback_context_works_;
  bool async_layer_tree_frame_sink_creation_;
};

class LayerTreeHostContextTestLostContextSucceeds
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestLostContextSucceeds()
      : LayerTreeHostContextTest(),
        test_case_(0),
        num_losses_(0),
        num_losses_last_test_case_(-1),
        recovered_context_(true),
        first_initialized_(false) {}

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void RequestNewLayerTreeFrameSink() override {
    if (async_layer_tree_frame_sink_creation_) {
      MainThreadTaskRunner()->PostTask(
          FROM_HERE,
          base::BindOnce(&LayerTreeHostContextTestLostContextSucceeds::
                             AsyncRequestNewLayerTreeFrameSink,
                         base::Unretained(this)));
    } else {
      AsyncRequestNewLayerTreeFrameSink();
    }
  }

  void AsyncRequestNewLayerTreeFrameSink() {
    LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
  }

  void DidInitializeLayerTreeFrameSink() override {
    if (first_initialized_)
      ++num_losses_;
    else
      first_initialized_ = true;

    recovered_context_ = true;
  }

  void AfterTest() override { EXPECT_EQ(11u, test_case_); }

  void DidCommitAndDrawFrame() override {
    // If the last frame had a context loss, then we'll commit again to
    // recover.
    if (!recovered_context_)
      return;
    if (times_to_lose_during_commit_)
      return;
    if (times_to_lose_during_draw_)
      return;

    recovered_context_ = false;
    if (NextTestCase())
      InvalidateAndSetNeedsCommit();
    else
      EndTest();
  }

  virtual void InvalidateAndSetNeedsCommit() {
    // Cause damage so we try to draw.
    layer_tree_host()->root_layer()->SetNeedsDisplay();
    layer_tree_host()->SetNeedsCommit();
  }

  bool NextTestCase() {
    static const TestCase kTests[] = {
        // Losing the context and failing to recreate it (or losing it again
        // immediately) a small number of times should succeed.
        {
            1,      // times_to_lose_during_commit
            0,      // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            0,      // times_to_lose_during_commit
            1,      // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            1,      // times_to_lose_during_commit
            0,      // times_to_lose_during_draw
            3,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            0,      // times_to_lose_during_commit
            1,      // times_to_lose_during_draw
            3,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            0,      // times_to_lose_during_commit
            1,      // times_to_lose_during_draw
            3,      // times_to_fail_recreate
            false,  // fallback_context_works
            true,   // async_layer_tree_frame_sink_creation
        },
        // Losing the context and recreating it any number of times should
        // succeed.
        {
            10,     // times_to_lose_during_commit
            0,      // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            0,      // times_to_lose_during_commit
            10,     // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            10,     // times_to_lose_during_commit
            0,      // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            true,   // async_layer_tree_frame_sink_creation
        },
        {
            0,      // times_to_lose_during_commit
            10,     // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            false,  // fallback_context_works
            true,   // async_layer_tree_frame_sink_creation
        },
        // Losing the context, failing to reinitialize it, and making a fallback
        // context should work.
        {
            0,      // times_to_lose_during_commit
            1,      // times_to_lose_during_draw
            0,      // times_to_fail_recreate
            true,   // fallback_context_works
            false,  // async_layer_tree_frame_sink_creation
        },
        {
            0,     // times_to_lose_during_commit
            1,     // times_to_lose_during_draw
            0,     // times_to_fail_recreate
            true,  // fallback_context_works
            true,  // async_layer_tree_frame_sink_creation
        },
    };

    if (test_case_ >= base::size(kTests))
      return false;
    // Make sure that we lost our context at least once in the last test run so
    // the test did something.
    EXPECT_GT(num_losses_, num_losses_last_test_case_);
    num_losses_last_test_case_ = num_losses_;

    times_to_lose_during_commit_ =
        kTests[test_case_].times_to_lose_during_commit;
    times_to_lose_during_draw_ = kTests[test_case_].times_to_lose_during_draw;
    times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate;
    fallback_context_works_ = kTests[test_case_].fallback_context_works;
    async_layer_tree_frame_sink_creation_ =
        kTests[test_case_].async_layer_tree_frame_sink_creation;
    ++test_case_;
    return true;
  }

  struct TestCase {
    int times_to_lose_during_commit;
    int times_to_lose_during_draw;
    int times_to_fail_recreate;
    bool fallback_context_works;
    bool async_layer_tree_frame_sink_creation;
  };

 protected:
  size_t test_case_;
  int num_losses_;
  int num_losses_last_test_case_;
  bool recovered_context_;
  bool first_initialized_;
};

// Disabled because of crbug.com/736392
// SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds);

class LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink()
      : LayerTreeHostContextTest() {}

  void WillBeginTest() override {
    // Override to not become visible.
    DCHECK(!layer_tree_host()->IsVisible());
  }

  void BeginTest() override {
    PostSetNeedsCommitToMainThread();
    EndTest();
  }

  void RequestNewLayerTreeFrameSink() override {
    ADD_FAILURE() << "RequestNewLayerTreeFrameSink() should not be called";
  }

  void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); }

  void AfterTest() override {}
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostClientNotVisibleDoesNotCreateLayerTreeFrameSink);

// This tests the LayerTreeFrameSink release logic in the following sequence.
// SetUp LTH and create and init LayerTreeFrameSink.
// LTH::SetVisible(false);
// LTH::ReleaseLayerTreeFrameSink();
// ...
// LTH::SetVisible(true);
// Create and init new LayerTreeFrameSink
class LayerTreeHostClientTakeAwayLayerTreeFrameSink
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostClientTakeAwayLayerTreeFrameSink()
      : LayerTreeHostContextTest(), setos_counter_(0) {}

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void RequestNewLayerTreeFrameSink() override {
    if (layer_tree_host()->IsVisible()) {
      setos_counter_++;
      LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
    }
  }

  void HideAndReleaseLayerTreeFrameSink() {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    layer_tree_host()->SetVisible(false);
    std::unique_ptr<LayerTreeFrameSink> surface =
        layer_tree_host()->ReleaseLayerTreeFrameSink();
    CHECK(surface);
    MainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(
            &LayerTreeHostClientTakeAwayLayerTreeFrameSink::MakeVisible,
            base::Unretained(this)));
  }

  void DidInitializeLayerTreeFrameSink() override {
    EXPECT_TRUE(layer_tree_host()->IsVisible());
    if (setos_counter_ == 1) {
      MainThreadTaskRunner()->PostTask(
          FROM_HERE,
          base::BindOnce(&LayerTreeHostClientTakeAwayLayerTreeFrameSink::
                             HideAndReleaseLayerTreeFrameSink,
                         base::Unretained(this)));
    } else {
      EndTest();
    }
  }

  void MakeVisible() {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    layer_tree_host()->SetVisible(true);
  }

  void AfterTest() override {}

  int setos_counter_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostClientTakeAwayLayerTreeFrameSink);

class MultipleCompositeDoesNotCreateLayerTreeFrameSink
    : public LayerTreeHostContextTest {
 public:
  MultipleCompositeDoesNotCreateLayerTreeFrameSink()
      : LayerTreeHostContextTest(), request_count_(0) {}

  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->single_thread_proxy_scheduler = false;
    settings->use_zero_copy = true;
  }

  void RequestNewLayerTreeFrameSink() override {
    EXPECT_GE(1, ++request_count_);
    EndTest();
  }

  void BeginTest() override {
    layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
    layer_tree_host()->Composite(TicksFromMicroseconds(2), false);
  }

  void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); }

  void AfterTest() override {}

  int request_count_;
};

// This test uses Composite() which only exists for single thread.
SINGLE_THREAD_TEST_F(MultipleCompositeDoesNotCreateLayerTreeFrameSink);

// This test makes sure that once a SingleThreadProxy issues a
// DidFailToInitializeLayerTreeFrameSink, that future Composite calls will not
// trigger additional requests for output surfaces.
class FailedCreateDoesNotCreateExtraLayerTreeFrameSink
    : public LayerTreeHostContextTest {
 public:
  FailedCreateDoesNotCreateExtraLayerTreeFrameSink()
      : LayerTreeHostContextTest(), num_requests_(0), has_failed_(false) {
    times_to_fail_create_ = 1;
  }

  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->single_thread_proxy_scheduler = false;
    settings->use_zero_copy = true;
  }

  void RequestNewLayerTreeFrameSink() override {
    num_requests_++;
    // There should be one initial request and then one request from
    // the LayerTreeTest test hooks DidFailToInitializeLayerTreeFrameSink
    // (which is hard to skip).  This second request is just ignored and is test
    // cruft.
    EXPECT_LE(num_requests_, 2);
    if (num_requests_ > 1)
      return;
    LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
  }

  void BeginTest() override {
    // First composite tries to create a surface.
    layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
    EXPECT_EQ(num_requests_, 2);
    EXPECT_TRUE(has_failed_);

    // Second composite should not request or fail.
    layer_tree_host()->Composite(TicksFromMicroseconds(2), false);
    EXPECT_EQ(num_requests_, 2);
    EndTest();
  }

  void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); }

  void DidFailToInitializeLayerTreeFrameSink() override {
    LayerTreeHostContextTest::DidFailToInitializeLayerTreeFrameSink();
    EXPECT_FALSE(has_failed_);
    has_failed_ = true;
  }

  void AfterTest() override {}

  int num_requests_;
  bool has_failed_;
};

// This test uses Composite() which only exists for single thread.
SINGLE_THREAD_TEST_F(FailedCreateDoesNotCreateExtraLayerTreeFrameSink);

class LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink()
      : LayerTreeHostContextTest(), creating_output_(false) {}

  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->single_thread_proxy_scheduler = false;
    settings->use_zero_copy = true;
  }

  void RequestNewLayerTreeFrameSink() override {
    MainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(
            &LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink::
                CreateAndSetLayerTreeFrameSink,
            base::Unretained(this)));
  }

  void CreateAndSetLayerTreeFrameSink() {
    creating_output_ = true;
    LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
  }

  void BeginTest() override {
    layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
  }

  void ScheduleComposite() override {
    if (creating_output_)
      EndTest();
  }

  void AfterTest() override {}

  bool creating_output_;
};

// This test uses Composite() which only exists for single thread.
SINGLE_THREAD_TEST_F(
    LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink);

class LayerTreeHostContextTestAvoidUnnecessaryComposite
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestAvoidUnnecessaryComposite()
      : LayerTreeHostContextTest(), in_composite_(false) {}

  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->single_thread_proxy_scheduler = false;
    settings->use_zero_copy = true;
  }

  void RequestNewLayerTreeFrameSink() override {
    LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
    EndTest();
  }

  void BeginTest() override {
    in_composite_ = true;
    layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
    in_composite_ = false;
  }

  void ScheduleComposite() override { EXPECT_FALSE(in_composite_); }

  void AfterTest() override {}

  bool in_composite_;
};

// This test uses Composite() which only exists for single thread.
SINGLE_THREAD_TEST_F(LayerTreeHostContextTestAvoidUnnecessaryComposite);

// This test uses PictureLayer to check for a working context.
class LayerTreeHostContextTestLostContextSucceedsWithContent
    : public LayerTreeHostContextTestLostContextSucceeds {
 public:
  void SetupTree() override {
    root_ = Layer::Create();
    root_->SetBounds(gfx::Size(10, 10));
    root_->SetIsDrawable(true);

    // Paint non-solid color.
    PaintFlags flags;
    flags.setColor(SkColorSetARGB(100, 80, 200, 200));
    client_.add_draw_rect(gfx::Rect(5, 5), flags);

    layer_ = FakePictureLayer::Create(&client_);
    layer_->SetBounds(gfx::Size(10, 10));
    layer_->SetIsDrawable(true);

    root_->AddChild(layer_);

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeHostContextTest::SetupTree();
    client_.set_bounds(root_->bounds());
  }

  void InvalidateAndSetNeedsCommit() override {
    // Invalidate the render surface so we don't try to use a cached copy of the
    // surface.  We want to make sure to test the drawing paths for drawing to
    // a child surface.
    layer_->SetNeedsDisplay();
    LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit();
  }

  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
    FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(
        host_impl->active_tree()->LayerById(layer_->id()));
    EXPECT_TRUE(picture_impl->HighResTiling()
                    ->TileAt(0, 0)
                    ->draw_info()
                    .IsReadyToDraw());
  }

 protected:
  FakeContentLayerClient client_;
  scoped_refptr<Layer> root_;
  scoped_refptr<Layer> layer_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostContextTestLostContextSucceedsWithContent);

class LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce()
      : times_to_fail_(1), times_initialized_(0) {
    times_to_fail_create_ = times_to_fail_;
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DidInitializeLayerTreeFrameSink() override { times_initialized_++; }

  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); }

  void AfterTest() override {
    EXPECT_EQ(times_to_fail_, times_create_failed_);
    EXPECT_NE(0, times_initialized_);
  }

 private:
  int times_to_fail_;
  int times_initialized_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostContextTestCreateLayerTreeFrameSinkFailsOnce);

class LayerTreeHostContextTestLostContextAndEvictTextures
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestLostContextAndEvictTextures()
      : LayerTreeHostContextTest(),
        impl_host_(nullptr),
        num_commits_(0),
        lost_context_(false) {}

  void SetupTree() override {
    // Paint non-solid color.
    PaintFlags flags;
    flags.setColor(SkColorSetARGB(100, 80, 200, 200));
    client_.add_draw_rect(gfx::Rect(5, 5), flags);

    scoped_refptr<FakePictureLayer> picture_layer =
        FakePictureLayer::Create(&client_);
    picture_layer->SetBounds(gfx::Size(10, 20));
    client_.set_bounds(picture_layer->bounds());
    layer_tree_host()->SetRootLayer(picture_layer);

    LayerTreeHostContextTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void PostEvictTextures() {
    if (HasImplThread()) {
      ImplThreadTaskRunner()->PostTask(
          FROM_HERE,
          base::BindOnce(&LayerTreeHostContextTestLostContextAndEvictTextures::
                             EvictTexturesOnImplThread,
                         base::Unretained(this)));
    } else {
      DebugScopedSetImplThread impl(task_runner_provider());
      EvictTexturesOnImplThread();
    }
  }

  void EvictTexturesOnImplThread() {
    impl_host_->EvictTexturesForTesting();

    if (lose_after_evict_) {
      LoseContext();
      lost_context_ = true;
    }
  }

  void DidCommitAndDrawFrame() override {
    if (num_commits_ > 1)
      return;
    PostEvictTextures();
  }

  void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
    if (num_commits_ > 1)
      return;
    ++num_commits_;
    if (!lose_after_evict_) {
      LoseContext();
      lost_context_ = true;
    }
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>(
        impl->active_tree()->root_layer_for_testing());
    EXPECT_TRUE(picture_impl->HighResTiling()
                    ->TileAt(0, 0)
                    ->draw_info()
                    .IsReadyToDraw());

    impl_host_ = impl;
    if (lost_context_)
      EndTest();
  }

  void DidInitializeLayerTreeFrameSink() override {}

  void AfterTest() override {}

 protected:
  bool lose_after_evict_;
  FakeContentLayerClient client_;
  LayerTreeHostImpl* impl_host_;
  int num_commits_;
  bool lost_context_;
};

TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
       LoseAfterEvict_SingleThread) {
  lose_after_evict_ = true;
  RunTest(CompositorMode::SINGLE_THREADED);
}

TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
       LoseAfterEvict_MultiThread) {
  lose_after_evict_ = true;
  RunTest(CompositorMode::THREADED);
}

TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
       LoseBeforeEvict_SingleThread) {
  lose_after_evict_ = false;
  RunTest(CompositorMode::SINGLE_THREADED);
}

TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
       LoseBeforeEvict_MultiThread) {
  lose_after_evict_ = false;
  RunTest(CompositorMode::THREADED);
}

class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestLayersNotified()
      : LayerTreeHostContextTest(), num_commits_(0) {}

  void SetupTree() override {
    root_ = FakePictureLayer::Create(&client_);
    child_ = FakePictureLayer::Create(&client_);
    grandchild_ = FakePictureLayer::Create(&client_);

    root_->AddChild(child_);
    child_->AddChild(grandchild_);

    LayerTreeHostContextTest::SetupTree();
    client_.set_bounds(root_->bounds());
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void AttachTree() { layer_tree_host()->SetRootLayer(root_); }

  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
    LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl);

    ++num_commits_;

    FakePictureLayerImpl* root_picture = nullptr;
    FakePictureLayerImpl* child_picture = nullptr;
    FakePictureLayerImpl* grandchild_picture = nullptr;
    // Root layer isn't attached on first activation so the static_cast will
    // fail before second activation.
    if (num_commits_ >= 2) {
      root_picture = static_cast<FakePictureLayerImpl*>(
          host_impl->active_tree()->root_layer_for_testing());
      child_picture = static_cast<FakePictureLayerImpl*>(
          host_impl->active_tree()->LayerById(child_->id()));
      grandchild_picture = static_cast<FakePictureLayerImpl*>(
          host_impl->active_tree()->LayerById(grandchild_->id()));
    }
    switch (num_commits_) {
      case 1:
        // Because setting the colorspace on the first activation releases
        // resources, don't attach the layers until the first activation.
        // Because of single thread vs multi thread differences (i.e.
        // commit to active tree), if this delay is not done, then the
        // active tree layers will have a different number of resource
        // releasing.
        MainThreadTaskRunner()->PostTask(
            FROM_HERE,
            base::BindOnce(&LayerTreeHostContextTestLayersNotified::AttachTree,
                           base::Unretained(this)));
        break;
      case 2:
        EXPECT_EQ(0u, root_picture->release_resources_count());
        EXPECT_EQ(0u, child_picture->release_resources_count());
        EXPECT_EQ(0u, grandchild_picture->release_resources_count());

        // Lose the context and struggle to recreate it.
        LoseContext();
        times_to_fail_create_ = 1;
        break;
      case 3:
        EXPECT_TRUE(root_picture->release_resources_count());
        EXPECT_TRUE(child_picture->release_resources_count());
        EXPECT_TRUE(grandchild_picture->release_resources_count());

        EndTest();
        break;
      default:
        NOTREACHED();
    }
  }

  void AfterTest() override {}

 private:
  int num_commits_;

  FakeContentLayerClient client_;
  scoped_refptr<Layer> root_;
  scoped_refptr<Layer> child_;
  scoped_refptr<Layer> grandchild_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified);

class LayerTreeHostContextTestDontUseLostResources
    : public LayerTreeHostContextTest {
 public:
  LayerTreeHostContextTestDontUseLostResources() : lost_context_(false) {
    context_should_support_io_surface_ = true;

    child_context_provider_ = viz::TestContextProvider::Create();
    auto result = child_context_provider_->BindToCurrentThread();
    CHECK_EQ(result, gpu::ContextResult::kSuccess);
    shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
    child_resource_provider_ =
        std::make_unique<viz::ClientResourceProvider>(true);
  }

  static void EmptyReleaseCallback(const gpu::SyncToken& sync_token,
                                   bool lost) {}

  void SetupTree() override {
    gpu::gles2::GLES2Interface* gl = child_context_provider_->ContextGL();

    gpu::Mailbox mailbox = gpu::Mailbox::Generate();

    gpu::SyncToken sync_token;
    gl->GenSyncTokenCHROMIUM(sync_token.GetData());

    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(10, 10));
    root->SetIsDrawable(true);

    scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client_);
    layer->SetBounds(gfx::Size(10, 10));
    layer->SetIsDrawable(true);
    root->AddChild(layer);

    scoped_refptr<TextureLayer> texture =
        TextureLayer::CreateForMailbox(nullptr);
    texture->SetBounds(gfx::Size(10, 10));
    texture->SetIsDrawable(true);
    constexpr gfx::Size size(64, 64);
    auto resource = viz::TransferableResource::MakeGL(
        mailbox, GL_LINEAR, GL_TEXTURE_2D, sync_token, size,
        false /* is_overlay_candidate */);
    texture->SetTransferableResource(
        resource, viz::SingleReleaseCallback::Create(base::BindOnce(
                      &LayerTreeHostContextTestDontUseLostResources::
                          EmptyReleaseCallback)));
    root->AddChild(texture);

    scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_);
    mask->SetBounds(gfx::Size(10, 10));
    client_.set_bounds(mask->bounds());

    scoped_refptr<PictureLayer> layer_with_mask =
        PictureLayer::Create(&client_);
    layer_with_mask->SetBounds(gfx::Size(10, 10));
    layer_with_mask->SetIsDrawable(true);
    layer_with_mask->SetMaskLayer(mask.get());
    root->AddChild(layer_with_mask);

    scoped_refptr<VideoLayer> video_color =
        VideoLayer::Create(&color_frame_provider_, media::VIDEO_ROTATION_0);
    video_color->SetBounds(gfx::Size(10, 10));
    video_color->SetIsDrawable(true);
    root->AddChild(video_color);

    scoped_refptr<VideoLayer> video_hw =
        VideoLayer::Create(&hw_frame_provider_, media::VIDEO_ROTATION_0);
    video_hw->SetBounds(gfx::Size(10, 10));
    video_hw->SetIsDrawable(true);
    root->AddChild(video_hw);

    scoped_refptr<VideoLayer> video_scaled_hw =
        VideoLayer::Create(&scaled_hw_frame_provider_, media::VIDEO_ROTATION_0);
    video_scaled_hw->SetBounds(gfx::Size(10, 10));
    video_scaled_hw->SetIsDrawable(true);
    root->AddChild(video_scaled_hw);

    color_video_frame_ = VideoFrame::CreateColorFrame(
        gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
    ASSERT_TRUE(color_video_frame_);
    gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = {
        gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D)};
    hw_video_frame_ = VideoFrame::WrapNativeTextures(
        media::PIXEL_FORMAT_ARGB, holders,
        media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4),
        gfx::Rect(0, 0, 4, 4), gfx::Size(4, 4), base::TimeDelta());
    ASSERT_TRUE(hw_video_frame_);
    scaled_hw_video_frame_ = VideoFrame::WrapNativeTextures(
        media::PIXEL_FORMAT_ARGB, holders,
        media::VideoFrame::ReleaseMailboxCB(), gfx::Size(4, 4),
        gfx::Rect(0, 0, 3, 2), gfx::Size(4, 4), base::TimeDelta());
    ASSERT_TRUE(scaled_hw_video_frame_);

    color_frame_provider_.set_frame(color_video_frame_);
    hw_frame_provider_.set_frame(hw_video_frame_);
    scaled_hw_frame_provider_.set_frame(scaled_hw_video_frame_);

    // Enable the hud.
    LayerTreeDebugState debug_state;
    debug_state.show_property_changed_rects = true;
    layer_tree_host()->SetDebugState(debug_state);

    scoped_refptr<PaintedScrollbarLayer> scrollbar =
        PaintedScrollbarLayer::Create(
            std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->element_id());
    scrollbar->SetBounds(gfx::Size(10, 10));
    scrollbar->SetIsDrawable(true);
    root->AddChild(scrollbar);

    layer_tree_host()->SetRootLayer(root);
    LayerTreeHostContextTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(host_impl);

    if (host_impl->active_tree()->source_frame_number() == 3) {
      // On the third commit we're recovering from context loss. Hardware
      // video frames should not be reused by the VideoFrameProvider, but
      // software frames can be.
      hw_frame_provider_.set_frame(nullptr);
      scaled_hw_frame_provider_.set_frame(nullptr);
    }
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame,
                                   DrawResult draw_result) override {
    if (host_impl->active_tree()->source_frame_number() == 2) {
      // Lose the context after draw on the second commit. This will cause
      // a third commit to recover.
      gl_->set_times_bind_texture_succeeds(0);
    }
    return draw_result;
  }

  void RequestNewLayerTreeFrameSink() override {
    // This will get called twice:
    // First when we create the initial LayerTreeFrameSink...
    if (layer_tree_host()->SourceFrameNumber() > 0) {
      // ... and then again after we forced the context to be lost.
      lost_context_ = true;
    }
    LayerTreeHostContextTest::RequestNewLayerTreeFrameSink();
  }

  void DidCommitAndDrawFrame() override {
    ASSERT_TRUE(layer_tree_host()->hud_layer());
    // End the test once we know the 3nd frame drew.
    if (layer_tree_host()->SourceFrameNumber() < 5) {
      layer_tree_host()->root_layer()->SetNeedsDisplay();
      layer_tree_host()->SetNeedsCommit();
    } else {
      EndTest();
    }
  }

  void AfterTest() override { EXPECT_TRUE(lost_context_); }

 private:
  FakeContentLayerClient client_;
  bool lost_context_;

  scoped_refptr<viz::TestContextProvider> child_context_provider_;
  std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_;
  std::unique_ptr<viz::ClientResourceProvider> child_resource_provider_;

  scoped_refptr<VideoFrame> color_video_frame_;
  scoped_refptr<VideoFrame> hw_video_frame_;
  scoped_refptr<VideoFrame> scaled_hw_video_frame_;

  FakeVideoFrameProvider color_frame_provider_;
  FakeVideoFrameProvider hw_frame_provider_;
  FakeVideoFrameProvider scaled_hw_frame_provider_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources);

class LayerTreeHostContextTestImplSidePainting
    : public LayerTreeHostContextTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(10, 10));
    root->SetIsDrawable(true);

    scoped_refptr<PictureLayer> picture = PictureLayer::Create(&client_);
    picture->SetBounds(gfx::Size(10, 10));
    client_.set_bounds(picture->bounds());
    picture->SetIsDrawable(true);
    root->AddChild(picture);

    layer_tree_host()->SetRootLayer(root);
    LayerTreeHostContextTest::SetupTree();
  }

  void BeginTest() override {
    times_to_lose_during_commit_ = 1;
    PostSetNeedsCommitToMainThread();
  }

  void AfterTest() override {}

  void DidInitializeLayerTreeFrameSink() override { EndTest(); }

 private:
  FakeContentLayerClient client_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestImplSidePainting);

class ScrollbarLayerLostContext : public LayerTreeHostContextTest {
 public:
  ScrollbarLayerLostContext() : commits_(0) {}

  void BeginTest() override {
    scoped_refptr<Layer> scroll_layer = Layer::Create();
    scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
        false, true, scroll_layer->element_id());
    scrollbar_layer_->SetBounds(gfx::Size(10, 100));
    layer_tree_host()->root_layer()->AddChild(scrollbar_layer_);
    layer_tree_host()->root_layer()->AddChild(scroll_layer);
    PostSetNeedsCommitToMainThread();
  }

  void AfterTest() override {}

  void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);

    ++commits_;
    switch (commits_) {
      case 1:
        // First (regular) update, we should upload 2 resources (thumb, and
        // backtrack).
        EXPECT_EQ(1, scrollbar_layer_->update_count());
        LoseContext();
        break;
      case 2:
        // Second update, after the lost context, we should still upload 2
        // resources even if the contents haven't changed.
        EXPECT_EQ(2, scrollbar_layer_->update_count());
        EndTest();
        break;
      default:
        NOTREACHED();
    }
  }

 private:
  int commits_;
  scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext);

class UIResourceLostTest : public LayerTreeHostContextTest {
 public:
  UIResourceLostTest() : time_step_(0) {}
  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
  void AfterTest() override {}

  // This is called on the main thread after each commit and
  // DidActivateTreeOnThread, with the value of time_step_ at the time
  // of the call to DidActivateTreeOnThread. Similar tests will do
  // work on the main thread in DidCommit but that is unsuitable because
  // the main thread work for these tests must happen after
  // DidActivateTreeOnThread, which happens after DidCommit with impl-side
  // painting.
  virtual void StepCompleteOnMainThread(int time_step) = 0;

  // Called after DidActivateTreeOnThread. If this is done during the commit,
  // the call to StepCompleteOnMainThread will not occur until after
  // the commit completes, because the main thread is blocked.
  void PostStepCompleteToMainThread() {
    task_runner_provider()->MainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(&UIResourceLostTest::StepCompleteOnMainThreadInternal,
                       base::Unretained(this), time_step_));
  }

  void PostLoseContextToImplThread() {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    ImplThreadTaskRunner()->PostTask(
        FROM_HERE, base::BindOnce(&LayerTreeHostContextTest::LoseContext,
                                  base::Unretained(this)));
  }

 protected:
  int time_step_;
  std::unique_ptr<FakeScopedUIResource> ui_resource_;

 private:
  void StepCompleteOnMainThreadInternal(int step) {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    StepCompleteOnMainThread(step);
  }
};

class UIResourceLostTestSimple : public UIResourceLostTest {
 public:
  // This is called when the new layer tree has been activated.
  virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) = 0;

  void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
    StepCompleteOnImplThread(impl);
    PostStepCompleteToMainThread();
    ++time_step_;
  }
};

// Losing context after an UI resource has been created.
class UIResourceLostAfterCommit : public UIResourceLostTestSimple {
 public:
  void StepCompleteOnMainThread(int step) override {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    switch (step) {
      case 0:
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        // Expects a valid UIResourceId.
        EXPECT_NE(0, ui_resource_->id());
        PostSetNeedsCommitToMainThread();
        break;
      case 4:
        // Release resource before ending the test.
        ui_resource_ = nullptr;
        EndTest();
        break;
      case 5:
        NOTREACHED();
        break;
    }
  }

  void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
    switch (time_step_) {
      case 1:
        // The resource should have been created on LTHI after the commit.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        PostSetNeedsCommitToMainThread();
        break;
      case 2:
        LoseContext();
        break;
      case 3:
        // The resources should have been recreated. The bitmap callback should
        // have been called once with the resource_lost flag set to true.
        EXPECT_EQ(1, ui_resource_->lost_resource_count);
        // Resource Id on the impl-side have been recreated as well. Note
        // that the same UIResourceId persists after the context lost.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        PostSetNeedsCommitToMainThread();
        break;
    }
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostAfterCommit);

// Losing context before UI resource requests can be commited.  Three sequences
// of creation/deletion are considered:
// 1. Create one resource -> Context Lost => Expect the resource to have been
// created.
// 2. Delete an existing resource (test_id0_) -> create a second resource
// (test_id1_) -> Context Lost => Expect the test_id0_ to be removed and
// test_id1_ to have been created.
// 3. Create one resource -> Delete that same resource -> Context Lost => Expect
// the resource to not exist in the manager.
class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
 public:
  UIResourceLostBeforeCommit() : test_id0_(0), test_id1_(0) {}

  void StepCompleteOnMainThread(int step) override {
    switch (step) {
      case 0:
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        // Lose the context on the impl thread before the commit.
        PostLoseContextToImplThread();
        break;
      case 2:
        // Sequence 2:
        // Currently one resource has been created.
        test_id0_ = ui_resource_->id();
        // Delete this resource.
        ui_resource_ = nullptr;
        // Create another resource.
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        test_id1_ = ui_resource_->id();
        // Sanity check that two resource creations return different ids.
        EXPECT_NE(test_id0_, test_id1_);
        // Lose the context on the impl thread before the commit.
        PostLoseContextToImplThread();
        break;
      case 3:
        // Clear the manager of resources.
        ui_resource_ = nullptr;
        PostSetNeedsCommitToMainThread();
        break;
      case 4:
        // Sequence 3:
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        test_id0_ = ui_resource_->id();
        // Sanity check the UIResourceId should not be 0.
        EXPECT_NE(0, test_id0_);
        // Usually ScopedUIResource are deleted from the manager in their
        // destructor (so usually ui_resource_ = nullptr).  But here we need
        // ui_resource_ for the next step, so call DeleteUIResource directly.
        layer_tree_host()->GetUIResourceManager()->DeleteUIResource(test_id0_);
        // Delete the resouce and then lose the context.
        PostLoseContextToImplThread();
        break;
      case 5:
        // Release resource before ending the test.
        ui_resource_ = nullptr;
        EndTest();
        break;
      case 6:
        NOTREACHED();
        break;
    }
  }

  void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
    switch (time_step_) {
      case 1:
        // Sequence 1 (continued):
        // The first context lost happens before the resources were created,
        // and because it resulted in no resources being destroyed, it does not
        // trigger resource re-creation.
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        // Resource Id on the impl-side has been created.
        PostSetNeedsCommitToMainThread();
        break;
      case 3:
        // Sequence 2 (continued):
        // The previous resource should have been deleted.
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_));
        // The second resource should have been created.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_));
        // The second resource was not actually uploaded before the context
        // was lost, so it only got created once.
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        break;
      case 5:
        // Sequence 3 (continued):
        // Expect the resource callback to have been called once.
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        // No "resource lost" callbacks.
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        // The UI resource id should not be valid
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_));
        break;
    }
  }

 private:
  UIResourceId test_id0_;
  UIResourceId test_id1_;
};

// http://crbug.com/803532 : Flaky on Win 7 (dbg) and linux tsan
#if (defined(NDEBUG) || !defined(OS_WIN)) && \
    (!defined(THREAD_SANITIZER) || !defined(OS_LINUX))
SINGLE_THREAD_TEST_F(UIResourceLostBeforeCommit);
#endif
MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit);

// Losing UI resource before the pending trees is activated but after the
// commit.  Impl-side-painting only.
class UIResourceLostBeforeActivateTree : public UIResourceLostTest {
  void StepCompleteOnMainThread(int step) override {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    switch (step) {
      case 0:
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        PostSetNeedsCommitToMainThread();
        break;
      case 3:
        test_id_ = ui_resource_->id();
        ui_resource_ = nullptr;
        PostSetNeedsCommitToMainThread();
        break;
      case 5:
        // Release resource before ending the test.
        ui_resource_ = nullptr;
        EndTest();
        break;
      case 6:
        // Make sure no extra commits happened.
        NOTREACHED();
    }
  }

  void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
    switch (time_step_) {
      case 2:
        PostSetNeedsCommitToMainThread();
        break;
      case 4:
        PostSetNeedsCommitToMainThread();
        break;
    }
  }

  void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
    switch (time_step_) {
      case 1:
        // The resource creation callback has been called.
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        // The resource is not yet lost (sanity check).
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        // The resource should not have been created yet on the impl-side.
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        LoseContext();
        break;
      case 3:
        LoseContext();
        break;
    }
  }

  void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::DidActivateTreeOnThread(impl);
    switch (time_step_) {
      case 1:
        // The pending requests on the impl-side should not have been processed
        // since the context was lost. But we should have marked the resource as
        // evicted instead.
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_TRUE(impl->EvictedUIResourcesExist());
        break;
      case 2:
        // The "lost resource" callback should have been called once and it
        // should have gotten recreated now and shouldn't be marked as evicted
        // anymore.
        EXPECT_EQ(1, ui_resource_->lost_resource_count);
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_FALSE(impl->EvictedUIResourcesExist());
        break;
      case 4:
        // The resource is deleted and should not be in the manager.  Use
        // test_id_ since ui_resource_ has been deleted.
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id_));
        break;
    }

    PostStepCompleteToMainThread();
    ++time_step_;
  }

 private:
  UIResourceId test_id_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeActivateTree);

// Resources evicted explicitly and by visibility changes.
class UIResourceLostEviction : public UIResourceLostTestSimple {
 public:
  void StepCompleteOnMainThread(int step) override {
    EXPECT_TRUE(layer_tree_host()->GetTaskRunnerProvider()->IsMainThread());
    switch (step) {
      case 0:
        ui_resource_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        ui_resource2_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        EXPECT_NE(0, ui_resource_->id());
        EXPECT_NE(0, ui_resource2_->id());
        PostSetNeedsCommitToMainThread();
        break;
      case 2:
        // Make the tree not visible.
        PostSetVisibleToMainThread(false);
        ui_resource2_->DeleteResource();
        ui_resource3_ = FakeScopedUIResource::Create(
            layer_tree_host()->GetUIResourceManager());
        break;
      case 3:
        // Release resources before ending the test.
        ui_resource_ = nullptr;
        ui_resource2_ = nullptr;
        ui_resource3_ = nullptr;
        EndTest();
        break;
      case 4:
        NOTREACHED();
    }
  }

  void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, bool visible) override {
    if (!visible) {
      // All resources should have been evicted.
      ASSERT_EQ(0u, sii_->shared_image_count());
      EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
      EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
      EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource3_->id()));
      EXPECT_EQ(2, ui_resource_->resource_create_count);
      EXPECT_EQ(1, ui_resource_->lost_resource_count);
      // Drawing is disabled both because of the evicted resources and
      // because the renderer is not visible.
      EXPECT_FALSE(impl->CanDraw());
      // Make the renderer visible again.
      PostSetVisibleToMainThread(true);
    }
  }

  void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override {
    LayerTreeHostContextTest::CommitCompleteOnThread(impl);
    switch (time_step_) {
      case 1:
        // The first two resources should have been created on LTHI after the
        // commit.
        ASSERT_EQ(2u, sii_->shared_image_count());
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        EXPECT_TRUE(impl->CanDraw());
        // Evict all UI resources. This will trigger a commit.
        impl->EvictAllUIResources();
        ASSERT_EQ(0u, sii_->shared_image_count());
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
        EXPECT_EQ(1, ui_resource_->resource_create_count);
        EXPECT_EQ(0, ui_resource_->lost_resource_count);
        EXPECT_FALSE(impl->CanDraw());
        break;
      case 2:
        // The first two resources should have been recreated.
        ASSERT_EQ(2u, sii_->shared_image_count());
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_EQ(2, ui_resource_->resource_create_count);
        EXPECT_EQ(1, ui_resource_->lost_resource_count);
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
        EXPECT_EQ(2, ui_resource2_->resource_create_count);
        EXPECT_EQ(1, ui_resource2_->lost_resource_count);
        EXPECT_TRUE(impl->CanDraw());
        break;
      case 3:
        // The first resource should have been recreated after visibility was
        // restored.
        ASSERT_EQ(2u, sii_->shared_image_count());
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_EQ(3, ui_resource_->resource_create_count);
        EXPECT_EQ(2, ui_resource_->lost_resource_count);

        // This resource was deleted.
        EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
        EXPECT_EQ(2, ui_resource2_->resource_create_count);
        EXPECT_EQ(1, ui_resource2_->lost_resource_count);

        // This resource should have been created now.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource3_->id()));
        EXPECT_EQ(1, ui_resource3_->resource_create_count);
        EXPECT_EQ(0, ui_resource3_->lost_resource_count);
        EXPECT_TRUE(impl->CanDraw());
        break;
    }
  }

 private:
  std::unique_ptr<FakeScopedUIResource> ui_resource2_;
  std::unique_ptr<FakeScopedUIResource> ui_resource3_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostEviction);

class UIResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
 protected:
  void BeginTest() override {
    // Make 1 UIResource, post it to the compositor thread, where it will be
    // uploaded.
    ui_resource_ =
        FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
    EXPECT_NE(0, ui_resource_->id());
    PostSetNeedsCommitToMainThread();
  }

  void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        // The UIResource has been created and a gpu resource made for it.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_EQ(1u, sii_->shared_image_count());
        // Lose the LayerTreeFrameSink connection. The UI resource should
        // be replaced and the old texture should be destroyed.
        impl->DidLoseLayerTreeFrameSink();
        break;
      case 1:
        // The UIResource has been recreated, the old texture is not kept
        // around.
        EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
        EXPECT_EQ(1u, sii_->shared_image_count());
        MainThreadTaskRunner()->PostTask(
            FROM_HERE,
            base::BindOnce(
                &UIResourceFreedIfLostWhileExported::DeleteAndEndTest,
                base::Unretained(this)));
    }
  }

  void DeleteAndEndTest() {
    ui_resource_->DeleteResource();
    EndTest();
  }

  void AfterTest() override {}

  std::unique_ptr<FakeScopedUIResource> ui_resource_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceFreedIfLostWhileExported);

class TileResourceFreedIfLostWhileExported : public LayerTreeHostContextTest {
 protected:
  void SetupTree() override {
    PaintFlags flags;
    client_.set_fill_with_nonsolid_color(true);

    scoped_refptr<FakePictureLayer> picture_layer =
        FakePictureLayer::Create(&client_);
    picture_layer->SetBounds(gfx::Size(10, 20));
    client_.set_bounds(picture_layer->bounds());
    layer_tree_host()->SetRootLayer(std::move(picture_layer));

    LayerTreeTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    auto* context_provider = static_cast<viz::TestContextProvider*>(
        impl->layer_tree_frame_sink()->worker_context_provider());
    viz::TestSharedImageInterface* sii =
        context_provider->SharedImageInterface();
    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        // The PicturLayer has a texture for a tile, that has been exported to
        // the display compositor now.
        EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
        EXPECT_EQ(1u, impl->resource_pool()->resource_count());
        // Shows that the tile texture is allocated with the current worker
        // context.
        num_textures_ = sii->shared_image_count();
        EXPECT_GT(num_textures_, 0u);

        // Lose the LayerTreeFrameSink connection. The tile resource should
        // be replaced and the old texture should be destroyed.
        LoseContext();
        break;
      case 1:
        // The tile has been recreated, the old texture is not kept around in
        // the pool indefinitely. It can be dropped as soon as the context is
        // known to be lost.
        EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
        EXPECT_EQ(1u, impl->resource_pool()->resource_count());
        // Shows that the replacement tile texture is re-allocated with the
        // current worker context, not just the previous one.
        EXPECT_EQ(num_textures_, sii->shared_image_count());
        EndTest();
    }
  }

  void AfterTest() override {}

  FakeContentLayerClient client_;
  size_t num_textures_ = 0;
};

SINGLE_AND_MULTI_THREAD_TEST_F(TileResourceFreedIfLostWhileExported);

class SoftwareTileResourceFreedIfLostWhileExported : public LayerTreeTest {
 protected:
  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
      const viz::RendererSettings& renderer_settings,
      double refresh_rate,
      scoped_refptr<viz::ContextProvider> compositor_context_provider,
      scoped_refptr<viz::RasterContextProvider> worker_context_provider)
      override {
    // Induce software compositing in cc.
    return LayerTreeTest::CreateLayerTreeFrameSink(
        renderer_settings, refresh_rate, nullptr, nullptr);
  }

  std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread(
      scoped_refptr<viz::ContextProvider> compositor_context_provider)
      override {
    // Induce software compositing in the display compositor.
    return viz::FakeOutputSurface::CreateSoftware(
        std::make_unique<viz::SoftwareOutputDevice>());
  }

  void SetupTree() override {
    PaintFlags flags;
    client_.set_fill_with_nonsolid_color(true);

    scoped_refptr<FakePictureLayer> picture_layer =
        FakePictureLayer::Create(&client_);
    picture_layer->SetBounds(gfx::Size(10, 20));
    client_.set_bounds(picture_layer->bounds());
    layer_tree_host()->SetRootLayer(std::move(picture_layer));

    LayerTreeTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    switch (impl->active_tree()->source_frame_number()) {
      case 0: {
        // The PicturLayer has a bitmap for a tile, that has been exported to
        // the display compositor now.
        EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
        EXPECT_EQ(1u, impl->resource_pool()->resource_count());

        impl->DidLoseLayerTreeFrameSink();
        break;
      }
      case 1: {
        // The tile did not need to be recreated, the same bitmap/resource
        // should be used for it.
        EXPECT_EQ(1u, impl->resource_provider()->num_resources_for_testing());
        EXPECT_EQ(1u, impl->resource_pool()->resource_count());

        // TODO(danakj): It'd be possible to not destroy and recreate the
        // software bitmap, however for simplicity we do the same for software
        // and for gpu paths. If we didn't destroy it we could see the same
        // bitmap on PictureLayerImpl's tile.

        EndTest();
      }
    }
  }

  void AfterTest() override {}

  FakeContentLayerClient client_;
  viz::ResourceId exported_resource_id_ = 0;
};

SINGLE_AND_MULTI_THREAD_TEST_F(SoftwareTileResourceFreedIfLostWhileExported);

class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
    : public LayerTreeHostContextTest {
 protected:
  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void WillBeginMainFrame() override {
    // Don't begin a frame with a lost surface.
    EXPECT_FALSE(lost_);

    if (deferred_)
      return;
    deferred_ = true;

    // TODO(schenney): This should switch back to defer_commits_ because there
    // is no way in the real code to start deferring main frame updates when
    // inside WillBeginMainFrame. Defer commits before the BeginFrame completes,
    // causing it to be delayed.
    scoped_defer_main_frame_update_ = layer_tree_host()->DeferMainFrameUpdate();
    // Meanwhile, lose the context while we are in defer BeginMainFrame.
    ImplThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(&LayerTreeHostContextTestLoseAfterSendingBeginMainFrame::
                           LoseContextOnImplThread,
                       base::Unretained(this)));

    // After the first frame, we will lose the context and then not start
    // lifecycle updates and commits until that happens. The 2nd frame should
    // not happen before DidInitializeLayerTreeFrameSink occurs.
    lost_ = true;
  }

  void DidInitializeLayerTreeFrameSink() override {
    EXPECT_TRUE(lost_);
    lost_ = false;
  }

  void LoseContextOnImplThread() {
    LoseContext();

    // TODO(schenney): This should switch back to defer_commits_ to match the
    // change above.
    // After losing the context, stop deferring commits.
    PostReturnDeferMainFrameUpdateToMainThread(
        std::move(scoped_defer_main_frame_update_));
  }

  void DidCommitAndDrawFrame() override { EndTest(); }

  void AfterTest() override {}

  std::unique_ptr<ScopedDeferMainFrameUpdate> scoped_defer_main_frame_update_;
  bool deferred_ = false;
  bool lost_ = true;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostContextTestLoseAfterSendingBeginMainFrame);

class LayerTreeHostContextTestWorkerContextLostRecovery : public LayerTreeTest {
 protected:
  void SetupTree() override {
    PaintFlags flags;
    client_.set_fill_with_nonsolid_color(true);
    client_.add_draw_rect(gfx::Rect(5, 5), flags);

    scoped_refptr<FakePictureLayer> picture_layer =
        FakePictureLayer::Create(&client_);
    picture_layer->SetBounds(gfx::Size(10, 20));
    client_.set_bounds(picture_layer->bounds());
    layer_tree_host()->SetRootLayer(picture_layer);

    LayerTreeTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override {
    if (did_lose_context)
      return;
    did_lose_context = true;
    viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
        host_impl->layer_tree_frame_sink()->worker_context_provider());
    gpu::raster::RasterInterface* ri = scoped_context.RasterInterface();
    ri->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                            GL_INNOCENT_CONTEXT_RESET_ARB);
  }

  void DidInitializeLayerTreeFrameSink() override { num_frame_sinks_++; }

  void DidCommitAndDrawFrame() override { EndTest(); }

  void AfterTest() override {
    EXPECT_TRUE(did_lose_context);
    EXPECT_EQ(num_frame_sinks_, 2);
  }

  FakeContentLayerClient client_;
  bool did_lose_context = false;
  int num_frame_sinks_ = 0;
};

MULTI_THREAD_TEST_F(LayerTreeHostContextTestWorkerContextLostRecovery);

}  // namespace
}  // namespace cc
