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