root
root copied to clipboard
[draft] [DO NOT MERGE] Introducing `TObject::PaintOn()` method
It will be central method to paint any primitive on specified pad.
To support all kinds of old implementations in TObject class Paint() method will be implemented as:
void TObject::Paint(Option_t *opt)
{
if (gPad)
PaintOn(gPad);
}
Main trick will be painting of pad primitives. There one can use semi-standard method to detect
if custom Paint() method implemented for the object. If yes - such old Paint() will be invoked.
if ((void *) (obj->*(&TObject::Paint)) != (void *) (&TObject::Paint))
obj->Paint(lnk->GetOption());
else
obj->PaintOn(this, lnk->GetOption());
If class converted into new scheme - Paint() method MUST be re removed and replaced by new PaintOn().
This is very important to support sub-classes of classes like TLine or TBox. TLine::PaintOn() implemented from very beginning, but SubClass::Paint() will exists. Calling scheme will be: SubClass::Paint() -> TObject::Paint() -> TLine::PaintOn()
Step-by-step in all ROOT classes one will implement PaintOn() methods - without breaking any existing code.
PR shows example with several "simple" classes how it can be done.
During ROOT code modifications graphics continues to work as before.
But contentiously usage of gPad will be reduced.
Main goal - gPad should not be touched when painting ROOT classes.
Only to support arbitrary user classes one will keep TObject::PaintOn() as shown.
After code conversion is completed, one can declare
special methods which are using gPad (like TLine::PaintLineNDC()) deprecated and
advertise use of new methods (like TLine::PaintLineNDCOn()).
Ultimate goal - painting of main ROOT classes do not touch gPad and thus will be really thread-safe.
Interactive methods (like moving stats box around) will still rely on gPad,
but this pointer will not be touched during any re-painting and will remain consistent.
Test Results
9 files 9 suites 2d 7h 33m 44s :stopwatch: 2 613 tests 2 612 :white_check_mark: 0 :zzz: 1 :x: 22 465 runs 22 456 :white_check_mark: 0 :zzz: 9 :x:
For more details on these failures, see this check.
Results for commit 33ec5ead.
:recycle: This comment has been updated with latest results.
There is problem with derived classes.
Once TLine::PaintOn() is overwritten, all derived classes should do the same - including users classes derived from TLine.
Suppose I have N threads creating M png files in batch. Will this work?
Suppose I have N threads creating M png files in batch. Will this work?
Yes, this is that I want to achieve.
But replacing gPad is first step.
Most critical point are gVirtualX and gVirtualPS instances which are same for all threads.
And therefore we need to make sure that concurrent calls from different threads are correct.