blob: b032aa0250695ebcabeafb5e5d529e318408753a [file] [log] [blame]
// Copyright (c) 2006-2008 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 "gpu/command_buffer/common/command_buffer_mock.h"
#include "gpu/gpu_plugin/gpu_plugin_object.h"
#include "gpu/command_buffer/service/gpu_processor_mock.h"
#include "gpu/np_utils/np_browser_mock.h"
#include "gpu/np_utils/dynamic_np_object.h"
#include "gpu/np_utils/np_object_mock.h"
#include "gpu/np_utils/np_object_pointer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "webkit/glue/plugins/nphostapi.h"
using ::base::SharedMemory;
using command_buffer::GPUProcessor;
using command_buffer::MockCommandBuffer;
using command_buffer::MockGPUProcessor;
using np_utils::MockNPBrowser;
using np_utils::NPBrowser;
using np_utils::NPObjectPointer;
using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::NotNull;
using testing::Return;
using testing::SetArgumentPointee;
using testing::StrictMock;
namespace gpu_plugin {
class GPUPluginObjectTest : public testing::Test {
protected:
virtual void SetUp() {
plugin_object_ = np_utils::NPCreateObject<GPUPluginObject>(NULL);
command_buffer_ = new MockCommandBuffer;
// Takes ownership.
plugin_object_->set_command_buffer(command_buffer_);
processor_ = new MockGPUProcessor(command_buffer_);
plugin_object_->set_gpu_processor(processor_.get());
}
MockNPBrowser mock_browser_;
NPObjectPointer<GPUPluginObject> plugin_object_;
MockCommandBuffer* command_buffer_;
scoped_refptr<MockGPUProcessor> processor_;
};
namespace {
template <typename T>
void DeleteObject(T* object) {
delete object;
}
} // namespace anonymous
TEST_F(GPUPluginObjectTest, CanInstantiateAndDestroyPluginObject) {
EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
}
TEST_F(GPUPluginObjectTest, DestroyFailsIfNotInitialized) {
EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->Destroy(NULL));
}
TEST_F(GPUPluginObjectTest, NewFailsIfAlreadyInitialized) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
}
TEST_F(GPUPluginObjectTest, NewFailsIfObjectHasPreviouslyBeenDestroyed) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus());
}
TEST_F(GPUPluginObjectTest, WindowIsNullBeforeSetWindowCalled) {
NPWindow window = plugin_object_->GetWindow();
EXPECT_EQ(NULL, window.window);
}
TEST_F(GPUPluginObjectTest, CanSetWindow) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
NPWindow window = {0};
window.window = &window;
window.x = 7;
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window));
EXPECT_EQ(0, memcmp(&window, &plugin_object_->GetWindow(), sizeof(window)));
EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
TEST_F(GPUPluginObjectTest, CanGetWindowSize) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
NPWindow window = {0};
window.window = &window;
window.x = 10;
window.y = 10;
window.width = 100;
window.height = 200;
EXPECT_EQ(0, plugin_object_->GetWidth());
EXPECT_EQ(0, plugin_object_->GetHeight());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window));
EXPECT_EQ(100, plugin_object_->GetWidth());
EXPECT_EQ(200, plugin_object_->GetHeight());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
TEST_F(GPUPluginObjectTest, SetWindowFailsIfNotInitialized) {
NPWindow window = {0};
EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->SetWindow(&window));
EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus());
}
TEST_F(GPUPluginObjectTest, CanGetScriptableNPObject) {
NPObject* scriptable_object = plugin_object_->GetScriptableNPObject();
EXPECT_EQ(plugin_object_.Get(), scriptable_object);
NPBrowser::get()->ReleaseObject(scriptable_object);
}
TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsInitializedCommandBuffer) {
EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
.WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
Return(true)));
EXPECT_CALL(*processor_.get(), Initialize(NULL))
.WillOnce(Return(true));
EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NotNull()))
.WillOnce(Invoke(DeleteObject<Callback0::Type>));
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
// Set status as though SetWindow has been called. Avoids having to create a
// valid window handle to pass to SetWindow in tests.
plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer());
// Calling OpenCommandBuffer again just returns the existing command buffer.
EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer());
EXPECT_EQ(GPUPluginObject::kInitializationSuccessful,
plugin_object_->GetStatus());
EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NULL));
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsNullIfWindowNotReady) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
// Set status as though SetWindow has not been called.
plugin_object_->set_status(GPUPluginObject::kWaitingForSetWindow);
EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus());
}
TEST_F(GPUPluginObjectTest,
OpenCommandBufferReturnsNullIfCommandBufferCannotInitialize) {
EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
.WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
Return(false)));
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
// Set status as though SetWindow has been called. Avoids having to create a
// valid window handle to pass to SetWindow in tests.
plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
TEST_F(GPUPluginObjectTest,
OpenCommandBufferReturnsNullIGPUProcessorCannotInitialize) {
EXPECT_CALL(*command_buffer_, Initialize(NotNull()))
.WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>),
Return(true)));
EXPECT_CALL(*processor_.get(), Initialize(NULL))
.WillOnce(Return(false));
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
// Set status as though SetWindow has been called. Avoids having to create a
// valid window handle to pass to SetWindow in tests.
plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer);
EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer());
EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer,
plugin_object_->GetStatus());
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
class MockEventSync : public np_utils::DefaultNPObject<NPObject> {
public:
explicit MockEventSync(NPP npp) {
}
MOCK_METHOD2(Resize, void(int32 width, int32 height));
NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockEventSync, DefaultNPObject<NPObject>)
NP_UTILS_DISPATCHER(Resize, void(int32 width, int32 height))
NP_UTILS_END_DISPATCHER_CHAIN
private:
DISALLOW_COPY_AND_ASSIGN(MockEventSync);
};
TEST_F(GPUPluginObjectTest, SendsResizeEventOnSetWindow) {
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo",
0,
NULL,
NULL,
NULL));
NPObjectPointer<MockEventSync> event_sync =
np_utils::NPCreateObject<MockEventSync>(NULL);
plugin_object_->SetEventSync(event_sync);
EXPECT_CALL(*event_sync.Get(), Resize(100, 200));
NPWindow window = {0};
window.window = &window;
window.x = 10;
window.y = 10;
window.width = 100;
window.height = 200;
plugin_object_->SetWindow(&window);
EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL));
}
} // namespace gpu_plugin