Home | History | Annotate | Download | only in osx
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program Tester Core
      3  * ----------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief OS X platform.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "tcuOSXPlatform.hpp"
     25 #include "gluRenderContext.hpp"
     26 #include "gluRenderConfig.hpp"
     27 #include "tcuRenderTarget.hpp"
     28 #include "glwFunctions.hpp"
     29 #include "glwInitFunctions.hpp"
     30 #include "deDynamicLibrary.hpp"
     31 #include "glwEnums.hpp"
     32 #include "gluDefs.hpp"
     33 
     34 #include <string>
     35 
     36 #include <OpenGL/OpenGL.h>
     37 #include <OpenGL/CGLCurrent.h>
     38 #include <OpenGL/CGLContext.h>
     39 #include <OpenGL/CGLTypes.h>
     40 #include <OpenGL/CGLRenderers.h>
     41 
     42 #define OPENGL_LIBRARY_PATH "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
     43 
     44 namespace tcu
     45 {
     46 
     47 namespace
     48 {
     49 
     50 class GLFunctionLoader : public glw::FunctionLoader
     51 {
     52 public:
     53 	GLFunctionLoader (const char* path)
     54 		: m_library(path)
     55 	{
     56 	}
     57 
     58 	glw::GenericFuncType get (const char* name) const
     59 	{
     60 		return m_library.getFunction(name);
     61 	}
     62 
     63 private:
     64 	de::DynamicLibrary m_library;
     65 };
     66 
     67 } // anonymous
     68 
     69 class CGLRenderContext : public glu::RenderContext
     70 {
     71 public:
     72 								CGLRenderContext		(const glu::RenderConfig& config);
     73 								~CGLRenderContext		(void);
     74 
     75 	glu::ContextType			getType					(void) const { return m_type;			}
     76 	const glw::Functions&		getFunctions			(void) const { return m_functions;		}
     77 	const tcu::RenderTarget&	getRenderTarget			(void) const { return m_renderTarget;	}
     78 	void						postIterate				(void) {}
     79 
     80 private:
     81 	const glu::ContextType		m_type;
     82 	CGLContextObj				m_context;
     83 	glw::Functions				m_functions;
     84 	RenderTarget				m_renderTarget;
     85 };
     86 
     87 static CGLOpenGLProfile getCGLProfile (glu::ContextType type)
     88 {
     89 	if (type.getAPI().getProfile() != glu::PROFILE_CORE)
     90 		throw NotSupportedError("Requested OpenGL profile is not supported in CGL");
     91 
     92 	if (type.getAPI().getMajorVersion() == 4)
     93 		return kCGLOGLPVersion_GL4_Core;
     94 	else if (type.getAPI().getMajorVersion() == 3)
     95 		return kCGLOGLPVersion_GL3_Core;
     96 	else
     97 		throw NotSupportedError("Requested OpenGL version is not supported in CGL");
     98 }
     99 
    100 static glu::ApiType getVersion (const glw::Functions& gl)
    101 {
    102 	int major = 0;
    103 	int minor = 0;
    104 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
    105 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
    106 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query exact GL version");
    107 	return glu::ApiType::core(major, minor);
    108 }
    109 
    110 CGLRenderContext::CGLRenderContext (const glu::RenderConfig& config)
    111 	: m_type			(config.type)
    112 	, m_context			(DE_NULL)
    113 	, m_renderTarget	(0, 0, tcu::PixelFormat(0,0,0,0), 0, 0, 0)
    114 {
    115 	try
    116 	{
    117 		const CGLPixelFormatAttribute attribs[] =
    118 		{
    119 			kCGLPFAAccelerated,
    120 			kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)getCGLProfile(config.type),
    121 			(CGLPixelFormatAttribute)0
    122 		};
    123 
    124 		CGLPixelFormatObj	pixelFormat;
    125 		int					numVScreens;
    126 
    127 		if (CGLChoosePixelFormat(&attribs[0], &pixelFormat, &numVScreens) != kCGLNoError)
    128 			throw NotSupportedError("No compatible pixel formats found");
    129 
    130 		try
    131 		{
    132 			if (CGLCreateContext(pixelFormat, DE_NULL, &m_context) != kCGLNoError)
    133 				throw ResourceError("Failed to create CGL context");
    134 
    135 			if (CGLSetCurrentContext(m_context) != kCGLNoError)
    136 				throw ResourceError("Failed to set current CGL context");
    137 		}
    138 		catch (...)
    139 		{
    140 			CGLReleasePixelFormat(pixelFormat);
    141 			throw;
    142 		}
    143 
    144 		CGLReleasePixelFormat(pixelFormat);
    145 
    146 		{
    147 			GLFunctionLoader loader(OPENGL_LIBRARY_PATH);
    148 			glu::initFunctions(&m_functions, &loader, config.type.getAPI());
    149 		}
    150 
    151 		{
    152 			const glu::ApiType actualApi = getVersion(m_functions);
    153 			if (!contextSupports(glu::ContextType(actualApi, glu::ContextFlags(0)), config.type.getAPI()))
    154 				throw tcu::NotSupportedError("OpenGL version not supported");
    155 		}
    156 	}
    157 	catch (...)
    158 	{
    159 		if (m_context)
    160 		{
    161 			CGLSetCurrentContext(DE_NULL);
    162 			CGLDestroyContext(m_context);
    163 		}
    164 		throw;
    165 	}
    166 }
    167 
    168 CGLRenderContext::~CGLRenderContext (void)
    169 {
    170 	CGLSetCurrentContext(DE_NULL);
    171 	if (m_context)
    172 		CGLDestroyContext(m_context);
    173 }
    174 
    175 class CGLContextFactory : public glu::ContextFactory
    176 {
    177 public:
    178 	CGLContextFactory (void)
    179 		: glu::ContextFactory("cgl", "CGL Context (surfaceless, use fbo)")
    180 	{
    181 	}
    182 
    183 	glu::RenderContext*	createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const
    184 	{
    185 		return new CGLRenderContext(config);
    186 	}
    187 };
    188 
    189 OSXPlatform::OSXPlatform (void)
    190 {
    191 	m_contextFactoryRegistry.registerFactory(new CGLContextFactory());
    192 }
    193 
    194 OSXPlatform::~OSXPlatform (void)
    195 {
    196 }
    197 
    198 } // tcu
    199 
    200 tcu::Platform* createPlatform (void)
    201 {
    202 	return new tcu::OSXPlatform();
    203 }
    204