summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp239
1 files changed, 1 insertions, 238 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 7655971..b3b5fe1 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -75,15 +75,14 @@
#include <QPaintEngine>
#include <private/qpainter_p.h>
#include <private/qfontengine_p.h>
-#include <private/qtextureglyphcache_p.h>
#include <private/qpixmapdata_gl_p.h>
#include <private/qdatabuffer_p.h>
#include "qglgradientcache_p.h"
#include "qglengineshadermanager_p.h"
#include "qgl2pexvertexarray_p.h"
-
#include "qtriangulatingstroker_p.h"
+#include "qtextureglyphcache_gl_p.h"
#include <QDebug>
@@ -91,240 +90,6 @@ QT_BEGIN_NAMESPACE
//#define QT_GL_NO_SCISSOR_TEST
-static const GLuint GL_STENCIL_HIGH_BIT = 0x80;
-static const GLuint QT_BRUSH_TEXTURE_UNIT = 0;
-static const GLuint QT_IMAGE_TEXTURE_UNIT = 0; //Can be the same as brush texture unit
-static const GLuint QT_MASK_TEXTURE_UNIT = 1;
-static const GLuint QT_BACKGROUND_TEXTURE_UNIT = 2;
-
-#ifdef Q_WS_WIN
-extern Q_GUI_EXPORT bool qt_cleartype_enabled;
-#endif
-
-class QGLTextureGlyphCache : public QObject, public QTextureGlyphCache
-{
- Q_OBJECT
-public:
- QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
- ~QGLTextureGlyphCache();
-
- virtual void createTextureData(int width, int height);
- virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
- virtual int glyphMargin() const;
-
- inline GLuint texture() const { return m_texture; }
-
- inline int width() const { return m_width; }
- inline int height() const { return m_height; }
-
- inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
-
-
-public Q_SLOTS:
- void contextDestroyed(const QGLContext *context) {
- if (context == ctx) {
- const QGLContext *nextCtx = qt_gl_transfer_context(ctx);
- if (!nextCtx) {
- // the context may not be current, so we cannot directly
- // destroy the fbo and texture here, but since the context
- // is about to be destroyed, the GL server will do the
- // clean up for us anyway
- m_fbo = 0;
- m_texture = 0;
- ctx = 0;
- } else {
- // since the context holding the texture is shared, and
- // about to be destroyed, we have to transfer ownership
- // of the texture to one of the share contexts
- ctx = const_cast<QGLContext *>(nextCtx);
- }
- }
- }
-
-private:
- QGLContext *ctx;
-
- QGL2PaintEngineExPrivate *pex;
-
- GLuint m_texture;
- GLuint m_fbo;
-
- int m_width;
- int m_height;
-
- QGLShaderProgram *m_program;
-};
-
-QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
- : QTextureGlyphCache(type, matrix)
- , ctx(context)
- , m_width(0)
- , m_height(0)
-{
- glGenFramebuffers(1, &m_fbo);
- connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(contextDestroyed(const QGLContext*)));
-}
-
-QGLTextureGlyphCache::~QGLTextureGlyphCache()
-{
- if (ctx) {
- QGLShareContextScope scope(ctx);
- glDeleteFramebuffers(1, &m_fbo);
-
- if (m_width || m_height)
- glDeleteTextures(1, &m_texture);
- }
-}
-
-void QGLTextureGlyphCache::createTextureData(int width, int height)
-{
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- m_width = width;
- m_height = height;
-
- QVarLengthArray<uchar> data(width * height);
- for (int i = 0; i < data.size(); ++i)
- data[i] = 0;
-
- if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-}
-
-void QGLTextureGlyphCache::resizeTextureData(int width, int height)
-{
- // ### the QTextureGlyphCache API needs to be reworked to allow
- // ### resizeTextureData to fail
-
- int oldWidth = m_width;
- int oldHeight = m_height;
-
- GLuint oldTexture = m_texture;
- createTextureData(width, height);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
-
- GLuint tmp_texture;
- glGenTextures(1, &tmp_texture);
- glBindTexture(GL_TEXTURE_2D, tmp_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_2D, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, tmp_texture, 0);
-
- glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- glBindTexture(GL_TEXTURE_2D, oldTexture);
-
- pex->transferMode(BrushDrawingMode);
-
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
- glViewport(0, 0, oldWidth, oldHeight);
-
- float vertexCoordinateArray[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
- float textureCoordinateArray[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
-
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray);
-
- pex->shaderManager->useBlitProgram();
- pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
-#ifdef QT_OPENGL_ES_2
- QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);
- buffer.resize(4*oldWidth*oldHeight);
- glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
-
- // do an in-place conversion from GL_RGBA to GL_ALPHA
- for (int i=0; i<oldWidth*oldHeight; ++i)
- buffer.data()[i] = buffer.at(4*i + 3);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,
- GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());
-#else
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
-#endif
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_RENDERBUFFER_EXT, 0);
- glDeleteTextures(1, &tmp_texture);
- glDeleteTextures(1, &oldTexture);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
-
- glViewport(0, 0, pex->width, pex->height);
- pex->updateClipScissorTest();
-}
-
-void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
-{
- QImage mask = textureMapForGlyph(glyph);
- const int maskWidth = mask.width();
- const int maskHeight = mask.height();
-
- if (mask.format() == QImage::Format_Mono) {
- mask = mask.convertToFormat(QImage::Format_Indexed8);
- for (int y = 0; y < maskHeight; ++y) {
- uchar *src = (uchar *) mask.scanLine(y);
- for (int x = 0; x < maskWidth; ++x)
- src[x] = -src[x]; // convert 0 and 1 into 0 and 255
- }
- }
-
-
- glBindTexture(GL_TEXTURE_2D, m_texture);
- if (mask.format() == QImage::Format_RGB32) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
- } else {
-#ifdef QT_OPENGL_ES2
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
-#else
- // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
- // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
- // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a
- // multiple of four bytes per line, and most of the glyph shows up correctly in the
- // texture, which makes me think that this is a driver bug.
- // One workaround is to make sure the mask width is a multiple of four bytes, for instance
- // by converting it to a format with four bytes per pixel. Another is to copy one line at a
- // time.
-
- for (int i = 0; i < maskHeight; ++i)
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
-#endif
- }
-}
-
-int QGLTextureGlyphCache::glyphMargin() const
-{
-#if defined(Q_WS_MAC)
- return 2;
-#elif defined (Q_WS_X11)
- return 0;
-#else
- return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
-#endif
-}
-
extern QImage qt_imageForBrush(int brushStyle, bool invert);
////////////////////////////////// Private Methods //////////////////////////////////////////
@@ -2261,5 +2026,3 @@ QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()
}
QT_END_NAMESPACE
-
-#include "qpaintengineex_opengl2.moc"