root/gpu/command_buffer/service/gpu_scheduler_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SetUp
  2. TearDown
  3. GetError
  4. TEST_F
  5. TEST_F
  6. TEST_F
  7. TEST_F
  8. TEST_F
  9. TEST_F
  10. TEST_F
  11. ACTION_P2
  12. TEST_F
  13. TEST_F

// Copyright (c) 2011 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 "base/message_loop/message_loop.h"
#include "gpu/command_buffer/common/command_buffer_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "gpu/command_buffer/service/mocks.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#endif

using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::SetArgumentPointee;
using testing::StrictMock;

namespace gpu {

const size_t kRingBufferSize = 1024;
const size_t kRingBufferEntries = kRingBufferSize / sizeof(CommandBufferEntry);

class GpuSchedulerTest : public testing::Test {
 protected:
  static const int32 kTransferBufferId = 123;

  virtual void SetUp() {
    scoped_ptr<base::SharedMemory> shared_memory(new ::base::SharedMemory);
    shared_memory->CreateAndMapAnonymous(kRingBufferSize);
    buffer_ = static_cast<int32*>(shared_memory->memory());
    shared_memory_buffer_ =
        MakeBufferFromSharedMemory(shared_memory.Pass(), kRingBufferSize);
    memset(buffer_, 0, kRingBufferSize);

    command_buffer_.reset(new MockCommandBuffer);

    CommandBuffer::State default_state;
    default_state.num_entries = kRingBufferEntries;
    ON_CALL(*command_buffer_.get(), GetState())
        .WillByDefault(Return(default_state));

    decoder_.reset(new gles2::MockGLES2Decoder());
    scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
                                           decoder_.get(),
                                           decoder_.get()));
    EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
       .WillOnce(Return(shared_memory_buffer_));
    EXPECT_CALL(*command_buffer_, SetGetOffset(0));
    EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));
  }

  virtual void TearDown() {
    // Ensure that any unexpected tasks posted by the GPU scheduler are executed
    // in order to fail the test.
    base::MessageLoop::current()->RunUntilIdle();
  }

  error::Error GetError() {
    return command_buffer_->GetState().error;
  }

#if defined(OS_MACOSX)
  base::mac::ScopedNSAutoreleasePool autorelease_pool_;
#endif
  base::MessageLoop message_loop;
  scoped_ptr<MockCommandBuffer> command_buffer_;
  scoped_refptr<Buffer> shared_memory_buffer_;
  int32* buffer_;
  scoped_ptr<gles2::MockGLES2Decoder> decoder_;
  scoped_ptr<GpuScheduler> scheduler_;
};

TEST_F(GpuSchedulerTest, SchedulerDoesNothingIfRingBufferIsEmpty) {
  CommandBuffer::State state;

  state.put_offset = 0;
  EXPECT_CALL(*command_buffer_, GetState())
    .WillRepeatedly(Return(state));

  EXPECT_CALL(*command_buffer_, SetParseError(_))
    .Times(0);

  scheduler_->PutChanged();
}

TEST_F(GpuSchedulerTest, GetSetBuffer) {
  CommandBuffer::State state;

  // Set the get offset to something not 0.
  EXPECT_CALL(*command_buffer_, SetGetOffset(2));
  scheduler_->SetGetOffset(2);
  EXPECT_EQ(2, scheduler_->GetGetOffset());

  // Set the buffer.
  EXPECT_CALL(*command_buffer_, GetTransferBuffer(kTransferBufferId))
     .WillOnce(Return(shared_memory_buffer_));
  EXPECT_CALL(*command_buffer_, SetGetOffset(0));
  EXPECT_TRUE(scheduler_->SetGetBuffer(kTransferBufferId));

  // Check the get offset was reset.
  EXPECT_EQ(0, scheduler_->GetGetOffset());
}

TEST_F(GpuSchedulerTest, ProcessesOneCommand) {
  CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
  header[0].command = 7;
  header[0].size = 2;
  buffer_[1] = 123;

  CommandBuffer::State state;

  state.put_offset = 2;
  EXPECT_CALL(*command_buffer_, GetState())
    .WillRepeatedly(Return(state));
  EXPECT_CALL(*command_buffer_, SetGetOffset(2));

  EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    .WillOnce(Return(error::kNoError));

  EXPECT_CALL(*command_buffer_, SetParseError(_))
    .Times(0);

  scheduler_->PutChanged();
}

TEST_F(GpuSchedulerTest, ProcessesTwoCommands) {
  CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
  header[0].command = 7;
  header[0].size = 2;
  buffer_[1] = 123;
  header[2].command = 8;
  header[2].size = 1;

  CommandBuffer::State state;

  state.put_offset = 3;
  EXPECT_CALL(*command_buffer_, GetState())
    .WillRepeatedly(Return(state));

  EXPECT_CALL(*decoder_, DoCommand(7, 1, &buffer_[0]))
    .WillOnce(Return(error::kNoError));
  EXPECT_CALL(*command_buffer_, SetGetOffset(2));

  EXPECT_CALL(*decoder_, DoCommand(8, 0, &buffer_[2]))
    .WillOnce(Return(error::kNoError));
  EXPECT_CALL(*command_buffer_, SetGetOffset(3));

  scheduler_->PutChanged();
}

TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) {
  CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
  header[0].command = 7;
  header[0].size = 1;

  CommandBuffer::State state;

  state.put_offset = 1;
  EXPECT_CALL(*command_buffer_, GetState())
    .WillRepeatedly(Return(state));

  EXPECT_CALL(*decoder_, DoCommand(7, 0, &buffer_[0]))
    .WillOnce(Return(
        error::kUnknownCommand));
  EXPECT_CALL(*command_buffer_, SetGetOffset(1));

  EXPECT_CALL(*command_buffer_, SetContextLostReason(_));
  EXPECT_CALL(*decoder_, GetContextLostReason())
    .WillOnce(Return(error::kUnknown));
  EXPECT_CALL(*command_buffer_,
      SetParseError(error::kUnknownCommand));

  scheduler_->PutChanged();
}

TEST_F(GpuSchedulerTest, ProcessCommandsDoesNothingAfterError) {
  CommandBuffer::State state;
  state.error = error::kGenericError;

  EXPECT_CALL(*command_buffer_, GetState())
    .WillRepeatedly(Return(state));

  scheduler_->PutChanged();
}

TEST_F(GpuSchedulerTest, CanGetAddressOfSharedMemory) {
  EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    .WillOnce(Return(shared_memory_buffer_));

  EXPECT_EQ(&buffer_[0], scheduler_->GetSharedMemoryBuffer(7)->memory());
}

ACTION_P2(SetPointee, address, value) {
  *address = value;
}

TEST_F(GpuSchedulerTest, CanGetSizeOfSharedMemory) {
  EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7))
    .WillOnce(Return(shared_memory_buffer_));

  EXPECT_EQ(kRingBufferSize, scheduler_->GetSharedMemoryBuffer(7)->size());
}

TEST_F(GpuSchedulerTest, SetTokenForwardsToCommandBuffer) {
  EXPECT_CALL(*command_buffer_, SetToken(7));
  scheduler_->set_token(7);
}

}  // namespace gpu

/* [<][>][^][v][top][bottom][index][help] */