| 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 3962311c6aadc5b272795a9bfcc599ea8f3fe951..7aa4428bf47258042027fb338a9f7b2b42059bfa 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
|
| @@ -15,6 +15,7 @@
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h"
|
| #include "gpu/command_buffer/service/image_manager.h"
|
| #include "gpu/command_buffer/service/mailbox_manager.h"
|
| +#include "gpu/command_buffer/service/mocks.h"
|
| #include "gpu/command_buffer/service/program_manager.h"
|
| #include "gpu/command_buffer/service/stream_texture_manager_mock.h"
|
| #include "gpu/command_buffer/service/stream_texture_mock.h"
|
| @@ -8086,6 +8087,260 @@ TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
|
| info->SetAsyncTransferState(scoped_ptr<gfx::AsyncPixelTransferState>());
|
| }
|
|
|
| +namespace {
|
| +
|
| +class SizeOnlyMemoryTracker : public MemoryTracker {
|
| + public:
|
| + SizeOnlyMemoryTracker() {
|
| + // These are the default textures. 1 for TEXTURE_2D and 6 faces for
|
| + // TEXTURE_CUBE_MAP.
|
| + const size_t kInitialUnmanagedPoolSize = 7 * 4;
|
| + const size_t kInitialManagedPoolSize = 0;
|
| + pool_infos_[MemoryTracker::kUnmanaged].initial_size =
|
| + kInitialUnmanagedPoolSize;
|
| + pool_infos_[MemoryTracker::kManaged].initial_size =
|
| + kInitialManagedPoolSize;
|
| + }
|
| +
|
| + // Ensure a certain amount of GPU memory is free. Returns true on success.
|
| + MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
|
| +
|
| + virtual void TrackMemoryAllocatedChange(
|
| + size_t old_size, size_t new_size, Pool pool) {
|
| + PoolInfo& info = pool_infos_[pool];
|
| + info.size += new_size - old_size;
|
| + }
|
| +
|
| + size_t GetPoolSize(Pool pool) {
|
| + const PoolInfo& info = pool_infos_[pool];
|
| + return info.size - info.initial_size;
|
| + }
|
| +
|
| + private:
|
| + virtual ~SizeOnlyMemoryTracker() {
|
| + }
|
| + struct PoolInfo {
|
| + PoolInfo()
|
| + : initial_size(0),
|
| + size(0) {
|
| + }
|
| + size_t initial_size;
|
| + size_t size;
|
| + };
|
| + std::map<Pool, PoolInfo> pool_infos_;
|
| +};
|
| +
|
| +} // anonymous namespace.
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + false, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + false, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + // Expect that initial size - size is 0.
|
| + EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
|
| +}
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + false, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + false, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(true))
|
| + .RetiresOnSaturation();
|
| + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
| + kSharedMemoryId, kSharedMemoryOffset);
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(64))
|
| + .WillOnce(Return(true))
|
| + .RetiresOnSaturation();
|
| + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
| + kSharedMemoryId, kSharedMemoryOffset);
|
| + EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| + // Check we get out of memory and no call to glTexImage2D if Ensure fails.
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(64))
|
| + .WillOnce(Return(false))
|
| + .RetiresOnSaturation();
|
| + TexImage2D cmd;
|
| + cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
| + kSharedMemoryId, kSharedMemoryOffset);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
|
| + EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| +}
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + false, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + false, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
|
| + // Check we get out of memory and no call to glTexStorage2DEXT
|
| + // if Ensure fails.
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(false))
|
| + .RetiresOnSaturation();
|
| + TexStorage2DEXT cmd;
|
| + cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
|
| +}
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
|
| + GLenum target = GL_TEXTURE_2D;
|
| + GLint level = 0;
|
| + GLenum internal_format = GL_RGBA;
|
| + GLsizei width = 4;
|
| + GLsizei height = 8;
|
| + GLint border = 0;
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + true, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + true, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(true))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*gl_, GetError())
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*gl_, CopyTexImage2D(
|
| + target, level, internal_format, 0, 0, width, height, border))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + CopyTexImage2D cmd;
|
| + cmd.Init(target, level, internal_format, 0, 0, width, height, border);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| + // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(false))
|
| + .RetiresOnSaturation();
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| +}
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + false, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + false, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
|
| + kServiceRenderbufferId);
|
| + EXPECT_CALL(*gl_, GetError())
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(true))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*gl_, RenderbufferStorageEXT(
|
| + GL_RENDERBUFFER, GL_RGBA, 8, 4))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + RenderbufferStorage cmd;
|
| + cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| + // Check we get out of memory and no call to glRenderbufferStorage if Ensure
|
| + // fails.
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(false))
|
| + .RetiresOnSaturation();
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
|
| +}
|
| +
|
| +TEST_F(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
|
| + scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
|
| + new SizeOnlyMemoryTracker();
|
| + set_memory_tracker(memory_tracker.get());
|
| + InitDecoder(
|
| + "", // extensions
|
| + false, // has alpha
|
| + false, // has depth
|
| + false, // has stencil
|
| + false, // request alpha
|
| + false, // request depth
|
| + false, // request stencil
|
| + true); // bind generates resource
|
| + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_,
|
| + kServiceBufferId);
|
| + EXPECT_CALL(*gl_, GetError())
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .WillOnce(Return(GL_NO_ERROR))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(true))
|
| + .RetiresOnSaturation();
|
| + EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + BufferData cmd;
|
| + cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
|
| + // Check we get out of memory and no call to glBufferData if Ensure
|
| + // fails.
|
| + EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128))
|
| + .WillOnce(Return(false))
|
| + .RetiresOnSaturation();
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
|
| + EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
|
| +}
|
| +
|
| // TODO(gman): Complete this test.
|
| // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
|
| // }
|
|
|