GPU: Remove memory duplication in async uploads.

Now that gpu::Buffer is ref-counted, we can avoid duplicating
memory for security (to prevent use-after-free).

BUG=177063, 353822

Review URL: https://codereview.chromium.org/211493006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259807 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/async_pixel_transfer_delegate.cc b/gpu/command_buffer/service/async_pixel_transfer_delegate.cc
index 074f675..6b1dbc6 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_delegate.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_delegate.cc
@@ -4,26 +4,18 @@
 
 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
 
-#include "base/memory/shared_memory.h"
-#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
-
 namespace gpu {
 
-namespace {
-
-void* GetAddressImpl(base::SharedMemory* shared_memory,
-                     uint32 shm_size,
-                     uint32 shm_data_offset,
-                     uint32 shm_data_size) {
-  // Memory bounds have already been validated, so there
-  // are just DCHECKS here.
-  DCHECK(shared_memory);
-  DCHECK(shared_memory->memory());
-  DCHECK_LE(shm_data_offset + shm_data_size, shm_size);
-  return static_cast<int8*>(shared_memory->memory()) + shm_data_offset;
+AsyncMemoryParams::AsyncMemoryParams(scoped_refptr<Buffer> buffer,
+                    uint32 data_offset,
+                    uint32 data_size)
+    : buffer_(buffer), data_offset_(data_offset), data_size_(data_size) {
+  DCHECK(buffer_);
+  DCHECK(buffer_->memory());
 }
 
-}  // namespace
+AsyncMemoryParams::~AsyncMemoryParams() {
+}
 
 AsyncPixelTransferUploadStats::AsyncPixelTransferUploadStats()
     : texture_upload_count_(0) {}
@@ -44,27 +36,8 @@
   return texture_upload_count_;
 }
 
-AsyncPixelTransferDelegate::AsyncPixelTransferDelegate(){}
+AsyncPixelTransferDelegate::AsyncPixelTransferDelegate() {}
 
-AsyncPixelTransferDelegate::~AsyncPixelTransferDelegate(){}
-
-// static
-void* AsyncPixelTransferDelegate::GetAddress(
-    const AsyncMemoryParams& mem_params) {
-  return GetAddressImpl(mem_params.shared_memory,
-                        mem_params.shm_size,
-                        mem_params.shm_data_offset,
-                        mem_params.shm_data_size);
-}
-
-// static
-void* AsyncPixelTransferDelegate::GetAddress(
-    ScopedSafeSharedMemory* safe_shared_memory,
-    const AsyncMemoryParams& mem_params) {
-  return GetAddressImpl(safe_shared_memory->shared_memory(),
-                        mem_params.shm_size,
-                        mem_params.shm_data_offset,
-                        mem_params.shm_data_size);
-}
+AsyncPixelTransferDelegate::~AsyncPixelTransferDelegate() {}
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/async_pixel_transfer_delegate.h b/gpu/command_buffer/service/async_pixel_transfer_delegate.h
index dc0f2d7..47d71d8 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_delegate.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_delegate.h
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
+#include "gpu/command_buffer/common/buffer.h"
 #include "gpu/gpu_export.h"
 #include "ui/gl/gl_bindings.h"
 
@@ -44,11 +45,24 @@
   GLenum type;
 };
 
