MASSIVE Mac OS X Performance Increase!


#1

AppConfig.h

#define USE_COREGRAPHICS_RENDERING 0

#2

I believe text rendering is faster on Mac when using the CoreGraphics renderer over the Juce Software Renderer. CoreGraphics probably has some sort of global font cache used across the entire OS.


#3

Half my application window is text and it was definitely faster with CoreGraphics off.


#4

Wow Vinn, you are right. I haven’t done specific profiling but activity monitor goes from 68% to 26% for me. Except the fonts are pretty rough looking now.


#5

What does the text rending look like in your application compared to CoreGraphics? The reason I use CoreGraphicsRendering is because text looks so much sharper and clearer. Are you using your freetype renderer? Does this improve things?

The other reason I use CoreGraphics is that downscaling images seems to be much clearer with less artifacts. Take a look at the image below from the dRowAudio demo. The top two are using a NativeImageType and the bottom is using a SoftwareImageType, there really is no comparison in the rescaling quality. It doesn’t appear to do any sub-pixel scaling, just averages the surrounding areas. Not sure if this is a bug or not but its pretty much unusable for my purposes at the moment.

[attachment=0]CoreGraphics vs Software ImageType.png[/attachment]


#6

Because CoreGraphics supports hinting, and Juce doesn’t. CoreGraphics might also use variations in RGB colours to create the illusion of subpixel coverage (called ClearType in Windows). Not sure if Apple uses that on OS X though, but I think its certain on iOS.

I use FreeType to get hinted outlines with the Juce renderer, its all in VFLib:

“FreeTypeFaces” is dual licensed, MIT and GPL (it was MIT licensed when originally posted in the JUCE forum).

Yeah predictably my text rendering looks perfect. It is pixel by pixel exactly the same as my Windows app, since I have embedded the font and I use FreeType to extract hinted outlines for each font height.

Actually it looks like “nearest neighbor”, with no interpolation at all. Try using Graphics::setInterpolationQuality (highResamplingQuality).


#7

I think that is with highResamplingQuality. Its medium in the CoreGraphics image and still looks great.

You can see for yourself in the JuceDemo. Select the “Tiled Images - RGB” rendering demo, set the size to something like 0.05 and make sure “Higher Image Interpolating” is on (when off it uses low, not medium). Switch between the Software and CoreGraphics renderer and you’ll see a blocky, artefact ridden image rather than the smooth image of CoreGraphics.

Cool, might have to check that out.


#8

Dave, the dRowAudio repository is a hot mess. This whole business of IntroJucer creating the junky “JuceLibraryCode” files with relative paths is a nightmare. Where exactly am I supposed to put “juce_source/JUCE”? I can’t figure it out, and I can’t get “Decks” to compile so I can see the differences in drawing.

Jules is partly to blame for this nightmarish system of locating the JUCE sources. That’s why I amalgamated JUCE in the first place, to make it EASY to distribute applications without requiring external dependencies or setups. If you look at any of my repositories (which all use JUCE) they are just clone/build/run:


https://github.com/vinniefalco/AppletJUCE

These all work right out of the box.

What the heck is this:

I don’t understand this at all…how is dRowAudio.h in JUCE?? How am I supposed to build?

// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../../../juce_source/juce/modules/dRowAudio/dRowAudio.h"

#9

[quote=“TheVinn”]I use FreeType to get hinted outlines with the Juce renderer, its all in VFLib:

https://github.com/vinniefalco/VFLib/tr … i/graphics

“FreeTypeFaces” is dual licensed, MIT and GPL (it was MIT licensed when originally posted in the JUCE forum).[/quote]

That’s super awesome Vinn. I’ll give it a shot. Thanks!


#10

I do appreciate its not as clean as it could be, I am in process of tidying it up but I am really waiting for a “THIS IS HOW YOU DESIGN NAD USE MODULES” guide from Jules. I know we have taken different approaches, you see modules as side companions to JUCE, I see then as any other juce_*** module so have designed mine to fit in with that system. For what its worth the module is getting rather bloated now so I may well adopt the scheme you have chosen.

Please, please ignore the Decks application (and in fact anything else in the repository that isn’t the module or the demo). I wrote those things years ago when I was studying so are incomplete, based on old versions of JUCE and are definitely not up to the standard of programming the module is. I had them in there originally as a nice way to keep all of my open source projects together but havent had time to work on them in a long time so will probably remove them soon.

In essence, to compile the demo you need to:

  1. pull the repository
  2. copy the dRowAudio module in to your juce/modules folder
  3. open the “dRowAudio Demo.jucer” project
  4. correct the “Local JUCE folder” path to point to your juce/modules folder
  5. save and build the project

