Skip to content

feat: wire compositor pipeline + fix 50 type errors#20

Open
LayerDynamics wants to merge 4 commits intomainfrom
feat/compositor-pipeline-wiring
Open

feat: wire compositor pipeline + fix 50 type errors#20
LayerDynamics wants to merge 4 commits intomainfrom
feat/compositor-pipeline-wiring

Conversation

@LayerDynamics
Copy link
Owner

@LayerDynamics LayerDynamics commented Mar 4, 2026

Summary

  • Wire PaintLayer tree into CompositorThread — updateLayerTree() now called in RenderingOrchestrator after paint, connecting the paint layer tree → compositor layer manager → tiling/GPU upload
  • CPU composite uses LayerTree path when available (layer-aware compositing), falls back to RenderToPixels re-paint
  • Fix getPixels() to auto-composite when layerTree exists
  • Fix script execution timing bug (duration was always ~0)
  • Fix all 50 deno task browser:check type errors across 13 files (DOMElement casts, Uint8Array buffer compat, FFI return types, etc.)
  • Add 16 new integration tests (10 compositor pipeline + 6 E2E rendering)

Test plan

  • deno test --allow-all browser/tests/integration/compositor_pipeline.test.ts — 10 pass
  • deno test --allow-all browser/tests/integration/e2e_rendering_pipeline.test.ts — 6 pass
  • deno test --allow-all browser/tests/integration/layout_paint_chain.test.ts — 10 pass
  • deno test --allow-all browser/tests/engine/rendering/paint/ — 256 pass
  • deno task browser:check — 0 errors (was 50)

🤖 Generated with Claude Code

Summary by Sourcery

Wire the paint layer tree into the compositor pipeline so CPU compositing can use layer-aware rendering, while tightening types across rendering, JavaScript, WebGPU, and FFI layers and adding integration coverage for the end-to-end rendering pipeline.

New Features:

  • Enable CPU compositing to consume the paint LayerTree directly, with a RenderToPixels-based render tree fallback.
  • Expose layer-aware compositing to the compositor by uploading the paint layer tree from the rendering orchestrator.
  • Add integration tests for the compositor pipeline and end-to-end rendering pipeline from layout through compositing to pixel output.

Bug Fixes:

  • Ensure script execution timing is measured and reported with correct start and end timestamps.
  • Allow getPixels() in CPU mode to auto-trigger compositing when either a layer tree or render tree is available, avoiding zero-length outputs.
  • Fix multiple type mismatches and unsafe DOM, WebGPU, PDF, logging, and serial bindings that caused type-check failures and potential runtime issues.

Enhancements:

  • Refine compute pipeline execution to unwrap and use the native GPU compute pipeline when available.
  • Improve LayerTree and compositing behavior in CPU mode, including resize handling and layer enumeration.
  • Adjust various canvas and DOM element usages to satisfy stricter TypeScript typings without changing runtime behavior.

Build:

  • Resolve all outstanding deno task browser:check type errors to restore a clean type-checking build.

Tests:

  • Add compositor pipeline integration tests validating layer tree wiring, CPU vs fallback compositing, tiling behavior, VSync stats, and resize handling.
  • Add end-to-end rendering pipeline tests covering block layout, nested blocks, text rendering, paint stats, incremental repaint behavior, and compositor frame counting.

…gine

- Wire PaintLayer tree into CompositorThread via updateLayerTree() in RenderingOrchestrator
- CPU composite now uses LayerTree path when available, falls back to RenderToPixels
- getPixels() auto-composites when layerTree exists but no prior composite() call
- Fix script execution timing (emitStage used Date.now() as startTime, duration was always ~0)
- Fix 50 type errors: DOMElement→HTMLCanvasElement casts, Uint8Array buffer compatibility,
  FFI return type casts, Console cast through unknown, override modifier, null assertions
- Add 10 compositor pipeline integration tests
- Add 6 E2E rendering pipeline tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 4, 2026

Reviewer's Guide

Wires the paint layer tree into the compositor pipeline for CPU compositing, fixes script timing and multiple type/FFI issues, and adds integration tests to cover the compositor and end-to-end rendering paths.

Sequence diagram for CPU compositing with wired paint layer tree

