13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements TestLog Library
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test case result logging
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpTestLog.h"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpXmlWriter.h"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpInfo.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "qpDebugOut.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMutex.h"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(QP_SUPPORT_PNG)
36fe01ea4c4da3e989f8274b6e296e9b0de4c84725Pyry Haulos#	include <png.h>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdio.h>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdlib.h>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdarg.h>
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if (DE_OS == DE_OS_WIN32)
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	include <windows.h>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	include <io.h>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG)
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Utils for verifying container (Section, ImageSet, EglConfigSet) usage in debug builds. */
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef enum ContainerType_e
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_SECTION = 0,
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_IMAGESET,
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_EGLCONFIGSET,
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_SHADERPROGRAM,
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_SAMPLELIST,
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_SAMPLEINFO,
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_SAMPLE,
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONTAINERTYPE_LAST
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} ContainerType;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE deBool childContainersOk (ContainerType type)
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return type == CONTAINERTYPE_SECTION || type == CONTAINERTYPE_SAMPLELIST;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_CONTAINER_STACK_DEPTH		= 32
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct ContainerStack_s
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numElements;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ContainerType	elements[MAX_CONTAINER_STACK_DEPTH];
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} ContainerStack;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE void ContainerStack_reset (ContainerStack* stack)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemset(stack, 0, sizeof(ContainerStack));
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE deBool ContainerStack_isEmpty (const ContainerStack* stack)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stack->numElements == 0;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE deBool ContainerStack_push (ContainerStack* stack, ContainerType type)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (stack->numElements == MAX_CONTAINER_STACK_DEPTH)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (stack->numElements > 0 && !childContainersOk(stack->elements[stack->numElements-1]))
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stack->elements[stack->numElements]  = type;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stack->numElements					+= 1;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE ContainerType ContainerStack_pop (ContainerStack* stack)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(stack->numElements > 0);
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stack->numElements -= 1;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stack->elements[stack->numElements];
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE ContainerType ContainerStack_getTop (const ContainerStack* stack)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (stack->numElements > 0)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return stack->elements[stack->numElements-1];
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTAINERTYPE_LAST;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* qpTestLog instance */
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct qpTestLog_s
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				flags;				/*!< Logging flags.						*/
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex					lock;				/*!< Lock for mutable state below.		*/
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* State protected by lock. */
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FILE*					outputFile;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlWriter*			writer;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deBool					isSessionOpen;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deBool					isCaseOpen;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ContainerStack			containerStack;		/*!< For container usage verification.	*/
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Maps integer to string. */
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct qpKeyStringMap_s
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		key;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char*	string;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} qpKeyStringMap;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* LOG_FORMAT_VERSION = "0.3.3";
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Mapping enum to above strings... */
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpTestTypeMap[] =
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_CASE_TYPE_SELF_VALIDATE,		"SelfValidate"	},
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_CASE_TYPE_PERFORMANCE,		"Performance"	},
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_CASE_TYPE_CAPABILITY,			"Capability"	},
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_CASE_TYPE_ACCURACY,			"Accuracy"		},
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_CASE_TYPE_LAST,				DE_NULL			}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTestTypeMap) == QP_TEST_CASE_TYPE_LAST + 1);
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpTestResultMap[] =
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_PASS,						"Pass"					},
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_FAIL,						"Fail"					},
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_QUALITY_WARNING,			"QualityWarning"		},
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_COMPATIBILITY_WARNING,		"CompatibilityWarning"	},
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_PENDING,					"Pending"				},	/* should not be needed here */
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_NOT_SUPPORTED,				"NotSupported"			},
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_RESOURCE_ERROR,			"ResourceError"			},
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_INTERNAL_ERROR,			"InternalError"			},
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_CRASH,						"Crash"					},
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_TIMEOUT,					"Timeout"				},
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Add new values here if needed, remember to update qpTestResult enumeration. */
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_TEST_RESULT_LAST,						DE_NULL					}
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTestResultMap) == QP_TEST_RESULT_LAST + 1);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Key tag to string mapping. */
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpTagMap[] =
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_NONE,			DE_NULL			},
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_PERFORMANCE,	"Performance"	},
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_QUALITY,		"Quality"		},
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_PRECISION,		"Precision"		},
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_TIME,			"Time"			},
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_KEY_TAG_LAST,			DE_NULL			}
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpTagMap) == QP_KEY_TAG_LAST + 1);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Sample value tag to string mapping. */
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpSampleValueTagMap[] =
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SAMPLE_VALUE_TAG_PREDICTOR,	"Predictor"	},
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SAMPLE_VALUE_TAG_RESPONSE,		"Response"	},
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SAMPLE_VALUE_TAG_LAST,			DE_NULL		}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpSampleValueTagMap) == QP_SAMPLE_VALUE_TAG_LAST + 1);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Image compression mode to string mapping. */
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpImageCompressionModeMap[] =
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_COMPRESSION_MODE_NONE,	"None"	},
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_COMPRESSION_MODE_PNG,	"PNG"	},
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_COMPRESSION_MODE_BEST,	DE_NULL	},	/* not allowed to be written! */
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_COMPRESSION_MODE_LAST,	DE_NULL	}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpImageCompressionModeMap) == QP_IMAGE_COMPRESSION_MODE_LAST + 1);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Image format to string mapping. */
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpImageFormatMap[] =
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_FORMAT_RGB888,	"RGB888"	},
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_FORMAT_RGBA8888,	"RGBA8888"	},
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_IMAGE_FORMAT_LAST,		DE_NULL		}
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpImageFormatMap) == QP_IMAGE_FORMAT_LAST + 1);
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* Shader type to string mapping. */
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const qpKeyStringMap s_qpShaderTypeMap[] =
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_VERTEX,			"VertexShader"			},
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_FRAGMENT,			"FragmentShader"		},
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_GEOMETRY,			"GeometryShader"		},
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_TESS_CONTROL,		"TessControlShader"		},
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_TESS_EVALUATION,	"TessEvaluationShader"	},
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_COMPUTE,			"ComputeShader"			},
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ QP_SHADER_TYPE_LAST,				DE_NULL					}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_qpShaderTypeMap) == QP_SHADER_TYPE_LAST + 1);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void qpTestLog_flushFile (qpTestLog* log)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && log->outputFile);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fflush(log->outputFile);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if (DE_OS == DE_OS_WIN32) && (DE_COMPILER == DE_COMPILER_MSC)
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* \todo [petri] Is this really necessary? */
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(log->outputFile)));
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define QP_LOOKUP_STRING(KEYMAP, KEY)	qpLookupString(KEYMAP, DE_LENGTH_OF_ARRAY(KEYMAP), (int)(KEY))
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* qpLookupString (const qpKeyStringMap* keyMap, int keyMapSize, int key)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(keyMap);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32(key, 0, keyMapSize));
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(keyMap[key].key == key);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(keyMapSize); /* for asserting only */
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return keyMap[key].string;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE void int32ToString (int val, char buf[32])
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deSprintf(&buf[0], 32, "%d", val);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE void int64ToString (deInt64 val, char buf[32])
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deSprintf(&buf[0], 32, "%lld", (long long int)val);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE void floatToString (float value, char* buf, int bufSize)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deSprintf(buf, bufSize, "%f", value);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_INLINE void doubleToString (double value, char* buf, int bufSize)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deSprintf(buf, bufSize, "%f", value);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deBool beginSession (qpTestLog* log)
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && !log->isSessionOpen);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Write session info. */
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "#sessionInfo releaseName %s\n", qpGetReleaseName());
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "#sessionInfo releaseId 0x%08x\n", qpGetReleaseId());
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "#sessionInfo targetName \"%s\"\n", qpGetTargetName());
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /* Write out #beginSession. */
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "#beginSession\n");
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_flushFile(log);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isSessionOpen = DE_TRUE;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deBool endSession (qpTestLog* log)
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && log->isSessionOpen);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /* Make sure xml is flushed. */
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    qpXmlWriter_flush(log->writer);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    /* Write out #endSession. */
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "\n#endSession\n");
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_flushFile(log);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isSessionOpen = DE_FALSE;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Create a file based logger instance
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param fileName Name of the file where to put logs
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return qpTestLog instance, or DE_NULL if cannot create file
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
3313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryqpTestLog* qpTestLog_createFileLog (const char* fileName, deUint32 flags)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog* log = (qpTestLog*)deCalloc(sizeof(qpTestLog));
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!log)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(fileName && fileName[0]); /* must have filename. */
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ContainerStack_reset(&log->containerStack);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Create output file. */
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->outputFile = fopen(fileName, "wb");
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!log->outputFile)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("ERROR: Unable to open test log output file '%s'.\n", fileName);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpTestLog_destroy(log);
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->flags			= flags;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->writer			= qpXmlWriter_createFileWriter(log->outputFile, 0);
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->lock			= deMutex_create(DE_NULL);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isSessionOpen	= DE_FALSE;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isCaseOpen		= DE_FALSE;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!log->writer)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("ERROR: Unable to create output XML writer to file '%s'.\n", fileName);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpTestLog_destroy(log);
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!log->lock)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("ERROR: Unable to create mutex.\n");
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpTestLog_destroy(log);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	beginSession(log);
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return log;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Destroy a logger instance
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param a	qpTestLog instance
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid qpTestLog_destroy (qpTestLog* log)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (log->isSessionOpen)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		endSession(log);
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (log->writer)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpXmlWriter_destroy(log->writer);
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (log->outputFile)
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fclose(log->outputFile);
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (log->lock)
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_destroy(log->lock);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deFree(log);
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Log start of test case
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log qpTestLog instance
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param testCasePath	Full test case path (as seen in Candy).
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param testCaseType	Test case type
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
4073c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startCase (qpTestLog* log, const char* testCasePath, qpTestCaseType testCaseType)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		typeStr				= QP_LOOKUP_STRING(s_qpTestTypeMap, testCaseType);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numResultAttribs	= 0;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	resultAttribs[8];
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && testCasePath && (testCasePath[0] != 0));
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!log->isCaseOpen);
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_isEmpty(&log->containerStack));
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Flush XML and write out #beginTestCaseResult. */
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlWriter_flush(log->writer);
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "\n#beginTestCaseResult %s\n", testCasePath);
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_flushFile(log);
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isCaseOpen = DE_TRUE;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Fill in attributes. */
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultAttribs[numResultAttribs++] = qpSetStringAttrib("Version", LOG_FORMAT_VERSION);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultAttribs[numResultAttribs++] = qpSetStringAttrib("CasePath", testCasePath);
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultAttribs[numResultAttribs++] = qpSetStringAttrib("CaseType", typeStr);
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startDocument(log->writer) ||
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_startElement(log->writer, "TestCaseResult", numResultAttribs, resultAttribs))
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startCase(): Writing XML failed\n");
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Log end of test case
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log qpTestLog instance
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param result Test result
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description Description of a problem in case of error
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
4503c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endCase (qpTestLog* log, qpTestResult result, const char* resultDetails)
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		statusStr		= QP_LOOKUP_STRING(s_qpTestResultMap, result);
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	statusAttrib	= qpSetStringAttrib("StatusCode", statusStr);
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && log->isCaseOpen);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_isEmpty(&log->containerStack));
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Result StatusCode="Pass">Result details</Result>
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	 * </TestCaseResult>
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	 */
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "Result", 1, &statusAttrib) ||
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(resultDetails && !qpXmlWriter_writeString(log->writer, resultDetails)) ||
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "Result") ||
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "TestCaseResult") ||
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endDocument(log->writer))		/* Close any XML elements still open */
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endCase(): Writing XML failed\n");
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Flush XML and write #endTestCaseResult. */
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlWriter_flush(log->writer);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "\n#endTestCaseResult\n");
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_flushFile(log);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isCaseOpen = DE_FALSE;
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Abrupt termination of logging.
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log		qpTestLog instance
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param result	Result code, only Crash and Timeout are allowed.
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
4903c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_terminateCase (qpTestLog* log, qpTestResult result)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* resultStr = QP_LOOKUP_STRING(s_qpTestResultMap, result);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(result == QP_TEST_RESULT_CRASH || result == QP_TEST_RESULT_TIMEOUT);
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!log->isCaseOpen)
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE; /* Soft error. This is called from error handler. */
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Flush XML and write #terminateTestCaseResult. */
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlWriter_flush(log->writer);
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fprintf(log->outputFile, "\n#terminateTestCaseResult %s\n", resultStr);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_flushFile(log);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log->isCaseOpen = DE_FALSE;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG)
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ContainerStack_reset(&log->containerStack);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deBool qpTestLog_writeKeyValuePair (qpTestLog* log, const char* elementName, const char* name, const char* description, const char* unit, qpKeyValueTag tag, const char* text)
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		tagString = QP_LOOKUP_STRING(s_qpTagMap, tag);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[8];
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && elementName && text);
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Fill in attributes. */
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (name)			attribs[numAttribs++] = qpSetStringAttrib("Name", name);
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (description)	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (tagString)		attribs[numAttribs++] = qpSetStringAttrib("Tag", tagString);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (unit)			attribs[numAttribs++] = qpSetStringAttrib("Unit", unit);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, elementName, numAttribs, attribs) ||
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeString(log->writer, text) ||
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, elementName))
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeKeyValuePair(): Writing XML failed\n");
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write a message to output log
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log		qpTestLog instance
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param format	Format string of message
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param ...		Parameters for message
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5553c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeMessage (qpTestLog* log, const char* format, ...)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char	buffer[1024];
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	va_list	args;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* \todo [petri] Handle buffer overflows! */
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	va_start(args, format);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer[DE_LENGTH_OF_ARRAY(buffer) - 1] = 0;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vsnprintf(buffer, sizeof(buffer), format, args);
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	va_end(args);
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf("%s\n", buffer);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Text>text</Text> */
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return qpTestLog_writeKeyValuePair(log, "Text", DE_NULL, DE_NULL, DE_NULL, QP_KEY_TAG_LAST, buffer);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write key-value-pair into log
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name			Unique identifier for entry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description	Human readable description
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param tag			Optional tag
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param value			Value of the key-value-pair
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5823c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeText (qpTestLog* log, const char* name, const char* description, qpKeyValueTag tag, const char* text)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Text Name="name" Description="description" Tag="tag">text</Text> */
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return qpTestLog_writeKeyValuePair(log, "Text", name, description, DE_NULL, tag, text);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write key-value-pair into log
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name			Unique identifier for entry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description	Human readable description
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param tag			Optional tag
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param value			Value of the key-value-pair
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
5973c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeInteger (qpTestLog* log, const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value)
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char tmpString[64];
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int64ToString(value, tmpString);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf("%s = %lld %s\n", description, (signed long long)value, unit ? unit : "");
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write key-value-pair into log
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name			Unique identifier for entry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description	Human readable description
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param tag			Optional tag
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param value			Value of the key-value-pair
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
6173c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeFloat (qpTestLog* log, const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char tmpString[64];
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	floatToString(value, tmpString, sizeof(tmpString));
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	printf("%s = %f %s\n", description, value, unit ? unit : "");
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct Buffer_s
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			capacity;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			size;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint8*	data;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} Buffer;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Buffer_init (Buffer* buffer)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->capacity	= 0;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->size		= 0;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->data		= DE_NULL;
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Buffer_deinit (Buffer* buffer)
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deFree(buffer->data);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer_init(buffer);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool Buffer_resize (Buffer* buffer, int newSize)
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Grow buffer if necessary. */
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (newSize > buffer->capacity)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			newCapacity	= deAlign32(deMax32(2*buffer->capacity, newSize), 512);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint8*	newData		= (deUint8*)deMalloc(newCapacity);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!newData)
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_FALSE;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		memcpy(newData, buffer->data, buffer->size);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deFree(buffer->data);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer->data		= newData;
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer->capacity	= newCapacity;
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->size = newSize;
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6683c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool Buffer_append (Buffer* buffer, const deUint8* data, int numBytes)
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int offset = buffer->size;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!Buffer_resize(buffer, buffer->size + numBytes))
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Append bytes. */
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	memcpy(&buffer->data[offset], data, numBytes);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(QP_SUPPORT_PNG)
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid pngWriteData (png_structp png, png_bytep dataPtr, png_size_t numBytes)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer* buffer = (Buffer*)png_get_io_ptr(png);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!Buffer_append(buffer, (const deUint8*)dataPtr, (int)numBytes))
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		png_error(png, "unable to resize PNG write buffer!");
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid pngFlushData (png_structp png)
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(png);
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* nada */
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
694246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulosstatic deBool writeCompressedPNG (png_structp png, png_infop info, png_byte** rowPointers, int width, int height, int colorFormat)
695246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos{
696246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	if (setjmp(png_jmpbuf(png)) == 0)
697246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	{
698246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		/* Write data. */
699246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		png_set_IHDR(png, info, width, height,
700246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos			8,
701246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos			colorFormat,
702246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos			PNG_INTERLACE_NONE,
703246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos			PNG_COMPRESSION_TYPE_BASE,
704246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos			PNG_FILTER_TYPE_BASE);
705246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		png_write_info(png, info);
706246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		png_write_image(png, rowPointers);
707246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		png_write_end(png, NULL);
708246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos
709246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		return DE_TRUE;
710246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	}
711246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	else
712246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		return DE_FALSE;
713246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos}
714246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deBool compressImagePNG (Buffer* buffer, qpImageFormat imageFormat, int width, int height, int rowStride, const void* data)
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
717246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	deBool			compressOk		= DE_FALSE;
718246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	png_structp		png				= DE_NULL;
719246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	png_infop		info			= DE_NULL;
720246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	png_byte**		rowPointers		= DE_NULL;
721246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	deBool			hasAlpha		= imageFormat == QP_IMAGE_FORMAT_RGBA8888;
722246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos	int				ndx;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Handle format. */
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(imageFormat == QP_IMAGE_FORMAT_RGB888 || imageFormat == QP_IMAGE_FORMAT_RGBA8888);
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Allocate & set row pointers. */
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rowPointers = (png_byte**)deMalloc(height * sizeof(png_byte*));
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!rowPointers)
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (ndx = 0; ndx < height; ndx++)
733246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		rowPointers[ndx] = (png_byte*)((const deUint8*)data + ndx*rowStride);
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Initialize PNG compressor. */
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	info = png ? png_create_info_struct(png) : DE_NULL;
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (png && info)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
740246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		/* Set our own write function. */
741246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		png_set_write_fn(png, buffer, pngWriteData, pngFlushData);
742246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos
743246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos		compressOk = writeCompressedPNG(png, info, rowPointers, width, height,
744246b7d9155dd3fa10c7e7129e41ec3949194f86bPyry Haulos										hasAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Cleanup & return. */
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (png && info)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		png_destroy_info_struct(png, &info);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		png_destroy_write_struct(&png, DE_NULL);
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (png)
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		png_destroy_write_struct(&png, &info);
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deFree(rowPointers);
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return compressOk;
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* QP_SUPPORT_PNG */
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Start image set
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name			Unique identifier for the set
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description	Human readable description
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
7683c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startImageSet (qpTestLog* log, const char* name, const char* description)
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[4];
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name);
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (description)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[numAttribs++] = qpSetStringAttrib("Description", description);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <ImageSet Name="<name>"> */
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "ImageSet", numAttribs, attribs))
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startImageSet(): Writing XML failed\n");
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_IMAGESET));
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief End image set
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
7993c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endImageSet (qpTestLog* log)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <ImageSet Name="<name>"> */
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "ImageSet"))
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endImageSet(): Writing XML failed\n");
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_IMAGESET);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write base64 encoded raw image data into log
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log				qpTestLog instance
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name				Unique name (matching names can be compared across BatchResults).
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description		Textual description (shown in Candy).
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param compressionMode	Compression mode
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param imageFormat		Color format
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param width				Width in pixels
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param height			Height in pixels
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param stride			Data stride (offset between rows)
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param data				Pointer to pixel data
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return 0 if OK, otherwise <0
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
8313c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeImage	(
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog*				log,
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*				name,
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*				description,
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpImageCompressionMode	compressionMode,
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpImageFormat			imageFormat,
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						width,
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						height,
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						stride,
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const void*				data)
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char			widthStr[32];
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char			heightStr[32];
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[8];
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs			= 0;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer			compressedBuffer;
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const void*		writeDataPtr		= DE_NULL;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				writeDataBytes		= -1;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name);
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInRange32(width, 1, 16384));
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInRange32(height, 1, 16384));
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(data);
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (log->flags & QP_TEST_LOG_EXCLUDE_IMAGES)
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_TRUE; /* Image not logged. */
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer_init(&compressedBuffer);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* BEST compression mode defaults to PNG. */
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (compressionMode == QP_IMAGE_COMPRESSION_MODE_BEST)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(QP_SUPPORT_PNG)
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compressionMode = QP_IMAGE_COMPRESSION_MODE_PNG;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compressionMode = QP_IMAGE_COMPRESSION_MODE_NONE;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(QP_SUPPORT_PNG)
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Try storing with PNG compression. */
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (compressionMode == QP_IMAGE_COMPRESSION_MODE_PNG)
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deBool compressOk = compressImagePNG(&compressedBuffer, imageFormat, width, height, stride, data);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (compressOk)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeDataPtr	= compressedBuffer.data;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeDataBytes	= compressedBuffer.size;
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			/* Fall-back to default compression. */
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			qpPrintf("WARNING: PNG compression failed -- storing image uncompressed.\n");
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			compressionMode	= QP_IMAGE_COMPRESSION_MODE_NONE;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Handle image compression. */
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compressionMode)
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case QP_IMAGE_COMPRESSION_MODE_NONE:
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int pixelSize		= imageFormat == QP_IMAGE_FORMAT_RGB888 ? 3 : 4;
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int packedStride	= pixelSize*width;
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (packedStride == stride)
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				writeDataPtr = data;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				/* Need to re-pack pixels. */
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (Buffer_resize(&compressedBuffer, packedStride*height))
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int row;
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (row = 0; row < height; row++)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						memcpy(&compressedBuffer.data[packedStride*row], &((const deUint8*)data)[row*stride], pixelSize*width);
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					qpPrintf("ERROR: Failed to pack pixels for writing.\n");
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Buffer_deinit(&compressedBuffer);
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return DE_FALSE;
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeDataBytes = packedStride*height;
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(QP_SUPPORT_PNG)
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case QP_IMAGE_COMPRESSION_MODE_PNG:
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(writeDataPtr); /* Already handled. */
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			qpPrintf("qpTestLog_writeImage(): Unknown compression mode: %s\n", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode));
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Buffer_deinit(&compressedBuffer);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_FALSE;
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Fill in attributes. */
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int32ToString(width, widthStr);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int32ToString(height, heightStr);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Width", widthStr);
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Height", heightStr);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Format", QP_LOOKUP_STRING(s_qpImageFormatMap, imageFormat));
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("CompressionMode", QP_LOOKUP_STRING(s_qpImageCompressionModeMap, compressionMode));
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (description) attribs[numAttribs++] = qpSetStringAttrib("Description", description);
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* \note Log lock is acquired after compression! */
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Image ID="result" Name="Foobar" Width="640" Height="480" Format="RGB888" CompressionMode="None">base64 data</Image> */
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "Image", numAttribs, attribs) ||
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeBase64(log->writer, (const deUint8*)writeDataPtr, writeDataBytes) ||
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "Image"))
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeImage(): Writing XML failed\n");
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Buffer_deinit(&compressedBuffer);
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* Free compressed data if allocated. */
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Buffer_deinit(&compressedBuffer);
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write a OpenGL ES shader program into the log.
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param linkOk			Shader program link result, false on failure
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param linkInfoLog		Implementation provided linkage log
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
9693c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startShaderProgram (qpTestLog* log, deBool linkOk, const char* linkInfoLog)
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	programAttribs[4];
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numProgramAttribs = 0;
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	programAttribs[numProgramAttribs++] = qpSetStringAttrib("LinkStatus", linkOk ? "OK" : "Fail");
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "ShaderProgram", numProgramAttribs, programAttribs) ||
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", linkInfoLog))
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startShaderProgram(): Writing XML failed\n");
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SHADERPROGRAM));
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief End shader program
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
9983c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endShaderProgram (qpTestLog* log)
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* </ShaderProgram> */
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "ShaderProgram"))
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endShaderProgram(): Writing XML failed\n");
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SHADERPROGRAM);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write a OpenGL ES shader into the log.
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param type				Shader type
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param source	 		Shader source
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param compileOk			Shader compilation result, false on failure
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param infoLog			Implementation provided shader compilation log
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
10243c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeShader (qpTestLog* log, qpShaderType type, const char* source, deBool compileOk, const char* infoLog)
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		tagName				= QP_LOOKUP_STRING(s_qpShaderTypeMap, type);
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numShaderAttribs	= 0;
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	shaderAttribs[4];
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && source);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SHADERPROGRAM);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderAttribs[numShaderAttribs++]	= qpSetStringAttrib("CompileStatus", compileOk ? "OK" : "Fail");
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, tagName, numShaderAttribs, shaderAttribs) ||
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeStringElement(log->writer, "ShaderSource", source) ||
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", infoLog) ||
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, tagName))
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeShader(): Writing XML failed\n");
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Start writing a set of EGL configurations into the log.
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
10533c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startEglConfigSet (qpTestLog* log, const char* name, const char* description)
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[4];
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name);
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (description)
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[numAttribs++] = qpSetStringAttrib("Description", description);
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <EglConfigSet Name="<name>"> */
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "EglConfigSet", numAttribs, attribs))
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startEglImageSet(): Writing XML failed\n");
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_EGLCONFIGSET));
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief End an EGL config set
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
10823c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endEglConfigSet (qpTestLog* log)
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <EglConfigSet Name="<name>"> */
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "EglConfigSet"))
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endEglImageSet(): Writing XML failed\n");
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_EGLCONFIGSET);
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write an EGL config inside an EGL config set
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \see   qpElgConfigInfo for details
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
11053c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeEglConfig (qpTestLog* log, const qpEglConfigInfo* config)
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[64];
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && config);
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("BufferSize", config->bufferSize);
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("RedSize", config->redSize);
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("GreenSize", config->greenSize);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("BlueSize", config->blueSize);
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("LuminanceSize", config->luminanceSize);
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("AlphaSize", config->alphaSize);
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("AlphaMaskSize", config->alphaMaskSize);
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetBoolAttrib		("BindToTextureRGB", config->bindToTextureRGB);
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetBoolAttrib		("BindToTextureRGBA", config->bindToTextureRGBA);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("ColorBufferType", config->colorBufferType);
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("ConfigCaveat", config->configCaveat);
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("ConfigID", config->configID);
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("Conformant", config->conformant);
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("DepthSize", config->depthSize);
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("Level", config->level);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferWidth", config->maxPBufferWidth);
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferHeight", config->maxPBufferHeight);
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("MaxPBufferPixels", config->maxPBufferPixels);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("MaxSwapInterval", config->maxSwapInterval);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("MinSwapInterval", config->minSwapInterval);
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetBoolAttrib		("NativeRenderable", config->nativeRenderable);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("RenderableType", config->renderableType);
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("SampleBuffers", config->sampleBuffers);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("Samples", config->samples);
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("StencilSize", config->stencilSize);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("SurfaceTypes", config->surfaceTypes);
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib	("TransparentType", config->transparentType);
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("TransparentRedValue", config->transparentRedValue);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("TransparentGreenValue", config->transparentGreenValue);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetIntAttrib		("TransparentBlueValue", config->transparentBlueValue);
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "EglConfig", numAttribs, attribs) ||
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "EglConfig"))
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeEglConfig(): Writing XML failed\n");
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Start section in log.
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param name			Section name
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param description	Human readable description
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
11643c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startSection (qpTestLog* log, const char* name, const char* description)
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[2];
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (description)
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[numAttribs++] = qpSetStringAttrib("Description", description);
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* <Section Name="<name>" Description="<description>"> */
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "Section", numAttribs, attribs))
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startSection(): Writing XML failed\n");
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SECTION));
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief End section in log.
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param log			qpTestLog instance
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if ok, false otherwise
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
11953c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endSection (qpTestLog* log)
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	/* </Section> */
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "Section"))
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endSection(): Writing XML failed\n");
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SECTION);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write OpenCL compute kernel source into the log.
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
12173c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeKernelSource (qpTestLog* log, const char* source)
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_writeStringElement(log->writer, "KernelSource", source))
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeKernelSource(): Writing XML failed\n");
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Write OpenCL kernel compilation results into the log
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
12363c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeCompileInfo (qpTestLog* log, const char* name, const char* description, deBool compileOk, const char* infoLog)
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[3];
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name && description && infoLog);
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("CompileStatus", compileOk ? "OK" : "Fail");
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "CompileInfo", numAttribs, attribs) ||
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_writeStringElement(log->writer, "InfoLog", infoLog) ||
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "CompileInfo"))
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeCompileInfo(): Writing XML failed\n");
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12613c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startSampleList (qpTestLog* log, const char* name, const char* description)
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs = 0;
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[2];
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name && description);
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "SampleList", numAttribs, attribs))
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startSampleList(): Writing XML failed\n");
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLELIST));
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12853c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startSampleInfo (qpTestLog* log)
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "SampleInfo", 0, DE_NULL))
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startSampleInfo(): Writing XML failed\n");
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLEINFO));
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeValueInfo (qpTestLog* log, const char* name, const char* description, const char* unit, qpSampleValueTag tag)
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		tagName		= QP_LOOKUP_STRING(s_qpSampleValueTagMap, tag);
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numAttribs	= 0;
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpXmlAttribute	attribs[4];
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log && name && description && tagName);
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLEINFO);
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Name", name);
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Description", description);
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attribs[numAttribs++] = qpSetStringAttrib("Tag", tagName);
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (unit)
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attribs[numAttribs++] = qpSetStringAttrib("Unit", unit);
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "ValueInfo", numAttribs, attribs) ||
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!qpXmlWriter_endElement(log->writer, "ValueInfo"))
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeValueInfo(): Writing XML failed\n");
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13333c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endSampleInfo (qpTestLog* log)
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "SampleInfo"))
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endSampleInfo(): Writing XML failed\n");
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLEINFO);
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13513c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_startSample (qpTestLog* log)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLELIST);
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_startElement(log->writer, "Sample", 0, DE_NULL))
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_startSample(): Writing XML failed\n");
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_push(&log->containerStack, CONTAINERTYPE_SAMPLE));
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeValueFloat (qpTestLog* log, double value)
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char tmpString[512];
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	doubleToString(value, tmpString, (int)sizeof(tmpString));
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLE);
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_writeStringElement(log->writer, "Value", &tmpString[0]))
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeSampleValue(): Writing XML failed\n");
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_writeValueInteger (qpTestLog* log, deInt64 value)
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char tmpString[64];
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int64ToString(value, tmpString);
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_getTop(&log->containerStack) == CONTAINERTYPE_SAMPLE);
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_writeStringElement(log->writer, "Value", &tmpString[0]))
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_writeSampleValue(): Writing XML failed\n");
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endSample (qpTestLog* log)
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "Sample"))
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endSample(): Writing XML failed\n");
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLE);
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeBool qpTestLog_endSampleList (qpTestLog* log)
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(log);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_lock(log->lock);
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!qpXmlWriter_endElement(log->writer, "SampleList"))
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpPrintf("qpTestLog_endSampleList(): Writing XML failed\n");
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMutex_unlock(log->lock);
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_FALSE;
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(ContainerStack_pop(&log->containerStack) == CONTAINERTYPE_SAMPLELIST);
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMutex_unlock(log->lock);
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_TRUE;
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* qpGetTestResultName (qpTestResult result)
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return QP_LOOKUP_STRING(s_qpTestResultMap, result);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1451