// Copyright 2013 The Flutter 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 "flutter/testing/testing.h"
#include "gtest/gtest.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/backend/vulkan/texture_vk.h"
#include "impeller/renderer/render_target.h"

namespace impeller {
namespace testing {

using RendererTest = PlaygroundTest;

TEST_P(RendererTest, CachesRenderPassAndFramebuffer) {
  if (GetBackend() != PlaygroundBackend::kVulkan) {
    GTEST_SKIP() << "Test only applies to Vulkan";
  }

  auto allocator = std::make_shared<RenderTargetAllocator>(
      GetContext()->GetResourceAllocator());

  auto render_target = RenderTarget::CreateOffscreenMSAA(
      *GetContext(), *allocator, {100, 100}, 1);
  auto resolve_texture =
      render_target.GetColorAttachments().find(0u)->second.resolve_texture;
  auto& texture_vk = TextureVK::Cast(*resolve_texture);

  EXPECT_EQ(texture_vk.GetFramebuffer(), nullptr);
  EXPECT_EQ(texture_vk.GetRenderPass(), nullptr);

  auto buffer = GetContext()->CreateCommandBuffer();
  auto render_pass = buffer->CreateRenderPass(render_target);

  EXPECT_NE(texture_vk.GetFramebuffer(), nullptr);
  EXPECT_NE(texture_vk.GetRenderPass(), nullptr);

  render_pass->EncodeCommands();
  GetContext()->GetCommandQueue()->Submit({buffer});

  // Can be reused without error.
  auto buffer_2 = GetContext()->CreateCommandBuffer();
  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);

  EXPECT_TRUE(render_pass_2->EncodeCommands());
  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
}

}  // namespace testing
}  // namespace impeller
