8000 Fix WebP decoding capability detection by guax1xi · Pull Request #2700 · galacean/engine · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix WebP decoding capability detection #2700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 28, 2025
Merged

Conversation

guax1xi
Copy link
Contributor
@guax1xi guax1xi commented May 27, 2025

Safari 的 WebP 支持和 canvas.toDataURL('image/webp') 并非同时支持,故使用canvas.toDataURL('image/webp')判断webp支持不合适,改成加载一个1px的webp base64图片进行判断

Summary by CodeRabbit

  • New Features

    • Improved WebP image support detection for textures with fully asynchronous handling, enhancing compatibility and reliability across browsers.
  • Bug Fixes

    • Fixed issues with WebP texture loading by replacing synchronous checks with an asynchronous verification process.

Copy link
coderabbitai bot commented May 27, 2025

Walkthrough

The EXT_texture_webp extension's WebP support detection is refactored to use an asynchronous approach by loading a minimal WebP image and resolving a promise. The createAndParse method is updated to be asynchronous, properly awaiting WebP support detection before selecting the appropriate texture source.

Changes

File(s) Change Summary
packages/loader/src/gltf/extensions/EXT_texture_webp.ts Refactored WebP support detection to be asynchronous; removed _supportWebP property; updated createAndParse to async and changed its signature.
packages/core/src/SystemInfo.ts Added static private property _webpSupported and static method _checkWebpSupported() to asynchronously detect WebP support via image loading.

Sequence Diagram(s)

sequenceDiagram
    participant EXT_texture_webp
    participant Browser
    participant GLTFParserContext

    EXT_texture_webp->>Browser: checkWebpSupport() (load minimal WebP image)
    Browser-->>EXT_texture_webp: Promise resolves with support status
    EXT_texture_webp->>EXT_texture_webp: Await support check in createAndParse
    EXT_texture_webp->>GLTFParserContext: Parse texture using WebP or fallback source
Loading

Possibly related PRs

  • Support WebP plugin #2310: Initial implementation of EXT_texture_webp extension and its texture parsing logic, directly related to this PR's refactoring of WebP support detection.

Suggested labels

enhancement

Suggested reviewers

  • GuoLei1990

Poem

A rabbit hopped with code so neat,
Now WebP checks are quite complete.
Async it waits, a promise in tow,
To see if WebP can truly show.
With textures parsed right on cue,
The loader’s smarter—thanks to you!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 418d07a and b56fbaa.

📒 Files selected for processing (1)
  • packages/core/src/SystemInfo.ts (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/core/src/SystemInfo.ts (1)
packages/core/src/asset/AssetPromise.ts (1)
  • resolve (25-35)
🪛 Biome (1.9.4)
packages/core/src/SystemInfo.ts

[error] 91-91: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 92-92: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 93-93: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 109-109: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (2)
packages/core/src/SystemInfo.ts (2)

5-5: LGTM: AssetPromise import added correctly.

The import is necessary for the new WebP support detection functionality.


22-22: LGTM: Static property for caching WebP support check.

The private static property appropriately caches the WebP support check result to avoid redundant detection calls.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2)

27-27: Fix spacing issue in type declaration.

Apply this diff to fix the formatting:

-  private _supportWebP = false as boolean| Promise<boolean>;
+  private _supportWebP = false as boolean | Promise<boolean>;
🧰 Tools
🪛 ESLint

[error] 27-27: Insert ·

(prettier/prettier)


34-34: Add missing semicolon.

Apply this diff to fix the formatting:

-      this._supportWebP = checkWebpSupport()
+      this._supportWebP = checkWebpSupport();
🧰 Tools
🪛 ESLint

[error] 34-34: Insert ;

(prettier/prettier)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74f771a and 82e067b.

📒 Files selected for processing (1)
  • packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2 hunks)
🧰 Additional context used
🪛 ESLint
packages/loader/src/gltf/extensions/EXT_texture_webp.ts

[error] 12-12: Delete ··

(prettier/prettier)


[error] 13-13: Delete ····

(prettier/prettier)


