Device Context cache for Scintilla allows to significantly speed-up window refreshing and reduce CPU load in case of "external" paint requests, such as those resulting from AUI layout changes.
The cache works in a very simple way: in ScintillaWX::DoPaint() the output from Editor::Paint() is passed trough the DC cache (wxMemoryDC). From this moment, all paint events are serviced by simply blitting the requested rectangle from the cache, completely bypassing Scintilla' rendering stack. The content of of the cache is invalidated by "normal" editor events - such as keystrokes or scroll events.
To keep memory consumption at a reasonable level, caches are allocated only for active (visible) editors, and this is achieved in EditorManager::OnPageChanged(), which calls EditorBase::DropCaches()
Since I've tested this solution only on GTK3, it is enabled by default only for WXGTK3 or if CB_ENABLE_SCINTILLA_DC_CACHE is defined - for testing on other platforms.
Motivation:
I've observed (on GTK3) that every time the mouse starts and stops moving, CPU load jumps to over 60% (a 3.6GHz CPU).
It turned out that this is caused by scintilla - rendering area under scrollbars during fade-in/fade-out animations.
The DC cache reduced CPU load by ~85% - from 60% to 8% (on average) and AUI layout swiching is now much faster.
Good work, I will test it under Windows.
I'm not sure, but it looks like the new
devcontextcache.h
file should be put in some other place?I put the
devcontextcache.h
file under the folder:codeblocks_sfmirror\src\sdk\wxscintilla\include
, and the cpp file is put in the folder:codeblocks_sfmirror\src\sdk\wxscintilla\src
. So, the build continues.Hi,
I think the location is correct - it allows to use the cache for other widgets too (in the future). The problem is most likely with what goes to pre-compiled header or with include paths passed to GCC under MSW - I'll try to figure this out.
Meanwhile, I've discovered that the cache can't be used when window size is reduced and line wrapping is enabled (I never use this option). So here's a trivial fix: Editor::ChangeSize() must call SCI_DC_CACHE_INVALIDATE if wrapping needs to be updated (otherwise size changes can be cached)
Updated version 2 of the patch attached.
EDIT:
@ollydbg:
from src/sdk/makefile.am:
The compilation error suggest that for some reason GCC does not get the "-I$(top_srcdir)/src/include" option - but it is shared for all platforms - so it should work.
Last edit: Tomasz Pawlak 2025-10-13
Hi, thanks for the update.
From my point of view, I think your added two files devcontextcache.h and devcontextcache.cpp should be put in the SDK level,
Option 1: the header file should be put here:
src/include
and the cpp file should be put here:
src/sdk
Option 2: if it is only for the wxScintilla control, it should be put inside the folder:
src/sdk/wxscintilla/src
(for both cpp and header files).When I build C::B yesterday with your patch, I'm using the option 2, and I'm using the
src/CodeBlocks_wx33_64.workspace
under Windows.Another thing I see is that it looks like the file:
src/sdk/wxscintilla/src/scintilla/src/Editor.cxx
is a more general file, which means every portion of the scintilla should use this file, and the platform dependent file is under the foldersrc/sdk/wxscintilla/src
, not inside the core editor control foldersrc/sdk/wxscintilla/src/scintilla
.My question is: can you code change be only inside the platform dependent files?
Thanks.
Hi,
For the patch to work, it really doesn't matter which location is chosen - both options will work if compiler will get correct include paths.
Regarding Editor.cxx: there are 10 occurrences of SCI_DC_CACHE_INVALIDATE macro, which expands to void if the DC cache is not enabled.
However, while working on this patch I've changed Editor::Redraw():
to
I've changed this, because it hurts my eyes when I see a code which does completely nothing except wasting CPU cycles. Probably I should change it back or add a comment before creating the patch ;)
Do You wish to have a patch without Editor::Redraw() modification?
Here are my comments about the patch.
From my point of view, I think you should keep the scintilla's core code unchanged. So, here is my suggest:
I see you have made some changes to the file:
src/sdk/wxscintilla/src/scintilla/src/Editor.cxx
for example:
But I see the function
wMain.InvalidateRectangle(rc);
will go to the function inside the file:
sdk\wxscintilla\src\PlatWX.cpp
So, why not put the code inside the PlatWX.cpp?
By this method, I think all the code changes can be restricted in the platform code, that is the code
Any ideas?
Thanks.
Hi,
The problem is that Window::InvalidateRectangle() operates on wxWindow base class, so it can't access Editor methods/members. -> crash.
Meanwhile, I've found and fixed 2 BUGs in DC cache implementation:
- Disassembly dialog did not invalidated the cache (no editor events) - so it was not updated.
- Incorrect handling of "abandoned" paints -> brace and occurrences highlighting did not always updated the editor.
Moreover, I've changed the cache logic by introducing SCI_DC_CACHE_TRIM_ARENA - it's now possible to use cached repaints for almost 100% of "manual" resize events.
Version 3 of the patch attached.
I'm not fully understand this sentence.
I see in your patch:
I'm not sure why the
DCcache
variable should be put inside theEditor
class, can this be put in the derived wxWidgets related class?And what does the
crash
here mean?All what I expect is the those scintilla core classes should not have any wxWidgets related code, that is, it should be more general code for all platforms, and the derived classes are for any platforms, such as the wxWidgets platforms.
Hi,
During early testing of this patch I've tried to up-cast 'wid' in Window::InvalidateRectangle() to wxScintilla, but that caused random crashes - so I've assumed that there must some other object derived from wxWindow which also uses the generic Window class.
Today I've confirmed that this is not the case - and the crashes were most likely a result of broken incremental build.
So, here's v4 of the patch, which accordingly to Your requirements does not touch the core Editor class - please check if this version is OK for You.
Last edit: Tomasz Pawlak 4 days ago
Thanks for your work, I will test your v4 patch under my Windows system as soon as possible.
This is the patch file I used to test the Windows (wx 3.3) build of C::B. I have enabled the
__WXWIN__
option.The result C::B looks OK, I don't see much difference(cpu usage) when i scroll the editor window.