Index: gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc |
index 1c0ec4e0dc1ee2d2c4f261cf1bddc7aef81eef24..1c2537b488c6c78c815ee7640b15eea81a5f3d70 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc |
@@ -8,6 +8,7 @@ |
#include "gpu/command_buffer/common/gles2_cmd_format.h" |
#include "gpu/command_buffer/common/gles2_cmd_utils.h" |
#include "gpu/command_buffer/common/id_allocator.h" |
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h" |
#include "gpu/command_buffer/service/cmd_buffer_engine.h" |
#include "gpu/command_buffer/service/context_group.h" |
#include "gpu/command_buffer/service/gl_surface_mock.h" |
@@ -30,6 +31,7 @@ |
using ::gfx::MockGLInterface; |
using ::testing::_; |
+using ::testing::DefaultValue; |
using ::testing::DoAll; |
using ::testing::InSequence; |
using ::testing::Invoke; |
@@ -38,6 +40,7 @@ using ::testing::Pointee; |
using ::testing::Return; |
using ::testing::SetArrayArgument; |
using ::testing::SetArgumentPointee; |
+using ::testing::SetArgPointee; |
using ::testing::StrEq; |
using ::testing::StrictMock; |
@@ -7935,6 +7938,138 @@ TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) { |
EXPECT_TRUE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL); |
} |
+TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransfers) { |
+ InitDecoder( |
+ "GL_CHROMIUM_async_pixel_transfers", // extensions |
+ false, false, false, // has alpha/depth/stencil |
+ false, false, false, // request alpha/depth/stencil |
+ true); // bind generates resource |
+ |
+ // Set up the texture. |
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); |
+ TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); |
+ |
+ // Set a mock AsyncPixelTransferDelegate |
+ StrictMock<gfx::MockAsyncPixelTransferDelegate>* delegate = |
+ new StrictMock<gfx::MockAsyncPixelTransferDelegate>; |
+ decoder_->SetAsyncPixelTransferDelegate(delegate); |
+ |
+ // Set a default mock AsyncPixelTransferState |
+ scoped_refptr<StrictMock<gfx::MockAsyncPixelTransferState> > state = |
+ new StrictMock<gfx::MockAsyncPixelTransferState>; |
+ DefaultValue<scoped_refptr<gfx::AsyncPixelTransferState> >::Set(state); |
+ |
+ // Tex(Sub)Image2D upload commands. |
+ AsyncTexImage2DCHROMIUM teximage_cmd; |
+ teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, |
+ GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset); |
+ AsyncTexSubImage2DCHROMIUM texsubimage_cmd; |
+ texsubimage_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, |
+ GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset); |
+ gfx::AsyncTexImage2DParams teximage_params = |
+ {GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE}; |
+ |
+ // No transfer state exists initially. |
+ EXPECT_FALSE(info->GetAsyncTransferState()); |
+ |
+ // AsyncTexImage2D |
+ { |
+ // Create transfer state since it doesn't exist. |
+ EXPECT_CALL(*delegate, CreatePixelTransferState(kServiceTextureId)) |
+ .WillOnce(Return(state)) |
+ .RetiresOnSaturation(); |
+ EXPECT_CALL(*delegate, AsyncTexImage2D(state.get(), _, _)) |
+ .RetiresOnSaturation(); |
+ // Command succeeds. |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ EXPECT_TRUE(info->GetAsyncTransferState()); |
+ EXPECT_TRUE(info->IsImmutable()); |
+ // The texture is safe but the level has not been defined yet. |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ GLsizei width, height; |
+ EXPECT_FALSE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); |
+ } |
+ { |
+ // Async redefinitions are not allowed! |
+ // Command fails. |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ EXPECT_TRUE(info->GetAsyncTransferState()); |
+ EXPECT_TRUE(info->IsImmutable()); |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ } |
+ // Lazy binding/defining of the async transfer |
+ { |
+ // We should get a real glBindTexture, followed by |
+ // a lazy BindTransfer call on the async state. |
+ // The texture becomes defined after the BindTransfer succeeds. |
+ InSequence scoped_in_sequence; |
+ EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId)); |
+ EXPECT_CALL(*state.get(), BindTransfer(GL_TEXTURE_2D, _)) |
+ .WillOnce(DoAll(SetArgPointee<1>(teximage_params), |
+ Return(true))) |
+ .RetiresOnSaturation(); |
+ BindTexture bind_cmd; |
+ bind_cmd.Init(GL_TEXTURE_2D, client_texture_id_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(bind_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ GLsizei width, height; |
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); |
+ EXPECT_EQ(width, 8); |
+ EXPECT_EQ(height, 8); |
+ } |
+ |
+ // AsyncTexSubImage2D |
+ info->SetAsyncTransferState(NULL); |
+ info->SetImmutable(false); |
+ { |
+ // Create transfer state since it doesn't exist. |
+ EXPECT_CALL(*delegate, CreatePixelTransferState(kServiceTextureId)) |
+ .WillOnce(Return(state)) |
+ .RetiresOnSaturation(); |
+ EXPECT_CALL(*delegate, AsyncTexSubImage2D(state.get(), _, _)) |
+ .RetiresOnSaturation(); |
+ // Command succeeds. |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ EXPECT_TRUE(info->GetAsyncTransferState()); |
+ EXPECT_TRUE(info->IsImmutable()); |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ } |
+ { |
+ // No transfer is in progress. |
+ EXPECT_CALL(*state.get(), TransferIsInProgress()) |
+ .WillOnce(Return(false)) |
+ .RetiresOnSaturation(); |
+ EXPECT_CALL(*delegate, AsyncTexSubImage2D(state.get(), _, _)) |
+ .RetiresOnSaturation(); |
+ // Command succeeds. |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ EXPECT_TRUE(info->GetAsyncTransferState()); |
+ EXPECT_TRUE(info->IsImmutable()); |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ } |
+ { |
+ // A transfer is still in progress! |
+ EXPECT_CALL(*state.get(), TransferIsInProgress()) |
+ .WillOnce(Return(true)) |
+ .RetiresOnSaturation(); |
+ // No async call, command fails. |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ EXPECT_TRUE(info->GetAsyncTransferState()); |
+ EXPECT_TRUE(info->IsImmutable()); |
+ EXPECT_TRUE(info->SafeToRenderFrom()); |
+ } |
+ |
+ decoder_->SetAsyncPixelTransferDelegate(NULL); |
+ DefaultValue<scoped_refptr<gfx::AsyncPixelTransferState> >::Set(NULL); |
+} |
+ |
+ |
// TODO(gman): Complete this test. |
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { |
// } |