12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 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)// Tests for the BufferTracker.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/client/buffer_tracker.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <GLES2/gl2ext.h>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/client/client_test_helper.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_cmd_helper.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/client/mapped_memory.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/common/command_buffer.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gpu {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gles2 {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockClientCommandBufferImpl : public MockClientCommandBuffer {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockClientCommandBufferImpl()
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : MockClientCommandBuffer(),
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        context_lost_(false) {}
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MockClientCommandBufferImpl() {}
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                          int32* id) OVERRIDE {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (context_lost_) {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *id = -1;
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return NULL;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return MockClientCommandBuffer::CreateTransferBuffer(size, id);
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_context_lost(bool context_lost) {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    context_lost_ = context_lost;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool context_lost_;
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
454ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochnamespace {
464ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid EmptyPoll() {
474ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch}
484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch}
494ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BufferTrackerTest : public testing::Test {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const int32 kNumCommandEntries = 400;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const int32 kCommandBufferSizeBytes =
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kNumCommandEntries * sizeof(CommandBufferEntry);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    command_buffer_.reset(new MockClientCommandBufferImpl());
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper_->Initialize(kCommandBufferSizeBytes);
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mapped_memory_.reset(new MappedMemoryManager(
614ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit));
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    buffer_tracker_.reset();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mapped_memory_.reset();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper_.reset();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_buffer_.reset();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<MockClientCommandBufferImpl> command_buffer_;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<GLES2CmdHelper> helper_;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<MappedMemoryManager> mapped_memory_;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<BufferTracker> buffer_tracker_;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(BufferTrackerTest, Basic) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GLuint kId1 = 123;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GLuint kId2 = 124;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GLsizeiptr size = 64;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we can create a Buffer.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId1, size);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(buffer != NULL);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we can get the same Buffer.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(buffer, buffer_tracker_->GetBuffer(kId1));
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check mapped memory address.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(buffer->address() != NULL);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check shared memory was allocated.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1lu, mapped_memory_->num_chunks());
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we get nothing for a non-existent buffer.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(buffer_tracker_->GetBuffer(kId2) == NULL);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we can delete the buffer.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffer_tracker_->RemoveBuffer(kId1);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check shared memory was freed.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped_memory_->FreeUnused();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we get nothing for a non-existent buffer.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(buffer_tracker_->GetBuffer(kId1) == NULL);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(BufferTrackerTest, ZeroSize) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GLuint kId = 123;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we can create a Buffer with zero size.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, 0);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(buffer != NULL);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check mapped memory address.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(buffer->address() == NULL);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check no shared memory was allocated.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check we can delete the buffer.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffer_tracker_->RemoveBuffer(kId);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(BufferTrackerTest, LostContext) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GLuint kId = 123;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GLsizeiptr size = 64;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  command_buffer_->set_context_lost(true);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check we can create a Buffer when after losing context.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, size);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(buffer != NULL);
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check mapped memory address.
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(64u, buffer->size());
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check mapped memory address.
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(buffer->address() == NULL);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check no shared memory was allocated.
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0lu, mapped_memory_->num_chunks());
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check we can delete the buffer.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  buffer_tracker_->RemoveBuffer(kId);
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1354ad1aa43a48567659193a298fad74f55e00b3dd9Ben MurdochTEST_F(BufferTrackerTest, Unmanage) {
1364ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  const GLuint kId = 123;
1374ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  const GLsizeiptr size = 64;
1384ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
1394ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  BufferTracker::Buffer* buffer = buffer_tracker_->CreateBuffer(kId, size);
1404ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  ASSERT_TRUE(buffer != NULL);
1414ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(size));
1424ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
1434ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  void* mem = buffer->address();
1444ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  buffer_tracker_->Unmanage(buffer);
1454ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  buffer_tracker_->RemoveBuffer(kId);
1464ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(size));
1474ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
1484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  mapped_memory_->Free(mem);
1494ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  EXPECT_EQ(mapped_memory_->bytes_in_use(), static_cast<size_t>(0));
1504ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch}
1514ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace gles2
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace gpu
154