📄 qpaintengine_opengl.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 <private/qtextengine_p.h>#include <qdebug.h>#include <private/qfontengine_p.h>#include <private/qmath_p.h>#include <private/qdrawhelper_p.h>#include <private/qpaintengine_p.h>#include "qapplication.h"#include "qbrush.h"#include "qgl.h"#include <private/qgl_p.h>#include "qmap.h"#include <private/qpaintengine_opengl_p.h>#include <private/qdatabuffer_p.h>#include "qpen.h"#include "qvarlengtharray.h"#include <private/qpainter_p.h>#include <qglpixelbuffer.h>#include <private/qglpixelbuffer_p.h>#include <private/qbezier_p.h>#include <qglframebufferobject.h>#include "private/qtessellator_p.h"#include "util/fragmentprograms_p.h"#ifdef Q_WS_QWS#include "private/qglpaintdevice_qws_p.h"#include "private/qglwindowsurface_qws_p.h"#include "qwsmanager_qws.h"#include "private/qwsmanager_p.h"#endifextern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp#define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(drawable.context());#define QGL_D_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(d->drawable.context());#include <stdlib.h>#include "qpaintengine_opengl_p.h"#define QREAL_MAX 9e100#define QREAL_MIN -9e100extern QGLContextPrivate *qt_glctx_get_dptr(QGLContext *);extern int qt_next_power_of_two(int v);#define DISABLE_DEBUG_ONCE//#define DEBUG_DISPLAY_MASK_TEXTURE#ifdef DISABLE_DEBUG_ONCE#define DEBUG_OVERRIDE(state) ;#define DEBUG_ONCE_STR(str) ;#define DEBUG_ONCE if (0)#elsestatic int DEBUG_OVERRIDE_FLAG = 0;static bool DEBUG_TEMP_FLAG;#define DEBUG_OVERRIDE(state) { state ? ++DEBUG_OVERRIDE_FLAG : --DEBUG_OVERRIDE_FLAG; }#define DEBUG_ONCE if ((DEBUG_TEMP_FLAG = DEBUG_OVERRIDE_FLAG) && 0) ; else for (static int DEBUG_ONCE_FLAG = false; !DEBUG_ONCE_FLAG || DEBUG_TEMP_FLAG; DEBUG_ONCE_FLAG = true, DEBUG_TEMP_FLAG = false)#define DEBUG_ONCE_STR(str) DEBUG_ONCE qDebug() << (str);#endifstatic inline void qt_glColor4ubv(unsigned char *col){#ifdef Q_WS_QWS glColor4f(col[0]/255.0, col[1]/255.0, col[2]/255.0, col[3]/255.0);#else glColor4ubv(col);#endif}static void qt_add_rect_to_array(const QRectF &r, float *array){ qreal left = r.left(); qreal right = r.right(); qreal top = r.top(); qreal bottom = r.bottom(); array[0] = left; array[1] = top; array[2] = right; array[3] = top; array[4] = right; array[5] = bottom; array[6] = left; array[7] = bottom;}static void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, float *array){ array[0] = x1; array[1] = y1; array[2] = x2; array[3] = y1; array[4] = x2; array[5] = y2; array[6] = x1; array[7] = y2;}struct QGLTrapezoid{ QGLTrapezoid() {} QGLTrapezoid(qreal top_, qreal bottom_, qreal topLeftX_, qreal topRightX_, qreal bottomLeftX_, qreal bottomRightX_) : top(top_), bottom(bottom_), topLeftX(topLeftX_), topRightX(topRightX_), bottomLeftX(bottomLeftX_), bottomRightX(bottomRightX_) {} const QGLTrapezoid translated(const QPointF &delta) const; qreal top; qreal bottom; qreal topLeftX; qreal topRightX; qreal bottomLeftX; qreal bottomRightX;};const QGLTrapezoid QGLTrapezoid::translated(const QPointF &delta) const{ QGLTrapezoid trap(*this); trap.top += delta.y(); trap.bottom += delta.y(); trap.topLeftX += delta.x(); trap.topRightX += delta.x(); trap.bottomLeftX += delta.x(); trap.bottomRightX += delta.x(); return trap;}class QGLDrawable {public: QGLDrawable() : widget(0), buffer(0), fbo(0)#ifdef Q_WS_QWS , wsurf(0)#endif {} inline void setDevice(QPaintDevice *pdev); inline void swapBuffers(); inline void makeCurrent(); inline void doneCurrent(); inline QSize size() const; inline QGLFormat format() const; inline GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); inline GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); inline QColor backgroundColor() const; inline QGLContext *context() const; inline bool autoFillBackground() const;private: QGLWidget *widget; QGLPixelBuffer *buffer; QGLFramebufferObject *fbo;#ifdef Q_WS_QWS QWSGLWindowSurface *wsurf;#endif};void QGLDrawable::setDevice(QPaintDevice *pdev){ widget = 0; buffer = 0; fbo = 0;#ifdef Q_WS_QWS wsurf = 0;#endif if (pdev->devType() == QInternal::Widget) widget = static_cast<QGLWidget *>(pdev); else if (pdev->devType() == QInternal::Pbuffer) buffer = static_cast<QGLPixelBuffer *>(pdev); else if (pdev->devType() == QInternal::FramebufferObject) fbo = static_cast<QGLFramebufferObject *>(pdev);#ifdef Q_WS_QWS else if (pdev->devType() == QInternal::UnknownDevice) wsurf = static_cast<QWSGLPaintDevice*>(pdev)->windowSurface();#endif}inline void QGLDrawable::swapBuffers(){ if (widget) { if (widget->autoBufferSwap()) widget->swapBuffers(); } else { glFlush(); }}inline void QGLDrawable::makeCurrent(){ if (widget) widget->makeCurrent(); else if (buffer) buffer->makeCurrent(); else if (fbo) fbo->bind();}inline void QGLDrawable::doneCurrent(){ if (fbo) fbo->release();}inline QSize QGLDrawable::size() const{ if (widget) { return QSize(widget->d_func()->glcx->device()->width(), widget->d_func()->glcx->device()->height()); } else if (buffer) { return buffer->size(); } else if (fbo) { return fbo->size();#ifdef Q_WS_QWS } else if (wsurf) { return wsurf->window()->frameSize();#endif } return QSize();}inline QGLFormat QGLDrawable::format() const{ if (widget) return widget->format(); else if (buffer) return buffer->format(); else if (fbo && QGLContext::currentContext()) { QGLFormat fmt = QGLContext::currentContext()->format(); fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil); fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment); return fmt; }#ifdef Q_WS_QWS else if (wsurf) return wsurf->context()->format();#endif return QGLFormat();}inline GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format){ if (widget) return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); else if (buffer) return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); else if (fbo && QGLContext::currentContext()) return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true);#ifdef Q_WS_QWS else if (wsurf) return wsurf->context()->d_func()->bindTexture(image, target, format, true);#endif return 0;}inline GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format){ if (widget) return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true); else if (buffer) return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true); else if (fbo && QGLContext::currentContext()) return const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true);#ifdef Q_WS_QWS else if (wsurf) return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true);#endif return 0;}inline QColor QGLDrawable::backgroundColor() const{ if (widget) return widget->palette().brush(widget->backgroundRole()).color(); return QApplication::palette().brush(QPalette::Background).color();}inline QGLContext *QGLDrawable::context() const{ if (widget) return widget->d_func()->glcx; else if (buffer) return buffer->d_func()->qctx; else if (fbo) return const_cast<QGLContext *>(QGLContext::currentContext());#ifdef Q_WS_QWS else if (wsurf) return wsurf->context();#endif return 0;}inline bool QGLDrawable::autoFillBackground() const{ if (widget) return widget->autoFillBackground(); else return false;}class QOpenGLImmediateModeTessellator;class QGLMaskGenerator;class QGLOffscreen;class QGLMaskTextureCache{public: void setOffscreenSize(const QSize &offscreenSize); void setDrawableSize(const QSize &drawableSize); struct CacheLocation { QRect rect; int channel; QRect screen_rect; }; struct CacheInfo { inline CacheInfo(const QPainterPath &p, const QTransform &m, qreal w = -1) : path(p), matrix(m), stroke_width(w), age(0) {} QPainterPath path; QTransform matrix; qreal stroke_width; CacheLocation loc; int age; }; struct QuadTreeNode { quint64 key; int largest_available_block; int largest_used_block; }; CacheLocation getMask(QGLMaskGenerator &maskGenerator, QOpenGLPaintEnginePrivate *engine); typedef QMultiHash<quint64, CacheInfo> QGLTextureCacheHash; enum {block_size = 64}; // throw out keys that are too old void maintainCache(); void clearCache();private: quint64 hash(const QPainterPath &p, const QTransform &m, qreal w); void createMask(quint64 key, CacheInfo &info, QGLMaskGenerator &maskGenerator); QSize offscreenSize; QSize drawableSize; QGLTextureCacheHash cache; QVector<QuadTreeNode> occupied_quadtree[4]; void quadtreeUpdate(int channel, int node, int current_block_size); void quadtreeAllocate(quint64 key, const QSize &size, QRect *rect, int *channel); bool quadtreeFindAvailableLocation(const QSize &size, QRect *rect, int *channel); void quadtreeFindExistingLocation(const QSize &size, QRect *rect, int *channel); void quadtreeInsert(int channel, quint64 key, const QRect &rect, int node = 0); void quadtreeClear(int channel, const QRect &rect, int node = 0); int quadtreeBlocksize(int node); QPoint quadtreeLocation(int node); QOpenGLPaintEnginePrivate *engine;};Q_GLOBAL_STATIC(QGLMaskTextureCache, qt_mask_texture_cache)class QGLOffscreen : public QObject{ Q_OBJECT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -