Cherry-pick: gpu: Expose GLFence impls
Clean cherry-pick of chromium r279621
Original description:
Move implementations to their own header+source files.
Then specifically use EGL_KHR_fence_sync implementation for
mailbox synchronizing because it's the only one working across
contexts and share groups.
Change-Id: I49b2d17acd2af3980351239c04143b1d50e6e296
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index f97a6dc..15eb0ea 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -721,6 +721,11 @@
EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
.WillOnce(Return(kGlSync))
.RetiresOnSaturation();
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
}
EndQueryEXT end_cmd;
@@ -737,6 +742,11 @@
.RetiresOnSaturation();
}
if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
.WillOnce(Return(GL_ALREADY_SIGNALED))
.RetiresOnSaturation();
@@ -752,8 +762,14 @@
if (query_type.is_gl) {
EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
}
- if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM)
+ if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
+ }
test->ResetDecoder();
}
@@ -879,6 +895,11 @@
EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
.WillOnce(Return(kGlSync))
.RetiresOnSaturation();
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl_, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EndQueryEXT end_cmd;
end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
@@ -886,6 +907,11 @@
EXPECT_EQ(GL_NO_ERROR, GetGLError());
EXPECT_TRUE(query->pending());
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl_, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
.WillOnce(Return(GL_TIMEOUT_EXPIRED))
.RetiresOnSaturation();
@@ -894,6 +920,11 @@
EXPECT_TRUE(process_success);
EXPECT_TRUE(query->pending());
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl_, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
.WillOnce(Return(GL_ALREADY_SIGNALED))
.RetiresOnSaturation();
@@ -904,6 +935,11 @@
QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result));
+#if DCHECK_IS_ON
+ EXPECT_CALL(*gl_, IsSync(kGlSync))
+ .WillOnce(Return(GL_TRUE))
+ .RetiresOnSaturation();
+#endif
EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
ResetDecoder();
}
diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc
index 3703f14..7028a5a 100644
--- a/gpu/command_buffer/service/texture_definition.cc
+++ b/gpu/command_buffer/service/texture_definition.cc
@@ -106,11 +106,32 @@
EGLDisplay display,
EGLImageKHR image);
virtual ~NativeImageBufferEGL();
+ virtual void AddClient(gfx::GLImage* client) OVERRIDE;
+ virtual void RemoveClient(gfx::GLImage* client) OVERRIDE;
+ virtual bool IsClient(gfx::GLImage* client) OVERRIDE;
virtual void BindToTexture(GLenum target) OVERRIDE;
+ virtual void WillRead(gfx::GLImage* client) OVERRIDE;
+ virtual void WillWrite(gfx::GLImage* client) OVERRIDE;
+ virtual void DidRead(gfx::GLImage* client) OVERRIDE;
+ virtual void DidWrite(gfx::GLImage* client) OVERRIDE;
EGLDisplay egl_display_;
EGLImageKHR egl_image_;
+ base::Lock lock_;
+
+ struct ClientInfo {
+ ClientInfo(gfx::GLImage* client);
+ ~ClientInfo();
+
+ gfx::GLImage* client;
+ bool needs_wait_before_read;
+ linked_ptr<gfx::GLFence> read_fence;
+ };
+ std::list<ClientInfo> client_infos_;
+ scoped_ptr<gfx::GLFence> write_fence_;
+ gfx::GLImage* write_client_;
+
DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL);
};
@@ -143,76 +164,35 @@
make_scoped_ptr(gfx::GLFence::Create()), egl_display, egl_image);
}
+NativeImageBufferEGL::ClientInfo::ClientInfo(gfx::GLImage* client)
+ : client(client), needs_wait_before_read(true) {}
+
+NativeImageBufferEGL::ClientInfo::~ClientInfo() {}
+
NativeImageBufferEGL::NativeImageBufferEGL(scoped_ptr<gfx::GLFence> write_fence,
EGLDisplay display,
EGLImageKHR image)
- : NativeImageBuffer(write_fence.Pass()),
+ : NativeImageBuffer(),
egl_display_(display),
- egl_image_(image) {
+ egl_image_(image),
+ write_fence_(write_fence.Pass()),
+ write_client_(NULL) {
DCHECK(egl_display_ != EGL_NO_DISPLAY);
DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
}
NativeImageBufferEGL::~NativeImageBufferEGL() {
+ DCHECK(client_infos_.empty());
if (egl_image_ != EGL_NO_IMAGE_KHR)
eglDestroyImageKHR(egl_display_, egl_image_);
}
-void NativeImageBufferEGL::BindToTexture(GLenum target) {
- DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
- glEGLImageTargetTexture2DOES(target, egl_image_);
- DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError());
- DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
-}
-#endif
-
-class NativeImageBufferStub : public NativeImageBuffer {
- public:
- NativeImageBufferStub() : NativeImageBuffer(scoped_ptr<gfx::GLFence>()) {}
-
- private:
- virtual ~NativeImageBufferStub() {}
- virtual void BindToTexture(GLenum target) OVERRIDE {}
-
- DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub);
-};
-
-} // anonymous namespace
-
-// static
-scoped_refptr<NativeImageBuffer> NativeImageBuffer::Create(GLuint texture_id) {
- switch (gfx::GetGLImplementation()) {
-#if !defined(OS_MACOSX)
- case gfx::kGLImplementationEGLGLES2:
- return NativeImageBufferEGL::Create(texture_id);
-#endif
- case gfx::kGLImplementationMockGL:
- return new NativeImageBufferStub;
- default:
- NOTREACHED();
- return NULL;
- }
-}
-
-NativeImageBuffer::ClientInfo::ClientInfo(gfx::GLImage* client)
- : client(client), needs_wait_before_read(true) {}
-
-NativeImageBuffer::ClientInfo::~ClientInfo() {}
-
-NativeImageBuffer::NativeImageBuffer(scoped_ptr<gfx::GLFence> write_fence)
- : write_fence_(write_fence.Pass()), write_client_(NULL) {
-}
-
-NativeImageBuffer::~NativeImageBuffer() {
- DCHECK(client_infos_.empty());
-}
-
-void NativeImageBuffer::AddClient(gfx::GLImage* client) {
+void NativeImageBufferEGL::AddClient(gfx::GLImage* client) {
base::AutoLock lock(lock_);
client_infos_.push_back(ClientInfo(client));
}
-void NativeImageBuffer::RemoveClient(gfx::GLImage* client) {
+void NativeImageBufferEGL::RemoveClient(gfx::GLImage* client) {
base::AutoLock lock(lock_);
if (write_client_ == client)
write_client_ = NULL;
@@ -227,7 +207,7 @@
NOTREACHED();
}
-bool NativeImageBuffer::IsClient(gfx::GLImage* client) {
+bool NativeImageBufferEGL::IsClient(gfx::GLImage* client) {
base::AutoLock lock(lock_);
for (std::list<ClientInfo>::iterator it = client_infos_.begin();
it != client_infos_.end();
@@ -238,7 +218,14 @@
return false;
}
-void NativeImageBuffer::WillRead(gfx::GLImage* client) {
+void NativeImageBufferEGL::BindToTexture(GLenum target) {
+ DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
+ glEGLImageTargetTexture2DOES(target, egl_image_);
+ DCHECK_EQ(static_cast<EGLint>(EGL_SUCCESS), eglGetError());
+ DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+}
+
+void NativeImageBufferEGL::WillRead(gfx::GLImage* client) {
base::AutoLock lock(lock_);
if (!write_fence_.get() || write_client_ == client)
return;
@@ -257,7 +244,7 @@
NOTREACHED();
}
-void NativeImageBuffer::WillWrite(gfx::GLImage* client) {
+void NativeImageBufferEGL::WillWrite(gfx::GLImage* client) {
base::AutoLock lock(lock_);
if (write_client_ != client)
write_fence_->ServerWait();
@@ -270,7 +257,7 @@
}
}
-void NativeImageBuffer::DidRead(gfx::GLImage* client) {
+void NativeImageBufferEGL::DidRead(gfx::GLImage* client) {
base::AutoLock lock(lock_);
for (std::list<ClientInfo>::iterator it = client_infos_.begin();
it != client_infos_.end();
@@ -283,7 +270,7 @@
NOTREACHED();
}
-void NativeImageBuffer::DidWrite(gfx::GLImage* client) {
+void NativeImageBufferEGL::DidWrite(gfx::GLImage* client) {
base::AutoLock lock(lock_);
// Sharing semantics require the client to flush in order to make changes
// visible to other clients.
@@ -296,6 +283,43 @@
}
}
+#endif
+
+class NativeImageBufferStub : public NativeImageBuffer {
+ public:
+ NativeImageBufferStub() : NativeImageBuffer() {}
+
+ private:
+ virtual ~NativeImageBufferStub() {}
+ virtual void AddClient(gfx::GLImage* client) OVERRIDE {}
+ virtual void RemoveClient(gfx::GLImage* client) OVERRIDE {}
+ virtual bool IsClient(gfx::GLImage* client) OVERRIDE { return true; }
+ virtual void BindToTexture(GLenum target) OVERRIDE {}
+ virtual void WillRead(gfx::GLImage* client) OVERRIDE {}
+ virtual void WillWrite(gfx::GLImage* client) OVERRIDE {}
+ virtual void DidRead(gfx::GLImage* client) OVERRIDE {}
+ virtual void DidWrite(gfx::GLImage* client) OVERRIDE {}
+
+ DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub);
+};
+
+} // anonymous namespace
+
+// static
+scoped_refptr<NativeImageBuffer> NativeImageBuffer::Create(GLuint texture_id) {
+ switch (gfx::GetGLImplementation()) {
+#if !defined(OS_MACOSX)
+ case gfx::kGLImplementationEGLGLES2:
+ return NativeImageBufferEGL::Create(texture_id);
+#endif
+ case gfx::kGLImplementationMockGL:
+ return new NativeImageBufferStub;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
TextureDefinition::LevelInfo::LevelInfo(GLenum target,
GLenum internal_format,
GLsizei width,
diff --git a/gpu/command_buffer/service/texture_definition.h b/gpu/command_buffer/service/texture_definition.h
index 7708902..0b4816a 100644
--- a/gpu/command_buffer/service/texture_definition.h
+++ b/gpu/command_buffer/service/texture_definition.h
@@ -29,35 +29,20 @@
class NativeImageBuffer : public base::RefCountedThreadSafe<NativeImageBuffer> {
public:
static scoped_refptr<NativeImageBuffer> Create(GLuint texture_id);
+
+ virtual void AddClient(gfx::GLImage* client) = 0;
+ virtual void RemoveClient(gfx::GLImage* client) = 0;
+ virtual bool IsClient(gfx::GLImage* client) = 0;
virtual void BindToTexture(GLenum target) = 0;
-
- void AddClient(gfx::GLImage* client);
- void RemoveClient(gfx::GLImage* client);
- bool IsClient(gfx::GLImage* client);
-
- void WillRead(gfx::GLImage* client);
- void WillWrite(gfx::GLImage* client);
- void DidRead(gfx::GLImage* client);
- void DidWrite(gfx::GLImage* client);
+ virtual void WillRead(gfx::GLImage* client) = 0;
+ virtual void WillWrite(gfx::GLImage* client) = 0;
+ virtual void DidRead(gfx::GLImage* client) = 0;
+ virtual void DidWrite(gfx::GLImage* client) = 0;
protected:
friend class base::RefCountedThreadSafe<NativeImageBuffer>;
- explicit NativeImageBuffer(scoped_ptr<gfx::GLFence> write_fence);
- virtual ~NativeImageBuffer();
-
- base::Lock lock_;
-
- struct ClientInfo {
- ClientInfo(gfx::GLImage* client);
- ~ClientInfo();
-
- gfx::GLImage* client;
- bool needs_wait_before_read;
- linked_ptr<gfx::GLFence> read_fence;
- };
- std::list<ClientInfo> client_infos_;
- scoped_ptr<gfx::GLFence> write_fence_;
- gfx::GLImage* write_client_;
+ NativeImageBuffer() {}
+ virtual ~NativeImageBuffer() {}
DISALLOW_COPY_AND_ASSIGN(NativeImageBuffer);
};
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index f63d580..8a904ab 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -50,6 +50,10 @@
"gl_export.h",
"gl_fence.cc",
"gl_fence.h",
+ "gl_fence_arb.cc",
+ "gl_fence_arb.h",
+ "gl_fence_nv.cc",
+ "gl_fence_nv.h",
"gl_gl_api_implementation.cc",
"gl_gl_api_implementation.h",
"gl_image.cc",
@@ -131,6 +135,8 @@
"egl_util.h",
"gl_context_egl.cc",
"gl_context_egl.h",
+ "gl_fence_egl.cc",
+ "gl_fence_egl.h",
"gl_image_egl.cc",
"gl_image_egl.h",
"gl_surface_egl.cc",
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index 248e4ff..2ff3de9 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -754,6 +754,9 @@
{ 'return_type': 'GLsync',
'names': ['glFenceSync'],
'arguments': 'GLenum condition, GLbitfield flags', },
+{ 'return_type': 'GLboolean',
+ 'names': ['glIsSync'],
+ 'arguments': 'GLsync sync', },
{ 'return_type': 'void',
'names': ['glDeleteSync'],
'arguments': 'GLsync sync', },
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 59e82a6..ddd361a 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -71,6 +71,10 @@
'gl_export.h',
'gl_fence.cc',
'gl_fence.h',
+ 'gl_fence_arb.cc',
+ 'gl_fence_arb.h',
+ 'gl_fence_nv.cc',
+ 'gl_fence_nv.h',
'gl_gl_api_implementation.cc',
'gl_gl_api_implementation.h',
'gl_image.cc',
@@ -177,6 +181,8 @@
'egl_util.h',
'gl_context_egl.cc',
'gl_context_egl.h',
+ 'gl_fence_egl.cc',
+ 'gl_fence_egl.h',
'gl_image_egl.cc',
'gl_image_egl.h',
'gl_surface_egl.cc',
diff --git a/ui/gl/gl.target.darwin-arm.mk b/ui/gl/gl.target.darwin-arm.mk
index 2bda780..006d278 100644
--- a/ui/gl/gl.target.darwin-arm.mk
+++ b/ui/gl/gl.target.darwin-arm.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.darwin-arm64.mk b/ui/gl/gl.target.darwin-arm64.mk
index 84157fb..596f90c 100644
--- a/ui/gl/gl.target.darwin-arm64.mk
+++ b/ui/gl/gl.target.darwin-arm64.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.darwin-mips.mk b/ui/gl/gl.target.darwin-mips.mk
index 90112a4..e88d594 100644
--- a/ui/gl/gl.target.darwin-mips.mk
+++ b/ui/gl/gl.target.darwin-mips.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.darwin-x86.mk b/ui/gl/gl.target.darwin-x86.mk
index 32118f9..8abced9 100644
--- a/ui/gl/gl.target.darwin-x86.mk
+++ b/ui/gl/gl.target.darwin-x86.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.darwin-x86_64.mk b/ui/gl/gl.target.darwin-x86_64.mk
index 9440fb9..aadbb3b 100644
--- a/ui/gl/gl.target.darwin-x86_64.mk
+++ b/ui/gl/gl.target.darwin-x86_64.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.linux-arm.mk b/ui/gl/gl.target.linux-arm.mk
index 2bda780..006d278 100644
--- a/ui/gl/gl.target.linux-arm.mk
+++ b/ui/gl/gl.target.linux-arm.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.linux-arm64.mk b/ui/gl/gl.target.linux-arm64.mk
index 84157fb..596f90c 100644
--- a/ui/gl/gl.target.linux-arm64.mk
+++ b/ui/gl/gl.target.linux-arm64.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.linux-mips.mk b/ui/gl/gl.target.linux-mips.mk
index 90112a4..e88d594 100644
--- a/ui/gl/gl.target.linux-mips.mk
+++ b/ui/gl/gl.target.linux-mips.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.linux-x86.mk b/ui/gl/gl.target.linux-x86.mk
index 32118f9..8abced9 100644
--- a/ui/gl/gl.target.linux-x86.mk
+++ b/ui/gl/gl.target.linux-x86.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl.target.linux-x86_64.mk b/ui/gl/gl.target.linux-x86_64.mk
index 9440fb9..aadbb3b 100644
--- a/ui/gl/gl.target.linux-x86_64.mk
+++ b/ui/gl/gl.target.linux-x86_64.mk
@@ -97,6 +97,8 @@
ui/gl/gl_context_stub.cc \
ui/gl/gl_context_stub_with_extensions.cc \
ui/gl/gl_fence.cc \
+ ui/gl/gl_fence_arb.cc \
+ ui/gl/gl_fence_nv.cc \
ui/gl/gl_gl_api_implementation.cc \
ui/gl/gl_image.cc \
ui/gl/gl_image_android.cc \
@@ -119,6 +121,7 @@
ui/gl/sync_control_vsync_provider.cc \
ui/gl/egl_util.cc \
ui/gl/gl_context_egl.cc \
+ ui/gl/gl_fence_egl.cc \
ui/gl/gl_image_egl.cc \
ui/gl/gl_surface_egl.cc \
ui/gl/gl_egl_api_implementation.cc \
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc
index 04c6a48..5186f23 100644
--- a/ui/gl/gl_fence.cc
+++ b/ui/gl/gl_fence.cc
@@ -7,6 +7,9 @@
#include "base/compiler_specific.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence_arb.h"
+#include "ui/gl/gl_fence_egl.h"
+#include "ui/gl/gl_fence_nv.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_version_info.h"
@@ -14,151 +17,6 @@
namespace {
-class GLFenceNVFence: public GLFence {
- public:
- GLFenceNVFence(bool flush) {
- // What if either of these GL calls fails? TestFenceNV will return true.
- // See spec:
- // http://www.opengl.org/registry/specs/NV/fence.txt
- //
- // What should happen if TestFenceNV is called for a name before SetFenceNV
- // is called?
- // We generate an INVALID_OPERATION error, and return TRUE.
- // This follows the semantics for texture object names before
- // they are bound, in that they acquire their state upon binding.
- // We will arbitrarily return TRUE for consistency.
- glGenFencesNV(1, &fence_);
- glSetFenceNV(fence_, GL_ALL_COMPLETED_NV);
- if (flush) {
- glFlush();
- } else {
- flush_event_ = GLContext::GetCurrent()->SignalFlush();
- }
- }
-
- virtual bool HasCompleted() OVERRIDE {
- return !!glTestFenceNV(fence_);
- }
-
- virtual void ClientWait() OVERRIDE {
- if (!flush_event_ || flush_event_->IsSignaled()) {
- glFinishFenceNV(fence_);
- } else {
- LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
- }
- }
-
- virtual void ServerWait() OVERRIDE {
- ClientWait();
- }
-
- private:
- virtual ~GLFenceNVFence() {
- glDeleteFencesNV(1, &fence_);
- }
-
- GLuint fence_;
- scoped_refptr<GLContext::FlushEvent> flush_event_;
-};
-
-class GLFenceARBSync: public GLFence {
- public:
- GLFenceARBSync(bool flush) {
- sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- if (flush) {
- glFlush();
- } else {
- flush_event_ = GLContext::GetCurrent()->SignalFlush();
- }
- }
-
- virtual bool HasCompleted() OVERRIDE {
- // Handle the case where FenceSync failed.
- if (!sync_)
- return true;
-
- // We could potentially use glGetSynciv here, but it doesn't work
- // on OSX 10.7 (always says the fence is not signaled yet).
- // glClientWaitSync works better, so let's use that instead.
- return glClientWaitSync(sync_, 0, 0) != GL_TIMEOUT_EXPIRED;
- }
-
- virtual void ClientWait() OVERRIDE {
- if (!flush_event_ || flush_event_->IsSignaled()) {
- glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
- } else {
- LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
- }
- }
-
- virtual void ServerWait() OVERRIDE {
- if (!flush_event_ || flush_event_->IsSignaled()) {
- glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED);
- } else {
- LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
- }
- }
-
- private:
- virtual ~GLFenceARBSync() {
- glDeleteSync(sync_);
- }
-
- GLsync sync_;
- scoped_refptr<GLContext::FlushEvent> flush_event_;
-};
-
-#if !defined(OS_MACOSX)
-class EGLFenceSync : public GLFence {
- public:
- EGLFenceSync(bool flush) {
- display_ = eglGetCurrentDisplay();
- sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
- if (flush) {
- glFlush();
- } else {
- flush_event_ = GLContext::GetCurrent()->SignalFlush();
- }
- }
-
- virtual bool HasCompleted() OVERRIDE {
- EGLint value = 0;
- eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
- DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR);
- return !value || value == EGL_SIGNALED_KHR;
- }
-
- virtual void ClientWait() OVERRIDE {
- if (!flush_event_ || flush_event_->IsSignaled()) {
- EGLint flags = 0;
- EGLTimeKHR time = EGL_FOREVER_KHR;
- eglClientWaitSyncKHR(display_, sync_, flags, time);
- } else {
- LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
- }
- }
-
- virtual void ServerWait() OVERRIDE {
- if (!flush_event_ || flush_event_->IsSignaled()) {
- EGLint flags = 0;
- eglWaitSyncKHR(display_, sync_, flags);
- } else {
- LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
- }
- }
-
-
- private:
- virtual ~EGLFenceSync() {
- eglDestroySyncKHR(display_, sync_);
- }
-
- EGLSyncKHR sync_;
- EGLDisplay display_;
- scoped_refptr<GLContext::FlushEvent> flush_event_;
-};
-#endif // !OS_MACOSX
-
// static
GLFence* CreateFence(bool flush) {
DCHECK(GLContext::GetCurrent())
@@ -168,13 +26,13 @@
// Prefer ARB_sync which supports server-side wait.
if (g_driver_gl.ext.b_GL_ARB_sync ||
GetGLVersionInfo()->is_es3) {
- fence.reset(new GLFenceARBSync(flush));
+ fence.reset(new GLFenceARB(flush));
#if !defined(OS_MACOSX)
} else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) {
- fence.reset(new EGLFenceSync(flush));
+ fence.reset(new GLFenceEGL(flush));
#endif
} else if (g_driver_gl.ext.b_GL_NV_fence) {
- fence.reset(new GLFenceNVFence(flush));
+ fence.reset(new GLFenceNV(flush));
}
DCHECK_EQ(!!fence.get(), GLFence::IsSupported());
diff --git a/ui/gl/gl_fence.h b/ui/gl/gl_fence.h
index a4f9743..5af253d 100644
--- a/ui/gl/gl_fence.h
+++ b/ui/gl/gl_fence.h
@@ -31,9 +31,6 @@
// client.
virtual void ServerWait() = 0;
- protected:
- static bool IsContextLost();
-
private:
DISALLOW_COPY_AND_ASSIGN(GLFence);
};
diff --git a/ui/gl/gl_fence_arb.cc b/ui/gl/gl_fence_arb.cc
new file mode 100644
index 0000000..b854346
--- /dev/null
+++ b/ui/gl/gl_fence_arb.cc
@@ -0,0 +1,57 @@
+// Copyright 2014 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 "ui/gl/gl_fence_arb.h"
+
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+
+namespace gfx {
+
+GLFenceARB::GLFenceARB(bool flush) {
+ sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ DCHECK_EQ(GL_TRUE, glIsSync(sync_));
+ if (flush) {
+ glFlush();
+ } else {
+ flush_event_ = GLContext::GetCurrent()->SignalFlush();
+ }
+}
+
+bool GLFenceARB::HasCompleted() {
+ // Handle the case where FenceSync failed.
+ if (!sync_)
+ return true;
+
+ DCHECK_EQ(GL_TRUE, glIsSync(sync_));
+ // We could potentially use glGetSynciv here, but it doesn't work
+ // on OSX 10.7 (always says the fence is not signaled yet).
+ // glClientWaitSync works better, so let's use that instead.
+ return glClientWaitSync(sync_, 0, 0) != GL_TIMEOUT_EXPIRED;
+}
+
+void GLFenceARB::ClientWait() {
+ DCHECK_EQ(GL_TRUE, glIsSync(sync_));
+ if (!flush_event_ || flush_event_->IsSignaled()) {
+ glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
+ } else {
+ LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
+ }
+}
+
+void GLFenceARB::ServerWait() {
+ DCHECK_EQ(GL_TRUE, glIsSync(sync_));
+ if (!flush_event_ || flush_event_->IsSignaled()) {
+ glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED);
+ } else {
+ LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
+ }
+}
+
+GLFenceARB::~GLFenceARB() {
+ DCHECK_EQ(GL_TRUE, glIsSync(sync_));
+ glDeleteSync(sync_);
+}
+
+} // namespace gfx
diff --git a/ui/gl/gl_fence_arb.h b/ui/gl/gl_fence_arb.h
new file mode 100644
index 0000000..db29675
--- /dev/null
+++ b/ui/gl/gl_fence_arb.h
@@ -0,0 +1,34 @@
+// Copyright 2014 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 UI_GL_GL_FENCE_ARB_H_
+#define UI_GL_GL_FENCE_ARB_H_
+
+#include "base/macros.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
+
+namespace gfx {
+
+class GL_EXPORT GLFenceARB : public GLFence {
+ public:
+ GLFenceARB(bool flush);
+ virtual ~GLFenceARB();
+
+ // GLFence implementation:
+ virtual bool HasCompleted() OVERRIDE;
+ virtual void ClientWait() OVERRIDE;
+ virtual void ServerWait() OVERRIDE;
+
+ private:
+ GLsync sync_;
+ scoped_refptr<GLContext::FlushEvent> flush_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLFenceARB);
+};
+
+} // namespace gfx
+
+#endif // UI_GL_GL_FENCE_ARB_H_
diff --git a/ui/gl/gl_fence_egl.cc b/ui/gl/gl_fence_egl.cc
new file mode 100644
index 0000000..71d3103
--- /dev/null
+++ b/ui/gl/gl_fence_egl.cc
@@ -0,0 +1,53 @@
+// Copyright 2014 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 "ui/gl/gl_fence_egl.h"
+
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+
+namespace gfx {
+
+GLFenceEGL::GLFenceEGL(bool flush) {
+ display_ = eglGetCurrentDisplay();
+ sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
+ DCHECK(sync_ != EGL_NO_SYNC_KHR);
+ if (flush) {
+ glFlush();
+ } else {
+ flush_event_ = GLContext::GetCurrent()->SignalFlush();
+ }
+}
+
+bool GLFenceEGL::HasCompleted() {
+ EGLint value = 0;
+ eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
+ DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR);
+ return !value || value == EGL_SIGNALED_KHR;
+}
+
+void GLFenceEGL::ClientWait() {
+ if (!flush_event_ || flush_event_->IsSignaled()) {
+ EGLint flags = 0;
+ EGLTimeKHR time = EGL_FOREVER_KHR;
+ eglClientWaitSyncKHR(display_, sync_, flags, time);
+ } else {
+ LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
+ }
+}
+
+void GLFenceEGL::ServerWait() {
+ if (!flush_event_ || flush_event_->IsSignaled()) {
+ EGLint flags = 0;
+ eglWaitSyncKHR(display_, sync_, flags);
+ } else {
+ LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
+ }
+}
+
+GLFenceEGL::~GLFenceEGL() {
+ eglDestroySyncKHR(display_, sync_);
+}
+
+} // namespace gfx
diff --git a/ui/gl/gl_fence_egl.h b/ui/gl/gl_fence_egl.h
new file mode 100644
index 0000000..531b3dc
--- /dev/null
+++ b/ui/gl/gl_fence_egl.h
@@ -0,0 +1,35 @@
+// Copyright 2014 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 UI_GL_GL_FENCE_EGL_H_
+#define UI_GL_GL_FENCE_EGL_H_
+
+#include "base/macros.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
+
+namespace gfx {
+
+class GL_EXPORT GLFenceEGL : public GLFence {
+ public:
+ GLFenceEGL(bool flush);
+ virtual ~GLFenceEGL();
+
+ // GLFence implementation:
+ virtual bool HasCompleted() OVERRIDE;
+ virtual void ClientWait() OVERRIDE;
+ virtual void ServerWait() OVERRIDE;
+
+ private:
+ EGLSyncKHR sync_;
+ EGLDisplay display_;
+ scoped_refptr<GLContext::FlushEvent> flush_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLFenceEGL);
+};
+
+} // namespace gfx
+
+#endif // UI_GL_GL_FENCE_EGL_H_
diff --git a/ui/gl/gl_fence_nv.cc b/ui/gl/gl_fence_nv.cc
new file mode 100644
index 0000000..9dbc47d
--- /dev/null
+++ b/ui/gl/gl_fence_nv.cc
@@ -0,0 +1,57 @@
+// Copyright 2014 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 "ui/gl/gl_fence_nv.h"
+
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+
+namespace gfx {
+
+GLFenceNV::GLFenceNV(bool flush) {
+ // What if either of these GL calls fails? TestFenceNV will return true.
+ // See spec:
+ // http://www.opengl.org/registry/specs/NV/fence.txt
+ //
+ // What should happen if TestFenceNV is called for a name before SetFenceNV
+ // is called?
+ // We generate an INVALID_OPERATION error, and return TRUE.
+ // This follows the semantics for texture object names before
+ // they are bound, in that they acquire their state upon binding.
+ // We will arbitrarily return TRUE for consistency.
+ glGenFencesNV(1, &fence_);
+ glSetFenceNV(fence_, GL_ALL_COMPLETED_NV);
+ DCHECK(glIsFenceNV(fence_));
+ if (flush) {
+ glFlush();
+ } else {
+ flush_event_ = GLContext::GetCurrent()->SignalFlush();
+ }
+}
+
+bool GLFenceNV::HasCompleted() {
+ DCHECK(glIsFenceNV(fence_));
+ return !!glTestFenceNV(fence_);
+}
+
+void GLFenceNV::ClientWait() {
+ DCHECK(glIsFenceNV(fence_));
+ if (!flush_event_ || flush_event_->IsSignaled()) {
+ glFinishFenceNV(fence_);
+ } else {
+ LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
+ }
+}
+
+void GLFenceNV::ServerWait() {
+ DCHECK(glIsFenceNV(fence_));
+ ClientWait();
+}
+
+GLFenceNV::~GLFenceNV() {
+ DCHECK(glIsFenceNV(fence_));
+ glDeleteFencesNV(1, &fence_);
+}
+
+} // namespace gfx
diff --git a/ui/gl/gl_fence_nv.h b/ui/gl/gl_fence_nv.h
new file mode 100644
index 0000000..fee9eff
--- /dev/null
+++ b/ui/gl/gl_fence_nv.h
@@ -0,0 +1,34 @@
+// Copyright 2014 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 UI_GL_GL_FENCE_NV_H_
+#define UI_GL_GL_FENCE_NV_H_
+
+#include "base/macros.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_fence.h"
+
+namespace gfx {
+
+class GL_EXPORT GLFenceNV : public GLFence {
+ public:
+ GLFenceNV(bool flush);
+ virtual ~GLFenceNV();
+
+ // GLFence implementation:
+ virtual bool HasCompleted() OVERRIDE;
+ virtual void ClientWait() OVERRIDE;
+ virtual void ServerWait() OVERRIDE;
+
+ private:
+ GLuint fence_;
+ scoped_refptr<GLContext::FlushEvent> flush_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLFenceNV);
+};
+
+} // namespace gfx
+
+#endif // UI_GL_GL_FENCE_NV_H_