summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/common/gpu/gpu_channel.cc4
-rw-r--r--content/common/gpu/gpu_channel.h2
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc3
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.h7
-rw-r--r--gpu/DEPS1
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py27
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h9
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h45
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc15
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h16
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h30
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt4
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h214
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h219
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h5
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h5
-rw-r--r--gpu/command_buffer/service/context_group.cc9
-rw-r--r--gpu/command_buffer/service/context_group.h12
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc4
-rw-r--r--gpu/command_buffer/service/feature_info.cc1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc93
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h92
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc127
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h5
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc2
-rw-r--r--gpu/command_buffer/service/mailbox_manager.cc125
-rw-r--r--gpu/command_buffer/service/mailbox_manager.h99
-rw-r--r--gpu/command_buffer/service/texture_definition.cc49
-rw-r--r--gpu/command_buffer/service/texture_definition.h75
-rw-r--r--gpu/command_buffer/service/texture_manager.cc131
-rw-r--r--gpu/command_buffer/service/texture_manager.h50
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc11
-rw-r--r--gpu/command_buffer/tests/gl_manager.h5
-rw-r--r--gpu/command_buffer/tests/gl_texture_mailbox_unittests.cc172
-rw-r--r--gpu/command_buffer/tests/gl_unittests.cc10
-rw-r--r--gpu/command_buffer_service.gypi5
-rw-r--r--gpu/gles2_conform_support/egl/display.cc2
-rw-r--r--gpu/gpu_common.gypi1
-rw-r--r--third_party/khronos/GLES2/gl2ext.h20
-rw-r--r--webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc2
40 files changed, 1663 insertions, 45 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index 9785ce7..a93c5b6 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -18,6 +18,7 @@
#include "content/common/gpu/gpu_messages.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_surface.h"
@@ -41,6 +42,7 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
: gpu_channel_manager_(gpu_channel_manager),
client_id_(client_id),
share_group_(share_group ? share_group : new gfx::GLShareGroup),
+ mailbox_manager_(new gpu::gles2::MailboxManager),
watchdog_(watchdog),
software_(software),
handle_messages_scheduled_(false),
@@ -192,6 +194,7 @@ void GpuChannel::CreateViewCommandBuffer(
this,
share_group,
window,
+ mailbox_manager_,
gfx::Size(),
disallowed_features_,
init_params.allowed_extensions,
@@ -349,6 +352,7 @@ void GpuChannel::OnCreateOffscreenCommandBuffer(
this,
share_group,
gfx::GLSurfaceHandle(),
+ mailbox_manager_.get(),
size,
disallowed_features_,
init_params.allowed_extensions,
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index 42e4d8b..67d856e 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -156,6 +156,8 @@ class GpuChannel : public IPC::Channel::Listener,
// process use.
scoped_refptr<gfx::GLShareGroup> share_group_;
+ scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
+
#if defined(ENABLE_GPU)
typedef IDMap<GpuCommandBufferStub, IDMapOwnPointer> StubMap;
StubMap stubs_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index b6f6d28..aa5b331 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -39,6 +39,7 @@ GpuCommandBufferStub::GpuCommandBufferStub(
GpuChannel* channel,
GpuCommandBufferStub* share_group,
const gfx::GLSurfaceHandle& handle,
+ gpu::gles2::MailboxManager* mailbox_manager,
const gfx::Size& size,
const gpu::gles2::DisallowedFeatures& disallowed_features,
const std::string& allowed_extensions,
@@ -65,7 +66,7 @@ GpuCommandBufferStub::GpuCommandBufferStub(
if (share_group) {
context_group_ = share_group->context_group_;
} else {
- context_group_ = new gpu::gles2::ContextGroup(true);
+ context_group_ = new gpu::gles2::ContextGroup(mailbox_manager, true);
}
if (surface_id != 0)
surface_state_.reset(new GpuCommandBufferStubBase::SurfaceState(
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index 4f08818..5a99c56 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -39,6 +39,12 @@ class GpuChannel;
struct GpuMemoryAllocation;
class GpuWatchdog;
+namespace gpu {
+namespace gles2 {
+class MailboxManager;
+}
+}
+
// This Base class is used to expose methods of GpuCommandBufferStub used for
// testability.
class CONTENT_EXPORT GpuCommandBufferStubBase {
@@ -88,6 +94,7 @@ class GpuCommandBufferStub
GpuChannel* channel,
GpuCommandBufferStub* share_group,
const gfx::GLSurfaceHandle& handle,
+ gpu::gles2::MailboxManager* mailbox_manager,
const gfx::Size& size,
const gpu::gles2::DisallowedFeatures& disallowed_features,
const std::string& allowed_extensions,
diff --git a/gpu/DEPS b/gpu/DEPS
index 10ef807..0eff51e 100644
--- a/gpu/DEPS
+++ b/gpu/DEPS
@@ -7,5 +7,6 @@ include_rules = [
"+../common",
"+../GLES2",
"+../service",
+ "+crypto",
"+ui/gfx",
]
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 39d2025..a279798 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -862,6 +862,15 @@ _FUNCTION_INFO = {
'gl_test_func': 'glClearDepth',
},
'ColorMask': {'decoder_func': 'DoColorMask', 'expectation': False},
+ 'ConsumeTextureCHROMIUM': {
+ 'decoder_func': 'DoConsumeTextureCHROMIUM',
+ 'type': 'PUT',
+ 'data_type': 'GLbyte',
+ 'count': 64,
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
'ClearStencil': {'decoder_func': 'DoClearStencil'},
'EnableFeatureCHROMIUM': {
'type': 'Custom',
@@ -988,6 +997,15 @@ _FUNCTION_INFO = {
'resource_type': 'Buffer',
'resource_types': 'Buffers',
},
+ 'GenMailboxCHROMIUM': {
+ 'type': 'Manual',
+ 'cmd_args': 'GLuint bucket_id',
+ 'result': ['SizedResult<GLint>'],
+ 'client_test': False,
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
'GenFramebuffers': {
'type': 'GENn',
'gl_test_func': 'glGenFramebuffersEXT',
@@ -1278,6 +1296,15 @@ _FUNCTION_INFO = {
'extension': True,
'chromium': True,
},
+ 'ProduceTextureCHROMIUM': {
+ 'decoder_func': 'DoProduceTextureCHROMIUM',
+ 'type': 'PUT',
+ 'data_type': 'GLbyte',
+ 'count': 64,
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
'RenderbufferStorage': {
'decoder_func': 'DoRenderbufferStorage',
'gl_test_func': 'glRenderbufferStorageEXT',
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 263c868..fa75173 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -641,6 +641,15 @@ void GLES2DrawElementsInstancedANGLE(
void GLES2VertexAttribDivisorANGLE(GLuint index, GLuint divisor) {
gles2::GetGLContext()->VertexAttribDivisorANGLE(index, divisor);
}
+void GLES2GenMailboxCHROMIUM(GLbyte* mailbox) {
+ gles2::GetGLContext()->GenMailboxCHROMIUM(mailbox);
+}
+void GLES2ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
+ gles2::GetGLContext()->ProduceTextureCHROMIUM(target, mailbox);
+}
+void GLES2ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
+ gles2::GetGLContext()->ConsumeTextureCHROMIUM(target, mailbox);
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index b520491..82b3b15 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1752,5 +1752,50 @@
}
}
+ void GenMailboxCHROMIUM(GLuint bucket_id) {
+ gles2::GenMailboxCHROMIUM* c = GetCmdSpace<gles2::GenMailboxCHROMIUM>();
+ if (c) {
+ c->Init(bucket_id);
+ }
+ }
+
+ void ProduceTextureCHROMIUM(
+ GLenum target, uint32 mailbox_shm_id, uint32 mailbox_shm_offset) {
+ gles2::ProduceTextureCHROMIUM* c =
+ GetCmdSpace<gles2::ProduceTextureCHROMIUM>();
+ if (c) {
+ c->Init(target, mailbox_shm_id, mailbox_shm_offset);
+ }
+ }
+
+ void ProduceTextureCHROMIUMImmediate(GLenum target, const GLbyte* mailbox) {
+ const uint32 size = gles2::ProduceTextureCHROMIUMImmediate::ComputeSize();
+ gles2::ProduceTextureCHROMIUMImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::ProduceTextureCHROMIUMImmediate>(
+ size);
+ if (c) {
+ c->Init(target, mailbox);
+ }
+ }
+
+ void ConsumeTextureCHROMIUM(
+ GLenum target, uint32 mailbox_shm_id, uint32 mailbox_shm_offset) {
+ gles2::ConsumeTextureCHROMIUM* c =
+ GetCmdSpace<gles2::ConsumeTextureCHROMIUM>();
+ if (c) {
+ c->Init(target, mailbox_shm_id, mailbox_shm_offset);
+ }
+ }
+
+ void ConsumeTextureCHROMIUMImmediate(GLenum target, const GLbyte* mailbox) {
+ const uint32 size = gles2::ConsumeTextureCHROMIUMImmediate::ComputeSize();
+ gles2::ConsumeTextureCHROMIUMImmediate* c =
+ GetImmediateCmdSpaceTotalSize<gles2::ConsumeTextureCHROMIUMImmediate>(
+ size);
+ if (c) {
+ c->Init(target, mailbox);
+ }
+ }
+
#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 d136753..1375fe8 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -3138,5 +3138,20 @@ void GLES2Implementation::DrawElementsInstancedANGLE(
#endif
}
+void GLES2Implementation::GenMailboxCHROMIUM(
+ GLbyte* mailbox) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << this << "] glGenMailboxCHROMIUM("
+ << static_cast<const void*>(mailbox) << ")");
+ TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM");
+
+ helper_->GenMailboxCHROMIUM(kResultBucketId);
+
+ std::vector<GLbyte> result;
+ GetBucketContents(kResultBucketId, &result);
+
+ std::copy(result.begin(), result.end(), mailbox);
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 9193535..d9ba14ca 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1562,5 +1562,21 @@ void DrawElementsInstancedANGLE(
void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+void GenMailboxCHROMIUM(GLbyte* mailbox);
+
+void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << this << "] glProduceTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")"); // NOLINT
+ GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]); // NOLINT
+ helper_->ProduceTextureCHROMIUMImmediate(target, mailbox);
+}
+
+void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << this << "] glConsumeTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")"); // NOLINT
+ GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]); // NOLINT
+ helper_->ConsumeTextureCHROMIUMImmediate(target, mailbox);
+}
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index 8128e9c..4545550 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -1666,5 +1666,35 @@ TEST_F(GLES2ImplementationTest, VertexAttribDivisorANGLE) {
gl_->VertexAttribDivisorANGLE(1, 2);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+
+TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
+ struct Cmds {
+ ProduceTextureCHROMIUMImmediate cmd;
+ GLbyte data[64];
+ };
+
+ Cmds expected;
+ for (int jj = 0; jj < 64; ++jj) {
+ expected.data[jj] = static_cast<GLbyte>(jj);
+ }
+ expected.cmd.Init(GL_TEXTURE_2D, &expected.data[0]);
+ gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, &expected.data[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
+ struct Cmds {
+ ConsumeTextureCHROMIUMImmediate cmd;
+ GLbyte data[64];
+ };
+
+ Cmds expected;
+ for (int jj = 0; jj < 64; ++jj) {
+ expected.data[jj] = static_cast<GLbyte>(jj);
+ }
+ expected.cmd.Init(GL_TEXTURE_2D, &expected.data[0]);
+ gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, &expected.data[0]);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 9676d02..b22d383 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -182,4 +182,6 @@ GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM (GLenum target, GLenum
GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenumDrawMode mode, GLint first, GLsizei count, GLsizei primcount);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices, GLsizei primcount);
GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor);
-
+GL_APICALL void GL_APIENTRY glGenMailboxCHROMIUM (GLbyte* mailbox);
+GL_APICALL void GL_APIENTRY glProduceTextureCHROMIUM (GLenumTextureTarget target, const GLbyte* mailbox);
+GL_APICALL void GL_APIENTRY glConsumeTextureCHROMIUM (GLenumTextureTarget target, const GLbyte* mailbox);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 3e93516..0f01f5c 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -9713,6 +9713,220 @@ COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, index) == 4,
COMPILE_ASSERT(offsetof(VertexAttribDivisorANGLE, divisor) == 8,
OffsetOf_VertexAttribDivisorANGLE_divisor_not_8);
+struct GenMailboxCHROMIUM {
+ typedef GenMailboxCHROMIUM ValueType;
+ static const CommandId kCmdId = kGenMailboxCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ typedef SizedResult<GLint> Result;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(GLuint _bucket_id) {
+ SetHeader();
+ bucket_id = _bucket_id;
+ }
+
+ void* Set(void* cmd, GLuint _bucket_id) {
+ static_cast<ValueType*>(cmd)->Init(_bucket_id);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 bucket_id;
+};
+
+COMPILE_ASSERT(sizeof(GenMailboxCHROMIUM) == 8,
+ Sizeof_GenMailboxCHROMIUM_is_not_8);
+COMPILE_ASSERT(offsetof(GenMailboxCHROMIUM, header) == 0,
+ OffsetOf_GenMailboxCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(GenMailboxCHROMIUM, bucket_id) == 4,
+ OffsetOf_GenMailboxCHROMIUM_bucket_id_not_4);
+
+struct ProduceTextureCHROMIUM {
+ typedef ProduceTextureCHROMIUM ValueType;
+ static const CommandId kCmdId = kProduceTextureCHROMIUM;
+ 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, uint32 _mailbox_shm_id, uint32 _mailbox_shm_offset) {
+ SetHeader();
+ target = _target;
+ mailbox_shm_id = _mailbox_shm_id;
+ mailbox_shm_offset = _mailbox_shm_offset;
+ }
+
+ void* Set(
+ void* cmd, GLenum _target, uint32 _mailbox_shm_id,
+ uint32 _mailbox_shm_offset) {
+ static_cast<ValueType*>(
+ cmd)->Init(_target, _mailbox_shm_id, _mailbox_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ uint32 mailbox_shm_id;
+ uint32 mailbox_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(ProduceTextureCHROMIUM) == 16,
+ Sizeof_ProduceTextureCHROMIUM_is_not_16);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUM, header) == 0,
+ OffsetOf_ProduceTextureCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUM, target) == 4,
+ OffsetOf_ProduceTextureCHROMIUM_target_not_4);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUM, mailbox_shm_id) == 8,
+ OffsetOf_ProduceTextureCHROMIUM_mailbox_shm_id_not_8);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUM, mailbox_shm_offset) == 12,
+ OffsetOf_ProduceTextureCHROMIUM_mailbox_shm_offset_not_12);
+
+struct ProduceTextureCHROMIUMImmediate {
+ typedef ProduceTextureCHROMIUMImmediate ValueType;
+ static const CommandId kCmdId = kProduceTextureCHROMIUMImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+
+ static uint32 ComputeDataSize() {
+ return static_cast<uint32>(
+ sizeof(GLbyte) * 64); // NOLINT
+ }
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(
+ sizeof(ValueType) + ComputeDataSize()); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize());
+ }
+
+ void Init(GLenum _target, const GLbyte* _mailbox) {
+ SetHeader();
+ target = _target;
+ memcpy(ImmediateDataAddress(this),
+ _mailbox, ComputeDataSize());
+ }
+
+ void* Set(void* cmd, GLenum _target, const GLbyte* _mailbox) {
+ static_cast<ValueType*>(cmd)->Init(_target, _mailbox);
+ const uint32 size = ComputeSize();
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+};
+
+COMPILE_ASSERT(sizeof(ProduceTextureCHROMIUMImmediate) == 8,
+ Sizeof_ProduceTextureCHROMIUMImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUMImmediate, header) == 0,
+ OffsetOf_ProduceTextureCHROMIUMImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(ProduceTextureCHROMIUMImmediate, target) == 4,
+ OffsetOf_ProduceTextureCHROMIUMImmediate_target_not_4);
+
+struct ConsumeTextureCHROMIUM {
+ typedef ConsumeTextureCHROMIUM ValueType;
+ static const CommandId kCmdId = kConsumeTextureCHROMIUM;
+ 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, uint32 _mailbox_shm_id, uint32 _mailbox_shm_offset) {
+ SetHeader();
+ target = _target;
+ mailbox_shm_id = _mailbox_shm_id;
+ mailbox_shm_offset = _mailbox_shm_offset;
+ }
+
+ void* Set(
+ void* cmd, GLenum _target, uint32 _mailbox_shm_id,
+ uint32 _mailbox_shm_offset) {
+ static_cast<ValueType*>(
+ cmd)->Init(_target, _mailbox_shm_id, _mailbox_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ uint32 mailbox_shm_id;
+ uint32 mailbox_shm_offset;
+};
+
+COMPILE_ASSERT(sizeof(ConsumeTextureCHROMIUM) == 16,
+ Sizeof_ConsumeTextureCHROMIUM_is_not_16);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUM, header) == 0,
+ OffsetOf_ConsumeTextureCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUM, target) == 4,
+ OffsetOf_ConsumeTextureCHROMIUM_target_not_4);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUM, mailbox_shm_id) == 8,
+ OffsetOf_ConsumeTextureCHROMIUM_mailbox_shm_id_not_8);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUM, mailbox_shm_offset) == 12,
+ OffsetOf_ConsumeTextureCHROMIUM_mailbox_shm_offset_not_12);
+
+struct ConsumeTextureCHROMIUMImmediate {
+ typedef ConsumeTextureCHROMIUMImmediate ValueType;
+ static const CommandId kCmdId = kConsumeTextureCHROMIUMImmediate;
+ static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+
+ static uint32 ComputeDataSize() {
+ return static_cast<uint32>(
+ sizeof(GLbyte) * 64); // NOLINT
+ }
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(
+ sizeof(ValueType) + ComputeDataSize()); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmdByTotalSize<ValueType>(ComputeSize());
+ }
+
+ void Init(GLenum _target, const GLbyte* _mailbox) {
+ SetHeader();
+ target = _target;
+ memcpy(ImmediateDataAddress(this),
+ _mailbox, ComputeDataSize());
+ }
+
+ void* Set(void* cmd, GLenum _target, const GLbyte* _mailbox) {
+ static_cast<ValueType*>(cmd)->Init(_target, _mailbox);
+ const uint32 size = ComputeSize();
+ return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+};
+
+COMPILE_ASSERT(sizeof(ConsumeTextureCHROMIUMImmediate) == 8,
+ Sizeof_ConsumeTextureCHROMIUMImmediate_is_not_8);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUMImmediate, header) == 0,
+ OffsetOf_ConsumeTextureCHROMIUMImmediate_header_not_0);
+COMPILE_ASSERT(offsetof(ConsumeTextureCHROMIUMImmediate, target) == 4,
+ OffsetOf_ConsumeTextureCHROMIUMImmediate_target_not_4);
+
#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 4a5d29d..f3c0661 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3775,5 +3775,224 @@ TEST_F(GLES2FormatTest, VertexAttribDivisorANGLE) {
next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, GenMailboxCHROMIUM) {
+ GenMailboxCHROMIUM& cmd = *GetBufferAs<GenMailboxCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLuint>(11));
+ EXPECT_EQ(static_cast<uint32>(GenMailboxCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, ProduceTextureCHROMIUM) {
+ ProduceTextureCHROMIUM& cmd = *GetBufferAs<ProduceTextureCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<uint32>(12),
+ static_cast<uint32>(13));
+ EXPECT_EQ(static_cast<uint32>(ProduceTextureCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<uint32>(12), cmd.mailbox_shm_id);
+ EXPECT_EQ(static_cast<uint32>(13), cmd.mailbox_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, ProduceTextureCHROMIUMImmediate) {
+ const int kSomeBaseValueToTestWith = 51;
+ static GLbyte data[] = {
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 0),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 1),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 2),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 3),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 4),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 5),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 6),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 7),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 8),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 9),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 10),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 11),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 12),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 13),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 14),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 15),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 16),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 17),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 18),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 19),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 20),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 21),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 22),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 23),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 24),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 25),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 26),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 27),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 28),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 29),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 30),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 31),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 32),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 33),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 34),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 35),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 36),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 37),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 38),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 39),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 40),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 41),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 42),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 43),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 44),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 45),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 46),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 47),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 48),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 49),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 50),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 51),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 52),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 53),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 54),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 55),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 56),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 57),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 58),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 59),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 60),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 61),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 62),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 63),
+ };
+ ProduceTextureCHROMIUMImmediate& cmd =
+ *GetBufferAs<ProduceTextureCHROMIUMImmediate>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ data);
+ EXPECT_EQ(static_cast<uint32>(ProduceTextureCHROMIUMImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) +
+ RoundSizeToMultipleOfEntries(sizeof(data)),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd) +
+ RoundSizeToMultipleOfEntries(sizeof(data)));
+ // TODO(gman): Check that data was inserted;
+}
+
+TEST_F(GLES2FormatTest, ConsumeTextureCHROMIUM) {
+ ConsumeTextureCHROMIUM& cmd = *GetBufferAs<ConsumeTextureCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<uint32>(12),
+ static_cast<uint32>(13));
+ EXPECT_EQ(static_cast<uint32>(ConsumeTextureCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<uint32>(12), cmd.mailbox_shm_id);
+ EXPECT_EQ(static_cast<uint32>(13), cmd.mailbox_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, ConsumeTextureCHROMIUMImmediate) {
+ const int kSomeBaseValueToTestWith = 51;
+ static GLbyte data[] = {
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 0),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 1),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 2),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 3),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 4),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 5),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 6),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 7),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 8),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 9),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 10),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 11),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 12),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 13),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 14),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 15),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 16),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 17),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 18),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 19),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 20),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 21),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 22),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 23),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 24),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 25),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 26),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 27),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 28),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 29),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 30),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 31),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 32),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 33),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 34),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 35),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 36),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 37),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 38),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 39),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 40),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 41),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 42),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 43),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 44),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 45),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 46),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 47),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 48),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 49),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 50),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 51),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 52),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 53),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 54),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 55),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 56),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 57),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 58),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 59),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 60),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 61),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 62),
+ static_cast<GLbyte>(kSomeBaseValueToTestWith + 63),
+ };
+ ConsumeTextureCHROMIUMImmediate& cmd =
+ *GetBufferAs<ConsumeTextureCHROMIUMImmediate>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ data);
+ EXPECT_EQ(static_cast<uint32>(ConsumeTextureCHROMIUMImmediate::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd) +
+ RoundSizeToMultipleOfEntries(sizeof(data)),
+ cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd) +
+ RoundSizeToMultipleOfEntries(sizeof(data)));
+ // TODO(gman): Check that data was inserted;
+}
+
#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 ac95b0c..5102903 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -222,6 +222,11 @@
OP(DrawArraysInstancedANGLE) /* 465 */ \
OP(DrawElementsInstancedANGLE) /* 466 */ \
OP(VertexAttribDivisorANGLE) /* 467 */ \
+ OP(GenMailboxCHROMIUM) /* 468 */ \
+ OP(ProduceTextureCHROMIUM) /* 469 */ \
+ OP(ProduceTextureCHROMIUMImmediate) /* 470 */ \
+ OP(ConsumeTextureCHROMIUM) /* 471 */ \
+ OP(ConsumeTextureCHROMIUMImmediate) /* 472 */ \
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 d99da6d..5fb03f7 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -224,7 +224,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x00000400, "GL_STENCIL_BUFFER_BIT", },
{ 0x800A, "GL_FUNC_SUBTRACT", },
{ 0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV", },
- { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", },
+ { 0x8508, "GL_DECR_WRAP", },
{ 0x8006, "GL_FUNC_ADD", },
{ 0x8007, "GL_MIN_EXT", },
{ 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA", },
@@ -378,6 +378,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x0502, "GL_INVALID_OPERATION", },
{ 0x0501, "GL_INVALID_VALUE", },
{ 0x0500, "GL_INVALID_ENUM", },
+ { 64, "GL_MAILBOX_SIZE_CHROMIUM", },
{ 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION", },
{ 0x0505, "GL_OUT_OF_MEMORY", },
{ 0x8B5F, "GL_SAMPLER_3D_OES", },
@@ -499,7 +500,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", },
{ 0x8253, "GL_GUILTY_CONTEXT_RESET_EXT", },
{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS", },
- { 0x8508, "GL_DECR_WRAP", },
+ { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", },
{ 0x8507, "GL_INCR_WRAP", },
{ 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING", },
{ 0x8894, "GL_ARRAY_BUFFER_BINDING", },
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index dd99d84..8916801 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -13,6 +13,7 @@
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/renderbuffer_manager.h"
#include "gpu/command_buffer/service/shader_manager.h"
@@ -22,8 +23,10 @@
namespace gpu {
namespace gles2 {
-ContextGroup::ContextGroup(bool bind_generates_resource)
- : num_contexts_(0),
+ContextGroup::ContextGroup(MailboxManager* mailbox_manager,
+ bool bind_generates_resource)
+ : mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager),
+ num_contexts_(0),
enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnforceGLMinimums)),
bind_generates_resource_(bind_generates_resource),
@@ -249,6 +252,8 @@ void ContextGroup::Destroy(bool have_context) {
}
if (texture_manager_ != NULL) {
+ mailbox_manager_->DestroyOwnedTextures(texture_manager_.get(),
+ have_context);
texture_manager_->Destroy(have_context);
texture_manager_.reset();
}
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index 5284c1c..8c5477e 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -22,9 +22,10 @@ class IdAllocatorInterface;
namespace gles2 {
-class GLES2Decoder;
class BufferManager;
+class GLES2Decoder;
class FramebufferManager;
+class MailboxManager;
class RenderbufferManager;
class ProgramManager;
class ShaderManager;
@@ -37,7 +38,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
public:
typedef scoped_refptr<ContextGroup> Ref;
- explicit ContextGroup(bool bind_generates_resource);
+ explicit ContextGroup(MailboxManager* mailbox_manager,
+ bool bind_generates_resource);
~ContextGroup();
// This should only be called by GLES2Decoder. This must be paired with a
@@ -49,6 +51,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
// It should only be called by GLES2Decoder.
void Destroy(bool have_context);
+ MailboxManager* mailbox_manager() const {
+ return mailbox_manager_.get();
+ }
+
bool bind_generates_resource() {
return bind_generates_resource_;
}
@@ -117,6 +123,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
bool QueryGLFeature(GLenum pname, GLint min_required, GLint* v);
bool QueryGLFeatureU(GLenum pname, GLint min_required, uint32* v);
+ scoped_refptr<MailboxManager> mailbox_manager_;
+
// Whether or not this context is initialized.
int num_contexts_;
bool enforce_gl_minimums_;
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index bb60af9..e0eb64a 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -36,7 +36,7 @@ class ContextGroupTest : public testing::Test {
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
- group_ = ContextGroup::Ref(new ContextGroup(true));
+ group_ = ContextGroup::Ref(new ContextGroup(NULL, true));
}
virtual void TearDown() {
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index fff10fc..01c0ffd 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -121,6 +121,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
AddExtensionString("GL_CHROMIUM_discard_framebuffer");
AddExtensionString("GL_CHROMIUM_command_buffer_query");
AddExtensionString("GL_CHROMIUM_copy_texture");
+ AddExtensionString("GL_CHROMIUM_texture_mailbox");
AddExtensionString("GL_ANGLE_translated_shader_source");
if (ext.Have("GL_ANGLE_translated_shader_source")) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index cc864ab..18c799d 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -36,6 +36,7 @@
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/query_manager.h"
#include "gpu/command_buffer/service/renderbuffer_manager.h"
@@ -43,6 +44,7 @@
#include "gpu/command_buffer/service/shader_translator.h"
#include "gpu/command_buffer/service/stream_texture.h"
#include "gpu/command_buffer/service/stream_texture_manager.h"
+#include "gpu/command_buffer/service/texture_definition.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "ui/gfx/gl/gl_context.h"
@@ -509,6 +511,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
void ApplyDirtyState();
+ // Reapply the texture parameters to the given texture.
+ void BindAndApplyTextureParameters(TextureManager::TextureInfo* info);
+
// These check the state of the currently bound framebuffer or the
// backbuffer if no framebuffer is bound.
bool BoundFramebufferHasColorAttachmentWithAlpha();
@@ -619,6 +624,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
return group_->texture_manager();
}
+ MailboxManager* mailbox_manager() {
+ return group_->mailbox_manager();
+ }
+
bool IsOffscreenBufferMultisampled() const {
return offscreen_target_samples_ > 1;
}
@@ -742,6 +751,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
GLsizei width,
GLsizei height);
+ void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
+ void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
+
// Creates a ProgramInfo for the given program.
ProgramManager::ProgramInfo* CreateProgramInfo(
GLuint client_id, GLuint service_id) {
@@ -3265,6 +3277,15 @@ void GLES2DecoderImpl::ApplyDirtyState() {
}
}
+void GLES2DecoderImpl::BindAndApplyTextureParameters(
+ TextureManager::TextureInfo* info) {
+ glBindTexture(info->target(), info->service_id());
+ glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter());
+ glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter());
+ glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s());
+ glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t());
+}
+
GLuint GLES2DecoderImpl::GetBackbufferServiceId() {
return (offscreen_target_frame_buffer_.get()) ?
offscreen_target_frame_buffer_->id() :
@@ -8507,6 +8528,78 @@ void GLES2DecoderImpl::DoTexStorage2DEXT(
}
}
+error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
+ uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) {
+ MailboxName name;
+ mailbox_manager()->GenerateMailboxName(&name);
+ uint32 bucket_id = static_cast<uint32>(c.bucket_id);
+ Bucket* bucket = CreateBucket(bucket_id);
+
+ bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
+ bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
+
+ return error::kNoError;
+}
+
+void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
+ const GLbyte* mailbox) {
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glProduceTextureCHROMIUM: unknown texture for target");
+ return;
+ }
+
+ TextureDefinition* definition = texture_manager()->Save(info);
+ if (!definition) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glProduceTextureCHROMIUM: invalid texture");
+ return;
+ }
+
+ if (!group_->mailbox_manager()->ProduceTexture(
+ target,
+ *reinterpret_cast<const MailboxName*>(mailbox),
+ definition,
+ texture_manager())) {
+ bool success = texture_manager()->Restore(info, definition);
+ DCHECK(success);
+ SetGLError(GL_INVALID_OPERATION,
+ "glProduceTextureCHROMIUM: invalid mailbox name");
+ return;
+ }
+
+ BindAndApplyTextureParameters(info);
+}
+
+void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
+ const GLbyte* mailbox) {
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glConsumeTextureCHROMIUM: unknown texture for target");
+ return;
+ }
+
+ scoped_ptr<TextureDefinition> definition(
+ group_->mailbox_manager()->ConsumeTexture(
+ target,
+ *reinterpret_cast<const MailboxName*>(mailbox)));
+ if (!definition.get()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glConsumeTextureCHROMIUM: invalid mailbox name");
+ return;
+ }
+
+ if (!texture_manager()->Restore(info, definition.release())) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glConsumeTextureCHROMIUM: invalid texture");
+ return;
+ }
+
+ BindAndApplyTextureParameters(info);
+}
+
// 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_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 01fc027..f2b9f26 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2736,5 +2736,97 @@ error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUM(
+ uint32 immediate_data_size, const gles2::ProduceTextureCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
+ c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ SetGLError(
+ GL_INVALID_ENUM, "glProduceTextureCHROMIUM: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoProduceTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate(
+ uint32 immediate_data_size,
+ const gles2::ProduceTextureCHROMIUMImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ SetGLError(
+ GL_INVALID_ENUM, "glProduceTextureCHROMIUM: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoProduceTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUM(
+ uint32 immediate_data_size, const gles2::ConsumeTextureCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetSharedMemoryAs<const GLbyte*>(
+ c.mailbox_shm_id, c.mailbox_shm_offset, data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ SetGLError(
+ GL_INVALID_ENUM, "glConsumeTextureCHROMIUM: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoConsumeTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate(
+ uint32 immediate_data_size,
+ const gles2::ConsumeTextureCHROMIUMImmediate& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
+ const GLbyte* mailbox = GetImmediateDataAs<const GLbyte*>(
+ c, data_size, immediate_data_size);
+ if (!validators_->texture_target.IsValid(target)) {
+ SetGLError(
+ GL_INVALID_ENUM, "glConsumeTextureCHROMIUM: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (mailbox == NULL) {
+ return error::kOutOfBounds;
+ }
+ DoConsumeTextureCHROMIUM(target, mailbox);
+ return error::kNoError;
+}
+
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 9f08a9e..08bd91c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -12,6 +12,7 @@
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h"
#include "gpu/command_buffer/service/cmd_buffer_engine.h"
#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/stream_texture_mock.h"
#include "gpu/command_buffer/service/stream_texture_manager_mock.h"
#include "gpu/command_buffer/service/program_manager.h"
@@ -6787,6 +6788,132 @@ TEST_F(GLES2DecoderTest, BeingEndQueryEXTCommandsIssuedCHROMIUM) {
EXPECT_FALSE(query->pending());
}
+TEST_F(GLES2DecoderTest, GenMailboxCHROMIUM) {
+ const uint32 kBucketId = 123;
+
+ GenMailboxCHROMIUM gen_mailbox_cmd;
+ gen_mailbox_cmd.Init(kBucketId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_mailbox_cmd));
+
+ CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+ ASSERT_TRUE(bucket != NULL);
+ ASSERT_EQ(static_cast<uint32>(GL_MAILBOX_SIZE_CHROMIUM), bucket->size());
+
+ static const GLbyte zero[GL_MAILBOX_SIZE_CHROMIUM] = {
+ 0
+ };
+ EXPECT_NE(0, memcmp(zero,
+ bucket->GetData(0, GL_MAILBOX_SIZE_CHROMIUM),
+ sizeof(zero)));
+}
+
+TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
+ GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
+ group().mailbox_manager()->GenerateMailboxName(
+ reinterpret_cast<MailboxName*>(mailbox));
+
+ memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
+
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ 0, 0);
+ TextureManager::TextureInfo* info =
+ group().texture_manager()->GetTextureInfo(client_texture_id_);
+ EXPECT_EQ(kServiceTextureId, info->service_id());
+
+ // Assigns and binds new service side texture ID and applies the texture
+ // objects' state to it.
+ EXPECT_CALL(*gl_, GenTextures(1, _))
+ .WillOnce(SetArgumentPointee<1>(kNewServiceId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kNewServiceId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_LINEAR));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_WRAP_S,
+ GL_REPEAT));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_WRAP_T,
+ GL_REPEAT));
+
+ ProduceTextureCHROMIUM produce_cmd;
+ produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
+
+ // Texture is zero-by-zero.
+ GLsizei width;
+ GLsizei height;
+ GLenum type;
+ GLenum internal_format;
+
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ EXPECT_EQ(0, width);
+ EXPECT_EQ(0, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
+ EXPECT_EQ(0, width);
+ EXPECT_EQ(0, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+ // Service ID has changed.
+ EXPECT_EQ(kNewServiceId, info->service_id());
+
+ // Assigns and binds original service side texture ID and applies the texture
+ // objects' state to it.
+ EXPECT_CALL(*gl_, DeleteTextures(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_LINEAR));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_WRAP_S,
+ GL_REPEAT));
+ EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_WRAP_T,
+ GL_REPEAT));
+
+ ConsumeTextureCHROMIUM consume_cmd;
+ consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
+
+ // Texture is redefined.
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ EXPECT_EQ(3, width);
+ EXPECT_EQ(1, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
+ EXPECT_EQ(2, width);
+ EXPECT_EQ(4, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+ // Service ID is restored.
+ EXPECT_EQ(kServiceTextureId, info->service_id());
+}
// TODO(gman): Complete this test.
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
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 8e2df7a..ccdc475 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
@@ -34,5 +34,10 @@
// TODO(gman): DrawArraysInstancedANGLE
// TODO(gman): DrawElementsInstancedANGLE
// TODO(gman): VertexAttribDivisorANGLE
+// TODO(gman): GenMailboxCHROMIUM
+// TODO(gman): ProduceTextureCHROMIUM
+// TODO(gman): ProduceTextureCHROMIUMImmediate
+// TODO(gman): ConsumeTextureCHROMIUM
+// TODO(gman): ConsumeTextureCHROMIUMImmediate
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 40e98d4..2a43f99 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -194,7 +194,7 @@ void GLES2DecoderTestBase::InitDecoder(
bool bind_generates_resource) {
gl_.reset(new StrictMock<MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
- group_ = ContextGroup::Ref(new ContextGroup(bind_generates_resource));
+ group_ = ContextGroup::Ref(new ContextGroup(NULL, bind_generates_resource));
InSequence sequence;
diff --git a/gpu/command_buffer/service/mailbox_manager.cc b/gpu/command_buffer/service/mailbox_manager.cc
new file mode 100644
index 0000000..e161fcb
--- /dev/null
+++ b/gpu/command_buffer/service/mailbox_manager.cc
@@ -0,0 +1,125 @@
+// 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/mailbox_manager.h"
+
+#include "base/rand_util.h"
+#include "crypto/hmac.h"
+#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/command_buffer/service/texture_definition.h"
+
+namespace gpu {
+namespace gles2 {
+
+MailboxManager::MailboxManager()
+ : hmac_(crypto::HMAC::SHA256),
+ textures_(std::ptr_fun(&MailboxManager::TargetNameLess)) {
+ unsigned char private_key[GL_MAILBOX_SIZE_CHROMIUM / 2];
+ base::RandBytes(private_key, sizeof(private_key));
+ bool success = hmac_.Init(private_key, sizeof(private_key));
+ DCHECK(success);
+}
+
+MailboxManager::~MailboxManager() {
+}
+
+void MailboxManager::GenerateMailboxName(MailboxName* name) {
+ base::RandBytes(name->key, sizeof(name->key));
+ SignMailboxName(name);
+}
+
+TextureDefinition* MailboxManager::ConsumeTexture(unsigned target,
+ const MailboxName& name) {
+ if (!IsMailboxNameValid(name))
+ return NULL;
+
+ TextureDefinitionMap::iterator it =
+ textures_.find(TargetName(target, name));
+ if (it == textures_.end()) {
+ NOTREACHED();
+ return NULL;
+ }
+
+ TextureDefinition* definition = it->second.definition.release();
+ textures_.erase(it);
+
+ return definition;
+}
+
+bool MailboxManager::ProduceTexture(unsigned target,
+ const MailboxName& name,
+ TextureDefinition* definition,
+ TextureManager* owner) {
+ if (!IsMailboxNameValid(name))
+ return false;
+
+ TextureDefinitionMap::iterator it =
+ textures_.find(TargetName(target, name));
+ if (it != textures_.end()) {
+ NOTREACHED();
+ GLuint service_id = it->second.definition->ReleaseServiceId();
+ glDeleteTextures(1, &service_id);
+ it->second = OwnedTextureDefinition(definition, owner);
+ } else {
+ textures_.insert(std::make_pair(
+ TargetName(target, name),
+ OwnedTextureDefinition(definition, owner)));
+ }
+
+ return true;
+}
+
+void MailboxManager::DestroyOwnedTextures(TextureManager* owner,
+ bool have_context) {
+ TextureDefinitionMap::iterator it = textures_.begin();
+ while (it != textures_.end()) {
+ TextureDefinitionMap::iterator current_it = it;
+ ++it;
+ if (current_it->second.owner == owner) {
+ NOTREACHED();
+ GLuint service_id = current_it->second.definition->ReleaseServiceId();
+ if (have_context)
+ glDeleteTextures(1, &service_id);
+ textures_.erase(current_it);
+ }
+ }
+}
+
+void MailboxManager::SignMailboxName(MailboxName* name) {
+ bool success = hmac_.Sign(
+ base::StringPiece(reinterpret_cast<char*>(name->key), sizeof(name->key)),
+ reinterpret_cast<unsigned char*>(name->signature),
+ sizeof(name->signature));
+ DCHECK(success);
+}
+
+bool MailboxManager::IsMailboxNameValid(const MailboxName& name) {
+ return hmac_.Verify(
+ base::StringPiece(reinterpret_cast<const char*>(name.key),
+ sizeof(name.key)),
+ base::StringPiece(reinterpret_cast<const char*>(name.signature),
+ sizeof(name.signature)));
+}
+
+MailboxManager::TargetName::TargetName(unsigned target, const MailboxName& name)
+ : target(target),
+ name(name) {
+}
+
+bool MailboxManager::TargetNameLess(MailboxManager::TargetName lhs,
+ MailboxManager::TargetName rhs) {
+ return memcmp(&lhs, &rhs, sizeof(lhs)) < 0;
+}
+
+MailboxManager::OwnedTextureDefinition::OwnedTextureDefinition(
+ TextureDefinition* definition,
+ TextureManager* owner)
+ : definition(definition),
+ owner(owner) {
+}
+
+MailboxManager::OwnedTextureDefinition::~OwnedTextureDefinition() {
+}
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/service/mailbox_manager.h b/gpu/command_buffer/service/mailbox_manager.h
new file mode 100644
index 0000000..e7af1c4
--- /dev/null
+++ b/gpu/command_buffer/service/mailbox_manager.h
@@ -0,0 +1,99 @@
+// 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.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_H_
+
+#include <functional>
+#include <map>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "crypto/hmac.h"
+#include "gpu/command_buffer/common/constants.h"
+#include "gpu/gpu_export.h"
+
+// From gl2/gl2ext.h.
+#ifndef GL_MAILBOX_SIZE_CHROMIUM
+#define GL_MAILBOX_SIZE_CHROMIUM 64
+#endif
+
+typedef signed char GLbyte;
+
+namespace gpu {
+namespace gles2 {
+
+class TextureDefinition;
+class TextureManager;
+
+// Identifies a mailbox where a texture definition can be stored for
+// transferring textures between contexts that are not in the same context
+// group. It is a random key signed with a hash of a private key.
+struct MailboxName {
+ GLbyte key[GL_MAILBOX_SIZE_CHROMIUM / 2];
+ GLbyte signature[GL_MAILBOX_SIZE_CHROMIUM / 2];
+};
+
+// Manages resources scoped beyond the context or context group level.
+class GPU_EXPORT MailboxManager : public base::RefCounted<MailboxManager> {
+ public:
+ MailboxManager();
+
+ // Generate a unique mailbox name signed with the manager's private key.
+ void GenerateMailboxName(MailboxName* name);
+
+ // Remove the texture definition from the named mailbox and empty the mailbox.
+ TextureDefinition* ConsumeTexture(unsigned target, const MailboxName& name);
+
+ // Put the texture definition in the named mailbox.
+ bool ProduceTexture(unsigned target,
+ const MailboxName& name,
+ TextureDefinition* definition,
+ TextureManager* owner);
+
+ // Destroy any texture definitions and mailboxes owned by the given texture
+ // manager.
+ void DestroyOwnedTextures(TextureManager* owner, bool have_context);
+
+ private:
+ friend class base::RefCounted<MailboxManager>;
+
+ ~MailboxManager();
+
+ void SignMailboxName(MailboxName* name);
+ bool IsMailboxNameValid(const MailboxName& name);
+
+ struct TargetName {
+ TargetName(unsigned target, const MailboxName& name);
+ unsigned target;
+ MailboxName name;
+ };
+
+ static bool TargetNameLess(TargetName lhs, TargetName rhs);
+
+ struct OwnedTextureDefinition {
+ OwnedTextureDefinition(TextureDefinition* definition,
+ TextureManager* owner);
+ ~OwnedTextureDefinition();
+ linked_ptr<TextureDefinition> definition;
+ TextureManager* owner;
+ };
+
+ typedef std::map<
+ TargetName,
+ OwnedTextureDefinition,
+ std::pointer_to_binary_function<TargetName, TargetName, bool> >
+ TextureDefinitionMap;
+
+ crypto::HMAC hmac_;
+ TextureDefinitionMap textures_;
+
+ DISALLOW_COPY_AND_ASSIGN(MailboxManager);
+};
+} // namespage gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_H_
+
+
diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc
new file mode 100644
index 0000000..731ff6f
--- /dev/null
+++ b/gpu/command_buffer/service/texture_definition.cc
@@ -0,0 +1,49 @@
+// 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/texture_definition.h"
+
+namespace gpu {
+namespace gles2 {
+
+TextureDefinition::LevelInfo::LevelInfo(GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ bool cleared)
+ : target(target),
+ internal_format(internal_format),
+ width(width),
+ height(height),
+ depth(depth),
+ border(border),
+ format(format),
+ type(type),
+ cleared(cleared) {
+}
+
+TextureDefinition::TextureDefinition(GLenum target,
+ GLuint service_id,
+ const LevelInfos& level_infos)
+ : target_(target),
+ service_id_(service_id),
+ level_infos_(level_infos) {
+}
+
+TextureDefinition::~TextureDefinition() {
+ DCHECK_EQ(0U, service_id_) << "TextureDefinition leaked texture.";
+}
+
+GLuint TextureDefinition::ReleaseServiceId() {
+ GLuint service_id = service_id_;
+ service_id_ = 0;
+ return service_id;
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_definition.h b/gpu/command_buffer/service/texture_definition.h
new file mode 100644
index 0000000..520c6f8
--- /dev/null
+++ b/gpu/command_buffer/service/texture_definition.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_DEFINITION_H_
+#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_DEFINITION_H_
+
+#include <vector>
+
+#include "base/callback.h"
+#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/gpu_export.h"
+
+namespace gpu {
+namespace gles2 {
+
+// A saved definition of a texture that still exists in the underlying
+// GLShareGroup and can be used to redefine a client visible texture in any
+// context using the same GLShareGroup with the corresponding service ID.
+class GPU_EXPORT TextureDefinition {
+ public:
+ struct LevelInfo {
+ LevelInfo(GLenum target,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ bool cleared);
+ GLenum target;
+ GLenum internal_format;
+ GLsizei width;
+ GLsizei height;
+ GLsizei depth;
+ GLint border;
+ GLenum format;
+ GLenum type;
+ bool cleared;
+ };
+
+ typedef std::vector<std::vector<LevelInfo> > LevelInfos;
+
+ typedef base::Callback<void(TextureDefinition*)> DestroyCallback;
+
+ TextureDefinition(GLenum target,
+ GLuint service_id,
+ const LevelInfos& level_infos);
+ ~TextureDefinition();
+
+ GLenum target() const {
+ return target_;
+ }
+
+ GLuint ReleaseServiceId();
+
+ const LevelInfos& level_infos() const {
+ return level_infos_;
+ }
+
+ private:
+ GLenum target_;
+ GLuint service_id_;
+ std::vector<std::vector<LevelInfo> > level_infos_;
+
+ DISALLOW_COPY_AND_ASSIGN(TextureDefinition);
+};
+
+} // namespage gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_DEFINITION_H_
+
+
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 241fb3e..e97514d 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -8,6 +8,8 @@
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/texture_definition.h"
namespace gpu {
namespace gles2 {
@@ -87,6 +89,34 @@ void TextureManager::Destroy(bool have_context) {
UpdateMemRepresented();
}
+TextureManager::TextureInfo::TextureInfo(TextureManager* manager,
+ GLuint service_id)
+ : manager_(manager),
+ service_id_(service_id),
+ deleted_(false),
+ cleared_(true),
+ num_uncleared_mips_(0),
+ target_(0),
+ min_filter_(GL_NEAREST_MIPMAP_LINEAR),
+ mag_filter_(GL_LINEAR),
+ wrap_s_(GL_REPEAT),
+ wrap_t_(GL_REPEAT),
+ usage_(GL_NONE),
+ max_level_set_(-1),
+ texture_complete_(false),
+ cube_complete_(false),
+ npot_(false),
+ has_been_bound_(false),
+ framebuffer_attachment_count_(0),
+ owned_(true),
+ stream_texture_(false),
+ immutable_(false),
+ estimated_size_(0) {
+ if (manager_) {
+ manager_->StartTracking(this);
+ }
+}
+
TextureManager::TextureInfo::~TextureInfo() {
if (manager_) {
if (owned_ && manager_->have_context_) {
@@ -798,6 +828,106 @@ void TextureManager::SetLevelInfo(
}
}
+TextureDefinition* TextureManager::Save(TextureInfo* info) {
+ DCHECK(info->owned_);
+
+ if (info->IsAttachedToFramebuffer())
+ return NULL;
+
+ if (info->IsImmutable())
+ return NULL;
+
+ TextureDefinition::LevelInfos level_infos(info->level_infos_.size());
+ for (size_t face = 0; face < level_infos.size(); ++face) {
+ GLenum target = info->target() == GL_TEXTURE_2D ?
+ GL_TEXTURE_2D : FaceIndexToGLTarget(face);
+ for (size_t level = 0; level < info->level_infos_[face].size(); ++level) {
+ const TextureInfo::LevelInfo& level_info =
+ info->level_infos_[face][level];
+ level_infos[face].push_back(
+ TextureDefinition::LevelInfo(target,
+ level_info.internal_format,
+ level_info.width,
+ level_info.height,
+ level_info.depth,
+ level_info.border,
+ level_info.format,
+ level_info.type,
+ level_info.cleared));
+
+ SetLevelInfo(info,
+ target,
+ level,
+ GL_RGBA,
+ 0,
+ 0,
+ 0,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ true);
+ }
+ }
+
+ GLuint old_service_id = info->service_id();
+
+ GLuint new_service_id = 0;
+ glGenTextures(1, &new_service_id);
+ info->SetServiceId(new_service_id);
+
+ return new TextureDefinition(info->target(),
+ old_service_id,
+ level_infos);
+}
+
+bool TextureManager::Restore(TextureInfo* info,
+ TextureDefinition* definition) {
+ DCHECK(info->owned_);
+
+ scoped_ptr<TextureDefinition> scoped_definition(definition);
+
+ if (info->IsAttachedToFramebuffer())
+ return false;
+
+ if (info->IsImmutable())
+ return false;
+
+ if (info->target() != definition->target())
+ return false;
+
+ if (info->level_infos_.size() != definition->level_infos().size())
+ return false;
+
+ if (info->level_infos_[0].size() != definition->level_infos()[0].size())
+ return false;
+
+ for (size_t face = 0; face < info->level_infos_.size(); ++face) {
+ GLenum target = info->target() == GL_TEXTURE_2D ?
+ GL_TEXTURE_2D : FaceIndexToGLTarget(face);
+ for (size_t level = 0; level < info->level_infos_[face].size(); ++level) {
+ const TextureDefinition::LevelInfo& level_info =
+ definition->level_infos()[face][level];
+ SetLevelInfo(info,
+ target,
+ level,
+ level_info.internal_format,
+ level_info.width,
+ level_info.height,
+ level_info.depth,
+ level_info.border,
+ level_info.format,
+ level_info.type,
+ level_info.cleared);
+ }
+ }
+
+ GLuint old_service_id = info->service_id();
+ glDeleteTextures(1, &old_service_id);
+ info->SetServiceId(definition->ReleaseServiceId());
+
+ return true;
+}
+
bool TextureManager::SetParameter(
TextureManager::TextureInfo* info, GLenum pname, GLint param) {
DCHECK(info);
@@ -915,7 +1045,6 @@ GLsizei TextureManager::ComputeMipMapCount(
return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
}
-
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 9cdc74a..927711c 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -18,6 +18,8 @@ namespace gpu {
namespace gles2 {
class GLES2Decoder;
+class Display;
+class TextureDefinition;
// This class keeps track of the textures and their sizes so we can do NPOT and
// texture complete checking.
@@ -39,32 +41,7 @@ class GPU_EXPORT TextureManager {
public:
typedef scoped_refptr<TextureInfo> Ref;
- TextureInfo(TextureManager* manager, GLuint service_id)
- : manager_(manager),
- service_id_(service_id),
- deleted_(false),
- cleared_(true),
- num_uncleared_mips_(0),
- target_(0),
- min_filter_(GL_NEAREST_MIPMAP_LINEAR),
- mag_filter_(GL_LINEAR),
- wrap_s_(GL_REPEAT),
- wrap_t_(GL_REPEAT),
- usage_(GL_NONE),
- max_level_set_(-1),
- texture_complete_(false),
- cube_complete_(false),
- npot_(false),
- has_been_bound_(false),
- framebuffer_attachment_count_(0),
- owned_(true),
- stream_texture_(false),
- immutable_(false),
- estimated_size_(0) {
- if (manager_) {
- manager_->StartTracking(this);
- }
- }
+ TextureInfo(TextureManager* manager, GLuint service_id);
GLenum min_filter() const {
return min_filter_;
@@ -223,6 +200,20 @@ class GPU_EXPORT TextureManager {
estimated_size(0) {
}
+ LevelInfo(const LevelInfo& rhs)
+ : cleared(rhs.cleared),
+ target(rhs.target),
+ level(rhs.level),
+ internal_format(rhs.internal_format),
+ width(rhs.width),
+ height(rhs.height),
+ depth(rhs.depth),
+ border(rhs.border),
+ format(rhs.format),
+ type(rhs.type),
+ estimated_size(rhs.estimated_size) {
+ }
+
bool cleared;
GLenum target;
GLint level;
@@ -436,6 +427,13 @@ class GPU_EXPORT TextureManager {
GLenum type,
bool cleared);
+ // Save the texture definition and leave it undefined.
+ TextureDefinition* Save(TextureInfo* info);
+
+ // Redefine all the levels from the texture definition.
+ bool Restore(TextureInfo* info,
+ TextureDefinition* definition);
+
// Sets a mip as cleared.
void SetLevelCleared(TextureInfo* info, GLenum target, GLint level);
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 7db4c10..48c15bf2 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -9,9 +9,10 @@
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/constants.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
-#include "gpu/command_buffer/service/command_buffer_service.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_share_group.h"
@@ -19,7 +20,10 @@
namespace gpu {
-GLManager::GLManager() {
+GLManager::GLManager(gles2::MailboxManager* mailbox_manager,
+ gfx::GLShareGroup* share_group)
+ : mailbox_manager_(mailbox_manager),
+ share_group_(share_group) {
}
GLManager::~GLManager() {
@@ -54,13 +58,12 @@ void GLManager::Initialize(const gfx::Size& size) {
attribs.push_back(16);
attribs.push_back(EGL_NONE);
- share_group_ = new gfx::GLShareGroup;
command_buffer_.reset(new CommandBufferService);
ASSERT_TRUE(command_buffer_->Initialize())
<< "could not create command buffer service";
decoder_.reset(::gpu::gles2::GLES2Decoder::Create(
- new gles2::ContextGroup(false)));
+ new gles2::ContextGroup(mailbox_manager_.get(), false)));
gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
decoder_.get(),
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index cacf47a..b25bbfb 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -25,6 +25,7 @@ class GpuScheduler;
namespace gles2 {
+class MailboxManager;
class GLES2Decoder;
class GLES2CmdHelper;
class GLES2Implementation;
@@ -33,7 +34,8 @@ class GLES2Implementation;
class GLManager {
public:
- GLManager();
+ GLManager(gles2::MailboxManager* mailbox_manager,
+ gfx::GLShareGroup* share_group);
~GLManager();
void Initialize(const gfx::Size& size);
@@ -45,6 +47,7 @@ class GLManager {
void PumpCommands();
bool GetBufferChanged(int32 transfer_buffer_id);
+ scoped_refptr<gles2::MailboxManager> mailbox_manager_;
scoped_refptr<gfx::GLShareGroup> share_group_;
scoped_ptr<CommandBufferService> command_buffer_;
scoped_ptr<gles2::GLES2Decoder> decoder_;
diff --git a/gpu/command_buffer/tests/gl_texture_mailbox_unittests.cc b/gpu/command_buffer/tests/gl_texture_mailbox_unittests.cc
new file mode 100644
index 0000000..9f13344
--- /dev/null
+++ b/gpu/command_buffer/tests/gl_texture_mailbox_unittests.cc
@@ -0,0 +1,172 @@
+// 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.
+
+#ifndef GL_GLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+#endif
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/tests/gl_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/gl/gl_share_group.h"
+
+namespace gpu {
+
+namespace {
+uint32 ReadTexel(GLuint id, GLint x, GLint y) {
+ GLint old_fbo = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
+
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ id,
+ 0);
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ uint32 texel;
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
+
+ glDeleteFramebuffers(1, &fbo);
+
+ return texel;
+}
+}
+
+class GLTextureMailboxTest : public testing::Test {
+ protected:
+ GLTextureMailboxTest() {
+ gles2::MailboxManager* mailbox_manager = new gles2::MailboxManager;
+ gfx::GLShareGroup* share_group = new gfx::GLShareGroup;
+ gl1_.reset(new GLManager(mailbox_manager, share_group));
+ gl2_.reset(new GLManager(mailbox_manager, share_group));
+ }
+
+ virtual void SetUp() {
+ gl1_->Initialize(gfx::Size(4, 4));
+ gl2_->Initialize(gfx::Size(4, 4));
+ }
+
+ virtual void TearDown() {
+ gl1_->Destroy();
+ gl2_->Destroy();
+ }
+
+ scoped_ptr<GLManager> gl1_;
+ scoped_ptr<GLManager> gl2_;
+};
+
+TEST_F(GLTextureMailboxTest, ProduceAndConsumeTexture) {
+ gl1_->MakeCurrent();
+
+ GLbyte mailbox1[GL_MAILBOX_SIZE_CHROMIUM];
+ glGenMailboxCHROMIUM(mailbox1);
+
+ GLbyte mailbox2[GL_MAILBOX_SIZE_CHROMIUM];
+ glGenMailboxCHROMIUM(mailbox2);
+
+ GLuint tex1;
+ glGenTextures(1, &tex1);
+
+ glBindTexture(GL_TEXTURE_2D, tex1);
+ uint32 source_pixel = 0xFF0000FF;
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_RGBA,
+ 1, 1,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ &source_pixel);
+
+ glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
+ glFlush();
+
+ gl2_->MakeCurrent();
+
+ GLuint tex2;
+ glGenTextures(1, &tex2);
+
+ glBindTexture(GL_TEXTURE_2D, tex2);
+ glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox1);
+ EXPECT_EQ(source_pixel, ReadTexel(tex2, 0, 0));
+ glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
+ glFlush();
+
+ gl1_->MakeCurrent();
+
+ glBindTexture(GL_TEXTURE_2D, tex1);
+ glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2);
+ EXPECT_EQ(source_pixel, ReadTexel(tex1, 0, 0));
+}
+
+TEST_F(GLTextureMailboxTest, ProduceTextureValidatesKey) {
+ GLuint tex;
+ glGenTextures(1, &tex);
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ uint32 source_pixel = 0xFF0000FF;
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_RGBA,
+ 1, 1,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ &source_pixel);
+
+ GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
+ glGenMailboxCHROMIUM(invalid_mailbox);
+ ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
+
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ glProduceTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
+ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
+
+ // Ensure level 0 is still intact after glProduceTextureCHROMIUM fails.
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+}
+
+TEST_F(GLTextureMailboxTest, ConsumeTextureValidatesKey) {
+ GLuint tex;
+ glGenTextures(1, &tex);
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+ uint32 source_pixel = 0xFF0000FF;
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_RGBA,
+ 1, 1,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ &source_pixel);
+
+ GLbyte invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM];
+ glGenMailboxCHROMIUM(invalid_mailbox);
+ ++invalid_mailbox[GL_MAILBOX_SIZE_CHROMIUM - 1];
+
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ glConsumeTextureCHROMIUM(GL_TEXTURE_2D, invalid_mailbox);
+ EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError());
+
+ // Ensure level 0 is still intact after glConsumeTextureCHROMIUM fails.
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+ EXPECT_EQ(source_pixel, ReadTexel(tex, 0, 0));
+ EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+}
+} // namespace gpu
+
diff --git a/gpu/command_buffer/tests/gl_unittests.cc b/gpu/command_buffer/tests/gl_unittests.cc
index 1a45349..921f5f2f 100644
--- a/gpu/command_buffer/tests/gl_unittests.cc
+++ b/gpu/command_buffer/tests/gl_unittests.cc
@@ -2,16 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef GL_GLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+#endif
+
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/tests/gl_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/gl/gl_share_group.h"
namespace gpu {
class GLTest : public testing::Test {
protected:
+ GLTest() : gl_(new gles2::MailboxManager, new gfx::GLShareGroup) {
+ }
+
virtual void SetUp() {
gl_.Initialize(gfx::Size(4, 4));
}
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index a1988ad..d9e0121 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -15,6 +15,7 @@
},
'dependencies': [
'../base/base.gyp:base',
+ '../crypto/crypto.gyp:crypto',
'../ui/gfx/gl/gl.gyp:gl',
'../ui/gfx/surface/surface.gyp:surface',
'../ui/ui.gyp:ui',
@@ -53,6 +54,8 @@
'command_buffer/service/gpu_switches.cc',
'command_buffer/service/id_manager.h',
'command_buffer/service/id_manager.cc',
+ 'command_buffer/service/mailbox_manager.cc',
+ 'command_buffer/service/mailbox_manager.h',
'command_buffer/service/mocks.h',
'command_buffer/service/program_manager.h',
'command_buffer/service/program_manager.cc',
@@ -66,6 +69,8 @@
'command_buffer/service/shader_translator.cc',
'command_buffer/service/stream_texture.h',
'command_buffer/service/stream_texture_manager.h',
+ 'command_buffer/service/texture_definition.cc',
+ 'command_buffer/service/texture_definition.h',
'command_buffer/service/texture_manager.h',
'command_buffer/service/texture_manager.cc',
'command_buffer/service/vertex_attrib_manager.h',
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index bc07fae..54912d2 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -87,7 +87,7 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config,
if (!command_buffer->Initialize())
return NULL;
- gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(true));
+ gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(NULL, true));
decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
if (!decoder_.get())
diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi
index 43646c8..0de1c3e 100644
--- a/gpu/gpu_common.gypi
+++ b/gpu/gpu_common.gypi
@@ -223,6 +223,7 @@
'command_buffer/tests/gl_tests_main.cc',
'command_buffer/tests/gl_manager.cc',
'command_buffer/tests/gl_manager.h',
+ 'command_buffer/tests/gl_texture_mailbox_unittests.cc',
'command_buffer/tests/gl_unittests.cc',
],
},
diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h
index 8effd30..45943a0 100644
--- a/third_party/khronos/GLES2/gl2ext.h
+++ b/third_party/khronos/GLES2/gl2ext.h
@@ -1982,6 +1982,26 @@ typedef void (GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUM) (GLenum target, GLenum sour
#define GL_COMMANDS_ISSUED_CHROMIUM 0x84F2
#endif
+/* GL_CHROMIUM_texture_mailbox */
+#ifndef GL_CHROMIUM_texture_mailbox
+#define GL_CHROMIUM_texture_mailbox 1
+#define GL_MAILBOX_SIZE_CHROMIUM 64
+#ifdef GL_GLEXT_PROTOTYPES
+#define glGenMailboxCHROMIUM GLES2_GET_FUN(GenMailboxCHROMIUM)
+#define glProduceTextureCHROMIUM GLES2_GET_FUN(ProduceTextureCHROMIUM)
+#define glConsumeTextureCHROMIUM GLES2_GET_FUN(ConsumeTextureCHROMIUM)
+#if !defined(GLES2_USE_CPP_BINDINGS)
+GL_APICALL void GL_APIENTRY glGenMailboxCHROMIUM (GLbyte* mailbox);
+GL_APICALL void GL_APIENTRY glProduceTextureCHROMIUM (GLenum target, const GLbyte* mailbox);
+GL_APICALL void GL_APIENTRY glConsumeTextureCHROMIUM (GLenum target, const GLbyte* mailbox);
+#endif
+#else
+typedef void (GL_APIENTRYP PFNGLGENMAILBOXCHROMIUM) (GLbyte* mailbox);
+typedef void (GL_APIENTRYP PFNGLPRODUCETEXTURECHROMIUM) (GLenum target, const GLbyte* mailbox);
+typedef void (GL_APIENTRYP PFNGLCONSUMETEXTURECHROMIUM) (GLenum target, const GLbyte* mailbox);
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index d9db876..36b7814 100644
--- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -399,7 +399,7 @@ bool GLInProcessContext::Initialize(const gfx::Size& size,
bool bind_generates_resource = false;
decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group ?
context_group->decoder_->GetContextGroup() :
- new ::gpu::gles2::ContextGroup(bind_generates_resource)));
+ new ::gpu::gles2::ContextGroup(NULL, bind_generates_resource)));
gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
decoder_.get(),