sequenceDiagram
  participant RenderingOrchestrator
  participant PaintPipeline
  participant CompositorThread
  participant LayerTree
  participant RenderToPixels
  participant Canvas2D

  RenderingOrchestrator->>PaintPipeline: paint(dom, rootRenderObject, options)
  PaintPipeline-->>RenderingOrchestrator: paintResult(displayList, layerTree)

  RenderingOrchestrator->>CompositorThread: updateLayerTree(paintResult.layerTree)
  CompositorThread->>CompositorThread: store layerTree

  alt CPU mode
    RenderingOrchestrator->>CompositorThread: composite()
    alt layerTree exists
      CompositorThread->>Canvas2D: getContext(2d)
      CompositorThread->>Canvas2D: clearRect()
      CompositorThread->>LayerTree: paintDirtyLayers()
      CompositorThread->>LayerTree: composite(ctx)
      LayerTree-->>CompositorThread: pixels on canvas
      CompositorThread->>CompositorThread: cpuCanvas = canvas
    else no layerTree
      CompositorThread->>RenderToPixels: paint(lastRenderObject, width, height, false)
      RenderToPixels-->>CompositorThread: paintResult(canvas)
      CompositorThread->>CompositorThread: cpuCanvas = paintResult.canvas
    end
  else GPU mode
    RenderingOrchestrator->>CompositorThread: composite()
    CompositorThread->>CompositorThread: GPU compositing path
  end

  note over CompositorThread,Canvas2D: getPixels() now auto-calls composite() if layerTree or lastRenderObject is available
Loading

Class diagram for RenderingOrchestrator and CompositorThread layer-aware CPU compositing

classDiagram
  class RenderingOrchestrator {
    +enableJavaScript boolean
    +compositor CompositorThread
    +renderDocument(url, options) Promise~void~
    +emitStage(id string, label string, state string, startTime number, endTime number, duration number, data any) void
  }

  class CompositorThread {
    -cpuRenderMode boolean
    -canvas HTMLCanvasElement
    -cpuCanvas HTMLCanvasElement
    -layerTree PaintLayerTree
    -renderToPixels RenderToPixels
    -lastRenderObject RenderObject
    -frameCount number
    +isCPUMode() boolean
    +updateLayerTree(layerTree PaintLayerTree) void
    +setRenderTree(rootRenderObject RenderObject) void
    +composite() void
    +getPixels() Uint8Array
  }

  class PaintLayerTree {
    +paintDirtyLayers() void
    +composite(ctx CanvasRenderingContext2D) void
    +getBounds() DOMRect
  }

  class RenderToPixels {
    +paint(rootRenderObject RenderObject, width Pixels, height Pixels, incremental boolean) RenderToPixelsResult
    -createCanvas(width Pixels, height Pixels) HTMLCanvasElement
  }

  class RenderToPixelsResult {
    +canvas HTMLCanvasElement
  }

  class RenderObject
  class CanvasRenderingContext2D
  class HTMLCanvasElement
  class Pixels
  class DOMRect

  RenderingOrchestrator --> CompositorThread : uses
  RenderingOrchestrator --> PaintLayerTree : receives from paint pipeline
  CompositorThread --> PaintLayerTree : updateLayerTree(layerTree)
  CompositorThread --> RenderToPixels : fallback CPU paint
  RenderToPixelsResult --> HTMLCanvasElement : canvas
  CompositorThread --> HTMLCanvasElement : canvas, cpuCanvas
  PaintLayerTree --> CanvasRenderingContext2D : composite(ctx)
  CompositorThread --> RenderObject : lastRenderObject
  RenderToPixels --> RenderObject : paint(rootRenderObject)
Loading

File-Level Changes

Change Details Files
Enable layer-aware CPU compositing path in CompositorThread with getPixels auto-compositing fallback.
  • In CPU mode, prefer compositing via stored LayerTree using Canvas 2D, falling back to RenderToPixels when no LayerTree is present.
  • Ensure composite() throws when neither LayerTree nor render tree is available in CPU mode.
  • Update getPixels() to trigger composite() when either a LayerTree or render tree exists but no cpuCanvas has been produced yet.
browser/src/engine/rendering/compositor/CompositorThread.ts
Wire paint layer tree from RenderingOrchestrator into the compositor and correct script timing reporting.
  • Capture script execution start time once and reuse for stage emission, fixing near-zero script duration reporting.
  • After paint, call compositor.updateLayerTree() with paintResult.layerTree to enable layer-aware compositing.
  • Keep setRenderTree() as CPU fallback path only when compositor is in CPU mode.
browser/src/engine/rendering/RenderingOrchestrator.ts
Tighten WebGPU, DOM, and rendering-related typings and casts to satisfy browser:check.
  • Cast FFI WebGPU adapter/device/shader/pipeline returns to bigint to align with TS typings.
  • Use non-null assertions and narrowed types for DOM attribute maps, canvas elements, and display-list command coordinates.
  • Adjust various APIs (PNG decoding, crypto.subtle.digest, console logging, ScriptExecutor documentElement check, RequestPipelineError.cause) to use explicit BufferSource/any/override types where required.
