summaryrefslogtreecommitdiffstats
path: root/src/openvg
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2010-02-15 15:23:23 (GMT)
committerJason Barron <jbarron@trolltech.com>2010-07-12 07:03:07 (GMT)
commit940930dd8102511e6890ed661cf3d2dd88c2e1f4 (patch)
tree2eaa62af9ff24eb0c45caa6c7d6f09274480b159 /src/openvg
parent4c392ee7f9f7445620269fbd3250a17a982e2369 (diff)
downloadQt-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.cpp4
-rw-r--r--src/openvg/qvg_symbian.cpp75
-rw-r--r--src/openvg/qvgfontglyphcache_p.h2
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,