📄 qgl_qws.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtOpenGL module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qgl.h"#if defined(Q_WS_QWS)#include <GLES/egl.h>#include <GLES/gl.h>#include <qdirectpainter_qws.h>#include <qglscreen_qws.h>#include <private/qglwindowsurface_qws_p.h>#endif#include <private/qbackingstore_p.h>#include <private/qfont_p.h>#include <private/qfontengine_p.h>#include <private/qgl_p.h>#include <private/qpaintengine_opengl_p.h>#include <qpixmap.h>#include <qtimer.h>#include <qapplication.h>#include <qstack.h>#include <qdesktopwidget.h>#include <qdebug.h>#include <qvarlengtharray.h>#define Q_USE_QEGL//#define Q_USE_DIRECTPAINTER// this one for full QScreen implemented using EGL/GLES://#define Q_USE_EGLWINDOWSURFACE#ifdef Q_USE_QEGL#include "qegl_qws_p.h"#ifdef Q_USE_EGLWINDOWSURFACE#include "private/qglwindowsurface_qws_p.h"#endif#endif/***************************************************************************** QOpenGL debug facilities *****************************************************************************///#define DEBUG_OPENGL_REGION_UPDATEbool QGLFormat::hasOpenGL(){ return true;}bool QGLFormat::hasOpenGLOverlays(){#ifdef Q_USE_EGLWINDOWSURFACE return false;#else return true;#endif}#define QT_EGL_CHECK(x) \ if (!(x)) { \ EGLint err = eglGetError(); \ printf("egl " #x " failure %x!\n", err); \ } \#define QT_EGL_ERR(txt) \ do { \ EGLint err = eglGetError(); \ if (err != EGL_SUCCESS) \ printf( txt " failure %x!\n", err); \ } while (0)#define QT_EGL_CHECK_ATTR(attr, val) success = eglGetConfigAttrib(dpy, config, attr, &value); \ if (!success || value != val) \ return false#if defined(Q_USE_QEGL) && !defined(Q_USE_EGLWINDOWSURFACE)static bool checkConfig(EGLDisplay dpy, EGLConfig config, int r, int g, int b, int a){ EGLint value; EGLBoolean success; QT_EGL_CHECK_ATTR(EGL_RED_SIZE, r); QT_EGL_CHECK_ATTR(EGL_GREEN_SIZE, g); QT_EGL_CHECK_ATTR(EGL_BLUE_SIZE, b); QT_EGL_CHECK_ATTR(EGL_ALPHA_SIZE, a); return true;}#endifbool QGLContext::chooseContext(const QGLContext* shareContext){#ifdef Q_USE_EGLWINDOWSURFACE // EGL Only works if drawable is a QGLWidget. QGLPixelBuffer not supported if (device() && device()->devType() == QInternal::Widget) return static_cast<QGLScreen*>(QScreen::instance())->chooseContext(this, shareContext); else return false;#else Q_D(QGLContext); d->cx = 0; EGLint matchingConfigs; EGLint configAttribs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_ALPHA_MASK_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, EGL_DONT_CARE, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE, EGL_NONE }; if (d->paintDevice->devType() == QInternal::Image) { QImage *img = static_cast<QImage*>(d->paintDevice); if (img->format() == QImage::Format_RGB16) { configAttribs[1] = 5; configAttribs[3] = 6; configAttribs[5] = 5; configAttribs[7] = 0; } } else if (d->paintDevice->devType() == QInternal::Widget) {#ifdef Q_USE_QEGL if (qt_screen->pixmapDepth() == 16) { configAttribs[1] = 5; configAttribs[3] = 6; configAttribs[5] = 5; configAttribs[7] = 0; } configAttribs[15] = EGL_PIXMAP_BIT;#else configAttribs[1] = 0; configAttribs[3] = 0; configAttribs[5] = 0; configAttribs[7] = 0; configAttribs[9] = 0;#endif } if (deviceIsPixmap() || d->paintDevice->devType() == QInternal::Image) configAttribs[15] = EGL_PIXMAP_BIT; //Ask for an available display d->dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); QT_EGL_CHECK(d->dpy); //Display initialization (don't care about the OGLES version numbers) if (!eglInitialize(d->dpy, NULL, NULL)) return false; eglBindAPI(EGL_OPENGL_ES_API); if (!eglChooseConfig(d->dpy, configAttribs, 0, 0, &matchingConfigs)) return false; //If there isn't any configuration good enough if (matchingConfigs < 1) return false; QVarLengthArray<EGLConfig> configs(matchingConfigs); if (!eglChooseConfig(d->dpy, configAttribs, configs.data(), matchingConfigs, &matchingConfigs)) return false;#ifdef Q_USE_QEGL bool found = false; for (int i = 0; i < matchingConfigs; ++i) { if (checkConfig(d->dpy, configs[i], configAttribs[1], configAttribs[3], configAttribs[5], configAttribs[7])) { d->config = configs[i]; found = true; break; } } if (!found) { qWarning("QGLContext::chooseContext none of the %d 'matching' configs actually match", matchingConfigs); return false; }#else d->config = configs[0];#endif GLint res; eglGetConfigAttrib(d->dpy, d->config, EGL_LEVEL,&res); d->glFormat.setPlane(res); QT_EGL_ERR("eglGetConfigAttrib"); /* if(deviceIsPixmap()) res = 0; else eglDescribePixelFormat(fmt, EGL_DOUBLEBUFFER, &res); d->glFormat.setDoubleBuffer(res); */ eglGetConfigAttrib(d->dpy,d->config, EGL_DEPTH_SIZE, &res); d->glFormat.setDepth(res); if (d->glFormat.depth()) d->glFormat.setDepthBufferSize(res); //eglGetConfigAttrib(d->dpy,d->config, EGL_RGBA, &res); //d->glFormat.setRgba(res); eglGetConfigAttrib(d->dpy,d->config, EGL_ALPHA_SIZE, &res); d->glFormat.setAlpha(res); if (d->glFormat.alpha()) d->glFormat.setAlphaBufferSize(res); //eglGetConfigAttrib(d->dpy,d->config, EGL_ACCUM_RED_SIZE, &res); //d->glFormat.setAccum(res); //if (d->glFormat.accum()) // d->glFormat.setAccumBufferSize(res); eglGetConfigAttrib(d->dpy, d->config, EGL_STENCIL_SIZE, &res); d->glFormat.setStencil(res); if (d->glFormat.stencil()) d->glFormat.setStencilBufferSize(res); //eglGetConfigAttrib(d->dpy, d->config, EGL_STEREO, &res); //d->glFormat.setStereo(res); eglGetConfigAttrib(d->dpy, d->config, EGL_SAMPLE_BUFFERS, &res); d->glFormat.setSampleBuffers(res); if (d->glFormat.sampleBuffers()) { eglGetConfigAttrib(d->dpy, d->config, EGL_SAMPLES, &res); d->glFormat.setSamples(res); } if(shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) { qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); shareContext = 0; } EGLContext ctx = eglCreateContext(d->dpy, d->config, 0, 0); //(shareContext ? shareContext->d_func()->cx : 0), //configAttribs); if(!ctx) { GLenum err = eglGetError(); qDebug("eglCreateContext err %x", err); if(err == EGL_BAD_MATCH || err == EGL_BAD_CONTEXT) { if(shareContext && shareContext->d_func()->cx) { qWarning("QGLContext::chooseContext(): Context sharing mismatch!"); if(!(ctx = eglCreateContext(d->dpy, d->config, 0, configAttribs))) return false; shareContext = 0; } } if(!ctx) { qWarning("QGLContext::chooseContext(): Unable to create QGLContext"); return false; } } d->cx = ctx; if (shareContext && shareContext->d_func()->cx) { QGLContext *share = const_cast<QGLContext *>(shareContext); d->sharing = true; share->d_func()->sharing = true; } // vblank syncing GLint interval = d->reqFormat.swapInterval(); if (interval != -1) { if (interval != 0) eglSwapInterval(d->dpy, interval); } if (deviceIsPixmap() || d->paintDevice->devType() == QInternal::Image) { d->surface = eglCreatePixmapSurface(d->dpy, d->config, (NativeWindowType)d->paintDevice, configAttribs); } else {#ifndef Q_USE_QEGL d->surface = eglCreateWindowSurface(d->dpy, d->config, (NativeWindowType)d->paintDevice, 0); if (!d->surface) { GLenum err = eglGetError(); qDebug("eglCreateWindowSurface err %x", err); } qDebug() << "create Window surface" << d->surface;#endif } if (!d->surface) return false; return true;#endif}void QGLContext::reset(){ Q_D(QGLContext); if (!d->valid) return; doneCurrent();#ifndef Q_USE_EGLWINDOWSURFACE if (d->cx) eglDestroyContext(d->dpy, d->cx); d->crWin = false;#endif d->cx = 0; d->sharing = false; d->valid = false; d->transpColor = QColor(); d->initDone = false; qgl_share_reg()->removeShare(this);}void QGLContext::makeCurrent(){ Q_D(QGLContext); if(!d->valid) { qWarning("QGLContext::makeCurrent(): Cannot make invalid context current"); return; }#ifndef Q_USE_EGLWINDOWSURFACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -