up to 20% faster

177 views
Skip to first unread message

Andre Höpfner

unread,
Jun 11, 2013, 8:48:14 AM6/11/13
to mapsfo...@googlegroups.com

Hallo,

Actually, I was just looking for some display problems and I have found a little bit performance.


But from the beginning!
I was looking for my problem with the tile border and have noticed that here the default values ​​are set in Area Builder on black.

 

public AreaBuilder(GraphicFactory graphicFactory, String elementName, Attributes attributes, int level,

 

                 
String relativePathPrefix) throws IOException, SAXException {

         
this.level = level;

 

         
this.fill = graphicFactory.createPaint();

         
this.fill.setColor(Color.TRANSPARENT); //Change from BLACK to TRANSPARENT

         
this.fill.setStyle(Style.FILL);

         
this.fill.setStrokeCap(Cap.ROUND);

 

         
this.stroke = graphicFactory.createPaint();

         
this.stroke.setColor(Color.TRANSPARENT); //Change from BLACK to TRANSPARENT

         
this.stroke.setStyle(Style.STROKE);

         
this.stroke.setStrokeCap(Cap.ROUND);

 

          extractValues
(graphicFactory, elementName, attributes, relativePathPrefix);

   
}


 

But if there is no value in the theme of this, of course, Black was then taken. So I put it to the test on transparent and my problem was solved. Also the reported problem of emux  => https://groups.google.com/forum/?fromgroups#!topic/mapsforge-dev/8o7TmLvn2jY was solved.

 

Then I asked myself why a transparent color must be drawn at all and have Prevents this. The result is a performance improvement of ~20%

 

(

What I have noticed in several tests on Android and AWT

·         Before changes tile generation at ~600ms, after changes ~500ms on Android

·         Before changes tile generation at ~80ms, after changes ~70ms on Android

)

The changes that I have made ​​here are not very serious.
So that can be queried on a transparency in the canvas, I extended the Paint interface.

 

public interface Paint {

 

   

   
boolean isTransparent();

     
....


And of course the two derived classes for Android and AWT

 

AwtPaint:

   @Override
   
public boolean isTransparent() {

   
return this.color.getAlpha()==0;

   
}


   AndroidPaint:

