summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-17 10:19:09 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-17 10:19:09 +0000
commitc4485aad698e143020b8177d688005d1a1705223 (patch)
treee6fb0ddfda378597f540f5650851492e7b26b801
parent40b2d96a694b5dcdf9883d7296c132115670e0a9 (diff)
downloadchromium_src-c4485aad698e143020b8177d688005d1a1705223.zip
chromium_src-c4485aad698e143020b8177d688005d1a1705223.tar.gz
chromium_src-c4485aad698e143020b8177d688005d1a1705223.tar.bz2
Add a command to lose the context
BUG=166020 Review URL: https://chromiumcodereview.appspot.com/11568029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173441 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_lose_context.txt55
-rw-r--r--gpu/GLES2/gl2chromium.h1
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py17
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h5
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h2
-rw-r--r--gpu/command_buffer/client/gles2_implementation_impl_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h11
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h1
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h1
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h3
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt3
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h38
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h15
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_autogen.h1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h10
-rw-r--r--gpu/command_buffer/service/context_group.cc47
-rw-r--r--gpu/command_buffer/service/context_group.h18
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc16
-rw-r--r--gpu/command_buffer/service/feature_info.cc1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc52
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc10
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_autogen.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h8
-rw-r--r--gpu/command_buffer/tests/gl_lose_context_chromium_unittests.cc63
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc12
-rw-r--r--gpu/command_buffer/tests/gl_manager.h3
-rw-r--r--gpu/command_buffer/tests/gl_test_utils.cc7
-rw-r--r--gpu/command_buffer/tests/gl_test_utils.h2
-rw-r--r--gpu/gpu.gyp1
-rw-r--r--third_party/khronos/GLES2/gl2ext.h9
-rw-r--r--third_party/khronos/README.chromium15
37 files changed, 411 insertions, 40 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_lose_context.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_lose_context.txt
new file mode 100644
index 0000000..a7ff30c
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_lose_context.txt
@@ -0,0 +1,55 @@
+Name
+
+ CHROMIUM_lose_context
+
+Name Strings
+
+ GL_CHROMIUM_lose_context
+
+Version
+
+ Last Modifed Date: December 17, 2012
+
+Dependencies
+
+ OpenGL ES 2.0 is required.
+
+Overview
+
+ This extension allows an application to force a lost context event.
+ This is useful for debugging that an app can correctly handle the context
+ becoming lost.
+
+Issues
+
+ None
+
+New Tokens
+
+ None
+
+New Procedures and Functions
+
+ void LoseContextCHROMIUM (GLenum current, GLenum other)
+
+ Causes the current context and all other contexts in the same share group
+ to become lost. <current> and <other> can each be one of:
+
+ GL_GUILTY_CONTEXT_RESET_EXT
+ GL_INNOCENT_CONTEXT_RESET_EXT
+ GL_UNKNOWN_CONTEXT_RESET_EXT
+
+ INVALID_ENUM is generated if <current> or <other> is not one of the values
+ mentioned above.
+
+Errors
+
+ None.
+
+New State
+
+ None.
+
+Revision History
+
+ 12/17/2012 Documented the extension
diff --git a/gpu/GLES2/gl2chromium.h b/gpu/GLES2/gl2chromium.h
index 8598052..7cc84f0 100644
--- a/gpu/GLES2/gl2chromium.h
+++ b/gpu/GLES2/gl2chromium.h
@@ -227,6 +227,7 @@
#define glAsyncTexSubImage2DCHROMIUM GLES2_GET_FUN(AsyncTexSubImage2DCHROMIUM)
#define glAsyncTexImage2DCHROMIUM GLES2_GET_FUN(AsyncTexImage2DCHROMIUM)
#define glDiscardFramebufferEXT GLES2_GET_FUN(DiscardFramebufferEXT)
+#define glLoseContextCHROMIUM GLES2_GET_FUN(LoseContextCHROMIUM)
#endif // GPU_GLES2_GL2CHROMIUM_H_
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 8ea1d3c..9babf73 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1114,6 +1114,14 @@ _ENUM_LISTS = {
'true',
],
},
+ 'ResetStatus': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_GUILTY_CONTEXT_RESET_ARB',
+ 'GL_INNOCENT_CONTEXT_RESET_ARB',
+ 'GL_UNKNOWN_CONTEXT_RESET_ARB',
+ ],
+ },
}
# This table specifies the different pepper interfaces that are supported for
@@ -2296,6 +2304,12 @@ _FUNCTION_INFO = {
'client_test': False,
'extension': True,
},
+ 'LoseContextCHROMIUM': {
+ 'type': 'Manual',
+ 'impl_func': True,
+ 'extension': True,
+ 'chromium': True,
+ },
}
@@ -3354,7 +3368,8 @@ class ManualHandler(CustomHandler):
def WriteGLES2Implementation(self, func, file):
"""Overrriden from TypeHandler."""
- pass
+ if func.GetInfo('impl_func'):
+ super(ManualHandler, self).WriteGLES2Implementation(func, file)
def WriteGLES2ImplementationHeader(self, func, file):
"""Overrriden from TypeHandler."""
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index b4d8e0f..dff3135 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -715,6 +715,9 @@ void GLES2DiscardFramebufferEXT(
GLenum target, GLsizei count, const GLenum* attachments) {
gles2::GetGLContext()->DiscardFramebufferEXT(target, count, attachments);
}
+void GLES2LoseContextCHROMIUM(GLenum current, GLenum other) {
+ gles2::GetGLContext()->LoseContextCHROMIUM(current, other);
+}
namespace gles2 {
@@ -1048,6 +1051,8 @@ NameToFunc g_gles2_function_table[] = {
glAsyncTexImage2DCHROMIUM), },
{ "glDiscardFramebufferEXT", reinterpret_cast<GLES2FunctionPointer>(
glDiscardFramebufferEXT), },
+ { "glLoseContextCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(
+ glLoseContextCHROMIUM), },
{ 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 66a5c8a5..18cf105 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1980,5 +1980,12 @@
}
}
+ void LoseContextCHROMIUM(GLenum current, GLenum other) {
+ gles2::LoseContextCHROMIUM* c = GetCmdSpace<gles2::LoseContextCHROMIUM>();
+ if (c) {
+ c->Init(current, other);
+ }
+ }
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index b0ed75f..efaaa28 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -522,5 +522,7 @@ virtual void AsyncTexImage2DCHROMIUM(
virtual void DiscardFramebufferEXT(
GLenum target, GLsizei count, const GLenum* attachments) OVERRIDE;
+virtual void LoseContextCHROMIUM(GLenum current, GLenum other) OVERRIDE;
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 57aa0cd..0fc3a4d 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -1696,5 +1696,12 @@ void GLES2Implementation::DiscardFramebufferEXT(
CheckGLError();
}
+void GLES2Implementation::LoseContextCHROMIUM(GLenum current, GLenum other) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLoseContextCHROMIUM(" << GLES2Util::GetStringEnum(current) << ", " << GLES2Util::GetStringEnum(other) << ")"); // NOLINT
+ helper_->LoseContextCHROMIUM(current, other);
+ CheckGLError();
+}
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_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 f23a512..2de2e54 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -1786,5 +1786,16 @@ TEST_F(GLES2ImplementationTest, DiscardFramebufferEXT) {
gl_->DiscardFramebufferEXT(1, 2, &expected.data[0][0]);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+
+TEST_F(GLES2ImplementationTest, LoseContextCHROMIUM) {
+ struct Cmds {
+ LoseContextCHROMIUM cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1, 2);
+
+ gl_->LoseContextCHROMIUM(1, 2);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 163361d..f295bdf 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -301,5 +301,6 @@ virtual void AsyncTexImage2DCHROMIUM(
const void* pixels) = 0;
virtual void DiscardFramebufferEXT(
GLenum target, GLsizei count, const GLenum* attachments) = 0;
+virtual void LoseContextCHROMIUM(GLenum current, GLenum other) = 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 f3d51d8..80e5607 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -333,5 +333,6 @@ virtual void AsyncTexImage2DCHROMIUM(
const void* pixels) OVERRIDE;
virtual void DiscardFramebufferEXT(
GLenum target, GLsizei count, const GLenum* attachments) OVERRIDE;
+virtual void LoseContextCHROMIUM(GLenum current, GLenum other) 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 cf516e3..bc55938 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -627,5 +627,8 @@ void GLES2InterfaceStub::DiscardFramebufferEXT(
GLenum /* target */, GLsizei /* count */,
const GLenum* /* attachments */) {
}
+void GLES2InterfaceStub::LoseContextCHROMIUM(
+ GLenum /* current */, GLenum /* other */) {
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index fb53030..2664631 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -206,3 +206,6 @@ 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);
GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei count, const GLenum* attachments);
+GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM (GLenum current, GLenum other);
+
+
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index d7e887d..ca9c90b 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -10830,6 +10830,44 @@ COMPILE_ASSERT(offsetof(DiscardFramebufferEXTImmediate, target) == 4,
COMPILE_ASSERT(offsetof(DiscardFramebufferEXTImmediate, count) == 8,
OffsetOf_DiscardFramebufferEXTImmediate_count_not_8);
+struct LoseContextCHROMIUM {
+ typedef LoseContextCHROMIUM ValueType;
+ static const CommandId kCmdId = kLoseContextCHROMIUM;
+ 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 _current, GLenum _other) {
+ SetHeader();
+ current = _current;
+ other = _other;
+ }
+
+ void* Set(void* cmd, GLenum _current, GLenum _other) {
+ static_cast<ValueType*>(cmd)->Init(_current, _other);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 current;
+ uint32 other;
+};
+
+COMPILE_ASSERT(sizeof(LoseContextCHROMIUM) == 12,
+ Sizeof_LoseContextCHROMIUM_is_not_12);
+COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, header) == 0,
+ OffsetOf_LoseContextCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, current) == 4,
+ OffsetOf_LoseContextCHROMIUM_current_not_4);
+COMPILE_ASSERT(offsetof(LoseContextCHROMIUM, other) == 8,
+ OffsetOf_LoseContextCHROMIUM_other_not_8);
+
#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 54795a7..80a2768 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4364,5 +4364,20 @@ TEST_F(GLES2FormatTest, DiscardFramebufferEXTImmediate) {
// TODO(gman): Check that data was inserted;
}
+TEST_F(GLES2FormatTest, LoseContextCHROMIUM) {
+ LoseContextCHROMIUM& cmd = *GetBufferAs<LoseContextCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<GLenum>(12));
+ EXPECT_EQ(static_cast<uint32>(LoseContextCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.current);
+ EXPECT_EQ(static_cast<GLenum>(12), cmd.other);
+ 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 0a7a577..13f6170 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -247,6 +247,7 @@
OP(AsyncTexImage2DCHROMIUM) /* 490 */ \
OP(DiscardFramebufferEXT) /* 491 */ \
OP(DiscardFramebufferEXTImmediate) /* 492 */ \
+ OP(LoseContextCHROMIUM) /* 493 */ \
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
index 944c16f..00e1f0ea 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -42,6 +42,7 @@ static std::string GetStringReadPixelType(uint32 value);
static std::string GetStringRenderBufferFormat(uint32 value);
static std::string GetStringRenderBufferParameter(uint32 value);
static std::string GetStringRenderBufferTarget(uint32 value);
+static std::string GetStringResetStatus(uint32 value);
static std::string GetStringShaderBinaryFormat(uint32 value);
static std::string GetStringShaderParameter(uint32 value);
static std::string GetStringShaderPrecision(uint32 value);
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 332d321..447efff 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -1134,6 +1134,16 @@ std::string GLES2Util::GetStringRenderBufferTarget(uint32 value) {
string_table, arraysize(string_table), value);
}
+std::string GLES2Util::GetStringResetStatus(uint32 value) {
+ static EnumToString string_table[] = {
+ { GL_GUILTY_CONTEXT_RESET_ARB, "GL_GUILTY_CONTEXT_RESET_ARB" },
+ { GL_INNOCENT_CONTEXT_RESET_ARB, "GL_INNOCENT_CONTEXT_RESET_ARB" },
+ { GL_UNKNOWN_CONTEXT_RESET_ARB, "GL_UNKNOWN_CONTEXT_RESET_ARB" },
+ };
+ return GLES2Util::GetQualifiedEnumString(
+ string_table, arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringShaderBinaryFormat(uint32 value) {
return GLES2Util::GetQualifiedEnumString(
NULL, 0, value);
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index d8487c7..abf262d 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -36,7 +36,6 @@ ContextGroup::ContextGroup(
: mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager),
image_manager_(image_manager ? image_manager : new ImageManager),
memory_tracker_(memory_tracker),
- num_contexts_(0),
enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnforceGLMinimums)),
bind_generates_resource_(bind_generates_resource),
@@ -71,10 +70,13 @@ static void GetIntegerv(GLenum pname, uint32* var) {
*var = value;
}
-bool ContextGroup::Initialize(const DisallowedFeatures& disallowed_features,
- const char* allowed_features) {
- if (num_contexts_ > 0) {
- ++num_contexts_;
+bool ContextGroup::Initialize(
+ GLES2Decoder* decoder,
+ const DisallowedFeatures& disallowed_features,
+ const char* allowed_features) {
+ // If we've already initialized the group just add the context.
+ if (HaveContexts()) {
+ decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder));
return true;
}
@@ -201,14 +203,31 @@ bool ContextGroup::Initialize(const DisallowedFeatures& disallowed_features,
return false;
}
- ++num_contexts_;
+ decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder));
return true;
}
-void ContextGroup::Destroy(bool have_context) {
- DCHECK(num_contexts_ > 0);
- if (--num_contexts_ > 0)
+namespace {
+
+bool IsNull(const base::WeakPtr<gles2::GLES2Decoder>& decoder) {
+ return !decoder;
+}
+
+} // namespace anonymous
+
+bool ContextGroup::HaveContexts() {
+ decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), IsNull),
+ decoders_.end());
+ return !decoders_.empty();
+}
+
+void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) {
+ decoders_.erase(std::remove(decoders_.begin(), decoders_.end(), decoder),
+ decoders_.end());
+ // If we still have contexts do nothing.
+ if (HaveContexts()) {
return;
+ }
if (buffer_manager_ != NULL) {
buffer_manager_->Destroy(have_context);
@@ -263,8 +282,16 @@ uint32 ContextGroup::GetMemRepresented() const {
return total;
}
+void ContextGroup::LoseContexts(GLenum reset_status) {
+ for (size_t ii = 0; ii < decoders_.size(); ++ii) {
+ if (decoders_[ii]) {
+ decoders_[ii]->LoseContext(reset_status);
+ }
+ }
+}
+
ContextGroup::~ContextGroup() {
- CHECK(num_contexts_ == 0);
+ CHECK(!HaveContexts());
}
bool ContextGroup::CheckGLFeature(GLint min_required, GLint* v) {
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index c459c56..064e36f 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -6,11 +6,13 @@
#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
#include "gpu/command_buffer/service/feature_info.h"
@@ -50,12 +52,14 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
// This should only be called by GLES2Decoder. This must be paired with a
// call to destroy if it succeeds.
- bool Initialize(const DisallowedFeatures& disallowed_features,
- const char* allowed_features);
+ bool Initialize(
+ GLES2Decoder* decoder,
+ const DisallowedFeatures& disallowed_features,
+ const char* allowed_features);
// Destroys all the resources when called for the last context in the group.
// It should only be called by GLES2Decoder.
- void Destroy(bool have_context);
+ void Destroy(GLES2Decoder* decoder, bool have_context);
MailboxManager* mailbox_manager() const {
return mailbox_manager_.get();
@@ -145,6 +149,9 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
uint32 GetMemRepresented() const;
+ // Loses all the context associated with this group.
+ void LoseContexts(GLenum reset_status);
+
private:
friend class base::RefCounted<ContextGroup>;
~ContextGroup();
@@ -153,14 +160,13 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
bool CheckGLFeatureU(GLint min_required, uint32* v);
bool QueryGLFeature(GLenum pname, GLint min_required, GLint* v);
bool QueryGLFeatureU(GLenum pname, GLint min_required, uint32* v);
+ bool HaveContexts();
scoped_refptr<MailboxManager> mailbox_manager_;
scoped_refptr<ImageManager> image_manager_;
scoped_refptr<MemoryTracker> memory_tracker_;
scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
- // Whether or not this context is initialized.
- int num_contexts_;
bool enforce_gl_minimums_;
bool bind_generates_resource_;
@@ -191,6 +197,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
FeatureInfo::Ref feature_info_;
+ std::vector<base::WeakPtr<gles2::GLES2Decoder> > decoders_;
+
DISALLOW_COPY_AND_ASSIGN(ContextGroup);
};
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 8ae1db3..983130f 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -5,6 +5,7 @@
#include "gpu/command_buffer/service/context_group.h"
#include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -36,6 +37,7 @@ class ContextGroupTest : public testing::Test {
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
+ decoder_.reset(new MockGLES2Decoder());
group_ = ContextGroup::Ref(new ContextGroup(NULL, NULL, NULL, true));
}
@@ -45,6 +47,7 @@ class ContextGroupTest : public testing::Test {
}
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
+ scoped_ptr<MockGLES2Decoder> decoder_;
ContextGroup::Ref group_;
};
@@ -68,7 +71,7 @@ TEST_F(ContextGroupTest, Basic) {
TEST_F(ContextGroupTest, InitializeNoExtensions) {
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
DisallowedFeatures(), "");
- group_->Initialize(DisallowedFeatures(), "");
+ group_->Initialize(decoder_.get(), DisallowedFeatures(), "");
EXPECT_EQ(static_cast<uint32>(TestHelper::kNumVertexAttribs),
group_->max_vertex_attribs());
EXPECT_EQ(static_cast<uint32>(TestHelper::kNumTextureUnits),
@@ -90,7 +93,7 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) {
EXPECT_TRUE(group_->program_manager() != NULL);
EXPECT_TRUE(group_->shader_manager() != NULL);
- group_->Destroy(false);
+ group_->Destroy(decoder_.get(), false);
EXPECT_TRUE(group_->buffer_manager() == NULL);
EXPECT_TRUE(group_->framebuffer_manager() == NULL);
EXPECT_TRUE(group_->renderbuffer_manager() == NULL);
@@ -100,10 +103,11 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) {
}
TEST_F(ContextGroupTest, MultipleContexts) {
+ scoped_ptr<MockGLES2Decoder> decoder2_(new MockGLES2Decoder());
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
DisallowedFeatures(), "");
- group_->Initialize(DisallowedFeatures(), "");
- group_->Initialize(DisallowedFeatures(), "");
+ group_->Initialize(decoder_.get(), DisallowedFeatures(), "");
+ group_->Initialize(decoder2_.get(), DisallowedFeatures(), "");
EXPECT_TRUE(group_->buffer_manager() != NULL);
EXPECT_TRUE(group_->framebuffer_manager() != NULL);
@@ -112,7 +116,7 @@ TEST_F(ContextGroupTest, MultipleContexts) {
EXPECT_TRUE(group_->program_manager() != NULL);
EXPECT_TRUE(group_->shader_manager() != NULL);
- group_->Destroy(false);
+ group_->Destroy(decoder_.get(), false);
EXPECT_TRUE(group_->buffer_manager() != NULL);
EXPECT_TRUE(group_->framebuffer_manager() != NULL);
@@ -121,7 +125,7 @@ TEST_F(ContextGroupTest, MultipleContexts) {
EXPECT_TRUE(group_->program_manager() != NULL);
EXPECT_TRUE(group_->shader_manager() != NULL);
- group_->Destroy(false);
+ group_->Destroy(decoder2_.get(), false);
EXPECT_TRUE(group_->buffer_manager() == NULL);
EXPECT_TRUE(group_->framebuffer_manager() == NULL);
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 2a738b8..a7ca864 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -244,6 +244,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
AddExtensionString("GL_CHROMIUM_copy_texture");
AddExtensionString("GL_CHROMIUM_discard_backbuffer");
AddExtensionString("GL_CHROMIUM_get_error_query");
+ AddExtensionString("GL_CHROMIUM_lose_context");
AddExtensionString("GL_CHROMIUM_pixel_transfer_buffer_object");
AddExtensionString("GL_CHROMIUM_rate_limit_offscreen_context");
AddExtensionString("GL_CHROMIUM_resize");
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a6a3055..2d80b70 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1469,8 +1469,8 @@ class GLES2DecoderImpl : public GLES2Decoder {
// the tracing system.
size_t GetBackbufferMemoryTotal();
- // Returns true if the context was just lost due to e.g. GL_ARB_robustness.
virtual bool WasContextLost() OVERRIDE;
+ virtual void LoseContext(uint32 reset_status) OVERRIDE;
#if defined(OS_MACOSX)
void ReleaseIOSurfaceForTexture(GLuint texture_id);
@@ -2162,7 +2162,7 @@ bool GLES2DecoderImpl::Initialize(
context_ = context;
surface_ = surface;
- if (!group_->Initialize(disallowed_features, allowed_extensions)) {
+ if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
<< "failed to initialize.";
group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
@@ -3059,7 +3059,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
}
if (group_) {
- group_->Destroy(have_context);
+ group_->Destroy(this, have_context);
group_ = NULL;
}
@@ -8869,6 +8869,9 @@ error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
}
bool GLES2DecoderImpl::WasContextLost() {
+ if (reset_status_ != GL_NO_ERROR) {
+ return true;
+ }
if (context_->WasAllocatedUsingRobustnessExtension()) {
GLenum status = GL_NO_ERROR;
if (has_robustness_extension_)
@@ -8877,14 +8880,53 @@ bool GLES2DecoderImpl::WasContextLost() {
// The graphics card was reset. Signal a lost context to the application.
reset_status_ = status;
LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
- << " context lost via ARB/EXT_robustness. Reset status = 0x"
- << std::hex << status << std::dec;
+ << " context lost via ARB/EXT_robustness. Reset status = "
+ << GLES2Util::GetStringEnum(status);
return true;
}
}
return false;
}
+void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
+ // Only loses the context once.
+ if (reset_status_ != GL_NO_ERROR) {
+ return;
+ }
+
+ // Marks this context as lost.
+ reset_status_ = reset_status;
+ current_decoder_error_ = error::kLostContext;
+
+ // Loses the parent's context.
+ if (parent_) {
+ parent_->LoseContext(reset_status);
+ }
+
+ // Loses any child contexts.
+ for (ChildList::iterator it = children_.begin();
+ it != children_.end();
+ ++it) {
+ (*it)->LoseContext(reset_status);
+ }
+}
+
+error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
+ uint32 immediate_data_size, const gles2::LoseContextCHROMIUM& c) {
+ GLenum current = static_cast<GLenum>(c.current);
+ GLenum other = static_cast<GLenum>(c.other);
+ if (!validators_->reset_status.IsValid(current)) {
+ SetGLErrorInvalidEnum("glLoseContextCHROMIUM", current, "current");
+ }
+ if (!validators_->reset_status.IsValid(other)) {
+ SetGLErrorInvalidEnum("glLoseContextCHROMIUM", other, "other");
+ }
+ group_->LoseContexts(other);
+ reset_status_ = current;
+ current_decoder_error_ = error::kLostContext;
+ return error::kLostContext;
+}
+
bool GLES2DecoderImpl::GenQueriesEXTHelper(
GLsizei n, const GLuint* client_ids) {
for (GLsizei ii = 0; ii < n; ++ii) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 4311198..1b36dcb0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -195,8 +195,12 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>,
virtual base::TimeDelta GetTotalProcessingCommandsTime() = 0;
virtual void AddProcessingCommandsTime(base::TimeDelta) = 0;
+ // Returns true if the context was just lost due to e.g. GL_ARB_robustness.
virtual bool WasContextLost() = 0;
+ // Lose this context.
+ virtual void LoseContext(uint32 reset_status) = 0;
+
static bool IsAngle();
// Used for testing only
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index e92ca94..363dfcb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -85,6 +85,7 @@ class MockGLES2Decoder : public GLES2Decoder {
MOCK_METHOD0(GetTotalProcessingCommandsTime, base::TimeDelta());
MOCK_METHOD1(AddProcessingCommandsTime, void(base::TimeDelta));
MOCK_METHOD0(WasContextLost, bool());
+ MOCK_METHOD1(LoseContext, void(uint32 reset_status));
DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder);
};
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 983269b..f644348 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
@@ -66,5 +66,7 @@
// TODO(gman): DiscardFramebufferEXT
// TODO(gman): DiscardFramebufferEXTImmediate
+// TODO(gman): LoseContextCHROMIUM
+
#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 4629284..b2c63fb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -13,6 +13,7 @@
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/cmd_buffer_engine.h"
#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
@@ -97,7 +98,12 @@ void GLES2DecoderTestBase::InitDecoder(
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
DisallowedFeatures(), extensions);
- EXPECT_TRUE(group_->Initialize(DisallowedFeatures(), NULL));
+ // We initialize the ContextGroup with a MockGLES2Decoder so that
+ // we can use the ContextGroup to figure out how the real GLES2Decoder
+ // will initialize itself.
+ mock_decoder_.reset(new MockGLES2Decoder());
+ EXPECT_TRUE(
+ group_->Initialize(mock_decoder_.get(), DisallowedFeatures(), NULL));
AddExpectationsForVertexAttribManager();
@@ -295,7 +301,7 @@ void GLES2DecoderTestBase::TearDown() {
decoder_->Destroy(true);
decoder_.reset();
- group_->Destroy(false);
+ group_->Destroy(mock_decoder_.get(), false);
engine_.reset();
::gfx::GLInterface::SetGLInterface(NULL);
gl_.reset();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 420351e..7a1f975 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -466,6 +466,7 @@ class GLES2DecoderTestBase : public testing::Test {
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
scoped_refptr<gfx::GLSurfaceStub> surface_;
scoped_refptr<gfx::GLContextStub> context_;
+ scoped_ptr<GLES2Decoder> mock_decoder_;
scoped_ptr<GLES2Decoder> decoder_;
GLuint client_buffer_id_;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
index c19ba38..7e41788 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -44,6 +44,7 @@ ValueValidator<GLenum> read_pixel_type;
ValueValidator<GLenum> render_buffer_format;
ValueValidator<GLenum> render_buffer_parameter;
ValueValidator<GLenum> render_buffer_target;
+ValueValidator<GLenum> reset_status;
ValueValidator<GLenum> shader_binary_format;
ValueValidator<GLenum> shader_parameter;
ValueValidator<GLenum> shader_precision;
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 d951e79..1f8535b 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -336,6 +336,12 @@ static GLenum valid_render_buffer_target_table[] = {
GL_RENDERBUFFER,
};
+static GLenum valid_reset_status_table[] = {
+ GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB,
+ GL_UNKNOWN_CONTEXT_RESET_ARB,
+};
+
static GLenum valid_shader_parameter_table[] = {
GL_SHADER_TYPE,
GL_DELETE_STATUS,
@@ -597,6 +603,8 @@ Validators::Validators()
render_buffer_target(
valid_render_buffer_target_table, arraysize(
valid_render_buffer_target_table)),
+ reset_status(
+ valid_reset_status_table, arraysize(valid_reset_status_table)),
shader_binary_format(),
shader_parameter(
valid_shader_parameter_table, arraysize(
diff --git a/gpu/command_buffer/tests/gl_lose_context_chromium_unittests.cc b/gpu/command_buffer/tests/gl_lose_context_chromium_unittests.cc
new file mode 100644
index 0000000..385cc88
--- /dev/null
+++ b/gpu/command_buffer/tests/gl_lose_context_chromium_unittests.cc
@@ -0,0 +1,63 @@
+// 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "base/logging.h"
+#include "gpu/command_buffer/tests/gl_manager.h"
+#include "gpu/command_buffer/tests/gl_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+
+class GLLoseContextTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ GLManager::Options options;
+ gl2_.Initialize(options);
+ options.context_lost_allowed = true;
+ gl1a_.Initialize(options);
+ options.share_group_manager = &gl1a_;
+ gl1b_.Initialize(options);
+ }
+
+ virtual void TearDown() {
+ gl1a_.Destroy();
+ gl1b_.Destroy();
+ gl2_.Destroy();
+ }
+
+ GLManager gl1a_;
+ GLManager gl1b_;
+ GLManager gl2_;
+};
+
+// Test that glLoseContextCHROMIUM loses context in the same
+// share group but not other.
+TEST_F(GLLoseContextTest, ShareGroup) {
+ gl1a_.MakeCurrent();
+ glLoseContextCHROMIUM(
+ GL_GUILTY_CONTEXT_RESET_EXT, GL_INNOCENT_CONTEXT_RESET_EXT);
+
+ uint8 expected_no_draw[] = {
+ GLTestHelper::kCheckClearValue,
+ GLTestHelper::kCheckClearValue,
+ GLTestHelper::kCheckClearValue,
+ GLTestHelper::kCheckClearValue,
+ };
+ // Expect the read will fail.
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw));
+ gl1b_.MakeCurrent();
+ // Expect the read will fail.
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_no_draw));
+ gl2_.MakeCurrent();
+ uint8 expected_draw[] = { 0, 0, 0, 0, };
+ // Expect the read will succeed.
+ EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_draw));
+}
+
+} // namespace gpu
+
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 6ec3097..57abc34 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -29,10 +29,12 @@ GLManager::Options::Options()
share_group_manager(NULL),
share_mailbox_manager(NULL),
virtual_manager(NULL),
- bind_generates_resource(false) {
+ bind_generates_resource(false),
+ context_lost_allowed(false) {
}
-GLManager::GLManager() {
+GLManager::GLManager()
+ : context_lost_allowed_(false) {
}
GLManager::~GLManager() {
@@ -45,6 +47,8 @@ void GLManager::Initialize(const GLManager::Options& options) {
const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
const bool kShareResources = true;
+ context_lost_allowed_ = options.context_lost_allowed;
+
gles2::MailboxManager* mailbox_manager = NULL;
if (options.share_mailbox_manager) {
mailbox_manager = options.share_mailbox_manager->mailbox_manager();
@@ -198,7 +202,9 @@ void GLManager::PumpCommands() {
decoder_->MakeCurrent();
gpu_scheduler_->PutChanged();
::gpu::CommandBuffer::State state = command_buffer_->GetState();
- ASSERT_EQ(::gpu::error::kNoError, state.error);
+ if (!context_lost_allowed_) {
+ ASSERT_EQ(::gpu::error::kNoError, state.error);
+ }
}
bool GLManager::GetBufferChanged(int32 transfer_buffer_id) {
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index 5f42a36..2b24331 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -48,6 +48,8 @@ class GLManager {
GLManager* virtual_manager;
// Whether or not glBindXXX generates a resource.
bool bind_generates_resource;
+ // Whether or not it's ok to lose the context.
+ bool context_lost_allowed;
};
GLManager();
~GLManager();
@@ -87,6 +89,7 @@ class GLManager {
scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_;
scoped_ptr<TransferBuffer> transfer_buffer_;
scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
+ bool context_lost_allowed_;
};
} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc
index f4ea96b..1a3e7c2 100644
--- a/gpu/command_buffer/tests/gl_test_utils.cc
+++ b/gpu/command_buffer/tests/gl_test_utils.cc
@@ -10,6 +10,11 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+// GCC requires these declarations, but MSVC requires they not be present.
+#ifndef COMPILER_MSVC
+const uint8 GLTestHelper::kCheckClearValue;
+#endif
+
bool GLTestHelper::HasExtension(const char* extension) {
std::string extensions(
reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
@@ -108,7 +113,7 @@ bool GLTestHelper::CheckPixels(
const uint8* color) {
GLsizei size = width * height * 4;
scoped_array<uint8> pixels(new uint8[size]);
- memset(pixels.get(), 123, size);
+ memset(pixels.get(), kCheckClearValue, size);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
bool same = true;
for (GLint yy = 0; yy < height; ++yy) {
diff --git a/gpu/command_buffer/tests/gl_test_utils.h b/gpu/command_buffer/tests/gl_test_utils.h
index bd2d380..31de7cd 100644
--- a/gpu/command_buffer/tests/gl_test_utils.h
+++ b/gpu/command_buffer/tests/gl_test_utils.h
@@ -12,6 +12,8 @@
class GLTestHelper {
public:
+ static const uint8 kCheckClearValue = 123u;
+
static bool HasExtension(const char* extension);
static bool CheckGLError(const char* msg, int line);
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index e7bd419..e3ccb37 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -238,6 +238,7 @@
'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc',
'command_buffer/tests/gl_depth_texture_unittest.cc',
'command_buffer/tests/gl_query_unittests.cc',
+ 'command_buffer/tests/gl_lose_context_chromium_unittests.cc',
'command_buffer/tests/gl_manager.cc',
'command_buffer/tests/gl_manager.h',
'command_buffer/tests/gl_pointcoord_unittest.cc',
diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h
index 35a28cb9..6cbca97 100644
--- a/third_party/khronos/GLES2/gl2ext.h
+++ b/third_party/khronos/GLES2/gl2ext.h
@@ -2173,6 +2173,15 @@ typedef void (GL_APIENTRYP PFNGLRELEASETEXIMAGE2DCHROMIUM) (GLenum target, GLint
#define GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM 0x84F5
#endif
+/* GL_CHROMIUM_lose_context */
+#ifndef GL_CHROMIUM_lose_context
+#define GL_CHROMIUM_lose_context 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM (GLenum current, GLenum other);
+#endif
+typedef void (GL_APIENTRYP PFNGLLOSECONTEXTCHROMIUM) (GLenum current, GLenum other);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/third_party/khronos/README.chromium b/third_party/khronos/README.chromium
index 7760f41..36caefa 100644
--- a/third_party/khronos/README.chromium
+++ b/third_party/khronos/README.chromium
@@ -21,20 +21,21 @@ GLES2/gl2.h
- Added include of gl2chromium.h
GLES2/gl2ext.h
- Added Chromium and Angle extensions.
- - Added ANGLE_instanced_arrays
+ - Added GL_ANGLE_instanced_arrays
- Added GL_ARB_robustness (subsetted)
- Added GL_ARB_texture_rectangle (subsetted)
- - Added GL_EXT_framebuffer_multisample
- - Added GL_CHROMIUM_command_buffer_query
+ - Added GL_CHROMIUM_async_pixel_transfers
+ - Added GL_CHROMIUM_bind_uniform_location
- Added GL_CHROMIUM_command_buffer_latency_query
+ - Added GL_CHROMIUM_command_buffer_query
- Added GL_CHROMIUM_copy_texture
- - Added GL_CHROMIUM_bind_uniform_location
- Added GL_CHROMIUM_get_error_query
+ - Added GL_CHROMIUM_gpu_memory_manager
- Added GL_CHROMIUM_iosurface
- - Added GL_CHROMIUM_texture_from_image
+ - Added GL_CHROMIUM_lose_context
- Added GL_CHROMIUM_pixel_transfer_buffer_object
- - Added GL_CHROMIUM_async_pixel_transfers
- - Added GL_CHROMIUM_gpu_memory_manager
+ - Added GL_CHROMIUM_texture_from_image
+ - Added GL_EXT_framebuffer_multisample
- Added GL_NVX_gpu_memory_info
- Added include of gl2chromium.h
EGL/eglplatform.h