X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fgui%2Fopengl%2Fqopenglpaintengine.cpp;h=2f84a0f2953641ac131bcee8dc2fd135c5f08754;hb=16f8afa5b1c906ae60f98619d17c34b40c21804e;hp=dfb854937561b35ad1933f91c5e9d1f67bc66665;hpb=c8fcc2929820b5deafc1e84a3bcb719d87028bd6;p=profile%2Fivi%2Fqtbase.git diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index dfb8549..2f84a0f 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -65,6 +65,7 @@ // #define QT_OPENGL_CACHE_AS_VBOS #include "qopenglgradientcache_p.h" +#include "qopengltexturecache_p.h" #include "qopenglpaintengine_p.h" #include //for memcpy @@ -84,20 +85,13 @@ #include "qopenglengineshadermanager_p.h" #include "qopengl2pexvertexarray_p.h" -#include "qopengltriangulatingstroker_p.h" #include "qopengltextureglyphcache_p.h" #include QT_BEGIN_NAMESPACE -#if defined(Q_WS_WIN) -extern Q_GUI_EXPORT bool qt_cleartype_enabled; -#endif -#ifdef Q_WS_MAC -extern bool qt_applefontsmoothing_enabled; -#endif Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); @@ -129,14 +123,14 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra lastTextureUsed = id; if (smoothPixmapTransform) { - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } - glTexParameterf(target, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameterf(target, GL_TEXTURE_WRAP_T, wrapMode); + glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); } @@ -197,7 +191,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() QImage texImage = qt_imageForBrush(style, false); funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - //ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QOpenGLContext::InternalBindOption); + QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); } else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { @@ -227,11 +221,9 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QOpenGLTexture *tex = 0;//ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, - // QOpenGLContext::InternalBindOption | - // QOpenGLContext::CanFlipNativePixmapBindOption); + QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); - textureInvertedY = tex->invertedY(); + textureInvertedY = false; } brushTextureDirty = false; } @@ -342,7 +334,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushUniforms() QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y()); qreal m22 = -1; qreal dy = height; - if (device->isFlipped()) { + if (device->paintFlipped()) { m22 = 1; dy = 0; } @@ -390,7 +382,7 @@ void QOpenGL2PaintEngineExPrivate::updateMatrix() GLfloat dx = transform.dx(); GLfloat dy = transform.dy(); - if (device->isFlipped()) { + if (device->paintFlipped()) { hfactor *= -1; dy -= height; } @@ -542,7 +534,8 @@ void QOpenGL2PaintEngineEx::beginNativePainting() d->funcs.glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 - const QSurfaceFormat &fmt = d->device->format(); + Q_ASSERT(QOpenGLContext::currentContext()); + const QSurfaceFormat &fmt = d->device->context()->format(); if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) || fmt.profile() == QSurfaceFormat::CompatibilityProfile) { @@ -679,8 +672,8 @@ void QOpenGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, voi d->unusedIBOSToClean << c->ibo; #else Q_UNUSED(engine); - qFree(c->vertices); - qFree(c->indices); + free(c->vertices); + free(c->indices); #endif delete c; } @@ -725,7 +718,7 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) cache->vbo = 0; Q_ASSERT(cache->ibo == 0); #else - qFree(cache->vertices); + free(cache->vertices); Q_ASSERT(cache->indices == 0); #endif updateCache = true; @@ -753,7 +746,7 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); cache->ibo = 0; #else - cache->vertices = (float *) qMalloc(floatSizeInBytes); + cache->vertices = (float *) malloc(floatSizeInBytes); memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); cache->indices = 0; #endif @@ -805,8 +798,8 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) glDeleteBuffers(1, &cache->vbo); glDeleteBuffers(1, &cache->ibo); #else - qFree(cache->vertices); - qFree(cache->indices); + free(cache->vertices); + free(cache->indices); #endif updateCache = true; } @@ -841,12 +834,12 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) vertices[i] = float(inverseScale * polys.vertices.at(i)); funcs.glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW); #else - cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size()); + cache->vertices = (float *) malloc(sizeof(float) * polys.vertices.size()); if (polys.indices.type() == QVertexIndexVector::UnsignedInt) { - cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size()); + cache->indices = (quint32 *) malloc(sizeof(quint32) * polys.indices.size()); memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size()); } else { - cache->indices = (quint16 *) qMalloc(sizeof(quint16) * polys.indices.size()); + cache->indices = (quint16 *) malloc(sizeof(quint16) * polys.indices.size()); memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size()); } for (int i = 0; i < polys.vertices.size(); ++i) @@ -878,7 +871,7 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path) // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable path.makeCacheable(); - if (!device->format().stencilBufferSize()) { + if (device->context()->format().stencilBufferSize() == 0) { // If there is no stencil buffer, triangulate the path instead. QRectF bbox = path.controlPointRect(); @@ -1359,18 +1352,15 @@ void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixma d->transferMode(ImageDrawingMode); d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - QOpenGLTexture *texture = 0; -// ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions); + GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); - GLfloat top = texture->invertedY() ? (pixmap.height() - src.top()) : src.top(); - GLfloat bottom = texture->invertedY() ? (pixmap.height() - src.bottom()) : src.bottom(); - QOpenGLRect srcRect(src.left(), top, src.right(), bottom); + QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom()); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && !pixmap.hasAlpha(); d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - state()->renderHints & QPainter::SmoothPixmapTransform, texture->id()); + state()->renderHints & QPainter::SmoothPixmapTransform, id); d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap); } @@ -1396,8 +1386,7 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - QOpenGLTexture *texture = 0;//ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, bindOptions); - GLuint id = texture->id(); + GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id); @@ -1415,13 +1404,12 @@ void QOpenGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) // don't try to cache huge fonts or vastly transformed fonts QFontEngine *fontEngine = textItem->fontEngine(); - const qreal pixelSize = fontEngine->fontDef.pixelSize; - if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f) { + if (shouldDrawCachedGlyphs(fontEngine, s->matrix) || det < 0.25f || det > 4.f) { QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat) : d->glyphCacheType; if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { - if (d->device->alphaRequested() || s->matrix.type() > QTransform::TxTranslate + if (d->device->context()->format().alphaBufferSize() > 0 || s->matrix.type() > QTransform::TxTranslate || (s->composition_mode != QPainter::CompositionMode_Source && s->composition_mode != QPainter::CompositionMode_SourceOver)) { @@ -1470,8 +1458,7 @@ void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &text bool drawCached = txtype < QTransform::TxProject; // don't try to cache huge fonts or vastly transformed fonts - const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; - if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f) + if (shouldDrawCachedGlyphs(ti.fontEngine, s->matrix) || det < 0.25f || det > 4.f) drawCached = false; QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 @@ -1480,7 +1467,7 @@ void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &text if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { - if (d->device->alphaRequested() || txtype > QTransform::TxTranslate + if (d->device->context()->format().alphaBufferSize() > 0 || txtype > QTransform::TxTranslate || (state()->composition_mode != QPainter::CompositionMode_Source && state()->composition_mode != QPainter::CompositionMode_SourceOver)) { @@ -1534,13 +1521,6 @@ namespace { } -#if defined(Q_WS_WIN) -static bool fontSmoothingApproximately(qreal target) -{ - extern Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; // qapplication_win.cpp - return (qAbs(qt_fontsmoothing_gamma - target) < 0.2); -} -#endif // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO @@ -1553,12 +1533,13 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type void *cacheKey = ctx->shareGroup(); bool recreateVertexArrays = false; + QFontEngine *fe = staticTextItem->fontEngine(); QOpenGLTextureGlyphCache *cache = - (QOpenGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform()); + (QOpenGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, QTransform()); if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) { cache = new QOpenGLTextureGlyphCache(glyphType, QTransform()); - staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache); + fe->setGlyphCache(cacheKey, cache); recreateVertexArrays = true; } @@ -1582,11 +1563,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type // cache so this text is performed before we test if the cache size has changed. if (recreateVertexArrays) { cache->setPaintEnginePrivate(this); - if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, + if (!cache->populate(fe, staticTextItem->numGlyphs, staticTextItem->glyphs, staticTextItem->glyphPositions)) { // No space for glyphs in cache. We need to reset it and try again. cache->clear(); - cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs, + cache->populate(fe, staticTextItem->numGlyphs, staticTextItem->glyphs, staticTextItem->glyphPositions); } cache->fillInPendingGlyphs(); @@ -1597,7 +1578,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type transferMode(TextDrawingMode); - int margin = cache->glyphMargin(); + int margin = fe->glyphMargin(glyphType); GLfloat dx = 1.0 / cache->width(); GLfloat dy = 1.0 / cache->height(); @@ -1637,11 +1618,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type vertexCoordinates->clear(); textureCoordinates->clear(); - bool supportsSubPixelPositions = staticTextItem->fontEngine()->supportsSubPixelPositions(); + bool supportsSubPixelPositions = fe->supportsSubPixelPositions(); for (int i=0; inumGlyphs; ++i) { QFixed subPixelPosition; if (supportsSubPixelPositions) - subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x); + subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition); @@ -1793,11 +1774,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type if (cache->filterMode() != filterMode) { if (filterMode == QOpenGLTextureGlyphCache::Linear) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } cache->setFilterMode(filterMode); } @@ -1805,13 +1786,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type bool srgbFrameBufferEnabled = false; if (funcs.hasOpenGLExtension(QOpenGLExtensions::SRGBFrameBuffer)) { -#if defined(Q_WS_MAC) - if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) -#elif defined(Q_WS_WIN) - if (glyphType != QFontEngineGlyphCache::Raster_RGBMask || fontSmoothingApproximately(2.1)) -#else if (false) -#endif { glEnable(GL_FRAMEBUFFER_SRGB); srgbFrameBufferEnabled = true; @@ -1906,24 +1881,14 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra } funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - QOpenGLTexture *texture = 0;//ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, - // QOpenGLContext::InternalBindOption - // | QOpenGLContext::CanFlipNativePixmapBindOption); - - if (texture->invertedY()) { - // Flip texture y-coordinate. - QOpenGLPoint *data = textureCoordinateArray.data(); - for (int i = 0; i < 6 * fragmentCount; ++i) - data[i].y = 1 - data[i].y; - } - + GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); transferMode(ImageArrayDrawingMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id()); + q->state()->renderHints & QPainter::SmoothPixmapTransform, id); // Setup for texture drawing currentBrush = noBrush; @@ -1944,24 +1909,21 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) { Q_D(QOpenGL2PaintEngineEx); -// qDebug("QOpenGL2PaintEngineEx::begin()"); - if (pdev->devType() == QInternal::OpenGL) - d->device = static_cast(pdev); - else - d->device = QOpenGLPaintDevice::getDevice(pdev); + Q_ASSERT(pdev->devType() == QInternal::OpenGL); + d->device = static_cast(pdev); if (!d->device) return false; - if (d->device->group() != QOpenGLContextGroup::currentContextGroup()) { - qWarning("QPainter::begin(): OpenGL resource not valid in current context"); + if (d->device->context() != QOpenGLContext::currentContext()) { + qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current"); return false; } d->ctx = QOpenGLContext::currentContext(); d->ctx->d_func()->active_engine = this; - d->funcs.initializeGLFunctions(); + d->funcs.initializeOpenGLFunctions(); for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) d->vertexAttributeArraysEnabledState[i] = false; @@ -1983,10 +1945,6 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); d->stencilClean = true; - // Calling begin paint should make the correct context current. So, any - // code which calls into GL or otherwise needs a current context *must* - // go after beginPaint: - d->device->beginPaint(); d->shaderManager = new QOpenGLEngineShaderManager(d->ctx); glDisable(GL_STENCIL_TEST); @@ -2000,20 +1958,13 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) -#if defined(Q_WS_WIN) - if (qt_cleartype_enabled - && (fontSmoothingApproximately(1.0) || fontSmoothingApproximately(2.1))) -#endif -#if defined(Q_WS_MAC) - if (qt_applefontsmoothing_enabled) -#endif d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; #endif #if defined(QT_OPENGL_ES_2) // OpenGL ES can't switch MSAA off, so if the gl paint device is // multisampled, it's always multisampled. - d->multisamplingAlwaysEnabled = d->device->format().samples() > 1; + d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1; #else d->multisamplingAlwaysEnabled = false; #endif @@ -2028,7 +1979,6 @@ bool QOpenGL2PaintEngineEx::end() QOpenGLContext *ctx = d->ctx; d->funcs.glUseProgram(0); d->transferMode(BrushDrawingMode); - d->device->endPaint(); ctx->d_func()->active_engine = 0; @@ -2062,8 +2012,6 @@ void QOpenGL2PaintEngineEx::ensureActive() d->needsSync = true; } - d->device->ensureActiveTarget(); - if (d->needsSync) { d->transferMode(BrushDrawingMode); glViewport(0, 0, d->width, d->height); @@ -2120,7 +2068,7 @@ void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect) const int left = rect.left(); const int width = rect.width(); int bottom = height - (rect.top() + rect.height()); - if (device->isFlipped()) { + if (device->paintFlipped()) { bottom = rect.top(); } const int height = rect.height();