[error] 14-14: Replace ········ with ····

(prettier/prettier)


[error] 15-15: Replace ··const·result·=·(img.width·>·0)·&&·(img.height·>·0) with const·result·=·img.width·>·0·&&·img.height·>·0

(prettier/prettier)


[error] 16-16: Replace ········ with ······

(prettier/prettier)


[error] 17-17: Replace ········ with ····

(prettier/prettier)


[error] 18-18: Delete ····

(prettier/prettier)


[error] 19-19: Delete ··

(prettier/prettier)


[error] 20-20: Delete ····

(prettier/prettier)


[error] 21-21: Replace ········img.src·=·'data:image/webp;base64,UklGRhACAABXRUJQVlA4WAoAAAAwAAAAAAAAAAAASUNDUMgBAAAAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADZBTFBIAgAAAAAAVlA4IBgAAAAwAQCdASoBAAEAAUAmJaQAA3AA/v02aAA=' with ····img.src·=⏎······"data:image/webp;base64,UklGRhACAABXRUJQVlA4WAoAAAAwAAAAAAAAAAAASUNDUMgBAAAAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADZBTFBIAgAAAAAAVlA4IBgAAAAwAQCdASoBAAEAAUAmJaQAA3AA/v02aAA="

(prettier/prettier)


[error] 22-22: Replace ··}) with });

(prettier/prettier)


[error] 27-27: Insert ·

(prettier/prettier)


[error] 34-34: Insert ;

(prettier/prettier)


[error] 50-50: Insert ·

(prettier/prettier)

🔇 Additional comments (2)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2)

40-46: Excellent improvement to WebP detection reliability.

Converting the method to async to properly handle the asynchronous WebP support detection is the correct approach. This addresses the Safari WebP detection issues mentioned in the PR objectives.


55-55: LGTM! Texture selection logic is correctly updated.

The texture selection now properly uses the awaited supportWebP boolean value instead of the potentially Promise-typed _supportWebP property.