   @Override
   
public boolean isTransparent() {

   
return this.paint. getAlpha()==0;

   
}


 

 

So then a transparent color is not drawn, I have in all canvas methods, in which is passed Paint, I use a query off transparency and I left the method.

 

@Override

 

       
public void drawLine(int x1, int y1, int x2, int y2, Paint paint) {

             
if(paint.isTransparent())return;

 


I hope that you still feed this changes and I have not overlooked anything.

I have committed this to my clone wwwlongride-cachebox

 

Greeting Andre

Ludwig

unread,
Jun 14, 2013, 3:01:06 AM6/14/13
to mapsfo...@googlegroups.com
Hi there,

I have tried this out and indeed this seems to run a bit faster (the 20% is perhaps about accurate) without any impact on the map being drawn.

The proposed changes trigger a test failure in AwtPaint, but I think this failure should be fixed by initializing the color in the ctor.

    AwtPaint() {
        this.cap = getCap(Cap.ROUND);
        this.style = Style.FILL;
        this.color = AwtGraphicFactory.getColor(Color.TRANSPARENT);
    }

I would suggest that this be integrated into the rewrite branch (with minor adaption to the project's style).

Ludwig



--
You received this message because you are subscribed to the Google Groups "mapsforge-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapsforge-de...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

emux

unread,
Jun 14, 2013, 3:32:45 AM6/14/13
to mapsfo...@googlegroups.com
Thanks Andre,

This is indeed the cause of the issue I reported.
There is a change at stroke paint's color (from transparent to black) at AreaBuilder between main and rewrite branch.

Regards.

Andre Höpfner

unread,
Jun 14, 2013, 4:21:30 AM6/14/13
to mapsfo...@googlegroups.com

I have also the TestFailer and I fixed with chk NPE on Paint.IsTransparent()

       @Override

       
public boolean isTransparent() {

             
if(this.color==null)return true;

             
return this.color.getAlpha()==0;

       
}


 

I think this chk is safer!

Thilo Mühlberg

unread,
Jun 16, 2013, 2:02:53 PM6/16/13
to mapsfo...@googlegroups.com
Hi Andre,

thank you for sharing the results of your investigation and the code
snippets with us. I just integrated them into the rewrite branch.

Rather than adding a null-check to the AwtPaint.isTransparent() class I
prefer defining a default color in the Paint interface and initialize
the color variable in the AwtPaint class accordingly (Ludwig's idea). I
think that black is the best choice here, I guess this is what most
developers would expect from a drawing API. Does anybody disagree?

Greetings,
Thilo
signature.asc

Andre Höpfner

unread,
Jun 16, 2013, 2:21:32 PM6/16/13
to mapsfo...@googlegroups.com
Yes, then black caused a representation error, as it is described by emux to an area with the black outline.

I think if an area is to be outlined in black, then that should be declared in the theme. If something is not declared in the theme, then it should also not be drawn unexpectedly.

That is the reason why I would choose transparent as the default.

Greeting Andre

Thilo Mühlberg

unread,
Jun 16, 2013, 5:28:13 PM6/16/13
to mapsfo...@googlegroups.com
I think there is a misunderstanding here. You are talking about the
default stroke of areas, which is defined in the renderTheme.xsd file as
transparent and now also correctly implemented in the AreaBuilder.
Unless you specify a different color, area strokes will be transparent.

What I meant was the default color of a newly created AwtPaint or
AndroidPaint instance. Assume you have written a custom layer where you
draw lines or circles using the new mapsforge drawing API from the
rewrite branch. I suggested to use black as the default color, which
should be mentioned in the Javadoc comment of the setColor() method.

Greetings,
Thilo
signature.asc

Andre Höpfner

unread,
Jun 17, 2013, 3:12:07 PM6/17/13
to mapsfo...@googlegroups.com

Ok, now I understand and that’s ok for me.

Thanks!

Andre Höpfner

unread,
Jun 18, 2013, 4:33:55 AM6/18/13
to mapsfo...@googlegroups.com
Oh sorry, I have found a big problem with my code.
When a Paint have a texture then is the Paint not Transparent.
I will check more and explain later!

Sorry!

Andre Höpfner

unread,
Jun 18, 2013, 8:56:58 AM6/18/13
to mapsfo...@googlegroups.com

I wondered why the areas are no longer filled with the bitmaps from the pattern here and have found that the Paint have a color and a texture.

So if a paint contains a texture, then this should also be drawn, even if the color is transparent.

I have reached this in the queried of isTransparent!

For AwtPaint


      @Override

       public boolean isTransparent() {

             return this.texturePaint==null && this.color.getAlpha()==0;

      }


 

For AndroidPaint

       @Override

       public boolean isTransparent() {

             return this.paint.getShader()==null && this.paint.getAlpha()==0;

      }

There is for Android, but still a problem when the android.graphics.Paint has a transparent color, but a shader, it is not drawn here.
This then helps only put one color in AndroidPaint.setBitmapShader ()

@Override

       public void setBitmapShader(org.mapsforge.core.graphics.Bitmap bitmap) {

             if (bitmap == null) {

                    return;

             }

 

             this.paint

                           .setShader(new BitmapShader(AndroidGraphicFactory.getBitmap(bitmap), TileMode.REPEAT, TileMode.REPEAT));

             this.paint.setColor(android.graphics.Color.BLACK);

      }

 

 

 

 

Thus, I longed for the performance gain is not as big though, but still 4%!

 

It was also no surprise that there is a performance increase if nothing is drawn.

 

Sorry again!

 

Greeting Andre

Ludwig

unread,
Jun 19, 2013, 9:30:57 AM6/19/13
to mapsfo...@googlegroups.com
I guess we all looked at what we wanted to see and were dazzled with the performance gain (we now know where it comes from, mapsforge could be even faster by not drawing anything at all!).

But even though this appears at first as an epic failure of testing, it also shows that problems like this get discovered and fixed very quickly in an open source project. As this is not a moonshot project (with a single chance to get everything right), integrating community suggestions early increases their exposure and will shake out problems by having more people look at it. If you had not spotted this yourself, someone else would have very soon.

A few per cent performance gain is still not bad for such a simple change.

Ludwig



 

Greeting Andre

--

Thilo Mühlberg

unread,
Jun 22, 2013, 11:44:09 AM6/22/13
to mapsfo...@googlegroups.com
For the record: I just integrated the fixes for the two isTransparent()
implementations in the rewrite branch and pushed the change to our Git
repository. Thanks Andre for reporting this bug.

Greetings,
Thilo

On 19/06/13 15:30, Ludwig wrote:
> I guess we all looked at what we wanted to see and were dazzled with the
> performance gain (we now know where it comes from, mapsforge could be
> even faster by not drawing anything at all!).
>
> But even though this appears at first as an epic failure of testing, it
> also shows that problems like this get discovered and fixed very quickly
> in an open source project. As this is not a moonshot project (with a
> single chance to get everything right), integrating community
> suggestions early increases their exposure and will shake out problems
> by having more people look at it. If you had not spotted this yourself,
> someone else would have very soon.
>
> A few per cent performance gain is still not bad for such a simple change.
>
> Ludwig
>
>
>
> On 18 June 2013 20:56, Andre Höpfner <www.lo...@googlemail.com
> <mailto:www.lo...@googlemail.com>> wrote:
>
> I wonderedwhy the areas are no longer filled with the bitmaps from
> the pattern here and have found that the Paint have a color and a
> texture.
>
> So ifa paint contains a texture, then this should also be drawn,
> even if the color is transparent.
>
> I have reached this in the queried of isTransparent!
>
> For AwtPaint
>
>
> @Override
>
> *public**boolean*isTransparent() {
>
> *return**this*.texturePaint==*null*&&
> *this*.color.getAlpha()==0;
>
> }
>
>
>
>
> For AndroidPaint
>
> @Override
>
> *public**boolean*isTransparent() {
>
> *return**this*.paint.getShader()==*null*&&
> *this*.paint.getAlpha()==0;
>
> }
>
> There isfor Android, but still a problem when the
> android.graphics.Paint has a transparent color, but a shader, it is
> not drawn here.
> This then helps only put one color in AndroidPaint.setBitmapShader ()
>
> @Override
>
>
> *public**void*setBitmapShader(org.mapsforge.core.graphics.Bitmap
> bitmap) {
>
> *if*(bitmap == *null*) {
>
> *return*;
>
> }
>
>
>
> *this*.paint
>
>
> .setShader(*new*BitmapShader(AndroidGraphicFactory./getBitmap/(bitmap),
> TileMode./REPEAT/, TileMode./REPEAT/));
>
> *this*.paint.setColor(android.graphics.Color./BLACK/);
>
> }
>
>
>
>
>
>
>
>
>
> Thus, I longed for the performance gain is not as big though, but
> still 4%!
>
>
>
> It was also no surprise that there is a performance increase if
> nothing is drawn.
>
>
>
> Sorry again!
>
>
>
> Greeting Andre
>
> --
> You received this message because you are subscribed to the Google
> Groups "mapsforge-dev" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to mapsforge-de...@googlegroups.com
> <mailto:mapsforge-dev%2Bunsu...@googlegroups.com>.
signature.asc
Reply all
Reply to author
Forward
0 new messages