FillBucket.uploadPending() is always true: `this.uploaded` is never set, so every fill bucket re-uploads on every frame
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 82/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- performance
Hướng nghiên cứu
Đọc các phần triển khai của FillBucket.upload() và uploadPending(), sau đó so sánh chúng với LineBucket và CircleBucket như issue mô tả. Tái hiện lỗi bằng cách kiểm tra xem fill bucket đã được tải lên có còn pending sau khi upload hay không; xác nhận bản sửa lỗi bằng cách kiểm tra rằng nó không còn pending khi không cần tải lên lại và các màu được render vẫn không thay đổi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
mapbox-gl-js version
3.33.0 and 3.34.2 (latest on npm; same code in both)
Browser
Chrome (desktop)
What happens
FillBucket.uploadPending() reads this.uploaded, but FillBucket.upload() never sets it. Only the inner FillBufferData sets its own uploaded flag. The bucket therefore reports "pending" forever.
From dist/mapbox-gl-dev.js (3.33.0):
// class FillBucket
uploadPending() {
return !this.uploaded || this.bufferData.needsUpload() || this.hdExt != null && this.hdExt.needsUpload();
}
upload(context) {
this.bufferData.upload(context); // sets bufferData.uploaded, not this.uploaded
if (this.hdExt) {
this.hdExt.upload(context);
}
}
Compare LineBucket and CircleBucket, whose upload() ends with this.uploaded = true.
Because the bucket is always pending, Tile.upload() takes its slow branch for every fill bucket on every call:
// Tile.upload
if (bucket.uploadPending()) {
...
featureStates = sourceCache._state.getState(sourceLayerId, void 0);
...
bucket.upload(context, this.tileID.canonical, featureStates, availableImages, globalProperties);
}
getState(sourceLayer, undefined) builds a new object with Object.assign({}, base, changes) over every feature that has state in that source layer. So the cost per frame is (visible fill tiles) x (features with feature-state), even when nothing changed.
Impact
On a map with a vector fill layer and many features carrying feature-state, the main thread spends most of a pan inside Tile.upload. Measured on a phone-size map (390x789, zoom 16) with roughly 5,000 to 7,000 features holding state, 7 pans over the same ground with the tile cache cleared first:
Tile.upload main thread over 7 pans |
long frames (> 34 ms) in the worst pan | |
|---|---|---|
| unpatched | 3,545 ms | 129 ms |
| patched (below) | 118 to 125 ms | 0 to 40 ms |
The cost grows with the number of features holding state. With few of them the bug is still there but cheap.
Steps to reproduce
- Add a vector source and a
filllayer on it. - Call
map.setFeatureStatefor a few thousand features of that source layer. - After the map is idle, take a fill bucket from a loaded tile and call
bucket.uploadPending(). It returnstrue, andbucket.uploadedis never set. - Pan, and profile
Tile.prototype.upload:getStateruns for every fill tile on every call.
Expected
uploadPending() returns false once the bucket has uploaded and nothing needs a re-upload.
Suggested fix
Set the flag in FillBucket.upload(), as the other buckets do:
upload(context) {
this.bufferData.upload(context);
if (this.hdExt) {
this.hdExt.upload(context);
}
this.uploaded = true;
}
Or have uploadPending() read this.bufferData.uploaded.
Workaround
Wrap FillBucket.prototype.upload at runtime so it sets this.uploaded = true after the original call. Rendered colours were unchanged with the wrap in place.
- Ngôn ngữ chính
- TypeScript
- Star
- 12.5k
- Fork
- 2.4k
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của mapbox/mapbox-gl-js
-
interpolate-lab gives the same result as RGB interpolate (rgb2xyz/xyz2rgb scale 0-1 channels by 255)Đang mởauto-triaged bug :lady_beetle:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
mapbox/mapbox-gl-js#13751 ·
-
TypeError: Cannot read properties of undefined (reading 'get') when a map is removed while a color-theme LUT is decodingCó thể đã có người làm @Piyush495 đã nhận 36 ngày trước. Đang mởauto-triaged bug :lady_beetle:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
mapbox/mapbox-gl-js#13737 · 1 bình luận ·
-
auto-triaged bug :lady_beetle:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
mapbox/mapbox-gl-js#13723 · 2 bình luận ·
-
auto-triaged bug :lady_beetle:
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 86/100
mapbox/mapbox-gl-js#13717 ·
-
>= v3.21 Symbol layer without feature-state expression crash the mapCó thể đã có người làm @liueric-dev đã nhận 77 ngày trước. Đang mởauto-triaged bug :lady_beetle:
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
mapbox/mapbox-gl-js#13714 · 1 reaction ·
Tất cả issue của mapbox/mapbox-gl-js
Issue tương tự
-
Autocomplete still accepts an option after becoming disabledCó thể đã có người làm @Xapollon430 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
reduxjs/react-redux#2416 · 1 bình luận ·