diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-08-05 13:57:33 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-08-05 13:57:33 +0100 |
commit | a36e5920737c6adbddd3e43b760e5de8431db6e0 (patch) | |
tree | 347d048bb8c8828d50113bf94ace40bf0613f2cd /gpu | |
parent | 34378da0e9429d394aafdaa771301aff58447cb1 (diff) | |
download | chromium_org-a36e5920737c6adbddd3e43b760e5de8431db6e0.tar.gz |
Merge from Chromium at DEPS revision r215573
This commit was generated by merge_to_master.py.
Change-Id: Ib95814f98e5765b459dd32425f9bf9138edf2bca
Diffstat (limited to 'gpu')
45 files changed, 690 insertions, 625 deletions
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc index b1b5a03a68..97f1715148 100644 --- a/gpu/command_buffer/client/gl_in_process_context.cc +++ b/gpu/command_buffer/client/gl_in_process_context.cc @@ -23,7 +23,6 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" #include "gpu/command_buffer/client/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/client/image_factory.h" #include "gpu/command_buffer/client/transfer_buffer.h" @@ -71,7 +70,7 @@ class GLInProcessContextImpl virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; // ImageFactory implementation: - virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( + virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned* image_id) OVERRIDE; virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE; @@ -107,17 +106,17 @@ size_t SharedContextCount() { return g_all_shared_contexts.Get().size(); } -scoped_ptr<GpuMemoryBuffer> GLInProcessContextImpl::CreateGpuMemoryBuffer( +scoped_ptr<gfx::GpuMemoryBuffer> GLInProcessContextImpl::CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned int* image_id) { - scoped_ptr<GpuMemoryBuffer> buffer( + scoped_ptr<gfx::GpuMemoryBuffer> buffer( g_gpu_memory_buffer_factory->CreateGpuMemoryBuffer(width, height, internalformat)); if (!buffer) - return scoped_ptr<GpuMemoryBuffer>(); + return scoped_ptr<gfx::GpuMemoryBuffer>(); *image_id = command_buffer_->CreateImageForGpuMemoryBuffer( - buffer->GetNativeBuffer(), gfx::Size(width, height)); + buffer->GetHandle(), gfx::Size(width, height)); return buffer.Pass(); } diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index a61da7756b..9285b6d82e 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -16,7 +16,6 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> #include "gpu/command_buffer/client/buffer_tracker.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" #include "gpu/command_buffer/client/mapped_memory.h" #include "gpu/command_buffer/client/program_info_manager.h" @@ -25,6 +24,7 @@ #include "gpu/command_buffer/client/vertex_array_object_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/trace_event.h" +#include "ui/gfx/gpu_memory_buffer.h" #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS @@ -3699,7 +3699,8 @@ GLuint GLES2Implementation::CreateImageCHROMIUM( } void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glDestroyImageCHROMIUM", "invalid image"); return; @@ -3720,7 +3721,8 @@ void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { } void GLES2Implementation::UnmapImageCHROMIUMHelper(GLuint image_id) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "invalid image"); return; @@ -3744,21 +3746,22 @@ void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) { void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id, GLenum access) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image"); return NULL; } - GpuMemoryBuffer::AccessMode mode; + gfx::GpuMemoryBuffer::AccessMode mode; switch(access) { case GL_WRITE_ONLY: - mode = GpuMemoryBuffer::WRITE_ONLY; + mode = gfx::GpuMemoryBuffer::WRITE_ONLY; break; case GL_READ_ONLY: - mode = GpuMemoryBuffer::READ_ONLY; + mode = gfx::GpuMemoryBuffer::READ_ONLY; break; case GL_READ_WRITE: - mode = GpuMemoryBuffer::READ_WRITE; + mode = gfx::GpuMemoryBuffer::READ_WRITE; break; default: SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM", @@ -3796,8 +3799,8 @@ void GLES2Implementation::GetImageParameterivCHROMIUMHelper( return; } - GpuMemoryBuffer* gpu_buffer = - gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", "invalid image"); diff --git a/gpu/command_buffer/client/gpu_memory_buffer.h b/gpu/command_buffer/client/gpu_memory_buffer.h deleted file mode 100644 index d1de7a4452..0000000000 --- a/gpu/command_buffer/client/gpu_memory_buffer.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2013 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. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "gles2_impl_export.h" - -namespace gpu { - -// Interface for creating and accessing a zero-copy GPU memory buffer. -// This design evolved from the generalization of GraphicBuffer API -// of Android framework. -// -// THREADING CONSIDERATIONS: -// -// This interface is thread-safe. However, multiple threads mapping -// a buffer for Write or ReadOrWrite simultaneously may result in undefined -// behavior and is not allowed. -class GLES2_IMPL_EXPORT GpuMemoryBuffer { - public: - enum AccessMode { - READ_ONLY, - WRITE_ONLY, - READ_WRITE, - }; - - // Frees a previously allocated buffer. Freeing a buffer that is still - // mapped in any process is undefined behavior. - virtual ~GpuMemoryBuffer() {} - - // Maps the buffer so the client can write the bitmap data in |*vaddr| - // subsequently. This call may block, for instance if the hardware needs - // to finish rendering or if CPU caches need to be synchronized. - virtual void Map(AccessMode mode, void** vaddr) = 0; - - // Unmaps the buffer. Called after all changes to the buffer are - // completed. - virtual void Unmap() = 0; - - // Returns true iff the buffer is mapped. - virtual bool IsMapped() = 0; - - // Returns the native pointer for the buffer. - virtual void* GetNativeBuffer() = 0; - - // Returns the stride in bytes for the buffer. - virtual uint32 GetStride() = 0; -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_H_ diff --git a/gpu/command_buffer/client/gpu_memory_buffer_factory.h b/gpu/command_buffer/client/gpu_memory_buffer_factory.h index 5ea4bf50d1..42dde409ea 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_factory.h +++ b/gpu/command_buffer/client/gpu_memory_buffer_factory.h @@ -7,12 +7,15 @@ #include "gpu/gpu_export.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} + +namespace gpu { class GPU_EXPORT GpuMemoryBufferFactory { public: - virtual gpu::GpuMemoryBuffer* CreateGpuMemoryBuffer( + virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat) = 0; diff --git a/gpu/command_buffer/client/gpu_memory_buffer_mock.cc b/gpu/command_buffer/client/gpu_memory_buffer_mock.cc deleted file mode 100644 index 289b0feac8..0000000000 --- a/gpu/command_buffer/client/gpu_memory_buffer_mock.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2013 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/client/gpu_memory_buffer_mock.h" - -namespace gpu { - -GpuMemoryBufferMock::GpuMemoryBufferMock(int width, int height) { -} - -GpuMemoryBufferMock::~GpuMemoryBufferMock() { - Die(); -} - -} // namespace gpu diff --git a/gpu/command_buffer/client/gpu_memory_buffer_mock.h b/gpu/command_buffer/client/gpu_memory_buffer_mock.h deleted file mode 100644 index 6a4db89d82..0000000000 --- a/gpu/command_buffer/client/gpu_memory_buffer_mock.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2013 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. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_MOCK_H_ -#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_MOCK_H_ - -#include "gpu/command_buffer/client/gpu_memory_buffer.h" -#include "base/basictypes.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { - -class GpuMemoryBufferMock : public GpuMemoryBuffer { - public: - GpuMemoryBufferMock(int width, int height); - virtual ~GpuMemoryBufferMock(); - - MOCK_METHOD2(Map, void(GpuMemoryBuffer::AccessMode, void**)); - MOCK_METHOD0(Unmap, void()); - MOCK_METHOD0(IsMapped, bool()); - MOCK_METHOD0(GetNativeBuffer, void*()); - MOCK_METHOD0(GetStride, uint32()); - MOCK_METHOD0(Die, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferMock); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_MOCK_H_ diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc index 894898b2fd..c1c9b4d63c 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc @@ -6,8 +6,8 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" #include "gpu/command_buffer/client/image_factory.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace gpu { namespace gles2 { @@ -27,7 +27,7 @@ GLuint GpuMemoryBufferTracker::CreateBuffer( GLsizei width, GLsizei height, GLenum internalformat) { GLuint image_id = 0; DCHECK(factory_); - scoped_ptr<GpuMemoryBuffer> buffer = + scoped_ptr<gfx::GpuMemoryBuffer> buffer = factory_->CreateGpuMemoryBuffer(width, height, internalformat, &image_id); if (buffer.get() == NULL) @@ -40,7 +40,7 @@ GLuint GpuMemoryBufferTracker::CreateBuffer( return image_id; } -GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { +gfx::GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { BufferMap::iterator it = buffers_.find(image_id); return (it != buffers_.end()) ? it->second : NULL; } @@ -48,7 +48,7 @@ GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { void GpuMemoryBufferTracker::RemoveBuffer(GLuint image_id) { BufferMap::iterator buffer_it = buffers_.find(image_id); if (buffer_it != buffers_.end()) { - GpuMemoryBuffer* buffer = buffer_it->second; + gfx::GpuMemoryBuffer* buffer = buffer_it->second; buffers_.erase(buffer_it); delete buffer; } diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h index f2f6e9f057..1192b1714f 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h @@ -11,9 +11,11 @@ #include "gles2_impl_export.h" #include "gpu/command_buffer/client/hash_tables.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} +namespace gpu { namespace gles2 { class ImageFactory; @@ -26,11 +28,11 @@ class GLES2_IMPL_EXPORT GpuMemoryBufferTracker { GLuint CreateBuffer( GLsizei width, GLsizei height, GLenum internalformat); - GpuMemoryBuffer* GetBuffer(GLuint image_id); + gfx::GpuMemoryBuffer* GetBuffer(GLuint image_id); void RemoveBuffer(GLuint image_id); private: - typedef gpu::hash_map<GLuint, GpuMemoryBuffer*> BufferMap; + typedef gpu::hash_map<GLuint, gfx::GpuMemoryBuffer*> BufferMap; BufferMap buffers_; ImageFactory* factory_; diff --git a/gpu/command_buffer/client/image_factory.h b/gpu/command_buffer/client/image_factory.h index b752cb1487..449c8a4b74 100644 --- a/gpu/command_buffer/client/image_factory.h +++ b/gpu/command_buffer/client/image_factory.h @@ -10,9 +10,11 @@ #include "base/memory/scoped_ptr.h" #include "gles2_impl_export.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} +namespace gpu { namespace gles2 { class GLES2_IMPL_EXPORT ImageFactory { @@ -22,7 +24,7 @@ class GLES2_IMPL_EXPORT ImageFactory { // Create a GpuMemoryBuffer and makes it available to the // service side by inserting it to the ImageManager. - virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( + virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned* image_id) = 0; virtual void DeleteGpuMemoryBuffer(unsigned image_id) = 0; }; diff --git a/gpu/command_buffer/client/image_factory_mock.cc b/gpu/command_buffer/client/image_factory_mock.cc deleted file mode 100644 index d167cee111..0000000000 --- a/gpu/command_buffer/client/image_factory_mock.cc +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2013 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/client/image_factory_mock.h" - -namespace gpu { -namespace gles2 { - -ImageFactoryMock::ImageFactoryMock(ImageManager* manager) { -} - -ImageFactoryMock::~ImageFactoryMock() { -} - -} // namespace gles2 -} // namespace gpu diff --git a/gpu/command_buffer/client/image_factory_mock.h b/gpu/command_buffer/client/image_factory_mock.h deleted file mode 100644 index 2516d69b9f..0000000000 --- a/gpu/command_buffer/client/image_factory_mock.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2013 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. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_MOCK_H_ -#define GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_MOCK_H_ - -#include "base/memory/scoped_ptr.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" -#include "gpu/command_buffer/client/image_factory.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { -namespace gles2 { -class ImageManager; - -// Mock implementation of ImageFactory -class ImageFactoryMock : public ImageFactory { - public: - ImageFactoryMock(ImageManager* image_manager); - virtual ~ImageFactoryMock(); - - MOCK_METHOD4(CreateGpuMemoryBufferMock, GpuMemoryBuffer*( - int width, int height, GLenum internalformat, unsigned* image_id)); - MOCK_METHOD1(DeleteGpuMemoryBuffer, void(unsigned)); - // Workaround for mocking methods that return scoped_ptrs - virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( - int width, int height, GLenum internalformat, - unsigned* image_id) OVERRIDE { - return scoped_ptr<GpuMemoryBuffer>(CreateGpuMemoryBufferMock( - width, height, internalformat, image_id)); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ImageFactoryMock); -}; - -} // namespace gles2 -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_MOCK_H_ diff --git a/gpu/command_buffer/command_buffer_untrusted.gyp b/gpu/command_buffer/command_buffer_untrusted.gyp index 5fe47f3da6..8f27a0b056 100644 --- a/gpu/command_buffer/command_buffer_untrusted.gyp +++ b/gpu/command_buffer/command_buffer_untrusted.gyp @@ -22,6 +22,7 @@ 'nlib_target': 'libgles2_utils_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'dependencies': [ '../../native_client/tools.gyp:prep_toolchain', diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index e8219a1819..25d57013f2 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 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. @@ -302,7 +302,7 @@ bool InProcessCommandBuffer::Initialize( share_group_id_ = share_group_id; base::WaitableEvent completion(true, false); - bool result; + bool result = false; base::Callback<bool(void)> init_task = base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, base::Unretained(this), @@ -453,7 +453,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( void InProcessCommandBuffer::Destroy() { base::WaitableEvent completion(true, false); - bool result; + bool result = false; base::Callback<bool(void)> destroy_task = base::Bind( &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); QueueTask( @@ -522,8 +522,10 @@ void InProcessCommandBuffer::RemoveImageOnGpuThread(unsigned int image_id) { } void InProcessCommandBuffer::OnContextLost() { - if (!context_lost_callback_.is_null()) + if (!context_lost_callback_.is_null()) { context_lost_callback_.Run(); + context_lost_callback_.Reset(); + } context_lost_ = true; if (share_resources_) { @@ -650,15 +652,16 @@ void InProcessCommandBuffer::SetContextLostReason( namespace { -static void PostCallback(const scoped_refptr<base::MessageLoopProxy>& loop, +void PostCallback(const scoped_refptr<base::MessageLoopProxy>& loop, const base::Closure& callback) { - if (loop != base::MessageLoopProxy::current()) + if (!loop->BelongsToCurrentThread()) { loop->PostTask(FROM_HERE, callback); - else + } else { callback.Run(); + } } -static void RunCallback(scoped_ptr<base::Closure> callback) { +void RunOnTargetThread(scoped_ptr<base::Closure> callback) { DCHECK(callback.get()); callback->Run(); } @@ -671,10 +674,10 @@ base::Closure InProcessCommandBuffer::WrapCallback( // ownership. scoped_ptr<base::Closure> scoped_callback(new base::Closure(callback)); base::Closure callback_on_client_thread = - base::Bind(&RunCallback, base::Passed(&scoped_callback)); + base::Bind(&RunOnTargetThread, base::Passed(&scoped_callback)); base::Closure wrapped_callback = base::Bind(&PostCallback, base::MessageLoopProxy::current(), - callback); + callback_on_client_thread); return wrapped_callback; } diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index 88d437dace..18c919ff1c 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 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. @@ -15,6 +15,7 @@ #include "base/synchronization/waitable_event.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/gpu_export.h" +#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/gpu_preference.h" diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc index 0df3cca1bf..3207f7c807 100644 --- a/gpu/command_buffer/service/memory_program_cache.cc +++ b/gpu/command_buffer/service/memory_program_cache.cc @@ -90,18 +90,21 @@ void RunShaderCallback(const ShaderCacheCallback& callback, MemoryProgramCache::MemoryProgramCache() : max_size_bytes_(GetCacheSizeBytes()), - curr_size_bytes_(0) { } + curr_size_bytes_(0), + store_(ProgramMRUCache::NO_AUTO_EVICT) { +} MemoryProgramCache::MemoryProgramCache(const size_t max_cache_size_bytes) : max_size_bytes_(max_cache_size_bytes), - curr_size_bytes_(0) {} + curr_size_bytes_(0), + store_(ProgramMRUCache::NO_AUTO_EVICT) { +} MemoryProgramCache::~MemoryProgramCache() {} void MemoryProgramCache::ClearBackend() { - curr_size_bytes_ = 0; - store_.clear(); - eviction_helper_.Clear(); + store_.Clear(); + DCHECK_EQ(0U, curr_size_bytes_); } ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( @@ -111,7 +114,7 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( Shader* shader_b, const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, - const ShaderCacheCallback& shader_callback) const { + const ShaderCacheCallback& shader_callback) { char a_sha[kHashLength]; char b_sha[kHashLength]; ComputeShaderHash( @@ -126,24 +129,24 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( sha); const std::string sha_string(sha, kHashLength); - StoreMap::const_iterator found = store_.find(sha_string); + ProgramMRUCache::iterator found = store_.Get(sha_string); if (found == store_.end()) { return PROGRAM_LOAD_FAILURE; } const scoped_refptr<ProgramCacheValue> value = found->second; glProgramBinary(program, - value->format, - static_cast<const GLvoid*>(value->data.get()), - value->length); + value->format(), + static_cast<const GLvoid*>(value->data()), + value->length()); GLint success = 0; glGetProgramiv(program, GL_LINK_STATUS, &success); if (success == GL_FALSE) { return PROGRAM_LOAD_FAILURE; } - shader_a->set_attrib_map(value->attrib_map_0); - shader_a->set_uniform_map(value->uniform_map_0); - shader_b->set_attrib_map(value->attrib_map_1); - shader_b->set_uniform_map(value->uniform_map_1); + shader_a->set_attrib_map(value->attrib_map_0()); + shader_a->set_uniform_map(value->uniform_map_0()); + shader_b->set_attrib_map(value->attrib_map_1()); + shader_b->set_uniform_map(value->uniform_map_1()); if (!shader_callback.is_null() && !CommandLine::ForCurrentProcess()->HasSwitch( @@ -151,8 +154,8 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( scoped_ptr<GpuProgramProto> proto( GpuProgramProto::default_instance().New()); proto->set_sha(sha, kHashLength); - proto->set_format(value->format); - proto->set_program(value->data.get(), value->length); + proto->set_format(value->format()); + proto->set_program(value->data(), value->length()); FillShaderProto(proto->mutable_vertex_shader(), a_sha, shader_a); FillShaderProto(proto->mutable_fragment_shader(), b_sha, shader_b); @@ -201,23 +204,15 @@ void MemoryProgramCache::SaveLinkedProgram( UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeBeforeKb", curr_size_bytes_ / 1024); - if (store_.find(sha_string) != store_.end()) { - const StoreMap::iterator found = store_.find(sha_string); - const ProgramCacheValue* evicting = found->second.get(); - curr_size_bytes_ -= evicting->length; - Evict(sha_string, evicting->shader_0_hash, evicting->shader_1_hash); - store_.erase(found); - } + // Evict any cached program with the same key in favor of the least recently + // accessed. + ProgramMRUCache::iterator existing = store_.Peek(sha_string); + if(existing != store_.end()) + store_.Erase(existing); while (curr_size_bytes_ + length > max_size_bytes_) { - DCHECK(!eviction_helper_.IsEmpty()); - const std::string* program = eviction_helper_.PeekKey(); - const StoreMap::iterator found = store_.find(*program); - const ProgramCacheValue* evicting = found->second.get(); - curr_size_bytes_ -= evicting->length; - Evict(*program, evicting->shader_0_hash, evicting->shader_1_hash); - store_.erase(found); - eviction_helper_.PopKey(); + DCHECK(!store_.empty()); + store_.Erase(store_.rbegin()); } if (!shader_callback.is_null() && @@ -234,24 +229,21 @@ void MemoryProgramCache::SaveLinkedProgram( RunShaderCallback(shader_callback, proto.get(), sha_string); } - store_[sha_string] = new ProgramCacheValue(length, - format, - binary.release(), - a_sha, - shader_a->attrib_map(), - shader_a->uniform_map(), - b_sha, - shader_b->attrib_map(), - shader_b->uniform_map()); - curr_size_bytes_ += length; - eviction_helper_.KeyUsed(sha_string); + store_.Put(sha_string, + new ProgramCacheValue(length, + format, + binary.release(), + sha_string, + a_sha, + shader_a->attrib_map(), + shader_a->uniform_map(), + b_sha, + shader_b->attrib_map(), + shader_b->uniform_map(), + this)); UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", curr_size_bytes_ / 1024); - - LinkedProgramCacheSuccess(sha_string, - std::string(a_sha, kHashLength), - std::string(b_sha, kHashLength)); } void MemoryProgramCache::LoadProgram(const std::string& program) { @@ -284,51 +276,63 @@ void MemoryProgramCache::LoadProgram(const std::string& program) { scoped_ptr<char[]> binary(new char[proto->program().length()]); memcpy(binary.get(), proto->program().c_str(), proto->program().length()); - store_[proto->sha()] = new ProgramCacheValue(proto->program().length(), - proto->format(), binary.release(), - proto->vertex_shader().sha().c_str(), vertex_attribs, vertex_uniforms, - proto->fragment_shader().sha().c_str(), fragment_attribs, - fragment_uniforms); + store_.Put(proto->sha(), + new ProgramCacheValue(proto->program().length(), + proto->format(), + binary.release(), + proto->sha(), + proto->vertex_shader().sha().c_str(), + vertex_attribs, + vertex_uniforms, + proto->fragment_shader().sha().c_str(), + fragment_attribs, + fragment_uniforms, + this)); ShaderCompilationSucceededSha(proto->sha()); ShaderCompilationSucceededSha(proto->vertex_shader().sha()); ShaderCompilationSucceededSha(proto->fragment_shader().sha()); - curr_size_bytes_ += proto->program().length(); - eviction_helper_.KeyUsed(proto->sha()); - UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", curr_size_bytes_ / 1024); - - LinkedProgramCacheSuccess(proto->sha(), - proto->vertex_shader().sha(), - proto->fragment_shader().sha()); } else { LOG(ERROR) << "Failed to parse proto file."; } } MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( - GLsizei _length, - GLenum _format, - const char* _data, - const char* _shader_0_hash, - const ShaderTranslator::VariableMap& _attrib_map_0, - const ShaderTranslator::VariableMap& _uniform_map_0, - const char* _shader_1_hash, - const ShaderTranslator::VariableMap& _attrib_map_1, - const ShaderTranslator::VariableMap& _uniform_map_1) - : length(_length), - format(_format), - data(_data), - shader_0_hash(_shader_0_hash, kHashLength), - attrib_map_0(_attrib_map_0), - uniform_map_0(_uniform_map_0), - shader_1_hash(_shader_1_hash, kHashLength), - attrib_map_1(_attrib_map_1), - uniform_map_1(_uniform_map_1) {} - -MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() {} + GLsizei length, + GLenum format, + const char* data, + const std::string& program_hash, + const char* shader_0_hash, + const ShaderTranslator::VariableMap& attrib_map_0, + const ShaderTranslator::VariableMap& uniform_map_0, + const char* shader_1_hash, + const ShaderTranslator::VariableMap& attrib_map_1, + const ShaderTranslator::VariableMap& uniform_map_1, + MemoryProgramCache* program_cache) + : length_(length), + format_(format), + data_(data), + program_hash_(program_hash), + shader_0_hash_(shader_0_hash, kHashLength), + attrib_map_0_(attrib_map_0), + uniform_map_0_(uniform_map_0), + shader_1_hash_(shader_1_hash, kHashLength), + attrib_map_1_(attrib_map_1), + uniform_map_1_(uniform_map_1), + program_cache_(program_cache) { + program_cache_->curr_size_bytes_ += length_; + program_cache_->LinkedProgramCacheSuccess(program_hash, + shader_0_hash_, + shader_1_hash_); +} + +MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { + program_cache_->curr_size_bytes_ -= length_; + program_cache_->Evict(program_hash_, shader_0_hash_, shader_1_hash_); +} } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/memory_program_cache.h b/gpu/command_buffer/service/memory_program_cache.h index 1f2e53ac22..b2f23e6d8c 100644 --- a/gpu/command_buffer/service/memory_program_cache.h +++ b/gpu/command_buffer/service/memory_program_cache.h @@ -9,11 +9,11 @@ #include <string> #include "base/containers/hash_tables.h" +#include "base/containers/mru_cache.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/program_cache.h" -#include "gpu/command_buffer/service/program_cache_lru_helper.h" #include "gpu/command_buffer/service/shader_translator.h" namespace gpu { @@ -33,7 +33,7 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache { Shader* shader_b, const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, - const ShaderCacheCallback& shader_callback) const OVERRIDE; + const ShaderCacheCallback& shader_callback) OVERRIDE; virtual void SaveLinkedProgram( GLuint program, const Shader* shader_a, @@ -48,42 +48,84 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache { private: virtual void ClearBackend() OVERRIDE; - struct ProgramCacheValue : public base::RefCounted<ProgramCacheValue> { + class ProgramCacheValue : public base::RefCounted<ProgramCacheValue> { public: - ProgramCacheValue(GLsizei _length, - GLenum _format, - const char* _data, - const char* _shader_0_hash, - const ShaderTranslator::VariableMap& _attrib_map_0, - const ShaderTranslator::VariableMap& _uniform_map_0, - const char* _shader_1_hash, - const ShaderTranslator::VariableMap& _attrib_map_1, - const ShaderTranslator::VariableMap& _uniform_map_1); - const GLsizei length; - const GLenum format; - const scoped_ptr<const char[]> data; - const std::string shader_0_hash; - const ShaderTranslator::VariableMap attrib_map_0; - const ShaderTranslator::VariableMap uniform_map_0; - const std::string shader_1_hash; - const ShaderTranslator::VariableMap attrib_map_1; - const ShaderTranslator::VariableMap uniform_map_1; + ProgramCacheValue(GLsizei length, + GLenum format, + const char* data, + const std::string& program_hash, + const char* shader_0_hash, + const ShaderTranslator::VariableMap& attrib_map_0, + const ShaderTranslator::VariableMap& uniform_map_0, + const char* shader_1_hash, + const ShaderTranslator::VariableMap& attrib_map_1, + const ShaderTranslator::VariableMap& uniform_map_1, + MemoryProgramCache* program_cache); + + GLsizei length() const { + return length_; + } + + GLenum format() const { + return format_; + } + + const char* data() const { + return data_.get(); + } + + const std::string& shader_0_hash() const { + return shader_0_hash_; + } + + const ShaderTranslator::VariableMap& attrib_map_0() const { + return attrib_map_0_; + } + + const ShaderTranslator::VariableMap& uniform_map_0() const { + return uniform_map_0_; + } + + const std::string& shader_1_hash() const { + return shader_1_hash_; + } + + const ShaderTranslator::VariableMap& attrib_map_1() const { + return attrib_map_1_; + } + + const ShaderTranslator::VariableMap& uniform_map_1() const { + return uniform_map_1_; + } private: friend class base::RefCounted<ProgramCacheValue>; ~ProgramCacheValue(); + const GLsizei length_; + const GLenum format_; + const scoped_ptr<const char[]> data_; + const std::string program_hash_; + const std::string shader_0_hash_; + const ShaderTranslator::VariableMap attrib_map_0_; + const ShaderTranslator::VariableMap uniform_map_0_; + const std::string shader_1_hash_; + const ShaderTranslator::VariableMap attrib_map_1_; + const ShaderTranslator::VariableMap uniform_map_1_; + MemoryProgramCache* const program_cache_; + DISALLOW_COPY_AND_ASSIGN(ProgramCacheValue); }; - typedef base::hash_map<std::string, - scoped_refptr<ProgramCacheValue> > StoreMap; + friend class ProgramCacheValue; + + typedef base::MRUCache<std::string, + scoped_refptr<ProgramCacheValue> > ProgramMRUCache; const size_t max_size_bytes_; size_t curr_size_bytes_; - StoreMap store_; - ProgramCacheLruHelper eviction_helper_; + ProgramMRUCache store_; DISALLOW_COPY_AND_ASSIGN(MemoryProgramCache); }; diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h index 11b8ae6fdb..fda872245c 100644 --- a/gpu/command_buffer/service/mocks.h +++ b/gpu/command_buffer/service/mocks.h @@ -100,7 +100,7 @@ class MockProgramCache : public ProgramCache { MockProgramCache(); virtual ~MockProgramCache(); - MOCK_CONST_METHOD7(LoadLinkedProgram, ProgramLoadResult( + MOCK_METHOD7(LoadLinkedProgram, ProgramLoadResult( GLuint program, Shader* shader_a, const ShaderTranslatorInterface* translator_a, diff --git a/gpu/command_buffer/service/program_cache.cc b/gpu/command_buffer/service/program_cache.cc index 62e636d813..f0adf6e504 100644 --- a/gpu/command_buffer/service/program_cache.cc +++ b/gpu/command_buffer/service/program_cache.cc @@ -15,9 +15,9 @@ ProgramCache::ProgramCache() {} ProgramCache::~ProgramCache() {} void ProgramCache::Clear() { + ClearBackend(); shader_status_.clear(); link_status_.clear(); - ClearBackend(); } ProgramCache::CompiledShaderStatus ProgramCache::GetShaderCompilationStatus( diff --git a/gpu/command_buffer/service/program_cache.h b/gpu/command_buffer/service/program_cache.h index 9b28dd8ef9..a8b9f913b3 100644 --- a/gpu/command_buffer/service/program_cache.h +++ b/gpu/command_buffer/service/program_cache.h @@ -68,7 +68,7 @@ class GPU_EXPORT ProgramCache { Shader* shader_b, const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, - const ShaderCacheCallback& shader_callback) const = 0; + const ShaderCacheCallback& shader_callback) = 0; // Saves the program into the cache. If successful, the implementation should // call LinkedProgramCacheSuccess. diff --git a/gpu/command_buffer/service/program_cache_lru_helper.cc b/gpu/command_buffer/service/program_cache_lru_helper.cc deleted file mode 100644 index a1f455524a..0000000000 --- a/gpu/command_buffer/service/program_cache_lru_helper.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2012 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/service/program_cache_lru_helper.h" - -namespace gpu { -namespace gles2 { - -ProgramCacheLruHelper::ProgramCacheLruHelper() {} -ProgramCacheLruHelper::~ProgramCacheLruHelper() {} - -void ProgramCacheLruHelper::Clear() { - location_map.clear(); - queue.clear(); -} - -bool ProgramCacheLruHelper::IsEmpty() { - return queue.empty(); -} - -void ProgramCacheLruHelper::KeyUsed(const std::string& key) { - IteratorMap::iterator location_iterator = location_map.find(key); - if (location_iterator != location_map.end()) { - // already exists, erase it - queue.erase(location_iterator->second); - } - queue.push_front(key); - location_map[key] = queue.begin(); -} - -const std::string* ProgramCacheLruHelper::PeekKey() { - if (queue.empty()) { - return NULL; - } - return &queue.back(); -} - -void ProgramCacheLruHelper::PopKey() { - if (queue.empty()) { - return; - } - const std::string& last = queue.back(); - location_map.erase(last); - queue.pop_back(); -} - -} // namespace gpu -} // namespace gles2 diff --git a/gpu/command_buffer/service/program_cache_lru_helper.h b/gpu/command_buffer/service/program_cache_lru_helper.h deleted file mode 100644 index 766704c00f..0000000000 --- a/gpu/command_buffer/service/program_cache_lru_helper.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_LRU_HELPER_H_ -#define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_LRU_HELPER_H_ - -#include <list> -#include <string> - -#include "base/basictypes.h" -#include "base/containers/hash_tables.h" -#include "gpu/gpu_export.h" - -namespace gpu { -namespace gles2 { - -// LRU helper for the program cache, operates in O(1) time. -// This class uses a linked list with a hash map. Both copy their string keys, -// so be mindful that keys you insert will be stored again twice in memory. -class GPU_EXPORT ProgramCacheLruHelper { - public: - ProgramCacheLruHelper(); - ~ProgramCacheLruHelper(); - - // clears the lru queue - void Clear(); - // returns true if the lru queue is empty - bool IsEmpty(); - // inserts or refreshes a key in the queue - void KeyUsed(const std::string& key); - // Peeks at the next key. Use IsEmpty() first (if the queue is empty then - // null is returned). - const std::string* PeekKey(); - // evicts the next key from the queue. - void PopKey(); - - private: - typedef std::list<std::string> StringList; - typedef base::hash_map<std::string, - StringList::iterator> IteratorMap; - StringList queue; - IteratorMap location_map; - - DISALLOW_COPY_AND_ASSIGN(ProgramCacheLruHelper); -}; - -} // namespace gles2 -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_LRU_HELPER_H_ diff --git a/gpu/command_buffer/service/program_cache_lru_helper_unittest.cc b/gpu/command_buffer/service/program_cache_lru_helper_unittest.cc deleted file mode 100644 index 5aaa08881d..0000000000 --- a/gpu/command_buffer/service/program_cache_lru_helper_unittest.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2012 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/service/program_cache_lru_helper.h" - -#include "base/memory/scoped_ptr.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu { -namespace gles2 { - -class ProgramCacheLruHelperTest : public testing::Test { - public: - ProgramCacheLruHelperTest() : - lru_helper_(new ProgramCacheLruHelper()) { } - - protected: - virtual void SetUp() { - } - - virtual void TearDown() { - lru_helper_->Clear(); - } - - scoped_ptr<ProgramCacheLruHelper> lru_helper_; -}; - -TEST_F(ProgramCacheLruHelperTest, ProgramCacheLruHelperEvictionOrderNoReuse) { - lru_helper_->KeyUsed("1"); - lru_helper_->KeyUsed("2"); - lru_helper_->KeyUsed("3"); - lru_helper_->KeyUsed("4"); - const std::string* key = lru_helper_->PeekKey(); - EXPECT_EQ("1", *key); - EXPECT_EQ("1", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_FALSE(lru_helper_->IsEmpty()); - EXPECT_EQ("2", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_FALSE(lru_helper_->IsEmpty()); - EXPECT_EQ("3", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_FALSE(lru_helper_->IsEmpty()); - EXPECT_EQ("4", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_TRUE(lru_helper_->IsEmpty()); -} - -TEST_F(ProgramCacheLruHelperTest, ProgramCacheLruHelperClear) { - EXPECT_TRUE(lru_helper_->IsEmpty()); - lru_helper_->KeyUsed("1"); - lru_helper_->KeyUsed("2"); - lru_helper_->KeyUsed("3"); - lru_helper_->KeyUsed("4"); - EXPECT_FALSE(lru_helper_->IsEmpty()); - lru_helper_->Clear(); - EXPECT_TRUE(lru_helper_->IsEmpty()); -} - -TEST_F(ProgramCacheLruHelperTest, ProgramCacheLruHelperEvictionOrderWithReuse) { - lru_helper_->KeyUsed("1"); - lru_helper_->KeyUsed("2"); - lru_helper_->KeyUsed("4"); - lru_helper_->KeyUsed("2"); - lru_helper_->KeyUsed("3"); - lru_helper_->KeyUsed("1"); - lru_helper_->KeyUsed("1"); - lru_helper_->KeyUsed("2"); - EXPECT_EQ("4", *lru_helper_->PeekKey()); - EXPECT_EQ("4", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_EQ("3", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_EQ("1", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_FALSE(lru_helper_->IsEmpty()); - EXPECT_EQ("2", *lru_helper_->PeekKey()); - lru_helper_->PopKey(); - EXPECT_TRUE(lru_helper_->IsEmpty()); -} - -} // namespace gles2 -} // namespace gpu diff --git a/gpu/command_buffer/service/program_cache_unittest.cc b/gpu/command_buffer/service/program_cache_unittest.cc index 63c032db5b..9ff6da95c2 100644 --- a/gpu/command_buffer/service/program_cache_unittest.cc +++ b/gpu/command_buffer/service/program_cache_unittest.cc @@ -22,7 +22,7 @@ class NoBackendProgramCache : public ProgramCache { Shader* /* shader_b */, const ShaderTranslatorInterface* /* translator_b */, const LocationMap* /* bind_attrib_location_map */, - const ShaderCacheCallback& /* callback */) const OVERRIDE { + const ShaderCacheCallback& /* callback */) OVERRIDE { return PROGRAM_LOAD_SUCCESS; } virtual void SaveLinkedProgram( diff --git a/gpu/command_buffer/service/safe_shared_memory_pool.cc b/gpu/command_buffer/service/safe_shared_memory_pool.cc index 1489d5f49d..9ba5390d20 100644 --- a/gpu/command_buffer/service/safe_shared_memory_pool.cc +++ b/gpu/command_buffer/service/safe_shared_memory_pool.cc @@ -36,7 +36,6 @@ base::SharedMemory* ScopedSafeSharedMemory::shared_memory() { return safe_shared_memory_; } - SafeSharedMemoryPool::SafeSharedMemoryPool() : handles_acquired_(0), handles_consumed_(0), @@ -94,8 +93,8 @@ void SafeSharedMemoryPool:: base::AutoLock scoped_lock(lock_); // Adjust stats. + DCHECK_GT(handles_acquired_, 0); handles_acquired_--; - DCHECK(handles_acquired_ >= 0); MemoryMap::iterator it = memory_.find(handle); CHECK(it != memory_.end()); @@ -103,10 +102,10 @@ void SafeSharedMemoryPool:: CHECK(it->second.safe_shared_memory); if (--it->second.reference_count == 0) { // Adjust stats. + DCHECK_GT(handles_consumed_, 0); handles_consumed_--; + DCHECK_LE(it->second.shm_size, address_space_consumed_); address_space_consumed_ -= it->second.shm_size; - DCHECK(handles_consumed_ >= 0); - DCHECK(address_space_consumed_ >= 0); // Delete the safe memory and remove it. delete it->second.safe_shared_memory; memory_.erase(it); @@ -147,4 +146,4 @@ SharedMemory* SafeSharedMemoryPool::DuplicateSharedMemory( return duped_shared_memory.release(); } -} // namespace gfx +} // namespace gpu diff --git a/gpu/command_buffer/tests/compressed_texture_test.cc b/gpu/command_buffer/tests/compressed_texture_test.cc new file mode 100644 index 0000000000..8c214b20cd --- /dev/null +++ b/gpu/command_buffer/tests/compressed_texture_test.cc @@ -0,0 +1,255 @@ +// Copyright 2013 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 <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include "base/basictypes.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +#define SHADER(src) #src + +namespace gpu { + +static const uint16 kRedMask = 0xF800; +static const uint16 kGreenMask = 0x07E0; +static const uint16 kBlueMask = 0x001F; + +// Color palette in 565 format. +static const uint16 kPalette[] = { + kGreenMask | kBlueMask, // Cyan. + kBlueMask | kRedMask, // Magenta. + kRedMask | kGreenMask, // Yellow. + 0x0000, // Black. + kRedMask, // Red. + kGreenMask, // Green. + kBlueMask, // Blue. + 0xFFFF, // White. +}; +static const unsigned kBlockSize = 4; +static const unsigned kPaletteSize = sizeof(kPalette) / sizeof(kPalette[0]); +static const unsigned kTextureWidth = kBlockSize * kPaletteSize; +static const unsigned kTextureHeight = kBlockSize; + +static const char* extension(GLenum format) { + switch(format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return "GL_EXT_texture_compression_dxt1"; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return "GL_CHROMIUM_texture_compression_dxt3"; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return "GL_CHROMIUM_texture_compression_dxt5"; + default: + NOTREACHED(); + } + return NULL; +} + +// Index that chooses the given colors (color_0 and color_1), +// not the interpolated colors (color_2 and color_3). +static const uint16 kColor0 = 0x0000; +static const uint16 kColor1 = 0x5555; + +static GLuint LoadCompressedTexture(const void* data, + GLsizeiptr size, + GLenum format, + GLsizei width, + GLsizei height) { + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCompressedTexImage2D( + GL_TEXTURE_2D, 0, format, width, height, 0, size, data); + return texture; +} + +GLuint LoadTextureDXT1(bool alpha) { + const unsigned kStride = 4; + uint16 data[kStride * kPaletteSize]; + for (unsigned i = 0; i < kPaletteSize; ++i) { + // Each iteration defines a 4x4 block of texture. + unsigned j = kStride * i; + data[j++] = kPalette[i]; // color_0. + data[j++] = kPalette[i]; // color_1. + data[j++] = kColor0; // color index. + data[j++] = kColor1; // color index. + } + GLenum format = alpha ? + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + return LoadCompressedTexture( + data, sizeof(data), format, kTextureWidth, kTextureHeight); +} + +GLuint LoadTextureDXT3() { + const unsigned kStride = 8; + const uint16 kOpaque = 0xFFFF; + uint16 data[kStride * kPaletteSize]; + for (unsigned i = 0; i < kPaletteSize; ++i) { + // Each iteration defines a 4x4 block of texture. + unsigned j = kStride * i; + data[j++] = kOpaque; // alpha row 0. + data[j++] = kOpaque; // alpha row 1. + data[j++] = kOpaque; // alpha row 2. + data[j++] = kOpaque; // alpha row 3. + data[j++] = kPalette[i]; // color_0. + data[j++] = kPalette[i]; // color_1. + data[j++] = kColor0; // color index. + data[j++] = kColor1; // color index. + } + return LoadCompressedTexture(data, + sizeof(data), + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + kTextureWidth, + kTextureHeight); +} + +GLuint LoadTextureDXT5() { + const unsigned kStride = 8; + const uint16 kClear = 0x0000; + const uint16 kAlpha7 = 0xFFFF; // Opaque alpha index. + uint16 data[kStride * kPaletteSize]; + for (unsigned i = 0; i < kPaletteSize; ++i) { + // Each iteration defines a 4x4 block of texture. + unsigned j = kStride * i; + data[j++] = kClear; // alpha_0 | alpha_1. + data[j++] = kAlpha7; // alpha index. + data[j++] = kAlpha7; // alpha index. + data[j++] = kAlpha7; // alpha index. + data[j++] = kPalette[i]; // color_0. + data[j++] = kPalette[i]; // color_1. + data[j++] = kColor0; // color index. + data[j++] = kColor1; // color index. + } + return LoadCompressedTexture(data, + sizeof(data), + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, + kTextureWidth, + kTextureHeight); +} + +static void ToRGB888(uint16 rgb565, uint8 rgb888[]) { + uint8 r5 = (rgb565 & kRedMask) >> 11; + uint8 g6 = (rgb565 & kGreenMask) >> 5; + uint8 b5 = (rgb565 & kBlueMask); + // Replicate upper bits to lower empty bits. + rgb888[0] = (r5 << 3) | (r5 >> 2); + rgb888[1] = (g6 << 2) | (g6 >> 4); + rgb888[2] = (b5 << 3) | (b5 >> 2); +} + +class CompressedTextureTest : public ::testing::TestWithParam<GLenum> { + protected: + virtual void SetUp() { + GLManager::Options options; + options.size = gfx::Size(kTextureWidth, kTextureHeight); + gl_.Initialize(options); + } + + virtual void TearDown() { + gl_.Destroy(); + } + + GLuint LoadProgram() { + const char* v_shader_src = SHADER( + attribute vec2 a_position; + varying vec2 v_texcoord; + void main() { + gl_Position = vec4(a_position, 0.0, 1.0); + v_texcoord = (a_position + 1.0) * 0.5; + } + ); + const char* f_shader_src = SHADER( + precision mediump float; + uniform sampler2D u_texture; + varying vec2 v_texcoord; + void main() { + gl_FragColor = texture2D(u_texture, v_texcoord); + } + ); + return GLTestHelper::LoadProgram(v_shader_src, f_shader_src); + } + + GLuint LoadTexture(GLenum format) { + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return LoadTextureDXT1(false); + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return LoadTextureDXT1(true); + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return LoadTextureDXT3(); + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return LoadTextureDXT5(); + default: NOTREACHED(); + } + return 0; + } + + private: + GLManager gl_; +}; + +// The test draws a texture in the given format and verifies that the drawn +// pixels are of the same color as the texture. +// The texture consists of 4x4 blocks of texels (same as DXT), one for each +// color defined in kPalette. +TEST_P(CompressedTextureTest, Draw) { + GLenum format = GetParam(); + + // This test is only valid if compressed texture extension is supported. + const char* ext = extension(format); + if (!GLTestHelper::HasExtension(ext)) + return; + + // Load shader program. + GLuint program = LoadProgram(); + ASSERT_NE(program, 0u); + GLint position_loc = glGetAttribLocation(program, "a_position"); + GLint texture_loc = glGetUniformLocation(program, "u_texture"); + ASSERT_NE(position_loc, -1); + ASSERT_NE(texture_loc, -1); + glUseProgram(program); + + // Load geometry. + GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc); + ASSERT_NE(vbo, 0u); + + // Load texture. + GLuint texture = LoadTexture(format); + ASSERT_NE(texture, 0u); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(texture_loc, 0); + + // Draw. + glDrawArrays(GL_TRIANGLES, 0, 6); + glFlush(); + + // Verify results. + int origin[] = {0, 0}; + uint8 expected_rgba[] = {0, 0, 0, 255}; + for (unsigned i = 0; i < kPaletteSize; ++i) { + origin[0] = kBlockSize * i; + ToRGB888(kPalette[i], expected_rgba); + EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1], + kBlockSize, kBlockSize, + 0, expected_rgba)); + } + GLTestHelper::CheckGLError("CompressedTextureTest.Draw", __LINE__); +} + +static const GLenum kFormats[] = { + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +}; +INSTANTIATE_TEST_CASE_P(Format, + CompressedTextureTest, + ::testing::ValuesIn(kFormats)); + +} // namespace gpu diff --git a/gpu/command_buffer/tests/gl_depth_texture_unittest.cc b/gpu/command_buffer/tests/gl_depth_texture_unittest.cc index 071ca44d91..e97863c4db 100644 --- a/gpu/command_buffer/tests/gl_depth_texture_unittest.cc +++ b/gpu/command_buffer/tests/gl_depth_texture_unittest.cc @@ -61,8 +61,8 @@ struct FormatType { } // anonymous namespace // crbug.com/135229 -// Fails on Win Intel, Linux Intel. -#if ((defined(OS_WIN) || defined(OS_LINUX)) && defined(NDEBUG)) +// Fails on all Windows platforms and on Linux Intel. +#if defined(OS_WIN) || (defined(OS_LINUX) && defined(NDEBUG)) #define MAYBE_RenderTo DISABLED_RenderTo #else #define MAYBE_RenderTo RenderTo diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc index 4647465abd..9c9d5ab1f1 100644 --- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc @@ -9,17 +9,14 @@ #include "base/bind.h" #include "base/memory/ref_counted.h" +#include "base/process/process_handle.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gpu_memory_buffer_mock.h" -#include "gpu/command_buffer/client/image_factory_mock.h" #include "gpu/command_buffer/service/image_manager.h" #include "gpu/command_buffer/tests/gl_manager.h" #include "gpu/command_buffer/tests/gl_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/native_widget_types.h" #include "ui/gl/gl_image.h" -#include "ui/gl/gl_image_mock.h" using testing::_; using testing::IgnoreResult; @@ -32,50 +29,116 @@ using testing::StrictMock; namespace gpu { namespace gles2 { -static const int kImageWidth = 256; -static const int kImageHeight = 256; +static const int kImageWidth = 32; +static const int kImageHeight = 32; static const int kImageBytesPerPixel = 4; +class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer { + public: + MockGpuMemoryBuffer(int width, int height) {} + virtual ~MockGpuMemoryBuffer() { + Die(); + } + + MOCK_METHOD2(Map, void(gfx::GpuMemoryBuffer::AccessMode, void**)); + MOCK_METHOD0(Unmap, void()); + MOCK_CONST_METHOD0(IsMapped, bool()); + MOCK_CONST_METHOD0(GetStride, uint32()); + MOCK_CONST_METHOD0(GetHandle, gfx::GpuMemoryBufferHandle()); + MOCK_METHOD0(Die, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBuffer); +}; + +class MockImageFactory : public ImageFactory { + public: + MockImageFactory(ImageManager* image_manager) {} + virtual ~MockImageFactory() {} + + MOCK_METHOD4(CreateGpuMemoryBufferMock, gfx::GpuMemoryBuffer*( + int width, int height, GLenum internalformat, unsigned* image_id)); + MOCK_METHOD1(DeleteGpuMemoryBuffer, void(unsigned)); + // Workaround for mocking methods that return scoped_ptrs + virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( + int width, int height, GLenum internalformat, + unsigned* image_id) OVERRIDE { + return scoped_ptr<gfx::GpuMemoryBuffer>(CreateGpuMemoryBufferMock( + width, height, internalformat, image_id)); + } + + private: + DISALLOW_COPY_AND_ASSIGN(MockImageFactory); +}; + class MockGpuMemoryBufferTest : public testing::Test { protected: virtual void SetUp() { GLManager::Options options; image_manager_ = new ImageManager; image_factory_.reset( - new StrictMock<ImageFactoryMock>(image_manager_.get())); + new StrictMock<MockImageFactory>(image_manager_.get())); options.image_manager = image_manager_.get(); options.image_factory = image_factory_.get(); gl_.Initialize(options); gl_.MakeCurrent(); + + glGenTextures(2, texture_ids_); + glBindTexture(GL_TEXTURE_2D, texture_ids_[1]); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glGenFramebuffers(1, &framebuffer_id_); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + texture_ids_[1], + 0); } virtual void TearDown() { + glDeleteTextures(2, texture_ids_); + glDeleteFramebuffers(1, &framebuffer_id_); + gl_.Destroy(); } - scoped_ptr<StrictMock<ImageFactoryMock> > image_factory_; + scoped_ptr<StrictMock<MockImageFactory> > image_factory_; scoped_refptr<ImageManager> image_manager_; GLManager gl_; + GLuint texture_ids_[2]; + GLuint framebuffer_id_; }; // An end to end test that tests the whole GpuMemoryBuffer lifecycle. TEST_F(MockGpuMemoryBufferTest, Lifecycle) { - // Create a client texture id. - GLuint texture_id; - glGenTextures(1, &texture_id); + size_t bytes = kImageWidth * kImageHeight * kImageBytesPerPixel; + uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u }; // Buffer is owned and freed by GpuMemoryBufferTracker. - StrictMock<GpuMemoryBufferMock>* gpu_memory_buffer = - new StrictMock<GpuMemoryBufferMock>(kImageWidth, kImageHeight); + StrictMock<MockGpuMemoryBuffer>* gpu_memory_buffer = + new StrictMock<MockGpuMemoryBuffer>(kImageWidth, kImageHeight); + base::SharedMemory shared_memory; + shared_memory.CreateAnonymous(bytes); + + base::SharedMemoryHandle duped_shared_memory_handle; + shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), + &duped_shared_memory_handle); + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::SHARED_MEMORY_BUFFER; + handle.handle = duped_shared_memory_handle; const GLuint kImageId = 345u; EXPECT_CALL(*image_factory_.get(), CreateGpuMemoryBufferMock( kImageWidth, kImageHeight, GL_RGBA8_OES, _)) .Times(1) - .WillOnce(DoAll(SetArgPointee<3>(kImageId), - Return(gpu_memory_buffer))) + .WillOnce(DoAll(SetArgPointee<3>(kImageId), Return(gpu_memory_buffer))) .RetiresOnSaturation(); // Create the GLImage and insert it into the ImageManager, which @@ -84,25 +147,41 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { kImageWidth, kImageHeight, GL_RGBA8_OES); EXPECT_EQ(kImageId, image_id); + EXPECT_CALL(*gpu_memory_buffer, GetHandle()) + .WillOnce(Return(handle)) + .RetiresOnSaturation(); + gfx::Size size(kImageWidth, kImageHeight); - scoped_refptr<gfx::GLImageMock> gl_image( - new gfx::GLImageMock(gpu_memory_buffer, size)); + scoped_refptr<gfx::GLImage> gl_image( + gfx::GLImage::CreateGLImageForGpuMemoryBuffer( + gpu_memory_buffer->GetHandle(), size)); image_manager_->AddImage(gl_image.get(), image_id); EXPECT_CALL(*gpu_memory_buffer, IsMapped()) .WillOnce(Return(false)) .RetiresOnSaturation(); - scoped_ptr<uint8[]> buffer_pixels(new uint8[ - kImageWidth * kImageHeight * kImageBytesPerPixel]); + shared_memory.Map(bytes); + EXPECT_TRUE(shared_memory.memory()); EXPECT_CALL(*gpu_memory_buffer, Map(_, _)) .Times(1) - .WillOnce(SetArgPointee<1>(buffer_pixels.get())) + .WillOnce(SetArgPointee<1>(shared_memory.memory())) .RetiresOnSaturation(); - void* mapped_buffer = - glMapImageCHROMIUM(image_id, GL_WRITE_ONLY); - EXPECT_EQ(buffer_pixels.get(), mapped_buffer); + uint8* mapped_buffer = static_cast<uint8*>( + glMapImageCHROMIUM(image_id, GL_READ_WRITE)); + ASSERT_TRUE(mapped_buffer != NULL); + + // Assign a value to each pixel. + int stride = kImageWidth * kImageBytesPerPixel; + for (int x = 0; x < kImageWidth; ++x) { + for (int y = 0; y < kImageHeight; ++y) { + mapped_buffer[y * stride + x * kImageBytesPerPixel + 0] = pixels[0]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 1] = pixels[1]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 2] = pixels[2]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 3] = pixels[3]; + } + } EXPECT_CALL(*gpu_memory_buffer, IsMapped()) .WillOnce(Return(true)) @@ -115,13 +194,25 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { glUnmapImageCHROMIUM(image_id); // Bind the texture and the image. - glBindTexture(GL_TEXTURE_2D, texture_id); - EXPECT_CALL(*gl_image.get(), BindTexImage()).Times(1).WillOnce(Return(true)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_image.get(), GetSize()).Times(1).WillOnce(Return(size)) - .RetiresOnSaturation(); + glBindTexture(GL_TEXTURE_2D, texture_ids_[0]); glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id); + // Copy texture so we can verify result using CheckPixels. + glCopyTextureCHROMIUM(GL_TEXTURE_2D, + texture_ids_[0], + texture_ids_[1], + 0, + GL_RGBA, + GL_UNSIGNED_BYTE); + EXPECT_TRUE(glGetError() == GL_NO_ERROR); + + // Check if pixels match the values that were assigned to the mapped buffer. + GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixels); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + // Release the image. + glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id); + // Destroy the image. EXPECT_CALL(*gpu_memory_buffer, Die()) .Times(1) @@ -132,9 +223,6 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { .RetiresOnSaturation(); glDestroyImageCHROMIUM(image_id); - - // Delete the texture. - glDeleteTextures(1, &texture_id); } } // namespace gles2 diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index 37d28a5b4c..f8e94c18eb 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -103,8 +103,6 @@ 'command_buffer/service/renderbuffer_manager.cc', 'command_buffer/service/program_cache.h', 'command_buffer/service/program_cache.cc', - 'command_buffer/service/program_cache_lru_helper.h', - 'command_buffer/service/program_cache_lru_helper.cc', 'command_buffer/service/safe_shared_memory_pool.h', 'command_buffer/service/safe_shared_memory_pool.cc', 'command_buffer/service/shader_manager.h', diff --git a/gpu/command_buffer_service.target.darwin-arm.mk b/gpu/command_buffer_service.target.darwin-arm.mk index dc7f90e20f..9755e0ee2f 100644 --- a/gpu/command_buffer_service.target.darwin-arm.mk +++ b/gpu/command_buffer_service.target.darwin-arm.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/command_buffer_service.target.darwin-mips.mk b/gpu/command_buffer_service.target.darwin-mips.mk index 8ab0fbf9a7..59049b6ee3 100644 --- a/gpu/command_buffer_service.target.darwin-mips.mk +++ b/gpu/command_buffer_service.target.darwin-mips.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/command_buffer_service.target.darwin-x86.mk b/gpu/command_buffer_service.target.darwin-x86.mk index 6c7b408aec..5bc2dfff61 100644 --- a/gpu/command_buffer_service.target.darwin-x86.mk +++ b/gpu/command_buffer_service.target.darwin-x86.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/command_buffer_service.target.linux-arm.mk b/gpu/command_buffer_service.target.linux-arm.mk index dc7f90e20f..9755e0ee2f 100644 --- a/gpu/command_buffer_service.target.linux-arm.mk +++ b/gpu/command_buffer_service.target.linux-arm.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/command_buffer_service.target.linux-mips.mk b/gpu/command_buffer_service.target.linux-mips.mk index 8ab0fbf9a7..59049b6ee3 100644 --- a/gpu/command_buffer_service.target.linux-mips.mk +++ b/gpu/command_buffer_service.target.linux-mips.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/command_buffer_service.target.linux-x86.mk b/gpu/command_buffer_service.target.linux-x86.mk index 6c7b408aec..5bc2dfff61 100644 --- a/gpu/command_buffer_service.target.linux-x86.mk +++ b/gpu/command_buffer_service.target.linux-x86.mk @@ -61,7 +61,6 @@ LOCAL_SRC_FILES := \ gpu/command_buffer/service/query_manager.cc \ gpu/command_buffer/service/renderbuffer_manager.cc \ gpu/command_buffer/service/program_cache.cc \ - gpu/command_buffer/service/program_cache_lru_helper.cc \ gpu/command_buffer/service/safe_shared_memory_pool.cc \ gpu/command_buffer/service/shader_manager.cc \ gpu/command_buffer/service/shader_translator.cc \ diff --git a/gpu/config/gpu_control_list.cc b/gpu/config/gpu_control_list.cc index b7da59bb7a..5eb09c489f 100644 --- a/gpu/config/gpu_control_list.cc +++ b/gpu/config/gpu_control_list.cc @@ -625,6 +625,24 @@ GpuControlList::GpuControlListEntry::GetEntryFromValue( dictionary_entry_count++; } + const base::DictionaryValue* gl_reset_notification_strategy_value = NULL; + if (value->GetDictionary("gl_reset_notification_strategy", + &gl_reset_notification_strategy_value)) { + std::string op; + std::string int_value; + std::string int_value2; + gl_reset_notification_strategy_value->GetString(kOp, &op); + gl_reset_notification_strategy_value->GetString("value", &int_value); + gl_reset_notification_strategy_value->GetString("value2", &int_value2); + if (!entry->SetGLResetNotificationStrategyInfo( + op, int_value, int_value2)) { + LOG(WARNING) << "Malformed gl_reset_notification_strategy entry " + << entry->id(); + return NULL; + } + dictionary_entry_count++; + } + const base::DictionaryValue* cpu_brand_value = NULL; if (value->GetDictionary("cpu_info", &cpu_brand_value)) { std::string cpu_op; @@ -906,6 +924,15 @@ bool GpuControlList::GpuControlListEntry::SetGLExtensionsInfo( return gl_extensions_info_->IsValid(); } +bool GpuControlList::GpuControlListEntry::SetGLResetNotificationStrategyInfo( + const std::string& op, + const std::string& int_string, + const std::string& int_string2) { + gl_reset_notification_strategy_info_.reset( + new IntInfo(op, int_string, int_string2)); + return gl_reset_notification_strategy_info_->IsValid(); +} + bool GpuControlList::GpuControlListEntry::SetCpuBrand( const std::string& cpu_op, const std::string& cpu_value) { @@ -1070,6 +1097,10 @@ bool GpuControlList::GpuControlListEntry::Contains( if (gl_extensions_info_.get() != NULL && !gpu_info.gl_extensions.empty() && !gl_extensions_info_->Contains(gpu_info.gl_extensions)) return false; + if (gl_reset_notification_strategy_info_.get() != NULL && + !gl_reset_notification_strategy_info_->Contains( + gpu_info.gl_reset_notification_strategy)) + return false; if (perf_graphics_info_.get() != NULL && (gpu_info.performance_stats.graphics == 0.0 || !perf_graphics_info_->Contains(gpu_info.performance_stats.graphics))) diff --git a/gpu/config/gpu_control_list.h b/gpu/config/gpu_control_list.h index 3e1f182167..62b66ec278 100644 --- a/gpu/config/gpu_control_list.h +++ b/gpu/config/gpu_control_list.h @@ -386,6 +386,10 @@ class GPU_EXPORT GpuControlList { bool SetGLExtensionsInfo(const std::string& extensions_op, const std::string& extensions_value); + bool SetGLResetNotificationStrategyInfo(const std::string& op, + const std::string& int_string, + const std::string& int_string2); + bool SetCpuBrand(const std::string& cpu_op, const std::string& cpu_value); @@ -444,6 +448,7 @@ class GPU_EXPORT GpuControlList { scoped_ptr<StringInfo> gl_vendor_info_; scoped_ptr<StringInfo> gl_renderer_info_; scoped_ptr<StringInfo> gl_extensions_info_; + scoped_ptr<IntInfo> gl_reset_notification_strategy_info_; scoped_ptr<StringInfo> cpu_brand_; scoped_ptr<FloatInfo> perf_graphics_info_; scoped_ptr<FloatInfo> perf_gaming_info_; diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 0127f028e3..827c76c17c 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc @@ -19,6 +19,7 @@ GPUInfo::GPUInfo() amd_switchable(false), lenovo_dcute(false), adapter_luid(0), + gl_reset_notification_strategy(0), can_lose_context(false), software_rendering(false), sandboxed(false) { diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h index 2489850902..98ab80ca30 100644 --- a/gpu/config/gpu_info.h +++ b/gpu/config/gpu_info.h @@ -120,6 +120,10 @@ struct GPU_EXPORT GPUInfo { // GL window system binding extensions. "" if not available. std::string gl_ws_extensions; + // GL reset notification strategy as defined by GL_ARB_robustness. 0 if GPU + // reset detection or notification not available. + uint32 gl_reset_notification_strategy; + // The device semantics, i.e. whether the Vista and Windows 7 specific // semantics are available. bool can_lose_context; diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index dba8c0be82..0bb83dd04f 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc @@ -108,6 +108,14 @@ bool CollectGraphicsInfoGL(GPUInfo* gpu_info) { gpu_info->gl_ws_extensions = window_system_binding_info.extensions; } + bool supports_robustness = + gpu_info->gl_extensions.find("GL_EXT_robustness") != std::string::npos || + gpu_info->gl_extensions.find("GL_ARB_robustness") != std::string::npos; + if (supports_robustness) { + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, + reinterpret_cast<GLint*>(&gpu_info->gl_reset_notification_strategy)); + } + // TODO(kbr): remove once the destruction of a current context automatically // clears the current context. context->ReleaseCurrent(surface.get()); @@ -135,6 +143,8 @@ void MergeGPUInfoGL(GPUInfo* basic_gpu_info, basic_gpu_info->gl_ws_vendor = context_gpu_info.gl_ws_vendor; basic_gpu_info->gl_ws_version = context_gpu_info.gl_ws_version; basic_gpu_info->gl_ws_extensions = context_gpu_info.gl_ws_extensions; + basic_gpu_info->gl_reset_notification_strategy = + context_gpu_info.gl_reset_notification_strategy; if (!context_gpu_info.driver_vendor.empty()) basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor; diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc index d9350f7f87..b7c5c53980 100644 --- a/gpu/config/software_rendering_list_json.cc +++ b/gpu/config/software_rendering_list_json.cc @@ -35,27 +35,28 @@ // 10. "gl_vendor" is a STRING structure (defined below). // 11. "gl_renderer" is a STRING structure (defined below). // 12. "gl_extensions" is a STRING structure (defined below). -// 13. "perf_graphics" is a FLOAT structure (defined below). -// 14. "perf_gaming" is a FLOAT structure (defined below). -// 15. "perf_overall" is a FLOAT structure (defined below). -// 16. "machine_model" contais "name" and an optional "version". "name" is a +// 13. "gl_reset_notification_strategy" is an INT structure (defined below). +// 14. "perf_graphics" is a FLOAT structure (defined below). +// 15. "perf_gaming" is a FLOAT structure (defined below). +// 16. "perf_overall" is a FLOAT structure (defined below). +// 17. "machine_model" contais "name" and an optional "version". "name" is a // STRING structure and "version" is a VERSION structure (defined below). -// 17. "gpu_count" is a INT structure (defined below). -// 18 "cpu_info" is a STRING structure (defined below). -// 19. "exceptions" is a list of entries. -// 20. "features" is a list of gpu feature strings, valid values include +// 18. "gpu_count" is a INT structure (defined below). +// 19 "cpu_info" is a STRING structure (defined below). +// 20. "exceptions" is a list of entries. +// 21. "features" is a list of gpu feature strings, valid values include // "accelerated_2d_canvas", "accelerated_compositing", "webgl", // "multisampling", "flash_3d", "flash_stage3d", "texture_sharing", // "accelerated_video", "accelerated_video_decode", "panel_fitting", // "force_compositing_mode", and "all". // This field is mandatory. -// 21. "description" has the description of the entry. -// 22. "webkit_bugs" is an array of associated webkit bug numbers. -// 23. "cr_bugs" is an array of associated webkit bug numbers. -// 24. "browser_version" is a VERSION structure (defined below). If this +// 22. "description" has the description of the entry. +// 23. "webkit_bugs" is an array of associated webkit bug numbers. +// 24. "cr_bugs" is an array of associated webkit bug numbers. +// 25. "browser_version" is a VERSION structure (defined below). If this // condition is not satisfied, the entry will be ignored. If it is not // present, then the entry applies to all versions of the browser. -// 25. "disabled" is a boolean. If it is present, the entry will be skipped. +// 26. "disabled" is a boolean. If it is present, the entry will be skipped. // This can not be used in exceptions. // // VERSION includes "op", "style", "number", and "number2". "op" can be any of @@ -88,7 +89,7 @@ const char kSoftwareRenderingListJson[] = LONG_STRING_CONST( { "name": "software rendering list", // Please update the version number whenever you change this file. - "version": "6.4", + "version": "6.5", "entries": [ { "id": 1, @@ -1139,6 +1140,26 @@ const char kSoftwareRenderingListJson[] = LONG_STRING_CONST( "features": [ "texture_sharing" ] + }, +) // String split to avoid MSVC char limit. +LONG_STRING_CONST( + { + "id": 76, + "description": "WebGL is disabled on Android unless GPU reset notification is supported", + "os": { + "type": "android" + }, + "exceptions": [ + { + "gl_reset_notification_strategy": { + "op": "=", + "value": "33362" + } + } + ], + "features": [ + "webgl" + ] } ] } diff --git a/gpu/demos/compressed_textures/compressed_textures.cc b/gpu/demos/compressed_textures/compressed_textures.cc index 4c32bd2ac7..d2b1ec8192 100644 --- a/gpu/demos/compressed_textures/compressed_textures.cc +++ b/gpu/demos/compressed_textures/compressed_textures.cc @@ -23,10 +23,7 @@ int g_numTextures = 1; GLuint g_textures[5]; int g_textureLoc = -1; GLuint g_programObject = 0; -GLuint g_worldMatrixLoc = 0; GLuint g_vbo = 0; -GLsizei g_texCoordOffset = 0; -int g_angle = 0; void CheckGLError(const char* func_name, int line_no) { #ifndef NDEBUG @@ -65,15 +62,12 @@ GLuint LoadShader(GLenum type, const char* shaderSrc) { void InitShaders() { static const char* vShaderStr = - "uniform mat4 worldMatrix;\n" - "attribute vec3 g_Position;\n" - "attribute vec2 g_TexCoord0;\n" + "attribute vec2 g_Position;\n" "varying vec2 texCoord;\n" "void main()\n" "{\n" - " gl_Position = worldMatrix *\n" - " vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n" - " texCoord = g_TexCoord0;\n" + " gl_Position = vec4(g_Position.x, g_Position.y, 0.0, 1.0);\n" + " texCoord = g_Position * vec2(0.5) + vec2(0.5);\n" "}\n"; static const char* fShaderStr = "precision mediump float;" @@ -96,9 +90,7 @@ void InitShaders() { glAttachShader(programObject, vertexShader); glAttachShader(programObject, fragmentShader); // Bind g_Position to attribute 0 - // Bind g_TexCoord0 to attribute 1 glBindAttribLocation(programObject, 0, "g_Position"); - glBindAttribLocation(programObject, 1, "g_TexCoord0"); // Link the program glLinkProgram(programObject); // Check the link status @@ -114,34 +106,21 @@ void InitShaders() { return; } g_programObject = programObject; - g_worldMatrixLoc = glGetUniformLocation(g_programObject, "worldMatrix"); g_textureLoc = glGetUniformLocation(g_programObject, "tex"); glGenBuffers(1, &g_vbo); glBindBuffer(GL_ARRAY_BUFFER, g_vbo); static float vertices[] = { - 0.25, 0.75, 0.0, - -0.75, 0.75, 0.0, - -0.75, -0.25, 0.0, - 0.25, 0.75, 0.0, - -0.75, -0.25, 0.0, - 0.25, -0.25, 0.0, + 1.0f, 1.0f, + -1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, -1.0f }; - static float texCoords[] = { - 1.0, 1.0, - 0.0, 1.0, - 0.0, 0.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, - }; - g_texCoordOffset = sizeof(vertices); glBufferData(GL_ARRAY_BUFFER, - sizeof(vertices) + sizeof(texCoords), - NULL, + sizeof(vertices), + vertices, GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); - glBufferSubData(GL_ARRAY_BUFFER, g_texCoordOffset, - sizeof(texCoords), texCoords); CheckGLError("InitShaders", __LINE__); } @@ -334,35 +313,7 @@ static int stInit(ESContext *esContext) { } static void stDraw (ESContext *esContext) { - const float kPi = 3.1415926535897932384626433832795f; - CheckGLError("GLFromCPPDraw", __LINE__); - // TODO(kbr): base the angle on time rather than on ticks - g_angle = (g_angle + 1) % 360; - // Rotate about the Z axis - GLfloat rot_matrix[16]; - GLfloat cos_angle = cosf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); - GLfloat sin_angle = sinf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); - // OpenGL matrices are column-major - rot_matrix[0] = cos_angle; - rot_matrix[1] = sin_angle; - rot_matrix[2] = 0.0f; - rot_matrix[3] = 0.0f; - - rot_matrix[4] = -sin_angle; - rot_matrix[5] = cos_angle; - rot_matrix[6] = 0.0f; - rot_matrix[7] = 0.0f; - - rot_matrix[8] = 0.0f; - rot_matrix[9] = 0.0f; - rot_matrix[10] = 1.0f; - rot_matrix[11] = 0.0f; - - rot_matrix[12] = 0.0f; - rot_matrix[13] = 0.0f; - rot_matrix[14] = 0.0f; - rot_matrix[15] = 1.0f; g_frameCount++; if (g_frameCount > 60) @@ -371,7 +322,7 @@ static void stDraw (ESContext *esContext) { g_textureIndex = (g_textureIndex + 1) % g_numTextures; } - // Note: the viewport is automatically set up to cover the entire Canvas. + glViewport(0, 0, esContext->width, esContext->height); // Clear the color buffer glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); @@ -380,16 +331,11 @@ static void stDraw (ESContext *esContext) { // Use the program object glUseProgram(g_programObject); CheckGLError("GLFromCPPDraw", __LINE__); - // Set up the model matrix - glUniformMatrix4fv(g_worldMatrixLoc, 1, GL_FALSE, rot_matrix); // Load the vertex data glBindBuffer(GL_ARRAY_BUFFER, g_vbo); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, - reinterpret_cast<const void*>(g_texCoordOffset)); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); CheckGLError("GLFromCPPDraw", __LINE__); // Bind the texture to texture unit 0 glBindTexture(GL_TEXTURE_2D, g_textures[g_textureIndex]); diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 3974604965..265b5c9061 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -132,7 +132,6 @@ bool Window::CreateRenderContext(gfx::AcceleratedWidget hwnd) { gles2_cmd_helper_.get(), NULL, transfer_buffer_.get(), - false, true, NULL)); diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 3b612a0be3..316aa91442 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -199,7 +199,6 @@ 'command_buffer/service/program_manager_unittest.cc', 'command_buffer/service/query_manager_unittest.cc', 'command_buffer/service/renderbuffer_manager_unittest.cc', - 'command_buffer/service/program_cache_lru_helper_unittest.cc', 'command_buffer/service/program_cache_unittest.cc', 'command_buffer/service/shader_manager_unittest.cc', 'command_buffer/service/shader_translator_unittest.cc', @@ -271,10 +270,7 @@ ], 'sources': [ '<@(gles2_c_lib_source_files)', - 'command_buffer/client/gpu_memory_buffer_mock.cc', - 'command_buffer/client/gpu_memory_buffer_mock.h', - 'command_buffer/client/image_factory_mock.cc', - 'command_buffer/client/image_factory_mock.h', + 'command_buffer/tests/compressed_texture_test.cc', 'command_buffer/tests/gl_bind_uniform_location_unittest.cc', 'command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc', 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 026e5e66ac..da2be68476 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -36,7 +36,6 @@ 'command_buffer/client/gles2_trace_implementation.cc', 'command_buffer/client/gles2_trace_implementation.h', 'command_buffer/client/gles2_trace_implementation_impl_autogen.h', - 'command_buffer/client/gpu_memory_buffer.h', 'command_buffer/client/gpu_memory_buffer_factory.h', 'command_buffer/client/gpu_memory_buffer_tracker.cc', 'command_buffer/client/gpu_memory_buffer_tracker.h', diff --git a/gpu/gpu_untrusted.gyp b/gpu/gpu_untrusted.gyp index a6e502fde6..a1f755cc89 100644 --- a/gpu/gpu_untrusted.gyp +++ b/gpu/gpu_untrusted.gyp @@ -23,6 +23,7 @@ 'nlib_target': 'libgles2_implementation_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'defines': [ 'GLES2_IMPL_IMPLEMENTATION', @@ -46,6 +47,7 @@ 'nlib_target': 'libcommand_buffer_common_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'includes': [ 'command_buffer_common.gypi', @@ -64,6 +66,7 @@ 'nlib_target': 'libgles2_cmd_helper_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'includes': [ 'gles2_cmd_helper.gypi', @@ -82,6 +85,7 @@ 'nlib_target': 'libcommand_buffer_client_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'includes': [ 'command_buffer_client.gypi', @@ -100,6 +104,7 @@ 'nlib_target': 'libgpu_ipc_untrusted.a', 'build_glibc': 0, 'build_newlib': 1, + 'build_irt': 1, }, 'includes': [ 'gpu_ipc.gypi', |