diff --git a/chromium/content/common/gpu/gpu_channel_manager.cc b/chromium/content/common/gpu/gpu_channel_manager.cc
index 2c93ef449102e6772691f4dae088726d5fea56b1..97bbbbb0b813607f3df103e1b45bc4ad59769084 100644
--- a/chromium/content/common/gpu/gpu_channel_manager.cc
+++ b/chromium/content/common/gpu/gpu_channel_manager.cc
@@ -56,6 +56,7 @@ GpuChannelManager::~GpuChannelManager() {
     default_offscreen_surface_ = NULL;
   }
   DCHECK(image_operations_.empty());
+  DCHECK(sync_point_gl_fences_.empty());
 }
 
 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
diff --git a/chromium/content/common/gpu/gpu_channel_manager.h b/chromium/content/common/gpu/gpu_channel_manager.h
index 4c23f8009d0c81f00102e3c3fcb46f8aefae311c..dcaf3f11c05df3ba8134dd2240eae50f695485de 100644
--- a/chromium/content/common/gpu/gpu_channel_manager.h
+++ b/chromium/content/common/gpu/gpu_channel_manager.h
@@ -27,6 +27,7 @@ class WaitableEvent;
 }
 
 namespace gfx {
+class GLFence;
 class GLShareGroup;
 struct GpuMemoryBufferHandle;
 }
@@ -97,6 +98,8 @@ class GpuChannelManager : public IPC::Listener,
   GpuChannel* LookupChannel(int32 client_id);
 
   SyncPointManager* sync_point_manager() { return sync_point_manager_.get(); }
+  typedef base::hash_map<uint32, gfx::GLFence*> SyncPointGLFences;
+  SyncPointGLFences sync_point_gl_fences_;
 
   gfx::GLSurface* GetDefaultOffscreenSurface();
 
diff --git a/chromium/content/common/gpu/gpu_command_buffer_stub.cc b/chromium/content/common/gpu/gpu_command_buffer_stub.cc
index 37f50a8cdf4c5b597c27a323d10d63d07bfffefd..84d611a8ce209f073e4ee40cab67675292ada5cb 100644
--- a/chromium/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/chromium/content/common/gpu/gpu_command_buffer_stub.cc
@@ -35,6 +35,7 @@
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/query_manager.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_fence.h"
 #include "ui/gl/gl_switches.h"
 
 #if defined(OS_WIN)
@@ -111,6 +112,15 @@ const int64 kHandleMoreWorkPeriodBusyMs = 1;
 // Prevents idle work from being starved.
 const int64 kMaxTimeSinceIdleMs = 10;
 
+void DestroyGLFence(GpuChannelManager::SyncPointGLFences &fences, uint32 sync_point)
+{
+  GpuChannelManager::SyncPointGLFences::iterator it = fences.find(sync_point);
+  if (it != fences.end()) {
+    delete it->second;
+    fences.erase(it);
+  }
+}
+
 }  // namespace
 
 GpuCommandBufferStub::GpuCommandBufferStub(
@@ -143,6 +153,7 @@ GpuCommandBufferStub::GpuCommandBufferStub(
       last_memory_allocation_valid_(false),
       watchdog_(watchdog),
       sync_point_wait_count_(0),
+      last_fence_sync_point_(0),
       delayed_work_scheduled_(false),
       previous_messages_processed_(0),
       active_url_(active_url),
@@ -194,7 +205,10 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
   if (decoder_.get() && message.type() != GpuCommandBufferMsg_Echo::ID &&
       message.type() != GpuCommandBufferMsg_WaitForTokenInRange::ID &&
       message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID &&
+#if !defined(TOOLKIT_QT)
+      // Qt needs the context to be current here to insert/destroy fences.
       message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
+#endif
       message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) {
     if (!MakeCurrent())
       return false;
@@ -402,6 +416,7 @@ void GpuCommandBufferStub::Destroy() {
                     OnWillDestroyStub());
 
   if (decoder_) {
+    DestroyGLFence(channel_->gpu_channel_manager()->sync_point_gl_fences_, last_fence_sync_point_);
     decoder_->Destroy(have_context);
     decoder_.reset();
   }
@@ -835,6 +850,23 @@ void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
   if (context_group_->mailbox_manager()->UsesSync() && MakeCurrent())
     context_group_->mailbox_manager()->PushTextureUpdates();
   GpuChannelManager* manager = channel_->gpu_channel_manager();
+
+#if defined(TOOLKIT_QT)
+  // Only keep the last fence alive to keep its temporary ownership in GpuCommandBufferStub
+  // simple in case where Qt would not pick this fence to eventually destroy it.
+  DestroyGLFence(manager->sync_point_gl_fences_, last_fence_sync_point_);
+  // We submitted all resource-producing GL commands, convert the logical sync point into a GL fence
+  // to allow Qt's GL context to wait for the results of commands submitted in this context using the
+  // sync point as reference.
+  scoped_ptr<gfx::GLFence> fence = scoped_ptr<gfx::GLFence>(gfx::GLFence::CreateWithoutFlush());
+  if (fence)
+    manager->sync_point_gl_fences_.insert(std::make_pair(sync_point, fence.release()));
+  // Flush regardless of the success of the fence creation to at least make sure that commands
+  // producing our textures are in the pipe before the scene graph inserts its own on the other thread.
+  glFlush();
+  last_fence_sync_point_ = sync_point;
+#endif
+
   manager->sync_point_manager()->RetireSyncPoint(sync_point);
 }
 
diff --git a/chromium/content/common/gpu/gpu_command_buffer_stub.h b/chromium/content/common/gpu/gpu_command_buffer_stub.h
index f660f1df3e89c77458a5e943466429c83b4c9050..d6dfb6fbba8bb8332672fc74a4dd7ba4da3101e2 100644
--- a/chromium/content/common/gpu/gpu_command_buffer_stub.h
+++ b/chromium/content/common/gpu/gpu_command_buffer_stub.h
@@ -266,6 +266,7 @@ class GpuCommandBufferStub
   // A queue of sync points associated with this stub.
   std::deque<uint32> sync_points_;
   int sync_point_wait_count_;
+  uint32 last_fence_sync_point_;
 
   bool delayed_work_scheduled_;
   uint64 previous_messages_processed_;
diff --git a/chromium/ui/gl/gl_fence.cc b/chromium/ui/gl/gl_fence.cc
index 073e6eea31465443db2bb2fad5b70b01a41378c2..69714e7d36e8bf107ba07cbd0b8bc2a683ffcb3e 100644
--- a/chromium/ui/gl/gl_fence.cc
+++ b/chromium/ui/gl/gl_fence.cc
@@ -33,6 +33,10 @@ class GLFenceNVFence: public gfx::GLFence {
     }
   }
 
+  virtual gfx::TransferableFence Transfer() OVERRIDE {
+    return gfx::TransferableFence();
+  }
+
   virtual bool HasCompleted() OVERRIDE {
     return !!glTestFenceNV(fence_);
   }
@@ -69,6 +73,16 @@ class GLFenceARBSync: public gfx::GLFence {
     }
   }
 