-struct AsyncMemoryParams {
-  base::SharedMemory* shared_memory;
-  uint32 shm_size;
-  uint32 shm_data_offset;
-  uint32 shm_data_size;
+class AsyncMemoryParams {
+ public:
+  AsyncMemoryParams(scoped_refptr<Buffer> buffer,
+                    uint32 data_offset,
+                    uint32 data_size);
+  ~AsyncMemoryParams();
+
+  scoped_refptr<Buffer> buffer() const { return buffer_; }
+  uint32 data_size() const { return data_size_; }
+  uint32 data_offset() const { return data_offset_; }
+  void* GetDataAddress() const {
+    return buffer_->GetDataAddress(data_offset_, data_size_);
+  }
+
+ private:
+  scoped_refptr<Buffer> buffer_;
+  uint32 data_offset_;
+  uint32 data_size_;
 };
 
 class AsyncPixelTransferUploadStats
@@ -92,13 +106,6 @@
   // Block until the specified transfer completes.
   virtual void WaitForTransferCompletion() = 0;
 
-  // Gets the address of the data from shared memory.
-  static void* GetAddress(const AsyncMemoryParams& mem_params);
-
-  // Sometimes the |safe_shared_memory| is duplicate to prevent use after free.
-  static void* GetAddress(ScopedSafeSharedMemory* safe_shared_memory,
-                          const AsyncMemoryParams& mem_params);
-
  protected:
   AsyncPixelTransferDelegate();
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager.h b/gpu/command_buffer/service/async_pixel_transfer_manager.h
index d0ea5da1..4b57619 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager.h
@@ -32,7 +32,7 @@
 
 namespace gpu {
 class AsyncPixelTransferDelegate;
-struct AsyncMemoryParams;
+class AsyncMemoryParams;
 struct AsyncTexImage2DParams;
 
 class AsyncPixelTransferCompletionObserver
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
index 3f3acc5..32fa4c04 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
@@ -16,7 +16,6 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread.h"
 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
-#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_surface_egl.h"
 #include "ui/gl/scoped_binders.h"
@@ -81,12 +80,9 @@
 
 void PerformNotifyCompletion(
     AsyncMemoryParams mem_params,
-    ScopedSafeSharedMemory* safe_shared_memory,
     scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
   TRACE_EVENT0("gpu", "PerformNotifyCompletion");
-  AsyncMemoryParams safe_mem_params = mem_params;
-  safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
-  observer->DidComplete(safe_mem_params);
+  observer->DidComplete(mem_params);
 }
 
 class TransferThread : public base::Thread {
@@ -117,16 +113,10 @@
     context_ = NULL;
   }
 
-  SafeSharedMemoryPool* safe_shared_memory_pool() {
-      return &safe_shared_memory_pool_;
-  }
-
  private:
   scoped_refptr<gfx::GLContext> context_;
   scoped_refptr<gfx::GLSurface> surface_;
 
-  SafeSharedMemoryPool safe_shared_memory_pool_;
-
   DISALLOW_COPY_AND_ASSIGN(TransferThread);
 };
 
@@ -137,10 +127,6 @@
   return g_transfer_thread.Pointer()->message_loop_proxy().get();
 }
 
-SafeSharedMemoryPool* safe_shared_memory_pool() {
-  return g_transfer_thread.Pointer()->safe_shared_memory_pool();
-}
-
 // Class which holds async pixel transfers state (EGLImage).
 // The EGLImage is accessed by either thread, but everything
 // else accessed only on the main thread.
@@ -254,7 +240,6 @@
   void PerformAsyncTexImage2D(
       AsyncTexImage2DParams tex_params,
       AsyncMemoryParams mem_params,
-      ScopedSafeSharedMemory* safe_shared_memory,
       scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
     TRACE_EVENT2("gpu",
                  "PerformAsyncTexImage",
@@ -269,8 +254,7 @@
       return;
     }
 
-    void* data =
-        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);
+    void* data = mem_params.GetDataAddress();
 
     base::TimeTicks begin_time;
     if (texture_upload_stats.get())
@@ -317,7 +301,6 @@
   void PerformAsyncTexSubImage2D(
       AsyncTexSubImage2DParams tex_params,
       AsyncMemoryParams mem_params,
-      ScopedSafeSharedMemory* safe_shared_memory,
       scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
     TRACE_EVENT2("gpu",
                  "PerformAsyncTexSubImage2D",
@@ -329,8 +312,7 @@
     DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
     DCHECK_EQ(0, tex_params.level);
 
-    void* data =
-        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);
+    void* data = mem_params.GetDataAddress();
 
     base::TimeTicks begin_time;
     if (texture_upload_stats.get())
@@ -509,9 +491,6 @@
   if (WorkAroundAsyncTexImage2D(tex_params, mem_params, bind_callback))
     return;
 
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   DCHECK(!state_->TransferIsInProgress());
   DCHECK_EQ(state_->egl_image_, EGL_NO_IMAGE_KHR);
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
@@ -533,9 +512,6 @@
           state_,
           tex_params,
           mem_params,
-          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                 mem_params.shared_memory,
-                                                 mem_params.shm_size)),
           shared_state_->texture_upload_stats));
 
   DCHECK(CHECK_GL());
@@ -550,9 +526,6 @@
   if (WorkAroundAsyncTexSubImage2D(tex_params, mem_params))
     return;
   DCHECK(!state_->TransferIsInProgress());
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
   DCHECK_EQ(tex_params.level, 0);
 
