summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorepenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-27 06:10:12 +0000
committerepenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-27 06:10:12 +0000
commitc8021e0389e481a019865d77773c17f1d8492cdc (patch)
tree307d36abcb1a252d9c90f0fef1eaa601354dcc5a /gpu
parentf645be519c2a95fb0540c62d5f957527ac9e9d6f (diff)
downloadchromium_src-c8021e0389e481a019865d77773c17f1d8492cdc.zip
chromium_src-c8021e0389e481a019865d77773c17f1d8492cdc.tar.gz
chromium_src-c8021e0389e481a019865d77773c17f1d8492cdc.tar.bz2
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
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/common/buffer.cc10
-rw-r--r--gpu/command_buffer/common/buffer.h9
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_delegate.cc47
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_delegate.h31
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager.h2
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc47
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc72
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc45
-rw-r--r--gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc4
-rw-r--r--gpu/command_buffer/service/common_decoder.cc10
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc24
-rw-r--r--gpu/command_buffer/service/query_manager.cc17
-rw-r--r--gpu/command_buffer/service/safe_shared_memory_pool.cc149
-rw-r--r--gpu/command_buffer/service/safe_shared_memory_pool.h82
-rw-r--r--gpu/command_buffer_service.gypi2
15 files changed, 86 insertions, 465 deletions
diff --git a/gpu/command_buffer/common/buffer.cc b/gpu/command_buffer/common/buffer.cc
index 5ba4e51..bbf40a1 100644
--- a/gpu/command_buffer/common/buffer.cc
+++ b/gpu/command_buffer/common/buffer.cc
@@ -6,6 +6,8 @@
#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+
namespace gpu {
Buffer::Buffer(scoped_ptr<base::SharedMemory> shared_memory, size_t size)
@@ -17,4 +19,12 @@ Buffer::Buffer(scoped_ptr<base::SharedMemory> shared_memory, size_t size)
Buffer::~Buffer() {}
+void* Buffer::GetDataAddress(uint32 data_offset, uint32 data_size) const {
+ base::CheckedNumeric<uint32> end = data_offset;
+ end += data_size;
+ if (!end.IsValid() || end.ValueOrDie() > static_cast<uint32>(size_))
+ return NULL;
+ return static_cast<uint8*>(memory_) + data_offset;
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/common/buffer.h b/gpu/command_buffer/common/buffer.h
index 74d9705..e9a1558 100644
--- a/gpu/command_buffer/common/buffer.h
+++ b/gpu/command_buffer/common/buffer.h
@@ -22,9 +22,12 @@ class GPU_EXPORT Buffer : public base::RefCountedThreadSafe<Buffer> {
public:
Buffer(scoped_ptr<base::SharedMemory> shared_memory, size_t size);
- base::SharedMemory* shared_memory() { return shared_memory_.get(); }
- void* memory() { return memory_; }
- size_t size() { return size_; }
+ base::SharedMemory* shared_memory() const { return shared_memory_.get(); }
+ void* memory() const { return memory_; }
+ size_t size() const { return size_; }
+
+ // Returns NULL if the address overflows the memory.
+ void* GetDataAddress(uint32 data_offset, uint32 data_size) const;
private:
friend class base::RefCountedThreadSafe<Buffer>;
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 @@ int AsyncPixelTransferUploadStats::GetStats(
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 @@ struct AsyncTexSubImage2DParams {
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 @@ class GPU_EXPORT AsyncPixelTransferDelegate {
// 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 d0ea5da..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 @@ class GLContext;
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..32fa4c0 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 SetGlParametersForEglImageTexture() {
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 @@ class TransferThread : public base::Thread {
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 @@ base::MessageLoopProxy* transfer_message_loop_proxy() {
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ void AsyncPixelTransferDelegateEGL::AsyncTexImage2D(
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 @@ void AsyncPixelTransferDelegateEGL::AsyncTexImage2D(
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 @@ void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D(
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 @@ void AsyncPixelTransferDelegateEGL::AsyncTexSubImage2D(
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 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexImage2D(
// 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 @@ bool AsyncPixelTransferDelegateEGL::WorkAroundAsyncTexSubImage2D(
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::BindCompletedAsyncTransfers() {
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 @@ class AsyncPixelTransferDelegateIdle
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 @@ void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
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 @@ void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
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::WaitForTransferCompletion() {
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::PerformAsyncTexImage2D(
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 @@ void AsyncPixelTransferManagerIdle::AsyncNotifyCompletion(
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 dcdab1c..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 @@ const char kAsyncTransferThreadName[] = "AsyncTransferThread";
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 @@ class TransferThread : public base::Thread {
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 @@ base::MessageLoopProxy* transfer_message_loop_proxy() {
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ class TransferStateInternal
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 @@ void AsyncPixelTransferDelegateShareGroup::AsyncTexImage2D(
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 @@ void AsyncPixelTransferDelegateShareGroup::AsyncTexSubImage2D(
"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::BindCompletedAsyncTransfers() {
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 ffe5584..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 @@ void AsyncPixelTransferDelegateSync::AsyncTexImage2D(
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::AsyncTexImage2D(
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() : engine_(NULL) {}
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..e6a1270 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -10392,20 +10392,12 @@ error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
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 @@ error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
}
}
- // 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 @@ class AsyncPixelTransferCompletionObserverImpl
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::Begin() {
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 fed17ff..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_
-
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index 89689cf..cd4662d 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -111,8 +111,6 @@
'command_buffer/service/renderbuffer_manager.cc',
'command_buffer/service/program_cache.h',
'command_buffer/service/program_cache.cc',
- 'command_buffer/service/safe_shared_memory_pool.h',
- 'command_buffer/service/safe_shared_memory_pool.cc',
'command_buffer/service/shader_manager.h',
'command_buffer/service/shader_manager.cc',
'command_buffer/service/shader_translator.h',