I know that isn’t as elegant as your approach but I don’t really want to keep a copy of a JUCE amalgamation in each of my repositories which I have to update all the time. This may change in the near future however.


#11

Oh! So the waveform drawing isn’t in Decks?


#12

Moving this to a new post.


#13

No, its in the dRowAudio demo first “Audio Playback” tab. I did some work to the PositionalableWaveDisplay a couple of days ago so the pre-built may be slightly out of date. I’ve got some tinkering to do with the AudioThumbnailImage class and then I’ll update them both.

Because the image scaling is so bad on Windows it just uses the mono-chromatic waveform, not the colour-coded one as on Mac.


#14

I have the same kind of issue actually. I have exactly the same code for waveform rendering, and it looks awesome on OSX (like your first 2 rows) and ugly in Windows (like you bottom rows).
I tried the resamplingQuality setting in Graphics, but it doesn’t make a difference at all :frowning:

Does this mean that windows uses the SoftwareRenderer while OSX uses the CoreGraphics one ? Is there a way to improve the looks under windows ? Using direct2D maybe ? (although that would limit the app to users using at least windows vista :confused: )


#15

That is correct.

Implement a different scaling algorithm in the software renderer.

It is possible that Direct2D may have a better rescaling algorithm. The Direct2D renderer in Juce is near feature complete but needs a bit more work before it is usuable in the tip. You may however find its performance lacking.


#16

Mmmh I see. And have you,or someone else, tried opengl ? It might be à fast, good looking crossplatform solution and it’s already in Juce


#17

Here’s an image resampler suitable for reduction:

void linshrinkmap(
  int		 rows,
  int		 destCols,
  unsigned char* dest,
  int		 destRowBytes,
  int		 destColBytes,
  int		 srcCols,
  unsigned char* src,
  int		 srcRowBytes,
  int		 srcColBytes )
{
  int cols;

  srcRowBytes -=srcCols *srcColBytes;
  destRowBytes-=destCols*destColBytes;

  if( destCols!=srcCols )
  {
    int acc;

    unsigned long s, r, val;

    r=srcCols/2;
    while( rows-- )
    {
      acc=0;
      val=0;
      cols=srcCols;

      while( cols-- )
      {
        s= (unsigned long) *src;
        src+=srcColBytes;

        if( acc+destCols<srcCols )
        {
          acc+=destCols;
          val=val+s*destCols;
        }
        else
        {
          acc=srcCols-acc;
          val=val+s*acc;

          *dest=(unsigned char)((val+r)/srcCols);
          dest+=destColBytes;

          acc=destCols-acc;
          val=s*acc;
        }
      }

      src+=srcRowBytes;
      dest+=destRowBytes;
    }
  }
  else
  {
    while( rows-- )
    {
      cols=srcCols;

      while( cols-- )
      {
        *dest=*src;

        src+=srcColBytes;
        dest+=destColBytes;
      }

      src+=srcRowBytes;
      dest+=destRowBytes;
    }
  }
}

This routine shrinks one axis of one color channel of the image using all-integer linear downsampling. To shrink an image in both dimensions, call it first for all the rows and then for all the columns. You will need to adjust rows, cols, row bytes and col bytes appropriately. For color images, shrink all the channels first one axis then shrink all the channels again on the other axis.

The source and destination buffers cannot overlap in memory. It will be necessary to allocate a small temporary buffer to hold the intermediate results when shrinking in two dimensions, and you’ll want to intelligently choose which axis to shrink first, minimizing the total number of pixels accessed.

A trade-off can be made to reduce the amount of memory used in the temporary buffer in exchange for speed, by processing an axis in chunks. The least amount of temporary memory is used when rows == 1, then all you need is temporary buffer for a 1-dimensional image big enough to hold the larger of the destination dimensions (width or height).

The resampler uses linear interpolation with subpixel precision using a fractional equivalent of the Bresenham line drawing algorithm (the temporary variables hold accumulated subpixel portions). It would be difficult to come up with a faster algorithm without resorting to processor-specific instructions.


#18

 

 

 

WOW!!!! +++++11111!

 

This should be included with the damn Juce manual.  Serious increase in speed for me.

Thanks Vinn!


#19

Agreed, this should be on a more predominante place in the manual! Huge Speed increase, when I switched from core graphics renderer to software renderer. On JUCE 3.2.0. Mac Book from around 2008 running OSX 10.9.4.

My scenario: I was drawing and scrolling *lots* of small buttons, each representing one note in a Midi file.


#20

Be careful - this thread is VERY old! Hardware has changed since then - if you try using the software renderer on a retina display, you'll get horrible performance. OpenGL is currently the fastest choice on most platforms.