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