| Index: gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc
|
| index 6d15c515998e348d79f91e08330125d2aa94c2df..6885c00f85a43e60e948b57ae36c310e47abe6df 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc
|
| @@ -218,6 +218,117 @@ TEST_P(GLES2DecoderTest, MapBufferRangeUnmapBufferWriteSucceeds) {
|
| EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| }
|
|
|
| +
|
| +TEST_P(GLES3DecoderTest, FlushMappedBufferRangeSucceeds) {
|
| + const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
|
| + const GLintptr kMappedOffset = 10;
|
| + const GLsizeiptr kMappedSize = 64;
|
| + const GLintptr kFlushRangeOffset = 5;
|
| + const GLsizeiptr kFlushRangeSize = 32;
|
| + const GLsizeiptr kTotalSize = kMappedOffset + kMappedSize;
|
| + const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
|
| + const GLbitfield kMappedAccess = kAccess | GL_MAP_READ_BIT;
|
| +
|
| + uint32_t result_shm_id = kSharedMemoryId;
|
| + uint32_t result_shm_offset = kSharedMemoryOffset;
|
| + uint32_t data_shm_id = kSharedMemoryId;
|
| + // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
|
| + uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
|
| +
|
| + typedef MapBufferRange::Result Result;
|
| + Result* result = GetSharedMemoryAs<Result*>();
|
| + int8_t* client_data = GetSharedMemoryAs<int8_t*>() + sizeof(uint32_t);
|
| +
|
| + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
|
| + Buffer* buffer = GetBuffer(client_buffer_id_);
|
| + EXPECT_TRUE(buffer != nullptr);
|
| + DoBufferData(kTarget, kTotalSize);
|
| + std::vector<int8_t> gpu_data(kTotalSize);
|
| + for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
|
| + gpu_data[ii] = static_cast<int8_t>(ii % 128);
|
| + }
|
| + DoBufferSubData(kTarget, 0, kTotalSize, &gpu_data[0]);
|
| +
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| + EXPECT_TRUE(buffer->shadowed());
|
| + const int8_t* shadow_data = reinterpret_cast<const int8_t*>(
|
| + buffer->GetRange(0, kTotalSize));
|
| + EXPECT_TRUE(shadow_data);
|
| + // Verify the shadow data is initialized.
|
| + for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
|
| + EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
|
| + }
|
| +
|
| + { // MapBufferRange succeeds
|
| + EXPECT_CALL(*gl_, MapBufferRange(kTarget, kMappedOffset, kMappedSize,
|
| + kMappedAccess))
|
| + .WillOnce(Return(&gpu_data[kMappedOffset]))
|
| + .RetiresOnSaturation();
|
| +
|
| + MapBufferRange cmd;
|
| + cmd.Init(kTarget, kMappedOffset, kMappedSize, kAccess,
|
| + data_shm_id, data_shm_offset,
|
| + result_shm_id, result_shm_offset);
|
| + *result = 0;
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(1u, *result);
|
| + // Verify the buffer range from GPU is copied to client mem.
|
| + EXPECT_EQ(0, memcmp(&gpu_data[kMappedOffset], client_data, kMappedSize));
|
| + }
|
| +
|
| + // Update the client mem, including data within and outside the flush range.
|
| + const int8_t kValue0 = 21;
|
| + memset(client_data, kValue0, kTotalSize);
|
| +
|
| + { // FlushMappedBufferRange succeeds
|
| + EXPECT_CALL(*gl_, FlushMappedBufferRange(kTarget, kFlushRangeOffset,
|
| + kFlushRangeSize))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| +
|
| + FlushMappedBufferRange cmd;
|
| + cmd.Init(kTarget, kFlushRangeOffset, kFlushRangeSize);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| +
|
| + // Verify the GPU mem and shadow data are both updated, but only within
|
| + // the flushed range.
|
| + for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
|
| + if (ii >= kMappedOffset + kFlushRangeOffset &&
|
| + ii < kMappedOffset + kFlushRangeOffset + kFlushRangeSize) {
|
| + EXPECT_EQ(kValue0, gpu_data[ii]);
|
| + EXPECT_EQ(kValue0, shadow_data[ii]);
|
| + } else {
|
| + EXPECT_EQ(static_cast<int8_t>(ii % 128), gpu_data[ii]);
|
| + EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
|
| + }
|
| + }
|
| + }
|
| +
|
| + { // UnmapBuffer succeeds
|
| + EXPECT_CALL(*gl_, UnmapBuffer(kTarget))
|
| + .WillOnce(Return(GL_TRUE))
|
| + .RetiresOnSaturation();
|
| +
|
| + UnmapBuffer cmd;
|
| + cmd.Init(kTarget);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| +
|
| + // Verify no further update to the GPU mem and shadow data.
|
| + for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
|
| + if (ii >= kMappedOffset + kFlushRangeOffset &&
|
| + ii < kMappedOffset + kFlushRangeOffset + kFlushRangeSize) {
|
| + EXPECT_EQ(kValue0, gpu_data[ii]);
|
| + EXPECT_EQ(kValue0, shadow_data[ii]);
|
| + } else {
|
| + EXPECT_EQ(static_cast<int8_t>(ii % 128), gpu_data[ii]);
|
| + EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
|
| + }
|
| + }
|
| + }
|
| +
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| +}
|
| +
|
| TEST_P(GLES2DecoderTest, MapBufferRangeNotInitFails) {
|
| const GLenum kTarget = GL_ARRAY_BUFFER;
|
| const GLintptr kOffset = 10;
|
| @@ -399,6 +510,9 @@ TEST_P(GLES2DecoderTest, MapBufferRangeBadSharedMemoryFails) {
|
| data[ii] = static_cast<int8_t>(ii % 255);
|
| }
|
|
|
| + DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
|
| + DoBufferData(kTarget, kOffset + kSize);
|
| +
|
| typedef MapBufferRange::Result Result;
|
| Result* result = GetSharedMemoryAs<Result*>();
|
| *result = 0;
|
|
|