summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Rahn <rahn@kde.org>2016-11-10 18:29:56 (GMT)
committerTorsten Rahn <trahn@testo.de>2016-11-10 18:55:49 (GMT)
commit4f89f8ea3c72354e3814a36a1076d62f3ef982f5 (patch)
tree33279ccf7306fa4da22b8d45a1ad4a9a0e3c9fb1
parent73dcb3cb8cfc3bb2341aa7fc57178866b7ff0036 (diff)
Minor building rendering optimization:
Cache the outline and inner polygon screen coordinates and reuse them for the roof ( same pattern as for streets in 620499fdb830ced95e0ab3b4b8f635aa59db13d6 )
-rw-r--r--src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.cpp55
-rw-r--r--src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.h13
-rw-r--r--src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp6
3 files changed, 42 insertions, 32 deletions
diff --git a/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.cpp
index fa8af0a..7a23303 100644
--- a/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.cpp
+++ b/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.cpp
@@ -29,6 +29,7 @@ BuildingGeoPolygonGraphicsItem::BuildingGeoPolygonGraphicsItem(const GeoDataPlac
, m_buildingHeight(extractBuildingHeight(*placemark))
, m_buildingLabel(extractBuildingLabel(*placemark))
, m_entries(extractNamedEntries(*placemark))
+ , m_hasInnerBoundaries(false)
{
setZValue(this->zValue() + m_buildingHeight);
Q_ASSERT(m_buildingHeight > 0.0);
@@ -56,9 +57,7 @@ BuildingGeoPolygonGraphicsItem::BuildingGeoPolygonGraphicsItem(const GeoDataPlac
}
void BuildingGeoPolygonGraphicsItem::initializeBuildingPainting(const GeoPainter* painter, const ViewportParams *viewport,
- bool &drawAccurate3D, bool &isCameraAboveBuilding, bool &hasInnerBoundaries,
- QVector<QPolygonF*>& outlinePolygons,
- QVector<QPolygonF*>& innerPolygons) const
+ bool &drawAccurate3D, bool &isCameraAboveBuilding ) const
{
drawAccurate3D = false;
isCameraAboveBuilding = false;
@@ -66,7 +65,13 @@ void BuildingGeoPolygonGraphicsItem::initializeBuildingPainting(const GeoPainter
QPointF offsetAtCorner = buildingOffset(QPointF(0, 0), viewport, &isCameraAboveBuilding);
qreal maxOffset = qMax( qAbs( offsetAtCorner.x() ), qAbs( offsetAtCorner.y() ) );
drawAccurate3D = painter->mapQuality() == HighQuality ? maxOffset > 5.0 : maxOffset > 8.0;
+}
+void BuildingGeoPolygonGraphicsItem::updatePolygons( const ViewportParams *viewport,
+ QVector<QPolygonF*>& outlinePolygons,
+ QVector<QPolygonF*>& innerPolygons,
+ bool &hasInnerBoundaries )
+{
// Since subtracting one fully contained polygon from another results in a single
// polygon with a "connecting line" between the inner and outer part we need
// to first paint the inner area with no pen and then the outlines with the correct pen.
@@ -196,9 +201,17 @@ QVector<BuildingGeoPolygonGraphicsItem::NamedEntry> BuildingGeoPolygonGraphicsIt
void BuildingGeoPolygonGraphicsItem::paint(GeoPainter* painter, const ViewportParams* viewport, const QString &layer)
{
if (layer.endsWith(QLatin1String("/frame"))) {
+ Q_ASSERT(!m_cachedOutlinePolygons.isEmpty());
+ Q_ASSERT(!m_cachedInnerPolygons.isEmpty());
+ updatePolygons(viewport, m_cachedOutlinePolygons, m_cachedInnerPolygons, m_hasInnerBoundaries);
+ if (m_cachedOutlinePolygons.isEmpty()) return;
paintFrame(painter, viewport);
} else if (layer.endsWith(QLatin1String("/roof"))) {
+ if (m_cachedOutlinePolygons.isEmpty()) return;
paintRoof(painter, viewport);
+ qDeleteAll(m_cachedOutlinePolygons);
+ m_cachedOutlinePolygons.clear();
+ m_cachedInnerPolygons.clear();
} else {
mDebug() << "Didn't expect to have to paint layer " << layer << ", ignoring it.";
}
@@ -208,10 +221,7 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
{
bool drawAccurate3D;
bool isCameraAboveBuilding;
- bool hasInnerBoundaries;
- QVector<QPolygonF*> outlinePolygons;
- QVector<QPolygonF*> innerPolygons;
- initializeBuildingPainting(painter, viewport, drawAccurate3D, isCameraAboveBuilding, hasInnerBoundaries, outlinePolygons, innerPolygons);
+ initializeBuildingPainting(painter, viewport, drawAccurate3D, isCameraAboveBuilding);
if (!isCameraAboveBuilding) {
return; // do not render roof if we look inside the building
}
@@ -222,14 +232,14 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
qreal maxSize(0.0);
QPointF roofCenter;
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
painter->setPen(Qt::NoPen);
}
// first paint the area (and the outline if there are no inner boundaries)
double maxArea = 0.0;
- foreach(QPolygonF* outlinePolygon, outlinePolygons) {
+ foreach(QPolygonF* outlinePolygon, m_cachedOutlinePolygons) {
QRectF const boundingRect = outlinePolygon->boundingRect();
QPolygonF buildingRoof;
if (!m_buildingLabel.isEmpty() || !m_entries.isEmpty()) {
@@ -248,10 +258,10 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
foreach(const QPointF &point, *outlinePolygon) {
buildingRoof << point + buildingOffset(point, viewport);
}
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
QRegion clip(buildingRoof.toPolygon());
- foreach(QPolygonF* innerPolygon, innerPolygons) {
+ foreach(QPolygonF* innerPolygon, m_cachedInnerPolygons) {
QPolygonF buildingInner;
buildingInner.reserve(innerPolygon->size());
foreach(const QPointF &point, *innerPolygon) {
@@ -265,10 +275,10 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
} else {
QPointF const offset = buildingOffset(boundingRect.center(), viewport);
painter->translate(offset);
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
QRegion clip(outlinePolygon->toPolygon());
- foreach(QPolygonF* clipPolygon, innerPolygons) {
+ foreach(QPolygonF* clipPolygon, m_cachedInnerPolygons) {
clip-=QRegion(clipPolygon->toPolygon());
}
painter->setClipRegion(clip);
@@ -319,9 +329,9 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
// then paint the outlines if there are inner boundaries
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
painter->setPen(currentPen);
- foreach(QPolygonF * polygon, outlinePolygons) {
+ foreach(QPolygonF * polygon, m_cachedOutlinePolygons) {
QRectF const boundingRect = polygon->boundingRect();
if ( drawAccurate3D) {
QPolygonF buildingRoof;
@@ -339,7 +349,6 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
}
}
- qDeleteAll(outlinePolygons);
painter->restore();
}
@@ -359,13 +368,10 @@ void BuildingGeoPolygonGraphicsItem::paintFrame(GeoPainter *painter, const Viewp
bool drawAccurate3D;
bool isCameraAboveBuilding;
- bool hasInnerBoundaries;
- QVector<QPolygonF*> outlinePolygons;
- QVector<QPolygonF*> innerPolygons;
- initializeBuildingPainting(painter, viewport, drawAccurate3D, isCameraAboveBuilding, hasInnerBoundaries, outlinePolygons, innerPolygons);
+ initializeBuildingPainting(painter, viewport, drawAccurate3D, isCameraAboveBuilding);
configureFramePainter(painter);
- foreach(QPolygonF* outlinePolygon, outlinePolygons) {
+ foreach(QPolygonF* outlinePolygon, m_cachedOutlinePolygons) {
if (outlinePolygon->isEmpty()) {
continue;
}
@@ -378,7 +384,7 @@ void BuildingGeoPolygonGraphicsItem::paintFrame(GeoPainter *painter, const Viewp
QPointF const & b = (*outlinePolygon)[i];
QPointF const shiftB = b + buildingOffset(b, viewport);
QPolygonF buildingSide = QPolygonF() << a << shiftA << shiftB << b;
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
//smoothen away our loss of antialiasing due to the QRegion Qt-bug workaround
painter->setPen(QPen(painter->brush().color(), 1.5));
}
@@ -388,10 +394,10 @@ void BuildingGeoPolygonGraphicsItem::paintFrame(GeoPainter *painter, const Viewp
}
} else {
// don't draw the building sides - just draw the base frame instead
- if (hasInnerBoundaries) {
+ if (m_hasInnerBoundaries) {
QRegion clip(outlinePolygon->toPolygon());
- foreach(QPolygonF* clipPolygon, innerPolygons) {
+ foreach(QPolygonF* clipPolygon, m_cachedInnerPolygons) {
clip-=QRegion(clipPolygon->toPolygon());
}
painter->setClipRegion(clip);
@@ -399,7 +405,6 @@ void BuildingGeoPolygonGraphicsItem::paintFrame(GeoPainter *painter, const Viewp
painter->drawPolygon(*outlinePolygon);
}
}
- qDeleteAll(outlinePolygons);
painter->restore();
}
diff --git a/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.h b/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.h
index 8514cc5..c6793ba 100644
--- a/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.h
+++ b/src/lib/marble/geodata/graphicsitem/BuildingGeoPolygonGraphicsItem.h
@@ -38,9 +38,12 @@ private:
void paintRoof(GeoPainter* painter, const ViewportParams *viewport);
void configureFramePainter(GeoPainter *painter) const;
void initializeBuildingPainting(const GeoPainter* painter, const ViewportParams *viewport,
- bool &drawAccurate3D, bool &isCameraAboveBuilding, bool &hasInnerBoundaries,
- QVector<QPolygonF*>& outlinePolygons,
- QVector<QPolygonF*>& innerPolygons) const;
+ bool &drawAccurate3D, bool &isCameraAboveBuilding) const;
+ void updatePolygons( const ViewportParams *viewport,
+ QVector<QPolygonF*>& outlinePolygons,
+ QVector<QPolygonF*>& innerPolygons,
+ bool &hasInnerBoundaries);
+
QPointF buildingOffset(const QPointF &point, const ViewportParams *viewport, bool* isCameraAboveBuilding = nullptr) const;
static QPointF centroid(const QPolygonF &polygon, double &area);
@@ -54,6 +57,10 @@ private:
const double m_buildingHeight;
const QString m_buildingLabel;
const QVector<NamedEntry> m_entries;
+ QVector<QPolygonF*> m_cachedOutlinePolygons;
+ QVector<QPolygonF*> m_cachedInnerPolygons;
+ bool m_hasInnerBoundaries;
+
};
}
diff --git a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
index fed9c3f..1233c94 100644
--- a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
+++ b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
@@ -125,8 +125,7 @@ void GeoLineStringGraphicsItem::paint(GeoPainter* painter, const ViewportParams*
setRenderContext(RenderContext(tileLevel));
if (layer.endsWith(QLatin1String("/outline"))) {
- qDeleteAll(m_cachedPolygons);
- m_cachedPolygons.clear();
+ Q_ASSERT(!m_cachedPolygons.isEmpty());
painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons);
if (m_cachedPolygons.empty()) {
return;
@@ -148,8 +147,7 @@ void GeoLineStringGraphicsItem::paint(GeoPainter* painter, const ViewportParams*
qDeleteAll(m_cachedPolygons);
m_cachedPolygons.clear();
} else {
- qDeleteAll(m_cachedPolygons);
- m_cachedPolygons.clear();
+ Q_ASSERT(!m_cachedPolygons.isEmpty());
painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons);
if (m_cachedPolygons.empty()) {
return;