| Index: content/common/gpu/gpu_command_buffer_stub.h | 
| diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h | 
| index ed4724388ca7403be0717f4bb3f7f2c48c304565..db6eca4eb5d36760c70cbb6643dacff6af5b6c83 100644 | 
| --- a/content/common/gpu/gpu_command_buffer_stub.h | 
| +++ b/content/common/gpu/gpu_command_buffer_stub.h | 
| @@ -6,6 +6,8 @@ | 
| #define CONTENT_COMMON_GPU_GPU_COMMAND_BUFFER_STUB_H_ | 
|  | 
| #include <deque> | 
| +#include <functional> | 
| +#include <queue> | 
| #include <string> | 
| #include <vector> | 
|  | 
| @@ -18,6 +20,7 @@ | 
| #include "gpu/command_buffer/common/gpu_memory_allocation.h" | 
| #include "gpu/command_buffer/service/command_buffer_service.h" | 
| #include "gpu/command_buffer/service/context_group.h" | 
| +#include "gpu/command_buffer/service/fence_sync_manager.h" | 
| #include "gpu/command_buffer/service/gpu_scheduler.h" | 
| #include "ipc/ipc_listener.h" | 
| #include "ipc/ipc_sender.h" | 
| @@ -114,6 +117,9 @@ class GpuCommandBufferStub | 
|  | 
| gpu::gles2::GLES2Decoder* decoder() const { return decoder_.get(); } | 
| gpu::GpuScheduler* scheduler() const { return scheduler_.get(); } | 
| +  gpu::FenceSyncManager* fence_sync_manager() const { | 
| +    return fence_sync_manager_.get(); | 
| +  } | 
| GpuChannel* channel() const { return channel_; } | 
|  | 
| // Identifies the target surface. | 
| @@ -148,6 +154,9 @@ class GpuCommandBufferStub | 
|  | 
| void SetLatencyInfoCallback(const LatencyInfoCallback& callback); | 
|  | 
| +  // Make sure fence sync is released by the time the order number is processed. | 
| +  void ValidateFenceSyncRelease(uint32_t max_order_number, uint32_t release); | 
| + | 
| void MarkContextLost(); | 
|  | 
| const gpu::gles2::FeatureInfo* GetFeatureInfo() const; | 
| @@ -159,6 +168,11 @@ class GpuCommandBufferStub | 
| base::TimeDelta interval); | 
|  | 
| private: | 
| +  typedef std::pair<uint32_t, uint32_t> OrderFenceSync; | 
| +  typedef std::priority_queue<OrderFenceSync, | 
| +                              std::vector<OrderFenceSync>, | 
| +                              std::greater<OrderFenceSync>> OrderFenceQueue; | 
| + | 
| GpuMemoryManager* GetMemoryManager() const; | 
|  | 
| void Destroy(); | 
| @@ -210,6 +224,15 @@ class GpuCommandBufferStub | 
| void OnSignalSyncPointAck(uint32 id); | 
| void OnSignalQuery(uint32 query, uint32 id); | 
|  | 
| +  void OnFenceSenceRelease(uint32_t release); | 
| +  bool OnWaitFenceSync(int channel_client_id, | 
| +                       uint32_t route_id, | 
| +                       uint32_t release); | 
| +  void OnWaitFenceSyncCompleted(int channel_client_id, | 
| +                                uint32_t route_id, | 
| +                                uint32_t release); | 
| +  void OnOrderNumberReached(uint32_t order_number); | 
| + | 
| void OnSetClientHasMemoryAllocationChangedCallback(bool has_callback); | 
|  | 
| void OnCreateImage(int32 id, | 
| @@ -239,7 +262,7 @@ class GpuCommandBufferStub | 
|  | 
| bool CheckContextLost(); | 
| void CheckCompleteWaits(); | 
| -  void PullTextureUpdates(uint32 sync_point); | 
| +  void PullTextureUpdates(int channel_id, uint32_t route_id, uint32 release); | 
|  | 
| // The lifetime of objects of this class is managed by a GpuChannel. The | 
| // GpuChannels destroy all the GpuCommandBufferStubs that they own when they | 
| @@ -268,6 +291,7 @@ class GpuCommandBufferStub | 
| scoped_ptr<gpu::CommandBufferService> command_buffer_; | 
| scoped_ptr<gpu::gles2::GLES2Decoder> decoder_; | 
| scoped_ptr<gpu::GpuScheduler> scheduler_; | 
| +  scoped_ptr<gpu::FenceSyncManager> fence_sync_manager_; | 
| scoped_refptr<gfx::GLSurface> surface_; | 
|  | 
| scoped_ptr<GpuMemoryManagerClientState> memory_manager_client_state_; | 
| @@ -299,6 +323,16 @@ class GpuCommandBufferStub | 
| scoped_ptr<WaitForCommandState> wait_for_token_; | 
| scoped_ptr<WaitForCommandState> wait_for_get_offset_; | 
|  | 
| +  // In situations where we are waiting on fence syncs that do not exist, we | 
| +  // validate the channel which the fence sync should have occurred by making | 
| +  // sure the order number of that channel does not pass the order number which | 
| +  // the wait command was issued. If that channel's order number reaches the | 
| +  // wait command's order, we should automatically release up to the expected | 
| +  // release count. Note that this also releases other lower release counts, | 
| +  // so a single misbehaved fence sync is enough to invalidate/signal all | 
| +  // previous fence syncs. | 
| +  OrderFenceQueue order_fence_queue_; | 
| + | 
| DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub); | 
| }; | 
|  | 
|  |