summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-27 03:24:50 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-27 03:24:50 +0000
commit1786d84c72c33d3fcece9622b98c5d584f6b1b31 (patch)
treeca2ee4a55d69ed76aa9890b244ce7873126b4826
parent1400e6dc12c13f62aa300dd4468019a08388daec (diff)
downloadchromium_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.gyp2
-rw-r--r--cc/output/gl_renderer_pixeltest.cc67
-rw-r--r--cc/resources/sync_point_helper.cc37
-rw-r--r--cc/resources/sync_point_helper.h36
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc16
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h4
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc79
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h6
8 files changed, 242 insertions, 5 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 3ba91bb..d536b16 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -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();