| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 
| 6 | 6 | 
| 7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" | 
| 8 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 8 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 
| 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 
| 10 #include "gpu/command_buffer/common/id_allocator.h" | 10 #include "gpu/command_buffer/common/id_allocator.h" | 
| 11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h" | 11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h" | 
| 12 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 12 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 
| 13 #include "gpu/command_buffer/service/context_group.h" | 13 #include "gpu/command_buffer/service/context_group.h" | 
| 14 #include "gpu/command_buffer/service/gl_surface_mock.h" | 14 #include "gpu/command_buffer/service/gl_surface_mock.h" | 
| 15 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" | 15 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" | 
| 16 #include "gpu/command_buffer/service/image_manager.h" | 16 #include "gpu/command_buffer/service/image_manager.h" | 
| 17 #include "gpu/command_buffer/service/mailbox_manager.h" | 17 #include "gpu/command_buffer/service/mailbox_manager.h" | 
|  | 18 #include "gpu/command_buffer/service/mocks.h" | 
| 18 #include "gpu/command_buffer/service/program_manager.h" | 19 #include "gpu/command_buffer/service/program_manager.h" | 
| 19 #include "gpu/command_buffer/service/stream_texture_manager_mock.h" | 20 #include "gpu/command_buffer/service/stream_texture_manager_mock.h" | 
| 20 #include "gpu/command_buffer/service/stream_texture_mock.h" | 21 #include "gpu/command_buffer/service/stream_texture_mock.h" | 
| 21 #include "gpu/command_buffer/service/test_helper.h" | 22 #include "gpu/command_buffer/service/test_helper.h" | 
| 22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" | 
| 23 #include "ui/gl/gl_implementation.h" | 24 #include "ui/gl/gl_implementation.h" | 
| 24 #include "ui/gl/gl_mock.h" | 25 #include "ui/gl/gl_mock.h" | 
| 25 #include "ui/gl/gl_surface_stub.h" | 26 #include "ui/gl/gl_surface_stub.h" | 
| 26 | 27 | 
| 27 | 28 | 
| (...skipping 8051 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 8079     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); | 8080     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); | 
| 8080     EXPECT_TRUE(info->GetAsyncTransferState()); | 8081     EXPECT_TRUE(info->GetAsyncTransferState()); | 
| 8081     EXPECT_TRUE(info->IsImmutable()); | 8082     EXPECT_TRUE(info->IsImmutable()); | 
| 8082     EXPECT_TRUE(info->SafeToRenderFrom()); | 8083     EXPECT_TRUE(info->SafeToRenderFrom()); | 
| 8083   } | 8084   } | 
| 8084 | 8085 | 
| 8085   decoder_->SetAsyncPixelTransferDelegate(NULL); | 8086   decoder_->SetAsyncPixelTransferDelegate(NULL); | 
| 8086   info->SetAsyncTransferState(scoped_ptr<gfx::AsyncPixelTransferState>()); | 8087   info->SetAsyncTransferState(scoped_ptr<gfx::AsyncPixelTransferState>()); | 
| 8087 } | 8088 } | 
| 8088 | 8089 | 
|  | 8090 namespace { | 
|  | 8091 | 
|  | 8092 class SizeOnlyMemoryTracker : public MemoryTracker { | 
|  | 8093  public: | 
|  | 8094   SizeOnlyMemoryTracker() { | 
|  | 8095     // These are the default textures. 1 for TEXTURE_2D and 6 faces for | 
|  | 8096     // TEXTURE_CUBE_MAP. | 
|  | 8097     const size_t kInitialUnmanagedPoolSize = 7 * 4; | 
|  | 8098     const size_t kInitialManagedPoolSize = 0; | 
|  | 8099     pool_infos_[MemoryTracker::kUnmanaged].initial_size = | 
|  | 8100         kInitialUnmanagedPoolSize; | 
|  | 8101     pool_infos_[MemoryTracker::kManaged].initial_size = | 
|  | 8102         kInitialManagedPoolSize; | 
|  | 8103   } | 
|  | 8104 | 
|  | 8105   // Ensure a certain amount of GPU memory is free. Returns true on success. | 
|  | 8106   MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed)); | 
|  | 8107 | 
|  | 8108   virtual void TrackMemoryAllocatedChange( | 
|  | 8109       size_t old_size, size_t new_size, Pool pool) { | 
|  | 8110     PoolInfo& info = pool_infos_[pool]; | 
|  | 8111     info.size += new_size - old_size; | 
|  | 8112   } | 
|  | 8113 | 
|  | 8114   size_t GetPoolSize(Pool pool) { | 
|  | 8115     const PoolInfo& info = pool_infos_[pool]; | 
|  | 8116     return info.size - info.initial_size; | 
|  | 8117   } | 
|  | 8118 | 
|  | 8119  private: | 
|  | 8120   virtual ~SizeOnlyMemoryTracker() { | 
|  | 8121   } | 
|  | 8122   struct PoolInfo { | 
|  | 8123     PoolInfo() | 
|  | 8124         : initial_size(0), | 
|  | 8125           size(0) { | 
|  | 8126     } | 
|  | 8127     size_t initial_size; | 
|  | 8128     size_t size; | 
|  | 8129   }; | 
|  | 8130   std::map<Pool, PoolInfo> pool_infos_; | 
|  | 8131 }; | 
|  | 8132 | 
|  | 8133 }  // anonymous namespace. | 
|  | 8134 | 
|  | 8135 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) { | 
|  | 8136   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8137       new SizeOnlyMemoryTracker(); | 
|  | 8138   set_memory_tracker(memory_tracker.get()); | 
|  | 8139   InitDecoder( | 
|  | 8140       "",      // extensions | 
|  | 8141       false,   // has alpha | 
|  | 8142       false,   // has depth | 
|  | 8143       false,   // has stencil | 
|  | 8144       false,   // request alpha | 
|  | 8145       false,   // request depth | 
|  | 8146       false,   // request stencil | 
|  | 8147       true);   // bind generates resource | 
|  | 8148   // Expect that initial size - size is 0. | 
|  | 8149   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8150   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); | 
|  | 8151 } | 
|  | 8152 | 
|  | 8153 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) { | 
|  | 8154   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8155       new SizeOnlyMemoryTracker(); | 
|  | 8156   set_memory_tracker(memory_tracker.get()); | 
|  | 8157   InitDecoder( | 
|  | 8158       "",      // extensions | 
|  | 8159       false,   // has alpha | 
|  | 8160       false,   // has depth | 
|  | 8161       false,   // has stencil | 
|  | 8162       false,   // request alpha | 
|  | 8163       false,   // request depth | 
|  | 8164       false,   // request stencil | 
|  | 8165       true);   // bind generates resource | 
|  | 8166   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); | 
|  | 8167   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8168       .WillOnce(Return(true)) | 
|  | 8169       .RetiresOnSaturation(); | 
|  | 8170   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, | 
|  | 8171                kSharedMemoryId, kSharedMemoryOffset); | 
|  | 8172   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8173   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(64)) | 
|  | 8174       .WillOnce(Return(true)) | 
|  | 8175       .RetiresOnSaturation(); | 
|  | 8176   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, | 
|  | 8177                kSharedMemoryId, kSharedMemoryOffset); | 
|  | 8178   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8179   EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 
|  | 8180   // Check we get out of memory and no call to glTexImage2D if Ensure fails. | 
|  | 8181   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(64)) | 
|  | 8182       .WillOnce(Return(false)) | 
|  | 8183       .RetiresOnSaturation(); | 
|  | 8184   TexImage2D cmd; | 
|  | 8185   cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, | 
|  | 8186            kSharedMemoryId, kSharedMemoryOffset); | 
|  | 8187   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8188   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); | 
|  | 8189   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8190 } | 
|  | 8191 | 
|  | 8192 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) { | 
|  | 8193   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8194       new SizeOnlyMemoryTracker(); | 
|  | 8195   set_memory_tracker(memory_tracker.get()); | 
|  | 8196   InitDecoder( | 
|  | 8197       "",      // extensions | 
|  | 8198       false,   // has alpha | 
|  | 8199       false,   // has depth | 
|  | 8200       false,   // has stencil | 
|  | 8201       false,   // request alpha | 
|  | 8202       false,   // request depth | 
|  | 8203       false,   // request stencil | 
|  | 8204       true);   // bind generates resource | 
|  | 8205   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); | 
|  | 8206   // Check we get out of memory and no call to glTexStorage2DEXT | 
|  | 8207   // if Ensure fails. | 
|  | 8208   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8209       .WillOnce(Return(false)) | 
|  | 8210       .RetiresOnSaturation(); | 
|  | 8211   TexStorage2DEXT cmd; | 
|  | 8212   cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4); | 
|  | 8213   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8214   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8215   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); | 
|  | 8216 } | 
|  | 8217 | 
|  | 8218 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) { | 
|  | 8219   GLenum target = GL_TEXTURE_2D; | 
|  | 8220   GLint level = 0; | 
|  | 8221   GLenum internal_format = GL_RGBA; | 
|  | 8222   GLsizei width = 4; | 
|  | 8223   GLsizei height = 8; | 
|  | 8224   GLint border = 0; | 
|  | 8225   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8226       new SizeOnlyMemoryTracker(); | 
|  | 8227   set_memory_tracker(memory_tracker.get()); | 
|  | 8228   InitDecoder( | 
|  | 8229       "",      // extensions | 
|  | 8230       true,    // has alpha | 
|  | 8231       false,   // has depth | 
|  | 8232       false,   // has stencil | 
|  | 8233       true,    // request alpha | 
|  | 8234       false,   // request depth | 
|  | 8235       false,   // request stencil | 
|  | 8236       true);   // bind generates resource | 
|  | 8237   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); | 
|  | 8238   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8239       .WillOnce(Return(true)) | 
|  | 8240       .RetiresOnSaturation(); | 
|  | 8241   EXPECT_CALL(*gl_, GetError()) | 
|  | 8242       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8243       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8244       .RetiresOnSaturation(); | 
|  | 8245   EXPECT_CALL(*gl_, CopyTexImage2D( | 
|  | 8246       target, level, internal_format, 0, 0, width, height, border)) | 
|  | 8247       .Times(1) | 
|  | 8248       .RetiresOnSaturation(); | 
|  | 8249   CopyTexImage2D cmd; | 
|  | 8250   cmd.Init(target, level, internal_format, 0, 0, width, height, border); | 
|  | 8251   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8252   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8253   EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 
|  | 8254   // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails. | 
|  | 8255   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8256       .WillOnce(Return(false)) | 
|  | 8257       .RetiresOnSaturation(); | 
|  | 8258   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8259   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); | 
|  | 8260   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8261 } | 
|  | 8262 | 
|  | 8263 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) { | 
|  | 8264   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8265       new SizeOnlyMemoryTracker(); | 
|  | 8266   set_memory_tracker(memory_tracker.get()); | 
|  | 8267   InitDecoder( | 
|  | 8268       "",      // extensions | 
|  | 8269       false,   // has alpha | 
|  | 8270       false,   // has depth | 
|  | 8271       false,   // has stencil | 
|  | 8272       false,   // request alpha | 
|  | 8273       false,   // request depth | 
|  | 8274       false,   // request stencil | 
|  | 8275       true);   // bind generates resource | 
|  | 8276   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, | 
|  | 8277                     kServiceRenderbufferId); | 
|  | 8278   EXPECT_CALL(*gl_, GetError()) | 
|  | 8279       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8280       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8281       .RetiresOnSaturation(); | 
|  | 8282   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8283       .WillOnce(Return(true)) | 
|  | 8284       .RetiresOnSaturation(); | 
|  | 8285   EXPECT_CALL(*gl_, RenderbufferStorageEXT( | 
|  | 8286       GL_RENDERBUFFER, GL_RGBA, 8, 4)) | 
|  | 8287       .Times(1) | 
|  | 8288       .RetiresOnSaturation(); | 
|  | 8289   RenderbufferStorage cmd; | 
|  | 8290   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4); | 
|  | 8291   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8292   EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 
|  | 8293   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8294   // Check we get out of memory and no call to glRenderbufferStorage if Ensure | 
|  | 8295   // fails. | 
|  | 8296   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8297       .WillOnce(Return(false)) | 
|  | 8298       .RetiresOnSaturation(); | 
|  | 8299   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8300   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); | 
|  | 8301   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); | 
|  | 8302 } | 
|  | 8303 | 
|  | 8304 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerBufferData) { | 
|  | 8305   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = | 
|  | 8306       new SizeOnlyMemoryTracker(); | 
|  | 8307   set_memory_tracker(memory_tracker.get()); | 
|  | 8308   InitDecoder( | 
|  | 8309       "",      // extensions | 
|  | 8310       false,   // has alpha | 
|  | 8311       false,   // has depth | 
|  | 8312       false,   // has stencil | 
|  | 8313       false,   // request alpha | 
|  | 8314       false,   // request depth | 
|  | 8315       false,   // request stencil | 
|  | 8316       true);   // bind generates resource | 
|  | 8317   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, | 
|  | 8318                kServiceBufferId); | 
|  | 8319   EXPECT_CALL(*gl_, GetError()) | 
|  | 8320       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8321       .WillOnce(Return(GL_NO_ERROR)) | 
|  | 8322       .RetiresOnSaturation(); | 
|  | 8323   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8324       .WillOnce(Return(true)) | 
|  | 8325       .RetiresOnSaturation(); | 
|  | 8326   EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW)) | 
|  | 8327       .Times(1) | 
|  | 8328       .RetiresOnSaturation(); | 
|  | 8329   BufferData cmd; | 
|  | 8330   cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW); | 
|  | 8331   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8332   EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 
|  | 8333   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); | 
|  | 8334   // Check we get out of memory and no call to glBufferData if Ensure | 
|  | 8335   // fails. | 
|  | 8336   EXPECT_CALL(*memory_tracker, EnsureGPUMemoryAvailable(128)) | 
|  | 8337       .WillOnce(Return(false)) | 
|  | 8338       .RetiresOnSaturation(); | 
|  | 8339   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 
|  | 8340   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); | 
|  | 8341   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); | 
|  | 8342 } | 
|  | 8343 | 
| 8089 // TODO(gman): Complete this test. | 8344 // TODO(gman): Complete this test. | 
| 8090 // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { | 8345 // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { | 
| 8091 // } | 8346 // } | 
| 8092 | 8347 | 
| 8093 // TODO(gman): BufferData | 8348 // TODO(gman): BufferData | 
| 8094 | 8349 | 
| 8095 // TODO(gman): BufferDataImmediate | 8350 // TODO(gman): BufferDataImmediate | 
| 8096 | 8351 | 
| 8097 // TODO(gman): BufferSubData | 8352 // TODO(gman): BufferSubData | 
| 8098 | 8353 | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 8115 // TODO(gman): TexImage2DImmediate | 8370 // TODO(gman): TexImage2DImmediate | 
| 8116 | 8371 | 
| 8117 // TODO(gman): TexSubImage2DImmediate | 8372 // TODO(gman): TexSubImage2DImmediate | 
| 8118 | 8373 | 
| 8119 // TODO(gman): UseProgram | 8374 // TODO(gman): UseProgram | 
| 8120 | 8375 | 
| 8121 // TODO(gman): SwapBuffers | 8376 // TODO(gman): SwapBuffers | 
| 8122 | 8377 | 
| 8123 }  // namespace gles2 | 8378 }  // namespace gles2 | 
| 8124 }  // namespace gpu | 8379 }  // namespace gpu | 
| OLD | NEW | 
|---|