summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyen <dyen@chromium.org>2015-11-04 19:49:25 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-05 03:50:11 +0000
commitc7aff68a0c11820cc2b8d488851c682c0d32cd2b (patch)
tree78819208e3f1532e4dcf42c43bfcef9ba7c3d9b2
parent67d14d4249ec9be027df91655d301872e75d493a (diff)
downloadchromium_src-c7aff68a0c11820cc2b8d488851c682c0d32cd2b.zip
chromium_src-c7aff68a0c11820cc2b8d488851c682c0d32cd2b.tar.gz
chromium_src-c7aff68a0c11820cc2b8d488851c682c0d32cd2b.tar.bz2
Converted video frame and image callbacks to use new sync tokens.
As an incremental step towards utilizing the new sync tokens, this CL converts existing video frame and image sync points to use sync tokens instead. In order to accomplish this, the GpuCommandBufferMsg_CreateImage IPC message has been modified to accept a fence_release parameter so that it can act as a sync token IPC. A new SyncPointClientWaiter concept has also added which can wait on other sync point clients without an associated order number. This only works because the SyncPointClientWaiter cannot be waited on so no deadlocks can occur. BUG=514815 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1429213002 Cr-Commit-Position: refs/heads/master@{#357997}
-rw-r--r--cc/resources/video_resource_updater.cc11
-rw-r--r--cc/test/test_gpu_memory_buffer_manager.cc5
-rw-r--r--cc/test/test_gpu_memory_buffer_manager.h4
-rw-r--r--components/mus/gles2/mojo_gpu_memory_buffer_manager.cc4
-rw-r--r--components/mus/gles2/mojo_gpu_memory_buffer_manager.h4
-rw-r--r--content/browser/gpu/browser_gpu_memory_buffer_manager.cc22
-rw-r--r--content/browser/gpu/browser_gpu_memory_buffer_manager.h8
-rw-r--r--content/browser/gpu/gpu_process_host.cc4
-rw-r--r--content/browser/gpu/gpu_process_host.h6
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc4
-rw-r--r--content/browser/renderer_host/render_message_filter.cc4
-rw-r--r--content/browser/renderer_host/render_message_filter.h6
-rw-r--r--content/child/child_gpu_memory_buffer_manager.cc13
-rw-r--r--content/child/child_gpu_memory_buffer_manager.h4
-rw-r--r--content/common/child_process_host_impl.cc2
-rw-r--r--content/common/child_process_host_impl.h6
-rw-r--r--content/common/child_process_messages.h3
-rw-r--r--content/common/gpu/client/command_buffer_proxy_impl.cc55
-rw-r--r--content/common/gpu/client/command_buffer_proxy_impl.h4
-rw-r--r--content/common/gpu/client/gl_helper.cc6
-rw-r--r--content/common/gpu/client/gl_helper.h3
-rw-r--r--content/common/gpu/client/gpu_channel_host.cc5
-rw-r--r--content/common/gpu/client/gpu_channel_host.h2
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl.cc5
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl.h9
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc2
-rw-r--r--content/common/gpu/gpu_channel_manager.cc26
-rw-r--r--content/common/gpu/gpu_channel_manager.h5
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc16
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.h8
-rw-r--r--content/common/gpu/gpu_messages.h23
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc9
-rw-r--r--content/renderer/media/video_capture_impl.cc2
-rw-r--r--content/test/gpu_memory_buffer_impl_test_template.h2
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc1
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_manager.h6
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc85
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h4
-rw-r--r--gpu/command_buffer/service/sync_point_manager.cc23
-rw-r--r--gpu/command_buffer/service/sync_point_manager.h28
-rw-r--r--media/base/video_frame.cc2
-rw-r--r--media/base/video_frame.h2
-rw-r--r--media/base/video_frame_unittest.cc16
-rw-r--r--media/renderers/skcanvas_video_renderer.cc6
44 files changed, 315 insertions, 150 deletions
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index fd32212..3ef6e76 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -75,13 +75,14 @@ class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient {
const gpu::SyncToken& sync_token)
: gl_(gl), sync_token_(sync_token) {}
~SyncTokenClientImpl() override {}
- uint32 InsertSyncPoint() override {
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
if (sync_token_.HasData()) {
- DCHECK_EQ(gpu::CommandBufferNamespace::OLD_SYNC_POINTS,
- sync_token_.namespace_id());
- return static_cast<uint32>(sync_token_.release_count());
+ *sync_token = sync_token_;
+ } else {
+ const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
+ gl_->ShallowFlushCHROMIUM();
+ gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData());
}
- return gl_->InsertSyncPointCHROMIUM();
}
void WaitSyncToken(const gpu::SyncToken& sync_token) override {
if (sync_token.HasData()) {
diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc
index 352a75c..ed5e713 100644
--- a/cc/test/test_gpu_memory_buffer_manager.cc
+++ b/cc/test/test_gpu_memory_buffer_manager.cc
@@ -114,9 +114,8 @@ TestGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return reinterpret_cast<gfx::GpuMemoryBuffer*>(buffer);
}
-void TestGpuMemoryBufferManager::SetDestructionSyncPoint(
+void TestGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) {
-}
+ const gpu::SyncToken& sync_token) {}
} // namespace cc
diff --git a/cc/test/test_gpu_memory_buffer_manager.h b/cc/test/test_gpu_memory_buffer_manager.h
index a3720bf..85f642c 100644
--- a/cc/test/test_gpu_memory_buffer_manager.h
+++ b/cc/test/test_gpu_memory_buffer_manager.h
@@ -25,8 +25,8 @@ class TestGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
gfx::BufferFormat format) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
- void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) override;
+ void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) override;
private:
DISALLOW_COPY_AND_ASSIGN(TestGpuMemoryBufferManager);
diff --git a/components/mus/gles2/mojo_gpu_memory_buffer_manager.cc b/components/mus/gles2/mojo_gpu_memory_buffer_manager.cc
index 5de16a5..1f5c084 100644
--- a/components/mus/gles2/mojo_gpu_memory_buffer_manager.cc
+++ b/components/mus/gles2/mojo_gpu_memory_buffer_manager.cc
@@ -35,9 +35,9 @@ MojoGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return MojoGpuMemoryBufferImpl::FromClientBuffer(buffer);
}
-void MojoGpuMemoryBufferManager::SetDestructionSyncPoint(
+void MojoGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
NOTIMPLEMENTED();
}
diff --git a/components/mus/gles2/mojo_gpu_memory_buffer_manager.h b/components/mus/gles2/mojo_gpu_memory_buffer_manager.h
index b44c84c..6d4e235 100644
--- a/components/mus/gles2/mojo_gpu_memory_buffer_manager.h
+++ b/components/mus/gles2/mojo_gpu_memory_buffer_manager.h
@@ -25,8 +25,8 @@ class MojoGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
gfx::BufferFormat format) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
- void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) override;
+ void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) override;
private:
DISALLOW_COPY_AND_ASSIGN(MojoGpuMemoryBufferManager);
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
index fa61b00a..b7f36b6 100644
--- a/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -67,9 +67,9 @@ void HostCreateGpuMemoryBufferFromHandle(
void GpuMemoryBufferDeleted(
scoped_refptr<base::SingleThreadTaskRunner> destruction_task_runner,
const GpuMemoryBufferImpl::DestructionCallback& destruction_callback,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
destruction_task_runner->PostTask(
- FROM_HERE, base::Bind(destruction_callback, sync_point));
+ FROM_HERE, base::Bind(destruction_callback, sync_token));
}
bool IsNativeGpuMemoryBufferFactoryConfigurationSupported(
@@ -342,11 +342,11 @@ BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return GpuMemoryBufferImpl::FromClientBuffer(buffer);
}
-void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
+void BrowserGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
static_cast<GpuMemoryBufferImpl*>(buffer)
- ->set_destruction_sync_point(sync_point);
+ ->set_destruction_sync_token(sync_token);
}
bool BrowserGpuMemoryBufferManager::OnMemoryDump(
@@ -395,10 +395,10 @@ void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
base::ProcessHandle child_process_handle,
int child_client_id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DestroyGpuMemoryBufferOnIO(id, child_client_id, sync_point);
+ DestroyGpuMemoryBufferOnIO(id, child_client_id, sync_token);
}
void BrowserGpuMemoryBufferManager::ProcessRemoved(
@@ -419,7 +419,7 @@ void BrowserGpuMemoryBufferManager::ProcessRemoved(
GpuProcessHost* host = GpuProcessHost::FromID(buffer.second.gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(buffer.first, client_id, 0);
+ host->DestroyGpuMemoryBuffer(buffer.first, client_id, gpu::SyncToken());
}
clients_.erase(client_it);
@@ -654,7 +654,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
if (!handle.is_null()) {
GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(handle.id, client_id, 0);
+ host->DestroyGpuMemoryBuffer(handle.id, client_id, gpu::SyncToken());
}
callback.Run(gfx::GpuMemoryBufferHandle());
return;
@@ -706,7 +706,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
gfx::GpuMemoryBufferId id,
int client_id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(clients_.find(client_id) != clients_.end());
@@ -727,7 +727,7 @@ void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
GpuProcessHost* host = GpuProcessHost::FromID(buffer_it->second.gpu_host_id);
if (host)
- host->DestroyGpuMemoryBuffer(id, client_id, sync_point);
+ host->DestroyGpuMemoryBuffer(id, client_id, sync_token);
buffers.erase(buffer_it);
}
diff --git a/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/content/browser/gpu/browser_gpu_memory_buffer_manager.h
index 9cb9c43..09c8f73 100644
--- a/content/browser/gpu/browser_gpu_memory_buffer_manager.h
+++ b/content/browser/gpu/browser_gpu_memory_buffer_manager.h
@@ -65,8 +65,8 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
gfx::BufferFormat format) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
- void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) override;
+ void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) override;
// Overridden from base::trace_event::MemoryDumpProvider:
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
@@ -90,7 +90,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
gfx::GpuMemoryBufferId id,
base::ProcessHandle child_process_handle,
int child_client_id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
void ProcessRemoved(base::ProcessHandle process_handle, int client_id);
bool IsNativeGpuMemoryBufferConfiguration(gfx::BufferFormat format,
@@ -164,7 +164,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
const gfx::GpuMemoryBufferHandle& handle);
void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
int client_id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
uint64_t ClientIdToTracingProcessId(int client_id) const;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 9edf3ab..a3b56cc 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -766,12 +766,12 @@ void GpuProcessHost::CreateGpuMemoryBufferFromHandle(
void GpuProcessHost::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
int client_id,
- int sync_point) {
+ const gpu::SyncToken& sync_token) {
TRACE_EVENT0("gpu", "GpuProcessHost::DestroyGpuMemoryBuffer");
DCHECK(CalledOnValidThread());
- Send(new GpuMsg_DestroyGpuMemoryBuffer(id, client_id, sync_point));
+ Send(new GpuMsg_DestroyGpuMemoryBuffer(id, client_id, sync_token));
}
void GpuProcessHost::OnInitialized(bool result, const gpu::GPUInfo& gpu_info) {
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index 83e3410..245e330 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -40,6 +40,10 @@ namespace IPC {
struct ChannelHandle;
}
+namespace gpu {
+struct SyncToken;
+}
+
namespace content {
class BrowserChildProcessHostImpl;
class GpuMainThread;
@@ -148,7 +152,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Tells the GPU process to destroy GPU memory buffer.
void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
int client_id,
- int sync_point);
+ const gpu::SyncToken& sync_token);
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 50f3a5f..01a7772 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -45,7 +45,9 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
public:
explicit SyncTokenClientImpl(GLHelper* gl_helper) : gl_helper_(gl_helper) {}
~SyncTokenClientImpl() override {}
- uint32 InsertSyncPoint() override { return gl_helper_->InsertSyncPoint(); }
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
+ gl_helper_->GenerateSyncToken(sync_token);
+ }
void WaitSyncToken(const gpu::SyncToken& sync_token) override {
gl_helper_->WaitSyncToken(sync_token);
}
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 8861e37..9feac40 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -687,11 +687,11 @@ void RenderMessageFilter::GpuMemoryBufferAllocated(
void RenderMessageFilter::OnDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
DCHECK(BrowserGpuMemoryBufferManager::current());
BrowserGpuMemoryBufferManager::current()->ChildProcessDeletedGpuMemoryBuffer(
- id, PeerHandle(), render_process_id_, sync_point);
+ id, PeerHandle(), render_process_id_, sync_token);
}
} // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 2fdf7f6..da1f387 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -59,6 +59,10 @@ namespace gfx {
struct GpuMemoryBufferHandle;
}
+namespace gpu {
+struct SyncToken;
+}
+
namespace media {
class AudioManager;
struct MediaLogEvent;
@@ -210,7 +214,7 @@ class CONTENT_EXPORT RenderMessageFilter : public BrowserMessageFilter {
void GpuMemoryBufferAllocated(IPC::Message* reply,
const gfx::GpuMemoryBufferHandle& handle);
void OnDeletedGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
// Cached resource request dispatcher host, guaranteed to be non-null. We do
// not own it; it is managed by the BrowserProcess, which has a wider scope
diff --git a/content/child/child_gpu_memory_buffer_manager.cc b/content/child/child_gpu_memory_buffer_manager.cc
index 6eaf229..c83ceea 100644
--- a/content/child/child_gpu_memory_buffer_manager.cc
+++ b/content/child/child_gpu_memory_buffer_manager.cc
@@ -13,10 +13,10 @@ namespace {
void DeletedGpuMemoryBuffer(ThreadSafeSender* sender,
gfx::GpuMemoryBufferId id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
TRACE_EVENT0("renderer",
"ChildGpuMemoryBufferManager::DeletedGpuMemoryBuffer");
- sender->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(id, sync_point));
+ sender->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(id, sync_token));
}
} // namespace
@@ -52,7 +52,8 @@ ChildGpuMemoryBufferManager::AllocateGpuMemoryBuffer(const gfx::Size& size,
handle, size, format, usage,
base::Bind(&DeletedGpuMemoryBuffer, sender_, handle.id)));
if (!buffer) {
- sender_->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(handle.id, 0));
+ sender_->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(
+ handle.id, gpu::SyncToken()));
return nullptr;
}
@@ -74,11 +75,11 @@ ChildGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
return GpuMemoryBufferImpl::FromClientBuffer(buffer);
}
-void ChildGpuMemoryBufferManager::SetDestructionSyncPoint(
+void ChildGpuMemoryBufferManager::SetDestructionSyncToken(
gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
static_cast<GpuMemoryBufferImpl*>(buffer)
- ->set_destruction_sync_point(sync_point);
+ ->set_destruction_sync_token(sync_token);
}
} // namespace content
diff --git a/content/child/child_gpu_memory_buffer_manager.h b/content/child/child_gpu_memory_buffer_manager.h
index 2625853..1cdb945 100644
--- a/content/child/child_gpu_memory_buffer_manager.h
+++ b/content/child/child_gpu_memory_buffer_manager.h
@@ -26,8 +26,8 @@ class ChildGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
gfx::BufferFormat format) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;
- void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) override;
+ void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) override;
private:
scoped_refptr<ThreadSafeSender> sender_;
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc
index 707d644a..b7ce51b 100644
--- a/content/common/child_process_host_impl.cc
+++ b/content/common/child_process_host_impl.cc
@@ -317,7 +317,7 @@ void ChildProcessHostImpl::OnAllocateGpuMemoryBuffer(
void ChildProcessHostImpl::OnDeletedGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
// Note: Nothing to do here as ownership of shared memory backed
// GpuMemoryBuffers is passed with IPC.
}
diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h
index d859323..f07e2a8 100644
--- a/content/common/child_process_host_impl.h
+++ b/content/common/child_process_host_impl.h
@@ -28,6 +28,10 @@ namespace IPC {
class MessageFilter;
}
+namespace gpu {
+struct SyncToken;
+}
+
namespace content {
class ChildProcessHostDelegate;
@@ -101,7 +105,7 @@ class CONTENT_EXPORT ChildProcessHostImpl : public ChildProcessHost,
gfx::BufferUsage usage,
gfx::GpuMemoryBufferHandle* handle);
void OnDeletedGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- uint32 sync_point);
+ const gpu::SyncToken& sync_token);
ChildProcessHostDelegate* delegate_;
base::Process peer_process_;
diff --git a/content/common/child_process_messages.h b/content/common/child_process_messages.h
index 7e78e87..ec2a4bf 100644
--- a/content/common/child_process_messages.h
+++ b/content/common/child_process_messages.h
@@ -14,6 +14,7 @@
#include "cc/resources/shared_bitmap_manager.h"
#include "content/common/content_export.h"
#include "content/common/host_discardable_shared_memory_manager.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "ipc/ipc_message_macros.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
@@ -210,7 +211,7 @@ IPC_SYNC_MESSAGE_CONTROL5_1(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
// Informs the browser that the child deleted a gpu memory buffer.
IPC_MESSAGE_CONTROL2(ChildProcessHostMsg_DeletedGpuMemoryBuffer,
gfx::GpuMemoryBufferId,
- uint32 /* sync_point */)
+ gpu::SyncToken /* sync_token */)
// Asks the browser to create a block of discardable shared memory for the
// child process.
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index c3c8419..b8785bc 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -400,7 +400,7 @@ gpu::Capabilities CommandBufferProxyImpl::GetCapabilities() {
int32_t CommandBufferProxyImpl::CreateImage(ClientBuffer buffer,
size_t width,
size_t height,
- unsigned internalformat) {
+ unsigned internal_format) {
CheckLock();
if (last_state_.error != gpu::error::kNoError)
return -1;
@@ -416,29 +416,47 @@ int32_t CommandBufferProxyImpl::CreateImage(ClientBuffer buffer,
// This handle is owned by the GPU process and must be passed to it or it
// will leak. In otherwords, do not early out on error between here and the
// sending of the CreateImage IPC below.
- bool requires_sync_point = false;
+ bool requires_sync_token = false;
gfx::GpuMemoryBufferHandle handle =
channel_->ShareGpuMemoryBufferToGpuProcess(gpu_memory_buffer->GetHandle(),
- &requires_sync_point);
+ &requires_sync_token);
+
+ uint64_t image_fence_sync = 0;
+ if (requires_sync_token) {
+ image_fence_sync = GenerateFenceSyncRelease();
+
+ // Make sure fence syncs were flushed before CreateImage() was called.
+ DCHECK_LE(image_fence_sync - 1, flushed_fence_sync_release_);
+ }
DCHECK(gpu::ImageFactory::IsGpuMemoryBufferFormatSupported(
gpu_memory_buffer->GetFormat(), capabilities_));
DCHECK(gpu::ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat(
gfx::Size(width, height), gpu_memory_buffer->GetFormat()));
DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
- internalformat, gpu_memory_buffer->GetFormat()));
- if (!Send(new GpuCommandBufferMsg_CreateImage(route_id_,
- new_id,
- handle,
- gfx::Size(width, height),
- gpu_memory_buffer->GetFormat(),
- internalformat))) {
+ internal_format, gpu_memory_buffer->GetFormat()));
+
+ GpuCommandBufferMsg_CreateImage_Params params;
+ params.id = new_id;
+ params.gpu_memory_buffer = handle;
+ params.size = gfx::Size(width, height);
+ params.format = gpu_memory_buffer->GetFormat();
+ params.internal_format = internal_format;
+ params.image_release_count = image_fence_sync;
+
+ if (!Send(new GpuCommandBufferMsg_CreateImage(route_id_, params)))
return -1;
- }
- if (requires_sync_point) {
- gpu_memory_buffer_manager->SetDestructionSyncPoint(gpu_memory_buffer,
- InsertSyncPoint());
+ if (image_fence_sync) {
+ gpu::SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(),
+ image_fence_sync);
+
+ // Force a synchronous IPC to validate sync token.
+ channel_->ValidateFlushIDReachedServer(stream_id_, true);
+ sync_token.SetVerifyFlush();
+
+ gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer,
+ sync_token);
}
return new_id;
@@ -455,18 +473,18 @@ void CommandBufferProxyImpl::DestroyImage(int32 id) {
int32_t CommandBufferProxyImpl::CreateGpuMemoryBufferImage(
size_t width,
size_t height,
- unsigned internalformat,
+ unsigned internal_format,
unsigned usage) {
CheckLock();
scoped_ptr<gfx::GpuMemoryBuffer> buffer(
channel_->gpu_memory_buffer_manager()->AllocateGpuMemoryBuffer(
gfx::Size(width, height),
- gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat),
+ gpu::ImageFactory::DefaultBufferFormatForImageFormat(internal_format),
gfx::BufferUsage::SCANOUT));
if (!buffer)
return -1;
- return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
+ return CreateImage(buffer->AsClientBuffer(), width, height, internal_format);
}
uint32 CommandBufferProxyImpl::CreateStreamTexture(uint32 texture_id) {
@@ -530,7 +548,8 @@ bool CommandBufferProxyImpl::IsFenceSyncFlushReceived(uint64_t release) {
return true;
// Has not been validated, validate it now.
- UpdateVerifiedReleases(channel_->ValidateFlushIDReachedServer(stream_id_));
+ UpdateVerifiedReleases(
+ channel_->ValidateFlushIDReachedServer(stream_id_, false));
return release <= verified_fence_sync_release_;
}
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h
index 39bc76b..5646cca 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.h
+++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -106,11 +106,11 @@ class CommandBufferProxyImpl
int32 CreateImage(ClientBuffer buffer,
size_t width,
size_t height,
- unsigned internalformat) override;
+ unsigned internal_format) override;
void DestroyImage(int32 id) override;
int32 CreateGpuMemoryBufferImage(size_t width,
size_t height,
- unsigned internalformat,
+ unsigned internal_format,
unsigned usage) override;
uint32 InsertSyncPoint() override;
uint32_t InsertFutureSyncPoint() override;
diff --git a/content/common/gpu/client/gl_helper.cc b/content/common/gpu/client/gl_helper.cc
index 88c6499..33c9521 100644
--- a/content/common/gpu/client/gl_helper.cc
+++ b/content/common/gpu/client/gl_helper.cc
@@ -954,6 +954,12 @@ void GLHelper::DeleteTexture(GLuint texture_id) {
uint32 GLHelper::InsertSyncPoint() { return gl_->InsertSyncPointCHROMIUM(); }
+void GLHelper::GenerateSyncToken(gpu::SyncToken* sync_token) {
+ const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
+ gl_->ShallowFlushCHROMIUM();
+ gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData());
+}
+
void GLHelper::WaitSyncToken(const gpu::SyncToken& sync_token) {
gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
diff --git a/content/common/gpu/client/gl_helper.h b/content/common/gpu/client/gl_helper.h
index 828097d..c8224d4 100644
--- a/content/common/gpu/client/gl_helper.h
+++ b/content/common/gpu/client/gl_helper.h
@@ -247,6 +247,9 @@ class CONTENT_EXPORT GLHelper {
// Insert a sync point into the GL command buffer.
uint32 InsertSyncPoint();
+ // Inserts a fence sync, flushes, and generates a sync token.
+ void GenerateSyncToken(gpu::SyncToken* sync_token);
+
// Wait for the sync token before executing further GL commands.
void WaitSyncToken(const gpu::SyncToken& sync_token);
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
index 30700df..8ff3ab8 100644
--- a/content/common/gpu/client/gpu_channel_host.cc
+++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -398,7 +398,8 @@ int32 GpuChannelHost::GenerateStreamID() {
return next_stream_id_.GetNext();
}
-uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32 stream_id) {
+uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32 stream_id,
+ bool force_validate) {
// Store what flush ids we will be validating for all streams.
base::hash_map<int32, uint32_t> validate_flushes;
uint32_t flushed_stream_flush_id = 0;
@@ -421,7 +422,7 @@ uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32 stream_id) {
}
}
- if (flushed_stream_flush_id == verified_stream_flush_id) {
+ if (!force_validate && flushed_stream_flush_id == verified_stream_flush_id) {
// Current stream has no unverified flushes.
return verified_stream_flush_id;
}
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index a161a78..b5488ed9 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -190,7 +190,7 @@ class GpuChannelHost : public IPC::Sender,
// If the validation fails (which can only happen upon context lost), the
// highest validated flush id will not change. If no flush ID were ever
// validated then it will return 0 (Note the lowest valid flush ID is 1).
- uint32_t ValidateFlushIDReachedServer(int32 stream_id);
+ uint32_t ValidateFlushIDReachedServer(int32 stream_id, bool force_validate);
// Returns the highest validated flush ID for a given stream.
uint32_t GetHighestValidatedFlushID(int32 stream_id);
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.cc b/content/common/gpu/client/gpu_memory_buffer_impl.cc
index bfe4656..e900829 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.cc
@@ -29,12 +29,11 @@ GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id,
size_(size),
format_(format),
callback_(callback),
- mapped_(false),
- destruction_sync_point_(0) {}
+ mapped_(false) {}
GpuMemoryBufferImpl::~GpuMemoryBufferImpl() {
DCHECK(!mapped_);
- callback_.Run(destruction_sync_point_);
+ callback_.Run(destruction_sync_token_);
}
// static
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.h b/content/common/gpu/client/gpu_memory_buffer_impl.h
index 44b528e..a3ba3f5 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.h
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -16,7 +17,7 @@ namespace content {
// Provides common implementation of a GPU memory buffer.
class CONTENT_EXPORT GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
public:
- typedef base::Callback<void(uint32 sync_point)> DestructionCallback;
+ typedef base::Callback<void(const gpu::SyncToken& sync)> DestructionCallback;
~GpuMemoryBufferImpl() override;
@@ -40,8 +41,8 @@ class CONTENT_EXPORT GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
gfx::GpuMemoryBufferId GetId() const override;
ClientBuffer AsClientBuffer() override;
- void set_destruction_sync_point(uint32 sync_point) {
- destruction_sync_point_ = sync_point;
+ void set_destruction_sync_token(const gpu::SyncToken& sync_token) {
+ destruction_sync_token_ = sync_token;
}
protected:
@@ -55,7 +56,7 @@ class CONTENT_EXPORT GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
const gfx::BufferFormat format_;
const DestructionCallback callback_;
bool mapped_;
- uint32 destruction_sync_point_;
+ gpu::SyncToken destruction_sync_token_;
private:
DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl);
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
index cce258b..251e16c 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory_unittest.cc
@@ -12,7 +12,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSharedMemory,
GpuMemoryBufferImplTest,
GpuMemoryBufferImplSharedMemory);
-void BufferDestroyed(bool* destroyed, uint32 sync_point) {
+void BufferDestroyed(bool* destroyed, const gpu::SyncToken& sync_token) {
*destroyed = true;
}
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc
index 4d9c435..3f603a6 100644
--- a/content/common/gpu/gpu_channel_manager.cc
+++ b/content/common/gpu/gpu_channel_manager.cc
@@ -60,6 +60,7 @@ GpuChannelManager::GpuChannelManager(
this,
GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
sync_point_manager_(sync_point_manager),
+ sync_point_client_waiter_(new gpu::SyncPointClientWaiter),
gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
weak_factory_(this) {
DCHECK(task_runner);
@@ -227,17 +228,22 @@ void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
void GpuChannelManager::OnDestroyGpuMemoryBuffer(
gfx::GpuMemoryBufferId id,
int client_id,
- int32 sync_point) {
- if (!sync_point) {
- DestroyGpuMemoryBuffer(id, client_id);
- } else {
- sync_point_manager()->AddSyncPointCallback(
- sync_point,
- base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
- base::Unretained(this),
- id,
- client_id));
+ const gpu::SyncToken& sync_token) {
+ if (sync_token.HasData()) {
+ scoped_refptr<gpu::SyncPointClientState> release_state =
+ sync_point_manager()->GetSyncPointClientState(
+ sync_token.namespace_id(), sync_token.command_buffer_id());
+ if (release_state) {
+ sync_point_client_waiter_->Wait(
+ release_state.get(), sync_token.release_count(),
+ base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
+ base::Unretained(this), id, client_id));
+ return;
+ }
}
+
+ // No sync token or invalid sync token, destroy immediately.
+ DestroyGpuMemoryBuffer(id, client_id);
}
void GpuChannelManager::OnUpdateValueState(
diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h
index 19cec9d..c3e889a 100644
--- a/content/common/gpu/gpu_channel_manager.h
+++ b/content/common/gpu/gpu_channel_manager.h
@@ -34,7 +34,9 @@ class GLShareGroup;
namespace gpu {
class PreemptionFlag;
+class SyncPointClientWaiter;
class SyncPointManager;
+struct SyncToken;
union ValueState;
namespace gles2 {
class FramebufferCompletenessCache;
@@ -156,7 +158,7 @@ class CONTENT_EXPORT GpuChannelManager : public IPC::Listener,
void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id, int client_id);
void OnDestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
int client_id,
- int32 sync_point);
+ const gpu::SyncToken& sync_token);
void OnUpdateValueState(int client_id,
unsigned int target,
@@ -182,6 +184,7 @@ class CONTENT_EXPORT GpuChannelManager : public IPC::Listener,
GpuMemoryManager gpu_memory_manager_;
// SyncPointManager guaranteed to outlive running MessageLoop.
gpu::SyncPointManager* sync_point_manager_;
+ scoped_ptr<gpu::SyncPointClientWaiter> sync_point_client_waiter_;
scoped_ptr<gpu::gles2::ProgramCache> program_cache_;
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index b82d715..a26854f 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -1107,12 +1107,15 @@ void GpuCommandBufferStub::OnWaitFenceSyncCompleted(
scheduler_->SetScheduled(true);
}
-void GpuCommandBufferStub::OnCreateImage(int32 id,
- gfx::GpuMemoryBufferHandle handle,
- gfx::Size size,
- gfx::BufferFormat format,
- uint32 internalformat) {
+void GpuCommandBufferStub::OnCreateImage(
+ const GpuCommandBufferMsg_CreateImage_Params& params) {
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateImage");
+ const int32_t id = params.id;
+ const gfx::GpuMemoryBufferHandle& handle = params.gpu_memory_buffer;
+ const gfx::Size& size = params.size;
+ const gfx::BufferFormat& format = params.format;
+ const uint32_t internalformat = params.internal_format;
+ const uint64_t image_release_count = params.image_release_count;
if (!decoder_)
return;
@@ -1148,6 +1151,9 @@ void GpuCommandBufferStub::OnCreateImage(int32 id,
return;
image_manager->AddImage(image.get(), id);
+ if (image_release_count) {
+ sync_point_client_->ReleaseFenceSync(image_release_count);
+ }
}
void GpuCommandBufferStub::OnDestroyImage(int32 id) {
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index 910cd91..0537c30 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -44,6 +44,8 @@ class SubscriptionRefSet;
}
}
+struct GpuCommandBufferMsg_CreateImage_Params;
+
namespace content {
class GpuChannel;
@@ -214,11 +216,7 @@ class GpuCommandBufferStub
uint64_t command_buffer_id,
uint64_t release);
- void OnCreateImage(int32 id,
- gfx::GpuMemoryBufferHandle handle,
- gfx::Size size,
- gfx::BufferFormat format,
- uint32 internalformat);
+ void OnCreateImage(const GpuCommandBufferMsg_CreateImage_Params& params);
void OnDestroyImage(int32 id);
void OnCreateStreamTexture(uint32 texture_id,
int32 stream_id,
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index 949ecf9..a9c84a4 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -184,7 +184,16 @@ IPC_STRUCT_BEGIN(GpuStreamTextureMsg_MatrixChanged_Params)
IPC_STRUCT_END()
#endif
- IPC_STRUCT_TRAITS_BEGIN(gpu::DxDiagNode)
+IPC_STRUCT_BEGIN(GpuCommandBufferMsg_CreateImage_Params)
+ IPC_STRUCT_MEMBER(int32, id)
+ IPC_STRUCT_MEMBER(gfx::GpuMemoryBufferHandle, gpu_memory_buffer)
+ IPC_STRUCT_MEMBER(gfx::Size, size)
+ IPC_STRUCT_MEMBER(gfx::BufferFormat, format)
+ IPC_STRUCT_MEMBER(uint32, internal_format)
+ IPC_STRUCT_MEMBER(uint64, image_release_count)
+IPC_STRUCT_END()
+
+IPC_STRUCT_TRAITS_BEGIN(gpu::DxDiagNode)
IPC_STRUCT_TRAITS_MEMBER(values)
IPC_STRUCT_TRAITS_MEMBER(children)
IPC_STRUCT_TRAITS_END()
@@ -331,8 +340,8 @@ IPC_MESSAGE_CONTROL1(GpuMsg_CreateGpuMemoryBufferFromHandle,
// Tells the GPU process to destroy buffer.
IPC_MESSAGE_CONTROL3(GpuMsg_DestroyGpuMemoryBuffer,
gfx::GpuMemoryBufferId, /* id */
- int32, /* client_id */
- int32 /* sync_point */)
+ int32, /* client_id */
+ gpu::SyncToken /* sync_token */)
// Create and initialize a hardware jpeg decoder using the specified route_id.
// Created decoders should be freed with AcceleratedJpegDecoderMsg_Destroy when
@@ -652,12 +661,8 @@ IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_SignalAck,
// Create an image from an existing gpu memory buffer. The id that can be
// used to identify the image from a command buffer.
-IPC_MESSAGE_ROUTED5(GpuCommandBufferMsg_CreateImage,
- int32 /* id */,
- gfx::GpuMemoryBufferHandle /* gpu_memory_buffer */,
- gfx::Size /* size */,
- gfx::BufferFormat /* format */,
- uint32 /* internalformat */)
+IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_CreateImage,
+ GpuCommandBufferMsg_CreateImage_Params /* params */)
// Destroy a previously created image.
IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_DestroyImage,
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index e732515..ceecc08 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -136,11 +136,10 @@ class SyncTokenClientImpl : public media::VideoFrame::SyncTokenClient {
blink::WebGraphicsContext3D* web_graphics_context)
: web_graphics_context_(web_graphics_context) {}
~SyncTokenClientImpl() override {}
- uint32 InsertSyncPoint() override {
- gpu::SyncToken sync_token;
- if (!web_graphics_context_->insertSyncPoint(sync_token.GetData()))
- return 0;
- return static_cast<uint32>(sync_token.release_count());
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
+ if (!web_graphics_context_->insertSyncPoint(sync_token->GetData())) {
+ sync_token->Clear();
+ }
}
void WaitSyncToken(const gpu::SyncToken& sync_token) override {
web_graphics_context_->waitSyncToken(sync_token.GetConstData());
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index 174344d..3349590 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -100,7 +100,7 @@ class VideoCaptureImpl::ClientBuffer2
buffer->Unmap();
}
- void DestroyGpuMemoryBuffer(uint32 sync_point) {}
+ void DestroyGpuMemoryBuffer(const gpu::SyncToken& sync_token) {}
const std::vector<gfx::GpuMemoryBufferHandle> handles_;
const gfx::Size size_;
diff --git a/content/test/gpu_memory_buffer_impl_test_template.h b/content/test/gpu_memory_buffer_impl_test_template.h
index a91589f..73cce9e 100644
--- a/content/test/gpu_memory_buffer_impl_test_template.h
+++ b/content/test/gpu_memory_buffer_impl_test_template.h
@@ -32,7 +32,7 @@ class GpuMemoryBufferImplTest : public testing::Test {
private:
void FreeGpuMemoryBuffer(const base::Closure& free_callback,
bool* destroyed,
- uint32 sync_point) {
+ const gpu::SyncToken& sync_token) {
free_callback.Run();
if (destroyed)
*destroyed = true;
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 4fcb0b3..d1258e87 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -5522,6 +5522,7 @@ GLuint GLES2Implementation::CreateImageCHROMIUMHelper(ClientBuffer buffer,
return 0;
}
+ ShallowFlushCHROMIUM();
int32_t image_id =
gpu_control_->CreateImage(buffer, width, height, internalformat);
if (image_id < 0) {
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_manager.h b/gpu/command_buffer/client/gpu_memory_buffer_manager.h
index 9502b28..c95f841 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_manager.h
+++ b/gpu/command_buffer/client/gpu_memory_buffer_manager.h
@@ -12,6 +12,8 @@
namespace gpu {
+struct SyncToken;
+
class GPU_EXPORT GpuMemoryBufferManager {
public:
GpuMemoryBufferManager();
@@ -34,8 +36,8 @@ class GPU_EXPORT GpuMemoryBufferManager {
ClientBuffer buffer) = 0;
// Associates destruction sync point with |buffer|.
- virtual void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
- uint32 sync_point) = 0;
+ virtual void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer,
+ const gpu::SyncToken& sync_token) = 0;
protected:
virtual ~GpuMemoryBufferManager();
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index b3b1b12..5e1921a 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -65,6 +65,21 @@ static void RunTaskWithResult(base::Callback<T(void)> task,
completion->Signal();
}
+struct ScopedOrderNumberProcessor {
+ ScopedOrderNumberProcessor(SyncPointOrderData* order_data, uint32_t order_num)
+ : order_data_(order_data), order_num_(order_num) {
+ order_data_->BeginProcessingOrderNumber(order_num_);
+ }
+
+ ~ScopedOrderNumberProcessor() {
+ order_data_->FinishProcessingOrderNumber(order_num_);
+ }
+
+ private:
+ SyncPointOrderData* order_data_;
+ uint32_t order_num_;
+};
+
struct GpuInProcessThreadHolder {
GpuInProcessThreadHolder()
: sync_point_manager(new SyncPointManager(false)),
@@ -497,22 +512,24 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset,
ScopedEvent handle_flush(&flush_event_);
base::AutoLock lock(command_buffer_lock_);
- sync_point_order_data_->BeginProcessingOrderNumber(order_num);
- command_buffer_->Flush(put_offset);
{
- // Update state before signaling the flush event.
- base::AutoLock lock(state_after_last_flush_lock_);
- state_after_last_flush_ = command_buffer_->GetLastState();
+ ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(),
+ order_num);
+ command_buffer_->Flush(put_offset);
+ {
+ // Update state before signaling the flush event.
+ base::AutoLock lock(state_after_last_flush_lock_);
+ state_after_last_flush_ = command_buffer_->GetLastState();
+ }
+ DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) ||
+ (error::IsError(state_after_last_flush_.error) && context_lost_));
+
+ // Currently the in process command buffer does not support being
+ // descheduled, if it does we would need to back off on calling the finish
+ // processing number function until the message is rescheduled and finished
+ // processing. This DCHECK is to enforce this.
+ DCHECK(context_lost_ || put_offset == state_after_last_flush_.get_offset);
}
- DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) ||
- (error::IsError(state_after_last_flush_.error) && context_lost_));
-
- // Currently the in process command buffer does not support being descheduled,
- // if it does we would need to back off on calling the finish processing
- // order number function until the message is rescheduled and finished
- // processing. This DCHECK is to enforce this.
- DCHECK(context_lost_ || put_offset == state_after_last_flush_.get_offset);
- sync_point_order_data_->FinishProcessingOrderNumber(order_num);
// If we've processed all pending commands but still have pending queries,
// pump idle work until the query is passed.
@@ -668,17 +685,29 @@ int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer,
ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(),
&requires_sync_point);
- QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread,
- base::Unretained(this),
- new_id,
- handle,
- gfx::Size(width, height),
- gpu_memory_buffer->GetFormat(),
- internalformat));
+ SyncPointManager* sync_manager = service_->sync_point_manager();
+ const uint32_t order_num =
+ sync_point_order_data_->GenerateUnprocessedOrderNumber(sync_manager);
+ uint64_t fence_sync = 0;
if (requires_sync_point) {
- gpu_memory_buffer_manager_->SetDestructionSyncPoint(gpu_memory_buffer,
- InsertSyncPoint());
+ fence_sync = GenerateFenceSyncRelease();
+
+ // Previous fence syncs should be flushed already.
+ DCHECK_EQ(fence_sync - 1, flushed_fence_sync_release_);
+ }
+
+ QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread,
+ base::Unretained(this), new_id, handle,
+ gfx::Size(width, height), gpu_memory_buffer->GetFormat(),
+ internalformat, order_num, fence_sync));
+
+ if (fence_sync) {
+ flushed_fence_sync_release_ = fence_sync;
+ SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), fence_sync);
+ sync_token.SetVerifyFlush();
+ gpu_memory_buffer_manager_->SetDestructionSyncToken(gpu_memory_buffer,
+ sync_token);
}
return new_id;
@@ -689,7 +718,11 @@ void InProcessCommandBuffer::CreateImageOnGpuThread(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format,
- uint32 internalformat) {
+ uint32 internalformat,
+ uint32_t order_num,
+ uint64_t fence_sync) {
+ ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(),
+ order_num);
if (!decoder_)
return;
@@ -733,6 +766,10 @@ void InProcessCommandBuffer::CreateImageOnGpuThread(
break;
}
}
+
+ if (fence_sync) {
+ sync_point_client_->ReleaseFenceSync(fence_sync);
+ }
}
void InProcessCommandBuffer::DestroyImage(int32 id) {
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 83318b5..0c881c1 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -230,7 +230,9 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::BufferFormat format,
- uint32 internalformat);
+ uint32 internalformat,
+ uint32_t order_num,
+ uint64_t fence_sync);
void DestroyImageOnGpuThread(int32 id);
void SetGetBufferOnGpuThread(int32 shm_id, base::WaitableEvent* completion);
diff --git a/gpu/command_buffer/service/sync_point_manager.cc b/gpu/command_buffer/service/sync_point_manager.cc
index bc73adb..3fa7539 100644
--- a/gpu/command_buffer/service/sync_point_manager.cc
+++ b/gpu/command_buffer/service/sync_point_manager.cc
@@ -282,6 +282,29 @@ SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager,
namespace_id_(namespace_id),
client_id_(client_id) {}
+bool SyncPointClientWaiter::Wait(SyncPointClientState* release_state,
+ uint64_t release_count,
+ const base::Closure& wait_complete_callback) {
+ // No order number associated with the current execution context, using
+ // UINT32_MAX will just assume the release is in the SyncPointClientState's
+ // order numbers to be executed.
+ if (!release_state->WaitForRelease(UINT32_MAX, release_count,
+ wait_complete_callback)) {
+ wait_complete_callback.Run();
+ return false;
+ }
+ return true;
+}
+
+bool SyncPointClientWaiter::WaitNonThreadSafe(
+ SyncPointClientState* release_state,
+ uint64_t release_count,
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
+ const base::Closure& wait_complete_callback) {
+ return Wait(release_state, release_count,
+ base::Bind(&RunOnThread, runner, wait_complete_callback));
+}
+
SyncPointManager::SyncPointManager(bool allow_threaded_wait)
: allow_threaded_wait_(allow_threaded_wait),
// To reduce the risk that a sync point created in a previous GPU process
diff --git a/gpu/command_buffer/service/sync_point_manager.h b/gpu/command_buffer/service/sync_point_manager.h
index a72566b..c71b471 100644
--- a/gpu/command_buffer/service/sync_point_manager.h
+++ b/gpu/command_buffer/service/sync_point_manager.h
@@ -13,6 +13,7 @@
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/condition_variable.h"
@@ -137,6 +138,7 @@ class GPU_EXPORT SyncPointClientState
private:
friend class base::RefCountedThreadSafe<SyncPointClientState>;
friend class SyncPointClient;
+ friend class SyncPointClientWaiter;
friend class SyncPointOrderData;
struct ReleaseCallback {
@@ -232,6 +234,32 @@ class GPU_EXPORT SyncPointClient {
DISALLOW_COPY_AND_ASSIGN(SyncPointClient);
};
+// A SyncPointClientWaiter is a Sync Point Client which can only wait and on
+// fence syncs and not release any fence syncs itself. Because they cannot
+// release any fence syncs they do not need an associated order number since
+// deadlocks cannot happen. Note that it is important that this class does
+// not exist in the same execution context as a SyncPointClient, or else a
+// deadlock could occur. Basically, SyncPointClientWaiter::Wait() should never
+// be called between SyncPointOrderData::BeginProcessingOrderNumber() and
+// SyncPointOrderData::FinishProcessingOrderNumber() on the same thread.
+class GPU_EXPORT SyncPointClientWaiter {
+ public:
+ SyncPointClientWaiter() {}
+ ~SyncPointClientWaiter() {}
+
+ bool Wait(SyncPointClientState* release_state,
+ uint64_t release_count,
+ const base::Closure& wait_complete_callback);
+
+ bool WaitNonThreadSafe(SyncPointClientState* release_state,
+ uint64_t release_count,
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
+ const base::Closure& wait_complete_callback);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyncPointClientWaiter);
+};
+
// This class manages the sync points, which allow cross-channel
// synchronization.
class GPU_EXPORT SyncPointManager {
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index f73d5ac..f14e91f 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -813,7 +813,7 @@ void VideoFrame::UpdateReleaseSyncToken(SyncTokenClient* client) {
// occurred when it waits on |release_sync_token_|.
if (release_sync_token_.HasData())
client->WaitSyncToken(release_sync_token_);
- release_sync_token_ = gpu::SyncToken(client->InsertSyncPoint());
+ client->GenerateSyncToken(&release_sync_token_);
}
// static
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 717649e..a6ff33a 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -80,7 +80,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
class SyncTokenClient {
public:
SyncTokenClient() {}
- virtual uint32 InsertSyncPoint() = 0;
+ virtual void GenerateSyncToken(gpu::SyncToken* sync_token) = 0;
virtual void WaitSyncToken(const gpu::SyncToken& sync_token) = 0;
protected:
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index c9f05ec..ee2a454 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -269,7 +269,7 @@ static void TextureCallback(gpu::SyncToken* called_sync_token,
// Verify the gpu::MailboxHolder::ReleaseCallback is called when VideoFrame is
// destroyed with the default release sync point.
TEST(VideoFrame, TextureNoLongerNeededCallbackIsCalled) {
- gpu::SyncToken called_sync_token(1);
+ gpu::SyncToken called_sync_token(gpu::CommandBufferNamespace::GPU_IO, 1, 1);
{
scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTexture(
@@ -296,8 +296,8 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
explicit SyncTokenClientImpl(const gpu::SyncToken& sync_token)
: sync_token_(sync_token) {}
~SyncTokenClientImpl() override {}
- uint32 InsertSyncPoint() override {
- return static_cast<uint32>(sync_token_.release_count());
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
+ *sync_token = sync_token_;
}
void WaitSyncToken(const gpu::SyncToken& sync_token) override {}
@@ -313,14 +313,20 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
TEST(VideoFrame,
TexturesNoLongerNeededCallbackAfterTakingAndReleasingMailboxes) {
const int kPlanesNum = 3;
+ const gpu::CommandBufferNamespace kNamespace =
+ gpu::CommandBufferNamespace::GPU_IO;
+ const uint64_t kCommandBufferId = 0x123;
gpu::Mailbox mailbox[kPlanesNum];
for (int i = 0; i < kPlanesNum; ++i) {
mailbox[i].name[0] = 50 + 1;
}
- gpu::SyncToken sync_token(7);
+ gpu::SyncToken sync_token(kNamespace, kCommandBufferId, 7);
+ sync_token.SetVerifyFlush();
uint32 target = 9;
- gpu::SyncToken release_sync_token(111);
+ gpu::SyncToken release_sync_token(kNamespace, kCommandBufferId, 111);
+ release_sync_token.SetVerifyFlush();
+
gpu::SyncToken called_sync_token;
{
scoped_refptr<VideoFrame> frame = VideoFrame::WrapYUV420NativeTextures(
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc
index 675839b..d2f25d6 100644
--- a/media/renderers/skcanvas_video_renderer.cc
+++ b/media/renderers/skcanvas_video_renderer.cc
@@ -63,7 +63,11 @@ class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
public:
explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {}
~SyncTokenClientImpl() override {}
- uint32 InsertSyncPoint() override { return gl_->InsertSyncPointCHROMIUM(); }
+ void GenerateSyncToken(gpu::SyncToken* sync_token) override {
+ const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
+ gl_->ShallowFlushCHROMIUM();
+ gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token->GetData());
+ }
void WaitSyncToken(const gpu::SyncToken& sync_token) override {
gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}