Skip to content

[experimental] modifying TVirtualX interface [DO NOT MERGE!]#21586

Draft
linev wants to merge 36 commits intoroot-project:masterfrom
linev:virtualx_attributes
Draft

[experimental] modifying TVirtualX interface [DO NOT MERGE!]#21586
linev wants to merge 36 commits intoroot-project:masterfrom
linev:virtualx_attributes

Conversation

@linev
Copy link
Member

@linev linev commented Mar 12, 2026

Current TVirtualX api is not thread safe.
There is no way to create several canvases and update them individually from different threads.
Main reason - several global X11 objects which are modified all the time during painting.
But already in the current implementation there is array of XWindow_t structures which is used to manage
widget-related data.

So idea to extend XWindow_t structure and put there all data which are relevant for widgets painting.
And then provide API methods where window id or directly XWindow_t pointer used as first argument.
So one can implement painting which in theory can be fully independent from other parallel actions.

This PR is the exercise if such transition is possible. It moves all attributes to XWindow_t structure and
provide all painting methods using these attributes. And this seems to be working!

Missing part is refactoring of TTF class. It is crucial for text drawing and currently has fully static interface - which does not allow multi-threaded usage. But there is no principal problem to solve this. Similar problem is code in Rotated.cxx - which used for text rotation.

PR made on top of #21485

linev added 30 commits March 12, 2026 14:12
Instead gPad use provided pad pointer in the DrawFillAreaAux.
Idea to have exactly same interface as TPadPainter,
but perform drawing on the TVirtualPS device.

Add extra OnPad(pad) virtual method which
specifies current pad which used for next commands
It replace pad painter by TPadPainterPS instance if
gVirtualPS is detected.
So PS painting can be done with pad painter API.
At the end of Paint/PaintModified methods previous instance will be reset
Do not use gVirtualPS directly
Speical handling of TVirtualX in TPad::PaintBox.
This method used for pad background painting and there
difference between gVirtualX and gVirtualPS is significant.
So keep two different handling of "native" (gVirtualX) and
not-native kind of TPadPainter.
Excludes duplication of box boundary painting when
fillstyle already 0. Appears in gmuiltierrors
So for both TVirtualX and TVirtualPS same code is used
Slight difference in borders width calculation while
before absolute pixel size was implemented in TVirtualPS
Create TSVG only after main canavas pad is selected with C->cd();
This important for size of created SVG image which ratio should
correspond to ratio of pad pixel size
All four signature are changed
Need to provide special virtual method.
Also supply default implementation
On the long run gVirtualPS should disappear
Similar to line, fill and text attributes while
markers also used in pad painting
It is now not really necessary while attributes
should be applied directly to pad painter
Now these methods act directly with actual pad painter to set attributes on device (gVirtualX or gVirtualPS) which is used.
ModifyOn allows to work with pad pointer from user code
While new methods add to TAttLine and TAttFill
`NewPage()` used only PS to start page

`IsCocoa()` let check if cocoa backend is used,
invoved in several places

`ResizeDrawable()` to change gVirtualX created pixmap

Provide `TGLPadPainter::ClearDrawable()` while now
pad painter API used in painting

Now gVirtualPS usage in TPad minimized only to
Print() method.
Only make sense when pad painter exists and has native funcitonality
Move from plain array to unordered_map.
So pointer on XWindow_t will not change if new window will be created later.
Idea to use this pointer later as main handle for graphics operation -
while using window id will costs locking of the mutex which need to be
introduced later for threads safety
First provide window context for each active window.
Window context should allow access per-window functionality fully independent from each other

As a first interfaces declare methods to change attributes.
So one can set different drawing attributes independently for each window.
Allows to use native X11 types without casting.
List of windows now defined as:
```
std::unordered_map<Int_t,std::unique_ptr<XWindow_t>> fWindows
```
In TCanvas::Feedback() method first select fCanvasID before
changing draw mode. Only becase of global GC attributes it was possible before.
If GC allocated per window - one should do it correctly
Only window-specific contexts are used
Remove unused method CopyWindowtoPixmap
So setting line/fill style to TGX11 will change attributes for
currently selected window.
Comment out most of members
Allocate marker attributes per window,
comment aout global gMarker structures
Where it make sense - use XDrawSegments for markerS
linev added 6 commits March 12, 2026 14:12
Without TTF support X11 fonts are used.
Move text attributes handling to XWindow_t structure,
keep only global gTextFont for text size handling.
Up to now font size was not scaled
One can add hook there to allocate and initialize there TTF structures.
For now keep global members
Last place was PutImage method - used either special window GC or just temporary created GC
PutImage is not used at all
Now only window-special contexts are used
Use when TGX11TTF instance must be created.
Copy constructor it too complicated.
@linev linev self-assigned this Mar 12, 2026
@linev linev marked this pull request as draft March 12, 2026 13:37
@github-actions
Copy link

Test Results

    22 files      22 suites   3d 3h 58m 24s ⏱️
 3 807 tests  3 804 ✅ 1 💤  2 ❌
75 792 runs  75 761 ✅ 9 💤 22 ❌

For more details on these failures, see this check.

Results for commit 77b2d76.

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.

1 participant