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