remove OpenVG support
Qt5 will require OpenGL, so there's no need for supporting OpenVG anymore.
This commit is contained in:
parent
5c2282ffa3
commit
4ece3fc24e
@ -1,74 +0,0 @@
|
||||
TARGET = QtOpenVG
|
||||
QT += core \
|
||||
gui
|
||||
|
||||
CONFIG += module
|
||||
MODULE_PRI = ../modules/qt_openvg.pri
|
||||
|
||||
DEFINES+=QT_BUILD_OPENVG_LIB
|
||||
|
||||
contains(QT_CONFIG, shivavg) {
|
||||
DEFINES += QVG_NO_DRAW_GLYPHS
|
||||
DEFINES += QVG_NO_RENDER_TO_MASK
|
||||
DEFINES += QVG_SCISSOR_CLIP
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
qvg.h \
|
||||
qvg_p.h \
|
||||
qpaintengine_vg_p.h \
|
||||
qpixmapdata_vg_p.h \
|
||||
qpixmapfilter_vg_p.h \
|
||||
qvgcompositionhelper_p.h \
|
||||
qvgimagepool_p.h \
|
||||
qvgfontglyphcache_p.h
|
||||
SOURCES += \
|
||||
qpaintengine_vg.cpp \
|
||||
qpixmapdata_vg.cpp \
|
||||
qpixmapfilter_vg.cpp \
|
||||
qvgimagepool.cpp
|
||||
|
||||
contains(QT_CONFIG, egl) {
|
||||
HEADERS += \
|
||||
qwindowsurface_vgegl_p.h \
|
||||
qwindowsurface_vg_p.h
|
||||
SOURCES += \
|
||||
qwindowsurface_vg.cpp \
|
||||
qwindowsurface_vgegl.cpp
|
||||
}
|
||||
|
||||
symbian {
|
||||
DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP
|
||||
SOURCES += \
|
||||
qvg_symbian.cpp
|
||||
|
||||
contains(QT_CONFIG, freetype) {
|
||||
DEFINES += QT_NO_FONTCONFIG
|
||||
INCLUDEPATH += \
|
||||
../3rdparty/freetype/src \
|
||||
../3rdparty/freetype/include
|
||||
}
|
||||
}
|
||||
|
||||
include(../qbase.pri)
|
||||
|
||||
unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui
|
||||
symbian:TARGET.UID3 = 0x2001E62F
|
||||
|
||||
!isEmpty(QMAKE_INCDIR_OPENVG): INCLUDEPATH += $$QMAKE_INCDIR_OPENVG
|
||||
!isEmpty(QMAKE_LIBDIR_OPENVG): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENVG
|
||||
!isEmpty(QMAKE_LIBS_OPENVG): LIBS_PRIVATE += $$QMAKE_LIBS_OPENVG
|
||||
|
||||
contains(QT_CONFIG, egl) {
|
||||
!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
|
||||
!isEmpty(QMAKE_LIBDIR_EGL): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_EGL
|
||||
!isEmpty(QMAKE_LIBS_EGL): LIBS_PRIVATE += $$QMAKE_LIBS_EGL
|
||||
}
|
||||
|
||||
contains(QT_CONFIG, openvg_on_opengl) {
|
||||
!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL
|
||||
!isEmpty(QMAKE_LIBDIR_OPENGL): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENGL
|
||||
!isEmpty(QMAKE_LIBS_OPENGL): LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL
|
||||
}
|
||||
|
||||
INCLUDEPATH += ../3rdparty/harfbuzz/src
|
File diff suppressed because it is too large
Load Diff
@ -1,178 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QPAINTENGINE_VG_P_H
|
||||
#define QPAINTENGINE_VG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/private/qpaintengineex_p.h>
|
||||
#include <QtGui/private/qtextureglyphcache_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QFixedPoint;
|
||||
class QVGPaintEnginePrivate;
|
||||
class QPixmapData;
|
||||
class QVGEGLWindowSurfacePrivate;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGPainterState : public QPainterState
|
||||
{
|
||||
public:
|
||||
QVGPainterState(QVGPainterState& other);
|
||||
QVGPainterState();
|
||||
~QVGPainterState();
|
||||
|
||||
bool isNew;
|
||||
QRegion clipRegion;
|
||||
QPaintEngine::DirtyFlags savedDirty;
|
||||
};
|
||||
|
||||
class Q_OPENVG_EXPORT QVGPaintEngine : public QPaintEngineEx
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QVGPaintEngine)
|
||||
public:
|
||||
QVGPaintEngine();
|
||||
~QVGPaintEngine();
|
||||
|
||||
Type type() const { return OpenVG; }
|
||||
|
||||
QPainterState *createState(QPainterState *orig) const;
|
||||
|
||||
bool begin(QPaintDevice *pdev);
|
||||
bool end();
|
||||
|
||||
void draw(const QVectorPath &path);
|
||||
void fill(const QVectorPath &path, const QBrush &brush);
|
||||
void stroke(const QVectorPath &path, const QPen &pen);
|
||||
|
||||
void clip(const QVectorPath &path, Qt::ClipOperation op);
|
||||
void clip(const QRect &rect, Qt::ClipOperation op);
|
||||
void clip(const QRegion ®ion, Qt::ClipOperation op);
|
||||
void clip(const QPainterPath &path, Qt::ClipOperation op);
|
||||
|
||||
void clipEnabledChanged();
|
||||
void penChanged();
|
||||
void brushChanged();
|
||||
void brushOriginChanged();
|
||||
void opacityChanged();
|
||||
void compositionModeChanged();
|
||||
void renderHintsChanged();
|
||||
void transformChanged();
|
||||
|
||||
void fillRect(const QRectF &rect, const QBrush &brush);
|
||||
void fillRect(const QRectF &rect, const QColor &color);
|
||||
|
||||
void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode);
|
||||
|
||||
void drawRects(const QRect *rects, int rectCount);
|
||||
void drawRects(const QRectF *rects, int rectCount);
|
||||
|
||||
void drawLines(const QLine *lines, int lineCount);
|
||||
void drawLines(const QLineF *lines, int lineCount);
|
||||
|
||||
void drawEllipse(const QRectF &r);
|
||||
void drawEllipse(const QRect &r);
|
||||
|
||||
void drawPath(const QPainterPath &path);
|
||||
|
||||
void drawPoints(const QPointF *points, int pointCount);
|
||||
void drawPoints(const QPoint *points, int pointCount);
|
||||
|
||||
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
|
||||
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
|
||||
|
||||
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
|
||||
void drawPixmap(const QPointF &pos, const QPixmap &pm);
|
||||
|
||||
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
|
||||
Qt::ImageConversionFlags flags = Qt::AutoColor);
|
||||
void drawImage(const QPointF &pos, const QImage &image);
|
||||
|
||||
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
|
||||
|
||||
void drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, const QPixmap &pixmap,
|
||||
QFlags<QPainter::PixmapFragmentHint> hints);
|
||||
|
||||
void drawTextItem(const QPointF &p, const QTextItem &textItem);
|
||||
void drawStaticTextItem(QStaticTextItem *staticTextItem);
|
||||
bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
|
||||
QFontEngine *fontEngine, const QPointF &p,
|
||||
const QFixedPoint *positions);
|
||||
|
||||
void setState(QPainterState *s);
|
||||
QVGPainterState *state() { return static_cast<QVGPainterState *>(QPaintEngineEx::state()); }
|
||||
const QVGPainterState *state() const { return static_cast<const QVGPainterState *>(QPaintEngineEx::state()); }
|
||||
|
||||
void beginNativePainting();
|
||||
void endNativePainting();
|
||||
|
||||
QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
|
||||
|
||||
QVGPaintEnginePrivate *vgPrivate() { Q_D(QVGPaintEngine); return d; }
|
||||
|
||||
void fillRegion(const QRegion& region, const QColor& color, const QSize& surfaceSize);
|
||||
|
||||
protected:
|
||||
QVGPaintEngine(QVGPaintEnginePrivate &data);
|
||||
|
||||
private:
|
||||
void restoreState(QPaintEngine::DirtyFlags dirty);
|
||||
void updateScissor();
|
||||
QRegion defaultClipRegion();
|
||||
bool isDefaultClipRegion(const QRegion& region);
|
||||
bool isDefaultClipRect(const QRect& rect);
|
||||
bool clearRect(const QRectF &rect, const QColor &color);
|
||||
bool canVgWritePixels(const QImage &image) const;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,575 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
#include "qpaintengine_vg_p.h"
|
||||
#include <QtGui/private/qdrawhelper_p.h>
|
||||
#if !defined(QT_NO_EGL)
|
||||
#include <QtGui/private/qegl_p.h>
|
||||
#endif
|
||||
#include "qvg_p.h"
|
||||
#include "qvgimagepool_p.h"
|
||||
#include <QBuffer>
|
||||
#include <QImageReader>
|
||||
#include <QtGui/private/qimage_p.h>
|
||||
#include <QtGui/private/qnativeimagehandleprovider_p.h>
|
||||
#include <QtGui/private/qfont_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static int qt_vg_pixmap_serial = 0;
|
||||
|
||||
QVGPixmapData::QVGPixmapData(PixelType type)
|
||||
: QPixmapData(type, OpenVGClass)
|
||||
{
|
||||
Q_ASSERT(type == QPixmapData::PixmapType);
|
||||
vgImage = VG_INVALID_HANDLE;
|
||||
vgImageOpacity = VG_INVALID_HANDLE;
|
||||
cachedOpacity = 1.0f;
|
||||
recreate = true;
|
||||
inImagePool = false;
|
||||
inLRU = false;
|
||||
failedToAlloc = false;
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
nativeImageHandleProvider = 0;
|
||||
nativeImageHandle = 0;
|
||||
#endif
|
||||
#if !defined(QT_NO_EGL)
|
||||
context = 0;
|
||||
qt_vg_register_pixmap(this);
|
||||
#endif
|
||||
updateSerial();
|
||||
}
|
||||
|
||||
QVGPixmapData::~QVGPixmapData()
|
||||
{
|
||||
destroyImageAndContext();
|
||||
#if !defined(QT_NO_EGL)
|
||||
qt_vg_unregister_pixmap(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QVGPixmapData::destroyImages()
|
||||
{
|
||||
if (inImagePool) {
|
||||
QVGImagePool *pool = QVGImagePool::instance();
|
||||
if (vgImage != VG_INVALID_HANDLE)
|
||||
pool->releaseImage(this, vgImage);
|
||||
if (vgImageOpacity != VG_INVALID_HANDLE)
|
||||
pool->releaseImage(this, vgImageOpacity);
|
||||
} else {
|
||||
if (vgImage != VG_INVALID_HANDLE)
|
||||
vgDestroyImage(vgImage);
|
||||
if (vgImageOpacity != VG_INVALID_HANDLE)
|
||||
vgDestroyImage(vgImageOpacity);
|
||||
}
|
||||
vgImage = VG_INVALID_HANDLE;
|
||||
vgImageOpacity = VG_INVALID_HANDLE;
|
||||
inImagePool = false;
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
releaseNativeImageHandle();
|
||||
#endif
|
||||
}
|
||||
|
||||
void QVGPixmapData::destroyImageAndContext()
|
||||
{
|
||||
if (vgImage != VG_INVALID_HANDLE) {
|
||||
// We need to have a context current to destroy the image.
|
||||
#if !defined(QT_NO_EGL)
|
||||
if (!context)
|
||||
context = qt_vg_create_context(0, QInternal::Pixmap);
|
||||
if (context->isCurrent()) {
|
||||
destroyImages();
|
||||
} else {
|
||||
// We don't currently have a widget surface active, but we
|
||||
// need a surface to make the context current. So use the
|
||||
// shared pbuffer surface instead.
|
||||
context->makeCurrent(qt_vg_shared_surface());
|
||||
destroyImages();
|
||||
context->lazyDoneCurrent();
|
||||
}
|
||||
#else
|
||||
destroyImages();
|
||||
#endif
|
||||
} else {
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
releaseNativeImageHandle();
|
||||
#endif
|
||||
}
|
||||
#if !defined(QT_NO_EGL)
|
||||
if (context) {
|
||||
qt_vg_destroy_context(context, QInternal::Pixmap);
|
||||
context = 0;
|
||||
}
|
||||
#endif
|
||||
recreate = true;
|
||||
}
|
||||
|
||||
QPixmapData *QVGPixmapData::createCompatiblePixmapData() const
|
||||
{
|
||||
return new QVGPixmapData(pixelType());
|
||||
}
|
||||
|
||||
bool QVGPixmapData::isValid() const
|
||||
{
|
||||
return (w > 0 && h > 0);
|
||||
}
|
||||
|
||||
void QVGPixmapData::updateSerial()
|
||||
{
|
||||
setSerialNumber(++qt_vg_pixmap_serial);
|
||||
}
|
||||
|
||||
void QVGPixmapData::resize(int wid, int ht)
|
||||
{
|
||||
if (w == wid && h == ht) {
|
||||
updateSerial();
|
||||
return;
|
||||
}
|
||||
|
||||
w = wid;
|
||||
h = ht;
|
||||
d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
|
||||
is_null = (w <= 0 || h <= 0);
|
||||
source = QVolatileImage();
|
||||
recreate = true;
|
||||
|
||||
updateSerial();
|
||||
}
|
||||
|
||||
void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
|
||||
{
|
||||
if (image.isNull())
|
||||
return;
|
||||
|
||||
QImage img = image;
|
||||
createPixmapForImage(img, flags, false);
|
||||
}
|
||||
|
||||
void QVGPixmapData::fromImageReader(QImageReader *imageReader,
|
||||
Qt::ImageConversionFlags flags)
|
||||
{
|
||||
QImage image = imageReader->read();
|
||||
if (image.isNull())
|
||||
return;
|
||||
|
||||
createPixmapForImage(image, flags, true);
|
||||
}
|
||||
|
||||
bool QVGPixmapData::fromFile(const QString &filename, const char *format,
|
||||
Qt::ImageConversionFlags flags)
|
||||
{
|
||||
QImage image = QImageReader(filename, format).read();
|
||||
if (image.isNull())
|
||||
return false;
|
||||
|
||||
createPixmapForImage(image, flags, true);
|
||||
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
|
||||
Qt::ImageConversionFlags flags)
|
||||
{
|
||||
QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
|
||||
QBuffer b(&a);
|
||||
b.open(QIODevice::ReadOnly);
|
||||
QImage image = QImageReader(&b, format).read();
|
||||
if (image.isNull())
|
||||
return false;
|
||||
|
||||
createPixmapForImage(image, flags, true);
|
||||
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
|
||||
{
|
||||
QImage::Format format = sourceFormat();
|
||||
int d = image->depth();
|
||||
if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
|
||||
format = QImage::Format_RGB32;
|
||||
else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
|
||||
format = sourceFormat();
|
||||
else
|
||||
format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
|
||||
return format;
|
||||
}
|
||||
|
||||
void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
|
||||
{
|
||||
resize(image.width(), image.height());
|
||||
|
||||
QImage::Format format = idealFormat(&image, flags);
|
||||
|
||||
if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
|
||||
source = QVolatileImage(image);
|
||||
} else {
|
||||
QImage convertedImage = image.convertToFormat(format);
|
||||
// convertToFormat won't detach the image if format stays the
|
||||
// same. Detaching is needed to prevent issues with painting
|
||||
// onto this QPixmap later on.
|
||||
convertedImage.detach();
|
||||
source = QVolatileImage(convertedImage);
|
||||
}
|
||||
|
||||
recreate = true;
|
||||
}
|
||||
|
||||
void QVGPixmapData::fill(const QColor &color)
|
||||
{
|
||||
if (!isValid())
|
||||
return;
|
||||
forceToImage();
|
||||
if (source.depth() == 1) {
|
||||
// Pick the best approximate color in the image's colortable.
|
||||
int gray = qGray(color.rgba());
|
||||
if (qAbs(qGray(source.imageRef().color(0)) - gray)
|
||||
< qAbs(qGray(source.imageRef().color(1)) - gray))
|
||||
source.fill(0);
|
||||
else
|
||||
source.fill(1);
|
||||
} else {
|
||||
source.fill(PREMUL(color.rgba()));
|
||||
}
|
||||
}
|
||||
|
||||
bool QVGPixmapData::hasAlphaChannel() const
|
||||
{
|
||||
ensureReadback(true);
|
||||
if (!source.isNull())
|
||||
return source.hasAlphaChannel();
|
||||
else
|
||||
return isValid();
|
||||
}
|
||||
|
||||
void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
|
||||
{
|
||||
if (!isValid())
|
||||
return;
|
||||
forceToImage();
|
||||
source.setAlphaChannel(alphaChannel);
|
||||
}
|
||||
|
||||
QImage QVGPixmapData::toImage() const
|
||||
{
|
||||
if (!isValid())
|
||||
return QImage();
|
||||
ensureReadback(true);
|
||||
if (source.isNull()) {
|
||||
source = QVolatileImage(w, h, sourceFormat());
|
||||
recreate = true;
|
||||
}
|
||||
return source.toImage();
|
||||
}
|
||||
|
||||
void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
|
||||
{
|
||||
// toImage() is potentially expensive with QVolatileImage so provide a
|
||||
// more efficient implementation of copy() that does not rely on it.
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (data->classId() != OpenVGClass) {
|
||||
fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
|
||||
return;
|
||||
}
|
||||
const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
|
||||
QRect r = rect;
|
||||
if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
|
||||
r = QRect(0, 0, pd->w, pd->h);
|
||||
}
|
||||
resize(r.width(), r.height());
|
||||
recreate = true;
|
||||
if (!pd->source.isNull()) {
|
||||
source = QVolatileImage(r.width(), r.height(), pd->source.format());
|
||||
source.copyFrom(&pd->source, r);
|
||||
}
|
||||
}
|
||||
|
||||
QImage *QVGPixmapData::buffer()
|
||||
{
|
||||
// Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
|
||||
return 0;
|
||||
}
|
||||
|
||||
QPaintEngine* QVGPixmapData::paintEngine() const
|
||||
{
|
||||
// If the application wants to paint into the QPixmap, we first
|
||||
// force it to QImage format and then paint into that.
|
||||
// This is simpler than juggling multiple VG contexts.
|
||||
const_cast<QVGPixmapData *>(this)->forceToImage();
|
||||
return source.paintEngine();
|
||||
}
|
||||
|
||||
VGImage QVGPixmapData::toVGImage()
|
||||
{
|
||||
if (!isValid() || failedToAlloc)
|
||||
return VG_INVALID_HANDLE;
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
// Increase the reference count on the shared context.
|
||||
if (!context)
|
||||
context = qt_vg_create_context(0, QInternal::Pixmap);
|
||||
#endif
|
||||
|
||||
if (recreate && prevSize != QSize(w, h))
|
||||
destroyImages();
|
||||
else if (recreate)
|
||||
cachedOpacity = -1.0f; // Force opacity image to be refreshed later.
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
if (recreate && nativeImageHandleProvider && !nativeImageHandle) {
|
||||
createFromNativeImageHandleProvider();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgImage == VG_INVALID_HANDLE) {
|
||||
vgImage = QVGImagePool::instance()->createImageForPixmap
|
||||
(qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);
|
||||
|
||||
// Bail out if we run out of GPU memory - try again next time.
|
||||
if (vgImage == VG_INVALID_HANDLE) {
|
||||
failedToAlloc = true;
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
inImagePool = true;
|
||||
} else if (inImagePool) {
|
||||
QVGImagePool::instance()->useImage(this);
|
||||
}
|
||||
|
||||
if (!source.isNull() && recreate) {
|
||||
source.beginDataAccess();
|
||||
vgImageSubData
|
||||
(vgImage,
|
||||
source.constBits(), source.bytesPerLine(),
|
||||
qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
|
||||
source.endDataAccess(true);
|
||||
}
|
||||
|
||||
recreate = false;
|
||||
prevSize = QSize(w, h);
|
||||
|
||||
return vgImage;
|
||||
}
|
||||
|
||||
VGImage QVGPixmapData::toVGImage(qreal opacity)
|
||||
{
|
||||
#if !defined(QT_SHIVAVG)
|
||||
// Force the primary VG image to be recreated if necessary.
|
||||
if (toVGImage() == VG_INVALID_HANDLE)
|
||||
return VG_INVALID_HANDLE;
|
||||
|
||||
if (opacity == 1.0f)
|
||||
return vgImage;
|
||||
|
||||
// Create an alternative image for the selected opacity.
|
||||
if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) {
|
||||
if (vgImageOpacity == VG_INVALID_HANDLE) {
|
||||
if (inImagePool) {
|
||||
vgImageOpacity = QVGImagePool::instance()->createImageForPixmap
|
||||
(VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
|
||||
} else {
|
||||
vgImageOpacity = vgCreateImage
|
||||
(VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
|
||||
}
|
||||
|
||||
// Bail out if we run out of GPU memory - try again next time.
|
||||
if (vgImageOpacity == VG_INVALID_HANDLE)
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
VGfloat matrix[20] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, opacity,
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
vgColorMatrix(vgImageOpacity, vgImage, matrix);
|
||||
cachedOpacity = opacity;
|
||||
}
|
||||
|
||||
return vgImageOpacity;
|
||||
#else
|
||||
// vgColorMatrix() doesn't work with ShivaVG, so ignore the opacity.
|
||||
Q_UNUSED(opacity);
|
||||
return toVGImage();
|
||||
#endif
|
||||
}
|
||||
|
||||
void QVGPixmapData::detachImageFromPool()
|
||||
{
|
||||
if (inImagePool) {
|
||||
QVGImagePool::instance()->detachImage(this);
|
||||
inImagePool = false;
|
||||
}
|
||||
}
|
||||
|
||||
void QVGPixmapData::hibernate()
|
||||
{
|
||||
// If the image was imported (e.g, from an SgImage under Symbian), then
|
||||
// skip the hibernation, there is no sense in copying it back to main
|
||||
// memory because the data is most likely shared between several processes.
|
||||
bool skipHibernate = (vgImage != VG_INVALID_HANDLE && source.isNull());
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
// However we have to proceed normally if the image was retrieved via
|
||||
// a handle provider.
|
||||
skipHibernate &= !nativeImageHandleProvider;
|
||||
#endif
|
||||
if (skipHibernate)
|
||||
return;
|
||||
|
||||
forceToImage(false); // no readback allowed here
|
||||
destroyImageAndContext();
|
||||
}
|
||||
|
||||
void QVGPixmapData::reclaimImages()
|
||||
{
|
||||
if (!inImagePool)
|
||||
return;
|
||||
forceToImage();
|
||||
destroyImages();
|
||||
}
|
||||
|
||||
int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
|
||||
{
|
||||
switch (metric) {
|
||||
case QPaintDevice::PdmWidth:
|
||||
return w;
|
||||
case QPaintDevice::PdmHeight:
|
||||
return h;
|
||||
case QPaintDevice::PdmNumColors:
|
||||
return 0;
|
||||
case QPaintDevice::PdmDepth:
|
||||
return d;
|
||||
case QPaintDevice::PdmWidthMM:
|
||||
return qRound(w * 25.4 / qt_defaultDpiX());
|
||||
case QPaintDevice::PdmHeightMM:
|
||||
return qRound(h * 25.4 / qt_defaultDpiY());
|
||||
case QPaintDevice::PdmDpiX:
|
||||
case QPaintDevice::PdmPhysicalDpiX:
|
||||
return qt_defaultDpiX();
|
||||
case QPaintDevice::PdmDpiY:
|
||||
case QPaintDevice::PdmPhysicalDpiY:
|
||||
return qt_defaultDpiY();
|
||||
default:
|
||||
qWarning("QVGPixmapData::metric(): Invalid metric");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures that the pixmap is backed by some valid data and forces the data to
|
||||
// be re-uploaded to the VGImage when toVGImage() is called next time.
|
||||
void QVGPixmapData::forceToImage(bool allowReadback)
|
||||
{
|
||||
if (!isValid())
|
||||
return;
|
||||
|
||||
if (allowReadback)
|
||||
ensureReadback(false);
|
||||
|
||||
if (source.isNull())
|
||||
source = QVolatileImage(w, h, sourceFormat());
|
||||
|
||||
recreate = true;
|
||||
}
|
||||
|
||||
void QVGPixmapData::ensureReadback(bool readOnly) const
|
||||
{
|
||||
if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
|
||||
source = QVolatileImage(w, h, sourceFormat());
|
||||
source.beginDataAccess();
|
||||
vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
|
||||
qt_vg_image_to_vg_format(source.format()),
|
||||
0, 0, w, h);
|
||||
source.endDataAccess();
|
||||
if (readOnly) {
|
||||
recreate = false;
|
||||
} else {
|
||||
// Once we did a readback, the original VGImage must be destroyed
|
||||
// because it may be shared (e.g. created via SgImage) and a subsequent
|
||||
// upload of the image data may produce unexpected results.
|
||||
const_cast<QVGPixmapData *>(this)->destroyImages();
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
// There is now an own copy of the data so drop the handle provider,
|
||||
// otherwise toVGImage() would request the handle again, which is wrong.
|
||||
nativeImageHandleProvider = 0;
|
||||
#endif
|
||||
recreate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QImage::Format QVGPixmapData::sourceFormat() const
|
||||
{
|
||||
return QImage::Format_ARGB32_Premultiplied;
|
||||
}
|
||||
|
||||
/*
|
||||
\internal
|
||||
|
||||
Returns the VGImage that is storing the contents of \a pixmap.
|
||||
Returns VG_INVALID_HANDLE if \a pixmap is not owned by the OpenVG
|
||||
graphics system or \a pixmap is invalid.
|
||||
|
||||
This function is typically used to access the backing store
|
||||
for a pixmap when executing raw OpenVG calls. It must only
|
||||
be used when a QPainter is active and the OpenVG paint engine
|
||||
is in use by the QPainter.
|
||||
|
||||
\sa {QtOpenVG Module}
|
||||
*/
|
||||
Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap)
|
||||
{
|
||||
QPixmapData *pd = pixmap.pixmapData();
|
||||
if (!pd)
|
||||
return VG_INVALID_HANDLE; // null QPixmap
|
||||
if (pd->classId() == QPixmapData::OpenVGClass) {
|
||||
QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
|
||||
if (vgpd->isValid())
|
||||
return vgpd->toVGImage();
|
||||
}
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,202 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QPIXMAPDATA_VG_P_H
|
||||
#define QPIXMAPDATA_VG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/private/qpixmap_raster_p.h>
|
||||
#include <QtGui/private/qvolatileimage_p.h>
|
||||
#include "qvg_p.h"
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
class RSGImage;
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QEglContext;
|
||||
class QVGImagePool;
|
||||
class QImageReader;
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
class QVGPixmapData;
|
||||
class QVGSharedContext;
|
||||
|
||||
void qt_vg_register_pixmap(QVGPixmapData *pd);
|
||||
void qt_vg_unregister_pixmap(QVGPixmapData *pd);
|
||||
void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
|
||||
#endif
|
||||
|
||||
class QNativeImageHandleProvider;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData
|
||||
{
|
||||
public:
|
||||
QVGPixmapData(PixelType type);
|
||||
~QVGPixmapData();
|
||||
|
||||
QPixmapData *createCompatiblePixmapData() const;
|
||||
|
||||
// Is this pixmap valid (i.e. non-zero in size)?
|
||||
bool isValid() const;
|
||||
|
||||
void resize(int width, int height);
|
||||
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
|
||||
void fromImageReader(QImageReader *imageReader,
|
||||
Qt::ImageConversionFlags flags);
|
||||
bool fromFile(const QString &filename, const char *format,
|
||||
Qt::ImageConversionFlags flags);
|
||||
bool fromData(const uchar *buffer, uint len, const char *format,
|
||||
Qt::ImageConversionFlags flags);
|
||||
|
||||
void fill(const QColor &color);
|
||||
bool hasAlphaChannel() const;
|
||||
void setAlphaChannel(const QPixmap &alphaChannel);
|
||||
QImage toImage() const;
|
||||
void copy(const QPixmapData *data, const QRect &rect);
|
||||
QImage *buffer();
|
||||
QPaintEngine* paintEngine() const;
|
||||
|
||||
// Return the VGImage form of this pixmap, creating it if necessary.
|
||||
// This assumes that there is a VG context current.
|
||||
virtual VGImage toVGImage();
|
||||
|
||||
// Return the VGImage form for a specific opacity setting.
|
||||
virtual VGImage toVGImage(qreal opacity);
|
||||
|
||||
// Detach this image from the image pool.
|
||||
virtual void detachImageFromPool();
|
||||
|
||||
// Release the VG resources associated with this pixmap and copy
|
||||
// the pixmap's contents out of the GPU back into main memory.
|
||||
// The VG resource will be automatically recreated the next time
|
||||
// toVGImage() is called. Does nothing if the pixmap cannot be
|
||||
// hibernated for some reason (e.g. VGImage is shared with another
|
||||
// process via a SgImage).
|
||||
virtual void hibernate();
|
||||
|
||||
// Called when the QVGImagePool wants to reclaim this pixmap's
|
||||
// VGImage objects to reuse storage.
|
||||
virtual void reclaimImages();
|
||||
|
||||
// If vgImage is valid but source is null, copies pixel data from GPU back
|
||||
// into main memory and destroys vgImage. For a normal pixmap this function
|
||||
// does nothing, however if the pixmap was created directly from a VGImage
|
||||
// (e.g. via SgImage on Symbian) then by doing the readback this ensures
|
||||
// that QImage-based functions can operate too.
|
||||
virtual void ensureReadback(bool readOnly) const;
|
||||
|
||||
QSize size() const { return QSize(w, h); }
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
void* toNativeType(NativeType type);
|
||||
void fromNativeType(void* pixmap, NativeType type);
|
||||
bool initFromNativeImageHandle(void *handle, const QString &type);
|
||||
void createFromNativeImageHandleProvider();
|
||||
void releaseNativeImageHandle();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
int metric(QPaintDevice::PaintDeviceMetric metric) const;
|
||||
void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
void cleanup();
|
||||
#endif
|
||||
|
||||
private:
|
||||
QVGPixmapData *nextLRU;
|
||||
QVGPixmapData *prevLRU;
|
||||
bool inLRU;
|
||||
bool failedToAlloc;
|
||||
friend class QVGImagePool;
|
||||
friend class QVGPaintEngine;
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
QVGPixmapData *next;
|
||||
QVGPixmapData *prev;
|
||||
|
||||
friend void qt_vg_register_pixmap(QVGPixmapData *pd);
|
||||
friend void qt_vg_unregister_pixmap(QVGPixmapData *pd);
|
||||
friend void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
QSize prevSize;
|
||||
VGImage vgImage;
|
||||
VGImage vgImageOpacity;
|
||||
qreal cachedOpacity;
|
||||
mutable QVolatileImage source;
|
||||
mutable bool recreate;
|
||||
bool inImagePool;
|
||||
#if !defined(QT_NO_EGL)
|
||||
mutable QEglContext *context;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
mutable QNativeImageHandleProvider *nativeImageHandleProvider;
|
||||
void *nativeImageHandle;
|
||||
QString nativeImageType;
|
||||
#endif
|
||||
|
||||
void forceToImage(bool allowReadback = true);
|
||||
QImage::Format sourceFormat() const;
|
||||
QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const;
|
||||
void updateSerial();
|
||||
|
||||
void destroyImageAndContext();
|
||||
void destroyImages();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,356 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qpixmapfilter_vg_p.h"
|
||||
#include "qvgimagepool_p.h"
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtGui/qpainter.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(QT_SHIVAVG)
|
||||
|
||||
QVGPixmapConvolutionFilter::QVGPixmapConvolutionFilter()
|
||||
: QPixmapConvolutionFilter()
|
||||
{
|
||||
}
|
||||
|
||||
QVGPixmapConvolutionFilter::~QVGPixmapConvolutionFilter()
|
||||
{
|
||||
}
|
||||
|
||||
extern void qt_vg_drawVGImage
|
||||
(QPainter *painter, const QPointF& pos, VGImage vgImg);
|
||||
extern void qt_vg_drawVGImageStencil
|
||||
(QPainter *painter, const QPointF& pos, VGImage vgImg, const QBrush& brush);
|
||||
|
||||
void QVGPixmapConvolutionFilter::draw
|
||||
(QPainter *painter, const QPointF &dest,
|
||||
const QPixmap &src, const QRectF &srcRect) const
|
||||
{
|
||||
if (src.isNull())
|
||||
return;
|
||||
|
||||
if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
|
||||
// The pixmap data is not an instance of QVGPixmapData, so fall
|
||||
// back to the default convolution filter implementation.
|
||||
QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
|
||||
return;
|
||||
}
|
||||
|
||||
QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
|
||||
|
||||
VGImage srcImage = pd->toVGImage();
|
||||
if (srcImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
QSize size = pd->size();
|
||||
VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
|
||||
(VG_sARGB_8888_PRE, size.width(), size.height(),
|
||||
VG_IMAGE_QUALITY_FASTER, pd);
|
||||
if (dstImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
int kernelWidth = rows();
|
||||
int kernelHeight = columns();
|
||||
const qreal *kern = convolutionKernel();
|
||||
QVarLengthArray<VGshort> kernel;
|
||||
for (int i = 0; i < kernelWidth; ++i) {
|
||||
for (int j = 0; j < kernelHeight; ++j) {
|
||||
kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
|
||||
}
|
||||
}
|
||||
|
||||
VGfloat values[4];
|
||||
values[0] = 0.0f;
|
||||
values[1] = 0.0f;
|
||||
values[2] = 0.0f;
|
||||
values[3] = 0.0f;
|
||||
vgSetfv(VG_TILE_FILL_COLOR, 4, values);
|
||||
|
||||
vgConvolve(dstImage, srcImage,
|
||||
kernelWidth, kernelHeight, 0, 0,
|
||||
kernel.constData(), 1.0f / 1024.0f, 0.0f,
|
||||
VG_TILE_FILL);
|
||||
|
||||
VGImage child = VG_INVALID_HANDLE;
|
||||
|
||||
if (srcRect.isNull() ||
|
||||
(srcRect.topLeft().isNull() && srcRect.size() == size)) {
|
||||
child = dstImage;
|
||||
} else {
|
||||
QRect src = srcRect.toRect();
|
||||
child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
|
||||
}
|
||||
|
||||
qt_vg_drawVGImage(painter, dest, child);
|
||||
|
||||
if(child != dstImage)
|
||||
vgDestroyImage(child);
|
||||
QVGImagePool::instance()->releaseImage(0, dstImage);
|
||||
}
|
||||
|
||||
QVGPixmapColorizeFilter::QVGPixmapColorizeFilter()
|
||||
: QPixmapColorizeFilter()
|
||||
{
|
||||
}
|
||||
|
||||
QVGPixmapColorizeFilter::~QVGPixmapColorizeFilter()
|
||||
{
|
||||
}
|
||||
|
||||
void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
|
||||
{
|
||||
if (src.isNull())
|
||||
return;
|
||||
|
||||
if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
|
||||
// The pixmap data is not an instance of QVGPixmapData, so fall
|
||||
// back to the default colorize filter implementation.
|
||||
QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
|
||||
return;
|
||||
}
|
||||
|
||||
QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
|
||||
|
||||
VGImage srcImage = pd->toVGImage();
|
||||
if (srcImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
QSize size = pd->size();
|
||||
VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
|
||||
(VG_sARGB_8888_PRE, size.width(), size.height(),
|
||||
VG_IMAGE_QUALITY_FASTER, pd);
|
||||
if (dstImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
// Determine the weights for the matrix from the color and strength.
|
||||
QColor c = color();
|
||||
VGfloat strength = this->strength();
|
||||
VGfloat weights[3];
|
||||
VGfloat invweights[3];
|
||||
VGfloat alpha = c.alphaF();
|
||||
weights[0] = c.redF() * alpha;
|
||||
weights[1] = c.greenF() * alpha;
|
||||
weights[2] = c.blueF() * alpha;
|
||||
invweights[0] = (1.0f - weights[0]) * strength;
|
||||
invweights[1] = (1.0f - weights[1]) * strength;
|
||||
invweights[2] = (1.0f - weights[2]) * strength;
|
||||
|
||||
// Grayscale weights.
|
||||
static const VGfloat redGray = 11.0f / 32.0f;
|
||||
static const VGfloat greenGray = 16.0f / 32.0f;
|
||||
static const VGfloat blueGray = 1.0f - (redGray + greenGray);
|
||||
|
||||
VGfloat matrix[5][4];
|
||||
matrix[0][0] = redGray * invweights[0] + (1.0f - strength);
|
||||
matrix[0][1] = redGray * invweights[1];
|
||||
matrix[0][2] = redGray * invweights[2];
|
||||
matrix[0][3] = 0.0f;
|
||||
matrix[1][0] = greenGray * invweights[0];
|
||||
matrix[1][1] = greenGray * invweights[1] + (1.0f - strength);
|
||||
matrix[1][2] = greenGray * invweights[2];
|
||||
matrix[1][3] = 0.0f;
|
||||
matrix[2][0] = blueGray * invweights[0];
|
||||
matrix[2][1] = blueGray * invweights[1];
|
||||
matrix[2][2] = blueGray * invweights[2] + (1.0f - strength);
|
||||
matrix[2][3] = 0.0f;
|
||||
matrix[3][0] = 0.0f;
|
||||
matrix[3][1] = 0.0f;
|
||||
matrix[3][2] = 0.0f;
|
||||
matrix[3][3] = 1.0f;
|
||||
matrix[4][0] = weights[0] * strength;
|
||||
matrix[4][1] = weights[1] * strength;
|
||||
matrix[4][2] = weights[2] * strength;
|
||||
matrix[4][3] = 0.0f;
|
||||
|
||||
vgColorMatrix(dstImage, srcImage, matrix[0]);
|
||||
|
||||
VGImage child = VG_INVALID_HANDLE;
|
||||
|
||||
if (srcRect.isNull() ||
|
||||
(srcRect.topLeft().isNull() && srcRect.size() == size)) {
|
||||
child = dstImage;
|
||||
} else {
|
||||
QRect src = srcRect.toRect();
|
||||
child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
|
||||
}
|
||||
|
||||
qt_vg_drawVGImage(painter, dest, child);
|
||||
|
||||
if(child != dstImage)
|
||||
vgDestroyImage(child);
|
||||
QVGImagePool::instance()->releaseImage(0, dstImage);
|
||||
}
|
||||
|
||||
QVGPixmapDropShadowFilter::QVGPixmapDropShadowFilter()
|
||||
: QPixmapDropShadowFilter()
|
||||
{
|
||||
}
|
||||
|
||||
QVGPixmapDropShadowFilter::~QVGPixmapDropShadowFilter()
|
||||
{
|
||||
}
|
||||
|
||||
void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
|
||||
{
|
||||
if (src.isNull())
|
||||
return;
|
||||
|
||||
if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
|
||||
// The pixmap data is not an instance of QVGPixmapData, so fall
|
||||
// back to the default drop shadow filter implementation.
|
||||
QPixmapDropShadowFilter::draw(painter, dest, src, srcRect);
|
||||
return;
|
||||
}
|
||||
|
||||
QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
|
||||
|
||||
VGImage srcImage = pd->toVGImage();
|
||||
if (srcImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
QSize size = pd->size();
|
||||
VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
|
||||
(VG_A_8, size.width(), size.height(),
|
||||
VG_IMAGE_QUALITY_FASTER, pd);
|
||||
if (dstImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
// Clamp the radius range. We divide by 2 because the OpenVG blur
|
||||
// is "too blurry" compared to the default raster implementation.
|
||||
VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
|
||||
VGfloat radiusF = VGfloat(blurRadius()) / 2.0f;
|
||||
if (radiusF < 0.001f)
|
||||
radiusF = 0.001f;
|
||||
else if (radiusF > maxRadius)
|
||||
radiusF = maxRadius;
|
||||
|
||||
// Blur the blackened source image.
|
||||
vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
|
||||
|
||||
VGImage child = VG_INVALID_HANDLE;
|
||||
|
||||
QRect srect;
|
||||
if (srcRect.isNull() ||
|
||||
(srcRect.topLeft().isNull() && srcRect.size() == size)) {
|
||||
child = dstImage;
|
||||
srect = QRect(0, 0, size.width(), size.height());
|
||||
} else {
|
||||
srect = srcRect.toRect();
|
||||
child = vgChildImage(dstImage, srect.x(), srect.y(), srect.width(), srect.height());
|
||||
}
|
||||
|
||||
qt_vg_drawVGImageStencil(painter, dest + offset(), child, color());
|
||||
|
||||
if(child != dstImage)
|
||||
vgDestroyImage(child);
|
||||
QVGImagePool::instance()->releaseImage(0, dstImage);
|
||||
|
||||
// Now draw the actual pixmap over the top.
|
||||
painter->drawPixmap(dest, src, srect);
|
||||
}
|
||||
|
||||
QVGPixmapBlurFilter::QVGPixmapBlurFilter(QObject *parent)
|
||||
: QPixmapBlurFilter(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVGPixmapBlurFilter::~QVGPixmapBlurFilter()
|
||||
{
|
||||
}
|
||||
|
||||
void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
|
||||
{
|
||||
if (src.isNull())
|
||||
return;
|
||||
|
||||
if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
|
||||
// The pixmap data is not an instance of QVGPixmapData, so fall
|
||||
// back to the default blur filter implementation.
|
||||
QPixmapBlurFilter::draw(painter, dest, src, srcRect);
|
||||
return;
|
||||
}
|
||||
|
||||
QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
|
||||
|
||||
VGImage srcImage = pd->toVGImage();
|
||||
if (srcImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
QSize size = pd->size();
|
||||
VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
|
||||
(VG_sARGB_8888_PRE, size.width(), size.height(),
|
||||
VG_IMAGE_QUALITY_FASTER, pd);
|
||||
if (dstImage == VG_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
// Clamp the radius range. We divide by 2 because the OpenVG blur
|
||||
// is "too blurry" compared to the default raster implementation.
|
||||
VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
|
||||
VGfloat radiusF = VGfloat(radius()) / 2.0f;
|
||||
if (radiusF < 0.001f)
|
||||
radiusF = 0.001f;
|
||||
else if (radiusF > maxRadius)
|
||||
radiusF = maxRadius;
|
||||
|
||||
vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
|
||||
|
||||
VGImage child = VG_INVALID_HANDLE;
|
||||
|
||||
if (srcRect.isNull() ||
|
||||
(srcRect.topLeft().isNull() && srcRect.size() == size)) {
|
||||
child = dstImage;
|
||||
} else {
|
||||
QRect src = srcRect.toRect();
|
||||
child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
|
||||
}
|
||||
|
||||
qt_vg_drawVGImage(painter, dest, child);
|
||||
|
||||
if(child != dstImage)
|
||||
vgDestroyImage(child);
|
||||
QVGImagePool::instance()->releaseImage(0, dstImage);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,108 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QPIXMAPFILTER_VG_P_H
|
||||
#define QPIXMAPFILTER_VG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
#include <QtGui/private/qpixmapfilter_p.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(QT_SHIVAVG)
|
||||
|
||||
class QVGPixmapConvolutionFilter : public QPixmapConvolutionFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QVGPixmapConvolutionFilter();
|
||||
~QVGPixmapConvolutionFilter();
|
||||
|
||||
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const;
|
||||
};
|
||||
|
||||
class QVGPixmapColorizeFilter : public QPixmapColorizeFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QVGPixmapColorizeFilter();
|
||||
~QVGPixmapColorizeFilter();
|
||||
|
||||
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const;
|
||||
};
|
||||
|
||||
class QVGPixmapDropShadowFilter : public QPixmapDropShadowFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QVGPixmapDropShadowFilter();
|
||||
~QVGPixmapDropShadowFilter();
|
||||
|
||||
void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src) const;
|
||||
};
|
||||
|
||||
class QVGPixmapBlurFilter : public QPixmapBlurFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QVGPixmapBlurFilter(QObject *parent = 0);
|
||||
~QVGPixmapBlurFilter();
|
||||
|
||||
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,65 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVG_H
|
||||
#define QVG_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
// Include the OpenVG headers for use in applications that
|
||||
// issue raw OpenVG function calls.
|
||||
#if defined(QT_LOWER_CASE_VG_INCLUDES)
|
||||
#include <vg/openvg.h>
|
||||
#else
|
||||
#include <VG/openvg.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(OpenVG)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
@ -1,112 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVG_P_H
|
||||
#define QVG_P_H
|
||||
|
||||
#include "qvg.h"
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
|
||||
#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
|
||||
#define QVG_NO_DRAW_GLYPHS 1
|
||||
#endif
|
||||
|
||||
#include <QtGui/qimage.h>
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
#include <QtGui/private/qeglcontext_p.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QVGPaintEngine;
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
|
||||
class QEglContext;
|
||||
|
||||
// Create an EGL context, but don't bind it to a surface. If single-context
|
||||
// mode is enabled, this will return the previously-created context.
|
||||
// "devType" indicates the type of device using the context, usually
|
||||
// QInternal::Widget or QInternal::Pixmap.
|
||||
Q_OPENVG_EXPORT QEglContext *qt_vg_create_context
|
||||
(QPaintDevice *device, int devType);
|
||||
|
||||
// Destroy an EGL context that was created by qt_vg_create_context().
|
||||
// If single-context mode is enabled, this will decrease the reference count.
|
||||
// "devType" indicates the type of device destroying the context, usually
|
||||
// QInternal::Widget or QInternal::Pixmap.
|
||||
Q_OPENVG_EXPORT void qt_vg_destroy_context
|
||||
(QEglContext *context, int devType);
|
||||
|
||||
// Return the shared pbuffer surface that can be made current to
|
||||
// destroy VGImage objects when there is no other surface available.
|
||||
Q_OPENVG_EXPORT EGLSurface qt_vg_shared_surface(void);
|
||||
|
||||
// Convert the configuration format in a context to a VG or QImage format.
|
||||
Q_OPENVG_EXPORT VGImageFormat qt_vg_config_to_vg_format(QEglContext *context);
|
||||
Q_OPENVG_EXPORT QImage::Format qt_vg_config_to_image_format(QEglContext *context);
|
||||
|
||||
#endif
|
||||
|
||||
// Create a paint engine. Returns the common engine in single-context mode.
|
||||
Q_OPENVG_EXPORT QVGPaintEngine *qt_vg_create_paint_engine(void);
|
||||
|
||||
// Destroy a paint engine. Does nothing in single-context mode.
|
||||
Q_OPENVG_EXPORT void qt_vg_destroy_paint_engine(QVGPaintEngine *engine);
|
||||
|
||||
// Convert between QImage and VGImage format values.
|
||||
Q_OPENVG_EXPORT VGImageFormat qt_vg_image_to_vg_format(QImage::Format format);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,366 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
#include "qvgfontglyphcache_p.h"
|
||||
#include <QtGui/private/qnativeimagehandleprovider_p.h>
|
||||
#include <private/qt_s60_p.h>
|
||||
|
||||
#include <fbs.h>
|
||||
|
||||
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
|
||||
# include <sgresource/sgimage.h>
|
||||
# ifdef SYMBIAN_FBSERV_GLYPHDATA // defined in fbs.h
|
||||
# define QT_SYMBIAN_HARDWARE_GLYPH_CACHE
|
||||
# include <graphics/fbsglyphdataiterator.h>
|
||||
# include <private/qfontengine_s60_p.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
typedef VGImage (*_vgCreateEGLImageTargetKHR)(VGeglImageKHR);
|
||||
static _vgCreateEGLImageTargetKHR qt_vgCreateEGLImageTargetKHR = 0;
|
||||
|
||||
namespace QVG
|
||||
{
|
||||
VGImage vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage);
|
||||
}
|
||||
|
||||
VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
|
||||
{
|
||||
if (!qt_vgCreateEGLImageTargetKHR && QEgl::hasExtension("EGL_KHR_image"))
|
||||
qt_vgCreateEGLImageTargetKHR = (_vgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
|
||||
|
||||
return qt_vgCreateEGLImageTargetKHR ? qt_vgCreateEGLImageTargetKHR(eglImage) : 0;
|
||||
}
|
||||
|
||||
extern int qt_vg_pixmap_serial;
|
||||
|
||||
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
|
||||
static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
|
||||
{
|
||||
// when "0" used as argument then
|
||||
// default display, context are used
|
||||
if (!context)
|
||||
context = qt_vg_create_context(0, QInternal::Pixmap);
|
||||
|
||||
VGImage vgImage = VG_INVALID_HANDLE;
|
||||
|
||||
if (sgImage.IsNull())
|
||||
return vgImage;
|
||||
|
||||
const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
|
||||
EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_PIXMAP_KHR,
|
||||
(EGLClientBuffer)&sgImage,
|
||||
(EGLint*)KEglImageAttribs);
|
||||
|
||||
if (!eglImage)
|
||||
return vgImage;
|
||||
|
||||
vgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
|
||||
|
||||
QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
|
||||
return vgImage;
|
||||
}
|
||||
#endif
|
||||
|
||||
void QVGPixmapData::cleanup()
|
||||
{
|
||||
is_null = w = h = 0;
|
||||
recreate = false;
|
||||
source = QVolatileImage();
|
||||
}
|
||||
|
||||
bool QVGPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
|
||||
{
|
||||
if (type == QLatin1String("RSgImage")) {
|
||||
fromNativeType(handle, QPixmapData::SgImage);
|
||||
return true;
|
||||
} else if (type == QLatin1String("CFbsBitmap")) {
|
||||
fromNativeType(handle, QPixmapData::FbsBitmap);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QVGPixmapData::createFromNativeImageHandleProvider()
|
||||
{
|
||||
void *handle = 0;
|
||||
QString type;
|
||||
nativeImageHandleProvider->get(&handle, &type);
|
||||
if (handle) {
|
||||
if (initFromNativeImageHandle(handle, type)) {
|
||||
nativeImageHandle = handle;
|
||||
nativeImageType = type;
|
||||
} else {
|
||||
qWarning("QVGPixmapData: Unknown native image type '%s'", qPrintable(type));
|
||||
}
|
||||
} else {
|
||||
qWarning("QVGPixmapData: Native handle is null");
|
||||
}
|
||||
}
|
||||
|
||||
void QVGPixmapData::releaseNativeImageHandle()
|
||||
{
|
||||
if (nativeImageHandleProvider && nativeImageHandle) {
|
||||
nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
|
||||
nativeImageHandle = 0;
|
||||
nativeImageType = QString();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool conversionLessFormat(QImage::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case QImage::Format_RGB16: // EColor64K
|
||||
case QImage::Format_RGB32: // EColor16MU
|
||||
case QImage::Format_ARGB32: // EColor16MA
|
||||
case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
|
||||
case QImage::Format_Indexed8: // EGray256, EColor256
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
|
||||
{
|
||||
if (type == QPixmapData::SgImage && pixmap) {
|
||||
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
|
||||
RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
|
||||
destroyImages();
|
||||
prevSize = QSize();
|
||||
|
||||
vgImage = sgImageToVGImage(context, *sgImage);
|
||||
if (vgImage != VG_INVALID_HANDLE) {
|
||||
w = vgGetParameteri(vgImage, VG_IMAGE_WIDTH);
|
||||
h = vgGetParameteri(vgImage, VG_IMAGE_HEIGHT);
|
||||
d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
|
||||
}
|
||||
|
||||
is_null = (w <= 0 || h <= 0);
|
||||
source = QVolatileImage(); // readback will be done later, only when needed
|
||||
recreate = false;
|
||||
prevSize = QSize(w, h);
|
||||
updateSerial();
|
||||
#endif
|
||||
} else if (type == QPixmapData::FbsBitmap && pixmap) {
|
||||
CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
|
||||
QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
|
||||
resize(size.width(), size.height());
|
||||
source = QVolatileImage(bitmap); // duplicates only, if possible
|
||||
if (source.isNull())
|
||||
return;
|
||||
if (!conversionLessFormat(source.format())) {
|
||||
// Here we may need to copy if the formats do not match.
|
||||
// (e.g. for display modes other than EColor16MAP and EColor16MU)
|
||||
source.beginDataAccess();
|
||||
QImage::Format format = idealFormat(&source.imageRef(), Qt::AutoColor);
|
||||
source.endDataAccess(true);
|
||||
source.ensureFormat(format);
|
||||
}
|
||||
recreate = true;
|
||||
} else if (type == QPixmapData::VolatileImage && pixmap) {
|
||||
QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
|
||||
resize(img->width(), img->height());
|
||||
source = *img;
|
||||
recreate = true;
|
||||
} else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
|
||||
destroyImages();
|
||||
nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
|
||||
// Cannot defer the retrieval, we need at least the size right away.
|
||||
createFromNativeImageHandleProvider();
|
||||
}
|
||||
}
|
||||
|
||||
void* QVGPixmapData::toNativeType(NativeType type)
|
||||
{
|
||||
if (type == QPixmapData::SgImage) {
|
||||
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
|
||||
toVGImage();
|
||||
|
||||
if (!isValid() || vgImage == VG_INVALID_HANDLE)
|
||||
return 0;
|
||||
|
||||
TInt err = 0;
|
||||
|
||||
RSgDriver driver;
|
||||
err = driver.Open();
|
||||
if (err != KErrNone)
|
||||
return 0;
|
||||
|
||||
TSgImageInfo sgInfo;
|
||||
sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
|
||||
sgInfo.iSizeInPixels.SetSize(w, h);
|
||||
sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
|
||||
|
||||
QScopedPointer<RSgImage> sgImage(new RSgImage());
|
||||
err = sgImage->Create(sgInfo, NULL, NULL);
|
||||
if (err != KErrNone) {
|
||||
driver.Close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
|
||||
EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_PIXMAP_KHR,
|
||||
(EGLClientBuffer)sgImage.data(),
|
||||
(EGLint*)KEglImageAttribs);
|
||||
if (!eglImage || eglGetError() != EGL_SUCCESS) {
|
||||
sgImage->Close();
|
||||
driver.Close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
|
||||
if (!dstVgImage || vgGetError() != VG_NO_ERROR) {
|
||||
QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
|
||||
sgImage->Close();
|
||||
driver.Close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgCopyImage(dstVgImage, 0, 0,
|
||||
vgImage, 0, 0,
|
||||
w, h, VG_FALSE);
|
||||
|
||||
if (vgGetError() != VG_NO_ERROR) {
|
||||
sgImage->Close();
|
||||
sgImage.reset();
|
||||
}
|
||||
|
||||
// release stuff
|
||||
vgDestroyImage(dstVgImage);
|
||||
QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
|
||||
driver.Close();
|
||||
return reinterpret_cast<void*>(sgImage.take());
|
||||
#endif
|
||||
} else if (type == QPixmapData::FbsBitmap && isValid()) {
|
||||
ensureReadback(true);
|
||||
if (source.isNull()) {
|
||||
source = QVolatileImage(w, h, sourceFormat());
|
||||
}
|
||||
// Just duplicate the bitmap handle, no data copying happens.
|
||||
return source.duplicateNativeImage();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QSymbianVGFontGlyphCache::QSymbianVGFontGlyphCache() : QVGFontGlyphCache()
|
||||
{
|
||||
#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
|
||||
invertedGlyphs = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSymbianVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
|
||||
QFontEngine *fontEngine,
|
||||
const glyph_t *g, int count)
|
||||
{
|
||||
#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
|
||||
QFontEngineS60 *s60fontEngine = static_cast<QFontEngineS60*>(fontEngine);
|
||||
if (s60fontEngine->m_activeFont->TypeUid() != KCFbsFontUid)
|
||||
return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
|
||||
|
||||
QVector<glyph_t> uncachedGlyphs;
|
||||
while (count-- > 0) {
|
||||
// Skip this glyph if we have already cached it before.
|
||||
glyph_t glyph = *g++;
|
||||
if (((glyph < 256) && ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0))
|
||||
|| cachedGlyphs.contains(glyph))
|
||||
continue;
|
||||
if (!uncachedGlyphs.contains(glyph))
|
||||
uncachedGlyphs.append(glyph);
|
||||
}
|
||||
|
||||
if (!uncachedGlyphs.isEmpty()) {
|
||||
CFbsFont *cfbsFont = static_cast<CFbsFont *>(s60fontEngine->m_activeFont);
|
||||
RFbsGlyphDataIterator iter;
|
||||
|
||||
int err = iter.Open(*cfbsFont, (const unsigned int*)uncachedGlyphs.constData(), uncachedGlyphs.count());
|
||||
|
||||
if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases
|
||||
iter.Close();
|
||||
qWarning("Falling back to default QVGFontGlyphCache");
|
||||
return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
|
||||
}
|
||||
|
||||
for (; err == KErrNone; err = iter.Next()) {
|
||||
const unsigned int glyph = iter.GlyphCode();
|
||||
|
||||
const RSgImage& image = iter.Image();
|
||||
const TOpenFontCharMetrics& metrics = iter.Metrics();
|
||||
|
||||
TRect glyphBounds;
|
||||
metrics.GetHorizBounds(glyphBounds);
|
||||
VGImage vgImage = sgImageToVGImage(0, image);
|
||||
VGfloat origin[2];
|
||||
VGfloat escapement[2];
|
||||
origin[0] = -glyphBounds.iTl.iX;
|
||||
origin[1] = glyphBounds.iBr.iY;
|
||||
escapement[0] = 0;
|
||||
escapement[1] = 0;
|
||||
vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
|
||||
vgDestroyImage(vgImage);
|
||||
|
||||
// Add to cache
|
||||
if (glyph < 256)
|
||||
cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32));
|
||||
else
|
||||
cachedGlyphs.insert(glyph);
|
||||
}
|
||||
iter.Close();
|
||||
|
||||
if (err == KErrNoMemory || err == KErrNoGraphicsMemory)
|
||||
qWarning("Not enough memory to cache glyph");
|
||||
else if (err != KErrNotFound)
|
||||
qWarning("Received error %d from glyph cache", err);
|
||||
}
|
||||
#else
|
||||
QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,90 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVGCOMPOSITIONHELPER_H
|
||||
#define QVGCOMPOSITIONHELPER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qwindowsurface_vgegl_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL)
|
||||
|
||||
class QVGPaintEnginePrivate;
|
||||
class QVGEGLWindowSurfacePrivate;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGCompositionHelper
|
||||
{
|
||||
public:
|
||||
QVGCompositionHelper();
|
||||
virtual ~QVGCompositionHelper();
|
||||
|
||||
void startCompositing(const QSize& screenSize);
|
||||
void endCompositing();
|
||||
|
||||
void blitWindow(VGImage image, const QSize& imageSize,
|
||||
const QRect& rect, const QPoint& topLeft, int opacity);
|
||||
void fillBackground(const QRegion& region, const QBrush& brush);
|
||||
void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset);
|
||||
void setScissor(const QRegion& region);
|
||||
void clearScissor();
|
||||
|
||||
private:
|
||||
QVGPaintEnginePrivate *d;
|
||||
QSize screenSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,101 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVGFONTGLYPHCACHE_H
|
||||
#define QVGFONTGLYPHCACHE_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtGui/private/qfontengine_p.h>
|
||||
|
||||
#include "qvg_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QVGPaintEnginePrivate;
|
||||
|
||||
#ifndef QVG_NO_DRAW_GLYPHS
|
||||
|
||||
class QVGFontGlyphCache
|
||||
{
|
||||
public:
|
||||
QVGFontGlyphCache();
|
||||
virtual ~QVGFontGlyphCache();
|
||||
|
||||
virtual void cacheGlyphs(QVGPaintEnginePrivate *d,
|
||||
QFontEngine *fontEngine,
|
||||
const glyph_t *g, int count);
|
||||
void setScaleFromText(const QFont &font, QFontEngine *fontEngine);
|
||||
|
||||
VGFont font;
|
||||
VGfloat scaleX;
|
||||
VGfloat scaleY;
|
||||
bool invertedGlyphs;
|
||||
uint cachedGlyphsMask[256 / 32];
|
||||
QSet<glyph_t> cachedGlyphs;
|
||||
};
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
class QSymbianVGFontGlyphCache : public QVGFontGlyphCache
|
||||
{
|
||||
public:
|
||||
QSymbianVGFontGlyphCache();
|
||||
void cacheGlyphs(QVGPaintEnginePrivate *d,
|
||||
QFontEngine *fontEngine,
|
||||
const glyph_t *g, int count);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QVGFONTGLYPHCACHE_H
|
@ -1,233 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qvgimagepool_p.h"
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QVGImagePool *qt_vg_image_pool = 0;
|
||||
|
||||
class QVGImagePoolPrivate
|
||||
{
|
||||
public:
|
||||
QVGImagePoolPrivate() : lruFirst(0), lruLast(0) {}
|
||||
|
||||
QVGPixmapData *lruFirst;
|
||||
QVGPixmapData *lruLast;
|
||||
};
|
||||
|
||||
QVGImagePool::QVGImagePool()
|
||||
: d_ptr(new QVGImagePoolPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
QVGImagePool::~QVGImagePool()
|
||||
{
|
||||
}
|
||||
|
||||
QVGImagePool *QVGImagePool::instance()
|
||||
{
|
||||
if (!qt_vg_image_pool)
|
||||
qt_vg_image_pool = new QVGImagePool();
|
||||
return qt_vg_image_pool;
|
||||
}
|
||||
|
||||
void QVGImagePool::setImagePool(QVGImagePool *pool)
|
||||
{
|
||||
if (qt_vg_image_pool != pool)
|
||||
delete qt_vg_image_pool;
|
||||
qt_vg_image_pool = pool;
|
||||
}
|
||||
|
||||
VGImage QVGImagePool::createTemporaryImage(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality,
|
||||
QVGPixmapData *keepData)
|
||||
{
|
||||
VGImage image;
|
||||
do {
|
||||
image = vgCreateImage(format, width, height, allowedQuality);
|
||||
if (image != VG_INVALID_HANDLE)
|
||||
return image;
|
||||
} while (reclaimSpace(format, width, height, keepData));
|
||||
qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d temporary image",
|
||||
width, height);
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
VGImage QVGImagePool::createImageForPixmap(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality,
|
||||
QVGPixmapData *data)
|
||||
{
|
||||
VGImage image;
|
||||
do {
|
||||
image = vgCreateImage(format, width, height, allowedQuality);
|
||||
if (image != VG_INVALID_HANDLE) {
|
||||
if (data)
|
||||
moveToHeadOfLRU(data);
|
||||
return image;
|
||||
}
|
||||
} while (reclaimSpace(format, width, height, data));
|
||||
qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d pixmap",
|
||||
width, height);
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
VGImage QVGImagePool::createPermanentImage(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality)
|
||||
{
|
||||
VGImage image;
|
||||
do {
|
||||
image = vgCreateImage(format, width, height, allowedQuality);
|
||||
if (image != VG_INVALID_HANDLE)
|
||||
return image;
|
||||
} while (reclaimSpace(format, width, height, 0));
|
||||
qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d image",
|
||||
width, height);
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
void QVGImagePool::releaseImage(QVGPixmapData *data, VGImage image)
|
||||
{
|
||||
// Very simple strategy at the moment: just destroy the image.
|
||||
if (data)
|
||||
removeFromLRU(data);
|
||||
vgDestroyImage(image);
|
||||
}
|
||||
|
||||
void QVGImagePool::useImage(QVGPixmapData *data)
|
||||
{
|
||||
moveToHeadOfLRU(data);
|
||||
}
|
||||
|
||||
void QVGImagePool::detachImage(QVGPixmapData *data)
|
||||
{
|
||||
removeFromLRU(data);
|
||||
}
|
||||
|
||||
bool QVGImagePool::reclaimSpace(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
QVGPixmapData *data)
|
||||
{
|
||||
Q_UNUSED(format); // For future use in picking the best image to eject.
|
||||
Q_UNUSED(width);
|
||||
Q_UNUSED(height);
|
||||
|
||||
bool succeeded = false;
|
||||
bool wasInLRU = false;
|
||||
if (data) {
|
||||
wasInLRU = data->inLRU;
|
||||
moveToHeadOfLRU(data);
|
||||
}
|
||||
|
||||
QVGPixmapData *lrudata = pixmapLRU();
|
||||
if (lrudata && lrudata != data) {
|
||||
lrudata->reclaimImages();
|
||||
succeeded = true;
|
||||
}
|
||||
|
||||
if (data && !wasInLRU)
|
||||
removeFromLRU(data);
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
void QVGImagePool::hibernate()
|
||||
{
|
||||
Q_D(QVGImagePool);
|
||||
QVGPixmapData *pd = d->lruLast;
|
||||
while (pd) {
|
||||
QVGPixmapData *prevLRU = pd->prevLRU;
|
||||
pd->inImagePool = false;
|
||||
pd->inLRU = false;
|
||||
pd->nextLRU = 0;
|
||||
pd->prevLRU = 0;
|
||||
pd->hibernate();
|
||||
pd = prevLRU;
|
||||
}
|
||||
d->lruFirst = 0;
|
||||
d->lruLast = 0;
|
||||
}
|
||||
|
||||
void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
|
||||
{
|
||||
Q_D(QVGImagePool);
|
||||
if (data->inLRU) {
|
||||
if (!data->prevLRU)
|
||||
return; // Already at the head of the list.
|
||||
removeFromLRU(data);
|
||||
}
|
||||
data->inLRU = true;
|
||||
data->nextLRU = d->lruFirst;
|
||||
data->prevLRU = 0;
|
||||
if (d->lruFirst)
|
||||
d->lruFirst->prevLRU = data;
|
||||
else
|
||||
d->lruLast = data;
|
||||
d->lruFirst = data;
|
||||
}
|
||||
|
||||
void QVGImagePool::removeFromLRU(QVGPixmapData *data)
|
||||
{
|
||||
Q_D(QVGImagePool);
|
||||
if (!data->inLRU)
|
||||
return;
|
||||
if (data->nextLRU)
|
||||
data->nextLRU->prevLRU = data->prevLRU;
|
||||
else
|
||||
d->lruLast = data->prevLRU;
|
||||
if (data->prevLRU)
|
||||
data->prevLRU->nextLRU = data->nextLRU;
|
||||
else
|
||||
d->lruFirst = data->nextLRU;
|
||||
data->inLRU = false;
|
||||
}
|
||||
|
||||
QVGPixmapData *QVGImagePool::pixmapLRU()
|
||||
{
|
||||
Q_D(QVGImagePool);
|
||||
return d->lruLast;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,157 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVGIMAGEPOOL_P_H
|
||||
#define QVGIMAGEPOOL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qvg.h"
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QVGPixmapData;
|
||||
class QVGImagePoolPrivate;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGImagePool
|
||||
{
|
||||
public:
|
||||
QVGImagePool();
|
||||
virtual ~QVGImagePool();
|
||||
|
||||
static QVGImagePool *instance();
|
||||
|
||||
// This function can be used from system-specific graphics system
|
||||
// plugins to alter the image allocation strategy.
|
||||
static void setImagePool(QVGImagePool *pool);
|
||||
|
||||
// Create a new VGImage from the pool with the specified parameters
|
||||
// that is not associated with a pixmap. The VGImage is returned to
|
||||
// the pool when releaseImage() is called.
|
||||
//
|
||||
// This function will call reclaimSpace() when vgCreateImage() fails.
|
||||
//
|
||||
// This function is typically called when allocating temporary
|
||||
// VGImage's for pixmap filters. The "keepData" object will not
|
||||
// be reclaimed if reclaimSpace() needs to be called.
|
||||
virtual VGImage createTemporaryImage(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality,
|
||||
QVGPixmapData *keepData = 0);
|
||||
|
||||
// Create a new VGImage with the specified parameters and associate
|
||||
// it with "data". The QVGPixmapData will be notified when the
|
||||
// VGImage needs to be reclaimed by the pool.
|
||||
//
|
||||
// This function will call reclaimSpace() when vgCreateImage() fails.
|
||||
virtual VGImage createImageForPixmap(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality,
|
||||
QVGPixmapData *data);
|
||||
|
||||
// Create a permanent VGImage with the specified parameters.
|
||||
// If there is insufficient space for the vgCreateImage call,
|
||||
// then this function will call reclaimSpace() and try again.
|
||||
//
|
||||
// The caller is responsible for calling vgDestroyImage()
|
||||
// when it no longer needs the VGImage, as the image is not
|
||||
// recorded in the image pool.
|
||||
//
|
||||
// This function is typically used for pattern brushes where
|
||||
// the OpenVG engine is responsible for managing the lifetime
|
||||
// of the VGImage, destroying it automatically when the brush
|
||||
// is no longer in use.
|
||||
virtual VGImage createPermanentImage(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
VGbitfield allowedQuality);
|
||||
|
||||
// Release a VGImage that is no longer required.
|
||||
virtual void releaseImage(QVGPixmapData *data, VGImage image);
|
||||
|
||||
// Notify the pool that a QVGPixmapData object is using
|
||||
// an image again. This allows the pool to move the image
|
||||
// within a least-recently-used list of QVGPixmapData objects.
|
||||
virtual void useImage(QVGPixmapData *data);
|
||||
|
||||
// Notify the pool that the VGImage's associated with a
|
||||
// QVGPixmapData are being detached from the pool. The caller
|
||||
// will become responsible for calling vgDestroyImage().
|
||||
virtual void detachImage(QVGPixmapData *data);
|
||||
|
||||
// Reclaim space for an image allocation with the specified parameters.
|
||||
// Returns true if space was reclaimed, or false if there is no
|
||||
// further space that can be reclaimed. The "data" parameter
|
||||
// indicates the pixmap that is trying to obtain space which should
|
||||
// not itself be reclaimed.
|
||||
virtual bool reclaimSpace(VGImageFormat format,
|
||||
VGint width, VGint height,
|
||||
QVGPixmapData *data);
|
||||
|
||||
// Hibernate the image pool because the context is about to be
|
||||
// destroyed. All VGImage's left in the pool should be released.
|
||||
virtual void hibernate();
|
||||
|
||||
protected:
|
||||
// Helper functions for managing the LRU list of QVGPixmapData objects.
|
||||
void moveToHeadOfLRU(QVGPixmapData *data);
|
||||
void removeFromLRU(QVGPixmapData *data);
|
||||
QVGPixmapData *pixmapLRU();
|
||||
|
||||
private:
|
||||
QScopedPointer<QVGImagePoolPrivate> d_ptr;
|
||||
|
||||
Q_DECLARE_PRIVATE(QVGImagePool)
|
||||
Q_DISABLE_COPY(QVGImagePool)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,137 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwindowsurface_vg_p.h"
|
||||
#include "qwindowsurface_vgegl_p.h"
|
||||
#include "qpaintengine_vg_p.h"
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
#include "qvg_p.h"
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
|
||||
#include <QtGui/private/qeglcontext_p.h>
|
||||
#include <QtGui/private/qwidget_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QVGWindowSurface::QVGWindowSurface(QWidget *window)
|
||||
: QWindowSurface(window)
|
||||
{
|
||||
// Create the default type of EGL window surface for windows.
|
||||
d_ptr = new QVGEGLWindowSurfaceDirect(this);
|
||||
}
|
||||
|
||||
QVGWindowSurface::QVGWindowSurface
|
||||
(QWidget *window, QVGEGLWindowSurfacePrivate *d)
|
||||
: QWindowSurface(window), d_ptr(d)
|
||||
{
|
||||
}
|
||||
|
||||
QVGWindowSurface::~QVGWindowSurface()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
QPaintDevice *QVGWindowSurface::paintDevice()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
Q_UNUSED(offset);
|
||||
QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
|
||||
d_ptr->endPaint(parent, region);
|
||||
}
|
||||
|
||||
void QVGWindowSurface::setGeometry(const QRect &rect)
|
||||
{
|
||||
QWindowSurface::setGeometry(rect);
|
||||
}
|
||||
|
||||
bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy)
|
||||
{
|
||||
if (!d_ptr->scroll(window(), area, dx, dy))
|
||||
return QWindowSurface::scroll(area, dx, dy);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QVGWindowSurface::beginPaint(const QRegion ®ion)
|
||||
{
|
||||
d_ptr->beginPaint(window());
|
||||
|
||||
// If the window is not opaque, then fill the region we are about
|
||||
// to paint with the transparent color.
|
||||
if (!qt_widget_private(window())->isOpaque &&
|
||||
window()->testAttribute(Qt::WA_TranslucentBackground)) {
|
||||
QVGPaintEngine *engine = static_cast<QVGPaintEngine *>
|
||||
(d_ptr->paintEngine());
|
||||
engine->fillRegion(region, Qt::transparent, d_ptr->surfaceSize());
|
||||
}
|
||||
}
|
||||
|
||||
void QVGWindowSurface::endPaint(const QRegion ®ion)
|
||||
{
|
||||
// Nothing to do here.
|
||||
Q_UNUSED(region);
|
||||
}
|
||||
|
||||
QPaintEngine *QVGWindowSurface::paintEngine() const
|
||||
{
|
||||
return d_ptr->paintEngine();
|
||||
}
|
||||
|
||||
QWindowSurface::WindowSurfaceFeatures QVGWindowSurface::features() const
|
||||
{
|
||||
WindowSurfaceFeatures features = PartialUpdates | PreservedContents;
|
||||
if (d_ptr->supportsStaticContents())
|
||||
features |= StaticContents;
|
||||
return features;
|
||||
}
|
||||
|
||||
int QVGWindowSurface::metric(PaintDeviceMetric met) const
|
||||
{
|
||||
return qt_paint_device_metric(window(), met);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,94 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWINDOWSURFACE_VG_P_H
|
||||
#define QWINDOWSURFACE_VG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/private/qwindowsurface_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
|
||||
class QVGEGLWindowSurfacePrivate;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGWindowSurface : public QWindowSurface, public QPaintDevice
|
||||
{
|
||||
public:
|
||||
QVGWindowSurface(QWidget *window);
|
||||
QVGWindowSurface(QWidget *window, QVGEGLWindowSurfacePrivate *d);
|
||||
~QVGWindowSurface();
|
||||
|
||||
QPaintDevice *paintDevice();
|
||||
void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset);
|
||||
void setGeometry(const QRect &rect);
|
||||
bool scroll(const QRegion &area, int dx, int dy);
|
||||
|
||||
void beginPaint(const QRegion ®ion);
|
||||
void endPaint(const QRegion ®ion);
|
||||
|
||||
QPaintEngine *paintEngine() const;
|
||||
|
||||
WindowSurfaceFeatures features() const;
|
||||
|
||||
protected:
|
||||
int metric(PaintDeviceMetric metric) const;
|
||||
|
||||
private:
|
||||
QVGEGLWindowSurfacePrivate *d_ptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWINDOWSURFACE_VG_P_H
|
@ -1,782 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwindowsurface_vgegl_p.h"
|
||||
#include "qpaintengine_vg_p.h"
|
||||
#include "qpixmapdata_vg_p.h"
|
||||
#include "qvgimagepool_p.h"
|
||||
#include "qvg_p.h"
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Turn off "direct to window" rendering if EGL cannot support it.
|
||||
#if !defined(EGL_RENDER_BUFFER) || !defined(EGL_SINGLE_BUFFER)
|
||||
#if defined(QVG_DIRECT_TO_WINDOW)
|
||||
#undef QVG_DIRECT_TO_WINDOW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Determine if preserved window contents should be used.
|
||||
#if !defined(EGL_SWAP_BEHAVIOR) || !defined(EGL_BUFFER_PRESERVED)
|
||||
#if !defined(QVG_NO_PRESERVED_SWAP)
|
||||
#define QVG_NO_PRESERVED_SWAP 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
VGImageFormat qt_vg_config_to_vg_format(QEglContext *context)
|
||||
{
|
||||
return qt_vg_image_to_vg_format
|
||||
(qt_vg_config_to_image_format(context));
|
||||
}
|
||||
|
||||
QImage::Format qt_vg_config_to_image_format(QEglContext *context)
|
||||
{
|
||||
EGLint red = context->configAttrib(EGL_RED_SIZE);
|
||||
EGLint green = context->configAttrib(EGL_GREEN_SIZE);
|
||||
EGLint blue = context->configAttrib(EGL_BLUE_SIZE);
|
||||
EGLint alpha = context->configAttrib(EGL_ALPHA_SIZE);
|
||||
QImage::Format argbFormat;
|
||||
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
|
||||
EGLint type = context->configAttrib(EGL_SURFACE_TYPE);
|
||||
if ((type & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
|
||||
argbFormat = QImage::Format_ARGB32_Premultiplied;
|
||||
else
|
||||
argbFormat = QImage::Format_ARGB32;
|
||||
#else
|
||||
argbFormat = QImage::Format_ARGB32;
|
||||
#endif
|
||||
if (red == 8 && green == 8 && blue == 8 && alpha == 8)
|
||||
return argbFormat;
|
||||
else if (red == 8 && green == 8 && blue == 8 && alpha == 0)
|
||||
return QImage::Format_RGB32;
|
||||
else if (red == 5 && green == 6 && blue == 5 && alpha == 0)
|
||||
return QImage::Format_RGB16;
|
||||
else if (red == 4 && green == 4 && blue == 4 && alpha == 4)
|
||||
return QImage::Format_ARGB4444_Premultiplied;
|
||||
else
|
||||
return argbFormat; // XXX
|
||||
}
|
||||
|
||||
#if !defined(QVG_NO_SINGLE_CONTEXT)
|
||||
|
||||
class QVGSharedContext
|
||||
{
|
||||
public:
|
||||
QVGSharedContext();
|
||||
~QVGSharedContext();
|
||||
|
||||
QEglContext *context;
|
||||
int refCount;
|
||||
int widgetRefCount;
|
||||
QVGPaintEngine *engine;
|
||||
EGLSurface surface;
|
||||
QVGPixmapData *firstPixmap;
|
||||
};
|
||||
|
||||
QVGSharedContext::QVGSharedContext()
|
||||
: context(0)
|
||||
, refCount(0)
|
||||
, widgetRefCount(0)
|
||||
, engine(0)
|
||||
, surface(EGL_NO_SURFACE)
|
||||
, firstPixmap(0)
|
||||
{
|
||||
}
|
||||
|
||||
QVGSharedContext::~QVGSharedContext()
|
||||
{
|
||||
// Don't accidentally destroy the QEglContext if the reference
|
||||
// count falls to zero while deleting the paint engine.
|
||||
++refCount;
|
||||
|
||||
if (context)
|
||||
context->makeCurrent(qt_vg_shared_surface());
|
||||
delete engine;
|
||||
if (context)
|
||||
context->doneCurrent();
|
||||
if (context && surface != EGL_NO_SURFACE)
|
||||
context->destroySurface(surface);
|
||||
delete context;
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QVGSharedContext, sharedContext);
|
||||
|
||||
QVGPaintEngine *qt_vg_create_paint_engine(void)
|
||||
{
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
if (!shared->engine)
|
||||
shared->engine = new QVGPaintEngine();
|
||||
return shared->engine;
|
||||
}
|
||||
|
||||
void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine);
|
||||
}
|
||||
|
||||
void qt_vg_register_pixmap(QVGPixmapData *pd)
|
||||
{
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
pd->next = shared->firstPixmap;
|
||||
pd->prev = 0;
|
||||
if (shared->firstPixmap)
|
||||
shared->firstPixmap->prev = pd;
|
||||
shared->firstPixmap = pd;
|
||||
}
|
||||
|
||||
void qt_vg_unregister_pixmap(QVGPixmapData *pd)
|
||||
{
|
||||
if (pd->next)
|
||||
pd->next->prev = pd->prev;
|
||||
if (pd->prev) {
|
||||
pd->prev->next = pd->next;
|
||||
} else {
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
if (shared)
|
||||
shared->firstPixmap = pd->next;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
QVGPaintEngine *qt_vg_create_paint_engine(void)
|
||||
{
|
||||
return new QVGPaintEngine();
|
||||
}
|
||||
|
||||
void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
|
||||
{
|
||||
delete engine;
|
||||
}
|
||||
|
||||
void qt_vg_register_pixmap(QVGPixmapData *pd)
|
||||
{
|
||||
Q_UNUSED(pd);
|
||||
}
|
||||
|
||||
void qt_vg_unregister_pixmap(QVGPixmapData *pd)
|
||||
{
|
||||
Q_UNUSED(pd);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
|
||||
|
||||
static bool isPremultipliedContext(const QEglContext *context)
|
||||
{
|
||||
return context->configAttrib(EGL_SURFACE_TYPE) & EGL_VG_ALPHA_FORMAT_PRE_BIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static QEglContext *createContext(QPaintDevice *device)
|
||||
{
|
||||
QEglContext *context;
|
||||
|
||||
// Create the context object and open the display.
|
||||
context = new QEglContext();
|
||||
context->setApi(QEgl::OpenVG);
|
||||
|
||||
// Set the swap interval for the display.
|
||||
QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL");
|
||||
if (!interval.isEmpty())
|
||||
eglSwapInterval(QEgl::display(), interval.toInt());
|
||||
else
|
||||
eglSwapInterval(QEgl::display(), 1);
|
||||
|
||||
#ifdef EGL_RENDERABLE_TYPE
|
||||
// Has the user specified an explicit EGL configuration to use?
|
||||
QByteArray configId = qgetenv("QT_VG_EGL_CONFIG");
|
||||
if (!configId.isEmpty()) {
|
||||
EGLint cfgId = configId.toInt();
|
||||
EGLint properties[] = {
|
||||
EGL_CONFIG_ID, cfgId,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint matching = 0;
|
||||
EGLConfig cfg;
|
||||
if (eglChooseConfig
|
||||
(QEgl::display(), properties, &cfg, 1, &matching) &&
|
||||
matching > 0) {
|
||||
// Check that the selected configuration actually supports OpenVG
|
||||
// and then create the context with it.
|
||||
EGLint id = 0;
|
||||
EGLint type = 0;
|
||||
eglGetConfigAttrib
|
||||
(QEgl::display(), cfg, EGL_CONFIG_ID, &id);
|
||||
eglGetConfigAttrib
|
||||
(QEgl::display(), cfg, EGL_RENDERABLE_TYPE, &type);
|
||||
if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) {
|
||||
context->setConfig(cfg);
|
||||
if (!context->createContext()) {
|
||||
delete context;
|
||||
return 0;
|
||||
}
|
||||
return context;
|
||||
} else {
|
||||
qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Choose an appropriate configuration for rendering into the device.
|
||||
QEglProperties configProps;
|
||||
configProps.setPaintDeviceFormat(device);
|
||||
int redSize = configProps.value(EGL_RED_SIZE);
|
||||
if (redSize == EGL_DONT_CARE || redSize == 0)
|
||||
configProps.setPixelFormat(QImage::Format_ARGB32); // XXX
|
||||
configProps.setValue(EGL_ALPHA_MASK_SIZE, 1);
|
||||
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
|
||||
configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
|
||||
EGL_VG_ALPHA_FORMAT_PRE_BIT);
|
||||
configProps.setRenderableType(QEgl::OpenVG);
|
||||
if (!context->chooseConfig(configProps)) {
|
||||
// Try again without the "pre" bit.
|
||||
configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
|
||||
if (!context->chooseConfig(configProps)) {
|
||||
delete context;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
|
||||
configProps.setRenderableType(QEgl::OpenVG);
|
||||
if (!context->chooseConfig(configProps)) {
|
||||
delete context;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Construct a new EGL context for the selected configuration.
|
||||
if (!context->createContext()) {
|
||||
delete context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
#if !defined(QVG_NO_SINGLE_CONTEXT)
|
||||
|
||||
QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
|
||||
{
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
if (devType == QInternal::Widget)
|
||||
++(shared->widgetRefCount);
|
||||
if (shared->context) {
|
||||
++(shared->refCount);
|
||||
return shared->context;
|
||||
} else {
|
||||
shared->context = createContext(device);
|
||||
shared->refCount = 1;
|
||||
return shared->context;
|
||||
}
|
||||
}
|
||||
|
||||
static void qt_vg_destroy_shared_context(QVGSharedContext *shared)
|
||||
{
|
||||
shared->context->makeCurrent(qt_vg_shared_surface());
|
||||
delete shared->engine;
|
||||
shared->engine = 0;
|
||||
shared->context->doneCurrent();
|
||||
if (shared->surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(QEgl::display(), shared->surface);
|
||||
shared->surface = EGL_NO_SURFACE;
|
||||
}
|
||||
delete shared->context;
|
||||
shared->context = 0;
|
||||
}
|
||||
|
||||
void qt_vg_hibernate_pixmaps(QVGSharedContext *shared)
|
||||
{
|
||||
// Artificially increase the reference count to prevent the
|
||||
// context from being destroyed until after we have finished
|
||||
// the hibernation process.
|
||||
++(shared->refCount);
|
||||
|
||||
// We need a context current to hibernate the VGImage objects.
|
||||
shared->context->makeCurrent(qt_vg_shared_surface());
|
||||
|
||||
// Scan all QVGPixmapData objects in the system and hibernate them.
|
||||
QVGPixmapData *pd = shared->firstPixmap;
|
||||
while (pd != 0) {
|
||||
pd->hibernate();
|
||||
pd = pd->next;
|
||||
}
|
||||
|
||||
// Hibernate any remaining VGImage's in the image pool.
|
||||
QVGImagePool::instance()->hibernate();
|
||||
|
||||
// Don't need the current context any more.
|
||||
shared->context->lazyDoneCurrent();
|
||||
|
||||
// Decrease the reference count and destroy the context if necessary.
|
||||
if (--(shared->refCount) <= 0)
|
||||
qt_vg_destroy_shared_context(shared);
|
||||
}
|
||||
|
||||
void qt_vg_destroy_context(QEglContext *context, int devType)
|
||||
{
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
if (shared->context != context) {
|
||||
// This is not the shared context. Shouldn't happen!
|
||||
delete context;
|
||||
return;
|
||||
}
|
||||
if (devType == QInternal::Widget)
|
||||
--(shared->widgetRefCount);
|
||||
if (--(shared->refCount) <= 0) {
|
||||
qt_vg_destroy_shared_context(shared);
|
||||
} else if (shared->widgetRefCount <= 0 && devType == QInternal::Widget) {
|
||||
// All of the widget window surfaces have been destroyed
|
||||
// but we still have VG pixmaps active. Ask them to hibernate
|
||||
// to free up GPU resources until a widget is shown again.
|
||||
// This may eventually cause the EGLContext to be destroyed
|
||||
// because nothing in the system needs a context, which will
|
||||
// free up even more GPU resources.
|
||||
qt_vg_hibernate_pixmaps(shared);
|
||||
}
|
||||
}
|
||||
|
||||
EGLSurface qt_vg_shared_surface(void)
|
||||
{
|
||||
QVGSharedContext *shared = sharedContext();
|
||||
if (shared->surface == EGL_NO_SURFACE) {
|
||||
EGLint attribs[7];
|
||||
attribs[0] = EGL_WIDTH;
|
||||
attribs[1] = 16;
|
||||
attribs[2] = EGL_HEIGHT;
|
||||
attribs[3] = 16;
|
||||
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
|
||||
if (isPremultipliedContext(shared->context)) {
|
||||
attribs[4] = EGL_VG_ALPHA_FORMAT;
|
||||
attribs[5] = EGL_VG_ALPHA_FORMAT_PRE;
|
||||
attribs[6] = EGL_NONE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
attribs[4] = EGL_NONE;
|
||||
}
|
||||
shared->surface = eglCreatePbufferSurface
|
||||
(QEgl::display(), shared->context->config(), attribs);
|
||||
}
|
||||
return shared->surface;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
|
||||
{
|
||||
Q_UNUSED(devType);
|
||||
return createContext(device);
|
||||
}
|
||||
|
||||
void qt_vg_destroy_context(QEglContext *context, int devType)
|
||||
{
|
||||
Q_UNUSED(devType);
|
||||
delete context;
|
||||
}
|
||||
|
||||
EGLSurface qt_vg_shared_surface(void)
|
||||
{
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QVGEGLWindowSurfacePrivate::QVGEGLWindowSurfacePrivate(QWindowSurface *win)
|
||||
{
|
||||
winSurface = win;
|
||||
engine = 0;
|
||||
}
|
||||
|
||||
QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate()
|
||||
{
|
||||
// Destroy the paint engine if it hasn't been destroyed already.
|
||||
destroyPaintEngine();
|
||||
}
|
||||
|
||||
QVGPaintEngine *QVGEGLWindowSurfacePrivate::paintEngine()
|
||||
{
|
||||
if (!engine)
|
||||
engine = qt_vg_create_paint_engine();
|
||||
return engine;
|
||||
}
|
||||
|
||||
VGImage QVGEGLWindowSurfacePrivate::surfaceImage() const
|
||||
{
|
||||
return VG_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
void QVGEGLWindowSurfacePrivate::destroyPaintEngine()
|
||||
{
|
||||
if (engine) {
|
||||
qt_vg_destroy_paint_engine(engine);
|
||||
engine = 0;
|
||||
}
|
||||
}
|
||||
|
||||
QSize QVGEGLWindowSurfacePrivate::windowSurfaceSize(QWidget *widget) const
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QRect rect = winSurface->geometry();
|
||||
QSize newSize = rect.size();
|
||||
|
||||
#if defined(Q_WS_QWS)
|
||||
// Account for the widget mask, if any.
|
||||
if (widget && !widget->mask().isEmpty()) {
|
||||
const QRegion region = widget->mask()
|
||||
& rect.translated(-widget->geometry().topLeft());
|
||||
newSize = region.boundingRect().size();
|
||||
}
|
||||
#endif
|
||||
|
||||
return newSize;
|
||||
}
|
||||
|
||||
#if defined(QVG_VGIMAGE_BACKBUFFERS)
|
||||
|
||||
QVGEGLWindowSurfaceVGImage::QVGEGLWindowSurfaceVGImage(QWindowSurface *win)
|
||||
: QVGEGLWindowSurfacePrivate(win)
|
||||
, context(0)
|
||||
, backBuffer(VG_INVALID_HANDLE)
|
||||
, backBufferSurface(EGL_NO_SURFACE)
|
||||
, recreateBackBuffer(false)
|
||||
, isPaintingActive(false)
|
||||
, windowSurface(EGL_NO_SURFACE)
|
||||
{
|
||||
}
|
||||
|
||||
QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage()
|
||||
{
|
||||
destroyPaintEngine();
|
||||
if (context) {
|
||||
if (backBufferSurface != EGL_NO_SURFACE) {
|
||||
// We need a current context to be able to destroy the image.
|
||||
// We use the shared surface because the native window handle
|
||||
// associated with "windowSurface" may have been destroyed already.
|
||||
context->makeCurrent(qt_vg_shared_surface());
|
||||
context->destroySurface(backBufferSurface);
|
||||
vgDestroyImage(backBuffer);
|
||||
context->doneCurrent();
|
||||
}
|
||||
if (windowSurface != EGL_NO_SURFACE)
|
||||
context->destroySurface(windowSurface);
|
||||
qt_vg_destroy_context(context, QInternal::Widget);
|
||||
}
|
||||
}
|
||||
|
||||
QEglContext *QVGEGLWindowSurfaceVGImage::ensureContext(QWidget *widget)
|
||||
{
|
||||
QSize newSize = windowSurfaceSize(widget);
|
||||
if (context && size != newSize) {
|
||||
// The surface size has changed, so we need to recreate
|
||||
// the back buffer. Keep the same context and paint engine.
|
||||
size = newSize;
|
||||
if (isPaintingActive)
|
||||
context->doneCurrent();
|
||||
isPaintingActive = false;
|
||||
recreateBackBuffer = true;
|
||||
}
|
||||
if (!context) {
|
||||
// Create a new EGL context. We create the surface in beginPaint().
|
||||
size = newSize;
|
||||
context = qt_vg_create_context(widget, QInternal::Widget);
|
||||
if (!context)
|
||||
return 0;
|
||||
isPaintingActive = false;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget)
|
||||
{
|
||||
QEglContext *context = ensureContext(widget);
|
||||
if (context) {
|
||||
if (recreateBackBuffer || backBufferSurface == EGL_NO_SURFACE) {
|
||||
// Create a VGImage object to act as the back buffer
|
||||
// for this window. We have to create the VGImage with a
|
||||
// current context, so activate the main surface for the window.
|
||||
context->makeCurrent(mainSurface());
|
||||
recreateBackBuffer = false;
|
||||
if (backBufferSurface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(QEgl::display(), backBufferSurface);
|
||||
backBufferSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
if (backBuffer != VG_INVALID_HANDLE) {
|
||||
vgDestroyImage(backBuffer);
|
||||
}
|
||||
VGImageFormat format = qt_vg_config_to_vg_format(context);
|
||||
backBuffer = vgCreateImage
|
||||
(format, size.width(), size.height(),
|
||||
VG_IMAGE_QUALITY_FASTER);
|
||||
if (backBuffer != VG_INVALID_HANDLE) {
|
||||
// Create an EGL surface for rendering into the VGImage.
|
||||
backBufferSurface = eglCreatePbufferFromClientBuffer
|
||||
(QEgl::display(), EGL_OPENVG_IMAGE,
|
||||
(EGLClientBuffer)(backBuffer),
|
||||
context->config(), NULL);
|
||||
if (backBufferSurface == EGL_NO_SURFACE) {
|
||||
vgDestroyImage(backBuffer);
|
||||
backBuffer = VG_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (backBufferSurface != EGL_NO_SURFACE)
|
||||
context->makeCurrent(backBufferSurface);
|
||||
else
|
||||
context->makeCurrent(mainSurface());
|
||||
isPaintingActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QVGEGLWindowSurfaceVGImage::endPaint
|
||||
(QWidget *widget, const QRegion& region, QImage *image)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_UNUSED(image);
|
||||
QEglContext *context = ensureContext(widget);
|
||||
if (context) {
|
||||
if (backBufferSurface != EGL_NO_SURFACE) {
|
||||
if (isPaintingActive)
|
||||
vgFlush();
|
||||
context->lazyDoneCurrent();
|
||||
}
|
||||
isPaintingActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
VGImage QVGEGLWindowSurfaceVGImage::surfaceImage() const
|
||||
{
|
||||
return backBuffer;
|
||||
}
|
||||
|
||||
EGLSurface QVGEGLWindowSurfaceVGImage::mainSurface() const
|
||||
{
|
||||
if (windowSurface != EGL_NO_SURFACE)
|
||||
return windowSurface;
|
||||
else
|
||||
return qt_vg_shared_surface();
|
||||
}
|
||||
|
||||
#endif // QVG_VGIMAGE_BACKBUFFERS
|
||||
|
||||
QVGEGLWindowSurfaceDirect::QVGEGLWindowSurfaceDirect(QWindowSurface *win)
|
||||
: QVGEGLWindowSurfacePrivate(win)
|
||||
, context(0)
|
||||
, isPaintingActive(false)
|
||||
, needToSwap(false)
|
||||
, windowSurface(EGL_NO_SURFACE)
|
||||
{
|
||||
}
|
||||
|
||||
QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect()
|
||||
{
|
||||
destroyPaintEngine();
|
||||
if (context) {
|
||||
if (windowSurface != EGL_NO_SURFACE)
|
||||
context->destroySurface(windowSurface);
|
||||
qt_vg_destroy_context(context, QInternal::Widget);
|
||||
}
|
||||
}
|
||||
|
||||
QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
|
||||
{
|
||||
QSize newSize = windowSurfaceSize(widget);
|
||||
QEglProperties surfaceProps;
|
||||
|
||||
#if defined(QVG_RECREATE_ON_SIZE_CHANGE)
|
||||
#if !defined(QVG_NO_SINGLE_CONTEXT)
|
||||
if (context && size != newSize) {
|
||||
// The surface size has changed, so we need to recreate it.
|
||||
// We can keep the same context and paint engine.
|
||||
size = newSize;
|
||||
if (isPaintingActive)
|
||||
context->doneCurrent();
|
||||
context->destroySurface(windowSurface);
|
||||
#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
|
||||
if (isPremultipliedContext(context)) {
|
||||
surfaceProps.setValue
|
||||
(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
|
||||
} else {
|
||||
surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
|
||||
}
|
||||
#endif
|
||||
windowSurface = context->createSurface(widget, &surfaceProps);
|
||||
isPaintingActive = false;
|
||||
needToSwap = true;
|
||||
}
|
||||
#else
|
||||
if (context && size != newSize) {
|
||||
// The surface size has changed, so we need to recreate
|
||||
// the EGL context for the widget. We also need to recreate
|
||||
// the surface's paint engine if context sharing is not
|
||||
// enabled because we cannot reuse the existing paint objects
|
||||
// in the new context.
|
||||
qt_vg_destroy_paint_engine(engine);
|
||||
engine = 0;
|
||||
context->destroySurface(windowSurface);
|
||||
qt_vg_destroy_context(context, QInternal::Widget);
|
||||
context = 0;
|
||||
windowSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (!context) {
|
||||
// Create a new EGL context and bind it to the widget surface.
|
||||
size = newSize;
|
||||
context = qt_vg_create_context(widget, QInternal::Widget);
|
||||
if (!context)
|
||||
return 0;
|
||||
// We want a direct to window rendering surface if possible.
|
||||
#if defined(QVG_DIRECT_TO_WINDOW)
|
||||
surfaceProps.setValue(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||
#endif
|
||||
#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
|
||||
if (isPremultipliedContext(context)) {
|
||||
surfaceProps.setValue
|
||||
(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
|
||||
} else {
|
||||
surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
|
||||
}
|
||||
#endif
|
||||
EGLSurface surface = context->createSurface(widget, &surfaceProps);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
qt_vg_destroy_context(context, QInternal::Widget);
|
||||
context = 0;
|
||||
return 0;
|
||||
}
|
||||
needToSwap = true;
|
||||
#if defined(QVG_DIRECT_TO_WINDOW)
|
||||
// Did we get a direct to window rendering surface?
|
||||
EGLint buffer = 0;
|
||||
if (eglQueryContext(QEgl::display(), context->context(),
|
||||
EGL_RENDER_BUFFER, &buffer) &&
|
||||
buffer == EGL_SINGLE_BUFFER) {
|
||||
needToSwap = false;
|
||||
}
|
||||
#endif
|
||||
windowSurface = surface;
|
||||
isPaintingActive = false;
|
||||
}
|
||||
|
||||
#if !defined(QVG_NO_PRESERVED_SWAP)
|
||||
// Try to force the surface back buffer to preserve its contents.
|
||||
if (needToSwap) {
|
||||
bool succeeded = eglSurfaceAttrib(QEgl::display(), windowSurface,
|
||||
EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
|
||||
if (!succeeded && eglGetError() != EGL_SUCCESS) {
|
||||
qWarning("QVG: could not enable preserved swap");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return context;
|
||||
}
|
||||
|
||||
void QVGEGLWindowSurfaceDirect::beginPaint(QWidget *widget)
|
||||
{
|
||||
QEglContext *context = ensureContext(widget);
|
||||
if (context) {
|
||||
context->makeCurrent(windowSurface);
|
||||
isPaintingActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QVGEGLWindowSurfaceDirect::endPaint
|
||||
(QWidget *widget, const QRegion& region, QImage *image)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_UNUSED(image);
|
||||
QEglContext *context = ensureContext(widget);
|
||||
if (context) {
|
||||
if (needToSwap) {
|
||||
if (!isPaintingActive)
|
||||
context->makeCurrent(windowSurface);
|
||||
context->swapBuffers(windowSurface);
|
||||
context->lazyDoneCurrent();
|
||||
} else if (isPaintingActive) {
|
||||
vgFlush();
|
||||
context->lazyDoneCurrent();
|
||||
}
|
||||
isPaintingActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool QVGEGLWindowSurfaceDirect::supportsStaticContents() const
|
||||
{
|
||||
#if defined(QVG_BUFFER_SCROLLING) && !defined(QVG_NO_PRESERVED_SWAP)
|
||||
return true;
|
||||
#else
|
||||
return QVGEGLWindowSurfacePrivate::supportsStaticContents();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int dx, int dy)
|
||||
{
|
||||
#ifdef QVG_BUFFER_SCROLLING
|
||||
QEglContext *context = ensureContext(widget);
|
||||
if (context) {
|
||||
context->makeCurrent(windowSurface);
|
||||
QRect scrollRect = area.boundingRect();
|
||||
int sx = scrollRect.x();
|
||||
int sy = size.height() - scrollRect.y() - scrollRect.height();
|
||||
vgSeti(VG_SCISSORING, VG_FALSE);
|
||||
vgCopyPixels(sx + dx, sy - dy, sx, sy, scrollRect.width(), scrollRect.height());
|
||||
context->lazyDoneCurrent();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(widget);
|
||||
Q_UNUSED(area);
|
||||
Q_UNUSED(dx);
|
||||
Q_UNUSED(dy);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,148 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenVG module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWINDOWSURFACE_VGEGL_P_H
|
||||
#define QWINDOWSURFACE_VGEGL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QLibrary class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/private/qwindowsurface_p.h>
|
||||
#include "qvg_p.h"
|
||||
|
||||
#if !defined(QT_NO_EGL)
|
||||
|
||||
#include <QtGui/private/qeglcontext_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWindowSurface;
|
||||
|
||||
class Q_OPENVG_EXPORT QVGEGLWindowSurfacePrivate
|
||||
{
|
||||
public:
|
||||
QVGEGLWindowSurfacePrivate(QWindowSurface *win);
|
||||
virtual ~QVGEGLWindowSurfacePrivate();
|
||||
|
||||
QVGPaintEngine *paintEngine();
|
||||
virtual QEglContext *ensureContext(QWidget *widget) = 0;
|
||||
virtual void beginPaint(QWidget *widget) = 0;
|
||||
virtual void endPaint
|
||||
(QWidget *widget, const QRegion& region, QImage *image = 0) = 0;
|
||||
virtual VGImage surfaceImage() const;
|
||||
virtual QSize surfaceSize() const = 0;
|
||||
virtual bool supportsStaticContents() const { return false; }
|
||||
virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; }
|
||||
|
||||
private:
|
||||
QVGPaintEngine *engine;
|
||||
|
||||
protected:
|
||||
QWindowSurface *winSurface;
|
||||
|
||||
void destroyPaintEngine();
|
||||
QSize windowSurfaceSize(QWidget *widget) const;
|
||||
};
|
||||
|
||||
#if defined(EGL_OPENVG_IMAGE) && !defined(QVG_NO_SINGLE_CONTEXT)
|
||||
|
||||
#define QVG_VGIMAGE_BACKBUFFERS 1
|
||||
|
||||
class Q_OPENVG_EXPORT QVGEGLWindowSurfaceVGImage : public QVGEGLWindowSurfacePrivate
|
||||
{
|
||||
public:
|
||||
QVGEGLWindowSurfaceVGImage(QWindowSurface *win);
|
||||
virtual ~QVGEGLWindowSurfaceVGImage();
|
||||
|
||||
QEglContext *ensureContext(QWidget *widget);
|
||||
void beginPaint(QWidget *widget);
|
||||
void endPaint(QWidget *widget, const QRegion& region, QImage *image);
|
||||
VGImage surfaceImage() const;
|
||||
QSize surfaceSize() const { return size; }
|
||||
|
||||
protected:
|
||||
QEglContext *context;
|
||||
VGImage backBuffer;
|
||||
EGLSurface backBufferSurface;
|
||||
bool recreateBackBuffer;
|
||||
bool isPaintingActive;
|
||||
QSize size;
|
||||
EGLSurface windowSurface;
|
||||
|
||||
EGLSurface mainSurface() const;
|
||||
};
|
||||
|
||||
#endif // EGL_OPENVG_IMAGE
|
||||
|
||||
class Q_OPENVG_EXPORT QVGEGLWindowSurfaceDirect : public QVGEGLWindowSurfacePrivate
|
||||
{
|
||||
public:
|
||||
QVGEGLWindowSurfaceDirect(QWindowSurface *win);
|
||||
virtual ~QVGEGLWindowSurfaceDirect();
|
||||
|
||||
QEglContext *ensureContext(QWidget *widget);
|
||||
void beginPaint(QWidget *widget);
|
||||
void endPaint(QWidget *widget, const QRegion& region, QImage *image);
|
||||
QSize surfaceSize() const { return size; }
|
||||
bool supportsStaticContents() const;
|
||||
bool scroll(QWidget *widget, const QRegion& area, int dx, int dy);
|
||||
|
||||
protected:
|
||||
QEglContext *context;
|
||||
QSize size;
|
||||
bool isPaintingActive;
|
||||
bool needToSwap;
|
||||
EGLSurface windowSurface;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // !QT_NO_EGL
|
||||
|
||||
#endif // QWINDOWSURFACE_VGEGL_P_H
|
Loading…
Reference in New Issue
Block a user