| /*------------------------------------------------------------------------- |
| * drawElements Quality Program Tester Core |
| * ---------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief OS X platform. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuOSXPlatform.hpp" |
| #include "tcuRenderTarget.hpp" |
| |
| #include "tcuOSXVulkanPlatform.hpp" |
| |
| #include "gluDefs.hpp" |
| #include "gluPlatform.hpp" |
| #include "gluRenderContext.hpp" |
| #include "gluRenderConfig.hpp" |
| #include "glwFunctions.hpp" |
| #include "glwInitFunctions.hpp" |
| #include "deDynamicLibrary.hpp" |
| #include "glwEnums.hpp" |
| |
| #include <string> |
| |
| #include <OpenGL/OpenGL.h> |
| #include <OpenGL/CGLCurrent.h> |
| #include <OpenGL/CGLContext.h> |
| #include <OpenGL/CGLTypes.h> |
| #include <OpenGL/CGLRenderers.h> |
| |
| #define OPENGL_LIBRARY_PATH "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" |
| |
| namespace tcu |
| { |
| |
| class CGLRenderContext : public glu::RenderContext |
| { |
| public: |
| CGLRenderContext (const glu::RenderConfig& config); |
| ~CGLRenderContext (void); |
| |
| glu::ContextType getType (void) const { return m_type; } |
| const glw::Functions& getFunctions (void) const { return m_functions; } |
| const tcu::RenderTarget& getRenderTarget (void) const { return m_renderTarget; } |
| void postIterate (void) {} |
| |
| private: |
| const glu::ContextType m_type; |
| CGLContextObj m_context; |
| glw::Functions m_functions; |
| RenderTarget m_renderTarget; |
| }; |
| |
| class CGLContextFactory : public glu::ContextFactory |
| { |
| public: |
| CGLContextFactory (void) |
| : glu::ContextFactory("cgl", "CGL Context (surfaceless, use fbo)") |
| { |
| } |
| |
| glu::RenderContext* createContext (const glu::RenderConfig& config, const tcu::CommandLine&, const glu::RenderContext*) const |
| { |
| return new CGLRenderContext(config); |
| } |
| }; |
| |
| class OSXGLPlatform : public glu::Platform |
| { |
| public: |
| OSXGLPlatform(void) |
| { |
| m_contextFactoryRegistry.registerFactory(new CGLContextFactory()); |
| } |
| |
| ~OSXGLPlatform(void) {} |
| }; |
| |
| class OSXPlatform : public tcu::Platform |
| { |
| public: |
| OSXPlatform(void) |
| : m_gluPlatform(), m_vkPlatform() |
| { |
| } |
| |
| ~OSXPlatform(void) |
| { |
| } |
| |
| const glu::Platform& getGLPlatform (void) const { return m_gluPlatform; } |
| const vk::Platform& getVulkanPlatform (void) const { return m_vkPlatform; } |
| |
| private: |
| OSXGLPlatform m_gluPlatform; |
| osx::VulkanPlatform m_vkPlatform; |
| }; |
| |
| namespace |
| { |
| |
| class GLFunctionLoader : public glw::FunctionLoader |
| { |
| public: |
| GLFunctionLoader (const char* path) |
| : m_library(path) |
| { |
| } |
| |
| glw::GenericFuncType get (const char* name) const |
| { |
| return m_library.getFunction(name); |
| } |
| |
| private: |
| de::DynamicLibrary m_library; |
| }; |
| |
| } // anonymous |
| |
| static CGLOpenGLProfile getCGLProfile (glu::ContextType type) |
| { |
| if (type.getAPI().getProfile() != glu::PROFILE_CORE) |
| throw NotSupportedError("Requested OpenGL profile is not supported in CGL"); |
| |
| if (type.getAPI().getMajorVersion() == 4) |
| return kCGLOGLPVersion_GL4_Core; |
| else if (type.getAPI().getMajorVersion() == 3) |
| return kCGLOGLPVersion_GL3_Core; |
| else |
| throw NotSupportedError("Requested OpenGL version is not supported in CGL"); |
| } |
| |
| static glu::ApiType getVersion (const glw::Functions& gl) |
| { |
| int major = 0; |
| int minor = 0; |
| gl.getIntegerv(GL_MAJOR_VERSION, &major); |
| gl.getIntegerv(GL_MINOR_VERSION, &minor); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query exact GL version"); |
| return glu::ApiType::core(major, minor); |
| } |
| |
| CGLRenderContext::CGLRenderContext (const glu::RenderConfig& config) |
| : m_type (config.type) |
| , m_context (DE_NULL) |
| , m_renderTarget (0, 0, tcu::PixelFormat(0,0,0,0), 0, 0, 0) |
| { |
| try |
| { |
| const CGLPixelFormatAttribute attribs[] = |
| { |
| kCGLPFAAccelerated, |
| kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)getCGLProfile(config.type), |
| (CGLPixelFormatAttribute)0 |
| }; |
| |
| CGLPixelFormatObj pixelFormat; |
| int numVScreens; |
| |
| if (CGLChoosePixelFormat(&attribs[0], &pixelFormat, &numVScreens) != kCGLNoError) |
| throw NotSupportedError("No compatible pixel formats found"); |
| |
| try |
| { |
| if (CGLCreateContext(pixelFormat, DE_NULL, &m_context) != kCGLNoError) |
| throw ResourceError("Failed to create CGL context"); |
| |
| if (CGLSetCurrentContext(m_context) != kCGLNoError) |
| throw ResourceError("Failed to set current CGL context"); |
| } |
| catch (...) |
| { |
| CGLReleasePixelFormat(pixelFormat); |
| throw; |
| } |
| |
| CGLReleasePixelFormat(pixelFormat); |
| |
| { |
| GLFunctionLoader loader(OPENGL_LIBRARY_PATH); |
| glu::initFunctions(&m_functions, &loader, config.type.getAPI()); |
| } |
| |
| { |
| const glu::ApiType actualApi = getVersion(m_functions); |
| if (!contextSupports(glu::ContextType(actualApi, glu::ContextFlags(0)), config.type.getAPI())) |
| throw tcu::NotSupportedError("OpenGL version not supported"); |
| } |
| } |
| catch (...) |
| { |
| if (m_context) |
| { |
| CGLSetCurrentContext(DE_NULL); |
| CGLDestroyContext(m_context); |
| } |
| throw; |
| } |
| } |
| |
| CGLRenderContext::~CGLRenderContext (void) |
| { |
| CGLSetCurrentContext(DE_NULL); |
| if (m_context) |
| CGLDestroyContext(m_context); |
| } |
| |
| } // tcu |
| |
| tcu::Platform* createPlatform (void) |
| { |
| return new tcu::OSXPlatform(); |
| } |