Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[draft] [DO NOT MERGE] Introducing TObject::PaintOn() method #15937

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

linev
Copy link
Member

@linev linev commented Jun 27, 2024

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.

Copy link

github-actions bot commented Jun 27, 2024

Test Results

     9 files       9 suites   2d 7h 33m 44s ⏱️
 2 613 tests  2 612 ✅ 0 💤 1 ❌
22 465 runs  22 456 ✅ 0 💤 9 ❌

For more details on these failures, see this check.

Results for commit 33ec5ea.

♻️ This comment has been updated with latest results.

@linev
Copy link
Member Author

linev commented Jun 27, 2024

There is problem with derived classes.
Once TLine::PaintOn() is overwritten, all derived classes should do the same - including users classes derived from TLine.

@dpiparo
Copy link
Member

dpiparo commented Jun 27, 2024

Suppose I have N threads creating M png files in batch. Will this work?

@linev
Copy link
Member Author

linev commented Jun 27, 2024

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.

This is new method for object painting.
One should invoke respective methods of pad to paint
lines, text, circles to represent object graphically.
To add object to the pad or canvas, one should use TPad::Add() method.
For backward compatibility old Paint() method is invoked when this method not implemented
@linev linev marked this pull request as draft June 28, 2024 09:19
@linev linev changed the title [draft] Introducing TObject::PaintOn() method [draft] [DO NOT MERGE] Introducing TObject::PaintOn() method Jun 28, 2024
linev added 12 commits June 28, 2024 13:32
It is central place where it should be used
If custom Paint method still exists in the class -
it will be invoked to keep backward compatibility

GCC allows direct check of virtual method pointer,

For all other compilers use type_info and TClass.
For ROOT classes with existing dictionaries we
can define if custom Paint exists or not.
For user classes - only with existing dictionary
and no Paint in list of methods - PaintOn will be used

Such workaround can be removed after two ROOT major
releases when Paint is declared as depricted.
Directly draw on provided pad, no need to use gPad
Keep support of extra public methods for painting
linev added 2 commits July 8, 2024 09:17
Use in all internal methods pad as first argument
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants