diff options
author | epenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-30 19:57:16 +0000 |
---|---|---|
committer | epenner@chromium.org <epenner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-30 19:57:16 +0000 |
commit | 69023944fd69b3cabe71f1dec7fdfa922f2034d7 (patch) | |
tree | 44f8d73a06d55e9136af99e1c79e4a59274e7c7a | |
parent | b949fcb52666d423b7c66d9a7a69d482bf056513 (diff) | |
download | chromium_src-69023944fd69b3cabe71f1dec7fdfa922f2034d7.zip chromium_src-69023944fd69b3cabe71f1dec7fdfa922f2034d7.tar.gz chromium_src-69023944fd69b3cabe71f1dec7fdfa922f2034d7.tar.bz2 |
gpu: Add async upload functions.
Just adding the API first to unblock other CLs and so
we can start to use the API. Async tasks are just
done synchronously, and the completion query is set
immediately when it executes in the GPU process.
BUG=161337
Review URL: https://chromiumcodereview.appspot.com/11412232
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170516 0039d316-1c4b-4281-b951-d872f2087c98
25 files changed, 626 insertions, 0 deletions
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 5a6dff1..0c2bdba 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -1644,6 +1644,36 @@ WGC3Dboolean WebGraphicsContext3DCommandBufferImpl::unmapBufferCHROMIUM( return gl_->UnmapBufferCHROMIUM(target); } +void WebGraphicsContext3DCommandBufferImpl::asyncTexImage2DCHROMIUM( + WGC3Denum target, + WGC3Dint level, + WGC3Denum internalformat, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Dint border, + WGC3Denum format, + WGC3Denum type, + const void* pixels) { + return gl_->AsyncTexImage2DCHROMIUM( + target, level, internalformat, + width, height, border, format, type, pixels); +} + +void WebGraphicsContext3DCommandBufferImpl::asyncTexSubImage2DCHROMIUM( + WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, + const void *pixels) { + return gl_->AsyncTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + GrGLInterface* WebGraphicsContext3DCommandBufferImpl::onCreateGrGLInterface() { return webkit::gpu::CreateCommandBufferSkiaGLBinding(); } diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h index 1fc3206..81dd6b5 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h @@ -606,6 +606,28 @@ class WebGraphicsContext3DCommandBufferImpl virtual void* mapBufferCHROMIUM(WGC3Denum target, WGC3Denum access); virtual WGC3Dboolean unmapBufferCHROMIUM(WGC3Denum target); + // Async pixel transfer functions. + virtual void asyncTexImage2DCHROMIUM( + WGC3Denum target, + WGC3Dint level, + WGC3Denum internalformat, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Dint border, + WGC3Denum format, + WGC3Denum type, + const void* pixels); + virtual void asyncTexSubImage2DCHROMIUM( + WGC3Denum target, + WGC3Dint level, + WGC3Dint xoffset, + WGC3Dint yoffset, + WGC3Dsizei width, + WGC3Dsizei height, + WGC3Denum format, + WGC3Denum type, + const void* pixels); + protected: virtual GrGLInterface* onCreateGrGLInterface(); diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index da321b2..fb78d79 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -777,6 +777,7 @@ _ENUM_LISTS = { 'GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT', 'GL_COMMANDS_ISSUED_CHROMIUM', 'GL_LATENCY_QUERY_CHROMIUM', + 'GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM', ], }, 'RenderBufferParameter': { @@ -2248,6 +2249,20 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, + 'AsyncTexImage2DCHROMIUM': { + 'type': 'Manual', + 'immediate': False, + 'client_test': False, + 'extension': True, + 'chromium': True, + }, + 'AsyncTexSubImage2DCHROMIUM': { + 'type': 'Manual', + 'immediate': False, + 'client_test': False, + 'extension': True, + 'chromium': True, + }, } diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 6e760c9..6a4ad9c 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -697,6 +697,20 @@ void GLES2TraceBeginCHROMIUM(const char* name) { void GLES2TraceEndCHROMIUM() { gles2::GetGLContext()->TraceEndCHROMIUM(); } +void GLES2AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* data) { + gles2::GetGLContext()->AsyncTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, width, height, format, type, data); +} +void GLES2AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) { + gles2::GetGLContext()->AsyncTexImage2DCHROMIUM( + target, level, internalformat, width, height, border, format, type, + pixels); +} namespace gles2 { @@ -1024,6 +1038,10 @@ NameToFunc g_gles2_function_table[] = { glTraceBeginCHROMIUM), }, { "glTraceEndCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( glTraceEndCHROMIUM), }, + { "glAsyncTexSubImage2DCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glAsyncTexSubImage2DCHROMIUM), }, + { "glAsyncTexImage2DCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glAsyncTexImage2DCHROMIUM), }, { NULL, NULL, }, }; diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 51a91e7..26e703b 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1932,5 +1932,31 @@ } } + void AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, uint32 data_shm_id, + uint32 data_shm_offset) { + gles2::AsyncTexSubImage2DCHROMIUM* c = + GetCmdSpace<gles2::AsyncTexSubImage2DCHROMIUM>(); + if (c) { + c->Init( + target, level, xoffset, yoffset, width, height, format, type, + data_shm_id, data_shm_offset); + } + } + + void AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + uint32 pixels_shm_id, uint32 pixels_shm_offset) { + gles2::AsyncTexImage2DCHROMIUM* c = + GetCmdSpace<gles2::AsyncTexImage2DCHROMIUM>(); + if (c) { + c->Init( + target, level, internalformat, width, height, border, format, type, + pixels_shm_id, pixels_shm_offset); + } + } + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index bf24aa8..71f768d 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -3194,6 +3194,96 @@ GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { return true; } +void GLES2Implementation::AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" + << GLES2Util::GetStringTextureTarget(target) << ", " + << level << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " + << width << ", " << height << ", " << border << ", " + << GLES2Util::GetStringTextureFormat(format) << ", " + << GLES2Util::GetStringPixelType(type) << ", " + << static_cast<const void*>(pixels) << ")"); + if (level < 0 || height < 0 || width < 0) { + SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0"); + return; + } + uint32 size; + uint32 unpadded_row_size; + uint32 padded_row_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, format, type, unpack_alignment_, &size, + &unpadded_row_size, &padded_row_size)) { + SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); + return; + } + + // If there's no data/buffer just issue the AsyncTexImage2D + if (!pixels && !bound_pixel_unpack_transfer_buffer_id_) { + helper_->AsyncTexImage2DCHROMIUM( + target, level, internalformat, width, height, border, format, type, + 0, 0); + return; + } + + // Otherwise, async uploads require a transfer buffer to be bound. + GLuint offset = ToGLuint(pixels); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + "glAsyncTexImage2DCHROMIUM", offset, size); + if (!buffer) + return; + + helper_->AsyncTexImage2DCHROMIUM( + target, level, internalformat, width, height, border, format, type, + buffer->shm_id(), buffer->shm_offset() + offset); + return; +} + +void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* pixels) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAsyncTexSubImage2DCHROMIUM(" + << GLES2Util::GetStringTextureTarget(target) << ", " + << level << ", " + << xoffset << ", " << yoffset << ", " + << width << ", " << height << ", " + << GLES2Util::GetStringTextureFormat(format) << ", " + << GLES2Util::GetStringPixelType(type) << ", " + << static_cast<const void*>(pixels) << ")"); + if (level < 0 || height < 0 || width < 0) { + SetGLError( + GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "dimension < 0"); + return; + } + + uint32 size; + uint32 unpadded_row_size; + uint32 padded_row_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, format, type, unpack_alignment_, &size, + &unpadded_row_size, &padded_row_size)) { + SetGLError( + GL_INVALID_VALUE, "glAsyncTexSubImage2DCHROMIUM", "size to large"); + return; + } + + // Async uploads require a transfer buffer to be bound. + GLuint offset = ToGLuint(pixels); + BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( + "glAsyncTexSubImage2DCHROMIUM", offset, size); + if (!buffer) + return; + + helper_->AsyncTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, width, height, format, type, + buffer->shm_id(), buffer->shm_offset() + offset); + return; +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index b6dce8c..db4ded8 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -510,5 +510,14 @@ virtual void TraceBeginCHROMIUM(const char* name) OVERRIDE; virtual void TraceEndCHROMIUM() OVERRIDE; +virtual void AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* data) OVERRIDE; + +virtual void AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) OVERRIDE; + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index b83bad5..aed2cc9 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -292,5 +292,12 @@ virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) = 0; virtual void TraceBeginCHROMIUM(const char* name) = 0; virtual void TraceEndCHROMIUM() = 0; +virtual void AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* data) = 0; +virtual void AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 452b4c7..3ac1250 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -324,5 +324,12 @@ virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) OVERRIDE; virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) OVERRIDE; virtual void TraceBeginCHROMIUM(const char* name) OVERRIDE; virtual void TraceEndCHROMIUM() OVERRIDE; +virtual void AsyncTexSubImage2DCHROMIUM( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* data) OVERRIDE; +virtual void AsyncTexImage2DCHROMIUM( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) OVERRIDE; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 1cf7548..60c22b2 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -613,5 +613,15 @@ void GLES2InterfaceStub::TraceBeginCHROMIUM(const char* /* name */) { } void GLES2InterfaceStub::TraceEndCHROMIUM() { } +void GLES2InterfaceStub::AsyncTexSubImage2DCHROMIUM( + GLenum /* target */, GLint /* level */, GLint /* xoffset */, + GLint /* yoffset */, GLsizei /* width */, GLsizei /* height */, + GLenum /* format */, GLenum /* type */, const void* /* data */) { +} +void GLES2InterfaceStub::AsyncTexImage2DCHROMIUM( + GLenum /* target */, GLint /* level */, GLint /* internalformat */, + GLsizei /* width */, GLsizei /* height */, GLint /* border */, + GLenum /* format */, GLenum /* type */, const void* /* pixels */) { +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/query_tracker.cc b/gpu/command_buffer/client/query_tracker.cc index a0c7b56..1983262 100644 --- a/gpu/command_buffer/client/query_tracker.cc +++ b/gpu/command_buffer/client/query_tracker.cc @@ -83,6 +83,10 @@ void QueryTracker::Query::Begin(GLES2Implementation* gl) { // tell service about id, shared memory and count gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); break; + case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: + // tell service about id, shared memory and count + gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); + break; default: // tell service about id, shared memory and count gl->helper()->BeginQueryEXT(target(), id(), shm_id(), shm_offset()); @@ -131,6 +135,9 @@ bool QueryTracker::Query::CheckResultsAvailable( result_ = std::min(info_.sync->result - client_begin_time_us_, static_cast<uint64>(0xFFFFFFFFL)); break; + case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: + result_ = info_.sync->result; + break; default: result_ = info_.sync->result; break; diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index a91f8db..75167d5 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -203,3 +203,5 @@ GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindT GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId); GL_APICALL void GL_APIENTRY glTraceBeginCHROMIUM (const char* name); GL_APICALL void GL_APIENTRY glTraceEndCHROMIUM (void); +GL_APICALL void GL_APIENTRY glAsyncTexSubImage2DCHROMIUM (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenumTextureFormat format, GLenumPixelType type, const void* data); +GL_APICALL void GL_APIENTRY glAsyncTexImage2DCHROMIUM (GLenumTextureTarget target, GLint level, GLintTextureInternalFormat internalformat, GLsizei width, GLsizei height, GLintTextureBorder border, GLenumTextureFormat format, GLenumPixelType type, const void* pixels); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index fd27f5b..3d291c0 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -10572,6 +10572,164 @@ COMPILE_ASSERT(sizeof(TraceEndCHROMIUM) == 4, COMPILE_ASSERT(offsetof(TraceEndCHROMIUM, header) == 0, OffsetOf_TraceEndCHROMIUM_header_not_0); +struct AsyncTexSubImage2DCHROMIUM { + typedef AsyncTexSubImage2DCHROMIUM ValueType; + static const CommandId kCmdId = kAsyncTexSubImage2DCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, + uint32 _data_shm_id, uint32 _data_shm_offset) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + type = _type; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, + uint32 _data_shm_id, uint32 _data_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _type, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + int32 level; + int32 xoffset; + int32 yoffset; + int32 width; + int32 height; + uint32 format; + uint32 type; + uint32 data_shm_id; + uint32 data_shm_offset; +}; + +COMPILE_ASSERT(sizeof(AsyncTexSubImage2DCHROMIUM) == 44, + Sizeof_AsyncTexSubImage2DCHROMIUM_is_not_44); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, header) == 0, + OffsetOf_AsyncTexSubImage2DCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, target) == 4, + OffsetOf_AsyncTexSubImage2DCHROMIUM_target_not_4); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, level) == 8, + OffsetOf_AsyncTexSubImage2DCHROMIUM_level_not_8); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, xoffset) == 12, + OffsetOf_AsyncTexSubImage2DCHROMIUM_xoffset_not_12); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, yoffset) == 16, + OffsetOf_AsyncTexSubImage2DCHROMIUM_yoffset_not_16); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, width) == 20, + OffsetOf_AsyncTexSubImage2DCHROMIUM_width_not_20); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, height) == 24, + OffsetOf_AsyncTexSubImage2DCHROMIUM_height_not_24); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, format) == 28, + OffsetOf_AsyncTexSubImage2DCHROMIUM_format_not_28); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, type) == 32, + OffsetOf_AsyncTexSubImage2DCHROMIUM_type_not_32); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_id) == 36, + OffsetOf_AsyncTexSubImage2DCHROMIUM_data_shm_id_not_36); +COMPILE_ASSERT(offsetof(AsyncTexSubImage2DCHROMIUM, data_shm_offset) == 40, + OffsetOf_AsyncTexSubImage2DCHROMIUM_data_shm_offset_not_40); + +struct AsyncTexImage2DCHROMIUM { + typedef AsyncTexImage2DCHROMIUM ValueType; + static const CommandId kCmdId = kAsyncTexImage2DCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLenum _format, GLenum _type, + uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLenum _format, + GLenum _type, uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, _format, + _type, _pixels_shm_id, _pixels_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + int32 level; + int32 internalformat; + int32 width; + int32 height; + int32 border; + uint32 format; + uint32 type; + uint32 pixels_shm_id; + uint32 pixels_shm_offset; +}; + +COMPILE_ASSERT(sizeof(AsyncTexImage2DCHROMIUM) == 44, + Sizeof_AsyncTexImage2DCHROMIUM_is_not_44); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, header) == 0, + OffsetOf_AsyncTexImage2DCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, target) == 4, + OffsetOf_AsyncTexImage2DCHROMIUM_target_not_4); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, level) == 8, + OffsetOf_AsyncTexImage2DCHROMIUM_level_not_8); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, internalformat) == 12, + OffsetOf_AsyncTexImage2DCHROMIUM_internalformat_not_12); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, width) == 16, + OffsetOf_AsyncTexImage2DCHROMIUM_width_not_16); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, height) == 20, + OffsetOf_AsyncTexImage2DCHROMIUM_height_not_20); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, border) == 24, + OffsetOf_AsyncTexImage2DCHROMIUM_border_not_24); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, format) == 28, + OffsetOf_AsyncTexImage2DCHROMIUM_format_not_28); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, type) == 32, + OffsetOf_AsyncTexImage2DCHROMIUM_type_not_32); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_id) == 36, + OffsetOf_AsyncTexImage2DCHROMIUM_pixels_shm_id_not_36); +COMPILE_ASSERT(offsetof(AsyncTexImage2DCHROMIUM, pixels_shm_offset) == 40, + OffsetOf_AsyncTexImage2DCHROMIUM_pixels_shm_offset_not_40); + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index 0c11756..55009c2 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -4256,5 +4256,67 @@ TEST_F(GLES2FormatTest, TraceEndCHROMIUM) { next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, AsyncTexSubImage2DCHROMIUM) { + AsyncTexSubImage2DCHROMIUM& cmd = *GetBufferAs<AsyncTexSubImage2DCHROMIUM>(); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLsizei>(15), + static_cast<GLsizei>(16), + static_cast<GLenum>(17), + static_cast<GLenum>(18), + static_cast<uint32>(19), + static_cast<uint32>(20)); + EXPECT_EQ(static_cast<uint32>(AsyncTexSubImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.height); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLenum>(18), cmd.type); + EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(20), cmd.data_shm_offset); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, AsyncTexImage2DCHROMIUM) { + AsyncTexImage2DCHROMIUM& cmd = *GetBufferAs<AsyncTexImage2DCHROMIUM>(); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLsizei>(14), + static_cast<GLsizei>(15), + static_cast<GLint>(16), + static_cast<GLenum>(17), + static_cast<GLenum>(18), + static_cast<uint32>(19), + static_cast<uint32>(20)); + EXPECT_EQ(static_cast<uint32>(AsyncTexImage2DCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLint>(16), cmd.border); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLenum>(18), cmd.type); + EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 324de9c..70925cd 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -243,6 +243,8 @@ OP(ReleaseTexImage2DCHROMIUM) /* 486 */ \ OP(TraceBeginCHROMIUM) /* 487 */ \ OP(TraceEndCHROMIUM) /* 488 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 489 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 490 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 03913b4..a358e7b 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -1057,6 +1057,8 @@ std::string GLES2Util::GetStringQueryTarget(uint32 value) { "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT" }, { GL_COMMANDS_ISSUED_CHROMIUM, "GL_COMMANDS_ISSUED_CHROMIUM" }, { GL_LATENCY_QUERY_CHROMIUM, "GL_LATENCY_QUERY_CHROMIUM" }, + { GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, + "GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM" }, }; return GLES2Util::GetQualifiedEnumString( string_table, arraysize(string_table), value); diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 3c2365e..4b8e09c 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -235,6 +235,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) { bool npot_ok = false; AddExtensionString("GL_ANGLE_translated_shader_source"); + AddExtensionString("GL_CHROMIUM_async_pixel_transfers"); AddExtensionString("GL_CHROMIUM_bind_uniform_location"); AddExtensionString("GL_CHROMIUM_command_buffer_query"); AddExtensionString("GL_CHROMIUM_command_buffer_latency_query"); diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h index ccd96f3..8fa9325 100644 --- a/gpu/command_buffer/service/gl_utils.h +++ b/gpu/command_buffer/service/gl_utils.h @@ -92,6 +92,9 @@ /* GL_CHROMIUM_command_buffer_latency_query */ #define GL_LATENCY_QUERY_CHROMIUM 0x84F4 +/* GL_CHROMIUM_async_pixel_transfers */ +#define GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM 0x84F5 + // GL_OES_texure_3D #define GL_SAMPLER_3D_OES 0x8B5F diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 8914a84..2ec1e96 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -9315,6 +9315,96 @@ void GLES2DecoderImpl::DoTraceEndCHROMIUM() { gpu_trace_stack_.pop(); } +error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( + uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); + + // TODO: This is a copy of HandleTexImage2D validation. Merge + // as much of it as possible. + tex_image_2d_failed_ = true; + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint internal_format = static_cast<GLint>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + 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; + if (!GLES2Util::ComputeImageDataSizes( + width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, + NULL)) { + return error::kOutOfBounds; + } + const void* pixels = NULL; + if (pixels_shm_id != 0 || pixels_shm_offset != 0) { + pixels = GetSharedMemoryAs<const void*>( + pixels_shm_id, pixels_shm_offset, pixels_size); + if (!pixels) { + return error::kOutOfBounds; + } + } + + // TODO(epenner): Do this via an async task. + return DoTexImage2D( + target, level, internal_format, width, height, border, format, type, + pixels, pixels_size); +} + +error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( + uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { + TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); + + // TODO: This is a copy of HandleTexSubImage2D validation. Merge + // as much of it as possible. + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + uint32 data_size; + if (!GLES2Util::ComputeImageDataSizes( + width, height, format, type, state_.unpack_alignment, &data_size, + NULL, NULL)) { + return error::kOutOfBounds; + } + const void* pixels = GetSharedMemoryAs<const void*>( + c.data_shm_id, c.data_shm_offset, data_size); + if (!validators_->texture_target.IsValid(target)) { + SetGLErrorInvalidEnum("glTexSubImage2D", target, "target"); + return error::kNoError; + } + if (width < 0) { + SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0"); + return error::kNoError; + } + if (height < 0) { + SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0"); + return error::kNoError; + } + if (!validators_->texture_format.IsValid(format)) { + SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); + return error::kNoError; + } + if (!validators_->pixel_type.IsValid(type)) { + SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); + return error::kNoError; + } + if (pixels == NULL) { + return error::kOutOfBounds; + } + + // TODO(epenner): Do this via an async task. + DoTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, pixels); + return error::kNoError; +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 36e1a8f..2d88af0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -60,5 +60,9 @@ // TODO(gman): TraceBeginCHROMIUM // TODO(gman): TraceEndCHROMIUM +// TODO(gman): AsyncTexSubImage2DCHROMIUM + +// TODO(gman): AsyncTexImage2DCHROMIUM + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 8029af4..26d73c7 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -290,6 +290,7 @@ static GLenum valid_query_target_table[] = { GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_COMMANDS_ISSUED_CHROMIUM, GL_LATENCY_QUERY_CHROMIUM, + GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, }; static GLenum valid_read_pixel_format_table[] = { diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index 45a3a56..61a8d7f 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc @@ -162,6 +162,52 @@ void CommandLatencyQuery::Destroy(bool /* have_context */) { CommandLatencyQuery::~CommandLatencyQuery() { } +class AsyncPixelTransfersCompletedQuery : public QueryManager::Query { + public: + AsyncPixelTransfersCompletedQuery( + QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); + + virtual bool Begin() OVERRIDE; + virtual bool End(uint32 submit_count) OVERRIDE; + virtual bool Process() OVERRIDE; + virtual void Destroy(bool have_context) OVERRIDE; + + protected: + virtual ~AsyncPixelTransfersCompletedQuery(); +}; + +AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( + QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) + : Query(manager, target, shm_id, shm_offset) { +} + +bool AsyncPixelTransfersCompletedQuery::Begin() { + return true; +} + +bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) { + // TODO(epenner): Mark completion via an async task. + // TODO(epenner): This will be a boolean to start, indicating + // completion of all tasks in the query. We could change this + // to return a count of tasks completed instead. + MarkAsPending(submit_count); + return MarkAsCompleted(1); +} + +bool AsyncPixelTransfersCompletedQuery::Process() { + NOTREACHED(); + return true; +} + +void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { + if (!IsDeleted()) { + MarkAsDeleted(); + } +} + +AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { +} + class GetErrorQuery : public QueryManager::Query { public: GetErrorQuery( @@ -248,6 +294,10 @@ QueryManager::Query* QueryManager::CreateQuery( case GL_LATENCY_QUERY_CHROMIUM: query = new CommandLatencyQuery(this, target, shm_id, shm_offset); break; + case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: + query = new AsyncPixelTransfersCompletedQuery( + this, target, shm_id, shm_offset); + break; case GL_GET_ERROR_QUERY_CHROMIUM: query = new GetErrorQuery(this, target, shm_id, shm_offset); break; diff --git a/third_party/khronos/GLES2/gl2chromium.h b/third_party/khronos/GLES2/gl2chromium.h index 1c3517e..2ce097e 100644 --- a/third_party/khronos/GLES2/gl2chromium.h +++ b/third_party/khronos/GLES2/gl2chromium.h @@ -224,6 +224,8 @@ #define glReleaseTexImage2DCHROMIUM GLES2_GET_FUN(ReleaseTexImage2DCHROMIUM) #define glTraceBeginCHROMIUM GLES2_GET_FUN(TraceBeginCHROMIUM) #define glTraceEndCHROMIUM GLES2_GET_FUN(TraceEndCHROMIUM) +#define glAsyncTexSubImage2DCHROMIUM GLES2_GET_FUN(AsyncTexSubImage2DCHROMIUM) +#define glAsyncTexImage2DCHROMIUM GLES2_GET_FUN(AsyncTexImage2DCHROMIUM) #endif // THIRD_PARTY_KHRONOS_GLES2_GL2CHROMIUM_H_ diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h index 14dda71..f1fd2c4 100644 --- a/third_party/khronos/GLES2/gl2ext.h +++ b/third_party/khronos/GLES2/gl2ext.h @@ -2154,6 +2154,13 @@ typedef void (GL_APIENTRYP PFNGLRELEASETEXIMAGE2DCHROMIUM) (GLenum target, GLint #define GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM 0x88EF #endif +/* GL_CHROMIUM_async_pixel_transfers */ +#ifndef GL_CHROMIUM_async_pixel_transfers +#define GL_CHROMIUM_async_pixel_transfers 1 +// TODO: Get official numbers for these constants. +#define GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM 0x84F5 +#endif + #ifdef __cplusplus } #endif diff --git a/third_party/khronos/README.chromium b/third_party/khronos/README.chromium index 1e36778..4b6290f 100644 --- a/third_party/khronos/README.chromium +++ b/third_party/khronos/README.chromium @@ -33,6 +33,7 @@ GLES2/gl2ext.h - Added GL_CHROMIUM_iosurface - Added GL_CHROMIUM_texture_from_image - Added GL_CHROMIUM_pixel_transfer_buffer_object + - Added GL_CHROMIUM_async_pixel_transfers - Added GL_NVX_gpu_memory_info - Added include of gl2chromium.h GLES2/glchromium.h |