Home | History | Annotate | Download | only in win32
      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 WGL GL context factory.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "tcuWGLContextFactory.hpp"
     25 
     26 #include "gluRenderConfig.hpp"
     27 #include "tcuRenderTarget.hpp"
     28 #include "tcuWin32Window.hpp"
     29 #include "glwFunctions.hpp"
     30 #include "glwInitFunctions.hpp"
     31 #include "deString.h"
     32 
     33 using std::vector;
     34 
     35 namespace tcu
     36 {
     37 namespace wgl
     38 {
     39 namespace
     40 {
     41 
     42 enum
     43 {
     44 	DEFAULT_WINDOW_WIDTH	= 400,
     45 	DEFAULT_WINDOW_HEIGHT	= 300
     46 };
     47 
     48 class WGLFunctionLoader : public glw::FunctionLoader
     49 {
     50 public:
     51 	WGLFunctionLoader (const wgl::Context& context)
     52 		: m_context(context)
     53 	{
     54 	}
     55 
     56 	glw::GenericFuncType get (const char* name) const
     57 	{
     58 		return (glw::GenericFuncType)m_context.getGLFunction(name);
     59 	}
     60 
     61 private:
     62 	const wgl::Context& m_context;
     63 };
     64 
     65 class WGLContext : public glu::RenderContext
     66 {
     67 public:
     68 									WGLContext			(HINSTANCE instance, const wgl::Core& wglCore, const glu::RenderConfig& config);
     69 									~WGLContext			(void);
     70 
     71 	glu::ContextType				getType				(void) const	{ return m_contextType;			}
     72 	const RenderTarget&				getRenderTarget		(void) const	{ return m_renderTarget;		}
     73 	void							postIterate			(void);
     74 	const glw::Functions&			getFunctions		(void) const	{ return m_functions;			}
     75 
     76 	glw::GenericFuncType			getProcAddress		(const char* name) const;
     77 
     78 	void							makeCurrent			(void);
     79 
     80 private:
     81 									WGLContext			(const WGLContext& other);
     82 	WGLContext&						operator=			(const WGLContext& other);
     83 
     84 	glu::ContextType				m_contextType;
     85 
     86 	win32::Window					m_window;
     87 	wgl::Context*					m_context;
     88 
     89 	tcu::RenderTarget				m_renderTarget;
     90 	glw::Functions					m_functions;
     91 };
     92 
     93 WGLContext::WGLContext (HINSTANCE instance, const wgl::Core& wglCore, const glu::RenderConfig& config)
     94 	: m_contextType	(config.type)
     95 	, m_window		(instance,
     96 					 config.width	!= glu::RenderConfig::DONT_CARE	? config.width	: DEFAULT_WINDOW_WIDTH,
     97 					 config.height	!= glu::RenderConfig::DONT_CARE	? config.height	: DEFAULT_WINDOW_HEIGHT)
     98 	, m_context		(DE_NULL)
     99 {
    100 	if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW &&
    101 		config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE)
    102 		throw NotSupportedError("Unsupported surface type");
    103 
    104 	HDC		deviceCtx	= m_window.getDeviceContext();
    105 	int		pixelFormat	= 0;
    106 
    107 	if (config.id != glu::RenderConfig::DONT_CARE)
    108 		pixelFormat = config.id;
    109 	else
    110 		pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config);
    111 
    112 	if (pixelFormat < 0)
    113 		throw NotSupportedError("Compatible WGL pixel format not found");
    114 
    115 	m_context = new wgl::Context(&wglCore, deviceCtx, config.type, pixelFormat, config.resetNotificationStrategy);
    116 
    117 	try
    118 	{
    119 		// Describe selected config & get render target props.
    120 		const wgl::PixelFormatInfo	info	= wglCore.getPixelFormatInfo(deviceCtx, pixelFormat);
    121 		const IVec2					size	= m_window.getSize();
    122 
    123 		m_renderTarget = tcu::RenderTarget(size.x(), size.y(),
    124 										   tcu::PixelFormat(info.redBits, info.greenBits, info.blueBits, info.alphaBits),
    125 										   info.depthBits, info.stencilBits,
    126 										   info.sampleBuffers ? info.samples : 0);
    127 
    128 		// Load functions
    129 		{
    130 			WGLFunctionLoader funcLoader(*m_context);
    131 			glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI());
    132 		}
    133 
    134 		if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE &&
    135 			config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN)
    136 			throw NotSupportedError("Unsupported window visibility mode");
    137 
    138 		m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN);
    139 	}
    140 	catch (...)
    141 	{
    142 		delete m_context;
    143 		throw;
    144 	}
    145 }
    146 
    147 WGLContext::~WGLContext (void)
    148 {
    149 	delete m_context;
    150 }
    151 
    152 glw::GenericFuncType WGLContext::getProcAddress (const char* name) const
    153 {
    154 	return m_context->getGLFunction(name);
    155 }
    156 
    157 void WGLContext::makeCurrent (void)
    158 {
    159 	m_context->makeCurrent();
    160 }
    161 
    162 void WGLContext::postIterate (void)
    163 {
    164 	m_context->swapBuffers();
    165 	m_window.processEvents();
    166 }
    167 
    168 } // anonymous
    169 
    170 ContextFactory::ContextFactory (HINSTANCE instance)
    171 	: glu::ContextFactory	("wgl", "Windows WGL OpenGL context")
    172 	, m_instance			(instance)
    173 	, m_wglCore				(instance)
    174 {
    175 }
    176 
    177 glu::RenderContext* ContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine&) const
    178 {
    179 	return new WGLContext(m_instance, m_wglCore, config);
    180 }
    181 
    182 } // wgl
    183 } // tcu
    184