PageRenderTime 407ms CodeModel.GetById 40ms RepoModel.GetById 0ms app.codeStats 0ms

/src/opengl/qgl_qpa.cpp

https://bitbucket.org/kasimling/qt
C++ | 412 lines | 296 code | 51 blank | 65 comment | 40 complexity | e939936f6a3f7b0fe965a75ef866cf78 MD5 | raw file
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the QtOpenGL module of the Qt Toolkit.
  8. **
  9. ** $QT_BEGIN_LICENSE:LGPL$
  10. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include <QApplication>
  42. #include <QtGui/private/qapplication_p.h>
  43. #include <QPixmap>
  44. #include <QDebug>
  45. #include <QtGui/private/qapplication_p.h>
  46. #include <QtGui/QPlatformWindow>
  47. #include "qgl.h"
  48. #include "qgl_p.h"
  49. QT_BEGIN_NAMESPACE
  50. /*!
  51. \since 4.8
  52. Returns an OpenGL format for the platform window format specified by \a format.
  53. */
  54. QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format)
  55. {
  56. QGLFormat retFormat;
  57. retFormat.setAccum(format.accum());
  58. if (format.accumBufferSize() >= 0)
  59. retFormat.setAccumBufferSize(format.accumBufferSize());
  60. retFormat.setAlpha(format.alpha());
  61. if (format.alphaBufferSize() >= 0)
  62. retFormat.setAlphaBufferSize(format.alphaBufferSize());
  63. if (format.blueBufferSize() >= 0)
  64. retFormat.setBlueBufferSize(format.blueBufferSize());
  65. retFormat.setDepth(format.depth());
  66. if (format.depthBufferSize() >= 0)
  67. retFormat.setDepthBufferSize(format.depthBufferSize());
  68. retFormat.setDirectRendering(format.directRendering());
  69. retFormat.setDoubleBuffer(format.doubleBuffer());
  70. if (format.greenBufferSize() >= 0)
  71. retFormat.setGreenBufferSize(format.greenBufferSize());
  72. if (format.redBufferSize() >= 0)
  73. retFormat.setRedBufferSize(format.redBufferSize());
  74. retFormat.setRgba(format.rgba());
  75. retFormat.setSampleBuffers(format.sampleBuffers());
  76. retFormat.setSamples(format.sampleBuffers());
  77. retFormat.setStencil(format.stencil());
  78. if (format.stencilBufferSize() >= 0)
  79. retFormat.setStencilBufferSize(format.stencilBufferSize());
  80. retFormat.setStereo(format.stereo());
  81. retFormat.setSwapInterval(format.swapInterval());
  82. return retFormat;
  83. }
  84. /*!
  85. \since 4.8
  86. Returns a platform window format for the OpenGL format specified by \a format.
  87. */
  88. QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format)
  89. {
  90. QPlatformWindowFormat retFormat;
  91. retFormat.setAccum(format.accum());
  92. if (format.accumBufferSize() >= 0)
  93. retFormat.setAccumBufferSize(format.accumBufferSize());
  94. retFormat.setAlpha(format.alpha());
  95. if (format.alphaBufferSize() >= 0)
  96. retFormat.setAlphaBufferSize(format.alphaBufferSize());
  97. if (format.blueBufferSize() >= 0)
  98. retFormat.setBlueBufferSize(format.blueBufferSize());
  99. retFormat.setDepth(format.depth());
  100. if (format.depthBufferSize() >= 0)
  101. retFormat.setDepthBufferSize(format.depthBufferSize());
  102. retFormat.setDirectRendering(format.directRendering());
  103. retFormat.setDoubleBuffer(format.doubleBuffer());
  104. if (format.greenBufferSize() >= 0)
  105. retFormat.setGreenBufferSize(format.greenBufferSize());
  106. if (format.redBufferSize() >= 0)
  107. retFormat.setRedBufferSize(format.redBufferSize());
  108. retFormat.setRgba(format.rgba());
  109. retFormat.setSampleBuffers(format.sampleBuffers());
  110. if (format.samples() >= 0)
  111. retFormat.setSamples(format.samples());
  112. retFormat.setStencil(format.stencil());
  113. if (format.stencilBufferSize() >= 0)
  114. retFormat.setStencilBufferSize(format.stencilBufferSize());
  115. retFormat.setStereo(format.stereo());
  116. retFormat.setSwapInterval(format.swapInterval());
  117. return retFormat;
  118. }
  119. void QGLContextPrivate::setupSharing() {
  120. Q_Q(QGLContext);
  121. QPlatformGLContext *sharedPlatformGLContext = platformContext->platformWindowFormat().sharedGLContext();
  122. if (sharedPlatformGLContext) {
  123. QGLContext *actualSharedContext = QGLContext::fromPlatformGLContext(sharedPlatformGLContext);
  124. sharing = true;
  125. QGLContextGroup::addShare(q,actualSharedContext);
  126. }
  127. }
  128. bool QGLFormat::hasOpenGL()
  129. {
  130. return QApplicationPrivate::platformIntegration()
  131. ->hasCapability(QPlatformIntegration::OpenGL);
  132. }
  133. void qDeleteQGLContext(void *handle)
  134. {
  135. QGLContext *context = static_cast<QGLContext *>(handle);
  136. delete context;
  137. }
  138. bool QGLContext::chooseContext(const QGLContext* shareContext)
  139. {
  140. Q_D(QGLContext);
  141. if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
  142. d->valid = false;
  143. }else {
  144. QWidget *widget = static_cast<QWidget *>(d->paintDevice);
  145. if (!widget->platformWindow()){
  146. QGLFormat glformat = format();
  147. QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat);
  148. if (shareContext) {
  149. winFormat.setSharedContext(shareContext->d_func()->platformContext);
  150. }
  151. if (widget->testAttribute(Qt::WA_TranslucentBackground))
  152. winFormat.setAlpha(true);
  153. winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
  154. winFormat.setWindowSurface(false);
  155. widget->setPlatformWindowFormat(winFormat);
  156. widget->winId();//make window
  157. }
  158. d->platformContext = widget->platformWindow()->glContext();
  159. Q_ASSERT(d->platformContext);
  160. d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat());
  161. d->valid =(bool) d->platformContext;
  162. if (d->valid) {
  163. d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
  164. }
  165. d->setupSharing();
  166. }
  167. return d->valid;
  168. }
  169. void QGLContext::reset()
  170. {
  171. Q_D(QGLContext);
  172. if (!d->valid)
  173. return;
  174. d->cleanup();
  175. d->crWin = false;
  176. d->sharing = false;
  177. d->valid = false;
  178. d->transpColor = QColor();
  179. d->initDone = false;
  180. QGLContextGroup::removeShare(this);
  181. if (d->platformContext) {
  182. d->platformContext->setQGLContextHandle(0,0);
  183. }
  184. }
  185. void QGLContext::makeCurrent()
  186. {
  187. Q_D(QGLContext);
  188. d->platformContext->makeCurrent();
  189. if (!d->workaroundsCached) {
  190. d->workaroundsCached = true;
  191. const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
  192. if (renderer && strstr(renderer, "Mali")) {
  193. d->workaround_brokenFBOReadBack = true;
  194. }
  195. }
  196. }
  197. void QGLContext::doneCurrent()
  198. {
  199. Q_D(QGLContext);
  200. d->platformContext->doneCurrent();
  201. }
  202. void QGLContext::swapBuffers() const
  203. {
  204. Q_D(const QGLContext);
  205. d->platformContext->swapBuffers();
  206. }
  207. void *QGLContext::getProcAddress(const QString &procName) const
  208. {
  209. Q_D(const QGLContext);
  210. return d->platformContext->getProcAddress(procName);
  211. }
  212. void QGLWidget::setContext(QGLContext *context,
  213. const QGLContext* shareContext,
  214. bool deleteOldContext)
  215. {
  216. Q_D(QGLWidget);
  217. if (context == 0) {
  218. qWarning("QGLWidget::setContext: Cannot set null context");
  219. return;
  220. }
  221. if (context->device() == 0) // a context may refere to more than 1 window.
  222. context->setDevice(this); //but its better to point to 1 of them than none of them.
  223. QGLContext* oldcx = d->glcx;
  224. d->glcx = context;
  225. if (!d->glcx->isValid())
  226. d->glcx->create(shareContext ? shareContext : oldcx);
  227. if (deleteOldContext)
  228. delete oldcx;
  229. }
  230. void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
  231. {
  232. initContext(context, shareWidget);
  233. }
  234. bool QGLFormat::hasOpenGLOverlays()
  235. {
  236. return false;
  237. }
  238. QColor QGLContext::overlayTransparentColor() const
  239. {
  240. return QColor(); // Invalid color
  241. }
  242. uint QGLContext::colorIndex(const QColor&) const
  243. {
  244. return 0;
  245. }
  246. void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
  247. {
  248. Q_UNUSED(fnt);
  249. Q_UNUSED(listBase);
  250. }
  251. /*
  252. QGLTemporaryContext implementation
  253. */
  254. class QGLTemporaryContextPrivate
  255. {
  256. public:
  257. QWidget *widget;
  258. QPlatformGLContext *context;
  259. };
  260. QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
  261. : d(new QGLTemporaryContextPrivate)
  262. {
  263. d->context = const_cast<QPlatformGLContext *>(QPlatformGLContext::currentContext());
  264. if (d->context)
  265. d->context->doneCurrent();
  266. d->widget = new QWidget;
  267. d->widget->setGeometry(0,0,3,3);
  268. QPlatformWindowFormat format = d->widget->platformWindowFormat();
  269. format.setWindowApi(QPlatformWindowFormat::OpenGL);
  270. format.setWindowSurface(false);
  271. d->widget->setPlatformWindowFormat(format);
  272. d->widget->winId();
  273. d->widget->platformWindow()->glContext()->makeCurrent();
  274. }
  275. QGLTemporaryContext::~QGLTemporaryContext()
  276. {
  277. d->widget->platformWindow()->glContext()->doneCurrent();
  278. if (d->context)
  279. d->context->makeCurrent();
  280. delete d->widget;
  281. }
  282. bool QGLWidgetPrivate::renderCxPm(QPixmap*)
  283. {
  284. return false;
  285. }
  286. /*! \internal
  287. Free up any allocated colormaps. This fn is only called for
  288. top-level widgets.
  289. */
  290. void QGLWidgetPrivate::cleanupColormaps()
  291. {
  292. }
  293. void QGLWidget::setMouseTracking(bool enable)
  294. {
  295. Q_UNUSED(enable);
  296. }
  297. bool QGLWidget::event(QEvent *e)
  298. {
  299. return QWidget::event(e);
  300. }
  301. void QGLWidget::resizeEvent(QResizeEvent *e)
  302. {
  303. Q_D(QGLWidget);
  304. QWidget::resizeEvent(e);
  305. if (!isValid())
  306. return;
  307. makeCurrent();
  308. if (!d->glcx->initialized())
  309. glInit();
  310. resizeGL(width(), height());
  311. }
  312. const QGLContext* QGLWidget::overlayContext() const
  313. {
  314. return 0;
  315. }
  316. void QGLWidget::makeOverlayCurrent()
  317. {
  318. }
  319. void QGLWidget::updateOverlayGL()
  320. {
  321. }
  322. const QGLColormap & QGLWidget::colormap() const
  323. {
  324. Q_D(const QGLWidget);
  325. return d->cmap;
  326. }
  327. void QGLWidget::setColormap(const QGLColormap & c)
  328. {
  329. Q_UNUSED(c);
  330. }
  331. QGLContext::QGLContext(QPlatformGLContext *platformContext)
  332. : d_ptr(new QGLContextPrivate(this))
  333. {
  334. Q_D(QGLContext);
  335. d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()));
  336. d->platformContext = platformContext;
  337. d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
  338. d->valid = true;
  339. d->setupSharing();
  340. }
  341. /*!
  342. \since 4.8
  343. Returns a OpenGL context for the platform-specific OpenGL context given by
  344. \a platformContext.
  345. */
  346. QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext)
  347. {
  348. if (!platformContext)
  349. return 0;
  350. if (platformContext->qGLContextHandle()) {
  351. return reinterpret_cast<QGLContext *>(platformContext->qGLContextHandle());
  352. }
  353. QGLContext *glContext = new QGLContext(platformContext);
  354. //Don't call create on context. This can cause the platformFormat to be set on the widget, which
  355. //will cause the platformWindow to be recreated.
  356. return glContext;
  357. }
  358. QT_END_NAMESPACE