Skip to content

render: harden CanvasKit direct replay contract#1057

Closed
seo-rii wants to merge 2 commits into
edwardkim:develfrom
seo-rii:render-p17
Closed

render: harden CanvasKit direct replay contract#1057
seo-rii wants to merge 2 commits into
edwardkim:develfrom
seo-rii:render-p17

Conversation

@seo-rii

@seo-rii seo-rii commented May 21, 2026

Copy link
Copy Markdown
Contributor

What

  • CanvasKit compat replay diagnostics를 Canvas2D overlay 허용이 아니라 direct replay required policy로 고정합니다.
  • WASM/Studio fallback getCanvasKitReplayPlanhiddenCanvas2dOverlayAllowed=false, directReplayRequired=true를 반환하도록 맞춥니다.
  • CanvasKit replay mode별 policy를 DIRECT_ONLY 계약으로 모아서 compat가 hidden Canvas2D overlay fallback으로 해석되지 않게 합니다.
  • layer schema constant export가 LAYER_TREE_SCHEMA와 동기화되는지 테스트를 보강합니다.
  • Studio regression test로 CanvasKit renderer가 Canvas2D overlay replay를 들여오지 않고, fallback replay plan도 direct contract를 유지하는지 확인합니다.

Why

P16에서 browser CanvasKit direct renderer가 들어갔으므로, P17은 실제 coverage를 크게 넓히기 전에 replay contract를 먼저 닫는 단계입니다.

중요한 기준은 defaultcompat 모두 Canvas2D overlay fallback이 아니라는 점입니다. compat는 보수적인 direct replay mode일 뿐, hidden Canvas2D paint로 unsupported op를 덮는 모드가 아닙니다. 따라서 native/WASM diagnostics와 Studio fallback bridge가 같은 contract를 말해야 합니다.

Compatibility

  • 기본 renderer는 계속 Canvas2D입니다.
  • CanvasKit은 opt-in path입니다.
  • public native Skia/PDF API는 바꾸지 않습니다.
  • CanvasKit full parity를 이 PR에서 닫지 않습니다.

Non-goals

  • Raster image/effect coverage 확장은 P18로 넘깁니다.
  • Text/glyph advanced payload gates는 P19로 넘깁니다.
  • Renderer sweep/WebGPU/performance artifact는 P20으로 넘깁니다.
  • PDF export는 P21로 넘깁니다.

Validation

  • wasm-pack build --target web --dev
  • npm --prefix rhwp-studio test
  • npm --prefix rhwp-studio run build
  • cargo test canvaskit --lib
  • cargo test layer_tree_schema_constants_match_schema --lib
  • cargo fmt --check
  • git diff --check

Refs #536

@edwardkim edwardkim self-requested a review May 21, 2026 09:22
@edwardkim edwardkim added the enhancement New feature or request label May 21, 2026
@edwardkim edwardkim added this to the v1.0.0 milestone May 21, 2026
@seo-rii seo-rii marked this pull request as ready for review May 21, 2026 13:44
Copilot AI review requested due to automatic review settings May 21, 2026 13:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates CanvasKit replay policy to enforce direct replay (and forbid hidden Canvas2D overlay) across modes, and updates Rust/TypeScript tests and bridge code to match the new contract.

Changes:

  • Make CanvasKit replay plan report hiddenCanvas2dOverlayAllowed: false and directReplayRequired: true (including wasm bridge fallback).
  • Update Rust policy logic + associated tests to treat compat as direct-replay-required.
  • Add/adjust schema and backend tests; tweak TS wasm bridge typing for getShapeBBox.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/wasm_api/tests.rs Updates wasm API test expectations for the new replay-plan flags.
src/wasm_api.rs Adjusts public API doc comment to reflect updated replay policy messaging.
src/renderer/canvaskit_policy.rs Enforces “no hidden overlay + direct replay required” in plan construction; updates related unit tests.
src/paint/schema.rs Adds assertions tying exported constants to schema fields.
rhwp-studio/tests/render-backend.test.ts Adds a test to ensure JS fallback JSON contract matches the new policy.
rhwp-studio/src/core/wasm-bridge.ts Changes fallback JSON to constant flags; adds a cast-based call for getShapeBBox.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/renderer/canvaskit_policy.rs Outdated
Comment thread src/renderer/canvaskit_policy.rs Outdated
Comment thread src/wasm_api.rs
Comment thread rhwp-studio/src/core/wasm-bridge.ts Outdated
Comment thread rhwp-studio/tests/render-backend.test.ts Outdated
Comment thread src/paint/schema.rs
edwardkim pushed a commit that referenced this pull request May 22, 2026
…t check 복구)

Task #1058 Stage 16 (adaa0b0) 에서 추가된 신규 파일이 rustfmt 정합
미통과 — devel CI #970 (sha=749048c9) Format check 실패. cargo fmt
적용으로 정정. 본 환경 cargo fmt --check 전체 exit 0 검증.

