Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3e4e6f5

Browse files
authored
Provide batching for semantics updates (#7988)
Some embedders prefer to minimise the number of semantics node/custom action updates sent back to the host platform -- for example due to expensive serialisation mechanisms, etc. This patch provides a 'batch end' signal that provides embedders with an indication of when a self-consistent set of semantics node or custom action updates have been sent. We overload the node/action ID with information that conveys a batch end by using an ID (-1) that is never allotted to semantics nodes by the framework.
1 parent 0852795 commit 3e4e6f5

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

shell/platform/embedder/embedder.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,11 @@ FlutterEngineResult FlutterEngineRun(size_t version,
448448
};
449449
ptr(&embedder_node, user_data);
450450
}
451+
const FlutterSemanticsNode batch_end_sentinel = {
452+
sizeof(FlutterSemanticsNode),
453+
kFlutterSemanticsNodeIdBatchEnd,
454+
};
455+
ptr(&batch_end_sentinel, user_data);
451456
};
452457
}
453458

@@ -469,6 +474,11 @@ FlutterEngineResult FlutterEngineRun(size_t version,
469474
};
470475
ptr(&embedder_action, user_data);
471476
}
477+
const FlutterSemanticsCustomAction batch_end_sentinel = {
478+
sizeof(FlutterSemanticsCustomAction),
479+
kFlutterSemanticsCustomActionIdBatchEnd,
480+
};
481+
ptr(&batch_end_sentinel, user_data);
472482
};
473483
}
474484

shell/platform/embedder/embedder.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ typedef struct {
319319
double bottom;
320320
} FlutterRect;
321321

322+
// |FlutterSemanticsNode| ID used as a sentinel to signal the end of a batch of
323+
// semantics node updates.
324+
const int32_t kFlutterSemanticsNodeIdBatchEnd = -1;
325+
322326
// A node that represents some semantic data.
323327
//
324328
// The semantics tree is maintained during the semantics phase of the pipeline
@@ -386,6 +390,10 @@ typedef struct {
386390
const int32_t* custom_accessibility_actions;
387391
} FlutterSemanticsNode;
388392

393+
// |FlutterSemanticsCustomAction| ID used as a sentinel to signal the end of a
394+
// batch of semantics custom action updates.
395+
const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1;
396+
389397
// A custom semantics action, or action override.
390398
//
391399
// Custom actions can be registered by applications in order to provide
@@ -496,14 +504,23 @@ typedef struct {
496504
// immediately after the root isolate has been created and marked runnable.
497505
VoidCallback root_isolate_create_callback;
498506
// The callback invoked by the engine in order to give the embedder the
499-
// chance to respond to semantics node updates from the Dart application. The
500-
// callback will be invoked on the thread on which the |FlutterEngineRun|
507+
// chance to respond to semantics node updates from the Dart application.
508+
// Semantics node updates are sent in batches terminated by a 'batch end'
509+
// callback that is passed a sentinel |FlutterSemanticsNode| whose |id| field
510+
// has the value |kFlutterSemanticsNodeIdBatchEnd|.
511+
//
512+
// The callback will be invoked on the thread on which the |FlutterEngineRun|
501513
// call is made.
502514
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback;
503515
// The callback invoked by the engine in order to give the embedder the
504516
// chance to respond to updates to semantics custom actions from the Dart
505-
// application. The callback will be invoked on the thread on which the
506-
// |FlutterEngineRun| call is made.
517+
// application. Custom action updates are sent in batches terminated by a
518+
// 'batch end' callback that is passed a sentinel
519+
// |FlutterSemanticsCustomAction| whose |id| field has the value
520+
// |kFlutterSemanticsCustomActionIdBatchEnd|.
521+
//
522+
// The callback will be invoked on the thread on which the |FlutterEngineRun|
523+
// call is made.
507524
FlutterUpdateSemanticsCustomActionCallback
508525
update_semantics_custom_action_callback;
509526
// Path to a directory used to store data that is cached across runs of a

shell/platform/embedder/tests/embedder_a11y_unittests.cc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,32 @@ TEST(EmbedderTest, CanLaunchAndShutdownWithValidProjectArgs) {
151151

152152
// Wait for UpdateSemantics callback on platform (current) thread.
153153
int node_count = 0;
154+
int node_batch_end_count = 0;
154155
test_data.on_semantics_update =
155-
[&node_count](const FlutterSemanticsNode* node) { ++node_count; };
156+
[&node_count, &node_batch_end_count](const FlutterSemanticsNode* node) {
157+
if (node->id == kFlutterSemanticsNodeIdBatchEnd) {
158+
++node_batch_end_count;
159+
} else {
160+
++node_count;
161+
}
162+
};
156163
int action_count = 0;
164+
int action_batch_end_count = 0;
157165
test_data.on_custom_action_update =
158-
[&action_count](const FlutterSemanticsCustomAction* action) {
159-
++action_count;
166+
[&action_count,
167+
&action_batch_end_count](const FlutterSemanticsCustomAction* action) {
168+
if (action->id == kFlutterSemanticsCustomActionIdBatchEnd) {
169+
++action_batch_end_count;
170+
} else {
171+
++action_count;
172+
}
160173
};
161174
g_latch.Wait();
162175
fml::MessageLoop::GetCurrent().RunExpiredTasksNow();
163176
ASSERT_EQ(4, node_count);
177+
ASSERT_EQ(1, node_batch_end_count);
164178
ASSERT_EQ(1, action_count);
179+
ASSERT_EQ(1, action_batch_end_count);
165180

166181
// Dispatch a tap to semantics node 42. Wait for NotifySemanticsAction.
167182
g_test_data_callback = [](Dart_NativeArguments args) {

0 commit comments

Comments
 (0)