blob: 2209a2deae7a4e8bf0571d9d9b8f9cada1e7d57a [file] [log] [blame]
/*-------------------------------------------------------------------------
* 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 WGL GL context factory.
*//*--------------------------------------------------------------------*/
#include "tcuWGLContextFactory.hpp"
#include "gluRenderConfig.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuWin32Window.hpp"
#include "glwFunctions.hpp"
#include "glwInitFunctions.hpp"
#include "deString.h"
using std::vector;
namespace tcu
{
namespace wgl
{
namespace
{
enum
{
DEFAULT_WINDOW_WIDTH = 400,
DEFAULT_WINDOW_HEIGHT = 300
};
class WGLFunctionLoader : public glw::FunctionLoader
{
public:
WGLFunctionLoader(const wgl::Context &context) : m_context(context)
{
}
glw::GenericFuncType get(const char *name) const
{
return (glw::GenericFuncType)m_context.getGLFunction(name);
}
private:
const wgl::Context &m_context;
};
class WGLContext : public glu::RenderContext
{
public:
WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext,
const glu::RenderConfig &config);
~WGLContext(void);
glu::ContextType getType(void) const
{
return m_contextType;
}
const RenderTarget &getRenderTarget(void) const
{
return m_renderTarget;
}
void postIterate(void);
const glw::Functions &getFunctions(void) const
{
return m_functions;
}
glw::GenericFuncType getProcAddress(const char *name) const;
void makeCurrent(void);
private:
WGLContext(const WGLContext &other);
WGLContext &operator=(const WGLContext &other);
glu::ContextType m_contextType;
win32::Window m_window;
wgl::Context *m_context;
tcu::RenderTarget m_renderTarget;
glw::Functions m_functions;
};
WGLContext::WGLContext(HINSTANCE instance, const wgl::Core &wglCore, const WGLContext *sharedContext,
const glu::RenderConfig &config)
: m_contextType(config.type)
, m_window(instance, config.width != glu::RenderConfig::DONT_CARE ? config.width : DEFAULT_WINDOW_WIDTH,
config.height != glu::RenderConfig::DONT_CARE ? config.height : DEFAULT_WINDOW_HEIGHT)
, m_context(DE_NULL)
{
if (config.surfaceType != glu::RenderConfig::SURFACETYPE_WINDOW &&
config.surfaceType != glu::RenderConfig::SURFACETYPE_DONT_CARE)
throw NotSupportedError("Unsupported surface type");
HDC deviceCtx = m_window.getDeviceContext();
int pixelFormat = 0;
if (config.id != glu::RenderConfig::DONT_CARE)
pixelFormat = config.id;
else
pixelFormat = wgl::choosePixelFormat(wglCore, deviceCtx, config);
if (pixelFormat < 0)
throw NotSupportedError("Compatible WGL pixel format not found");
const wgl::Context *sharedCtx = DE_NULL;
if (DE_NULL != sharedContext)
sharedCtx = sharedContext->m_context;
m_context =
new wgl::Context(&wglCore, deviceCtx, sharedCtx, config.type, pixelFormat, config.resetNotificationStrategy);
try
{
// Describe selected config & get render target props.
const wgl::PixelFormatInfo info = wglCore.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);
// Load functions
{
WGLFunctionLoader funcLoader(*m_context);
glu::initFunctions(&m_functions, &funcLoader, config.type.getAPI());
}
if (config.windowVisibility != glu::RenderConfig::VISIBILITY_VISIBLE &&
config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN)
throw NotSupportedError("Unsupported window visibility mode");
m_window.setVisible(config.windowVisibility != glu::RenderConfig::VISIBILITY_HIDDEN);
}
catch (...)
{
delete m_context;
throw;
}
}
WGLContext::~WGLContext(void)
{
delete m_context;
}
glw::GenericFuncType WGLContext::getProcAddress(const char *name) const
{
return m_context->getGLFunction(name);
}
void WGLContext::makeCurrent(void)
{
m_context->makeCurrent();
}
void WGLContext::postIterate(void)
{
m_context->swapBuffers();
m_window.processEvents();
}
} // namespace
ContextFactory::ContextFactory(HINSTANCE instance)
: glu::ContextFactory("wgl", "Windows WGL OpenGL context")
, m_instance(instance)
, m_wglCore(instance)
{
}
glu::RenderContext *ContextFactory::createContext(const glu::RenderConfig &config, const tcu::CommandLine &,
const glu::RenderContext *sharedContext) const
{
const WGLContext *sharedWGLContext = static_cast<const WGLContext *>(sharedContext);
return new WGLContext(m_instance, m_wglCore, sharedWGLContext, config);
}
} // namespace wgl
} // namespace tcu