@@ -571,9 +544,6 @@
           state_,
           tex_params,
           mem_params,
-          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                 mem_params.shared_memory,
-                                                 mem_params.shm_size)),
           shared_state_->texture_upload_stats));
 
   DCHECK(CHECK_GL());
@@ -621,7 +591,7 @@
   // On imagination we allocate synchronously all the time, even
   // if the dimensions support fast uploads. This is for part a.)
   // above, so allocations occur on a different thread/context as uploads.
-  void* data = GetAddress(mem_params);
+  void* data = mem_params.GetDataAddress();
   SetGlParametersForEglImageTexture();
 
   {
@@ -672,7 +642,7 @@
   DCHECK_EQ(state_->define_params_.format, tex_params.format);
   DCHECK_EQ(state_->define_params_.type, tex_params.type);
 
-  void* data = GetAddress(mem_params);
+  void* data = mem_params.GetDataAddress();
   base::TimeTicks begin_time;
   if (shared_state_->texture_upload_stats.get())
     begin_time = base::TimeTicks::HighResNow();
@@ -733,19 +703,12 @@
 void AsyncPixelTransferManagerEGL::AsyncNotifyCompletion(
     const AsyncMemoryParams& mem_params,
     AsyncPixelTransferCompletionObserver* observer) {
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   // Post a PerformNotifyCompletion task to the upload thread. This task
   // will run after all async transfers are complete.
   transfer_message_loop_proxy()->PostTask(
       FROM_HERE,
       base::Bind(&PerformNotifyCompletion,
                  mem_params,
-                 base::Owned(
-                     new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                mem_params.shared_memory,
-                                                mem_params.shm_size)),
                  make_scoped_refptr(observer)));
 }
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
index dcd870d..58748dd 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
@@ -9,30 +9,19 @@
 #include "base/debug/trace_event_synthetic_delay.h"
 #include "base/lazy_instance.h"
 #include "base/memory/weak_ptr.h"
-#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
 #include "ui/gl/scoped_binders.h"
 
 namespace gpu {
 
 namespace {
 
-base::LazyInstance<SafeSharedMemoryPool> g_safe_shared_memory_pool =
-    LAZY_INSTANCE_INITIALIZER;
-
-SafeSharedMemoryPool* safe_shared_memory_pool() {
-  return g_safe_shared_memory_pool.Pointer();
-}
-
 static uint64 g_next_pixel_transfer_state_id = 1;
 
 void PerformNotifyCompletion(
     AsyncMemoryParams mem_params,
-    ScopedSafeSharedMemory* safe_shared_memory,
     scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
   TRACE_EVENT0("gpu", "PerformNotifyCompletion");
-  AsyncMemoryParams safe_mem_params = mem_params;
-  safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
-  observer->DidComplete(safe_mem_params);
+  observer->DidComplete(mem_params);
 }
 
 }  // namespace
@@ -61,15 +50,11 @@
   virtual void WaitForTransferCompletion() OVERRIDE;
 
  private:
-  void PerformAsyncTexImage2D(
-      AsyncTexImage2DParams tex_params,
-      AsyncMemoryParams mem_params,
-      const base::Closure& bind_callback,
-      ScopedSafeSharedMemory* safe_shared_memory);
-  void PerformAsyncTexSubImage2D(
-      AsyncTexSubImage2DParams tex_params,
-      AsyncMemoryParams mem_params,
-      ScopedSafeSharedMemory* safe_shared_memory);
+  void PerformAsyncTexImage2D(AsyncTexImage2DParams tex_params,
+                              AsyncMemoryParams mem_params,
+                              const base::Closure& bind_callback);
+  void PerformAsyncTexSubImage2D(AsyncTexSubImage2DParams tex_params,
+                                 AsyncMemoryParams mem_params);
 
   uint64 id_;
   GLuint texture_id_;
@@ -101,21 +86,14 @@
     const base::Closure& bind_callback) {
   TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
 
   shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
       id_,
-      base::Bind(
-          &AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
-          AsWeakPtr(),
-          tex_params,
-          mem_params,
-          bind_callback,
-          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                 mem_params.shared_memory,
-                                                 mem_params.shm_size)))));
+      base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
+                 AsWeakPtr(),
+                 tex_params,
+                 mem_params,
+                 bind_callback)));
 
   transfer_in_progress_ = true;
 }
