KiCad PCB EDA Suite
Loading...
Searching...
No Matches
class_draw_panel_gal.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013-2018 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 * @author Maciej Suminski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#ifndef PANELGAL_WXSTRUCT_H
25#define PANELGAL_WXSTRUCT_H
26
27#include <wx/window.h>
28#include <wx/timer.h>
29#include <wx/grid.h> // needed for MSVC to see wxScrolledCanvas indirectly exported
30#include <math/box2.h>
31#include <math/vector2d.h>
32#include <view/automatic_fit.h>
33#include <widgets/msgpanel.h>
34#include <rhi/frame_packet.h>
35#include <rhi/rhi_surface.h>
36#include <atomic>
37#include <memory>
38#include <optional>
39#include <mutex>
40#include <chrono>
41
42#include <gal/cursors.h>
43
44class BOARD;
45class EDA_DRAW_FRAME;
46class TOOL_DISPATCHER;
47class PROF_COUNTER;
48class wxImage;
49
50namespace KIPLATFORM
51{
52namespace UI
53{
55}
56}
57
58namespace KIGFX
59{
60class GAL;
61class FRAME_MAILBOX;
62class RENDER_THREAD;
63class RHI_DEVICE_PROXY;
64class SWAPCHAIN_CONTROLLER;
65class VIEW;
66class WX_VIEW_CONTROLS;
67class VIEW_CONTROLS;
68class PAINTER;
69class GAL_DISPLAY_OPTIONS;
70class VIEW_OVERLAY;
71struct VC_SETTINGS;
72}
73
74
75class EDA_DRAW_PANEL_GAL : public wxScrolledCanvas
76{
77public:
86
87#ifdef __WXMAC__
88 // Cairo doesn't work on OSX so we really have no fallback available.
89 static constexpr GAL_TYPE GAL_FALLBACK = GAL_TYPE_OPENGL;
90#else
92#endif
94
108 EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
109 const wxPoint& aPosition, const wxSize& aSize,
111 GAL_TYPE aGalType = GAL_TYPE_OPENGL );
113
114 void SetFocus() override;
115
117 {
118 return m_statusPopup && m_statusPopup->HasFocus();
119 }
120
121 void SetStatusPopup( wxWindow* aPopup )
122 {
123 m_statusPopup = aPopup;
124 }
125
137 static GAL_TYPE ResolveStoredCanvasType( int aStoredCanvasType );
138
146 static GAL_TYPE CanvasAfterFailure( GAL_TYPE aFailedCanvasType );
147
151 static bool IsAccelerated( GAL_TYPE aCanvasType )
152 {
153 return aCanvasType == GAL_TYPE_OPENGL || aCanvasType == GAL_TYPE_MODERN;
154 }
155
161 virtual bool SwitchBackend( GAL_TYPE aGalType );
162
167
171 inline GAL_TYPE GetBackend() const { return m_backend; }
172
178 KIGFX::GAL* GetGAL() const { return m_gal; }
179
185 virtual KIGFX::VIEW* GetView() const { return m_view; }
186
196
203 bool GetScreenshot( wxImage& aDstImage );
204
208 virtual void Refresh( bool aEraseBackground = true, const wxRect* aRect = nullptr ) override;
209
213 void ForceRefresh();
214
218 void RequestRefresh();
219
226
238 void ResizeGal( bool aForce = false );
239
243 static int ScreenSizePad( GAL_TYPE aBackend );
244
253 void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher );
254
258 void StartDrawing();
259
264 void StopDrawing();
265
269 virtual void SetHighContrastLayer( int aLayer );
270
274 virtual void SetTopLayer( int aLayer );
275
276 virtual void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
277 {
278 wxASSERT( false );
279 }
280
285
286 bool IsDialogPreview() const { return m_parent != (wxWindow*) m_edaFrame; }
287
292 virtual void OnShow();
293
300 void SetStealsFocus( bool aStealsFocus ) { m_stealsFocus = aStealsFocus; }
301
305 void SetCurrentCursor( KICURSOR aCursor );
306
313 virtual BOX2I GetDefaultViewBBox() const { return BOX2I(); }
314
322 void ZoomToFit( const BOX2I& aBox, std::optional<double> aMarginScale = std::nullopt );
323
327 void OnEvent( wxEvent& aEvent );
328
333 static void NoteInput();
334
344 bool DoRePaint( bool aAllowSkip = true );
345
349 std::shared_ptr<KIGFX::VIEW_OVERLAY> DebugOverlay();
350
351
355 void ClearDebugOverlay();
356
357
362
369
370 std::unique_ptr<PROF_COUNTER> m_PaintEventCounter;
371
376 virtual void prepareGridSources() {}
377
382 virtual void beforeRedraw() {}
383
384protected:
385 virtual void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
386 void onSize( wxSizeEvent& aEvent );
387 void onEnter( wxMouseEvent& aEvent );
388 void onLostFocus( wxFocusEvent& aEvent );
389 void onIdle( wxIdleEvent& aEvent );
390 void onRefreshTimer( wxTimerEvent& aEvent );
391 void onShowEvent( wxShowEvent& aEvent );
392
393 bool recoverFromGalError( const std::exception& aErr );
394
398 float displayRefreshRate();
399
405 bool handleContextLoss();
406
413 void showMessageLater( const wxString& aTitle, const wxString& aDetail, bool aError );
414
419 bool abandonRhiCanvas( const wxString& aDetail );
420
426
433
438 void presentFrame();
439
443 wxSize backendScreenSize() const;
444
448 void submitCachedScene();
449
450 wxWindow* m_parent;
452
453 std::chrono::steady_clock::time_point m_lastRepaintStart;
454 std::chrono::steady_clock::time_point m_lastRepaintEnd;
456
457 std::mutex m_refreshMutex;
458
461
464
467
469 bool m_refreshDeferred = false;
470
473
476
479
481 std::unique_ptr<KIGFX::PAINTER> m_painter;
482
485
489
492
496
499
502
505
508
511
514
518
519 wxWindow* m_statusPopup;
520
522 std::shared_ptr<KIGFX::RENDER_THREAD> m_renderThread;
523
525 std::unique_ptr<KIGFX::RHI_DEVICE_PROXY> m_deviceProxy;
526
527 std::unique_ptr<KIGFX::SWAPCHAIN_CONTROLLER> m_swapchainCtrl;
528
530 std::unique_ptr<KIGFX::FRAME_MAILBOX> m_frameMailbox;
531
533 uint32_t m_windowId = 0;
534
537
544
546 float m_refreshRate = 0.0f;
547 std::chrono::steady_clock::time_point m_refreshRateAsked;
548
553
555 uint64_t m_staticEpoch = 1;
556 uint64_t m_dynamicEpoch = 1;
557
560
562 std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
563
564 std::unique_ptr<KIPLATFORM::UI::TOUCHPAD_GESTURE_HANDLER> m_touchpadGestureHandler;
565};
566
567#endif
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
The base class for create windows for drawing purpose.
std::unique_ptr< PROF_COUNTER > m_PaintEventCounter
EDA_DRAW_FRAME * m_edaFrame
Parent EDA_DRAW_FRAME (if available)
virtual void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
static GAL_TYPE CanvasAfterFailure(GAL_TYPE aFailedCanvasType)
Return the canvas that takes over from one that could not be used.
virtual void OnShow()
Called when the window is shown for the first time.
void onLostFocus(wxFocusEvent &aEvent)
static constexpr GAL_TYPE GAL_FALLBACK
std::unique_ptr< KIGFX::PAINTER > m_painter
Contains information about how to draw items using GAL.
RHI_NATIVE_WINDOW_HANDLE m_cachedNativeHandle
Fetching the handle forces a display-server flush, so it is cached between realizations and fetched a...
bool m_rebuiltAfterReset
The GAL was rebuilt after a GPU reset and has not completed a frame yet.
void onSize(wxSizeEvent &aEvent)
bool m_pendingResize
Set when a size change could not be applied because the GL context was unavailable.
bool m_needIdleRefresh
True when canvas needs to be refreshed from idle handler.
GAL_TYPE GetBackend() const
Return the type of backend currently used by GAL canvas.
std::unique_ptr< KIGFX::SWAPCHAIN_CONTROLLER > m_swapchainCtrl
bool abandonRhiCanvas(const wxString &aDetail)
Leave the RHI canvas for GAL_FALLBACK after its device could not be created or restored.
virtual void SetHighContrastLayer(int aLayer)
Take care of display settings for the given layer to be displayed in high contrast mode.
int m_overlayInsetTop
Rows at the top of the panel left to the infobars where the backend window would hide them.
bool m_stealsFocus
Flag to indicate whether the panel should take focus at certain times (when moused over,...
virtual BOX2I GetDefaultViewBBox() const
Return the bounding box of the view that should be used if model is not valid.
KIGFX::GAL_DISPLAY_OPTIONS & m_options
void StopDrawing()
Prevent the GAL canvas from further drawing until it is recreated or StartDrawing() is called.
KIGFX::RHI_LINE_PIPELINE_KIND m_linePipelineKind
Fixed in the constructor from the parent frame's editor.
static KIGFX::VC_SETTINGS GetVcSettings()
Gets a populated View Controls settings object dervived from our program settings.
static void NoteInput()
Count an input so the frame that answers it is never held back by the display-rate limit.
std::unique_ptr< KIGFX::FRAME_MAILBOX > m_frameMailbox
Delivers frame packets to the render thread.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Return a pointer to the KIGFX::VIEW_CONTROLS instance used in the panel.
virtual void SetTopLayer(int aLayer)
Move the selected layer to the top, so it is displayed above all others.
KIGFX::FRAME_DRAW_DESC m_lastFullStaticDesc
Draw descriptors of the last full redraw, reused by frames that need no new geometry.
void presentFrame()
Present the most recently submitted frame packet.
void ClearDebugOverlay()
Clear the contents of the debug overlay and removes it from the VIEW.
virtual KIGFX::VIEW * GetView() const
Return a pointer to the KIGFX::VIEW instance used in the panel.
static int ScreenSizePad(GAL_TYPE aBackend)
Return how many pixels larger than the client area a backend's GAL is made.
void ForceRefresh()
Force a redraw.
bool recoverFromGalError(const std::exception &aErr)
void ResizeGal(bool aForce=false)
Resize the GAL to the current client size of this panel.
bool m_drawing
True if GAL is currently redrawing the view.
KIGFX::GAL * m_gal
Interface for drawing objects on a 2D-surface.
EDA_DRAW_PANEL_GAL(wxWindow *aParentWindow, wxWindowID aWindowId, const wxPoint &aPosition, const wxSize &aSize, KIGFX::GAL_DISPLAY_OPTIONS &aOptions, GAL_TYPE aGalType=GAL_TYPE_OPENGL)
Create a drawing panel that is contained inside aParentWindow.
std::chrono::steady_clock::time_point m_lastRepaintStart
Timestamp of the last repaint start.
void onRefreshTimer(wxTimerEvent &aEvent)
float displayRefreshRate()
Refresh rate in Hz of the display showing the canvas, or 0 when unknown.
void releaseCachedNativeWindowHandle()
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
virtual void onPaint(wxPaintEvent &WXUNUSED(aEvent))
bool m_lostFocus
Flag to indicate that focus should be regained on the next mouse event.
std::unique_ptr< KIGFX::RHI_DEVICE_PROXY > m_deviceProxy
The UI thread's access to the device.
static bool IsAccelerated(GAL_TYPE aCanvasType)
True for a canvas drawn on the GPU, which keeps cached layers between frames.
wxSize backendScreenSize() const
The padded size of the backend window, which sits below the top overlay inset.
std::chrono::steady_clock::time_point m_lastRepaintEnd
Timestamp of the last repaint end.
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_debugOverlay
Optional overlay for drawing transient debug objects.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
bool m_needsExternalRenderingSetup
True until the first paint completes the deferred GTK drawing suppression.
wxTimer m_refreshTimer
Timer to prevent too-frequent refreshing.
TOOL_DISPATCHER * m_eventDispatcher
Processes and forwards events to tools.
wxWindow * m_parent
Pointer to the parent window.
@ GAL_TYPE_LAST
Sentinel, do not use as a parameter.
@ GAL_TYPE_UNKNOWN
not specified: a GAL engine must be set by the client
@ GAL_TYPE_OPENGL
OpenGL implementation.
@ GAL_TYPE_MODERN
RHI implementation, Vulkan or Metal on macOS.
@ GAL_TYPE_CAIRO
Cairo implementation.
@ GAL_TYPE_NONE
GAL not used (the legacy wxDC engine is used)
virtual void beforeRedraw()
Hook for subclasses to update view items whose inputs nothing else tracks.
KIGFX::FRAME_DRAW_DESC m_lastFullDynamicDesc
void teardownModernRenderInfra()
Stop the RHI render thread and release its swapchain, mailbox and buffers.
virtual void prepareGridSources()
Hook for subclasses to push per-frame grid sources onto the GAL.
KIGFX::VIEW * m_view
Stores view settings (scale, center, etc.) and items to be drawn.
bool m_MouseCapturedLost
used on wxMSW: true after a wxEVT_MOUSE_CAPTURE_LOST was received false after the mouse is recaptured...
KIGFX::WX_VIEW_CONTROLS * m_viewControls
Control for VIEW (moving, zooming, etc.)
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
const RHI_NATIVE_WINDOW_HANDLE & getCachedNativeWindowHandle()
Return the native window handle for RHI surface creation, or an invalid handle until the window is re...
void SetFocus() override
void onIdle(wxIdleEvent &aEvent)
void UpdateTouchpadGestureHandler()
Apply the current native touchpad gesture preference to the active backend window.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
void UpdateOverlayExclusions()
Tell the backend which areas of this panel are covered by an overlaid infobar.
float m_refreshRate
What displayRefreshRate() last asked the window system.
void onEnter(wxMouseEvent &aEvent)
void submitCachedScene()
Submit the last full scene again with the current camera and cursor, keeping all targets.
uint32_t m_windowId
Routes this window's work on the render thread.
void SetStatusPopup(wxWindow *aPopup)
void showMessageLater(const wxString &aTitle, const wxString &aDetail, bool aError)
Show a recovery message once the current event finishes.
std::unique_ptr< KIPLATFORM::UI::TOUCHPAD_GESTURE_HANDLER > m_touchpadGestureHandler
uint64_t m_staticEpoch
Content generations of the static and dynamic pools last submitted, see FRAME_PACKET.
void RequestRefresh()
Make sure a refresh gets done on the next idle event if it hasn't already.
int m_contextBindFailures
Consecutive frames dropped because the GL context could not be made current.
std::shared_ptr< KIGFX::RENDER_THREAD > m_renderThread
The render thread that owns the RHI device, shared by every canvas, see GAL_MODERN::AcquireRenderThre...
std::mutex m_refreshMutex
Blocks multiple calls to the draw.
virtual bool SwitchBackend(GAL_TYPE aGalType)
Switch method of rendering graphics.
void StartDrawing()
Begin drawing if it was stopped previously.
static GAL_TYPE ResolveStoredCanvasType(int aStoredCanvasType)
Convert a stored canvas type setting into a backend that can actually be used.
bool DoRePaint(bool aAllowSkip=true)
Repaint the canvas, and fix scrollbar cursors.
void OnEvent(wxEvent &aEvent)
Used to forward events to the canvas from popups, etc.
bool m_recoveryAttempted
Set after a GPU recovery attempt to prevent infinite retry loops.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
bool m_drawingEnabled
Flag that determines if VIEW may use GAL for redrawing the screen.
std::shared_ptr< KIGFX::VIEW_OVERLAY > DebugOverlay()
Create an overlay for rendering debug graphics.
KIGFX::AUTOMATIC_FIT m_automaticFit
What the last ZoomToFit() left, refitted on a resize until the view is zoomed or panned.
void onShowEvent(wxShowEvent &aEvent)
bool handleContextLoss()
Replace a GAL whose context was destroyed by a GPU reset.
static constexpr bool GAL_FALLBACK_AVAILABLE
GAL_TYPE m_backend
Currently used GAL.
std::chrono::steady_clock::time_point m_refreshRateAsked
void ZoomToFit(const BOX2I &aBox, std::optional< double > aMarginScale=std::nullopt)
Scale and centre the view on aBox, and fit it again whenever the canvas changes size until something ...
VECTOR2D m_lastCursorPosition
Last cursor position sent to GAL for drawing.
bool GetScreenshot(wxImage &aDstImage)
Capture the current canvas contents into aDstImage.
EDA_DRAW_FRAME * GetParentEDAFrame() const
Returns parent EDA_DRAW_FRAME, if available or NULL otherwise.
bool m_refreshDeferred
The refresh timer was armed by Refresh() for a repaint it postponed.
Abstract interface for drawing on a 2D-surface.
What the last zoom to fit showed, so a canvas that changes size can fit it again.
Abstract interface for drawing on a 2D-surface.
An interface for classes handling user events controlling the view behavior such as zooming,...
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:68
An implementation of class VIEW_CONTROLS for wxWidgets library.
Owns a platform touchpad input registration for the lifetime of an input window.
Definition touchpad.h:50
A thread-safe event counter.
Definition profile.h:262
KICURSOR
Definition cursors.h:41
Message panel definition file.
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
RHI_LINE_PIPELINE_KIND
GPU geometry of one frame, built by GAL_MODERN after EndDrawing() and passed through the FRAME_MAILBO...
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
Platform-agnostic wrapper for a native window handle.
Definition rhi_surface.h:45
VECTOR2< double > VECTOR2D
Definition vector2d.h:707