diff options
author | Ben Murdoch <benm@google.com> | 2013-08-08 10:24:53 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2013-08-08 10:24:53 +0100 |
commit | bb1529ce867d8845a77ec7cdf3e3003ef1771a40 (patch) | |
tree | f78d0de03cc8aed1a934d921636a0beb8d164378 /gpu | |
parent | c95505573d864f17cabf515e32f5b8e0831ae237 (diff) | |
download | chromium_org-bb1529ce867d8845a77ec7cdf3e3003ef1771a40.tar.gz |
Merge from Chromium at DEPS revision r216370
This commit was generated by merge_to_master.py.
Change-Id: I739228187a6f1df6c28c5761160e593a49891113
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/client/gl_in_process_context.cc | 164 | ||||
-rw-r--r-- | gpu/command_buffer/client/gl_in_process_context.h | 47 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 21 | ||||
-rw-r--r-- | gpu/command_buffer/service/in_process_command_buffer.cc | 55 | ||||
-rw-r--r-- | gpu/command_buffer/service/in_process_command_buffer.h | 16 | ||||
-rw-r--r-- | gpu/command_buffer/service/memory_program_cache.cc | 24 | ||||
-rw-r--r-- | gpu/command_buffer/service/memory_program_cache_unittest.cc | 40 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache.cc | 62 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache.h | 33 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache_unittest.cc | 101 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_manager.cc | 62 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_manager.h | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_manager_unittest.cc | 171 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager.cc | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager.h | 46 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_manager_unittest.cc | 40 |
16 files changed, 264 insertions, 634 deletions
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc index 97f1715148..cdbfc9f47c 100644 --- a/gpu/command_buffer/client/gl_in_process_context.cc +++ b/gpu/command_buffer/client/gl_in_process_context.cc @@ -53,16 +53,17 @@ class GLInProcessContextImpl explicit GLInProcessContextImpl(); virtual ~GLInProcessContextImpl(); - bool Initialize(bool is_offscreen, + bool Initialize(scoped_refptr<gfx::GLSurface> surface, + bool is_offscreen, bool share_resources, gfx::AcceleratedWidget window, const gfx::Size& size, const char* allowed_extensions, - const int32* attrib_list, - gfx::GpuPreference gpu_preference, - const base::Closure& context_lost_callback); + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference); // GLInProcessContext implementation: + virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE; virtual void SignalSyncPoint(unsigned sync_point, const base::Closure& callback) OVERRIDE; virtual void SignalQuery(unsigned query, const base::Closure& callback) @@ -79,7 +80,7 @@ class GLInProcessContextImpl void Destroy(); void PollQueryCallbacks(); void CallQueryCallback(size_t index); - void OnContextLost(const base::Closure& callback); + void OnContextLost(); void OnSignalSyncPoint(const base::Closure& callback); scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; @@ -92,6 +93,7 @@ class GLInProcessContextImpl unsigned int share_group_id_; bool context_lost_; + base::Closure context_lost_callback_; DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); }; @@ -147,9 +149,16 @@ gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { return gles2_implementation_.get(); } -void GLInProcessContextImpl::OnContextLost(const base::Closure& callback) { +void GLInProcessContextImpl::SetContextLostCallback( + const base::Closure& callback) { + context_lost_callback_ = callback; +} + +void GLInProcessContextImpl::OnContextLost() { context_lost_ = true; - callback.Run(); + if (!context_lost_callback_.is_null()) { + context_lost_callback_.Run(); + } } void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) { @@ -159,47 +168,63 @@ void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) { } bool GLInProcessContextImpl::Initialize( + scoped_refptr<gfx::GLSurface> surface, bool is_offscreen, bool share_resources, gfx::AcceleratedWidget window, const gfx::Size& size, const char* allowed_extensions, - const int32* attrib_list, - gfx::GpuPreference gpu_preference, - const base::Closure& context_lost_callback) { + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference) { DCHECK(size.width() >= 0 && size.height() >= 0); - std::vector<int32> attribs; - while (attrib_list) { - int32 attrib = *attrib_list++; - switch (attrib) { - // Known attributes - case ALPHA_SIZE: - case BLUE_SIZE: - case GREEN_SIZE: - case RED_SIZE: - case DEPTH_SIZE: - case STENCIL_SIZE: - case SAMPLES: - case SAMPLE_BUFFERS: - attribs.push_back(attrib); - attribs.push_back(*attrib_list++); - break; - case NONE: - attribs.push_back(attrib); - attrib_list = NULL; - break; - default: - attribs.push_back(NONE); - attrib_list = NULL; - break; - } + const int32 ALPHA_SIZE = 0x3021; + const int32 BLUE_SIZE = 0x3022; + const int32 GREEN_SIZE = 0x3023; + const int32 RED_SIZE = 0x3024; + const int32 DEPTH_SIZE = 0x3025; + const int32 STENCIL_SIZE = 0x3026; + const int32 SAMPLES = 0x3031; + const int32 SAMPLE_BUFFERS = 0x3032; + const int32 NONE = 0x3038; + + std::vector<int32> attrib_vector; + if (attribs.alpha_size >= 0) { + attrib_vector.push_back(ALPHA_SIZE); + attrib_vector.push_back(attribs.alpha_size); + } + if (attribs.blue_size >= 0) { + attrib_vector.push_back(BLUE_SIZE); + attrib_vector.push_back(attribs.blue_size); + } + if (attribs.green_size >= 0) { + attrib_vector.push_back(GREEN_SIZE); + attrib_vector.push_back(attribs.green_size); + } + if (attribs.red_size >= 0) { + attrib_vector.push_back(RED_SIZE); + attrib_vector.push_back(attribs.red_size); + } + if (attribs.depth_size >= 0) { + attrib_vector.push_back(DEPTH_SIZE); + attrib_vector.push_back(attribs.depth_size); + } + if (attribs.stencil_size >= 0) { + attrib_vector.push_back(STENCIL_SIZE); + attrib_vector.push_back(attribs.stencil_size); + } + if (attribs.samples >= 0) { + attrib_vector.push_back(SAMPLES); + attrib_vector.push_back(attribs.samples); + } + if (attribs.sample_buffers >= 0) { + attrib_vector.push_back(SAMPLE_BUFFERS); + attrib_vector.push_back(attribs.sample_buffers); } + attrib_vector.push_back(NONE); base::Closure wrapped_callback = - base::Bind(&GLInProcessContextImpl::OnContextLost, - AsWeakPtr(), - context_lost_callback); + base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr()); command_buffer_.reset(new InProcessCommandBuffer()); scoped_ptr<base::AutoLock> scoped_shared_context_lock; @@ -223,15 +248,16 @@ bool GLInProcessContextImpl::Initialize( if (!share_group && !++share_group_id_) ++share_group_id_; } - if (!command_buffer_->Initialize(is_offscreen, - share_resources, - window, - size, - allowed_extensions, - attribs, - gpu_preference, - wrapped_callback, - share_group_id_)) { + if (!command_buffer_->Initialize(surface, + is_offscreen, + share_resources, + window, + size, + allowed_extensions, + attrib_vector, + gpu_preference, + wrapped_callback, + share_group_id_)) { LOG(INFO) << "Failed to initialize InProcessCommmandBuffer"; return false; } @@ -337,6 +363,16 @@ void GLInProcessContextImpl::SignalQuery( } // anonymous namespace +GLInProcessContextAttribs::GLInProcessContextAttribs() + : alpha_size(-1), + blue_size(-1), + green_size(-1), + red_size(-1), + depth_size(-1), + stencil_size(-1), + samples(-1), + sample_buffers(-1) {} + // static GLInProcessContext* GLInProcessContext::CreateContext( bool is_offscreen, @@ -344,20 +380,42 @@ GLInProcessContext* GLInProcessContext::CreateContext( const gfx::Size& size, bool share_resources, const char* allowed_extensions, - const int32* attrib_list, - gfx::GpuPreference gpu_preference, - const base::Closure& callback) { + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference) { scoped_ptr<GLInProcessContextImpl> context( new GLInProcessContextImpl()); if (!context->Initialize( + NULL /* surface */, is_offscreen, share_resources, window, size, allowed_extensions, - attrib_list, - gpu_preference, - callback)) + attribs, + gpu_preference)) + return NULL; + + return context.release(); +} + +// static +GLInProcessContext* GLInProcessContext::CreateWithSurface( + scoped_refptr<gfx::GLSurface> surface, + bool share_resources, + const char* allowed_extensions, + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference) { + scoped_ptr<GLInProcessContextImpl> context( + new GLInProcessContextImpl()); + if (!context->Initialize( + surface, + surface->IsOffscreen(), + share_resources, + gfx::kNullAcceleratedWidget, + surface->GetSize(), + allowed_extensions, + attribs, + gpu_preference)) return NULL; return context.release(); diff --git a/gpu/command_buffer/client/gl_in_process_context.h b/gpu/command_buffer/client/gl_in_process_context.h index 2d0754b227..09f8140ee0 100644 --- a/gpu/command_buffer/client/gl_in_process_context.h +++ b/gpu/command_buffer/client/gl_in_process_context.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "gles2_impl_export.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gl/gl_surface.h" #include "ui/gl/gpu_preference.h" namespace gfx { @@ -23,6 +24,20 @@ class GLES2Implementation; class GpuMemoryBufferFactory; +// The default uninitialized value is -1. +struct GLES2_IMPL_EXPORT GLInProcessContextAttribs { + GLInProcessContextAttribs(); + + int32 alpha_size; + int32 blue_size; + int32 green_size; + int32 red_size; + int32 depth_size; + int32 stencil_size; + int32 samples; + int32 sample_buffers; +}; + class GLES2_IMPL_EXPORT GLInProcessContext { public: virtual ~GLInProcessContext() {} @@ -30,20 +45,6 @@ class GLES2_IMPL_EXPORT GLInProcessContext { // Must be called before any GLInProcessContext instances are created. static void SetGpuMemoryBufferFactory(GpuMemoryBufferFactory* factory); - // GLInProcessContext configuration attributes. These are the same as used by - // EGL. Attributes are matched using a closest fit algorithm. - enum Attribute { - ALPHA_SIZE = 0x3021, - BLUE_SIZE = 0x3022, - GREEN_SIZE = 0x3023, - RED_SIZE = 0x3024, - DEPTH_SIZE = 0x3025, - STENCIL_SIZE = 0x3026, - SAMPLES = 0x3031, - SAMPLE_BUFFERS = 0x3032, - NONE = 0x3038 // Attrib list = terminator - }; - // Create a GLInProcessContext, if |is_offscreen| is true, renders to an // offscreen context. |attrib_list| must be NULL or a NONE-terminated list // of attribute/value pairs. @@ -53,9 +54,21 @@ class GLES2_IMPL_EXPORT GLInProcessContext { const gfx::Size& size, bool share_resources, const char* allowed_extensions, - const int32* attrib_list, - gfx::GpuPreference gpu_preference, - const base::Closure& callback); + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference); + + // Create context with the provided GLSurface. All other arguments match + // CreateContext factory above. Can only be called if the command buffer + // service runs on the same thread as this client because GLSurface is not + // thread safe. + static GLInProcessContext* CreateWithSurface( + scoped_refptr<gfx::GLSurface> surface, + bool share_resources, + const char* allowed_extensions, + const GLInProcessContextAttribs& attribs, + gfx::GpuPreference gpu_preference); + + virtual void SetContextLostCallback(const base::Closure& callback) = 0; virtual void SignalSyncPoint(unsigned sync_point, const base::Closure& callback) = 0; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 4f63037c53..a9b1f1e0ec 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1584,8 +1584,6 @@ class GLES2DecoderImpl : public GLES2Decoder { void ProcessPendingReadPixels(); void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); - void ForceCompileShaderIfPending(Shader* shader); - // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -5652,23 +5650,6 @@ void GLES2DecoderImpl::PerformanceWarning( std::string("PERFORMANCE WARNING: ") + msg); } -void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) { - if (shader->compilation_status() == - Shader::PENDING_DEFERRED_COMPILE) { - ShaderTranslator* translator = NULL; - if (use_shader_translator_) { - translator = shader->shader_type() == GL_VERTEX_SHADER ? - vertex_translator_.get() : fragment_translator_.get(); - } - // We know there will be no errors, because we only defer compilation on - // shaders that were previously compiled successfully. - program_manager()->ForceCompileShader(shader->deferred_compilation_source(), - shader, - translator, - feature_info_.get()); - } -} - void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture) { if (texture && texture->IsStreamTexture()) { DCHECK(stream_texture_manager()); @@ -6366,7 +6347,6 @@ void GLES2DecoderImpl::DoGetShaderiv( *params = shader->log_info() ? shader->log_info()->size() + 1 : 0; return; case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: - ForceCompileShaderIfPending(shader); *params = shader->translated_source() ? shader->translated_source()->size() + 1 : 0; return; @@ -6402,7 +6382,6 @@ error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( bucket->SetSize(0); return error::kNoError; } - ForceCompileShaderIfPending(shader); bucket->SetFromString(shader->translated_source() ? shader->translated_source()->c_str() : NULL); diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index 766a7e0fc6..ccbfb32a50 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc @@ -20,6 +20,7 @@ #include "base/logging.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/sequence_checker.h" #include "base/threading/thread.h" #include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/service/command_buffer_service.h" @@ -32,7 +33,6 @@ #include "ui/gl/gl_context.h" #include "ui/gl/gl_image.h" #include "ui/gl/gl_share_group.h" -#include "ui/gl/gl_surface.h" namespace gpu { @@ -244,6 +244,7 @@ InProcessCommandBuffer::~InProcessCommandBuffer() { } bool InProcessCommandBuffer::IsContextLost() { + CheckSequencedThread(); if (context_lost_ || !command_buffer_) { return true; } @@ -252,11 +253,13 @@ bool InProcessCommandBuffer::IsContextLost() { } void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { + CheckSequencedThread(); DCHECK(!surface_->IsOffscreen()); surface_->Resize(size); } bool InProcessCommandBuffer::MakeCurrent() { + CheckSequencedThread(); command_buffer_lock_.AssertAcquired(); if (!context_lost_ && decoder_->MakeCurrent()) @@ -268,6 +271,7 @@ bool InProcessCommandBuffer::MakeCurrent() { } void InProcessCommandBuffer::PumpCommands() { + CheckSequencedThread(); command_buffer_lock_.AssertAcquired(); if (!MakeCurrent()) @@ -277,12 +281,14 @@ void InProcessCommandBuffer::PumpCommands() { } bool InProcessCommandBuffer::GetBufferChanged(int32 transfer_buffer_id) { + CheckSequencedThread(); command_buffer_lock_.AssertAcquired(); command_buffer_->SetGetBuffer(transfer_buffer_id); return true; } bool InProcessCommandBuffer::Initialize( + scoped_refptr<gfx::GLSurface> surface, bool is_offscreen, bool share_resources, gfx::AcceleratedWidget window, @@ -297,8 +303,13 @@ bool InProcessCommandBuffer::Initialize( context_lost_callback_ = WrapCallback(context_lost_callback); share_group_id_ = share_group_id; - base::WaitableEvent completion(true, false); - bool result = false; + if (surface) { + // GPU thread must be the same as client thread due to GLSurface not being + // thread safe. + sequence_checker_.reset(new base::SequenceChecker); + surface_ = surface; + } + base::Callback<bool(void)> init_task = base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, base::Unretained(this), @@ -308,6 +319,9 @@ bool InProcessCommandBuffer::Initialize( allowed_extensions, attribs, gpu_preference); + + base::WaitableEvent completion(true, false); + bool result = false; QueueTask( base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); completion.Wait(); @@ -321,6 +335,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( const char* allowed_extensions, const std::vector<int32>& attribs, gfx::GpuPreference gpu_preference) { + CheckSequencedThread(); // Use one share group for all contexts. CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, (new gfx::GLShareGroup)); @@ -377,10 +392,12 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( decoder_->set_engine(gpu_scheduler_.get()); - if (is_offscreen) - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); - else - surface_ = gfx::GLSurface::CreateViewGLSurface(window); + if (!surface_) { + if (is_offscreen) + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); + else + surface_ = gfx::GLSurface::CreateViewGLSurface(window); + } if (!surface_.get()) { LOG(ERROR) << "Could not create GLSurface."; @@ -448,6 +465,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( } void InProcessCommandBuffer::Destroy() { + CheckSequencedThread(); base::WaitableEvent completion(true, false); bool result = false; base::Callback<bool(void)> destroy_task = base::Bind( @@ -458,6 +476,7 @@ void InProcessCommandBuffer::Destroy() { } bool InProcessCommandBuffer::DestroyOnGpuThread() { + CheckSequencedThread(); command_buffer_.reset(); // Clean up GL resources if possible. bool have_context = context_ && context_->MakeCurrent(surface_); @@ -472,9 +491,15 @@ bool InProcessCommandBuffer::DestroyOnGpuThread() { return true; } +void InProcessCommandBuffer::CheckSequencedThread() { + DCHECK(!sequence_checker_ || + sequence_checker_->CalledOnValidSequencedThread()); +} + unsigned int InProcessCommandBuffer::CreateImageForGpuMemoryBuffer( gfx::GpuMemoryBufferHandle buffer, gfx::Size size) { + CheckSequencedThread(); unsigned int image_id; { // TODO: ID allocation should go through CommandBuffer @@ -494,12 +519,14 @@ void InProcessCommandBuffer::CreateImageOnGpuThread( gfx::GpuMemoryBufferHandle buffer, gfx::Size size, unsigned int image_id) { + CheckSequencedThread(); scoped_refptr<gfx::GLImage> gl_image = gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer, size); decoder_->GetContextGroup()->image_manager()->AddImage(gl_image, image_id); } void InProcessCommandBuffer::RemoveImage(unsigned int image_id) { + CheckSequencedThread(); { // TODO: ID allocation should go through CommandBuffer base::AutoLock lock(command_buffer_lock_); @@ -514,10 +541,12 @@ void InProcessCommandBuffer::RemoveImage(unsigned int image_id) { } void InProcessCommandBuffer::RemoveImageOnGpuThread(unsigned int image_id) { + CheckSequencedThread(); decoder_->GetContextGroup()->image_manager()->RemoveImage(image_id); } void InProcessCommandBuffer::OnContextLost() { + CheckSequencedThread(); if (!context_lost_callback_.is_null()) { context_lost_callback_.Run(); context_lost_callback_.Reset(); @@ -535,6 +564,7 @@ void InProcessCommandBuffer::OnContextLost() { } CommandBuffer::State InProcessCommandBuffer::GetStateFast() { + CheckSequencedThread(); base::AutoLock lock(state_after_last_flush_lock_); if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U) last_state_ = state_after_last_flush_; @@ -542,19 +572,23 @@ CommandBuffer::State InProcessCommandBuffer::GetStateFast() { } CommandBuffer::State InProcessCommandBuffer::GetState() { + CheckSequencedThread(); return GetStateFast(); } CommandBuffer::State InProcessCommandBuffer::GetLastState() { + CheckSequencedThread(); return last_state_; } int32 InProcessCommandBuffer::GetLastToken() { + CheckSequencedThread(); GetStateFast(); return last_state_.token; } void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) { + CheckSequencedThread(); ScopedEvent handle_flush(&flush_event_); base::AutoLock lock(command_buffer_lock_); command_buffer_->Flush(put_offset); @@ -568,6 +602,7 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) { } void InProcessCommandBuffer::Flush(int32 put_offset) { + CheckSequencedThread(); if (last_state_.error != gpu::error::kNoError) return; @@ -583,6 +618,7 @@ void InProcessCommandBuffer::Flush(int32 put_offset) { CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset, int32 last_known_get) { + CheckSequencedThread(); if (put_offset == last_known_get || last_state_.error != gpu::error::kNoError) return last_state_; @@ -598,6 +634,7 @@ CommandBuffer::State InProcessCommandBuffer::FlushSync(int32 put_offset, } void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) { + CheckSequencedThread(); if (last_state_.error != gpu::error::kNoError) return; @@ -614,11 +651,13 @@ void InProcessCommandBuffer::SetGetBuffer(int32 shm_id) { gpu::Buffer InProcessCommandBuffer::CreateTransferBuffer(size_t size, int32* id) { + CheckSequencedThread(); base::AutoLock lock(command_buffer_lock_); return command_buffer_->CreateTransferBuffer(size, id); } void InProcessCommandBuffer::DestroyTransferBuffer(int32 id) { + CheckSequencedThread(); base::Closure task = base::Bind(&CommandBuffer::DestroyTransferBuffer, base::Unretained(command_buffer_.get()), id); @@ -637,10 +676,12 @@ uint32 InProcessCommandBuffer::InsertSyncPoint() { } void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, const base::Closure& callback) { + CheckSequencedThread(); QueueTask(WrapCallback(callback)); } gpu::error::Error InProcessCommandBuffer::GetLastError() { + CheckSequencedThread(); return last_state_.error; } diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index d2e103a890..9bdbd49616 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h @@ -17,8 +17,13 @@ #include "gpu/gpu_export.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gl/gl_surface.h" #include "ui/gl/gpu_preference.h" +namespace base { +class SequenceChecker; +} + namespace gfx { class GLContext; class GLImage; @@ -57,7 +62,11 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer { static void EnableVirtualizedContext(); - bool Initialize(bool is_offscreen, + // If |surface| is not NULL, use it directly; in this case, the command + // buffer gpu thread must be the same as the client thread. Otherwise create + // a new GLSurface. + bool Initialize(scoped_refptr<gfx::GLSurface> surface, + bool is_offscreen, bool share_resources, gfx::AcceleratedWidget window, const gfx::Size& size, @@ -118,6 +127,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer { base::Closure WrapCallback(const base::Closure& callback); State GetStateFast(); void QueueTask(const base::Closure& task) { queue_->QueueTask(task); } + void CheckSequencedThread(); // Callbacks: void OnContextLost(); @@ -149,6 +159,10 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer { State state_after_last_flush_; base::Lock state_after_last_flush_lock_; + // Only used with explicit scheduling and the gpu thread is the same as + // the client thread. + scoped_ptr<base::SequenceChecker> sequence_checker_; + DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer); }; diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc index 3207f7c807..e09d132f6a 100644 --- a/gpu/command_buffer/service/memory_program_cache.cc +++ b/gpu/command_buffer/service/memory_program_cache.cc @@ -117,10 +117,12 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( const ShaderCacheCallback& shader_callback) { char a_sha[kHashLength]; char b_sha[kHashLength]; + DCHECK(shader_a && shader_a->signature_source() && + shader_b && shader_b->signature_source()); ComputeShaderHash( - *shader_a->deferred_compilation_source(), translator_a, a_sha); + *shader_a->signature_source(), translator_a, a_sha); ComputeShaderHash( - *shader_b->deferred_compilation_source(), translator_b, b_sha); + *shader_b->signature_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -189,10 +191,12 @@ void MemoryProgramCache::SaveLinkedProgram( char a_sha[kHashLength]; char b_sha[kHashLength]; + DCHECK(shader_a && shader_a->signature_source() && + shader_b && shader_b->signature_source()); ComputeShaderHash( - *shader_a->deferred_compilation_source(), translator_a, a_sha); + *shader_a->signature_source(), translator_a, a_sha); ComputeShaderHash( - *shader_b->deferred_compilation_source(), translator_b, b_sha); + *shader_b->signature_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -243,7 +247,7 @@ void MemoryProgramCache::SaveLinkedProgram( this)); UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", - curr_size_bytes_ / 1024); + curr_size_bytes_ / 1024); } void MemoryProgramCache::LoadProgram(const std::string& program) { @@ -289,10 +293,6 @@ void MemoryProgramCache::LoadProgram(const std::string& program) { fragment_uniforms, this)); - ShaderCompilationSucceededSha(proto->sha()); - ShaderCompilationSucceededSha(proto->vertex_shader().sha()); - ShaderCompilationSucceededSha(proto->fragment_shader().sha()); - UMA_HISTOGRAM_COUNTS("GPU.ProgramCache.MemorySizeAfterKb", curr_size_bytes_ / 1024); } else { @@ -324,14 +324,12 @@ MemoryProgramCache::ProgramCacheValue::ProgramCacheValue( 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_); + program_cache_->LinkedProgramCacheSuccess(program_hash); } MemoryProgramCache::ProgramCacheValue::~ProgramCacheValue() { program_cache_->curr_size_bytes_ -= length_; - program_cache_->Evict(program_hash_, shader_0_hash_, shader_1_hash_); + program_cache_->Evict(program_hash_); } } // namespace gles2 diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc index 603c21e58a..83fc12a386 100644 --- a/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc @@ -124,8 +124,6 @@ class MemoryProgramCacheTest : public testing::Test { vertex_shader_->UpdateSource("bbbalsldkdkdkd"); fragment_shader_->UpdateSource("bbbal sldkdkdkas 134 ad"); - vertex_shader_->FlagSourceAsCompiled(true); - fragment_shader_->FlagSourceAsCompiled(true); vertex_shader_->SetStatus(true, NULL, NULL); fragment_shader_->SetStatus(true, NULL, NULL); @@ -202,9 +200,9 @@ TEST_F(MemoryProgramCacheTest, CacheSave) { base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); @@ -227,9 +225,9 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) { base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); @@ -238,9 +236,9 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) { cache_->LoadProgram(shader_cache_shader()); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); } @@ -391,9 +389,9 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { base::Unretained(this))); const std::string vertex_orig_source = - *vertex_shader_->deferred_compilation_source(); + *vertex_shader_->signature_source(); vertex_shader_->UpdateSource("different!"); - vertex_shader_->FlagSourceAsCompiled(true); + vertex_shader_->SetStatus(true, NULL, NULL); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, @@ -405,9 +403,9 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { base::Unretained(this)))); vertex_shader_->UpdateSource(vertex_orig_source.c_str()); - vertex_shader_->FlagSourceAsCompiled(true); + vertex_shader_->SetStatus(true, NULL, NULL); fragment_shader_->UpdateSource("different!"); - fragment_shader_->FlagSourceAsCompiled(true); + fragment_shader_->SetStatus(true, NULL, NULL); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, @@ -485,9 +483,9 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { // save old source and modify for new program const std::string old_source = - *fragment_shader_->deferred_compilation_source(); + *fragment_shader_->signature_source(); fragment_shader_->UpdateSource("al sdfkjdk"); - fragment_shader_->FlagSourceAsCompiled(true); + fragment_shader_->SetStatus(true, NULL, NULL); scoped_ptr<char[]> bigTestBinary = scoped_ptr<char[]>(new char[kEvictingBinaryLength]); @@ -509,15 +507,15 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( old_source, NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); } @@ -540,9 +538,9 @@ TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) { base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); } @@ -564,9 +562,9 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( - *vertex_shader_->deferred_compilation_source(), + *vertex_shader_->signature_source(), NULL, - *fragment_shader_->deferred_compilation_source(), + *fragment_shader_->signature_source(), NULL, NULL)); diff --git a/gpu/command_buffer/service/program_cache.cc b/gpu/command_buffer/service/program_cache.cc index f0adf6e504..6599d4ad3d 100644 --- a/gpu/command_buffer/service/program_cache.cc +++ b/gpu/command_buffer/service/program_cache.cc @@ -16,45 +16,9 @@ ProgramCache::~ProgramCache() {} void ProgramCache::Clear() { ClearBackend(); - shader_status_.clear(); link_status_.clear(); } -ProgramCache::CompiledShaderStatus ProgramCache::GetShaderCompilationStatus( - const std::string& shader_src, - const ShaderTranslatorInterface* translator) const { - char sha[kHashLength]; - ComputeShaderHash(shader_src, translator, sha); - const std::string sha_string(sha, kHashLength); - - CompileStatusMap::const_iterator found = shader_status_.find(sha_string); - - if (found == shader_status_.end()) { - return ProgramCache::COMPILATION_UNKNOWN; - } else { - return found->second.status; - } -} - -void ProgramCache::ShaderCompilationSucceeded( - const std::string& shader_src, - const ShaderTranslatorInterface* translator) { - char sha[kHashLength]; - ComputeShaderHash(shader_src, translator, sha); - const std::string sha_string(sha, kHashLength); - ShaderCompilationSucceededSha(sha_string); -} - -void ProgramCache::ShaderCompilationSucceededSha( - const std::string& sha_string) { - CompileStatusMap::iterator it = shader_status_.find(sha_string); - if (it == shader_status_.end()) { - shader_status_[sha_string] = CompiledShaderInfo(COMPILATION_SUCCEEDED); - } else { - it->second.status = COMPILATION_SUCCEEDED; - } -} - ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus( const std::string& untranslated_a, const ShaderTranslatorInterface* translator_a, @@ -98,17 +62,11 @@ void ProgramCache::LinkedProgramCacheSuccess( sha); const std::string sha_string(sha, kHashLength); - LinkedProgramCacheSuccess(sha_string, - std::string(a_sha, kHashLength), - std::string(b_sha, kHashLength)); + LinkedProgramCacheSuccess(sha_string); } -void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash, - const std::string& shader_a_hash, - const std::string& shader_b_hash) { +void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash) { link_status_[program_hash] = LINK_SUCCEEDED; - shader_status_[shader_a_hash].ref_count++; - shader_status_[shader_b_hash].ref_count++; } void ProgramCache::ComputeShaderHash( @@ -122,21 +80,7 @@ void ProgramCache::ComputeShaderHash( s.length(), reinterpret_cast<unsigned char*>(result)); } -void ProgramCache::Evict(const std::string& program_hash, - const std::string& shader_0_hash, - const std::string& shader_1_hash) { - CompileStatusMap::iterator info0 = shader_status_.find(shader_0_hash); - CompileStatusMap::iterator info1 = shader_status_.find(shader_1_hash); - DCHECK(info0 != shader_status_.end()); - DCHECK(info1 != shader_status_.end()); - DCHECK(info0->second.ref_count > 0); - DCHECK(info1->second.ref_count > 0); - if (--info0->second.ref_count <= 0) { - shader_status_.erase(shader_0_hash); - } - if (--info1->second.ref_count <= 0) { - shader_status_.erase(shader_1_hash); - } +void ProgramCache::Evict(const std::string& program_hash) { link_status_.erase(program_hash); } diff --git a/gpu/command_buffer/service/program_cache.h b/gpu/command_buffer/service/program_cache.h index a8b9f913b3..3fb5687e8b 100644 --- a/gpu/command_buffer/service/program_cache.h +++ b/gpu/command_buffer/service/program_cache.h @@ -27,11 +27,6 @@ class GPU_EXPORT ProgramCache { typedef std::map<std::string, GLint> LocationMap; - enum CompiledShaderStatus { - COMPILATION_UNKNOWN, - COMPILATION_SUCCEEDED - }; - enum LinkedProgramStatus { LINK_UNKNOWN, LINK_SUCCEEDED @@ -45,13 +40,6 @@ class GPU_EXPORT ProgramCache { ProgramCache(); virtual ~ProgramCache(); - CompiledShaderStatus GetShaderCompilationStatus( - const std::string& shader_src, - const ShaderTranslatorInterface* translator) const; - void ShaderCompilationSucceeded(const std::string& shader_src, - const ShaderTranslatorInterface* translator); - void ShaderCompilationSucceededSha(const std::string& sha_string); - LinkedProgramStatus GetLinkedProgramStatus( const std::string& untranslated_shader_a, const ShaderTranslatorInterface* translator_a, @@ -95,9 +83,7 @@ class GPU_EXPORT ProgramCache { protected: // called by implementing class after a shader was successfully cached - void LinkedProgramCacheSuccess(const std::string& program_hash, - const std::string& shader_a_hash, - const std::string& shader_b_hash); + void LinkedProgramCacheSuccess(const std::string& program_hash); // result is not null terminated void ComputeShaderHash(const std::string& shader, @@ -112,30 +98,15 @@ class GPU_EXPORT ProgramCache { const LocationMap* bind_attrib_location_map, char* result) const; - void Evict(const std::string& program_hash, - const std::string& shader_0_hash, - const std::string& shader_1_hash); + void Evict(const std::string& program_hash); private: - struct CompiledShaderInfo { - CompiledShaderInfo() : status(COMPILATION_UNKNOWN), ref_count(0) { } - explicit CompiledShaderInfo(CompiledShaderStatus status_) - : status(status_), - ref_count(0) { } - - CompiledShaderStatus status; - size_t ref_count; - }; - - typedef base::hash_map<std::string, - CompiledShaderInfo> CompileStatusMap; typedef base::hash_map<std::string, LinkedProgramStatus> LinkStatusMap; // called to clear the backend cache virtual void ClearBackend() = 0; - CompileStatusMap shader_status_; LinkStatusMap link_status_; DISALLOW_COPY_AND_ASSIGN(ProgramCache); diff --git a/gpu/command_buffer/service/program_cache_unittest.cc b/gpu/command_buffer/service/program_cache_unittest.cc index 9ff6da95c2..4e2abc317d 100644 --- a/gpu/command_buffer/service/program_cache_unittest.cc +++ b/gpu/command_buffer/service/program_cache_unittest.cc @@ -55,9 +55,7 @@ class NoBackendProgramCache : public ProgramCache { sha); const std::string shaString(sha, kHashLength); - LinkedProgramCacheSuccess(shaString, - std::string(a_sha, kHashLength), - std::string(b_sha, kHashLength)); + LinkedProgramCacheSuccess(shaString); } void ComputeShaderHash(const std::string& shader, @@ -76,10 +74,8 @@ class NoBackendProgramCache : public ProgramCache { result); } - void Evict(const std::string& program_hash, - const std::string& shader_0_hash, - const std::string& shader_1_hash) { - ProgramCache::Evict(program_hash, shader_0_hash, shader_1_hash); + void Evict(const std::string& program_hash) { + ProgramCache::Evict(program_hash); } }; @@ -92,54 +88,6 @@ class ProgramCacheTest : public testing::Test { scoped_ptr<NoBackendProgramCache> cache_; }; -TEST_F(ProgramCacheTest, CompilationStatusSave) { - const std::string shader1 = "abcd1234"; - { - std::string shader = shader1; - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader, NULL)); - cache_->ShaderCompilationSucceeded(shader, NULL); - shader.clear(); - } - // make sure it was copied - EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader1, NULL)); -} - -TEST_F(ProgramCacheTest, CompilationStatusTranslatorOptionDependent) { - MockShaderTranslator translator; - - EXPECT_CALL(translator, GetStringForOptionsThatWouldEffectCompilation()) - .WillOnce(Return("foo")) // GetShaderCompilationStatus - .WillOnce(Return("foo")) // ShaderCompilationSucceeded - .WillOnce(Return("foo")) // GetShaderCompilationStatus - .WillOnce(Return("bar")); // GetShaderCompilationStatus - - const std::string shader1 = "abcd1234"; - { - std::string shader = shader1; - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader, &translator)); - cache_->ShaderCompilationSucceeded(shader, &translator); - shader.clear(); - } - // make sure it was copied - EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader1, &translator)); - // make sure if the options change it's not copied. - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1, &translator)); -} - -TEST_F(ProgramCacheTest, CompilationUnknownOnSourceChange) { - std::string shader1 = "abcd1234"; - cache_->ShaderCompilationSucceeded(shader1, NULL); - - shader1 = "different!"; - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1, NULL)); -} - TEST_F(ProgramCacheTest, LinkStatusSave) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; @@ -183,8 +131,6 @@ TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) { TEST_F(ProgramCacheTest, StatusEviction) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->ShaderCompilationSucceeded(shader1, NULL); - cache_->ShaderCompilationSucceeded(shader2, NULL); cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); char a_sha[ProgramCache::kHashLength]; char b_sha[ProgramCache::kHashLength]; @@ -196,13 +142,7 @@ TEST_F(ProgramCacheTest, StatusEviction) { b_sha, NULL, sha); - cache_->Evict(std::string(sha, ProgramCache::kHashLength), - std::string(a_sha, ProgramCache::kHashLength), - std::string(b_sha, ProgramCache::kHashLength)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2, NULL)); + cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); } @@ -211,11 +151,7 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->ShaderCompilationSucceeded(shader1, NULL); - cache_->ShaderCompilationSucceeded(shader2, NULL); cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); - cache_->ShaderCompilationSucceeded(shader1, NULL); - cache_->ShaderCompilationSucceeded(shader3, NULL); cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); char a_sha[ProgramCache::kHashLength]; @@ -230,15 +166,7 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) { b_sha, NULL, sha); - cache_->Evict(std::string(sha, ProgramCache::kHashLength), - std::string(a_sha, ProgramCache::kHashLength), - std::string(b_sha, ProgramCache::kHashLength)); - EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader1, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader3, NULL)); + cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, @@ -249,15 +177,7 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) { c_sha, NULL, sha); - cache_->Evict(std::string(sha, ProgramCache::kHashLength), - std::string(a_sha, ProgramCache::kHashLength), - std::string(c_sha, ProgramCache::kHashLength)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader3, NULL)); + cache_->Evict(std::string(sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, @@ -268,18 +188,9 @@ TEST_F(ProgramCacheTest, StatusClear) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->ShaderCompilationSucceeded(shader1, NULL); - cache_->ShaderCompilationSucceeded(shader2, NULL); cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); - cache_->ShaderCompilationSucceeded(shader3, NULL); cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); cache_->Clear(); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2, NULL)); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader3, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index d7ced0a96d..8b1eedea35 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc @@ -443,38 +443,9 @@ void Program::ExecuteBindAttribLocationCalls() { void ProgramManager::DoCompileShader(Shader* shader, ShaderTranslator* translator, FeatureInfo* feature_info) { - TimeTicks before = TimeTicks::HighResNow(); - if (program_cache_ && - program_cache_->GetShaderCompilationStatus( - shader->source() ? *shader->source() : std::string(), - translator) == ProgramCache::COMPILATION_SUCCEEDED) { - shader->SetStatus(true, "", translator); - shader->FlagSourceAsCompiled(false); - UMA_HISTOGRAM_CUSTOM_COUNTS( - "GPU.ProgramCache.CompilationCacheHitTime", - (TimeTicks::HighResNow() - before).InMicroseconds(), - 0, - TimeDelta::FromSeconds(1).InMicroseconds(), - 50); - return; - } - ForceCompileShader(shader->source(), shader, translator, feature_info); - UMA_HISTOGRAM_CUSTOM_COUNTS( - "GPU.ProgramCache.CompilationCacheMissTime", - (TimeTicks::HighResNow() - before).InMicroseconds(), - 0, - TimeDelta::FromSeconds(1).InMicroseconds(), - 50); -} - -void ProgramManager::ForceCompileShader(const std::string* source, - Shader* shader, - ShaderTranslator* translator, - FeatureInfo* feature_info) { - shader->FlagSourceAsCompiled(true); - // Translate GL ES 2.0 shader to Desktop GL shader and pass that to // glShaderSource and then glCompileShader. + const std::string* source = shader->source(); const char* shader_src = source ? source->c_str() : ""; if (translator) { if (!translator->Translate(shader_src)) { @@ -506,11 +477,6 @@ void ProgramManager::ForceCompileShader(const std::string* source, glGetShaderiv(shader->service_id(), GL_COMPILE_STATUS, &status); if (status) { shader->SetStatus(true, "", translator); - if (program_cache_) { - const char* untranslated_source = source ? source->c_str() : ""; - program_cache_->ShaderCompilationSucceeded( - untranslated_source, translator); - } } else { // We cannot reach here if we are using the shader translator. // All invalid shaders must be rejected by the translator. @@ -551,10 +517,12 @@ bool Program::Link(ShaderManager* manager, bool link = true; ProgramCache* cache = manager_->program_cache_; if (cache) { + DCHECK(attached_shaders_[0]->signature_source() && + attached_shaders_[1]->signature_source()); ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( - *attached_shaders_[0]->deferred_compilation_source(), + *attached_shaders_[0]->signature_source(), vertex_translator, - *attached_shaders_[1]->deferred_compilation_source(), + *attached_shaders_[1]->signature_source(), fragment_translator, &bind_attrib_location_map_); @@ -570,26 +538,6 @@ bool Program::Link(ShaderManager* manager, link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; UMA_HISTOGRAM_BOOLEAN("GPU.ProgramCache.LoadBinarySuccess", !link); } - - if (link) { - // compile our shaders if they're pending - const int kShaders = Program::kMaxAttachedShaders; - for (int i = 0; i < kShaders; ++i) { - Shader* shader = attached_shaders_[i].get(); - if (shader->compilation_status() == - Shader::PENDING_DEFERRED_COMPILE) { - ShaderTranslator* translator = ShaderIndexToTranslator( - i, - vertex_translator, - fragment_translator); - manager_->ForceCompileShader(shader->deferred_compilation_source(), - attached_shaders_[i].get(), - translator, - feature_info); - DCHECK(shader->IsValid()); - } - } - } } if (link) { diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h index 16dd97d703..dca232bf24 100644 --- a/gpu/command_buffer/service/program_manager.h +++ b/gpu/command_buffer/service/program_manager.h @@ -358,18 +358,10 @@ class GPU_EXPORT ProgramManager { static int32 MakeFakeLocation(int32 index, int32 element); - // Cache-aware shader compiling. If no cache or if the shader wasn't - // previously compiled, ForceCompileShader is called void DoCompileShader(Shader* shader, ShaderTranslator* translator, FeatureInfo* feature_info); - // Actually compiles the shader - void ForceCompileShader(const std::string* source, - Shader* shader, - ShaderTranslator* translator, - FeatureInfo* feature_info); - private: friend class Program; diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc index f7598c8202..90ce0af8ef 100644 --- a/gpu/command_buffer/service/program_manager_unittest.cc +++ b/gpu/command_buffer/service/program_manager_unittest.cc @@ -1192,18 +1192,8 @@ class ProgramManagerWithCacheTest : public testing::Test { } void SetShadersCompiled() { - cache_->ShaderCompilationSucceeded(*vertex_shader_->source(), NULL); - cache_->ShaderCompilationSucceeded(*fragment_shader_->source(), NULL); vertex_shader_->SetStatus(true, NULL, NULL); fragment_shader_->SetStatus(true, NULL, NULL); - vertex_shader_->FlagSourceAsCompiled(true); - fragment_shader_->FlagSourceAsCompiled(true); - } - - void SetShadersNotCompiledButCached() { - SetShadersCompiled(); - vertex_shader_->FlagSourceAsCompiled(false); - fragment_shader_->FlagSourceAsCompiled(false); } void SetProgramCached() { @@ -1363,31 +1353,6 @@ const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId; const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId; #endif -TEST_F(ProgramManagerWithCacheTest, CacheSuccessAfterShaderCompile) { - SetExpectationsForSuccessCompile(vertex_shader_); - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - manager_.DoCompileShader(vertex_shader_, NULL, info.get()); - EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus( - *vertex_shader_->source(), NULL)); -} - -TEST_F(ProgramManagerWithCacheTest, CacheUnknownAfterShaderError) { - SetExpectationsForErrorCompile(vertex_shader_); - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - manager_.DoCompileShader(vertex_shader_, NULL, info.get()); - EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus( - *vertex_shader_->source(), NULL)); -} - -TEST_F(ProgramManagerWithCacheTest, NoCompileWhenShaderCached) { - cache_->ShaderCompilationSucceeded(vertex_shader_->source()->c_str(), NULL); - SetExpectationsForNoCompile(vertex_shader_); - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - manager_.DoCompileShader(vertex_shader_, NULL, info.get()); -} - TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) { SetShadersCompiled(); SetExpectationsForProgramLink(); @@ -1396,21 +1361,8 @@ TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) { base::Bind(&ShaderCacheCb))); } -TEST_F(ProgramManagerWithCacheTest, CompileShaderOnLinkCacheMiss) { - SetShadersCompiled(); - vertex_shader_->FlagSourceAsCompiled(false); - - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - - SetExpectationsForSuccessCompile(vertex_shader_); - SetExpectationsForProgramLink(); - SetExpectationsForProgramCached(); - EXPECT_TRUE(program_->Link(&shader_manager_, NULL, NULL, - info.get(), base::Bind(&ShaderCacheCb))); -} - TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { - SetShadersNotCompiledButCached(); + SetShadersCompiled(); SetProgramCached(); SetExpectationsForNoCompile(vertex_shader_); @@ -1423,126 +1375,5 @@ TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { base::Bind(&ShaderCacheCb))); } -TEST_F(ProgramManagerWithCacheTest, CompileAndLinkOnProgramCacheError) { - SetShadersNotCompiledButCached(); - SetProgramCached(); - - SetExpectationsForSuccessCompile(vertex_shader_); - SetExpectationsForSuccessCompile(fragment_shader_); - SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_FAILURE); - SetExpectationsForProgramLink(); - SetExpectationsForProgramCached(); - - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - EXPECT_TRUE(program_->Link(&shader_manager_, NULL, NULL, info.get(), - base::Bind(&ShaderCacheCb))); -} - -TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeNoCompile) { - SetShadersNotCompiledButCached(); - SetProgramCached(); - - const GLuint kNewShaderClientId = 4; - const GLuint kNewShaderServiceId = 40; - const GLuint kNewProgramClientId = 5; - const GLuint kNewProgramServiceId = 50; - - Shader* new_vertex_shader = - shader_manager_.CreateShader(kNewShaderClientId, - kNewShaderServiceId, - GL_VERTEX_SHADER); - - const std::string original_source = *vertex_shader_->source(); - new_vertex_shader->UpdateSource(original_source.c_str()); - - Program* program = manager_.CreateProgram( - kNewProgramClientId, kNewProgramServiceId); - ASSERT_TRUE(program != NULL); - program->AttachShader(&shader_manager_, new_vertex_shader); - program->AttachShader(&shader_manager_, fragment_shader_); - - SetExpectationsForNoCompile(new_vertex_shader); - - manager_.DoCompileShader(new_vertex_shader, NULL, NULL); - EXPECT_EQ(Shader::PENDING_DEFERRED_COMPILE, - new_vertex_shader->compilation_status()); - - new_vertex_shader->UpdateSource("different!"); - EXPECT_EQ(original_source, - *new_vertex_shader->deferred_compilation_source()); - - EXPECT_EQ(Shader::PENDING_DEFERRED_COMPILE, - new_vertex_shader->compilation_status()); - EXPECT_EQ(Shader::PENDING_DEFERRED_COMPILE, - fragment_shader_->compilation_status()); - - SetExpectationsForNoCompile(fragment_shader_); - SetExpectationsForNotCachingProgram(program, - new_vertex_shader, - fragment_shader_); - SetExpectationsForProgramLoad(kNewProgramServiceId, - program, - new_vertex_shader, - fragment_shader_, - ProgramCache::PROGRAM_LOAD_SUCCESS); - SetExpectationsForProgramLoadSuccess(kNewProgramServiceId); - - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - EXPECT_TRUE(program->Link(&shader_manager_, NULL, NULL, info.get(), - base::Bind(&ShaderCacheCb))); -} - -TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeWithCompile) { - SetShadersNotCompiledButCached(); - SetProgramCached(); - - const GLuint kNewShaderClientId = 4; - const GLuint kNewShaderServiceId = 40; - const GLuint kNewProgramClientId = 5; - const GLuint kNewProgramServiceId = 50; - - Shader* new_vertex_shader = - shader_manager_.CreateShader(kNewShaderClientId, - kNewShaderServiceId, - GL_VERTEX_SHADER); - - new_vertex_shader->UpdateSource(vertex_shader_->source()->c_str()); - - Program* program = manager_.CreateProgram( - kNewProgramClientId, kNewProgramServiceId); - ASSERT_TRUE(program != NULL); - program->AttachShader(&shader_manager_, new_vertex_shader); - program->AttachShader(&shader_manager_, fragment_shader_); - - SetExpectationsForNoCompile(new_vertex_shader); - - manager_.DoCompileShader(new_vertex_shader, NULL, NULL); - - const std::string differentSource = "different!"; - new_vertex_shader->UpdateSource(differentSource.c_str()); - SetExpectationsForSuccessCompile(new_vertex_shader); - - scoped_refptr<FeatureInfo> info(new FeatureInfo()); - manager_.DoCompileShader(new_vertex_shader, NULL, info.get()); - EXPECT_EQ(differentSource, - *new_vertex_shader->deferred_compilation_source()); - - EXPECT_EQ(Shader::COMPILED, - new_vertex_shader->compilation_status()); - EXPECT_EQ(Shader::PENDING_DEFERRED_COMPILE, - fragment_shader_->compilation_status()); - - // so we don't recompile because we were pending originally - SetExpectationsForNoCompile(new_vertex_shader); - SetExpectationsForSuccessCompile(fragment_shader_); - SetExpectationsForProgramCached(program, - new_vertex_shader, - fragment_shader_); - SetExpectationsForProgramLink(kNewProgramServiceId); - - EXPECT_TRUE(program->Link(&shader_manager_, NULL, NULL, - info.get(), base::Bind(&ShaderCacheCb))); -} - } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc index 590b3a2507..a95b04ced0 100644 --- a/gpu/command_buffer/service/shader_manager.cc +++ b/gpu/command_buffer/service/shader_manager.cc @@ -16,8 +16,7 @@ Shader::Shader(GLuint service_id, GLenum shader_type) : use_count_(0), service_id_(service_id), shader_type_(shader_type), - valid_(false), - compilation_status_(NOT_COMPILED) { + valid_(false) { } Shader::~Shader() { @@ -50,6 +49,11 @@ void Shader::SetStatus( uniform_map_.clear(); name_map_.clear(); } + if (valid && source_.get()) { + signature_source_.reset(new std::string(source_->c_str())); + } else { + signature_source_.reset(); + } } const Shader::VariableInfo* diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h index 31d55726f0..bc68868bf2 100644 --- a/gpu/command_buffer/service/shader_manager.h +++ b/gpu/command_buffer/service/shader_manager.h @@ -26,19 +26,7 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { public: typedef ShaderTranslator::VariableInfo VariableInfo; - enum CompilationStatus { - NOT_COMPILED, - // We're pending compilation for a cache hit with the program cache. - PENDING_DEFERRED_COMPILE, - COMPILED - }; - void UpdateSource(const char* source) { - // If the source is flagged as compiled, then store our previous source - // for deferred compile and caching. - if (!deferred_compilation_source_.get()) { - deferred_compilation_source_.reset(source_.release()); - } source_.reset(source ? new std::string(source) : NULL); } @@ -63,31 +51,14 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { return translated_source_.get(); } + const std::string* signature_source() const { + return signature_source_.get(); + } + void SetStatus( bool valid, const char* log, ShaderTranslatorInterface* translator); - CompilationStatus compilation_status() const { - return compilation_status_; - } - - // The source that was used when the user called CompileShader. - // This is used for a deferred compile and in the program cache - const std::string* deferred_compilation_source() const { - return deferred_compilation_source_.get() != NULL ? - deferred_compilation_source_.get() : - source_.get(); - } - - // Resets our deferred compilation source and stores if the source was - // actually compiled, or if we're expecting a cache hit - void FlagSourceAsCompiled(bool actually_compiled) { - compilation_status_ = actually_compiled ? - COMPILED : - PENDING_DEFERRED_COMPILE; - deferred_compilation_source_.reset(); - } - const VariableInfo* GetAttribInfo(const std::string& name) const; const VariableInfo* GetUniformInfo(const std::string& name) const; @@ -165,6 +136,9 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { // The shader source as passed to glShaderSource. scoped_ptr<std::string> source_; + // The source the last compile used. + scoped_ptr<std::string> signature_source_; + // The translated shader source. scoped_ptr<std::string> translated_source_; @@ -177,12 +151,6 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> { // The name hashing info when the shader was last compiled. NameMap name_map_; - - // The current compilation status of the shader - CompilationStatus compilation_status_; - - // Holds on to the source for a deferred compile. - scoped_ptr<std::string> deferred_compilation_source_; }; // Tracks the Shaders. diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc index 0971bf16f2..a225a3cc8c 100644 --- a/gpu/command_buffer/service/shader_manager_unittest.cc +++ b/gpu/command_buffer/service/shader_manager_unittest.cc @@ -248,45 +248,5 @@ TEST_F(ShaderManagerTest, ShaderInfoUseCount) { EXPECT_TRUE(shader2 == NULL); } -TEST_F(ShaderManagerTest, ShaderInfoStoreCompilationStatus) { - const GLuint kClientId = 1; - const GLuint kServiceId = 11; - const GLenum kShaderType = GL_VERTEX_SHADER; - Shader* shader = manager_.CreateShader( - kClientId, kServiceId, kShaderType); - ASSERT_TRUE(shader != NULL); - - EXPECT_EQ(Shader::NOT_COMPILED, - shader->compilation_status()); - shader->UpdateSource("original source"); - EXPECT_EQ(Shader::NOT_COMPILED, - shader->compilation_status()); - shader->FlagSourceAsCompiled(false); - EXPECT_EQ(Shader::PENDING_DEFERRED_COMPILE, - shader->compilation_status()); - shader->FlagSourceAsCompiled(true); - EXPECT_EQ(Shader::COMPILED, - shader->compilation_status()); -} - -TEST_F(ShaderManagerTest, ShaderInfoStoreDeferredSource) { - const GLuint kClientId = 1; - const GLuint kServiceId = 11; - const GLenum kShaderType = GL_VERTEX_SHADER; - Shader* shader = manager_.CreateShader( - kClientId, kServiceId, kShaderType); - ASSERT_TRUE(shader != NULL); - - shader->UpdateSource("original source"); - shader->FlagSourceAsCompiled(false); - - EXPECT_EQ("original source", *shader->deferred_compilation_source()); - shader->UpdateSource("different!"); - EXPECT_EQ("original source", *shader->deferred_compilation_source()); - - shader->FlagSourceAsCompiled(true); - EXPECT_EQ("different!", *shader->deferred_compilation_source()); -} - } // namespace gles2 } // namespace gpu |