Comment on lines 49 to 52
let supportWebP = false;
if(this._supportWebP) {
supportWebP = await this._supportWebP;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix spacing and improve type safety.

The logic correctly awaits the WebP support promise, but there's a formatting issue and the type handling could be more explicit.

Apply this diff to fix formatting and improve type safety:

-    let supportWebP = false;
-    if(this._supportWebP) {
-      supportWebP = await this._supportWebP;
-    }
+    let supportWebP = false;
+    if (this._supportWebP instanceof Promise) {
+      supportWebP = await this._supportWebP;
+    } else {
+      supportWebP = this._supportWebP;
+    }

This makes the type checking more explicit and handles both Promise and boolean cases properly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let supportWebP = false;
if(this._supportWebP) {
supportWebP = await this._supportWebP;
}
let supportWebP = false;
if (this._supportWebP instanceof Promise) {
supportWebP = await this._supportWebP;
} else {
supportWebP = this._supportWebP;
}
🧰 Tools
🪛 ESLint

[error] 50-50: Insert ·

(prettier/prettier)

🤖 Prompt for AI Agents
In packages/loader/src/gltf/extensions/EXT_texture_webp.ts around lines 49 to
52, fix the spacing issue by adding proper indentation and line breaks. Improve
type safety by explicitly checking if this._supportWebP is a Promise or a
boolean, then await or assign accordingly to supportWebP. This ensures correct
handling of both Promise and boolean types and clearer, more maintainable code.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (1)

44-53: Method correctly handles asynchronous WebP support detection.

The createAndParse method properly uses .then() to wait for WebP support detection before selecting the appropriate texture source. The promise chaining maintains the same return type while enabling asynchronous behavior.

Consider caching WebP support detection globally.

The current implementation performs WebP detection for each extension instance. Consider caching the result globally to avoid redundant checks:

+let _globalWebPSupport: AssetPromise<boolean> | null = null;

 function checkWebpSupport(): AssetPromise<boolean> {
+  if (_globalWebPSupport) {
+    return _globalWebPSupport;
+  }
+  _globalWebPSupport = new AssetPromise((resolve) => {
-  return new AssetPromise((resolve) => {
     // existing implementation
   });
+  return _globalWebPSupport;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 82e067b and 91e42f2.

📒 Files selected for processing (1)
  • packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (3)
packages/core/src/asset/AssetPromise.ts (2)
  • AssetPromise (4-234)
  • resolve (25-35)
packages/core/src/SystemInfo.ts (1)
  • SystemInfo (9-126)
packages/loader/src/gltf/parser/GLTFParser.ts (1)
  • registerGLTFExtension (137-143)
🔇 Additional comments (2)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2)

11-29: Excellent implementation of reliable WebP detection!

The new checkWebpSupport() function correctly addresses the Safari WebP detection issue by loading a minimal WebP image instead of relying on canvas methods. The implementation properly:

  • Uses AssetPromise as required by the engine architecture
  • Handles both browser and non-browser environments
  • Uses a minimal 1-pixel WebP image for efficient testing
  • Properly resolves false on error or in non-browser environments

This approach is much more reliable than canvas-based detection for Safari compatibility.


33-33: Property type change correctly supports asynchronous WebP detection.

The _supportWebP property now correctly uses AssetPromise<boolean> instead of a synchronous boolean, enabling proper asynchronous WebP support detection. This aligns well with the engine's promise-based architecture.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (1)

23-24: Extract the base64 WebP string as a constant for better readability.

The inline base64 string is very long and reduces code readability. Consider extracting it as a named constant.

Add a constant at the module level:

+// 1x1 transparent WebP image for feature detection
+const WEBP_TEST_IMAGE = "data:image/webp;base64,UklGRhACAABXRUJQVlA4WAoAAAAwAAAAAAAAAAAASUNDUMgBAAAAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADZBTFBIAgAAAAAAVlA4IBgAAAAwAQCdASoBAAEAAUAmJaQAA3AA/v02aAA=";
+
 function checkWebpSupport(): AssetPromise<boolean> {

Then update the usage:

-      img.src =
-        "data:image/webp;base64,UklGRhACAABXRUJQVlA4WAoAAAAwAAAAAAAAAAAASUNDUMgBAAAAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADZBTFBIAgAAAAAAVlA4IBgAAAAwAQCdASoBAAEAAUAmJaQAA3AA/v02aAA=";
+      img.src = WEBP_TEST_IMAGE;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91e42f2 and f224e57.

📒 Files selected for processing (1)
  • packages/loader/src/gltf/extensions/EXT_texture_webp.ts (2 hunks)
🔇 Additional comments (1)
packages/loader/src/gltf/extensions/EXT_texture_webp.ts (1)

33-52: LGTM! The asynchronous WebP detection is correctly implemented.

The createAndParse method properly returns a promise chain and correctly handles the asynchronous WebP support check using AssetPromise as required by the engine guidelines.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b27669 and 9ce9158.

📒 Files selected for processing (2)
  • packages/core/src/SystemInfo.ts (3 hunks)
  • packages/loader/src/gltf/extensions/EXT_texture_webp.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/loader/src/gltf/extensions/EXT_texture_webp.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/core/src/SystemInfo.ts (1)
packages/core/src/asset/AssetPromise.ts (1)
  • resolve (25-35)
🪛 Biome (1.9.4)
packages/core/src/SystemInfo.ts

[error] 91-91: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 92-92: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 110-110: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🔇 Additional comments (2)
packages/core/src/SystemInfo.ts (2)

5-5: LGTM: Import added for AssetPromise.

The import is correctly added to support the new asynchronous WebP detection functionality.


22-22: LGTM: Static property for caching WebP support result.

The property correctly caches the AssetPromise to avoid redundant WebP support checks.

@GuoLei1990 GuoLei1990 changed the title fix: 修改是否支持解码webp的判断 Fix WebP decoding capability detection May 27, 2025
@GuoLei1990 GuoLei1990 added bug Something isn't working glTF labels May 27, 2025
@GuoLei1990 GuoLei1990 merged commit 596414b into galacean:main May 28, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 49BF glTF
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0