// Copyright 2018 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 <stdint.h>

#include "media/gpu/ipc/service/picture_buffer_manager.h"

#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "media/base/simple_sync_token_client.h"
#include "media/gpu/test/fake_command_buffer_helper.h"
#include "media/video/video_decode_accelerator.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

class PictureBufferManagerImplTest : public testing::Test {
 public:
  explicit PictureBufferManagerImplTest() {
    // TODO(sandersd): Use a separate thread for the GPU task runner.
    cbh_ = base::MakeRefCounted<FakeCommandBufferHelper>(
        environment_.GetMainThreadTaskRunner());
    pbm_ = PictureBufferManager::Create(reuse_cb_.Get());
  }

  PictureBufferManagerImplTest(const PictureBufferManagerImplTest&) = delete;
  PictureBufferManagerImplTest& operator=(const PictureBufferManagerImplTest&) =
      delete;

  ~PictureBufferManagerImplTest() override {
    // Drop ownership of anything that may have an async destruction process,
    // then allow destruction to complete.
    cbh_->StubLost();
    cbh_ = nullptr;
    pbm_ = nullptr;
    environment_.RunUntilIdle();
  }

 protected:
  void Initialize() {
    pbm_->Initialize(environment_.GetMainThreadTaskRunner(), cbh_);
  }

  std::vector<PictureBuffer> CreateARGBPictureBuffers(
      uint32_t count,
      VideoDecodeAccelerator::TextureAllocationMode mode =
          VideoDecodeAccelerator::TextureAllocationMode::kAllocateGLTextures) {
    return pbm_->CreatePictureBuffers(count, PIXEL_FORMAT_ARGB, 1,
                                      gfx::Size(320, 240), GL_TEXTURE_2D, mode);
  }

  PictureBuffer CreateARGBPictureBuffer(
      VideoDecodeAccelerator::TextureAllocationMode mode =
          VideoDecodeAccelerator::TextureAllocationMode::kAllocateGLTextures) {
    std::vector<PictureBuffer> picture_buffers =
        CreateARGBPictureBuffers(1, mode);
    DCHECK_EQ(picture_buffers.size(), 1U);
    return picture_buffers[0];
  }

  scoped_refptr<VideoFrame> CreateVideoFrame(int32_t picture_buffer_id) {
    return pbm_->CreateVideoFrame(
        Picture(picture_buffer_id,              // picture_buffer_id
                0,                              // bitstream_buffer_id
                gfx::Rect(),                    // visible_rect (ignored)
                gfx::ColorSpace::CreateSRGB(),  // color_space
                false),                         // allow_overlay
        base::TimeDelta(),                      // timestamp
        gfx::Rect(1, 1),                        // visible_rect
        gfx::Size(1, 1));                       // natural_size
  }

  gpu::SyncToken GenerateSyncToken(scoped_refptr<VideoFrame> video_frame) {
    gpu::SyncToken sync_token(gpu::GPU_IO,
                              gpu::CommandBufferId::FromUnsafeValue(1),
                              next_release_count_++);
    SimpleSyncTokenClient sync_token_client(sync_token);
    video_frame->UpdateReleaseSyncToken(&sync_token_client);
    return sync_token;
  }

  base::test::TaskEnvironment environment_;

  uint64_t next_release_count_ = 1;
  testing::StrictMock<
      base::MockCallback<PictureBufferManager::ReusePictureBufferCB>>
      reuse_cb_;
  scoped_refptr<FakeCommandBufferHelper> cbh_;
  scoped_refptr<PictureBufferManager> pbm_;
};

TEST_F(PictureBufferManagerImplTest, CreateAndDestroy) {}

TEST_F(PictureBufferManagerImplTest, Initialize) {
  Initialize();
}

TEST_F(PictureBufferManagerImplTest, CreatePictureBuffer) {
  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));
}

TEST_F(PictureBufferManagerImplTest, CreatePictureBuffer_SharedImage) {
  Initialize();
  PictureBuffer pb1 = CreateARGBPictureBuffer(
      VideoDecodeAccelerator::TextureAllocationMode::kDoNotAllocateGLTextures);
  EXPECT_EQ(pb1.client_texture_ids().size(), 0u);

  PictureBuffer pb2 = CreateARGBPictureBuffer(
      VideoDecodeAccelerator::TextureAllocationMode::kAllocateGLTextures);
  EXPECT_TRUE(cbh_->HasTexture(pb2.client_texture_ids()[0]));
}

TEST_F(PictureBufferManagerImplTest, CreatePictureBuffer_ContextLost) {
  Initialize();
  cbh_->ContextLost();
  std::vector<PictureBuffer> pbs = CreateARGBPictureBuffers(1);
  EXPECT_TRUE(pbs.empty());
}

TEST_F(PictureBufferManagerImplTest, ReusePictureBuffer) {
  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  scoped_refptr<VideoFrame> frame = CreateVideoFrame(pb.id());
  gpu::SyncToken sync_token = GenerateSyncToken(frame);

  // Dropping the frame does not immediately trigger reuse.
  frame = nullptr;
  environment_.RunUntilIdle();

  // Completing the SyncToken wait does.
  EXPECT_CALL(reuse_cb_, Run(pb.id()));
  cbh_->ReleaseSyncToken(sync_token);
  environment_.RunUntilIdle();
}