crates/webgpu_x/webgpu_x.ts
browser/src/engine/javascript/DOMBindings.ts
browser/src/engine/webgpu/compositor/WebGPUCompositorLayer.ts
browser/src/types/dom.ts
browser/src/engine/javascript/IgnitionInterpreter.ts
browser/src/engine/rendering/pdf/PDFGenerator.ts
browser/src/engine/webgpu/operations/compute/ComputePipeline.ts
browser/src/engine/logging/LogSink.ts
browser/src/engine/RequestPipeline.ts
browser/src/engine/javascript/ScriptExecutor.ts
browser/src/engine/network/security/Certificate.ts
browser/src/engine/rendering/compositor/CompositorLayer.ts
browser/src/engine/rendering/compositor/Tile.ts
browser/src/engine/rendering/paint/DisplayList.ts
browser/src/engine/rendering/paint/RenderToPixels.ts
Improve serialx bindings and printer integration to be more portable and type-safe under Deno.
  • Relax encode() return type and add android shared-object mapping in serialx FFI bindings.
  • Cast rawPort to any when constructing EscPos in Printer and add lint ignore to satisfy Deno lints.
crates/serialx/bindings/bindings.ts
browser/src/os/devices/Printer.ts
Add integration tests covering compositor pipeline and end-to-end rendering pipeline using CPU-mode canvas stubs.
  • Introduce compositor_pipeline integration suite that stubs an HTMLCanvasElement with CPU-only 2D context and exercises LayerTree wiring, CPU composite paths, getPixels behaviour, VSync stats, resize, and full RenderObject→pixels flow.
  • Introduce e2e_rendering_pipeline integration suite that uses real RenderBox/RenderText, LayoutEngine, RenderToPixels, and CompositorThread to validate layer tree generation, text handling, paint stats, incremental repaint, and frame count tracking.
browser/tests/integration/compositor_pipeline.test.ts
browser/tests/integration/e2e_rendering_pipeline.test.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly advances the browser's rendering capabilities by integrating the PaintLayer tree directly into the CompositorThread. This enables a more sophisticated, layer-aware CPU compositing process, which optimizes how visual elements are rendered and managed. Beyond this core rendering enhancement, the changes also address numerous type safety issues across the codebase, ensuring greater stability and maintainability. The addition of new integration tests provides comprehensive validation for the updated rendering pipeline and overall system behavior.

