[Kst] branches/work/kst/portto4/kst/src

Peter Kümmel syntheticpp at gmx.net
Tue Aug 31 20:52:20 CEST 2010


Cool, more than 10 times faster!

Peter



On 30.08.2010 23:56, Barth Netterfield wrote:
> SVN commit 1170152 by netterfield:
> 
> Some camping fun: lets optimize Image drawing!
> Reduce Image draw times from 460ms to 35ms.  Its now totally dominated by blitting.
> Also fix a couple un-initialzed variables complements of Valgrind.
> 
> 
> 
>  M  +1 -1      datasources/fitsimage/fitsimage.cpp  
>  M  +10 -3     libkst/matrix.cpp  
>  M  +1 -0      libkst/matrix.h  
>  M  +1 -1      libkstapp/applicationsettings.cpp  
>  M  +1 -0      libkstapp/plotitem.cpp  
>  M  +56 -35    libkstmath/image.cpp  
>  M  +1 -1      libkstmath/image.h  
>  M  +23 -38    libkstmath/palette.cpp  
>  M  +47 -10    libkstmath/palette.h  
> 
> 
> --- branches/work/kst/portto4/kst/src/datasources/fitsimage/fitsimage.cpp #1170151:1170152
> @@ -273,7 +273,7 @@
>  
>  
>  FitsImageSource::~FitsImageSource() {
> -  int status;
> +  int status = 0;
>    if (_fptr) {
>      fits_close_file( _fptr, &status );
>      _fptr = 0L;
> --- branches/work/kst/portto4/kst/src/libkst/matrix.cpp #1170151:1170152
> @@ -83,13 +83,20 @@
>  
>  
>  double Matrix::value(double x, double y, bool* ok) const {
> -  int x_index = (int)floor((x - _minX) / (double)_stepX);
> -  int y_index = (int)floor((y - _minY) / (double)_stepY);
> +  int x_index = (int)((x - _minX) / (double)_stepX);
> +  int y_index = (int)((y - _minY) / (double)_stepY);
>  
> -  return valueRaw(x_index, y_index, ok);
> +  int index = zIndex(x_index, y_index);
> +  if ((index < 0) || !finite(_z[index]) || KST_ISNAN(_z[index])) {
> +    (*ok) = false;
> +    return 0.0;
>  }
> +  (*ok) = true;
> +  return _z[index];
>  
> +}
>  
> +
>  double Matrix::valueRaw(int x, int y, bool* ok) const {
>    int index = zIndex(x,y);
>    if ((index < 0) || !finite(_z[index]) || KST_ISNAN(_z[index])) {
> --- branches/work/kst/portto4/kst/src/libkst/matrix.h #1170151:1170152
> @@ -147,6 +147,7 @@
>  
>      virtual void internalUpdate();
>  
> +    double Z(int i) const {return _z[i];}
>    protected:
>      int _NS;
>      int _NRealS; // number of samples with real values
> --- branches/work/kst/portto4/kst/src/libkstapp/applicationsettings.cpp #1170151:1170152
> @@ -51,7 +51,7 @@
>    //FIXME Not sure if this is the best test for hardware acceleration
>    // but right now opening with QGV with QGLWidget as viewport takes
>    // several seconds delay when opening application on my system.
> -  _useOpenGL = _settings->value("general/opengl", QVariant(QGLPixelBuffer::hasOpenGLPbuffers())).toBool();
> +  _useOpenGL = _settings->value("general/opengl", false).toBool(); //QVariant(QGLPixelBuffer::hasOpenGLPbuffers())).toBool();
>  
>    _maxUpdate = _settings->value("general/minimumupdateperiod", QVariant(200)).toInt();
>  
> --- branches/work/kst/portto4/kst/src/libkstapp/plotitem.cpp #1170151:1170152
> @@ -68,6 +68,7 @@
>    _calculatedLeftBaseOffset(0.0),
>    _calculatedRightLabelMargin(0.0),
>    _calculatedTopLabelMargin(0.0),
> +  _calculatedTopLabelHeight(0.0),
>    _calculatedBottomLabelMargin(0.0),
>    _calculatedBottomLabelWidth(0.0),
>    _calculatedLabelMarginWidth(0.0),
> --- branches/work/kst/portto4/kst/src/libkstmath/image.cpp #1170151:1170152
> @@ -63,7 +63,7 @@
>      s.writeAttribute("matrix", _inputMatrices[THEMATRIX]->Name());
>    }
>  
> -  if (!_pal.paletteData().isEmpty()) {
> +  if (_pal.colorCount()>0) {
>      s.writeAttribute("palettename", _pal.paletteName());
>    }
>  
> @@ -143,32 +143,20 @@
>    }
>  }
>  
> -
> -QColor Image::getMappedColor(MatrixPtr m, double x, double y) {
> -  bool ok;
> -
> -  double z = m->value(x, y, &ok);
> -  if (ok) {
> +//FIXME: Inline and optimize!
> +QColor Image::getMappedColor(double z) {
>      int index;
>      if (_zUpper - _zLower != 0) {
> -      if (z > _zUpper) {
> -        index = _pal.paletteData().count() - 1;
> -      } else if (z < _zLower) {
> -        index = 0;
> +    index = (int)(((z - _zLower) * (_pal.colorCount() - 1)) / (_zUpper - _zLower));
>        } else {
> -          index = (int)floor(((z - _zLower) * (_pal.paletteData().count() - 1)) / (_zUpper - _zLower));
> -      }
> -    } else {
>        index = 0;
>      }
> -    return _pal.paletteData().value(index);
> +  return _pal.color(index);
>    }
> -  return QColor();
> -}
>  
>  
>  void Image::setPalette(const Palette &pal) {
> -  _pal = pal;
> +  _pal.changePaletteName(pal.paletteName());
>  }
>  
>  
> @@ -214,7 +202,7 @@
>    _zUpper = upperZ;
>    _autoThreshold = autoThreshold;
>    if (_pal.paletteName() != paletteName) {
> -    _pal = Palette(paletteName);
> +    _pal.changePaletteName(paletteName);
>    }
>    _hasColorMap = true;
>    _hasContourMap = false;
> @@ -244,7 +232,7 @@
>    _zUpper = upperZ;
>    _autoThreshold = autoThreshold;
>    if (_pal.paletteName() != paletteName) {
> -    _pal = Palette(paletteName);
> +    _pal.changePaletteName(paletteName);
>    }
>    _numContourLines = numContours;
>    _contourWeight = contourWeight;
> @@ -437,8 +425,12 @@
>  
>  void Image::paintObjects(const CurveRenderContext& context) {
>    QPainter* p = context.painter;
> +
> +  if (hasColorMap()) {
>    p->drawImage(_imageLocation, _image);
> +  }
>  
> +  if (hasContourMap()) {
>    QColor lineColor = contourColor();
>  
>    foreach(CoutourLineDetails lineDetails, _lines) {
> @@ -446,8 +438,8 @@
>      p->drawLine(lineDetails._line);
>    }
>  }
> +}
>  
> -
>  void Image::updatePaintObjects(const CurveRenderContext& context) {
>    double Lx = context.Lx, Hx = context.Hx, Ly = context.Ly, Hy = context.Hy;
>    double m_X = context.m_X, m_Y = context.m_Y, b_X = context.b_X, b_Y = context.b_Y;
> @@ -532,26 +524,55 @@
>          int hXlXDiff = d2i(img_Hx_pix - img_Lx_pix);
>          int hYlYDiff = d2i(img_Hy_pix - img_Ly_pix - 1);
>          _image = QImage(hXlXDiff, hYlYDiff, QImage::Format_RGB32);
> -        for (int y = 0; y < _image.height(); ++y) {
> +        //_image.fill(0);
> +        int ih = _image.height();
> +        int iw = _image.width();
> +        double m_minX = m->minX();
> +        double m_minY = m->minY();
> +        double m_numY = m->yNumSteps();
> +        double m_stepYr = 1.0/m->yStepSize();
> +        double m_stepXr = 1.0/m->xStepSize();
> +        int x_index;
> +        int y_index;
> +        int palCountMinus1 = _pal.colorCount() - 1;
> +        double palCountMin1_OverDZ = double(palCountMinus1) / (_zUpper - _zLower);
> +
> +        for (int y = 0; y < ih; ++y) {
> +          bool okY = true;
> +
>            QRgb *scanLine = (QRgb *)_image.scanLine(y);
> -          for (int x = 0; x < _image.width(); ++x) {
> -            double new_x, new_y;
> +          double new_y;
> +          if (yLog) {
> +            new_y = pow(yLogBase, (y + 1 + img_Ly_pix - b_Y) / m_Y);
> +          } else {
> +            new_y = (y + 1 + img_Ly_pix - b_Y) / m_Y;
> +          }
> +          y_index = (int)((new_y - m_minY)*m_stepYr);
> +          if (y_index<0 || y_index>=m_numY) {
> +            okY = false;
> +          }
> +          double A = img_Lx_pix - b_X;
> +          double B = 1.0/m_X;
> +          for (int x = 0; x < iw; ++x) {
> +            bool okX = true;
> +            double new_x;
>              if (xLog) {
>                new_x = pow(xLogBase, (x + img_Lx_pix - b_X) / m_X);
>              } else {
> -              new_x = (x + img_Lx_pix - b_X) / m_X;
> +              new_x = (x + A)*B;
>              }
> -            if (yLog) {
> -              new_y = pow(yLogBase, (y + 1 + img_Ly_pix - b_Y) / m_Y);
> +            x_index = (int)((new_x - m_minX)*m_stepXr);
> +            double z = m->Z(x_index * m_numY + y_index);
> +
> +            okX = finite(z);
> +
> +            if (okX && okY) {
> +              scanLine[x] = _pal.rgb((int)(((z - _zLower) * palCountMin1_OverDZ)));
>              } else {
> -              new_y = (y + 1 + img_Ly_pix - b_Y) / m_Y;
> +              scanLine[x] = 0;
>              }
> -            thisPixel = image->getMappedColor(m, new_x, new_y);
> -            if (thisPixel.isValid()) {
> -              scanLine[x] = thisPixel.rgb();
>              }
>            }
> -        }
>          _imageLocation = QPoint(d2i(img_Lx_pix), d2i(img_Ly_pix + 1));
>        }
>  #ifdef BENCHMARK
> @@ -748,12 +769,12 @@
>  
>  
>  void Image::paintLegendSymbol(QPainter *p, const QRectF& bound) {
> -  if (hasColorMap() && !_pal.paletteData().isEmpty()) {
> +  if (hasColorMap() && (_pal.colorCount()>0)) {
>      int l = bound.left(), r = bound.right(), t = bound.top(), b = bound.bottom();
>      // draw the color palette
>      for (int i = l; i <= r; i++) {
> -      int index = (int)floor(static_cast<double>(((i - l) * (_pal.paletteData().count() - 1))) / (r - l));
> -      QColor sliceColor = _pal.paletteData().value(index).rgb();
> +      int index = (int)floor(static_cast<double>(((i - l) * (_pal.colorCount() - 1))) / (r - l));
> +      QColor sliceColor = _pal.color(index).rgb();
>        p->setPen(QPen(sliceColor, 1));
>        p->drawLine(i, t, i, b);
>      }
> --- branches/work/kst/portto4/kst/src/libkstmath/image.h #1170151:1170152
> @@ -51,7 +51,7 @@
>      virtual QString propertyString() const;
>  
>      virtual bool getNearestZ(double x, double y, double& z);
> -    virtual QColor getMappedColor(MatrixPtr m, double x, double y);
> +    virtual QColor getMappedColor(double z);
>      virtual void setPalette(const Palette &pal);
>      virtual void setUpperThreshold(double z);
>      virtual void setLowerThreshold(double z);
> --- branches/work/kst/portto4/kst/src/libkstmath/palette.cpp #1170151:1170152
> @@ -30,80 +30,65 @@
>                                        "#105010"
>                                        };
>  static const int KstColorsCount = sizeof(KstColors) / sizeof(char*);
> -
>  static const QString KstColorsName = "Kst Colors";
> +
> +static const int KstGrayscaleCount = 255;
>  static const QString KstGrayscaleName = "Kst Grayscale";
>  
> -
>  QStringList Palette::getPaletteList() { 
>    QStringList paletteList;
>  
> -  //TODO Populate a shared list of colors to return here.
>    paletteList.append(KstGrayscaleName);
>    paletteList.append(KstColorsName);
>  
> +  //TODO: support loading palettes from disk.
> +
>    return paletteList;
>  }
>  
> -Palette::Palette() {
> -  createPalette();
> +Palette::Palette(): _colors(0), _count(0) {
> +  changePaletteName(KstColorsName);
>  }
>  
>  
> -Palette::Palette(const QString &paletteName) {
> -  createPalette(paletteName);
> +Palette::Palette(const QString &paletteName): _colors(0), _count(0) {
> +  changePaletteName(paletteName);
>  }
>  
> -
>  Palette::~Palette() {
> +  delete[] _colors;
> +  delete[] _rgb;
> +  _colors = 0;
> +  _count = 0;
>  }
>  
> +void Palette::changePaletteName(const QString &paletteName) {
>  
> -QString Palette::paletteName() const {
> -  return _paletteName;
> +  if (_count==0) {
> +    _colors = new QColor[2048];
> +    _rgb = new QRgb[2048];
>  }
>  
> -  
> -int Palette::colorCount() const {
> -  return _count;
> -}
> -
> -PaletteData Palette::paletteData() const {
> -  return _palette;
> -}
> -
> -QColor Palette::color(const int colorId) const {
> -  return _palette[colorId];
> -}
> -
> -
> -void Palette::createPalette(const QString &paletteName) {
> -  //TODO Get Palette details from a palette name parameter when a shared list exists.
> -  _palette.clear();
>    if (paletteName.isEmpty()) {
>      _paletteName = KstColorsName;
>    } else {
> -    //TODO when a proper shared list exists, validate that the palette exists.
>      _paletteName = paletteName;
>    }
>  
>    if (_paletteName == KstColorsName) {
>      for (int i = 0; i < KstColorsCount; i++) {
> -      _palette.insert(i, QColor(KstColors[i]));
> +      _colors[i] = QColor(KstColors[i]);
> +      _rgb[i] = _colors[i].rgb();
>      }
> +    _count = KstColorsCount;
>    } else {
> -    for (int i = 0; i < 255; i++) {
> -      _palette.insert(i, QColor(i, i, i));
> +    for (int i = 0; i < KstGrayscaleCount; i++) {
> +      _colors[i] = QColor(i, i, i);
> +      _rgb[i] = _colors[i].rgb();
>      }
> +    _count = KstGrayscaleCount;
>    }
> -  _count = _palette.count();
>  }
>  
> -
> -void Palette::addColor(const QColor& color) {
> -  _palette.insert(_count, QColor(color));
> -  ++_count;
>  }
> -
> -}
>  // vim: ts=2 sw=2 et
> --- branches/work/kst/portto4/kst/src/libkstmath/palette.h #1170151:1170152
> @@ -1,13 +1,14 @@
> -/***************************************************************************
> +/*******************************************************************************
>   *                                                                         *
>   *   copyright : (C) 2007 The University of Toronto                        *
> + *   copyright : (C) 2010 C. Barth Netterfield <netterfield at astro.utoronto.ca> *
>   *                                                                         *
>   *   This program is free software; you can redistribute it and/or modify  *
>   *   it under the terms of the GNU General Public License as published by  *
>   *   the Free Software Foundation; either version 2 of the License, or     *
>   *   (at your option) any later version.                                   *
>   *                                                                         *
> - ***************************************************************************/
> + *******************************************************************************/
>  
>  #ifndef _PALETTE_H
>  #define _PALETTE_H
> @@ -20,25 +21,61 @@
>  
>  typedef QHash<int, QColor> PaletteData;
>  
> +const unsigned int maxColorTableSize = 2048;
> +
>  class KSTMATH_EXPORT Palette 
>  {
>    public:
> +    /**
> +     * @returns string list of avalible palettes
> +     */
>      static QStringList getPaletteList();
> +
>      Palette();
>      Palette(const QString &paletteName);
> +
>      virtual ~Palette();
>  
> -    void addColor(const QColor & color);
> +    void changePaletteName(const QString &paletteName);
> +    QString paletteName() const {return _paletteName;}
> +    int colorCount() const {return _count;}
>  
> -    QString paletteName() const;
> -    int colorCount() const;
> -    QColor color(const int colorId) const;
> -    PaletteData paletteData() const;
> +    /**
> +     * Returns the color corresponding to colorId.
> +     * It truncates to max or min _color if colorId is out
> +     * of bounds, so bounds checking is not necessary in the
> +     * calling function.
> +     * @returns the QColor
> +     */
> +    QColor color(const int colorId) const{
> +      if (colorId<0) {
> +        return _colors[0];
> +      } else if (colorId>=_count) {
> +        return _colors[_count-1];
> +      } else {
> +        return _colors[colorId];
> +      }
> +    }
> +    /**
> +     * Returns the rgb value for the color corresponding to colorId.
> +     * It truncates to max or min _rgb if colorId is out
> +     * of bounds, so bounds checking is not necessary in the
> +     * calling function.
> +     * @returns the QColor.rgb().
> +     */
> +    QRgb rgb(const int colorId) const{
> +      if (colorId<0) {
> +        return _rgb[0];
> +      } else if (colorId>=_count) {
> +        return _rgb[_count-1];
> +      } else {
> +        return _rgb[colorId];
> +      }
> +    }
>  
>    private:
> -    void createPalette(const QString &paletteName = QString());
> -
> -    PaletteData _palette;
> +    QColor *_colors;
> +    QRgb *_rgb;
>      QString _paletteName;
>      int _count;
>  };
> _______________________________________________
> Kst mailing list
> Kst at kde.org
> https://mail.kde.org/mailman/listinfo/kst
> 


More information about the Kst mailing list