diff options
author | Jason Barron <jbarron@trolltech.com> | 2010-02-15 15:23:23 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2010-07-12 07:03:07 (GMT) |
commit | 940930dd8102511e6890ed661cf3d2dd88c2e1f4 (patch) | |
tree | 2eaa62af9ff24eb0c45caa6c7d6f09274480b159 /src/openvg | |
parent | 4c392ee7f9f7445620269fbd3250a17a982e2369 (diff) | |
download | Qt-940930dd8102511e6890ed661cf3d2dd88c2e1f4.zip Qt-940930dd8102511e6890ed661cf3d2dd88c2e1f4.tar.gz Qt-940930dd8102511e6890ed661cf3d2dd88c2e1f4.tar.bz2 |
Enable cross-process glyph cache for OpenVG graphics system on Symbian.
This introduces a specialized OpenVG font cache for the Symbian
platform. By using RGlyphDataIterator we can create a VGImage to store
inside a VGFont without having to upload our own glyph image. This
works by utilizing RSgImage which can be used to share handles to
graphics memory across processes thus allowing glyph images to be
shared by multiple processes and reducing graphics memory usage.
Reviewed-by: Alessandro Portale
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 4 | ||||
-rw-r--r-- | src/openvg/qvg_symbian.cpp | 75 | ||||
-rw-r--r-- | src/openvg/qvgfontglyphcache_p.h | 2 |
3 files changed, 60 insertions, 21 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 564b390..01c7a7e 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3406,7 +3406,11 @@ void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) if (it != d->fontCache.constEnd()) { glyphCache = it.value(); } else { +#ifdef Q_OS_SYMBIAN + glyphCache = new QSymbianVGFontGlyphCache(); +#else glyphCache = new QVGFontGlyphCache(); +#endif if (glyphCache->font == VG_INVALID_HANDLE) { qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine"); delete glyphCache; diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp index 09962f6..e6086d0 100644 --- a/src/openvg/qvg_symbian.cpp +++ b/src/openvg/qvg_symbian.cpp @@ -45,16 +45,17 @@ #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE #include <private/qt_s60_p.h> #include <fbs.h> +#include <gdi.h> #include <sgresource/sgimage.h> typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); -#endif - -#if 1//defined(SYMBIAN_GDI_GLYPHDATA) && defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) +#ifdef SYMBIAN_GDI_GLYPHDATA // defined in gdi.h +#define QT_SYMBIAN_HARDWARE_GLYPH_CACHE #include <graphics/glyphdataiterator.h> #include <private/qfontengine_s60_p.h> #endif +#endif QT_BEGIN_NAMESPACE @@ -319,32 +320,66 @@ void* QVGPixmapData::toNativeType(NativeType type) return reinterpret_cast<void*>(bitmap); } return 0; -#endif } void QSymbianVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d, const QTextItemInt &ti, const QVarLengthArray<glyph_t> &glyphs) { +#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE QFontEngineS60 *fontEngine = static_cast<QFontEngineS60*>(ti.fontEngine); - CFont *font = fontEngine->m_font; + CFont *cfont = fontEngine->m_activeFont; + +// QVarLengthArray<glyph_t, 256> adjustedGlyphs(glyphs); +// for (int i = 0; i < glyphs.count(); ++i) +// adjustedGlyphs[i] |= 0x80000000; RGlyphDataIterator iter; - int err = iter.Open(*font, glyphs.data(), glyphs.count()); - -// for (; err == KErrNone; err = iter.Next()) { -// const RSgImage& image = iter.Image(); -// const TRect& rect = iter.Rect(); -// const TOpenFontCharMetrics& metrics = iter.Metrics(); -// -// QPixmap pix = QPixmap::fromSymbianRSgImage(*image); -// -// } -// iter.Close(); -// -// if (err != KErrNotFound) { -// // Handle the error... -// } + int err = iter.Open(*cfont, (const unsigned int*)glyphs.constData(), glyphs.count()); + + if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases + iter.Close(); + qWarning("Falling back to default QVGFontGlyphCache"); + return QVGFontGlyphCache::cacheGlyphs(d, ti, glyphs); + } + + for (; err == KErrNone; err = iter.Next()) { + // Skip this glyph if we have already cached it before. + const unsigned int glyph = iter.GlyphCode(); + if (((glyph < 256) && ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0)) + || cachedGlyphs.contains(glyph)) + continue; + + 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 + 0.5f; + origin[1] = -glyphBounds.iTl.iY + 0.5f; + escapement[0] = metrics.HorizAdvance(); + escapement[1] = 0; + vgSetGlyphToImage(font, iter.GlyphCode(), 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, ti, glyphs); +#endif } QT_END_NAMESPACE diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h index 4ba07ba..ee11082 100644 --- a/src/openvg/qvgfontglyphcache_p.h +++ b/src/openvg/qvgfontglyphcache_p.h @@ -79,7 +79,7 @@ public: QSet<glyph_t> cachedGlyphs; }; -#if defined( Q_OS_SYMBIAN) +#if defined(Q_OS_SYMBIAN) class QSymbianVGFontGlyphCache : public QVGFontGlyphCache { void cacheGlyphs(QVGPaintEnginePrivate *d, |