13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES Utilities
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 SGLR shader program.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrShaderProgram.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace sglr
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace pdec
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration::ShaderProgramDeclaration (void)
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_geometryDecl		(rr::GEOMETRYSHADERINPUTTYPE_LAST, rr::GEOMETRYSHADEROUTPUTTYPE_LAST, 0, 0)
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertexShaderSet		(false)
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fragmentShaderSet	(false)
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_geometryShaderSet	(false)
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexAttribute& v)
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexAttributes.push_back(v);
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToFragmentVarying& v)
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexToFragmentVaryings.push_back(v);
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToGeometryVarying& v)
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexToGeometryVaryings.push_back(v);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryToFragmentVarying& v)
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_geometryToFragmentVaryings.push_back(v);
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const FragmentOutput& v)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragmentOutputs.push_back(v);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const Uniform& v)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_uniforms.push_back(v);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexSource& c)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_vertexShaderSet);
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexSource = c.source;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexShaderSet = true;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const FragmentSource& c)
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_fragmentShaderSet);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragmentSource = c.source;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragmentShaderSet = true;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometrySource& c)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_geometryShaderSet);
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_geometrySource = c.source;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_geometryShaderSet = true;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryShaderDeclaration& c)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_geometryDecl = c;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderProgramDeclaration::valid (void) const
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_vertexShaderSet || !m_fragmentShaderSet)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fragmentOutputs.empty())
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasGeometryShader())
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_geometryDecl.inputType == rr::GEOMETRYSHADERINPUTTYPE_LAST ||
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_geometryDecl.outputType == rr::GEOMETRYSHADEROUTPUTTYPE_LAST)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_geometryDecl.inputType != rr::GEOMETRYSHADERINPUTTYPE_LAST ||
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_geometryDecl.outputType != rr::GEOMETRYSHADEROUTPUTTYPE_LAST ||
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_geometryDecl.numOutputVertices != 0 ||
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_geometryDecl.numInvocations != 0)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} //pdec
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgram::ShaderProgram (const pdec::ShaderProgramDeclaration& decl)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: rr::VertexShader		(decl.getVertexInputCount(), decl.getVertexOutputCount())
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, rr::GeometryShader	(decl.getGeometryInputCount(),
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 decl.getGeometryOutputCount(),
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 decl.m_geometryDecl.inputType,
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 decl.m_geometryDecl.outputType,
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 decl.m_geometryDecl.numOutputVertices,
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 decl.m_geometryDecl.numInvocations)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, rr::FragmentShader	(decl.getFragmentInputCount(), decl.getFragmentOutputCount())
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_attributeNames		(decl.getVertexInputCount())
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniforms			(decl.m_uniforms.size())
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertSrc				(decl.m_vertexSource)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fragSrc				(decl.m_fragmentSource)
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_geomSrc				(decl.hasGeometryShader() ? (decl.m_geometrySource) : (""))
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_hasGeometryShader	(decl.hasGeometryShader())
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(decl.valid());
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set up shader IO
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < decl.m_vertexAttributes.size(); ++ndx)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_inputs[ndx].type	= decl.m_vertexAttributes[ndx].type;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_attributeNames[ndx]						= decl.m_vertexAttributes[ndx].name;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_hasGeometryShader)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < decl.m_vertexToGeometryVaryings.size(); ++ndx)
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::VertexShader::m_outputs[ndx].type			= decl.m_vertexToGeometryVaryings[ndx].type;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::VertexShader::m_outputs[ndx].flatshade	= decl.m_vertexToGeometryVaryings[ndx].flatshade;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::GeometryShader::m_inputs[ndx]				= this->rr::VertexShader::m_outputs[ndx];
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < decl.m_geometryToFragmentVaryings.size(); ++ndx)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::GeometryShader::m_outputs[ndx].type		= decl.m_geometryToFragmentVaryings[ndx].type;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::GeometryShader::m_outputs[ndx].flatshade	= decl.m_geometryToFragmentVaryings[ndx].flatshade;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::FragmentShader::m_inputs[ndx]				= this->rr::GeometryShader::m_outputs[ndx];
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < decl.m_vertexToFragmentVaryings.size(); ++ndx)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::VertexShader::m_outputs[ndx].type			= decl.m_vertexToFragmentVaryings[ndx].type;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::VertexShader::m_outputs[ndx].flatshade	= decl.m_vertexToFragmentVaryings[ndx].flatshade;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->rr::FragmentShader::m_inputs[ndx]				= this->rr::VertexShader::m_outputs[ndx];
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < decl.m_fragmentOutputs.size(); ++ndx)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_outputs[ndx].type = decl.m_fragmentOutputs[ndx].type;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set up uniforms
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < decl.m_uniforms.size(); ++ndx)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->m_uniforms[ndx].name = decl.m_uniforms[ndx].name;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->m_uniforms[ndx].type = decl.m_uniforms[ndx].type;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgram::~ShaderProgram (void)
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst UniformSlot& ShaderProgram::getUniformByName (const char* name) const
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(name);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < m_uniforms.size(); ++ndx)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_uniforms[ndx].name == std::string(name))
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return m_uniforms[ndx];
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid uniform name, uniform not found.");
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_uniforms[0];
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderProgram::shadePrimitives (rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(output);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(verticesIn && packets && numPackets && invocationID);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Should never be called.
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(DE_FALSE);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // sglr
225