To recap:
Robert Roessler wrote:
The caching is going well - it is reasonably straightforward to do, and
seems to be yielding good results. :)
So far, I have an efficient caching *mechanism* - fast, good
distribution, few collisions - and very low dynamic memory allocation /
fragmentation.
...
0) What is cached? Right pretty much anything, subject to a few
controls - max length of glyph fragments, total # of cached elements,
and possibly styles to include/exclude. This last, while allowing for
very selective control, is nasty in that it requires Scintilla client
software (e.g., SciTE) do some extra setup based on the lexer in use...
to test this, I currently [with the OCaml lexer] can just say to cache
elements with styles < 11 to ignore strings and comments.
1) While admittedly, NON-GTK implementations (i.e., Windows) do not
*need* this as much, I saw no reason to stuff this down into the
"platform" layer - so it is implemented in Editor.
2) Currently, because of the issues that prompted the creation of
"2-phase drawing" mode, it is simpler to have caching active in parallel
with "buffered" drawing, but disabled if "2-phase" drawing is enabled...
the 2-phase model *could* be used with caching, but then it will be
uglier for both generating pixmaps for caching AND using those pixmaps
when a cache hit occurs.
3) To allow synchronization at one critical point in cache management, I
would like to add locking as an operation visible in the platform
layer. While this *could* be done just be repackaging / formalizing the
existing platform-specific locking mechanisms in use, it might be better
to have both explicit "internal" (platform layer) locks to be used by
"platform" code, and a second "external" lock on each platform available
to non-platform-specific code (like in Editor).
4) While just caching glyph fragments (I am currently testing with
string lengths of 11 and 19) has done a lot for GTK (and even gives a
perceived gain to the Windows native case), I am still looking for
more... I will look at layout/rendering efficiency issues next.
I suppose I am back to being more than a little concerned with [GTK on
Windows] things like, I don't know, the fact that dropping the time for
width measurement to 0 and just doing rect fills in place of showing
text STILL doesn't even come close to the minuscule time taken by the
Windows native version... :(
I mean, what are these folks *doing* in the depths of the Win32
implementation of all things GTK? It also seems like they are not using
GdiPlus, which from my admittedly limited use of it, is blazingly fast
(vs the raw GDI calls model).
All right - here is some *code* for people to play with! :)
Basically, I am still pretty bummed with the performance of GTK on
Windows - doing searches, I find I am not alone (*especially* since
GTK 2 arrived on the scene)... but, c'est la free GUI toolkit! ;)
What I am making available is really fairly simple - one class is
defined near the front of Editor.cxx and its methods are invoked from
one spot in Editor::DrawLine - right when we are displaying a "normal"
line (but 2-phase drawing is turned OFF).
I had a version that also implemented the "2-phase" style rendering,
but the performance was less than impressive, so I removed it... I am
happy to get help from anyone who has ideas on how to make "stipple"
filling of full color pixmaps from monochrome bitmaps FAST. :)
Note that, as I said, this "all" happens in Editor.cxx - i.e., the
caching feature itself is not tied to a platform (although obviously
the lower-level implementations are). In addition, I added two
methods to the Platform class to give access to the already defined
locking mechanisms - so Platform.h, PlatGTK.cxx, and PlatWin.cxx also
get touched, although in minor ways (and I adjusted the GTK internal
mutex naming to bring it into line with the Windows version).
So, to try this, just grab the "ScintillaCaching.zip" file from
http://www.rftp.com/ScintillaCaching.zip
and expand into a current Scintilla source tree. For purposes of
evaluation and tweaking, the changes in Editor.cxx are surrounded by
"RBR_CACHE*" ifdefs. Within that, there are additional ifdefs,
primarily for selecting between hashing functions and a WINDOWS-only
display of cache statistics. As posted, the defaults are for caching
to be enabled when BUFFERED drawing is ENABLED (but TWO-PHASE drawing
is DISABLED), using a hash function from Paul Hsieh (a Bob Jenkins one
is included too), and NOT gathering or displaying the statistics.
I am especially interested to hear what users of Scintilla/SciTE in
GTK trim have to say about any performance boost... since it does good
things for GTK on Windows, and I am getting the strong suspicion that
the performance hit is in the GTK-to-Windows layer(s), this could do
very nice things for "pure" GTK.
If and when it seems like a good idea to integrate this with mainline
Scintilla, two "packaging" issues need to be examined: availability of
caching, in the sense of "does this replace BUFFERED drawing?", and
possible lexer-specific tuning, in the form of an API call for
enabling (or disabling) particular styles for caching (or not - I am
thinking of a simple bit-per-style# mask). Currently, everything that
is less than 12 characters *is* cached, up to 2048 entries (obviously,
the 12 and 2048 are configurable).
Finally, I have been using this code in both SciTE (well, in
SciLexer.dll), and my Objective Caml wrapping of Scintilla since last
week and not experiencing any ugliness - but remember, if *you* want
to try it, you will need to place a
two.phase.draw=0
into [presumably] your SciTEUser.properties file to enable caching in
SciTE. Good luck, and any and all feedback welcomed! :)
Robert Roessler
[EMAIL PROTECTED]
http://www.rftp.com
_______________________________________________
Scintilla-interest mailing list
[email protected]
http://mailman.lyra.org/mailman/listinfo/scintilla-interest