본 정정은 PR #1057 처리 진행 전 devel CI 회복 위한 단독 commit.
다른 처리분 (PR #1054/#1059 누적 + 예정 PR #1057) 은 별도 누적 push
계획 (작업지시자 결정 "본 PR 처리분 누적 후 push").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edwardkim

Copy link
Copy Markdown
Owner

검토 완료 — merge 수용. devel 에 반영합니다.

검증 결과

  • CI 전체 pass (Build & Test / Analyze rust·js·py / Canvas visual diff / CodeQL)
  • 본 환경 cargo test --release --lib: 1324 passed, 0 failed
  • 본 환경 cargo test canvaskit --lib: 14 passed, 0 failed (정책/replay plan 검증)
  • 본 환경 cargo test layer_tree_schema_constants_match_schema --lib: passed (PR 본문 검증 항목)
  • cargo fmt --check 통과

처리

  • 본 PR 2 commit (2eb64e9b 본질 + 20fc48f2 Copilot review feedback 반영) author (seo-rii) 보존 cherry-pick
  • 코드 품질 지적 사항 없음 (Copilot 리뷰 6/6 이미 정직 반영됨)
  • 시각 판정 면제 (작업지시자 결정 옵션 A) — CanvasKit opt-in path, 정량 게이트 5 조건 충족 (CanvasKit opt-in path + 결정적 측정 + 회귀 가드 + Copilot 6/6 반영 + scope 정직)

평가

Copilot 리뷰 6 코멘트를 후속 commit (20fc48f2) 에서 정직하게 반영하신 점이 모범적입니다. 본 환경 git 확인 결과:

  • allows_canvas2d_overlay() 하드코딩 → CanvasKitReplayPolicy 구조체 + DIRECT_ONLY const 추출 (mode→policy 매핑 명료화)
  • as unknown as { getShapeBBox: ... } cast 제거 (타입 안전성 회복)
  • wasm_api.rs doc — compat 가 future tuning 용도임 명시
  • schema.rs assertion 중복 → struct 비교로 간결화

feedback_image_renderer_paths_separate 핵심 정합 — native (Rust canvaskit_policy) + WASM (wasm_api) + frontend (wasm-bridge.ts) + Studio fallback (render-backend.test.ts) 4 path 동시 contract 정합. 메모리 룰의 본질적 권위 사례입니다.

compat 가 hidden Canvas2D overlay 가 아니라 보수적인 direct replay mode 임을 명확히 한 점도 향후 P18~P21 단계의 토대가 됩니다. PR 본문의 P 시리즈 분리 (P18 raster / P19 text payload / P20 sweep+WebGPU / P21 PDF export) 정직 명시도 정합입니다.

frontend 영역 변경도 (1) opt-in CanvasKit path 한정, (2) 신규 의존성 추가 없음, (3) 기존 wasm-bridge / test 영역만 강화 — 거버넌스 우려 없음 확인했습니다.

기여 감사합니다.

@edwardkim

Copy link
Copy Markdown
Owner

devel 반영 완료 (cherry-pick). PR close 합니다.

@edwardkim edwardkim closed this May 22, 2026
edwardkim pushed a commit that referenced this pull request May 22, 2026
render: harden CanvasKit direct replay contract (Refs #536, P17, seo-rii).
default/compat 모두 direct replay only 로 contract 고정, Canvas2D overlay
fallback 차단. 4 path (native/WASM/frontend/Studio fallback) 동시 정합.
Copilot 리뷰 6/6 정직 반영 (CanvasKitReplayPolicy 구조체 추출 + as
unknown cast 제거 + schema struct 비교 등). CI 전부 pass + 본 환경 cargo
test --lib 1324 passed + canvaskit 14/0 + schema 1/0 + Canvas visual
diff pass. 시각 판정 면제 (작업지시자 옵션 A) — CanvasKit opt-in path.

feedback_image_renderer_paths_separate 핵심 정합 (4 path 동시 contract).
feedback_pr_supersede_chain — P15 → P16 → P17 chain + P18~P21 분리 정직.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 22, 2026
3 PR 본질 + 3 archives 통합 — author 보존 cherry-pick:
- PR #1054 (closes #1049, Jaeook Ryu): VPOS_CORR lazy_base trailing-ls
  bridge 정합. #1046 가설 반증 후 진짜 원인 (이중 차감) 정확 식별.
- PR #1059 (HaimLee-4869): U+00B7 폭 폰트 metric 정합 — 비례폰트
  .notdef 위장값 가드. native·WASM 공유 함수 가드.
- PR #1057 (Refs #536, seorii): CanvasKit direct replay contract harden
  (P17). 4 path 동시 정합 + Copilot 6/6 반영.

본 환경 cargo test --release --lib 1324 passed, 0 failed. CI 전부 pass.
시각 판정 면제 (모두 정량 게이트 충족) — 메모리 룰 후보 권위 사례
누적 (PR #1039#1044#1054#1059#1057 5 사례).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants