• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _TCUTESTLOG_HPP
2 #define _TCUTESTLOG_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Test Log C++ Wrapper.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "qpTestLog.h"
28 #include "tcuTexture.hpp"
29 
30 #include <sstream>
31 
32 namespace tcu
33 {
34 
35 class Surface;
36 class MessageBuilder;
37 class LogImageSet;
38 class LogImage;
39 class LogSection;
40 class LogShaderProgram;
41 class LogShader;
42 class LogSpirVAssemblySource;
43 class LogKernelSource;
44 class LogSampleList;
45 class LogValueInfo;
46 class SampleBuilder;
47 template<typename T> class LogNumber;
48 
49 /*--------------------------------------------------------------------*//*!
50  * \brief Test log
51  *
52  * TestLog provides convinient C++ API for logging. The API has been designed
53  * around stream operators much like STL iostream library. The following
54  * examples demonstrate how to use TestLog.
55  *
56  * \code
57  * TestLog& log = m_testCtx.getLog();
58  *
59  * // Write message to log.
60  * log << TestLog::Message << "Hello, World!" << TestLog::EndMessage;
61  * int myNumber = 3;
62  * log << TestLog::Message << "Diff is " << myNumber << TestLog::EndMessage;
63  *
64  * // Write image
65  * Surface myImage(256, 256);
66  * log << TestLog::Image("TestImage", "My test image", myImage);
67  *
68  * // Multiple commands can be combined:
69  * log << TestLog::Section("Details", "Test case details")
70  *     << TestLog::Message << "Here be dragons" << TestLog::EndMessage
71  *     << TestLog::ImageSet("Result", "Result images")
72  *     << TestLog::Image("ImageA", "Image A", imageA)
73  *     << TestLog::Image("ImageB", "Image B", imageB)
74  *     << TestLog::EndImageSet << TestLog::EndSection;
75  * \endcode
76  *//*--------------------------------------------------------------------*/
77 class TestLog
78 {
79 public:
80 	// Tokens
81 	static const class BeginMessageToken {}			Message;
82 	static const class EndMessageToken {}			EndMessage;
83 	static const class EndImageSetToken {}			EndImageSet;
84 	static const class EndSectionToken {}			EndSection;
85 	static const class EndShaderProgramToken {}		EndShaderProgram;
86 	static const class SampleInfoToken {}			SampleInfo;
87 	static const class EndSampleInfoToken {}		EndSampleInfo;
88 	static const class BeginSampleToken {}			Sample;
89 	static const class EndSampleToken {}			EndSample;
90 	static const class EndSampleListToken {}		EndSampleList;
91 
92 	// Typedefs.
93 	typedef LogImageSet				ImageSet;
94 	typedef LogImage				Image;
95 	typedef LogSection				Section;
96 	typedef LogShaderProgram		ShaderProgram;
97 	typedef LogShader				Shader;
98 	typedef LogSpirVAssemblySource	SpirVAssemblySource;
99 	typedef LogKernelSource			KernelSource;
100 	typedef LogSampleList			SampleList;
101 	typedef LogValueInfo			ValueInfo;
102 	typedef LogNumber<float>		Float;
103 	typedef LogNumber<deInt64>		Integer;
104 
105 	explicit			TestLog					(const char* fileName, deUint32 flags = 0);
106 						~TestLog				(void);
107 
108 	void				writeSessionInfo		(std::string additionalInfo = "");
109 
110 	MessageBuilder		operator<<				(const BeginMessageToken&);
111 	MessageBuilder		message					(void);
112 
113 	TestLog&			operator<<				(const ImageSet& imageSet);
114 	TestLog&			operator<<				(const Image& image);
115 	TestLog&			operator<<				(const EndImageSetToken&);
116 
117 	TestLog&			operator<<				(const Section& section);
118 	TestLog&			operator<<				(const EndSectionToken&);
119 
120 	TestLog&			operator<<				(const ShaderProgram& shaderProgram);
121 	TestLog&			operator<<				(const EndShaderProgramToken&);
122 	TestLog&			operator<<				(const Shader& shader);
123 	TestLog&			operator<<				(const SpirVAssemblySource& module);
124 
125 	TestLog&			operator<<				(const KernelSource& kernelSrc);
126 
127 	template<typename T>
128 	TestLog&			operator<<				(const LogNumber<T>& number);
129 
130 	TestLog&			operator<<				(const SampleList& sampleList);
131 	TestLog&			operator<<				(const SampleInfoToken&);
132 	TestLog&			operator<<				(const ValueInfo& valueInfo);
133 	TestLog&			operator<<				(const EndSampleInfoToken&);
134 	SampleBuilder		operator<<				(const BeginSampleToken&);
135 	TestLog&			operator<<				(const EndSampleListToken&);
136 
137 	// Raw api
138 	void				writeMessage			(const char* message);
139 
140 	void				startImageSet			(const char* name, const char* description);
141 	void				endImageSet				(void);
142 	void				writeImage				(const char* name, const char* description, const ConstPixelBufferAccess& surface, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compressionMode = QP_IMAGE_COMPRESSION_MODE_BEST);
143 	void				writeImage				(const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data);
144 
145 	void				startSection			(const char* name, const char* description);
146 	void				endSection				(void);
147 
148 	void				startShaderProgram		(bool linkOk, const char* linkInfoLog);
149 	void				endShaderProgram		(void);
150 	void				writeShader				(qpShaderType type, const char* source, bool compileOk, const char* infoLog);
151 	void				writeSpirVAssemblySource(const char* source);
152 	void				writeKernelSource		(const char* source);
153 	void				writeCompileInfo		(const char* name, const char* description, bool compileOk, const char* infoLog);
154 
155 	void				writeFloat				(const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value);
156 	void				writeInteger			(const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value);
157 
158 	void				startEglConfigSet		(const char* name, const char* description);
159 	void				writeEglConfig			(const qpEglConfigInfo* config);
160 	void				endEglConfigSet			(void);
161 
162 	void				startCase				(const char* testCasePath, qpTestCaseType testCaseType);
163 	void				endCase					(qpTestResult result, const char* description);
164 	void				terminateCase			(qpTestResult result);
165 
166 	void				startTestsCasesTime		(void);
167 	void				endTestsCasesTime		(void);
168 
169 	void				startSampleList			(const std::string& name, const std::string& description);
170 	void				startSampleInfo			(void);
171 	void				writeValueInfo			(const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag);
172 	void				endSampleInfo			(void);
173 	void				startSample				(void);
174 	void				writeSampleValue		(double value);
175 	void				writeSampleValue		(deInt64 value);
176 	void				endSample				(void);
177 	void				endSampleList			(void);
178 
179 	void				writeRaw				(const char* rawContents);
180 
181 	bool				isShaderLoggingEnabled	(void);
182 
183 	void				supressLogging			(bool value);
184 	bool				isSupressLogging		(void);
185 private:
186 						TestLog					(const TestLog& other); // Not allowed!
187 	TestLog&			operator=				(const TestLog& other); // Not allowed!
188 
189 	qpTestLog*			m_log;
190 	bool				m_logSupressed;
191 };
192 
193 class MessageBuilder
194 {
195 public:
MessageBuilder(TestLog * log)196 	explicit				MessageBuilder		(TestLog* log) : m_log(log) {}
~MessageBuilder(void)197 							~MessageBuilder		(void) {}
198 
toString(void) const199 	std::string				toString			(void) const { return m_str.str(); }
200 
201 	TestLog&				operator<<			(const TestLog::EndMessageToken&);
202 
203 	template <typename T>
204 	MessageBuilder&			operator<<			(const T& value);
205 
206 							MessageBuilder		(const MessageBuilder& other);
207 	MessageBuilder&			operator=			(const MessageBuilder& other);
208 
209 private:
210 	TestLog*				m_log;
211 	std::ostringstream		m_str;
212 };
213 
214 class SampleBuilder
215 {
216 public:
SampleBuilder(TestLog * log)217 							SampleBuilder		(TestLog* log) : m_log(log) {}
218 
operator <<(int v)219 	SampleBuilder&			operator<<			(int v)		{ m_values.push_back(Value((deInt64)v));	return *this; }
operator <<(deInt64 v)220 	SampleBuilder&			operator<<			(deInt64 v)	{ m_values.push_back(Value(v));				return *this; }
operator <<(float v)221 	SampleBuilder&			operator<<			(float v)	{ m_values.push_back(Value((double)v));		return *this; }
operator <<(double v)222 	SampleBuilder&			operator<<			(double v)	{ m_values.push_back(Value(v));				return *this; }
223 
224 	TestLog&				operator<<			(const TestLog::EndSampleToken&);
225 
226 private:
227 	struct Value
228 	{
229 		enum Type { TYPE_INT64 = 0, TYPE_FLOAT64, TYPE_LAST };
230 
231 		Type	type;
232 		union
233 		{
234 			deInt64		int64;
235 			double		float64;
236 		} value;
237 
Valuetcu::SampleBuilder::Value238 		Value (void)		: type(TYPE_LAST)		{ value.int64 = 0;		}
Valuetcu::SampleBuilder::Value239 		Value (double v)	: type(TYPE_FLOAT64)	{ value.float64 = v;	}
Valuetcu::SampleBuilder::Value240 		Value (deInt64 v)	: type(TYPE_INT64)		{ value.int64 = v;		}
241 	};
242 
243 	TestLog*				m_log;
244 	std::vector<Value>		m_values;
245 };
246 
247 class LogImageSet
248 {
249 public:
LogImageSet(const std::string & name,const std::string & description)250 	LogImageSet (const std::string& name, const std::string& description)
251 		: m_name		(name)
252 		, m_description	(description)
253 	{
254 	}
255 
256 	void write (TestLog& log) const;
257 
258 private:
259 	std::string		m_name;
260 	std::string		m_description;
261 };
262 
263 // \note Doesn't take copy of surface contents
264 class LogImage
265 {
266 public:
267 	LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
268 
269 	LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
270 
271 	LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
272 
273 	void write (TestLog& log) const;
274 
275 private:
276 	std::string				m_name;
277 	std::string				m_description;
278 	ConstPixelBufferAccess	m_access;
279 	Vec4					m_scale;
280 	Vec4					m_bias;
281 	qpImageCompressionMode	m_compression;
282 };
283 
284 class LogSection
285 {
286 public:
LogSection(const std::string & name,const std::string & description)287 	LogSection (const std::string& name, const std::string& description)
288 		: m_name		(name)
289 		, m_description	(description)
290 	{
291 	}
292 
293 	void write (TestLog& log) const;
294 
295 private:
296 	std::string		m_name;
297 	std::string		m_description;
298 };
299 
300 class LogShaderProgram
301 {
302 public:
LogShaderProgram(bool linkOk,const std::string & linkInfoLog)303 	LogShaderProgram (bool linkOk, const std::string& linkInfoLog)
304 		: m_linkOk		(linkOk)
305 		, m_linkInfoLog	(linkInfoLog)
306 	{
307 	}
308 
309 	void write (TestLog& log) const;
310 
311 private:
312 	bool			m_linkOk;
313 	std::string		m_linkInfoLog;
314 };
315 
316 class LogShader
317 {
318 public:
LogShader(qpShaderType type,const std::string & source,bool compileOk,const std::string & infoLog)319 	LogShader (qpShaderType type, const std::string& source, bool compileOk, const std::string& infoLog)
320 		: m_type		(type)
321 		, m_source		(source)
322 		, m_compileOk	(compileOk)
323 		, m_infoLog		(infoLog)
324 	{
325 	}
326 
327 	void write (TestLog& log) const;
328 
329 private:
330 	qpShaderType	m_type;
331 	std::string		m_source;
332 	bool			m_compileOk;
333 	std::string		m_infoLog;
334 };
335 
336 class LogSpirVAssemblySource
337 {
338 public:
LogSpirVAssemblySource(const std::string & source)339 	LogSpirVAssemblySource (const std::string& source)
340 		: m_source		(source)
341 	{
342 	}
343 
344 	void write (TestLog& log) const;
345 
346 private:
347 	std::string		m_source;
348 };
349 
350 class LogKernelSource
351 {
352 public:
LogKernelSource(const std::string & source)353 	explicit LogKernelSource (const std::string& source)
354 		: m_source(source)
355 	{
356 	}
357 
358 	void write (TestLog& log) const;
359 
360 private:
361 	std::string	m_source;
362 };
363 
364 class LogSampleList
365 {
366 public:
LogSampleList(const std::string & name,const std::string & description)367 	LogSampleList (const std::string& name, const std::string& description)
368 		: m_name		(name)
369 		, m_description	(description)
370 	{
371 	}
372 
373 	void write (TestLog& log) const;
374 
375 private:
376 	std::string		m_name;
377 	std::string		m_description;
378 };
379 
380 class LogValueInfo
381 {
382 public:
LogValueInfo(const std::string & name,const std::string & description,const std::string & unit,qpSampleValueTag tag)383 	LogValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag)
384 		: m_name		(name)
385 		, m_description	(description)
386 		, m_unit		(unit)
387 		, m_tag			(tag)
388 	{
389 	}
390 
391 	void write (TestLog& log) const;
392 
393 private:
394 	std::string			m_name;
395 	std::string			m_description;
396 	std::string			m_unit;
397 	qpSampleValueTag	m_tag;
398 };
399 
400 template<typename T>
401 class LogNumber
402 {
403 public:
LogNumber(const std::string & name,const std::string & desc,const std::string & unit,qpKeyValueTag tag,T value)404 	LogNumber (const std::string& name, const std::string& desc, const std::string& unit, qpKeyValueTag tag, T value)
405 		: m_name	(name)
406 		, m_desc	(desc)
407 		, m_unit	(unit)
408 		, m_tag		(tag)
409 		, m_value	(value)
410 	{
411 	}
412 
413 	void write (TestLog& log) const;
414 
415 private:
416 	std::string		m_name;
417 	std::string		m_desc;
418 	std::string		m_unit;
419 	qpKeyValueTag	m_tag;
420 	T				m_value;
421 };
422 
423 // Section helper that closes section when leaving scope.
424 class ScopedLogSection
425 {
426 public:
ScopedLogSection(TestLog & log,const std::string & name,const std::string & description)427 	ScopedLogSection (TestLog& log, const std::string& name, const std::string& description)
428 		: m_log(log)
429 	{
430 		m_log << TestLog::Section(name, description);
431 	}
432 
~ScopedLogSection(void)433 	~ScopedLogSection (void)
434 	{
435 		m_log << TestLog::EndSection;
436 	}
437 
438 private:
439 	TestLog& m_log;
440 };
441 
442 // TestLog stream operators.
443 
operator <<(const ImageSet & imageSet)444 inline TestLog& TestLog::operator<< (const ImageSet& imageSet)			{ imageSet.write(*this);	return *this;	}
operator <<(const Image & image)445 inline TestLog& TestLog::operator<< (const Image& image)				{ image.write(*this);		return *this;	}
operator <<(const EndImageSetToken &)446 inline TestLog& TestLog::operator<< (const EndImageSetToken&)			{ endImageSet();			return *this;	}
operator <<(const Section & section)447 inline TestLog& TestLog::operator<< (const Section& section)			{ section.write(*this);		return *this;	}
operator <<(const EndSectionToken &)448 inline TestLog& TestLog::operator<< (const EndSectionToken&)			{ endSection();				return *this;	}
operator <<(const ShaderProgram & shaderProg)449 inline TestLog& TestLog::operator<< (const ShaderProgram& shaderProg)	{ shaderProg.write(*this);	return *this;	}
operator <<(const EndShaderProgramToken &)450 inline TestLog& TestLog::operator<< (const EndShaderProgramToken&)		{ endShaderProgram();		return *this;	}
operator <<(const Shader & shader)451 inline TestLog& TestLog::operator<< (const Shader& shader)				{ shader.write(*this);		return *this;	}
operator <<(const SpirVAssemblySource & module)452 inline TestLog& TestLog::operator<< (const SpirVAssemblySource& module)	{ module.write(*this);		return *this;	}
operator <<(const KernelSource & kernelSrc)453 inline TestLog& TestLog::operator<< (const KernelSource& kernelSrc)		{ kernelSrc.write(*this);	return *this;	}
operator <<(const SampleList & sampleList)454 inline TestLog&	TestLog::operator<<	(const SampleList& sampleList)		{ sampleList.write(*this);	return *this;	}
operator <<(const SampleInfoToken &)455 inline TestLog&	TestLog::operator<<	(const SampleInfoToken&)			{ startSampleInfo();		return *this;	}
operator <<(const ValueInfo & valueInfo)456 inline TestLog&	TestLog::operator<<	(const ValueInfo& valueInfo)		{ valueInfo.write(*this);	return *this;	}
operator <<(const EndSampleInfoToken &)457 inline TestLog&	TestLog::operator<<	(const EndSampleInfoToken&)			{ endSampleInfo();			return *this;	}
operator <<(const EndSampleListToken &)458 inline TestLog&	TestLog::operator<<	(const EndSampleListToken&)			{ endSampleList();			return *this;	}
459 
460 template<typename T>
operator <<(const LogNumber<T> & number)461 inline TestLog& TestLog::operator<< (const LogNumber<T>& number)
462 {
463 	number.write(*this);
464 	return *this;
465 }
466 
operator <<(TestLog & log,const std::exception & e)467 inline TestLog& operator<< (TestLog& log, const std::exception& e)
468 {
469 	// \todo [2012-10-18 pyry] Print type info?
470 	return log << TestLog::Message << e.what() << TestLog::EndMessage;
471 }
472 
473 // Utility class inline implementations.
474 
475 template <typename T>
operator <<(const T & value)476 inline MessageBuilder& MessageBuilder::operator<< (const T& value)
477 {
478 	// Overload stream operator to implement custom format
479 	m_str << value;
480 	return *this;
481 }
482 
operator <<(const BeginMessageToken &)483 inline MessageBuilder TestLog::operator<< (const BeginMessageToken&)
484 {
485 	return MessageBuilder(this);
486 }
487 
message(void)488 inline MessageBuilder TestLog::message (void)
489 {
490 	return MessageBuilder(this);
491 }
492 
operator <<(const BeginSampleToken &)493 inline SampleBuilder TestLog::operator<< (const BeginSampleToken&)
494 {
495 	return SampleBuilder(this);
496 }
497 
write(TestLog & log) const498 inline void LogImageSet::write (TestLog& log) const
499 {
500 	log.startImageSet(m_name.c_str(), m_description.c_str());
501 }
502 
write(TestLog & log) const503 inline void LogSection::write (TestLog& log) const
504 {
505 	log.startSection(m_name.c_str(), m_description.c_str());
506 }
507 
write(TestLog & log) const508 inline void LogShaderProgram::write (TestLog& log) const
509 {
510 	log.startShaderProgram(m_linkOk, m_linkInfoLog.c_str());
511 }
512 
write(TestLog & log) const513 inline void LogShader::write (TestLog& log) const
514 {
515 	log.writeShader(m_type, m_source.c_str(), m_compileOk, m_infoLog.c_str());
516 }
517 
write(TestLog & log) const518 inline void LogSpirVAssemblySource::write (TestLog& log) const
519 {
520 	log.writeSpirVAssemblySource(m_source.c_str());
521 }
522 
write(TestLog & log) const523 inline void LogKernelSource::write (TestLog& log) const
524 {
525 	log.writeKernelSource(m_source.c_str());
526 }
527 
write(TestLog & log) const528 inline void LogSampleList::write (TestLog& log) const
529 {
530 	log.startSampleList(m_name, m_description);
531 }
532 
write(TestLog & log) const533 inline void LogValueInfo::write (TestLog& log) const
534 {
535 	log.writeValueInfo(m_name, m_description, m_unit, m_tag);
536 }
537 
538 template<>
write(TestLog & log) const539 inline void LogNumber<float>::write (TestLog& log) const
540 {
541 	log.writeFloat(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
542 }
543 
544 template<>
write(TestLog & log) const545 inline void LogNumber<deInt64>::write (TestLog& log) const
546 {
547 	log.writeInteger(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
548 }
549 
550 } // tcu
551 
552 #endif // _TCUTESTLOG_HPP
553