+  virtual gfx::TransferableFence Transfer() OVERRIDE {
+    gfx::TransferableFence ret;
+    if (sync_) {
+      ret.type = gfx::TransferableFence::ArbSync;
+      ret.arb.sync = sync_;
+      sync_ = 0;
+    }
+    return ret;
+  }
+
   virtual bool HasCompleted() OVERRIDE {
     // Handle the case where FenceSync failed.
     if (!sync_)
@@ -98,7 +112,8 @@ class GLFenceARBSync: public gfx::GLFence {
 
  private:
   virtual ~GLFenceARBSync() {
-    glDeleteSync(sync_);
+    if (sync_)
+      glDeleteSync(sync_);
   }
 
   GLsync sync_;
@@ -118,6 +133,15 @@ class EGLFenceSync : public gfx::GLFence {
     }
   }
 
+  virtual gfx::TransferableFence Transfer() OVERRIDE {
+    gfx::TransferableFence ret;
+    ret.type = gfx::TransferableFence::EglSync;
+    ret.egl.display = display_;
+    ret.egl.sync = sync_;
+    sync_ = 0;
+    return ret;
+  }
+
   virtual bool HasCompleted() OVERRIDE {
     EGLint value = 0;
     eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
diff --git a/chromium/ui/gl/gl_fence.h b/chromium/ui/gl/gl_fence.h
index 021f3456f132c831417cb80f0a9f90f3b1d8709d..1d4e4cb72a080a597b4a13a08b989a4369b3df22 100644
--- a/chromium/ui/gl/gl_fence.h
+++ b/chromium/ui/gl/gl_fence.h
@@ -8,8 +8,34 @@
 #include "base/basictypes.h"
 #include "ui/gl/gl_export.h"
 
+typedef void *EGLDisplay;
+typedef void *EGLSyncKHR;
+typedef struct __GLsync *GLsync;
+
 namespace gfx {
 
+union TransferableFence {
+    enum SyncType {
+        NoSync,
+        EglSync,
+        ArbSync
+    };
+    SyncType type;
+    struct {
+        SyncType type;
+        EGLDisplay display;
+        EGLSyncKHR sync;
+    } egl;
+    struct {
+        SyncType type;
+        GLsync sync;
+    } arb;
+
+    TransferableFence() : type(NoSync) { }
+    operator bool() { return type != NoSync; }
+    void reset() { type = NoSync; }
+};
+
 class GL_EXPORT GLFence {
  public:
   GLFence();
@@ -23,6 +49,8 @@ class GL_EXPORT GLFence {
   // context.
   static GLFence* CreateWithoutFlush();
 
+  virtual TransferableFence Transfer() = 0;
+
   virtual bool HasCompleted() = 0;
   virtual void ClientWait() = 0;