// Copyright 2016 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 "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"

#include <memory>

#include "base/test/simple_test_tick_clock.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/skia/include/core/SkSurface.h"

using testing::_;
using testing::Mock;

namespace blink {

class MockCanvasResourceDispatcher : public CanvasResourceDispatcher {
 public:
  MockCanvasResourceDispatcher()
      : CanvasResourceDispatcher(nullptr, 0, 0, 0, {10, 10}) {}

  MOCK_METHOD2(PostImageToPlaceholder,
               void(scoped_refptr<CanvasResource>, unsigned resource_id));
};

class CanvasResourceDispatcherTest : public testing::Test {
 public:
  void DispatchOneFrame();
  OffscreenCanvasResourceProvider* GetResourceProvider() {
    return dispatcher_->offscreen_canvas_resource_provider_.get();
  }

  unsigned GetNumUnreclaimedFramesPosted() {
    return dispatcher_->num_unreclaimed_frames_posted_;
  }

  CanvasResource* GetLatestUnpostedImage() {
    return dispatcher_->latest_unposted_image_.get();
  }

  unsigned GetLatestUnpostedResourceId() {
    return dispatcher_->latest_unposted_resource_id_;
  }

 protected:
  CanvasResourceDispatcherTest() {
    dispatcher_ = std::make_unique<MockCanvasResourceDispatcher>();
    resource_provider_ = CanvasResourceProvider::Create(
        IntSize(10, 10),
        CanvasResourceProvider::kSoftwareCompositedResourceUsage,
        nullptr,  // context_provider_wrapper
        0,        // msaa_sample_count
        CanvasColorParams(), CanvasResourceProvider::kDefaultPresentationMode,
        dispatcher_->GetWeakPtr());
  }

  MockCanvasResourceDispatcher* Dispatcher() { return dispatcher_.get(); }

 private:
  scoped_refptr<StaticBitmapImage> PrepareStaticBitmapImage();
  std::unique_ptr<MockCanvasResourceDispatcher> dispatcher_;
  std::unique_ptr<CanvasResourceProvider> resource_provider_;
};

void CanvasResourceDispatcherTest::DispatchOneFrame() {
  dispatcher_->DispatchFrame(resource_provider_->ProduceFrame(),
                             base::TimeTicks(), SkIRect::MakeEmpty());
}

TEST_F(CanvasResourceDispatcherTest, PlaceholderRunsNormally) {
  /* We allow OffscreenCanvas to post up to 3 frames without hearing a response
   * from placeholder. */
  // Post first frame
  unsigned post_resource_id = 1u;
  EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
  DispatchOneFrame();
  EXPECT_EQ(1u, GetNumUnreclaimedFramesPosted());
  EXPECT_EQ(1u, GetResourceProvider()->GetNextResourceId());
  Mock::VerifyAndClearExpectations(Dispatcher());

  // Post second frame
  post_resource_id++;
  EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
  DispatchOneFrame();
  EXPECT_EQ(2u, GetNumUnreclaimedFramesPosted());
  EXPECT_EQ(2u, GetResourceProvider()->GetNextResourceId());
  Mock::VerifyAndClearExpectations(Dispatcher());

  // Post third frame
  post_resource_id++;
  EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
  DispatchOneFrame();
  EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
  EXPECT_EQ(3u, GetResourceProvider()->GetNextResourceId());
  EXPECT_EQ(nullptr, GetLatestUnpostedImage());
  Mock::VerifyAndClearExpectations(Dispatcher());

  /* We mock the behavior of placeholder on main thread here, by reclaiming
   * the resources in order. */
  // Reclaim first frame
  unsigned reclaim_resource_id = 1u;
  Dispatcher()->ReclaimResource(reclaim_resource_id);
  EXPECT_EQ(2u, GetNumUnreclaimedFramesPosted());

  // Reclaim second frame
  reclaim_resource_id++;
  Dispatcher()->ReclaimResource(reclaim_resource_id);
  EXPECT_EQ(1u, GetNumUnreclaimedFramesPosted());

  // Reclaim third frame
  reclaim_resource_id++;
  Dispatcher()->ReclaimResource(reclaim_resource_id);
  EXPECT_EQ(0u, GetNumUnreclaimedFramesPosted());
}

TEST_F(CanvasResourceDispatcherTest, PlaceholderBeingBlocked) {
  /* When main thread is blocked, attempting to post more than 3 frames will
   * result in only 3 PostImageToPlaceholder. The latest unposted image will
   * be saved. */
  EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, _)).Times(3);

  // Attempt to post 4 times
  DispatchOneFrame();
  DispatchOneFrame();
  DispatchOneFrame();
  DispatchOneFrame();
  unsigned post_resource_id = 4u;
  EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
  EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
  EXPECT_TRUE(GetLatestUnpostedImage());
  EXPECT_EQ(post_resource_id, GetLatestUnpostedResourceId());

  // Attempt to post the 5th time. The latest unposted image will be replaced.
  post_resource_id++;
  DispatchOneFrame();
  EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
  EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
  EXPECT_TRUE(GetLatestUnpostedImage());
  EXPECT_EQ(post_resource_id, GetLatestUnpostedResourceId());

  Mock::VerifyAndClearExpectations(Dispatcher());

  /* When main thread becomes unblocked, the first reclaim called by placeholder
   * will trigger CanvasResourceDispatcher to post the last saved image.
   * Resource reclaim happens in the same order as frame posting. */
  unsigned reclaim_resource_id = 1u;
  EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
  Dispatcher()->ReclaimResource(reclaim_resource_id);
  // Reclaim 1 frame and post 1 frame, so numPostImagesUnresponded remains as 3
  EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
  // Not generating new resource Id
  EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
  EXPECT_FALSE(GetLatestUnpostedImage());
  EXPECT_EQ(0u, GetLatestUnpostedResourceId());
  Mock::VerifyAndClearExpectations(Dispatcher());

  reclaim_resource_id++;
  Dispatcher()->ReclaimResource(reclaim_resource_id);
  EXPECT_EQ(2u, GetNumUnreclaimedFramesPosted());
}

}  // namespace blink
