バージョン: 1.2.1-build3
最終更新: 2026-09-01
言語: 日本語 |
アプリケーションを再起動せずに描画経路を切り替える
API と、切替を跨いで
状態を引き継ぐ Handoff Meta のリファレンスです。
切替そのもの (blink_web_view_switch_render_path() と
render-path-changed
シグナル) の詳細は signals-api-ja.md
にあります。本ページは
引き継ぎメタを中心に、切替と組み合わせて使う形をまとめます。
描画経路には長所と短所があります。CPU 合成は互換性が高く、GPU の
dmabuf 直渡しは
帯域とCPU
に有利です。読者の環境や場面によって、望ましい経路は変わります。
従来は経路を変えるためにプロセスを起動し直していました。読者から見ると数秒の
中断です。BlinkShift
はこれを同一プロセス内の切替にします。
引き継ぎメタは「切替を跨いで何を保つか」を、経路に依存しない中間表現で表します。
幾何は論理 px と明示的な倍率で持ちます。
物理 px = logical × device_scale_factor
物理 px
をそのまま渡す形にしないのは、受け取る側が倍率を推測する必要をなくすため
です。倍率の解釈が両側でずれると、表示が半分の大きさになるなどの形で現れます。
#define BLINK_HANDOFF_META_SCHEMA_VERSION 1
typedef struct _BlinkHandoffMeta {
int schema_version; /* == BLINK_HANDOFF_META_SCHEMA_VERSION */
int logical_width; /* 幾何: 論理 px */
int logical_height;
int device_scale_factor; /* 物理 px = logical × これ */
char* url; /* 内容: 現在の URL (所有) */
int scroll_x; /* 論理 px */
int scroll_y;
char* path_id; /* 出力経路: "software" / "egl" など (所有) */
} BlinkHandoffMeta;schema_version
は前方互換のためにあります。読み込む側は自分が知っている版と
一致するかを確かめてから内容を使ってください。
| 関数 | 役割 |
|---|---|
blink_web_view_export_handoff_meta() |
現在の状態をメタに書き出す。戻り値は呼出側が解放 |
blink_web_view_import_handoff_meta() |
メタから状態を復元する |
blink_handoff_meta_serialize() |
メタをテキストにする。戻り値は呼出側が解放 |
blink_handoff_meta_deserialize() |
テキストからメタを作る。戻り値は呼出側が解放 |
blink_handoff_meta_free() |
メタを解放する |
BlinkHandoffMeta* blink_web_view_export_handoff_meta(BlinkWebView* web_view);
void blink_web_view_import_handoff_meta(BlinkWebView* web_view,
const BlinkHandoffMeta* meta);
char* blink_handoff_meta_serialize(const BlinkHandoffMeta* meta);
BlinkHandoffMeta* blink_handoff_meta_deserialize(const char* text);
void blink_handoff_meta_free(BlinkHandoffMeta* meta);export は失敗すると NULL
を返します。serialize の戻り値は
free()、
deserialize と export の戻り値は
blink_handoff_meta_free() で解放します。
直列化の形式は INI
互換のテキストで、セッション保存ファイルと同じ読み方が
できます。
含むのは経路に依存しない意味状態だけです。
| 含む | 含まない |
|---|---|
| 幾何 (論理 px + 倍率) | EGL コンテキスト |
| URL | Wayland サーフェス |
| スクロール位置 (論理 px) | dmabuf のファイル記述子 |
| 出力経路の id | サーフェス識別子 |
含まないものは切替のたびに作り直されます。生の資源を持ち回らないので、切替に
失敗しても前の経路へ戻せます。
次の状態はエンジンからは意味を判定できないため、メタには載せていません。
エンジンが値の正しさを検証できないものに型を付けると、型があるのに中身を保証
できない形になります。これらはアプリケーション側で保存・復元してください。
版面の幾何 (列ピッチなど) は縦書きメトリクスの API
から取得できます。メタに
写しを持たせると、片方だけ古くなったときに気付けません。
切替の前後でメタを採り、同じ状態に戻っているかを確かめる形です。切替は非同期
なので、完了はシグナルで受け取ります。
#include <blink_gtk/blink_gtk.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int g_seq = 0;
static char* g_before = NULL;
static void on_render_path_changed(BlinkWebView* view,
const char* to,
const char* result,
int gate_ms,
int seq,
gpointer user_data) {
(void)user_data;
if (seq != g_seq) {
return; /* 別の切替の通知。鍵が違えば触らない */
}
if (strcmp(result, "ok") != 0) {
printf("切替できませんでした (%s)。前の経路のままです\n", result);
return;
}
BlinkHandoffMeta* after = blink_web_view_export_handoff_meta(view);
if (after != NULL) {
char* text = blink_handoff_meta_serialize(after);
printf("経路=%s %d ms\n", to, gate_ms);
printf(" 前: %s", g_before != NULL ? g_before : "(採れず)\n");
printf(" 後: %s", text != NULL ? text : "(採れず)\n");
free(text);
blink_handoff_meta_free(after);
}
}
static void request_switch(BlinkWebView* view, const char* path_id) {
BlinkHandoffMeta* before = blink_web_view_export_handoff_meta(view);
if (before != NULL) {
free(g_before);
g_before = blink_handoff_meta_serialize(before);
blink_handoff_meta_free(before);
}
g_seq = blink_web_view_switch_render_path(view, path_id);
if (g_seq == 0) {
printf("切替の要求が受け付けられませんでした\n");
}
}
int main(int argc, char** argv) {
blink_gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new();
GtkWidget* widget = blink_web_view_new();
BlinkWebView* view = BLINK_WEB_VIEW(widget);
g_signal_connect(view, "render-path-changed",
G_CALLBACK(on_render_path_changed), NULL);
gtk_window_set_child(GTK_WINDOW(window), widget);
gtk_window_set_default_size(GTK_WINDOW(window), 1024, 768);
blink_web_view_load_uri(view, "https://example.com/");
gtk_widget_set_visible(window, TRUE);
request_switch(view, "P2");
blink_gtk_run_main_loop();
free(g_before);
blink_gtk_shutdown();
return 0;
}blink_web_view_switch_render_path()
は受理した切替の通し番号を返します
(1 以上。0 は受理されなかったことを表します)。完了シグナルの
seq 引数には
同じ番号が入ります。
切替が続けて起きる場面では、時刻の近さで前後を結びつけると別の切替の記録を
突き合わせてしまいます。しかも一致したように見えるので、間違いに気付けません。
番号で結んでください。
result |
意味 |
|---|---|
ok |
新しい経路で安定して描けている |
rollback |
新しい経路が確認に落ち、前の経路へ戻した。表示は保たれている |
fail |
前の経路へ戻せなかった。異常として扱う |
rollback は失敗ですが、読者の画面は壊れません。
| id | 内容 |
|---|---|
P1 |
CPU 合成の直接配送 (既定) |
P2 |
CPU 合成の共有メモリ配送 |
P3 |
GPU の dmabuf 配送。出力層だけを差し替えるため、失敗すれば CPU 合成へ戻せる |
blink_web_view_get_render_path() は現在の経路 id
を返します。値が変わるのは
切替が ok で完了したときだけです。
render-path-changed シグナル