@@ -125,20 +103,13 @@
     const AsyncMemoryParams& mem_params) {
   TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("gpu.AsyncTexImage");
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
 
   shared_state_->tasks.push_back(AsyncPixelTransferManagerIdle::Task(
       id_,
-      base::Bind(
-          &AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
-          AsWeakPtr(),
-          tex_params,
-          mem_params,
-          base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                 mem_params.shared_memory,
-                                                 mem_params.shm_size)))));
+      base::Bind(&AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
+                 AsWeakPtr(),
+                 tex_params,
+                 mem_params)));
 
   transfer_in_progress_ = true;
 }
@@ -166,13 +137,12 @@
 void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
     AsyncTexImage2DParams tex_params,
     AsyncMemoryParams mem_params,
-    const base::Closure& bind_callback,
-    ScopedSafeSharedMemory* safe_shared_memory) {
+    const base::Closure& bind_callback) {
   TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
                "width", tex_params.width,
                "height", tex_params.height);
 
-  void* data = GetAddress(safe_shared_memory, mem_params);
+  void* data = mem_params.GetDataAddress();
 
   base::TimeTicks begin_time(base::TimeTicks::HighResNow());
   gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
@@ -203,13 +173,12 @@
 
 void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
     AsyncTexSubImage2DParams tex_params,
-    AsyncMemoryParams mem_params,
-    ScopedSafeSharedMemory* safe_shared_memory) {
+    AsyncMemoryParams mem_params) {
   TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
                "width", tex_params.width,
                "height", tex_params.height);
 
-  void* data = GetAddress(safe_shared_memory, mem_params);
+  void* data = mem_params.GetDataAddress();
 
   base::TimeTicks begin_time(base::TimeTicks::HighResNow());
   gfx::ScopedTextureBinder texture_binder(tex_params.target, texture_id_);
@@ -301,9 +270,6 @@
            base::Bind(
                &PerformNotifyCompletion,
                mem_params,
-               base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                      mem_params.shared_memory,
-                                                      mem_params.shm_size)),
                make_scoped_refptr(observer))));
 }
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
index dcdab1c6..e670dc7 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
@@ -19,7 +19,6 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_checker.h"
 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
-#include "gpu/command_buffer/service/safe_shared_memory_pool.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_surface.h"
@@ -34,12 +33,9 @@
 
 void PerformNotifyCompletion(
     AsyncMemoryParams mem_params,
-    ScopedSafeSharedMemory* safe_shared_memory,
     scoped_refptr<AsyncPixelTransferCompletionObserver> observer) {
   TRACE_EVENT0("gpu", "PerformNotifyCompletion");
-  AsyncMemoryParams safe_mem_params = mem_params;
-  safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
-  observer->DidComplete(safe_mem_params);
+  observer->DidComplete(mem_params);
 }
 
 // TODO(backer): Factor out common thread scheduling logic from the EGL and
@@ -80,16 +76,11 @@
     context_ = NULL;
   }
 
-  SafeSharedMemoryPool* safe_shared_memory_pool() {
-    return &safe_shared_memory_pool_;
-  }
-
  private:
   bool initialized_;
 
   scoped_refptr<gfx::GLSurface> surface_;
   scoped_refptr<gfx::GLContext> context_;
-  SafeSharedMemoryPool safe_shared_memory_pool_;
 
   void InitializeOnTransferThread(gfx::GLContext* parent_context,
                                    base::WaitableEvent* caller_wait) {
@@ -136,10 +127,6 @@
   return g_transfer_thread.Pointer()->message_loop_proxy().get();
 }
 
