/*------------------------------------------------------------------------- * 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 Win32 GLES3 wrapper platform. *//*--------------------------------------------------------------------*/ #include "tcuWin32GLES3Platform.hpp" #include "gluRenderConfig.hpp" #include "gluRenderContext.hpp" #include "tcuRenderTarget.hpp" #include "gl3Context.h" #include "glwInitES30Direct.hpp" struct gl3PlatformContext_s { tcu::wgl::Context* context; gl3PlatformContext_s (void) : context(DE_NULL) { } }; gl3FunctionPtr gl3PlatformContext_getProcAddress (gl3PlatformContext* platformCtx, const char* procName) { DE_ASSERT(platformCtx && platformCtx->context); return platformCtx->context->getGLFunction(procName); } namespace tcu { enum { DEFAULT_WINDOW_WIDTH = 400, DEFAULT_WINDOW_HEIGHT = 300 }; // Win32GLES3Context class Win32GLES3Context : public glu::RenderContext { public: Win32GLES3Context (const wgl::Core& wgl, HINSTANCE instance, const glu::RenderConfig& config); ~Win32GLES3Context (void); glu::ContextType getType (void) const { return glu::CONTEXTTYPE_ES3; } const RenderTarget& getRenderTarget (void) const { return m_renderTarget; } void postIterate (void); const glw::Functions& getFunctions (void) const { return m_functions; } private: Win32GLES3Context (const Win32GLES3Context& other); Win32GLES3Context& operator= (const Win32GLES3Context& other); RenderTarget m_renderTarget; Win32Window m_window; gl3PlatformContext m_platformCtx; gl3Context* m_context; glw::Functions m_functions; }; typedef const char* (GL_APIENTRY* glGetStringHackFunc) (GLenum str); Win32GLES3Context::Win32GLES3Context (const wgl::Core& wgl, HINSTANCE instance, const glu::RenderConfig& config) : m_renderTarget(config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH, config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT, PixelFormat(8, 8, 8, 8), 24, 8, 0) , m_window (instance, m_renderTarget.getWidth(), m_renderTarget.getHeight()) , m_context (DE_NULL) { const HDC deviceCtx = m_window.getDeviceContext(); const int pixelFormat = wgl::choosePixelFormat(wgl, deviceCtx, config); if (pixelFormat < 0) throw NotSupportedError("No compatible WGL pixel format found"); m_platformCtx.context = new wgl::Context(&wgl, m_window.getDeviceContext(), wgl::PROFILE_COMPATIBILITY, 3, 3, pixelFormat); try { m_context = gl3Context_create(&m_platformCtx); if (!m_context) throw ResourceError("Failed to create GLES3 wrapper context"); gl3Context_setCurrentContext(m_context); glw::initES30Direct(&m_functions); m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN); { const wgl::PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, pixelFormat); const IVec2 size = m_window.getSize(); m_renderTarget = tcu::RenderTarget(size.x(), size.y(), tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits), info.depthBits, info.stencilBits, info.sampleBuffers ? info.samples : 0); } } catch (...) { if (m_context) gl3Context_destroy(m_context); delete m_platformCtx.context; throw; } } Win32GLES3Context::~Win32GLES3Context (void) { if (m_context) gl3Context_destroy(m_context); delete m_platformCtx.context; } void Win32GLES3Context::postIterate (void) { m_platformCtx.context->swapBuffers(); } // Win32GLES3ContextFactory class Win32GLES3ContextFactory : public glu::ContextFactory { public: Win32GLES3ContextFactory (HINSTANCE instance); ~Win32GLES3ContextFactory (void); virtual glu::RenderContext* createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine) const; private: const HINSTANCE m_instance; wgl::Core m_wglCore; }; Win32GLES3ContextFactory::Win32GLES3ContextFactory (HINSTANCE instance) : glu::ContextFactory ("gles3_wrapper", "GLES3 Wrapper Context") , m_instance (instance) , m_wglCore (instance) { } Win32GLES3ContextFactory::~Win32GLES3ContextFactory (void) { } glu::RenderContext* Win32GLES3ContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const { if (config.type == glu::CONTEXTTYPE_ES3) return new Win32GLES3Context(m_wglCore, m_instance, config); else throw NotSupportedError("Unsupported rendering context type"); } // Win32GLES3Platform Win32GLES3Platform::Win32GLES3Platform (void) { const HINSTANCE instance = GetModuleHandle(NULL); // Set priority to lower. SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); m_glContextFactoryRegistry.registerFactory(new Win32GLES3ContextFactory(instance)); } Win32GLES3Platform::~Win32GLES3Platform (void) { } bool Win32GLES3Platform::processEvents (void) { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, TRUE)) { DispatchMessage(&msg); if (msg.message == WM_QUIT) return false; } return true; } } // tcu // Platform factory tcu::Platform* createPlatform (void) { return new tcu::Win32GLES3Platform(); }