13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
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 OS X platform.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuOSXPlatform.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderConfig.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwInitFunctions.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDynamicLibrary.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDefs.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <OpenGL/OpenGL.h>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <OpenGL/CGLCurrent.h>
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <OpenGL/CGLContext.h>
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <OpenGL/CGLTypes.h>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <OpenGL/CGLRenderers.h>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define OPENGL_LIBRARY_PATH "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GLFunctionLoader : public glw::FunctionLoader
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLFunctionLoader (const char* path)
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_library(path)
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GenericFuncType get (const char* name) const
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_library.getFunction(name);
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::DynamicLibrary m_library;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CGLRenderContext : public glu::RenderContext
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								CGLRenderContext		(const glu::RenderConfig& config);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~CGLRenderContext		(void);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ContextType			getType					(void) const { return m_type;			}
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		getFunctions			(void) const { return m_functions;		}
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	getRenderTarget			(void) const { return m_renderTarget;	}
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						postIterate				(void) {}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ContextType		m_type;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CGLContextObj				m_context;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::Functions				m_functions;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderTarget				m_renderTarget;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic CGLOpenGLProfile getCGLProfile (glu::ContextType type)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.getAPI().getProfile() != glu::PROFILE_CORE)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw NotSupportedError("Requested OpenGL profile is not supported in CGL");
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.getAPI().getMajorVersion() == 4)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return kCGLOGLPVersion_GL4_Core;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.getAPI().getMajorVersion() == 3)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return kCGLOGLPVersion_GL3_Core;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw NotSupportedError("Requested OpenGL version is not supported in CGL");
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::ApiType getVersion (const glw::Functions& gl)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int major = 0;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int minor = 0;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAJOR_VERSION, &major);
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MINOR_VERSION, &minor);
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query exact GL version");
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::ApiType::core(major, minor);
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCGLRenderContext::CGLRenderContext (const glu::RenderConfig& config)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type			(config.type)
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_context			(DE_NULL)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTarget	(0, 0, tcu::PixelFormat(0,0,0,0), 0, 0, 0)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const CGLPixelFormatAttribute attribs[] =
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			kCGLPFAAccelerated,
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)getCGLProfile(config.type),
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(CGLPixelFormatAttribute)0
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CGLPixelFormatObj	pixelFormat;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					numVScreens;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (CGLChoosePixelFormat(&attribs[0], &pixelFormat, &numVScreens) != kCGLNoError)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw NotSupportedError("No compatible pixel formats found");
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		try
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (CGLCreateContext(pixelFormat, DE_NULL, &m_context) != kCGLNoError)
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw ResourceError("Failed to create CGL context");
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (CGLSetCurrentContext(m_context) != kCGLNoError)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw ResourceError("Failed to set current CGL context");
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		catch (...)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CGLReleasePixelFormat(pixelFormat);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CGLReleasePixelFormat(pixelFormat);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLFunctionLoader loader(OPENGL_LIBRARY_PATH);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::initFunctions(&m_functions, &loader, config.type.getAPI());
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::ApiType actualApi = getVersion(m_functions);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!contextSupports(glu::ContextType(actualApi, glu::ContextFlags(0)), config.type.getAPI()))
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				throw tcu::NotSupportedError("OpenGL version not supported");
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_context)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CGLSetCurrentContext(DE_NULL);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CGLDestroyContext(m_context);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCGLRenderContext::~CGLRenderContext (void)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CGLSetCurrentContext(DE_NULL);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CGLDestroyContext(m_context);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CGLContextFactory : public glu::ContextFactory
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CGLContextFactory (void)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: glu::ContextFactory("cgl", "CGL Context (surfaceless, use fbo)")
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext*	createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return new CGLRenderContext(config);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOSXPlatform::OSXPlatform (void)
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_contextFactoryRegistry.registerFactory(new CGLContextFactory());
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOSXPlatform::~OSXPlatform (void)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Platform* createPlatform (void)
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new tcu::OSXPlatform();
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
204