-SafeSharedMemoryPool* safe_shared_memory_pool() {
-  return g_transfer_thread.Pointer()->safe_shared_memory_pool();
-}
-
 class PendingTask : public base::RefCountedThreadSafe<PendingTask> {
  public:
   explicit PendingTask(const base::Closure& task)
@@ -258,11 +245,6 @@
         this,
         tex_params,
         mem_params,
-        // Duplicate the shared memory so there is no way we can get
-        // a use-after-free of the raw pixels.
-        base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                               mem_params.shared_memory,
-                                               mem_params.shm_size)),
         texture_upload_stats));
     transfer_message_loop_proxy()->PostTask(
         FROM_HERE,
@@ -284,9 +266,6 @@
         this,
         tex_params,
         mem_params,
-        base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                               mem_params.shared_memory,
-                                               mem_params.shm_size)),
         texture_upload_stats));
     transfer_message_loop_proxy()->PostTask(
         FROM_HERE,
@@ -303,7 +282,6 @@
   void PerformAsyncTexImage2D(
       AsyncTexImage2DParams tex_params,
       AsyncMemoryParams mem_params,
-      ScopedSafeSharedMemory* safe_shared_memory,
       scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
     TRACE_EVENT2("gpu",
                  "PerformAsyncTexImage",
@@ -317,8 +295,7 @@
     if (texture_upload_stats.get())
       begin_time = base::TimeTicks::HighResNow();
 
-    void* data =
-        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);
+    void* data = mem_params.GetDataAddress();
 
     {
       TRACE_EVENT0("gpu", "glTexImage2D");
@@ -343,7 +320,6 @@
   void PerformAsyncTexSubImage2D(
       AsyncTexSubImage2DParams tex_params,
       AsyncMemoryParams mem_params,
-      ScopedSafeSharedMemory* safe_shared_memory,
       scoped_refptr<AsyncPixelTransferUploadStats> texture_upload_stats) {
     TRACE_EVENT2("gpu",
                  "PerformAsyncTexSubImage2D",
@@ -357,9 +333,7 @@
     if (texture_upload_stats.get())
       begin_time = base::TimeTicks::HighResNow();
 
-    void* data =
-        AsyncPixelTransferDelegate::GetAddress(safe_shared_memory, mem_params);
-
+    void* data = mem_params.GetDataAddress();
     {
       TRACE_EVENT0("gpu", "glTexSubImage2D");
       glTexSubImage2D(GL_TEXTURE_2D,
@@ -467,9 +441,6 @@
     const AsyncTexImage2DParams& tex_params,
     const AsyncMemoryParams& mem_params,
     const base::Closure& bind_callback) {
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   DCHECK(!state_->TransferIsInProgress());
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
   DCHECK_EQ(tex_params.level, 0);
@@ -488,9 +459,6 @@
                "width", tex_params.width,
                "height", tex_params.height);
   DCHECK(!state_->TransferIsInProgress());
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
   DCHECK_EQ(tex_params.level, 0);
 
@@ -539,19 +507,12 @@
 void AsyncPixelTransferManagerShareGroup::AsyncNotifyCompletion(
     const AsyncMemoryParams& mem_params,
     AsyncPixelTransferCompletionObserver* observer) {
-  DCHECK(mem_params.shared_memory);
-  DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
-            mem_params.shm_size);
   // Post a PerformNotifyCompletion task to the upload thread. This task
   // will run after all async transfers are complete.
   transfer_message_loop_proxy()->PostTask(
       FROM_HERE,
       base::Bind(&PerformNotifyCompletion,
                  mem_params,
-                 base::Owned(
-                     new ScopedSafeSharedMemory(safe_shared_memory_pool(),
-                                                mem_params.shared_memory,
-                                                mem_params.shm_size)),
                  make_scoped_refptr(observer)));
 }
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
index ffe55849..69e3c34 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
@@ -46,7 +46,7 @@
     const base::Closure& bind_callback) {
   // Save the define params to return later during deferred
   // binding of the transfer texture.
-  void* data = GetAddress(mem_params);
+  void* data = mem_params.GetDataAddress();
   base::TimeTicks begin_time(base::TimeTicks::HighResNow());
   glTexImage2D(
       tex_params.target,
@@ -68,7 +68,7 @@
 void AsyncPixelTransferDelegateSync::AsyncTexSubImage2D(
     const AsyncTexSubImage2DParams& tex_params,
     const AsyncMemoryParams& mem_params) {
-  void* data = GetAddress(mem_params);
+  void* data = mem_params.GetDataAddress();
   base::TimeTicks begin_time(base::TimeTicks::HighResNow());
   glTexSubImage2D(
       tex_params.target,
diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc
index 1462289..06cf3a4 100644
--- a/gpu/command_buffer/service/common_decoder.cc
+++ b/gpu/command_buffer/service/common_decoder.cc
@@ -61,17 +61,13 @@
 CommonDecoder::~CommonDecoder() {}
 
 void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id,
-                                            unsigned int offset,
-                                            unsigned int size) {
+                                            unsigned int data_offset,
+                                            unsigned int data_size) {
   CHECK(engine_);
   scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id);
   if (!buffer)
     return NULL;
-  unsigned int end = offset + size;
-  if (end > buffer->size() || end < offset) {
-    return NULL;
-  }
-  return static_cast<int8*>(buffer->memory()) + offset;
+  return buffer->GetDataAddress(data_offset, data_size);
 }
 
 scoped_refptr<gpu::Buffer> CommonDecoder::GetSharedMemoryBuffer(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 427227c..e6a12701 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -10392,20 +10392,12 @@
     return error::kNoError;
   }
 
-  // We know the memory/size is safe, so get the real shared memory since
-  // it might need to be duped to prevent use-after-free of the memory.
-  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
-  base::SharedMemory* shared_memory = buffer->shared_memory();
-  uint32 shm_size = buffer->size();
-  uint32 shm_data_offset = c.pixels_shm_offset;
-  uint32 shm_data_size = pixels_size;
-
   // Setup the parameters.
   AsyncTexImage2DParams tex_params = {
       target, level, static_cast<GLenum>(internal_format),
       width, height, border, format, type};
-  AsyncMemoryParams mem_params = {
-      shared_memory, shm_size, shm_data_offset, shm_data_size};
+  AsyncMemoryParams mem_params(
+      GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
 
   // Set up the async state if needed, and make the texture
   // immutable so the async state stays valid. The level info
@@ -10482,19 +10474,11 @@
     }
   }
 
-  // We know the memory/size is safe, so get the real shared memory since
-  // it might need to be duped to prevent use-after-free of the memory.
-  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(c.data_shm_id);
-  base::SharedMemory* shared_memory = buffer->shared_memory();
-  uint32 shm_size = buffer->size();
-  uint32 shm_data_offset = c.data_shm_offset;
-  uint32 shm_data_size = data_size;
-
   // Setup the parameters.
   AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
                                               width, height, format, type};
-  AsyncMemoryParams mem_params = {shared_memory, shm_size,
-                                       shm_data_offset, shm_data_size};
+  AsyncMemoryParams mem_params(
+      GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
   AsyncPixelTransferDelegate* delegate =
       async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
   if (!delegate) {
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 2c30186..9f1d3a7 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -36,12 +36,9 @@
   virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
     base::AutoLock locked(lock_);
     if (!cancelled_) {
-      DCHECK(mem_params.shared_memory);
-      DCHECK(mem_params.shared_memory->memory());
-      void* data = static_cast<int8*>(mem_params.shared_memory->memory()) +
-                   mem_params.shm_data_offset;
+      DCHECK(mem_params.buffer());
+      void* data = mem_params.GetDataAddress();
       QuerySync* sync = static_cast<QuerySync*>(data);
-
       base::subtle::Release_Store(&sync->process_count, submit_count_);
     }
   }
@@ -86,20 +83,14 @@
 
 bool AsyncPixelTransfersCompletedQuery::End(
     base::subtle::Atomic32 submit_count) {
-  AsyncMemoryParams mem_params;
   // Get the real shared memory since it might need to be duped to prevent
   // use-after-free of the memory.
   scoped_refptr<Buffer> buffer =
       manager()->decoder()->GetSharedMemoryBuffer(shm_id());
   if (!buffer)
     return false;
-  mem_params.shared_memory = buffer->shared_memory();
-  mem_params.shm_size = buffer->size();
-  mem_params.shm_data_offset = shm_offset();
-  mem_params.shm_data_size = sizeof(QuerySync);
-  base::CheckedNumeric<uint32> end = mem_params.shm_data_offset;
-  end += mem_params.shm_data_size;
-  if (!end.IsValid() || end.ValueOrDie() > mem_params.shm_size)
+  AsyncMemoryParams mem_params(buffer, shm_offset(), sizeof(QuerySync));
+  if (!mem_params.GetDataAddress())
     return false;
 
   observer_ = new AsyncPixelTransferCompletionObserverImpl(submit_count);
diff --git a/gpu/command_buffer/service/safe_shared_memory_pool.cc b/gpu/command_buffer/service/safe_shared_memory_pool.cc
deleted file mode 100644
index 9ba5390..0000000
--- a/gpu/command_buffer/service/safe_shared_memory_pool.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2012 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 "gpu/command_buffer/service/safe_shared_memory_pool.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/process/process_handle.h"
-#include "build/build_config.h"
-
-using base::SharedMemory;
-using base::SharedMemoryHandle;
-
-namespace gpu {
-
-ScopedSafeSharedMemory::ScopedSafeSharedMemory(SafeSharedMemoryPool* pool,
-                                               base::SharedMemory* memory,
-                                               size_t shm_size) {
-  DCHECK(pool);
-  DCHECK(memory);
-  DCHECK(memory->memory());
-  pool_ = pool;
-  original_handle_ = memory->handle();
-  safe_shared_memory_ = pool->AcquireSafeSharedMemory(memory, shm_size);
-  CHECK(safe_shared_memory_);
-}
-
-ScopedSafeSharedMemory::~ScopedSafeSharedMemory() {
-  // Release the handle. The pool will delete the SharedMemory
-  // object when it is no longer referenced.
-  pool_->ReleaseSafeSharedMemory(original_handle_);
-}
-
-base::SharedMemory* ScopedSafeSharedMemory::shared_memory() {
-  return safe_shared_memory_;
-}
-
-SafeSharedMemoryPool::SafeSharedMemoryPool()
-    : handles_acquired_(0),
-      handles_consumed_(0),
-      address_space_consumed_(0),
-      max_handles_acquired_(0),
-      max_handles_consumed_(0),
-      max_address_space_consumed_(0) {
-}
-
-SafeSharedMemoryPool::~SafeSharedMemoryPool() {
-}
-
-base::SharedMemory* SafeSharedMemoryPool::
-    AcquireSafeSharedMemory(base::SharedMemory* shared_memory,
-                            size_t shm_size) {
-  DCHECK(shared_memory);
-  DCHECK(shared_memory->memory());
-  base::AutoLock scoped_lock(lock_);
-
-  // Adjust stats.
-  handles_acquired_++;
-  max_handles_acquired_ = std::max(max_handles_acquired_,
-                                   handles_acquired_);
-
-  MemoryMap::iterator it = memory_.find(shared_memory->handle());
-  // If we don't already have it, duplicated it.
-  if (it == memory_.end()) {
-    // Duplicate a new shared memory and track it.
-    TrackedMemory tracker;
-    tracker.safe_shared_memory = DuplicateSharedMemory(shared_memory, shm_size);
-    tracker.reference_count = 1;
-    tracker.shm_size = shm_size;
-    memory_[shared_memory->handle()] = tracker;
-
-    // Adjust stats.
-    handles_consumed_++;
-    address_space_consumed_ += shm_size;
-    max_handles_consumed_ = std::max(max_handles_consumed_,
-                                         handles_consumed_);
-    max_address_space_consumed_ = std::max(max_address_space_consumed_,
-                                               address_space_consumed_);
-    return tracker.safe_shared_memory;
-  }
-
-  // Otherwise, add a reference and return the existing one.
-  DCHECK(it->second.reference_count);
-  DCHECK(it->second.safe_shared_memory);
-  DCHECK(it->second.safe_shared_memory->memory());
-  it->second.reference_count++;
-  return it->second.safe_shared_memory;
-}
-
-void SafeSharedMemoryPool::
-    ReleaseSafeSharedMemory(const base::SharedMemoryHandle& handle) {
-  base::AutoLock scoped_lock(lock_);
-
-  // Adjust stats.
-  DCHECK_GT(handles_acquired_, 0);
-  handles_acquired_--;
-
-  MemoryMap::iterator it = memory_.find(handle);
-  CHECK(it != memory_.end());
-  CHECK(it->second.reference_count);
-  CHECK(it->second.safe_shared_memory);
-  if (--it->second.reference_count == 0) {
-    // Adjust stats.
-    DCHECK_GT(handles_consumed_, 0);
-    handles_consumed_--;
-    DCHECK_LE(it->second.shm_size, address_space_consumed_);
-    address_space_consumed_ -= it->second.shm_size;
-    // Delete the safe memory and remove it.
-    delete it->second.safe_shared_memory;
-    memory_.erase(it);
-  }
-}
-
-SharedMemory* SafeSharedMemoryPool::DuplicateSharedMemory(
-    SharedMemory* shared_memory, size_t size) {
-  // Duplicate the handle.
-  SharedMemoryHandle duped_shared_memory_handle;
-  if (!shared_memory->ShareToProcess(
-      base::GetCurrentProcessHandle(),
-      &duped_shared_memory_handle)) {
-    PLOG(ERROR) << "Failed SharedMemory::ShareToProcess";
-    LOG(ERROR) << "Total handles acquired " << handles_acquired_;
-    LOG(ERROR) << "Total handles open " << handles_consumed_;
-    LOG(ERROR) << "Total address space " << address_space_consumed_;
-    LOG(ERROR) << "Max handles acquired " << max_handles_acquired_;
-    LOG(ERROR) << "Max handles open " << max_handles_consumed_;
-    LOG(ERROR) << "Max address space " << max_address_space_consumed_;
-    CHECK(false); // Diagnosing a crash.
-    return NULL;
-  }
-  scoped_ptr<SharedMemory> duped_shared_memory(
-      new SharedMemory(duped_shared_memory_handle, false));
-  // Map the shared memory into this process. This validates the size.
-  if (!duped_shared_memory->Map(size)) {
-    PLOG(ERROR) << "Failed SharedMemory::Map(" << size << ")";
-    LOG(ERROR) << "Total handles acquired " << handles_acquired_;
-    LOG(ERROR) << "Total handles open " << handles_consumed_;
-    LOG(ERROR) << "Total address space " << address_space_consumed_;
-    LOG(ERROR) << "Max handles acquired " << max_handles_acquired_;
-    LOG(ERROR) << "Max handles open " << max_handles_consumed_;
-    LOG(ERROR) << "Max address space " << max_address_space_consumed_;
-    CHECK(false); // Diagnosing a crash.
-    return NULL;
-  }
-  return duped_shared_memory.release();
-}
-
-}  // namespace gpu
diff --git a/gpu/command_buffer/service/safe_shared_memory_pool.h b/gpu/command_buffer/service/safe_shared_memory_pool.h
deleted file mode 100644
index fed17ff3..0000000
--- a/gpu/command_buffer/service/safe_shared_memory_pool.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2011 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 GPU_COMMAND_BUFFER_SERVICE_SAFE_SHARED_MEMORY_POOL_H_
-#define GPU_COMMAND_BUFFER_SERVICE_SAFE_SHARED_MEMORY_POOL_H_
-
-#include <map>
-
-#include "base/basictypes.h"
-#include "base/memory/shared_memory.h"
-#include "base/synchronization/lock.h"
-#include "build/build_config.h"
-
-namespace gpu {
-class SafeSharedMemoryPool;
-
-// These classes exist to help protect against deletion of shared
-// memory that is being used on a worker thread. It's mainly a
-// security measure to prevent use-after-free in the browser, due
-// to a misbehaving client. That said, this should be removed
-// in favor of higher-level reference counting of an appropriate
-// opaque 'memory blob' data-structure.
-
-class ScopedSafeSharedMemory {
- public:
-  base::SharedMemory* shared_memory();
-  ScopedSafeSharedMemory(SafeSharedMemoryPool* pool,
-                         base::SharedMemory* memory,
-                         size_t shm_size);
-  ~ScopedSafeSharedMemory();
- private:
-  base::SharedMemory* safe_shared_memory_;
-  base::SharedMemoryHandle original_handle_;
-  SafeSharedMemoryPool* pool_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedSafeSharedMemory);
-};
-
-class SafeSharedMemoryPool {
- public:
-  SafeSharedMemoryPool();
-  virtual ~SafeSharedMemoryPool();
-
- private:
-  friend class ScopedSafeSharedMemory;
-
-  // Acquires and release shared memory. The acquired shared memory
-  // is guaranteed to live until it is released.
-  base::SharedMemory* AcquireSafeSharedMemory(base::SharedMemory*, size_t size);
-  void ReleaseSafeSharedMemory(const base::SharedMemoryHandle&);
-
-  // Utility function to duplicate shared memory.
-  base::SharedMemory* DuplicateSharedMemory(base::SharedMemory*, size_t size);
-
-  // Track all SharedMemory's that we have already duplicated.
-  struct TrackedMemory {
-    base::SharedMemory* safe_shared_memory;
-    size_t shm_size;
-    int reference_count;
-  };
-
-  typedef std::map<base::SharedMemoryHandle, TrackedMemory> MemoryMap;
-  MemoryMap memory_;
-
-  // Track usage to diagnose crashes.
-  int handles_acquired_;
-  int handles_consumed_;
-  size_t address_space_consumed_;
-  int max_handles_acquired_;
-  int max_handles_consumed_;
-  size_t max_address_space_consumed_;
-
-  base::Lock lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(SafeSharedMemoryPool);
-};
-
-}  // namespace gfx
-
-#endif  // GPU_COMMAND_BUFFER_SERVICE_SAFE_SHARED_MEMORY_POOL_H_
-