Highlights

  • Compositor Pipeline Integration: The PaintLayer tree is now wired into the CompositorThread, enabling layer-aware CPU compositing and improving rendering efficiency.
  • CPU Compositing Logic: CPU compositing now prioritizes the LayerTree path when available, falling back to RenderToPixels for re-painting when a layer tree is not present.
  • getPixels() Enhancement: The getPixels() function has been updated to automatically trigger a composite operation if a layer tree exists but no CPU canvas is ready.
  • Script Execution Timing Fix: A bug causing script execution duration to always be approximately zero has been resolved.
  • Type Safety Improvements: Approximately 50 TypeScript type errors across 13 files have been fixed, enhancing code robustness and maintainability through explicit type assertions and non-null checks.
  • New Integration Tests: 16 new integration tests have been added, covering the compositor pipeline (10 tests) and end-to-end rendering scenarios (6 tests).

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • browser/src/engine/RequestPipeline.ts
    • Added override keyword to the cause property in RequestPipelineError constructor.
  • browser/src/engine/javascript/DOMBindings.ts
    • Applied non-null assertion operators (!) to cloned.attributes accesses for improved type safety.
  • browser/src/engine/javascript/IgnitionInterpreter.ts
    • Added type assertions for obj.value when accessing properties in the inline cache logic.
  • browser/src/engine/javascript/ScriptExecutor.ts
    • Added a type assertion for doc.documentElement to resolve a type error.
  • browser/src/engine/logging/LogSink.ts
    • Added type assertions for the console object when logging messages.
  • browser/src/engine/network/security/Certificate.ts
    • Cast issuerDNBytes to BufferSource for crypto.subtle.digest to satisfy type requirements.
  • browser/src/engine/rendering/RenderingOrchestrator.ts
    • Corrected the timing calculation for script execution by moving the scriptStart variable initialization.
    • Integrated the updateLayerTree call to the compositor after paint, connecting the paint layer tree to the compositor.
    • Updated the comment for passing the render tree to the compositor, clarifying its role as a fallback for CPU rendering.
  • browser/src/engine/rendering/compositor/CompositorLayer.ts
    • Added a type assertion for document.createElement("canvas") to HTMLCanvasElement.
  • browser/src/engine/rendering/compositor/CompositorThread.ts
    • Implemented a layer-aware CPU compositing path that utilizes the LayerTree via Canvas 2D.
    • Introduced a fallback mechanism for CPU compositing to RenderToPixels when no LayerTree is available.
    • Modified getPixels() to automatically trigger composite() if a layerTree or lastRenderObject exists but cpuCanvas is not yet set.
  • browser/src/engine/rendering/compositor/Tile.ts
    • Added a type assertion for document.createElement("canvas") to HTMLCanvasElement.
  • browser/src/engine/rendering/paint/DisplayList.ts
    • Added type assertions for command.x, command.y, command.width, and command.height to number.
  • browser/src/engine/rendering/paint/RenderToPixels.ts
    • Added a type assertion for document.createElement("canvas") to HTMLCanvasElement.
  • browser/src/engine/rendering/pdf/PDFGenerator.ts
    • Added type assertions for imageData to Uint8Array<ArrayBuffer> and data to BufferSource for stream operations.
  • browser/src/engine/webgpu/compositor/WebGPUCompositorLayer.ts
    • Added type assertions for document.createElement("canvas") to a more specific object type.
  • browser/src/engine/webgpu/operations/compute/ComputePipeline.ts
    • Modified executeComputePass to unwrap PipelineResult to a native GPUComputePipeline and added a type assertion.
  • browser/src/os/devices/Printer.ts
    • Added a deno-lint-ignore no-explicit-any comment and as any type assertion for this.serialDevice.rawPort.
  • browser/src/types/dom.ts
    • Added non-null assertion operators (!) to seg.x and seg.y when transforming points.
  • browser/tests/integration/compositor_pipeline.test.ts
    • Added a new file containing 10 integration tests for the compositor pipeline, covering layer tree updates, CPU compositing paths, getPixels() behavior, VSync, resizing, and the full rendering pipeline.
  • browser/tests/integration/e2e_rendering_pipeline.test.ts
    • Added a new file containing 6 end-to-end integration tests for the rendering pipeline, verifying pixel output, layer tree generation, text rendering, paint stats, incremental repaint, and frame count.
  • crates/serialx/bindings/bindings.ts
    • Updated the encode function's return type to any and added a deno-lint-ignore no-explicit-any comment.
    • Extended Deno.build.os mapping to include android for libserialx.so.
  • crates/webgpu_x/webgpu_x.ts
    • Added as bigint type assertions to the return values of several FFI calls (e.g., gpu_request_adapter, gpu_request_device, gpu_create_shader_module, gpu_create_render_pipeline, gpu_create_compute_pipeline).
Activity
  • This pull request was initially generated using Claude Code, indicating an automated creation process.
  • No further human review comments or progress updates have been recorded yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • Several changes resolve type errors by broad any/unknown casts (e.g. encode() in serialx bindings, console as unknown as Record, EscPos ctor, WebGPU FFI returns, doc as unknown as { documentElement?: unknown }); consider tightening these to more specific interfaces or discriminated unions so that the unsafe boundaries remain small and well-typed.
  • The ComputePipeline.execute path now falls back to pipeline as unknown as GPUComputePipeline when nativePipeline is missing; it would be safer to adjust the PipelineResult/config types so that nativePipeline is always present (or explicitly optional with a clear invariant) instead of relying on a cast.
  • The new test helpers for createCPUCanvas and the various document.createElement("canvas") as unknown as ... usages rely on partial canvas/2D-context stubs; consider centralizing these into a shared test utility type that explicitly documents the supported surface area, to reduce duplication and accidental divergence from the real API.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several changes resolve type errors by broad `any`/`unknown` casts (e.g. `encode()` in `serialx` bindings, `console as unknown as Record`, `EscPos` ctor, WebGPU FFI returns, `doc as unknown as { documentElement?: unknown }`); consider tightening these to more specific interfaces or discriminated unions so that the unsafe boundaries remain small and well-typed.
- The `ComputePipeline.execute` path now falls back to `pipeline as unknown as GPUComputePipeline` when `nativePipeline` is missing; it would be safer to adjust the `PipelineResult`/config types so that `nativePipeline` is always present (or explicitly optional with a clear invariant) instead of relying on a cast.
- The new test helpers for `createCPUCanvas` and the various `document.createElement("canvas") as unknown as ...` usages rely on partial canvas/2D-context stubs; consider centralizing these into a shared test utility type that explicitly documents the supported surface area, to reduce duplication and accidental divergence from the real API.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant update that wires the paint layer tree into the compositor pipeline, enabling layer-aware CPU compositing and fixing a script execution timing bug. It's impressive that you've also resolved 50 type errors across the codebase, which greatly improves maintainability. The addition of 16 new integration tests for the compositor and end-to-end rendering pipelines is excellent and provides good coverage for the new features.

