1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2015 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief GL_EXT_debug_marker tests
22 *//*--------------------------------------------------------------------*/
23
24#include "es2fDebugMarkerTests.hpp"
25#include "gluContextInfo.hpp"
26#include "gluRenderContext.hpp"
27#include "glwFunctions.hpp"
28#include "glwEnums.hpp"
29#include "tcuTestLog.hpp"
30#include "deRandom.hpp"
31#include "deUniquePtr.hpp"
32
33namespace deqp
34{
35namespace gles2
36{
37namespace Functional
38{
39
40namespace
41{
42
43using std::vector;
44using tcu::TestLog;
45
46void checkSupport (const glu::ContextInfo& ctxInfo)
47{
48	if (!ctxInfo.isExtensionSupported("GL_EXT_debug_marker"))
49	{
50#if (DE_OS == DE_OS_ANDROID)
51		TCU_THROW(TestError, "Support for GL_EXT_debug_marker is mandatory on Android");
52#else
53		TCU_THROW(NotSupportedError, "GL_EXT_debug_marker is not supported");
54#endif
55	}
56	// else no exception thrown
57}
58
59class IsSupportedCase : public TestCase
60{
61public:
62	IsSupportedCase (Context& context)
63		: TestCase(context, "supported", "Is GL_EXT_debug_marker supported")
64	{
65	}
66
67	IterateResult iterate (void)
68	{
69		checkSupport(m_context.getContextInfo());
70		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "GL_EXT_debug_marker is supported");
71		return STOP;
72	}
73};
74
75void getSimpleRndString (vector<char>& dst, de::Random& rnd, int maxLen)
76{
77	const char s_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -_";
78
79	dst.resize(rnd.getInt(0, (int)maxLen));
80
81	for (size_t ndx = 0; ndx < dst.size(); ndx++)
82		dst[ndx] = rnd.choose<char>(DE_ARRAY_BEGIN(s_chars), DE_ARRAY_END(s_chars));
83}
84
85void getComplexRndString (vector<char>& dst, de::Random& rnd, int maxLen)
86{
87	dst.resize(rnd.getInt(0, (int)maxLen));
88
89	for (size_t ndx = 0; ndx < dst.size(); ndx++)
90		dst[ndx] = (char)rnd.getUint8();
91}
92
93enum CallType
94{
95	CALL_TYPE_PUSH_GROUP	= 0,
96	CALL_TYPE_POP_GROUP,
97	CALL_TYPE_INSERT_MARKER,
98
99	CALL_TYPE_LAST
100};
101
102class RandomCase : public TestCase
103{
104public:
105	RandomCase (Context& context)
106		: TestCase(context, "random", "Random GL_EXT_debug_marker usage")
107	{
108	}
109
110	void init (void)
111	{
112		checkSupport(m_context.getContextInfo());
113	}
114
115	IterateResult iterate (void)
116	{
117		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
118		const int				numIters	= 1000;
119		const int				maxMsgLen	= 4096;
120		de::Random				rnd			(0xaf829c0);
121
122		for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
123		{
124			const CallType		callType	= CallType(rnd.getInt(0, CALL_TYPE_LAST-1));
125
126			if (callType == CALL_TYPE_PUSH_GROUP || callType == CALL_TYPE_INSERT_MARKER)
127			{
128				const bool		nullTerminate	= rnd.getBool();
129				const bool		passLength		= rnd.getBool();
130				const bool		complexMsg		= rnd.getBool();
131				vector<char>	message;
132
133				if (complexMsg)
134					getComplexRndString(message, rnd, maxMsgLen);
135				else
136					getSimpleRndString(message, rnd, maxMsgLen);
137
138				if (nullTerminate)
139					message.push_back(char(0));
140
141				{
142					const glw::GLsizei	length	= passLength ? glw::GLsizei(nullTerminate ? message.size()-1 : message.size()) : 0;
143
144					if (callType == CALL_TYPE_PUSH_GROUP)
145						gl.pushGroupMarkerEXT(length, &message[0]);
146					else
147						gl.insertEventMarkerEXT(length, &message[0]);
148				}
149			}
150			else
151				gl.popGroupMarkerEXT();
152		}
153
154		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");
155
156		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
157		return STOP;
158	}
159};
160
161class InvalidCase : public TestCase
162{
163public:
164	InvalidCase (Context& context)
165		: TestCase(context, "invalid", "Invalid GL_EXT_debug_marker usage")
166	{
167	}
168
169	void init (void)
170	{
171		checkSupport(m_context.getContextInfo());
172	}
173
174	IterateResult iterate (void)
175	{
176		const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
177
178		m_testCtx.getLog() << TestLog::Message << "Note: GL_EXT_debug_marker calls must not report an error even if invalid arguments are supplied." << TestLog::EndMessage;
179
180		gl.pushGroupMarkerEXT(-1, "foo");
181		gl.insertEventMarkerEXT(-1, "foo");
182		gl.pushGroupMarkerEXT(0, DE_NULL);
183		gl.insertEventMarkerEXT(0, DE_NULL);
184		gl.pushGroupMarkerEXT(-1, DE_NULL);
185		gl.insertEventMarkerEXT(-1, DE_NULL);
186
187		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");
188
189		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
190		return STOP;
191	}
192};
193
194} // anonymous
195
196tcu::TestCaseGroup* createDebugMarkerTests (Context& context)
197{
198	de::MovePtr<tcu::TestCaseGroup>	debugMarkerGroup	(new tcu::TestCaseGroup(context.getTestContext(), "debug_marker", "GL_EXT_debug_marker tests"));
199
200	debugMarkerGroup->addChild(new IsSupportedCase	(context));
201	debugMarkerGroup->addChild(new RandomCase		(context));
202	debugMarkerGroup->addChild(new InvalidCase		(context));
203
204	return debugMarkerGroup.release();
205}
206
207} // Functional
208} // gles2
209} // deqp
210