TEST_F(PictureBufferManagerImplTest, ReusePictureBuffer_MultipleOutputs) {
  constexpr size_t kOutputCountPerPictureBuffer = 3;

  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  std::vector<scoped_refptr<VideoFrame>> frames;
  std::vector<gpu::SyncToken> sync_tokens;
  for (size_t i = 0; i < kOutputCountPerPictureBuffer; i++) {
    scoped_refptr<VideoFrame> frame = CreateVideoFrame(pb.id());
    frames.push_back(frame);
    sync_tokens.push_back(GenerateSyncToken(frame));
  }

  // Dropping the frames does not immediately trigger reuse.
  frames.clear();
  environment_.RunUntilIdle();

  // Completing the SyncToken waits does. (Clients are expected to wait for the
  // output count to reach zero before actually reusing the picture buffer.)
  EXPECT_CALL(reuse_cb_, Run(pb.id())).Times(kOutputCountPerPictureBuffer);
  for (const auto& sync_token : sync_tokens)
    cbh_->ReleaseSyncToken(sync_token);
  environment_.RunUntilIdle();
}

TEST_F(PictureBufferManagerImplTest, DismissPictureBuffer_Available) {
  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  pbm_->DismissPictureBuffer(pb.id());

  // Allocated textures should be deleted soon.
  environment_.RunUntilIdle();
  EXPECT_FALSE(cbh_->HasTexture(pb.client_texture_ids()[0]));
}

TEST_F(PictureBufferManagerImplTest, DismissPictureBuffer_Output) {
  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  scoped_refptr<VideoFrame> frame = CreateVideoFrame(pb.id());
  gpu::SyncToken sync_token = GenerateSyncToken(frame);
  pbm_->DismissPictureBuffer(pb.id());

  // Allocated textures should not be deleted while the VideoFrame exists.
  environment_.RunUntilIdle();
  EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));

  // Or after it has been returned.
  frame = nullptr;
  environment_.RunUntilIdle();
  EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));

  // The textures should be deleted once the the wait has completed. The reuse
  // callback should not be called for a dismissed picture buffer.
  cbh_->ReleaseSyncToken(sync_token);
  environment_.RunUntilIdle();
  EXPECT_FALSE(cbh_->HasTexture(pb.client_texture_ids()[0]));
}

TEST_F(PictureBufferManagerImplTest, DismissPictureBuffer_MultipleOutputs) {
  constexpr size_t kOutputCountPerPictureBuffer = 3;

  Initialize();
  PictureBuffer pb = CreateARGBPictureBuffer();
  std::vector<scoped_refptr<VideoFrame>> frames;
  std::vector<gpu::SyncToken> sync_tokens;
  for (size_t i = 0; i < kOutputCountPerPictureBuffer; i++) {
    scoped_refptr<VideoFrame> frame = CreateVideoFrame(pb.id());
    frames.push_back(frame);
    sync_tokens.push_back(GenerateSyncToken(frame));
  }
  pbm_->DismissPictureBuffer(pb.id());

  // Allocated textures should not be deleted while the VideoFrames exists.
  environment_.RunUntilIdle();
  EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));

  // Or after they have been returned.
  frames.clear();
  environment_.RunUntilIdle();
  EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));

  // The textures should be deleted only once all of the waits have completed.
  for (size_t i = 0; i < kOutputCountPerPictureBuffer; i++) {
    cbh_->ReleaseSyncToken(sync_tokens[i]);
    environment_.RunUntilIdle();
    if (i < kOutputCountPerPictureBuffer - 1) {
      EXPECT_TRUE(cbh_->HasTexture(pb.client_texture_ids()[0]));
    } else {
      EXPECT_FALSE(cbh_->HasTexture(pb.client_texture_ids()[0]));
    }
  }
}

TEST_F(PictureBufferManagerImplTest, CanReadWithoutStalling) {
  // Works before Initialize().
  EXPECT_TRUE(pbm_->CanReadWithoutStalling());

  // True before any picture buffers are allocated.
  Initialize();
  EXPECT_TRUE(pbm_->CanReadWithoutStalling());

  // True when a picture buffer is available.
  PictureBuffer pb = CreateARGBPictureBuffer();
  EXPECT_TRUE(pbm_->CanReadWithoutStalling());

  // False when all picture buffers are used.
  scoped_refptr<VideoFrame> frame = CreateVideoFrame(pb.id());
  EXPECT_FALSE(pbm_->CanReadWithoutStalling());

  // True once a picture buffer is returned.
  frame = nullptr;
  EXPECT_TRUE(pbm_->CanReadWithoutStalling());

  // True after all picture buffers have been dismissed.
  pbm_->DismissPictureBuffer(pb.id());
  EXPECT_TRUE(pbm_->CanReadWithoutStalling());
}

}  // namespace media
