summaryrefslogtreecommitdiff
path: root/gpu
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2013-08-08 10:24:53 +0100
committerBen Murdoch <benm@google.com>2013-08-08 10:24:53 +0100
commitbb1529ce867d8845a77ec7cdf3e3003ef1771a40 (patch)
treef78d0de03cc8aed1a934d921636a0beb8d164378 /gpu
parentc95505573d864f17cabf515e32f5b8e0831ae237 (diff)
downloadchromium_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.cc164
-rw-r--r--gpu/command_buffer/client/gl_in_process_context.h47
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc21
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc55
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h16
-rw-r--r--gpu/command_buffer/service/memory_program_cache.cc24
-rw-r--r--gpu/command_buffer/service/memory_program_cache_unittest.cc40
-rw-r--r--gpu/command_buffer/service/program_cache.cc62
-rw-r--r--gpu/command_buffer/service/program_cache.h33
-rw-r--r--gpu/command_buffer/service/program_cache_unittest.cc101
-rw-r--r--gpu/command_buffer/service/program_manager.cc62
-rw-r--r--gpu/command_buffer/service/program_manager.h8
-rw-r--r--gpu/command_buffer/service/program_manager_unittest.cc171
-rw-r--r--gpu/command_buffer/service/shader_manager.cc8
-rw-r--r--gpu/command_buffer/service/shader_manager.h46
-rw-r--r--gpu/command_buffer/service/shader_manager_unittest.cc40
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