16#include <unordered_map>
178 float x = 0,
y = 0,
w = 0,
h = 0;
214 struct RecordedCommands;
215 struct RepaintObserver {
217 RecordedCommands* stream =
nullptr;
232 : repaint_observer_(
std::make_shared<RepaintObserver>()) {
233 repaint_observer_->owner =
this;
234 observe_recorded_commands();
237 repaint_observer_->owner =
nullptr;
238 repaint_observer_->stream =
nullptr;
242 std::shared_ptr<NativeCanvasPainter>
painter,
245 native_painter_ = std::move(
painter);
246 native_backend_requirement_ = requirement;
252 native_painter_.reset();
259 return last_native_paint_succeeded_;
262 return last_native_paint_backend_;
266 recorded_commands_->commands.clear();
267 recorded_commands_->needs_backdrop_isolation =
false;
268 recorded_commands_->has_group_replays =
false;
272 abort_group_recording();
273 notify_recorded_command_consumers();
289 auto& stream = *recorded_commands_;
290 cmd.
x = sanitize_finite(cmd.
x);
291 cmd.
y = sanitize_finite(cmd.
y);
292 cmd.
w = sanitize_finite(cmd.
w);
293 cmd.
h = sanitize_finite(cmd.
h);
294 cmd.
x2 = sanitize_finite(cmd.
x2);
295 cmd.
y2 = sanitize_finite(cmd.
y2);
296 cmd.
x3 = sanitize_finite(cmd.
x3);
297 cmd.
y3 = sanitize_finite(cmd.
y3);
300 if (stream.recording_group) {
302 stream.recording.commands.push_back(std::move(cmd));
306 stream.commands.push_back(std::move(cmd));
327 auto& stream = *recorded_commands_;
328 if (stream.recording_group)
return false;
329 stream.recording_group =
true;
330 stream.recording_key = std::move(key);
331 stream.recording = CachedGroup{};
337 auto& stream = *recorded_commands_;
338 if (!stream.recording_group)
return false;
339 stream.recording_group =
false;
340 auto key = std::move(stream.recording_key);
341 stream.groups[key] = std::move(stream.recording);
342 stream.recording = CachedGroup{};
349 auto& stream = *recorded_commands_;
350 if (stream.recording_group)
return false;
351 const auto it = stream.groups.find(key);
352 if (it == stream.groups.end())
return false;
353 if (it->second.reads_backdrop) stream.needs_backdrop_isolation =
true;
354 stream.has_group_replays =
true;
358 stream.commands.push_back(std::move(cmd));
364 recorded_commands_->groups.erase(key);
367 recorded_commands_->groups.clear();
368 abort_group_recording();
370 size_t group_count()
const {
return recorded_commands_->groups.size(); }
374 const auto it = recorded_commands_->groups.find(key);
375 return it == recorded_commands_->groups.end() ? nullptr : &it->second.commands;
377 size_t command_count()
const {
return recorded_commands_->commands.size(); }
388 return recorded_commands_->needs_backdrop_isolation;
394 if (cmd.
type == T::clear_rect || cmd.
type == T::put_image_data)
return true;
395 if (cmd.
type != T::set_blend_mode)
return false;
412 const std::vector<CanvasDrawCmd>&
commands()
const {
413 return recorded_commands_->commands;
420 if (recorded_commands_ == source.recorded_commands_)
return;
421 recorded_commands_ = source.recorded_commands_;
422 observe_recorded_commands();
427 native_gpu_texture_provider_ = std::move(provider);
443 shader_effect_name_ = std::move(name);
444 shader_effect_intensity_ = std::clamp(intensity, 0.0f, 1.0f);
458 static float sanitize_finite(
float v)
noexcept {
459 return std::isfinite(
v) ?
v : 0.0f;
463 std::vector<CanvasDrawCmd>
commands;
464 bool reads_backdrop =
false;
466 struct RecordedCommands {
467 std::vector<CanvasDrawCmd>
commands;
469 bool has_group_replays =
false;
470 std::unordered_map<std::string, CachedGroup> groups;
471 bool recording_group =
false;
472 std::string recording_key;
473 CachedGroup recording;
474 std::vector<std::weak_ptr<RepaintObserver>> observers;
476 void abort_group_recording() {
477 auto& stream = *recorded_commands_;
478 stream.recording_group =
false;
479 stream.recording_key.clear();
480 stream.recording = CachedGroup{};
482 static void append_replay_sequence(
const RecordedCommands& stream,
483 std::vector<const CanvasDrawCmd*>& out);
484 void observe_recorded_commands() {
485 repaint_observer_->stream = recorded_commands_.get();
486 recorded_commands_->observers.emplace_back(repaint_observer_);
488 void notify_recorded_command_consumers() {
489 auto& observers = recorded_commands_->observers;
490 observers.erase(std::remove_if(observers.begin(), observers.end(),
491 [
this](
const std::weak_ptr<RepaintObserver>& weak) {
492 auto observer = weak.lock();
493 if (!observer) return true;
500 if (observer->owner && observer->stream == recorded_commands_.get())
501 observer->owner->request_repaint_self(1.0f);
503 }), observers.end());
505 std::shared_ptr<RecordedCommands> recorded_commands_ =
506 std::make_shared<RecordedCommands>();
507 std::shared_ptr<RepaintObserver> repaint_observer_;
508 std::shared_ptr<NativeCanvasPainter> native_painter_;
512 std::uint64_t native_frame_id_ = 0;
513 bool last_native_paint_succeeded_ =
false;
517 bool last_native_gpu_texture_draw_succeeded_ =
false;
520 std::string shader_effect_name_ =
"none";
521 float shader_effect_intensity_ = 1.0f;
Definition canvas.hpp:240
BlendMode
Indices 0..15 match the existing W3C "advanced" composite ops and must stay stable — set_blend_mode i...
Definition canvas.hpp:527
@ source_over
Definition canvas.hpp:533
@ normal
Definition canvas.hpp:529
Retained native painter installed on a CanvasWidget.
Definition canvas_widget.hpp:35
virtual void paint(const NativeCanvasPaintContext &context)=0
virtual ~NativeCanvasPainter()=default
void request_repaint()
Request that this view's host invalidate and schedule a repaint.
const std::shared_ptr< WidgetPainter > & painter() const
Definition view.hpp:235
Definition affine_transform.hpp:24
RendererBackend
Runtime identity of the concrete renderer receiving draw calls.
Definition canvas.hpp:29
@ unknown
Definition canvas.hpp:30
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ p
Definition input_events.hpp:40
@ v
Definition input_events.hpp:41
NativeCanvasBackendRequirement
Definition canvas_widget.hpp:41
@ skia_dawn
Definition canvas_widget.hpp:46
@ any
Definition canvas_widget.hpp:42
@ skia_dawn_allow_recording
Production paints require Graphite-on-Dawn; RecordingCanvas remains accepted so deterministic command...
Definition canvas_widget.hpp:45
A draw command recorded from JS for replay in paint().
Definition canvas_widget.hpp:51
bool has_source_rect
When true on a draw_image cmd, x2/y2/x3/y3 carry the source rect (sx, sy, sw, sh) for the 9-arg ctx....
Definition canvas_widget.hpp:206
float x3
Definition canvas_widget.hpp:180
Type type
Definition canvas_widget.hpp:177
float y
Definition canvas_widget.hpp:178
std::string shader_sksl
Definition canvas_widget.hpp:184
canvas::Color color
Definition canvas_widget.hpp:181
Type
Definition canvas_widget.hpp:52
@ clear
Definition canvas_widget.hpp:171
@ stroke_circle
Definition canvas_widget.hpp:55
@ stroke_path
Definition canvas_widget.hpp:122
@ scale
Definition canvas_widget.hpp:142
@ set_shadow_blur
blur (px) in extra
Definition canvas_widget.hpp:155
@ set_stroke_gradient_radial
Definition canvas_widget.hpp:109
@ cubic_to
Definition canvas_widget.hpp:121
@ set_stroke_gradient_linear
Definition canvas_widget.hpp:108
@ set_stroke_pattern
Definition canvas_widget.hpp:119
@ path_arc_to
Definition canvas_widget.hpp:136
@ set_fill_gradient_radial
Definition canvas_widget.hpp:85
@ stroke_arc
Definition canvas_widget.hpp:56
@ set_fill_color
Definition canvas_widget.hpp:81
@ replay_group
Definition canvas_widget.hpp:175
@ set_direction
Definition canvas_widget.hpp:168
@ path_arc
Definition canvas_widget.hpp:135
@ fill_rect
Definition canvas_widget.hpp:54
@ clear_stroke_gradient
Definition canvas_widget.hpp:112
@ fill_text
Definition canvas_widget.hpp:58
@ set_line_cap
Definition canvas_widget.hpp:82
@ stroke_line
Definition canvas_widget.hpp:56
@ stroke_rounded_rect
Definition canvas_widget.hpp:54
@ set_text_align
Definition canvas_widget.hpp:58
@ set_miter_limit
limit in extra
Definition canvas_widget.hpp:161
@ save
Definition canvas_widget.hpp:140
@ clip_path
Definition canvas_widget.hpp:122
@ set_line_join
Definition canvas_widget.hpp:82
@ set_blend_mode
Definition canvas_widget.hpp:83
@ set_shadow_color
color in color
Definition canvas_widget.hpp:154
@ set_fill_pattern
Definition canvas_widget.hpp:119
@ rotate
Definition canvas_widget.hpp:142
@ put_image_data
RGBA pixels in text (binary), int_val=width, x2=height (as int).
Definition canvas_widget.hpp:152
@ set_filter
Definition canvas_widget.hpp:169
@ clip_rect
Definition canvas_widget.hpp:142
@ fill_path
Definition canvas_widget.hpp:122
@ set_global_alpha
Definition canvas_widget.hpp:83
@ draw_sdf
Definition canvas_widget.hpp:149
@ line_to
Definition canvas_widget.hpp:121
@ set_stroke_color
Definition canvas_widget.hpp:81
@ set_font
Definition canvas_widget.hpp:58
@ clear_rect
Definition canvas_widget.hpp:171
@ stroke_text
Definition canvas_widget.hpp:65
@ set_fill_gradient_radial_two_circles
Canvas2D ctx.createRadialGradient(x0,y0,r0,x1,y1,r1) two-circle form.
Definition canvas_widget.hpp:91
@ path_ellipse
Definition canvas_widget.hpp:137
@ begin_path
Definition canvas_widget.hpp:121
@ draw_image
Definition canvas_widget.hpp:146
@ set_shadow_offset_x
dx (px) in extra
Definition canvas_widget.hpp:156
@ set_transform
Definition canvas_widget.hpp:143
@ clear_fill_gradient
Definition canvas_widget.hpp:85
@ fill_rounded_rect
Definition canvas_widget.hpp:54
@ restore
Definition canvas_widget.hpp:140
@ set_font_full
Definition canvas_widget.hpp:79
@ set_shadow_offset_y
dy (px) in extra
Definition canvas_widget.hpp:157
@ path_round_rect
Definition canvas_widget.hpp:138
@ set_stroke_gradient_conic
Definition canvas_widget.hpp:111
@ move_to
Definition canvas_widget.hpp:121
@ set_fill_gradient_linear
Definition canvas_widget.hpp:85
@ close_path
Definition canvas_widget.hpp:121
@ set_fill_gradient_conic
Definition canvas_widget.hpp:96
@ quad_to
Definition canvas_widget.hpp:121
@ set_line_width
Definition canvas_widget.hpp:81
@ clip
Definition canvas_widget.hpp:144
@ fill_circle
Definition canvas_widget.hpp:55
@ set_image_smoothing
enabled in int_val (0/1), quality in extra (0=low,1=med,2=high)
Definition canvas_widget.hpp:162
@ set_line_dash
pattern in gradient_positions, phase in extra
Definition canvas_widget.hpp:151
@ translate
Definition canvas_widget.hpp:142
@ set_text_baseline
Definition canvas_widget.hpp:58
@ set_stroke_gradient_radial_two_circles
Definition canvas_widget.hpp:110
@ stroke_rect
Definition canvas_widget.hpp:54
float w
Definition canvas_widget.hpp:178
float extra
Definition canvas_widget.hpp:182
std::optional< canvas::Canvas::ShaderGeometry > shader_geometry
Definition canvas_widget.hpp:186
float x
Definition canvas_widget.hpp:178
int int_val
Definition canvas_widget.hpp:187
std::vector< canvas::Color > gradient_colors
Definition canvas_widget.hpp:188
std::vector< float > gradient_positions
Definition canvas_widget.hpp:189
float x2
Definition canvas_widget.hpp:179
bool use_active_style
When true on a fill_rect / stroke_rect cmd, the paint loop must NOT call set_fill_color / set_stroke_...
Definition canvas_widget.hpp:198
float y2
Definition canvas_widget.hpp:179
float y3
Definition canvas_widget.hpp:180
std::vector< canvas::Canvas::NamedUniform > shader_uniforms
Definition canvas_widget.hpp:185
std::string text
Definition canvas_widget.hpp:183
float h
Definition canvas_widget.hpp:178
Definition canvas_widget.hpp:222
uint32_t width
Definition canvas_widget.hpp:224
bool available
Definition canvas_widget.hpp:227
uint32_t height
Definition canvas_widget.hpp:225
std::string format
Definition canvas_widget.hpp:226
void * texture_handle
Definition canvas_widget.hpp:223
Per-paint metadata for native, retained CanvasWidget content.
Definition canvas_widget.hpp:22
Rect local_bounds
Definition canvas_widget.hpp:24
float backing_scale
Definition canvas_widget.hpp:25
std::uint64_t frame_id
Definition canvas_widget.hpp:26
canvas::RendererBackend backend
Definition canvas_widget.hpp:27
canvas::Canvas & canvas
Definition canvas_widget.hpp:23
Axis-aligned rectangle in continuous (float) coordinates.
Definition geometry.hpp:52