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 Platform that uses X11 via GLX. 22 *//*--------------------------------------------------------------------*/ 23 24#include "tcuX11GlxPlatform.hpp" 25#include "tcuX11Platform.hpp" 26 27#include "tcuRenderTarget.hpp" 28#include "glwInitFunctions.hpp" 29#include "deUniquePtr.hpp" 30 31#include <sstream> 32#include <iterator> 33#include <set> 34 35#define GLX_GLXEXT_PROTOTYPES 36#include <GL/glx.h> 37 38namespace tcu 39{ 40namespace x11 41{ 42namespace glx 43{ 44 45using de::UniquePtr; 46using de::MovePtr; 47using glu::ApiType; 48using glu::ContextFactory; 49using glu::ContextType; 50using glu::RenderConfig; 51using glu::RenderContext; 52using tcu::CommandLine; 53using tcu::RenderTarget; 54using std::string; 55using std::set; 56using std::istringstream; 57using std::ostringstream; 58using std::istream_iterator; 59 60typedef RenderConfig::Visibility Visibility; 61 62 63template<typename T> 64static inline T checkGLX(T value, const char* expr, const char* file, int line) 65{ 66 if (!value) 67 throw tcu::TestError("GLX call failed", expr, file, line); 68 return value; 69} 70 71#define TCU_CHECK_GLX(EXPR) checkGLX(EXPR, #EXPR, __FILE__, __LINE__) 72#define TCU_CHECK_GLX_CONFIG(EXPR) checkGLX((EXPR) == Success, #EXPR, __FILE__, __LINE__) 73 74class GlxContextFactory : public glu::ContextFactory 75{ 76public: 77 GlxContextFactory (EventState& eventState); 78 ~GlxContextFactory (void); 79 RenderContext* createContext (const RenderConfig& config, 80 const CommandLine& cmdLine) const; 81 82 EventState& getEventState (void) const { return m_eventState;} 83 84 const PFNGLXCREATECONTEXTATTRIBSARBPROC 85 m_glXCreateContextAttribsARB; 86 87private: 88 EventState& m_eventState; 89}; 90 91class GlxDisplay : public x11::Display 92{ 93public: 94 GlxDisplay (EventState& eventState, 95 const char* name); 96 int getGlxMajorVersion (void) const { return m_majorVersion; } 97 int getGlxMinorVersion (void) const { return m_minorVersion; } 98 bool isGlxExtensionSupported (const char* extName) const; 99 100private: 101 int m_errorBase; 102 int m_eventBase; 103 int m_majorVersion; 104 int m_minorVersion; 105 set<string> m_extensions; 106}; 107 108class GlxVisual 109{ 110public: 111 GlxVisual (GlxDisplay& display, GLXFBConfig fbConfig); 112 int getAttrib (int attribute); 113 Visual* getXVisual (void) { return m_visual; } 114 GLXContext createContext (const GlxContextFactory& factory, 115 const ContextType& contextType); 116 GLXWindow createWindow (::Window xWindow); 117 GlxDisplay& getGlxDisplay (void) { return m_display; } 118 ::Display* getXDisplay (void) { return m_display.getXDisplay(); } 119 120private: 121 GlxDisplay& m_display; 122 ::Visual* m_visual; 123 const GLXFBConfig m_fbConfig; 124}; 125 126class GlxDrawable 127{ 128public: 129 virtual ~GlxDrawable (void) {} 130 131 virtual void processEvents (void) {} 132 virtual void getDimensions (int* width, int* height) = 0; 133 int getWidth (void); 134 int getHeight (void); 135 void swapBuffers (void) { glXSwapBuffers(getXDisplay(), getGLXDrawable()); } 136 137 virtual ::Display* getXDisplay (void) = 0; 138 virtual GLXDrawable getGLXDrawable (void) = 0; 139 140protected: 141 GlxDrawable () {} 142 unsigned int getAttrib (int attribute); 143}; 144 145class GlxWindow : public GlxDrawable 146{ 147public: 148 GlxWindow (GlxVisual& visual, const RenderConfig& cfg); 149 ~GlxWindow (void); 150 void processEvents (void) { m_x11Window.processEvents(); } 151 ::Display* getXDisplay (void) { return m_x11Display.getXDisplay(); } 152 void getDimensions (int* width, int* height); 153 154protected: 155 GLXDrawable getGLXDrawable () { return m_GLXDrawable; } 156 157private: 158 x11::Display& m_x11Display; 159 x11::Window m_x11Window; 160 const GLXDrawable m_GLXDrawable; 161}; 162 163class GlxRenderContext : public RenderContext 164{ 165public: 166 GlxRenderContext (const GlxContextFactory& factory, 167 const RenderConfig& config); 168 ~GlxRenderContext (void); 169 virtual ContextType getType (void) const; 170 virtual void postIterate (void); 171 void makeCurrent (void); 172 void clearCurrent (void); 173 virtual const glw::Functions& getFunctions (void) const; 174 virtual const tcu::RenderTarget& getRenderTarget (void) const; 175 176private: 177 GlxDisplay m_glxDisplay; 178 GlxVisual m_glxVisual; 179 ContextType m_type; 180 GLXContext m_GLXContext; 181 UniquePtr<GlxDrawable> m_glxDrawable; 182 RenderTarget m_renderTarget; 183 glw::Functions m_functions; 184}; 185 186extern "C" 187{ 188 static int tcuX11GlxErrorHandler (::Display* display, XErrorEvent* event) 189 { 190 char buf[80]; 191 XGetErrorText(display, event->error_code, buf, sizeof(buf)); 192 tcu::print("X operation %u:%u failed: %s\n", 193 event->request_code, event->minor_code, buf); 194 return 0; 195 } 196} 197 198GlxContextFactory::GlxContextFactory (EventState& eventState) 199 : glu::ContextFactory ("glx", "X11 GLX OpenGL Context") 200 , m_glXCreateContextAttribsARB ( 201 reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>( 202 TCU_CHECK_GLX( 203 glXGetProcAddress( 204 reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"))))) 205 , m_eventState (eventState) 206{ 207 XSetErrorHandler(tcuX11GlxErrorHandler); 208} 209 210RenderContext* GlxContextFactory::createContext (const RenderConfig& config, 211 const CommandLine& cmdLine) const 212{ 213 DE_UNREF(cmdLine); 214 GlxRenderContext* const renderContext = new GlxRenderContext(*this, config); 215 return renderContext; 216} 217 218GlxContextFactory::~GlxContextFactory (void) 219{ 220} 221 222GlxDisplay::GlxDisplay (EventState& eventState, const char* name) 223 : x11::Display (eventState, name) 224{ 225 const Bool supported = glXQueryExtension(m_display, &m_errorBase, &m_eventBase); 226 if (!supported) 227 TCU_THROW(NotSupportedError, "GLX protocol not supported by X server"); 228 229 TCU_CHECK_GLX(glXQueryVersion(m_display, &m_majorVersion, &m_minorVersion)); 230 231 { 232 const int screen = XDefaultScreen(m_display); 233 // nVidia doesn't seem to report client-side extensions correctly, 234 // so only use server side 235 const char* const extensions = 236 TCU_CHECK_GLX(glXQueryServerString(m_display, screen, GLX_EXTENSIONS)); 237 istringstream extStream(extensions); 238 m_extensions = set<string>(istream_iterator<string>(extStream), 239 istream_iterator<string>()); 240 } 241} 242 243 244bool GlxDisplay::isGlxExtensionSupported (const char* extName) const 245{ 246 return m_extensions.find(extName) != m_extensions.end(); 247} 248 249//! Throw `tcu::NotSupportedError` if `dpy` is not compatible with GLX 250//! version `major`.`minor`. 251static void checkGlxVersion (const GlxDisplay& dpy, int major, int minor) 252{ 253 const int dpyMajor = dpy.getGlxMajorVersion(); 254 const int dpyMinor = dpy.getGlxMinorVersion(); 255 if (!(dpyMajor == major && dpyMinor >= minor)) 256 { 257 ostringstream oss; 258 oss << "Server GLX version " 259 << dpyMajor << "." << dpyMinor 260 << " not compatible with required version " 261 << major << "." << minor; 262 TCU_THROW(NotSupportedError, oss.str().c_str()); 263 } 264} 265 266//! Throw `tcu::NotSupportedError` if `dpy` does not support extension `extName`. 267static void checkGlxExtension (const GlxDisplay& dpy, const char* extName) 268{ 269 if (!dpy.isGlxExtensionSupported(extName)) 270 { 271 ostringstream oss; 272 oss << "GLX extension \"" << extName << "\" not supported"; 273 TCU_THROW(NotSupportedError, oss.str().c_str()); 274 } 275} 276 277GlxVisual::GlxVisual (GlxDisplay& display, GLXFBConfig fbConfig) 278 : m_display (display) 279 , m_visual (DE_NULL) 280 , m_fbConfig (fbConfig) 281{ 282 XVisualInfo* visualInfo = glXGetVisualFromFBConfig(getXDisplay(), fbConfig); 283 if (visualInfo != DE_NULL) 284 { 285 m_visual = visualInfo->visual; 286 XFree(visualInfo); 287 } 288} 289 290int GlxVisual::getAttrib (int attribute) 291{ 292 int fbvalue; 293 TCU_CHECK_GLX_CONFIG(glXGetFBConfigAttrib(getXDisplay(), m_fbConfig, attribute, &fbvalue)); 294 return fbvalue; 295} 296 297GLXContext GlxVisual::createContext (const GlxContextFactory& factory, 298 const ContextType& contextType) 299{ 300 int profileMask = 0; 301 const ApiType apiType = contextType.getAPI(); 302 303 checkGlxVersion(m_display, 1, 4); 304 checkGlxExtension(m_display, "GLX_ARB_create_context"); 305 checkGlxExtension(m_display, "GLX_ARB_create_context_profile"); 306 307 switch (apiType.getProfile()) 308 { 309 case glu::PROFILE_ES: 310 checkGlxExtension(m_display, "GLX_EXT_create_context_es2_profile"); 311 profileMask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; 312 break; 313 case glu::PROFILE_CORE: 314 profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; 315 break; 316 case glu::PROFILE_COMPATIBILITY: 317 profileMask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 318 break; 319 default: 320 DE_ASSERT(!"Impossible context profile"); 321 } 322 323 const int attribs[] = 324 { 325 GLX_CONTEXT_MAJOR_VERSION_ARB, apiType.getMajorVersion(), 326 GLX_CONTEXT_MINOR_VERSION_ARB, apiType.getMinorVersion(), 327 GLX_CONTEXT_FLAGS_ARB, 0, 328 GLX_CONTEXT_PROFILE_MASK_ARB, profileMask, 329 None 330 }; 331 return TCU_CHECK_GLX(factory.m_glXCreateContextAttribsARB( 332 getXDisplay(), m_fbConfig, DE_NULL, True, attribs)); 333} 334 335GLXWindow GlxVisual::createWindow (::Window xWindow) 336{ 337 return TCU_CHECK_GLX(glXCreateWindow(getXDisplay(), m_fbConfig, xWindow, NULL)); 338} 339 340unsigned GlxDrawable::getAttrib (int attrib) 341{ 342 unsigned int value = 0; 343 glXQueryDrawable(getXDisplay(), getGLXDrawable(), attrib, &value); 344 return value; 345} 346 347int GlxDrawable::getWidth (void) 348{ 349 int width = 0; 350 getDimensions(&width, DE_NULL); 351 return width; 352} 353 354int GlxDrawable::getHeight (void) 355{ 356 int height = 0; 357 getDimensions(DE_NULL, &height); 358 return height; 359} 360 361GlxWindow::GlxWindow (GlxVisual& visual, const RenderConfig& cfg) 362 : m_x11Display (visual.getGlxDisplay()) 363 , m_x11Window (m_x11Display, cfg.width, cfg.height, 364 visual.getXVisual()) 365 , m_GLXDrawable (visual.createWindow(m_x11Window.getXID())) 366{ 367 m_x11Window.setVisibility(cfg.windowVisibility != RenderConfig::VISIBILITY_HIDDEN); 368} 369 370void GlxWindow::getDimensions (int* width, int* height) 371{ 372 if (width != DE_NULL) 373 *width = getAttrib(GLX_WIDTH); 374 if (height != DE_NULL) 375 *height = getAttrib(GLX_HEIGHT); 376 377 // glXQueryDrawable may be buggy, so fall back to X geometry if needed 378 if ((width != DE_NULL && *width == 0) || (height != DE_NULL && *height == 0)) 379 m_x11Window.getDimensions(width, height); 380} 381 382GlxWindow::~GlxWindow (void) 383{ 384 glXDestroyWindow(m_x11Display.getXDisplay(), m_GLXDrawable); 385} 386 387static const struct Attribute 388{ 389 int glxAttribute; 390 int RenderConfig::* cfgMember; 391} s_attribs[] = 392{ 393 { GLX_RED_SIZE, &RenderConfig::redBits }, 394 { GLX_GREEN_SIZE, &RenderConfig::greenBits }, 395 { GLX_BLUE_SIZE, &RenderConfig::blueBits }, 396 { GLX_ALPHA_SIZE, &RenderConfig::alphaBits }, 397 { GLX_DEPTH_SIZE, &RenderConfig::depthBits }, 398 { GLX_STENCIL_SIZE, &RenderConfig::stencilBits }, 399 { GLX_SAMPLES, &RenderConfig::numSamples }, 400 { GLX_FBCONFIG_ID, &RenderConfig::id }, 401}; 402 403static deUint32 surfaceTypeToDrawableBits (RenderConfig::SurfaceType type) 404{ 405 switch (type) 406 { 407 case RenderConfig::SURFACETYPE_WINDOW: 408 return GLX_WINDOW_BIT; 409 case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: 410 return GLX_PIXMAP_BIT; 411 case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: 412 return GLX_PBUFFER_BIT; 413 case RenderConfig::SURFACETYPE_DONT_CARE: 414 return GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; 415 default: 416 DE_ASSERT(!"Impossible case"); 417 } 418 return 0; 419} 420 421static bool configMatches (GlxVisual& visual, const RenderConfig& renderCfg) 422{ 423 if (renderCfg.id != RenderConfig::DONT_CARE) 424 return visual.getAttrib(GLX_FBCONFIG_ID) == renderCfg.id; 425 426 for (const Attribute* it = DE_ARRAY_BEGIN(s_attribs); it != DE_ARRAY_END(s_attribs); it++) 427 { 428 const int requested = renderCfg.*it->cfgMember; 429 if (requested != RenderConfig::DONT_CARE && 430 requested != visual.getAttrib(it->glxAttribute)) 431 return false; 432 } 433 434 { 435 deUint32 bits = surfaceTypeToDrawableBits(renderCfg.surfaceType); 436 437 if ((visual.getAttrib(GLX_DRAWABLE_TYPE) & bits) == 0) 438 return false; 439 440 // It shouldn't be possible to have GLX_WINDOW_BIT set without a visual, 441 // but let's make sure. 442 if (renderCfg.surfaceType == RenderConfig::SURFACETYPE_WINDOW && 443 visual.getXVisual() == DE_NULL) 444 return false; 445 } 446 447 return true; 448} 449 450class Rank 451{ 452public: 453 Rank (void) : m_value(0), m_bitsLeft(64) {} 454 void add (size_t bits, deUint32 value); 455 void sub (size_t bits, deUint32 value); 456 deUint64 getValue (void) { return m_value; } 457 458private: 459 deUint64 m_value; 460 size_t m_bitsLeft; 461}; 462 463void Rank::add (size_t bits, deUint32 value) 464{ 465 TCU_CHECK_INTERNAL(m_bitsLeft >= bits); 466 m_bitsLeft -= bits; 467 m_value = m_value << bits | de::min((1U << bits) - 1, value); 468} 469 470void Rank::sub (size_t bits, deUint32 value) 471{ 472 TCU_CHECK_INTERNAL(m_bitsLeft >= bits); 473 m_bitsLeft -= bits; 474 m_value = m_value << bits | ((1U << bits) - 1 - de::min((1U << bits) - 1U, value)); 475} 476 477static deUint64 configRank (GlxVisual& visual) 478{ 479 // Sanity checks. 480 if (visual.getAttrib(GLX_DOUBLEBUFFER) == False || 481 (visual.getAttrib(GLX_RENDER_TYPE) & GLX_RGBA_BIT) == 0) 482 return 0; 483 484 Rank rank; 485 int caveat = visual.getAttrib(GLX_CONFIG_CAVEAT); 486 int redSize = visual.getAttrib(GLX_RED_SIZE); 487 int greenSize = visual.getAttrib(GLX_GREEN_SIZE); 488 int blueSize = visual.getAttrib(GLX_BLUE_SIZE); 489 int alphaSize = visual.getAttrib(GLX_ALPHA_SIZE); 490 int depthSize = visual.getAttrib(GLX_DEPTH_SIZE); 491 int stencilSize = visual.getAttrib(GLX_STENCIL_SIZE); 492 int minRGB = de::min(redSize, de::min(greenSize, blueSize)); 493 494 // Prefer conformant configurations. 495 rank.add(1, (caveat != GLX_NON_CONFORMANT_CONFIG)); 496 497 // Prefer non-transparent configurations. 498 rank.add(1, visual.getAttrib(GLX_TRANSPARENT_TYPE) == GLX_NONE); 499 500 // Avoid stereo 501 rank.add(1, visual.getAttrib(GLX_STEREO) == False); 502 503 // Avoid overlays 504 rank.add(1, visual.getAttrib(GLX_LEVEL) == 0); 505 506 // Prefer to have some alpha. 507 rank.add(1, alphaSize > 0); 508 509 // Prefer to have a depth buffer. 510 rank.add(1, depthSize > 0); 511 512 // Prefer to have a stencil buffer. 513 rank.add(1, stencilSize > 0); 514 515 // Avoid slow configurations. 516 rank.add(1, (caveat != GLX_SLOW_CONFIG)); 517 518 // Prefer larger, evenly distributed color depths 519 rank.add(4, de::min(minRGB, alphaSize)); 520 521 // If alpha is low, choose best RGB 522 rank.add(4, minRGB); 523 524 // Prefer larger depth and stencil buffers 525 rank.add(6, deUint32(depthSize + stencilSize)); 526 527 // Avoid excessive sampling 528 rank.sub(5, visual.getAttrib(GLX_SAMPLES)); 529 530 // Prefer True/DirectColor 531 int visualType = visual.getAttrib(GLX_X_VISUAL_TYPE); 532 rank.add(1, visualType == GLX_TRUE_COLOR || visualType == GLX_DIRECT_COLOR); 533 534 return rank.getValue(); 535} 536 537static GlxVisual chooseVisual (GlxDisplay& display, const RenderConfig& cfg) 538{ 539 ::Display* dpy = display.getXDisplay(); 540 deUint64 maxRank = 0; 541 GLXFBConfig maxConfig = DE_NULL; 542 int numElems = 0; 543 544 GLXFBConfig* const fbConfigs = glXGetFBConfigs(dpy, DefaultScreen(dpy), &numElems); 545 TCU_CHECK_MSG(fbConfigs != DE_NULL, "Couldn't query framebuffer configurations"); 546 547 for (int i = 0; i < numElems; i++) 548 { 549 GlxVisual visual(display, fbConfigs[i]); 550 551 if (!configMatches(visual, cfg)) 552 continue; 553 554 deUint64 cfgRank = configRank(visual); 555 556 if (cfgRank > maxRank) 557 { 558 maxRank = cfgRank; 559 maxConfig = fbConfigs[i]; 560 } 561 } 562 XFree(fbConfigs); 563 564 if (maxRank == 0) 565 TCU_THROW(NotSupportedError, "Requested GLX configuration not found or unusable"); 566 567 return GlxVisual(display, maxConfig); 568} 569 570GlxDrawable* createDrawable (GlxVisual& visual, const RenderConfig& config) 571{ 572 RenderConfig::SurfaceType surfaceType = config.surfaceType; 573 574 if (surfaceType == RenderConfig::SURFACETYPE_DONT_CARE) 575 { 576 if (visual.getXVisual() == DE_NULL) 577 // No visual, cannot create X window 578 surfaceType = RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE; 579 else 580 surfaceType = RenderConfig::SURFACETYPE_WINDOW; 581 } 582 583 switch (surfaceType) 584 { 585 case RenderConfig::SURFACETYPE_DONT_CARE: 586 DE_ASSERT(!"Impossible case"); 587 588 case RenderConfig::SURFACETYPE_WINDOW: 589 return new GlxWindow(visual, config); 590 break; 591 592 case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: 593 // \todo [2013-11-28 lauri] Pixmaps 594 595 case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: 596 // \todo [2013-11-28 lauri] Pbuffers 597 598 default: 599 TCU_THROW(NotSupportedError, "Unsupported surface type"); 600 } 601 602 return DE_NULL; 603} 604 605struct GlxFunctionLoader : public glw::FunctionLoader 606{ 607 GlxFunctionLoader (void) {} 608 609 glw::GenericFuncType get (const char* name) const 610 { 611 return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name)); 612 } 613}; 614 615GlxRenderContext::GlxRenderContext (const GlxContextFactory& factory, 616 const RenderConfig& config) 617 : m_glxDisplay (factory.getEventState(), DE_NULL) 618 , m_glxVisual (chooseVisual(m_glxDisplay, config)) 619 , m_type (config.type) 620 , m_GLXContext (m_glxVisual.createContext(factory, config.type)) 621 , m_glxDrawable (createDrawable(m_glxVisual, config)) 622 , m_renderTarget (m_glxDrawable->getWidth(), m_glxDrawable->getHeight(), 623 PixelFormat(m_glxVisual.getAttrib(GLX_RED_SIZE), 624 m_glxVisual.getAttrib(GLX_GREEN_SIZE), 625 m_glxVisual.getAttrib(GLX_BLUE_SIZE), 626 m_glxVisual.getAttrib(GLX_ALPHA_SIZE)), 627 m_glxVisual.getAttrib(GLX_DEPTH_SIZE), 628 m_glxVisual.getAttrib(GLX_STENCIL_SIZE), 629 m_glxVisual.getAttrib(GLX_SAMPLES)) 630{ 631 const GlxFunctionLoader loader; 632 makeCurrent(); 633 glu::initFunctions(&m_functions, &loader, config.type.getAPI()); 634} 635 636GlxRenderContext::~GlxRenderContext (void) 637{ 638 clearCurrent(); 639 if (m_GLXContext != DE_NULL) 640 glXDestroyContext(m_glxDisplay.getXDisplay(), m_GLXContext); 641} 642 643void GlxRenderContext::makeCurrent (void) 644{ 645 const GLXDrawable drawRead = m_glxDrawable->getGLXDrawable(); 646 TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(), 647 drawRead, drawRead, m_GLXContext)); 648} 649 650void GlxRenderContext::clearCurrent (void) 651{ 652 TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(), 653 None, None, DE_NULL)); 654} 655 656ContextType GlxRenderContext::getType (void) const 657{ 658 return m_type; 659} 660 661void GlxRenderContext::postIterate (void) 662{ 663 m_glxDrawable->swapBuffers(); 664 m_glxDrawable->processEvents(); 665 m_glxDisplay.processEvents(); 666} 667 668const RenderTarget& GlxRenderContext::getRenderTarget (void) const 669{ 670 return m_renderTarget; 671} 672 673const glw::Functions& GlxRenderContext::getFunctions (void) const 674{ 675 return m_functions; 676} 677 678MovePtr<ContextFactory> createContextFactory (EventState& eventState) 679{ 680 return MovePtr<ContextFactory>(new GlxContextFactory(eventState)); 681} 682 683} // glx 684} // x11 685} // tcu 686