diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-27 03:24:50 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-27 03:24:50 +0000 |
commit | 1786d84c72c33d3fcece9622b98c5d584f6b1b31 (patch) | |
tree | ca2ee4a55d69ed76aa9890b244ce7873126b4826 | |
parent | 1400e6dc12c13f62aa300dd4468019a08388daec (diff) | |
download | chromium_src-1786d84c72c33d3fcece9622b98c5d584f6b1b31.zip chromium_src-1786d84c72c33d3fcece9622b98c5d584f6b1b31.tar.gz chromium_src-1786d84c72c33d3fcece9622b98c5d584f6b1b31.tar.bz2 |
Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
Adds signalSyncPoint() support to our command buffer implementations
of WebGraphicsContext3D. Because we have to use a raw callback pointer
for WebGraphicsContext3D and this is not great, I've added a
SyncPointHelper class that adapts a base::Closure() for use with the
signalSyncPoint() method.
Tests:
GLRendererPixelTest.SignalSyncPoint
GLRendererPixelTest.SignalSyncPointOnLostContext
R=jamesr, piman
BUG=179896
Review URL: https://chromiumcodereview.appspot.com/14126014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196930 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/cc.gyp | 2 | ||||
-rw-r--r-- | cc/output/gl_renderer_pixeltest.cc | 67 | ||||
-rw-r--r-- | cc/resources/sync_point_helper.cc | 37 | ||||
-rw-r--r-- | cc/resources/sync_point_helper.h | 36 | ||||
-rw-r--r-- | content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc | 16 | ||||
-rw-r--r-- | content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h | 4 | ||||
-rw-r--r-- | webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc | 79 | ||||
-rw-r--r-- | webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h | 6 |
8 files changed, 242 insertions, 5 deletions
@@ -291,6 +291,8 @@ 'resources/scoped_resource.h', 'resources/skpicture_content_layer_updater.cc', 'resources/skpicture_content_layer_updater.h', + 'resources/sync_point_helper.cc', + 'resources/sync_point_helper.h', 'resources/texture_mailbox.cc', 'resources/texture_mailbox.h', 'resources/tile.cc', diff --git a/cc/output/gl_renderer_pixeltest.cc b/cc/output/gl_renderer_pixeltest.cc index 02f783e..852c079 100644 --- a/cc/output/gl_renderer_pixeltest.cc +++ b/cc/output/gl_renderer_pixeltest.cc @@ -4,9 +4,12 @@ #include "cc/output/gl_renderer.h" +#include "base/message_loop.h" #include "cc/layers/append_quads_data.h" #include "cc/quads/draw_quad.h" +#include "cc/resources/sync_point_helper.h" #include "cc/test/pixel_test.h" +#include "gpu/GLES2/gl2extchromium.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" @@ -563,6 +566,70 @@ TEST_F(GLRendererPixelTest, AxisAligned) { ExactPixelComparator(true))); } +static void SyncPointCallback(int* callback_count) { + ++(*callback_count); + base::MessageLoop::current()->QuitWhenIdle(); +} + +static void OtherCallback(int* callback_count) { + ++(*callback_count); + base::MessageLoop::current()->QuitWhenIdle(); +} + +TEST_F(GLRendererPixelTest, SignalSyncPointOnLostContext) { + int sync_point_callback_count = 0; + int other_callback_count = 0; + unsigned sync_point = output_surface_->context3d()->insertSyncPoint(); + + output_surface_->context3d()->loseContextCHROMIUM( + GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); + + SyncPointHelper::SignalSyncPoint( + output_surface_->context3d(), + sync_point, + base::Bind(&SyncPointCallback, &sync_point_callback_count)); + EXPECT_EQ(0, sync_point_callback_count); + EXPECT_EQ(0, other_callback_count); + + // Make the sync point happen. + output_surface_->context3d()->finish(); + // Post a task after the sync point. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&OtherCallback, &other_callback_count)); + + base::MessageLoop::current()->Run(); + + // The sync point shouldn't have happened since the context was lost. + EXPECT_EQ(0, sync_point_callback_count); + EXPECT_EQ(1, other_callback_count); +} + +TEST_F(GLRendererPixelTest, SignalSyncPoint) { + int sync_point_callback_count = 0; + int other_callback_count = 0; + unsigned sync_point = output_surface_->context3d()->insertSyncPoint(); + + SyncPointHelper::SignalSyncPoint( + output_surface_->context3d(), + sync_point, + base::Bind(&SyncPointCallback, &sync_point_callback_count)); + EXPECT_EQ(0, sync_point_callback_count); + EXPECT_EQ(0, other_callback_count); + + // Make the sync point happen. + output_surface_->context3d()->finish(); + // Post a task after the sync point. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&OtherCallback, &other_callback_count)); + + base::MessageLoop::current()->Run(); + + // The sync point should have happened. + EXPECT_EQ(1, sync_point_callback_count); + EXPECT_EQ(1, other_callback_count); +} #endif } // namespace diff --git a/cc/resources/sync_point_helper.cc b/cc/resources/sync_point_helper.cc new file mode 100644 index 0000000..c398eb6 --- /dev/null +++ b/cc/resources/sync_point_helper.cc @@ -0,0 +1,37 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/resources/sync_point_helper.h" + +#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" + +namespace cc { + +class SignalSyncPointCallbackClass + : public WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback { + public: + explicit SignalSyncPointCallbackClass(const base::Closure& closure) + : closure_(closure) {} + + virtual void onSyncPointReached() { + if (!closure_.is_null()) + closure_.Run(); + } + + private: + base::Closure closure_; +}; + +void SyncPointHelper::SignalSyncPoint( + WebKit::WebGraphicsContext3D* context3d, + unsigned sync_point, + const base::Closure& closure) { + SignalSyncPointCallbackClass* callback_class = + new SignalSyncPointCallbackClass(closure); + + // Pass ownership of the CallbackClass to WebGraphicsContext3D. + context3d->signalSyncPoint(sync_point, callback_class); +} + +} // namespace cc diff --git a/cc/resources/sync_point_helper.h b/cc/resources/sync_point_helper.h new file mode 100644 index 0000000..c342069 --- /dev/null +++ b/cc/resources/sync_point_helper.h @@ -0,0 +1,36 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_SYNC_POINT_HELPER_H_ +#define CC_RESOURCES_SYNC_POINT_HELPER_H_ + +#include "base/callback.h" +#include "cc/base/cc_export.h" + +namespace WebKit { class WebGraphicsContext3D; } + +namespace cc { + +class CC_EXPORT SyncPointHelper { + public: + // Requests a callback to |closure| when the |sync_point| is reached by the + // |context3d|. + // + // If the |context3d| is destroyed or lost before the callback fires, then + // AbortBecauseDidLoseOrDestroyContext() must be called to clean up the + // callback's resources. + static void SignalSyncPoint( + WebKit::WebGraphicsContext3D* context3d, + unsigned sync_point, + const base::Closure& closure); + + private: + SyncPointHelper(); + + DISALLOW_COPY_AND_ASSIGN(SyncPointHelper); +}; + +} // namespace cc + +#endif // CC_RESOURCES_SYNC_POINT_HELPER_H_ diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 0f2fcb1..09eb95b 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -1625,6 +1625,22 @@ DELEGATE_TO_GL(shallowFlushCHROMIUM,ShallowFlushCHROMIUM); DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint) +static void SignalSyncPointCallback( + scoped_ptr< + WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) { + callback->onSyncPointReached(); +} + +void WebGraphicsContext3DCommandBufferImpl::signalSyncPoint( + unsigned sync_point, + WebGraphicsSyncPointCallback* callback) { + // Take ownership of the callback. + scoped_ptr<WebGraphicsSyncPointCallback> own_callback(callback); + command_buffer_->SignalSyncPoint( + sync_point, + base::Bind(&SignalSyncPointCallback, base::Passed(&own_callback))); +} + void WebGraphicsContext3DCommandBufferImpl::genMailboxCHROMIUM( WGC3Dbyte* name) { std::vector<gpu::Mailbox> names(1); diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h index 03b15da..6cbc318 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -151,7 +151,9 @@ class WebGraphicsContext3DCommandBufferImpl virtual bool setParentContext(WebGraphicsContext3D* parent_context); virtual unsigned int insertSyncPoint(); - virtual void waitSyncPoint(unsigned int); + virtual void waitSyncPoint(unsigned int sync_point); + virtual void signalSyncPoint(unsigned sync_point, + WebGraphicsSyncPointCallback* callback); virtual void reshape(int width, int height); diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc index c63e855..c0d0113 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -139,6 +139,12 @@ class GLInProcessContext { // problem communicating with the GPU process. bool IsCommandBufferContextLost(); + void LoseContext(uint32 current, uint32 other); + + void SetSignalSyncPointCallback( + scoped_ptr< + WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback); + CommandBufferService* GetCommandBufferService(); ::gpu::gles2::GLES2Decoder* GetDecoder(); @@ -166,6 +172,8 @@ class GLInProcessContext { scoped_ptr<GLES2CmdHelper> gles2_helper_; scoped_ptr<TransferBuffer> transfer_buffer_; scoped_ptr<GLES2Implementation> gles2_implementation_; + scoped_ptr<WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> + signal_sync_point_callback_; Error last_error_; bool share_resources_; bool context_lost_; @@ -281,6 +289,12 @@ AutoLockAndDecoderDetachThread::~AutoLockAndDecoderDetachThread() { } // namespace +static void CallAndDestroy( + scoped_ptr< + WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) { + callback->onSyncPointReached(); +} + void GLInProcessContext::PumpCommands() { if (!context_lost_) { AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), @@ -288,9 +302,15 @@ void GLInProcessContext::PumpCommands() { decoder_->MakeCurrent(); gpu_scheduler_->PutChanged(); ::gpu::CommandBuffer::State state = command_buffer_->GetState(); - if (::gpu::error::IsError(state.error)) { + if (::gpu::error::IsError(state.error)) context_lost_ = true; - } + } + + if (!context_lost_ && signal_sync_point_callback_) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&CallAndDestroy, + base::Passed(&signal_sync_point_callback_))); } } @@ -368,6 +388,18 @@ bool GLInProcessContext::IsCommandBufferContextLost() { return ::gpu::error::IsError(state.error); } +void GLInProcessContext::LoseContext(uint32 current, uint32 other) { + gles2_implementation_->LoseContextCHROMIUM(current, other); + gles2_implementation_->Finish(); + DCHECK(IsCommandBufferContextLost()); +} + +void GLInProcessContext::SetSignalSyncPointCallback( + scoped_ptr< + WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) { + signal_sync_point_callback_ = callback.Pass(); +} + CommandBufferService* GLInProcessContext::GetCommandBufferService() { return command_buffer_.get(); } @@ -454,8 +486,19 @@ bool GLInProcessContext::Initialize( { AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), g_all_shared_contexts.Get()); - if (share_resources_ && !g_all_shared_contexts.Get().empty()) - context_group = *g_all_shared_contexts.Get().begin(); + if (share_resources_ && !g_all_shared_contexts.Get().empty()) { + for (std::set<GLInProcessContext*>::iterator it = + g_all_shared_contexts.Get().begin(); + it != g_all_shared_contexts.Get().end(); + ++it) { + if (!(*it)->IsCommandBufferContextLost()) { + context_group = *it; + break; + } + } + if (!context_group) + share_group = new gfx::GLShareGroup; + } // TODO(gman): This needs to be true if this is Pepper. bool bind_generates_resource = false; @@ -604,6 +647,15 @@ void GLInProcessContext::Destroy() { void GLInProcessContext::OnContextLost() { if (!context_lost_callback_.is_null()) context_lost_callback_.Run(); + + context_lost_ = true; + if (share_resources_) { + for (std::set<GLInProcessContext*>::iterator it = + g_all_shared_contexts.Get().begin(); + it != g_all_shared_contexts.Get().end(); + ++it) + (*it)->context_lost_ = true; + } } // static @@ -1791,6 +1843,25 @@ DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM, DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*) +unsigned WebGraphicsContext3DInProcessCommandBufferImpl::insertSyncPoint() { + shallowFlushCHROMIUM(); + return 0; +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::signalSyncPoint( + unsigned sync_point, + WebGraphicsSyncPointCallback* callback) { + // Take ownership of the callback. + context_->SetSignalSyncPointCallback(make_scoped_ptr(callback)); + // Stick something in the command buffer. + shallowFlushCHROMIUM(); +} + +void WebGraphicsContext3DInProcessCommandBufferImpl::loseContextCHROMIUM( + WGC3Denum current, WGC3Denum other) { + context_->LoseContext(current, other); +} + DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint, WGC3Denum, WGC3Denum, const void*) diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h index e04e9e2..28e96d5 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h @@ -537,6 +537,12 @@ class WEBKIT_GPU_EXPORT WebGraphicsContext3DInProcessCommandBufferImpl virtual void drawBuffersEXT(WGC3Dsizei n, const WGC3Denum* bufs); + virtual unsigned insertSyncPoint(); + virtual void signalSyncPoint(unsigned sync_point, + WebGraphicsSyncPointCallback* callback); + + virtual void loseContextCHROMIUM(WGC3Denum current, WGC3Denum other); + protected: virtual GrGLInterface* onCreateGrGLInterface(); |