My review includes a couple of suggestions to further improve type safety in dom.ts and bindings.ts, which could prevent future issues and make the code even more robust. Overall, this is a high-quality contribution.

Note: Security Review did not run due to the size of the PR.

// Auto-generated with deno_bindgen
function encode(v: string | Uint8Array): Uint8Array {
// deno-lint-ignore no-explicit-any
function encode(v: string | Uint8Array): any {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Changing the return type of the encode function to any weakens type safety. The function's implementation appears to always return a Uint8Array, so the original return type Uint8Array was more accurate.

While this change likely resolves a TypeScript error, it's better to address the root cause of the type mismatch where encode is called, rather than using any. This would improve code clarity and prevent potential runtime errors if the implementation of encode were to change in the future.

Comment on lines +2228 to +2231
const [tx0, ty0] = transformPoint(seg.x!, seg.y!);
const [tx1, ty1] = transformPoint(seg.x! + sw, seg.y!);
const [tx2, ty2] = transformPoint(seg.x! + sw, seg.y! + sh);
const [tx3, ty3] = transformPoint(seg.x!, seg.y! + sh);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The use of non-null assertions (!) on seg.x and seg.y suggests that the type definition for _currentPath might be too loose. Currently, it's Array<{ type: string; x?: number; y?: number; w?: number; h?: number }>, which doesn't guarantee that x and y are present for a rect segment.

While the rect method implementation ensures these properties exist, relying on ! can make the code more brittle.

To improve type safety and remove the need for assertions, consider using a discriminated union for the path segments. This would make the type of each segment explicit and allow the compiler to enforce that rect segments always have x and y.

Example of a stricter type definition:

type PathSegment = 
  | { type: "rect"; x: number; y: number; w: number; h: number }
  | { type: "move"; x: number; y: number }
  | { type: "line"; x: number; y: number };

// Then _currentPath would be:
_currentPath: PathSegment[] = [];

With this change, you could safely access seg.x and seg.y within if (seg.type === "rect") without needing non-null assertions.

LayerDynamics and others added 3 commits March 4, 2026 15:52
…zation

Two-phase text rendering: bitmap font fallback (5x7 ASCII glyphs with
descenders) for immediate results, plus real anti-aliased glyph rendering
via fontdue WASM bindings (denosaurs/font) using system TTF/OTF fonts.

- RenderingPipeline: fillText/strokeText/measureText with FontEngine integration
- FontEngine: system font discovery, CSS font-family resolution, glyph caching
- RenderTreeBuilder: user-agent stylesheet defaults (block elements, margins, font sizes)
- RenderingOrchestrator: baseline calculation fix, NaN font-size guard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- HTMLTokenizer: full named entity table (252 entities) replacing literal '&' fallback
- HTMLTreeBuilder: add getAttribute/setAttribute/hasAttribute/removeAttribute to SimpleDOMNode
- RenderTreeBuilder: presentational HTML attributes (bgcolor, color, width, height,
  align, valign, cellpadding, cellspacing, border, font tag size/color/face)
- RenderTreeBuilder: fix table display values (table/table-row/table-cell) taking
  precedence over generic block; add center tag as block element
- LayoutEngine: table-row/table-row-group skip re-layout to preserve table positioning;
  table-cell contents laid out as block flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TLS Handshake:
- Wrap Deno.connectTls in 10s timeout with resource leak cleanup
- Custom TLS fallback wrapped in 5s timeout for fail-fast
- readExactly uses overall deadline + per-iteration timer cleanup
- receiveEncryptedHandshakeMessages loops until Finished (max 10)
- Throw on message cap exhaustion without Finished

Layout Performance:
- Remove redundant grandchild doLayout loop (O(n²) → O(n))
- hasDescendantsNeedingLayout propagated flag for O(1) dirty check
- Skip clean subtrees during recursive layout

Paint Optimization:
- Skip legacy PaintContext pass for DOMs >5000 nodes
- displayListTruncated flag on RenderingResult
- RenderToPixels layer tree is primary paint path

Request Pipeline:
- Internal AbortController cancels doRequest on timeout
- Growing buffer replaces O(n²) chunk concatenation
- ConnectionManager used for acquire/release
- Incremental header/chunked-terminator scanning

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant