Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
index d6f9fc89a47a18c7c4da25353db9f757a122e3c8..497134ce33c84b0c1ec210215a99df7bb21379cb 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -15,10 +15,12 @@ |
#include "base/at_exit.h" |
#include "base/bind.h" |
+#include "base/callback_helpers.h" |
#include "base/command_line.h" |
#include "base/debug/trace_event.h" |
#include "base/debug/trace_event_synthetic_delay.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/numerics/safe_math.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_split.h" |
#include "build/build_config.h" |
@@ -518,6 +520,26 @@ struct FenceCallback { |
scoped_ptr<gfx::GLFence> fence; |
}; |
+class AsyncUploadTokenCompletionObserver |
+ : public AsyncPixelTransferCompletionObserver { |
+ public: |
+ explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token) |
+ : async_upload_token_(async_upload_token) { |
+ } |
+ |
+ virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE { |
+ void* data = static_cast<int8*>(mem_params.shared_memory->memory()) + |
+ mem_params.shm_data_offset; |
+ AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data); |
+ sync->SetAsyncUploadToken(async_upload_token_); |
+ } |
+ |
+ private: |
+ uint32 async_upload_token_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver); |
+}; |
+ |
// } // anonymous namespace. |
bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, |
@@ -709,6 +731,13 @@ class GLES2DecoderImpl : public GLES2Decoder, |
bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
+ // Helper for async upload token completion notification callback. |
+ base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, |
+ uint32 sync_data_shm_id, |
+ uint32 sync_data_shm_offset); |
+ |
+ |
+ |
// Workarounds |
void OnFboChanged() const; |
void OnUseFramebuffer() const; |
@@ -10318,6 +10347,34 @@ bool GLES2DecoderImpl::ValidateAsyncTransfer( |
return true; |
} |
+base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure( |
+ uint32 async_upload_token, |
+ uint32 sync_data_shm_id, |
+ uint32 sync_data_shm_offset) { |
+ AsyncMemoryParams mem_params; |
+ gpu::Buffer buffer = GetSharedMemoryBuffer(sync_data_shm_id); |
+ if (!buffer.shared_memory) |
+ return base::Closure(); |
+ mem_params.shared_memory = buffer.shared_memory; |
+ mem_params.shm_size = buffer.size; |
+ mem_params.shm_data_offset = sync_data_shm_offset; |
+ mem_params.shm_data_size = sizeof(AsyncUploadSync); |
+ |
+ base::CheckedNumeric<uint32> end = mem_params.shm_data_offset; |
+ end += mem_params.shm_data_size; |
+ if (!end.IsValid() || end.ValueOrDie() > mem_params.shm_size) |
+ return base::Closure(); |
+ |
+ scoped_refptr<AsyncUploadTokenCompletionObserver> observer( |
+ new AsyncUploadTokenCompletionObserver(async_upload_token)); |
+ |
+ return base::Bind( |
+ &AsyncPixelTransferManager::AsyncNotifyCompletion, |
+ base::Unretained(GetAsyncPixelTransferManager()), |
+ mem_params, |
+ observer); |
+} |
+ |
error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( |
uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) { |
TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); |
@@ -10334,6 +10391,21 @@ error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( |
uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); |
uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); |
uint32 pixels_size; |
+ uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); |
+ uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); |
+ uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); |
+ |
+ base::ScopedClosureRunner scoped_completion_callback; |
+ if (async_upload_token) { |
+ base::Closure completion_closure = |
+ AsyncUploadTokenCompletionClosure(async_upload_token, |
+ sync_data_shm_id, |
+ sync_data_shm_offset); |
+ if (completion_closure.is_null()) |
+ return error::kInvalidArguments; |
+ |
+ scoped_completion_callback.Reset(completion_closure); |
+ } |
// TODO(epenner): Move this and copies of this memory validation |
// into ValidateTexImage2D step. |
@@ -10428,6 +10500,21 @@ error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( |
GLsizei height = static_cast<GLsizei>(c.height); |
GLenum format = static_cast<GLenum>(c.format); |
GLenum type = static_cast<GLenum>(c.type); |
+ uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); |
+ uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); |
+ uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); |
+ |
+ base::ScopedClosureRunner scoped_completion_callback; |
+ if (async_upload_token) { |
+ base::Closure completion_closure = |
+ AsyncUploadTokenCompletionClosure(async_upload_token, |
+ sync_data_shm_id, |
+ sync_data_shm_offset); |
+ if (completion_closure.is_null()) |
+ return error::kInvalidArguments; |
+ |
+ scoped_completion_callback.Reset(completion_closure); |
+ } |
// TODO(epenner): Move this and copies of this memory validation |
// into ValidateTexSubImage2D step. |
@@ -10538,6 +10625,15 @@ error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM( |
return error::kNoError; |
} |
+error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM( |
+ uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) { |
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM"); |
+ |
+ GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D(); |
+ ProcessFinishedAsyncTransfers(); |
+ return error::kNoError; |
+} |
+ |
void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( |
TextureRef* texture_ref) { |
Texture* texture = texture_ref->texture(); |