--Boundary-00=_E8fbHE5DSmDn5i/ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello, I've attached a patch that draws stars twenty times faster than our current code. The difference is made by reinstating something we had in 3.x: a cache of star pixmaps covering all sizes and colors, drawn on the map with drawPixmap(), instead of using drawEllipse(). The stellar pixmaps are stored in a static QHash in StarObject, and initialized once in StarComponent::init(). When a star needs to be drawn, the QHash key is constructed from the star's spectral type, and the int() of the size parameter passed by StarComponent (e.g., "K07" for a bright red star, or "B02" for a faint blue star). I added timing code to StarComponent to test the time taken by the star catalog draw loop. Try this test: add the timing code without changing anything else, then start KStars, and set both of the stars' magnitude limits to 10.0. Zoom out so you can see most of the sky, then press "." to stop the clock and advance one time step. Hit that a few times to get an average rendering time for all those stars. On my machine it was about 7.7 seconds. Then close Kstars, apply the rest of the patch, recompile, and run the same timing test. On my machine the same rendering loops were taking 0.3 seconds! I didn't simply apply the code, because I'm a little reluctant to introduce such a big change while we're frozen and a couple weeks away from a major release. It appears to work beautifully, but I have not implemented color-switching for Star Chart and Night Vision color schemes (not hard to do), and there may be some issues that I'm unaware of. So, I want people's opinion. Should we consider this a bugfix, or at least a regression fix, and add it now? Or should we hold off until trunk thaws? I'd really like some help testing this change if we're going to add it now. Whatever we decide, exciting times are ahead. With this fix, we'll be able to finally increase the number of stars handled by KStars well into the millions with no degradation in performance compared to what it does now. And actually, if we're smart about ignoring faint stars at low zoom, the performance should be really good. regards, Jason --Boundary-00=_E8fbHE5DSmDn5i/ Content-Type: text/x-diff; charset="us-ascii"; name="stars_as_images.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="stars_as_images.patch" Index: starobject.h =================================================================== --- starobject.h (revision 751528) +++ starobject.h (working copy) @@ -283,11 +283,14 @@ */ static void updateColors( bool desaturateColors, int saturation ); + static void initImages(); + quint64 updateID; quint64 updateNumID; protected: static QMap ColorMap; + static QHash StarImage; private: QString SpType; Index: skycomponents/starcomponent.cpp =================================================================== --- skycomponents/starcomponent.cpp (revision 751528) +++ skycomponents/starcomponent.cpp (working copy) @@ -74,6 +74,8 @@ readLineNumbers(); readData( Options::magLimitDrawStar() ); + + StarObject::initImages(); } void StarComponent::update( KStarsData *data, KSNumbers *num ) @@ -212,21 +214,27 @@ labelMagLim += ( 12.0 - labelMagLim ) * ( lgz - lgmin) / (lgmax - lgmin ); if ( labelMagLim > 8.0 ) labelMagLim = 8.0; - //Set the brush - QColor fillColor( Qt::white ); - if ( starColorMode() == 1 ) fillColor = Qt::red; - if ( starColorMode() == 2 ) fillColor = Qt::black; - psky.setBrush( QBrush( fillColor ) ); - if ( starColorMode() > 0 ) - psky.setPen( QPen( fillColor ) ); - else - //Reset the colors before drawing the stars. - //Strictly speaking, we don't need to do this every time, but once per - //draw loop isn't too expensive. - StarObject::updateColors( (! Options::useAntialias() || - map->isSlewing()), starColorIntensity() ); +//REMOVE +// //Set the brush +// QColor fillColor( Qt::white ); +// if ( starColorMode() == 1 ) fillColor = Qt::red; +// if ( starColorMode() == 2 ) fillColor = Qt::black; +// psky.setBrush( QBrush( fillColor ) ); +// if ( starColorMode() > 0 ) +// psky.setPen( QPen( fillColor ) ); +// else +// //Reset the colors before drawing the stars. +// //Strictly speaking, we don't need to do this every time, but once per +// //draw loop isn't too expensive. +// StarObject::updateColors( (! Options::useAntialias() || +// map->isSlewing()), starColorIntensity() ); +//END_REMOVE //Loop for drawing star images + //DEBUG_TIME_STARS + QTime t; + t.start(); + MeshIterator region(m_skyMesh, DRAW_BUF); while ( region.hasNext() ) { StarList* starList = m_starIndex->at( region.next() ); @@ -258,6 +266,10 @@ addLabel( o, curStar ); } } + + //DEBUG_TIME_STARS + kDebug() << QString("drawing stars took %1 ms").arg(t.elapsed()); + } void StarComponent::addLabel( const QPointF& p, StarObject *star ) Index: starobject.cpp =================================================================== --- starobject.cpp (revision 751528) +++ starobject.cpp (working copy) @@ -32,6 +32,7 @@ #include "skycomponents/skylabeler.h" QMap StarObject::ColorMap; +QHash StarObject::StarImage; //----- Static Methods ----- // @@ -104,6 +105,33 @@ updateID = updateNumID = 0; } +void StarObject::initImages() { + ColorMap.insert( "O", QColor::fromRgb( 0, 0, 255 ) ); + ColorMap.insert( "B", QColor::fromRgb( 0, 200, 255 ) ); + ColorMap.insert( "A", QColor::fromRgb( 0, 255, 255 ) ); + ColorMap.insert( "F", QColor::fromRgb( 200, 255, 100 ) ); + ColorMap.insert( "G", QColor::fromRgb( 255, 255, 0 ) ); + ColorMap.insert( "K", QColor::fromRgb( 255, 100, 0 ) ); + ColorMap.insert( "M", QColor::fromRgb( 255, 0, 0 ) ); + + foreach ( QString color, ColorMap.keys() ) { + QString imKey = color+"10"; + QPixmap BigImage( 10, 10 ); + QPainter p; + p.begin( &BigImage ); + p.setPen( QPen(ColorMap[color], 2) ); + p.setBrush( QColor(Qt::white) ); + p.drawEllipse( QRect( 0, 0, 10, 10 ) ); + p.end(); + StarImage.insert( imKey, BigImage ); + + for ( int size = 9; size > 0; size-- ) { + imKey = color+QString("0%1").arg(size); + StarImage.insert( imKey, BigImage.scaled( size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); + } + } +} + void StarObject::showPopupMenu( KSPopupMenu *pmenu, const QPoint &pos ) { pmenu->createStarMenu( this ); pmenu->popup( pos ); } @@ -325,23 +353,39 @@ void StarObject::draw( QPainter &psky, float x, float y, float size, bool useRealColors, int scIntensity, bool /*showMultiple*/ ) { - if ( useRealColors ) { +//REMOVE +// if ( useRealColors ) { //Realistic colors //Stars rendered as a white core with a colored ring. //With antialiasing, we can just set the ring thickness to 0.1*scIntensity //However, this won't work without antialiasing, because the ring thickness //cant be <1 in this case. So we desaturate the pen color instead - if ( Options::useAntialias() ) - psky.setPen( QPen( color(), 0.1*scIntensity ) ); - else { - psky.setPen( QPen( color(), 1 ) ); + +// if ( Options::useAntialias() ) +// psky.setPen( QPen( color(), 0.1*scIntensity ) ); +// else { +// psky.setPen( QPen( color(), 1 ) ); +// } +// } +//END_REMOVE + + int isize = int(size); + if ( isize > 10 ) { + kDebug() << "Star too big: " << size << endl; + isize = 10; } - } - if ( Options::useAntialias() ) - psky.drawEllipse( QRectF( x - 0.5*size, y - 0.5*size, size, size ) ); - else - psky.drawEllipse( QRect( int(x - 0.5*size), int(y - 0.5*size), int(size), int(size) ) ); + float offset = 0.5*float(isize); + QString imKey = SpType.at(0)+QString("0%1").arg(isize); + psky.drawPixmap( QPointF(x-offset, y-offset), StarImage[imKey] ); + +//REMOVE +// if ( Options::useAntialias() ) +// psky.drawEllipse( QRectF( x - 0.5*size, y - 0.5*size, size, size ) ); +// else +// psky.drawEllipse( QRect( int(x - 0.5*size), int(y - 0.5*size), int(size), int(size) ) ); +//END_REMOVE + } // The two routines below seem overly complicated but at least they are doing --Boundary-00=_E8fbHE5DSmDn5i/ Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Kstars-devel mailing list Kstars-devel@kde.org https://mail.kde.org/mailman/listinfo/kstars-devel --Boundary-00=_E8fbHE5DSmDn5i/--