Skip to content

feat: increase camera reel gallery capacity from 500 to 1000 photos - #10127

Open
decentraland-bot wants to merge 1 commit into
devfrom
feat/increase-gallery-capacity-to-1000
Open

decentraland-bot wants to merge 1 commit into
devfrom
feat/increase-gallery-capacity-to-1000

Conversation

@decentraland-bot

Copy link
Copy Markdown
Contributor

Summary

  • Bumps GRID_POOL_MAX_SIZE from 500 → 1000 in CameraReelGalleryController.cs to match the planned backend MAX_IMAGES_PER_USER=1000 env-var update
  • THUMBNAIL_POOL_MAX_SIZE is already 10000 — no change needed there

Why this is safe

  • Gallery uses infinite-scroll pagination (page size 100, triggered within 12 slots of bottom) — users never load all images at once
  • Textures are viewport-culled (off-screen textures nulled, restored from cache on re-entry)
  • camera-reel-service test suite already uses max_images_per_user: 1000 in tests/common/mod.rs
  • Storage cost increase: $0.006/month per user who fills the new cap ($6/month per 1,000 capped users)

Backend change (separate ops task)

Update MAX_IMAGES_PER_USER=1000 in the camera-reel-service deployment config. No code change or rebuild needed.

Documentation (follow-up)

Update "up to 500 photos" in:

  • decentraland/documentation → content/player/FAQs/decentraland-101.md line 121
  • decentraland/docs → player/faqs/decentraland-101.md line 148

Closes #10126

🤖 Generated with Claude Code

Bumps GRID_POOL_MAX_SIZE to match the planned backend MAX_IMAGES_PER_USER
increase. The gallery uses infinite-scroll pagination (100 items/page) so
memory impact is minimal — textures load on demand and are viewport-culled.

Closes #10126

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@decentraland-bot
decentraland-bot requested review from a team as code owners September 16, 2026 07:08
@github-actions
github-actions Bot requested a review from DafGreco September 16, 2026 07:08
@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

🚦 CI Status

Build

Windows and Mac built successfully in Unity Cloud.

Name Links & timing
Build 089030b · Logs · built 2026-09-16T08:44:36Z
Windows GitHub job · Unity Cloud #1 · Unity log · ⏱ 57m 10s build + 9m 9s queue · Download .zip · .zip via S3
Mac GitHub job · Unity Cloud #1 · Unity log · ⏱ 1h 28m build + 3m 0s queue · Download .zip · .zip via S3

Lint

Warnings not reduced: 11910 => 11910 — remove at least 1 warning to merge.

Warnings/errors in files changed by this PR (27)
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:655  AccessToStaticMemberViaDerivedType  Access to a static member of a type via a derived type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:459  CSharpWarnings::CS8600  Converting null literal or possible null value into non-nullable type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:472  CSharpWarnings::CS8603  Possible null reference return
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:227  CSharpWarnings::CS8604  Possible null reference argument for parameter 'shareToXMessage' in 'DCL.InWorldCamera.ReelActions.ReelCommonActions.ShareReelToX'
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:96  CSharpWarnings::CS8618  Non-nullable members 'ScreenshotDeleted', 'ScreenshotShared', 'ScreenshotDownloaded', 'MaxThumbnailsUpdated', 'thumbnailImages', 'reelToDelete', 'pagedCameraReelManager' must contain non-null values when exiting constructor. Consider adding the 'required' modifiers or declaring the members as nullable.
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:158  CSharpWarnings::CS8625  Cannot convert null literal to non-nullable reference type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:284  CSharpWarnings::CS8625  Cannot convert null literal to non-nullable reference type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:340  CSharpWarnings::CS8625  Cannot convert null literal to non-nullable reference type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:661  CSharpWarnings::CS8625  Cannot convert null literal to non-nullable reference type
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:281  ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract  Expression is always true according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:314  ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract  Expression is always true according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:135  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:136  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:137  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:159  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:160  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:203  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:205  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:222  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:228  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:239  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:299  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:302  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:509  ConditionalAccessQualifierIsNonNullableAccordingToAPIContract  Conditional access qualifier expression is never null according to nullable reference types' annotations
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:494  ParameterHidesMember  Parameter 'reelToDelete' hides field 'DCL.InWorldCamera.CameraReelGallery.CameraReelGalleryController.reelToDelete'
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:17  RedundantUsingDirective  Using directive is not required by the code and can be safely removed
Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs:257  UnusedParameter.Local  Parameter 'callbackContext' is never used

Lint run · took 26m 22s

Tests

All Unity tests passed ✅

TESTS SUITE Result Passed Failed Skipped Tests time Job time
EditMode ✅ Passed 25964 0 13 4m 28s 15m 42s
PlayMode ✅ Passed 248 0 37 49s 12m 57s

Tests time sums the test cases; Job time is the job's wall clock including checkout, licensing and asset import.

Slowest tests
  • [editmode] 16.5s DCL.AuthenticationScreenFlow.Tests.ProfileFetchingAuthStateShould.CancelStalledFetchOnTimeout
  • [editmode] 15.6s DCL.Tests.Editor.ValidationTests.CheckForDebugUsage
  • [editmode] 11.9s DCL.Tests.Editor.ValidationTests.CheckUnityObjectsForMissingReferences
  • [editmode] 10.0s DCL.Notifications.Tests.NotificationsRequestControllerShould.ReuseSingleListInstanceAcrossPollIterations
  • [editmode] 5.0s DCL.Friends.Tests.FriendsConnectivityStatusTrackerShould.RaiseOnlineEventWhenSameStatusIsRebroadcastAfterReset
  • [editmode] 5.0s CrdtEcsBridge.WorldSynchronizer.Tests.CrdtWorldSynchronizerShould.ThrowIfSyncBufferIsAlreadyRented
  • [editmode] 4.8s DCL.Tests.Editor.ValidationTests.SettingsAreValid
  • [editmode] 4.1s SceneRunner.Tests.SceneFacadeShould.ContinueUpdateLoopOnBackgroundThread(5,4000)
  • [editmode] 4.1s SceneRunner.Tests.SceneFacadeShould.ContinueUpdateLoopOnBackgroundThread(30,4000)
  • [editmode] 4.1s SceneRunner.Tests.SceneFacadeShould.ContinueUpdateLoopOnBackgroundThread(90,4000)
  • [playmode] 6.8s Global.Tests.PlayMode.CubeWaveSceneShould.EmitECSComponents
  • [playmode] 5.9s DCL.AvatarRendering.AvatarShape.Tests.AvatarBaseLegacyAnimationPlayModeShould.ReplaceEmoteAnimation_DoesNotEnableAnimator_WhileLegacyAnimationIsPlaying
  • [playmode] 3.0s DCL.SDKComponents.Tween.Tests.TweenUpdaterSystemShould.ContinuousTweensRunIndefinitelyWhenDurationIsZero
  • [playmode] 2.3s DCL.SDKComponents.Tween.Tests.TweenUpdaterSystemShould.MoveContinuousMovesAndCompletesAfterDuration
  • [playmode] 2.1s DCL.SDKComponents.Tween.Tests.TweenUpdaterSystemShould.RotateContinuousCompletesAfterDuration
  • [playmode] 2.1s DCL.SDKComponents.Tween.Tests.TweenSequenceSystemShould.TextureMoveSequenceUpdatesMaterial
  • [playmode] 2.1s DCL.SDKComponents.Tween.Tests.TweenUpdaterSystemShould.TextureMoveContinuousOffsetCompletesAndUpdatesMaterial
  • [playmode] 2.1s DCL.SDKComponents.Tween.Tests.TweenSequenceSystemShould.TweenSequenceWithoutLoopCompletesOnce
  • [playmode] 1.5s DCL.SDKComponents.Tween.Tests.TweenSequenceSystemShould.TweenSequenceWithMoveRotateScaleWithOmittedScale_ResolvesScaleFromCurrentTransform
  • [playmode] 1.5s DCL.SDKComponents.Tween.Tests.TweenUpdaterSystemShould.RotateContinuousPositiveAndNegativeYDirectionsAreOpposite

Full report: run summary · results + editor logs: editmode · playmode

Performance

🏁 Bare-metal benchmark finished — run #35075504820.

Full report

PR #10127, run #35075504820

Overall: ✅ no significant changes

Builds: Windows change, Windows baseline, macOS change, macOS baseline

How to read this table
  • Each build is measured 3 times, interleaved with the other build (change, baseline, change, baseline, ...) in the same session, so both see the same world content and machine state. The values are the median, and (min–max) is the lowest and highest of those runs.
  • Δ is Change minus Baseline (a negative Δ means Change is faster).
  • 🟢 faster / 🔴 slower — a difference that passed every check: the runs are fully separated (every run of one build faster than every run of the other), and the median difference is at least 3% and at least 0.5 ms.
  • ⚪ within noise — the builds' runs overlap, or the difference is tiny; it cannot be told apart from random variation. Treat it as no change.
  • — informational — the 0.1% worst metrics average only the few worst frames of a run, so a single OS hiccup swings them by a lot; they are shown for context and never earn a verdict.
  • ⚠️ no verdict — the two builds' sessions were not comparable (very different sample counts, or too few usable runs), so no conclusion is drawn from them.
  • Exceptions per run — the average number of exceptions in a run's log, not counting teardown ones logged while the app quits. Flagged only on a difference of at least 2 per run and 1.5× the other build; exception kinds the baseline never threw are called out under the table. The Exception breakdown groups all of them by the explorer's report category and exception type (as totals across the runs).
  • A run that logged unusually many exceptions (at least 10 and 5× the median of its build's runs — e.g. a service was down during it) is excluded from all numbers and called out under the table.
  • The Overall line at the top only reacts to a metric that moved on two or more machines, or by 10% or more on one — a single modest 🟢/🔴 cell can still be a statistical fluke.

Apple M1

Metric Baseline Change Δ Result
Samples 4093 (×3) 4043 (×3)
CPU average 21.9 ms (21.6–22.7) 22.2 ms (22.1–22.3) 0.3 ms ⚪ within noise
CPU 1% worst 218.5 ms (218.2–221.6) 218.5 ms (218.0–219.7) -0.0 ms ⚪ within noise
CPU 0.1% worst 225.6 ms (223.6–232.4) 226.1 ms (222.8–228.1) 0.5 ms — informational
GPU average 34.9 ms (34.6–35.4) 35.7 ms (35.4–36.4) 0.9 ms ⚪ within noise
GPU 1% worst 46.3 ms (45.4–47.8) 46.3 ms (46.1–46.5) 0.0 ms ⚪ within noise
GPU 0.1% worst 47.0 ms (46.6–48.8) 47.3 ms (47.1–47.3) 0.3 ms — informational
Exceptions per run 0 0 0 ⚪ no significant change

Intel Core i5

Metric Baseline Change Δ Result
Samples 4691 (×3) 4607 (×3)
CPU average 19.1 ms (18.2–22.2) 19.5 ms (17.0–22.5) 0.4 ms ⚪ within noise
CPU 1% worst 369.6 ms (294.2–434.9) 344.0 ms (255.4–430.3) -25.5 ms ⚪ within noise
CPU 0.1% worst 415.3 ms (413.3–473.4) 392.2 ms (294.5–467.6) -23.2 ms — informational
GPU average 11.9 ms (11.1–13.8) 11.9 ms (10.4–14.6) 0.0 ms ⚪ within noise
GPU 1% worst 223.7 ms (143.6–234.5) 182.2 ms (145.0–296.5) -41.5 ms ⚪ within noise
GPU 0.1% worst 408.1 ms (396.2–469.9) 394.1 ms (286.9–466.1) -14.0 ms — informational
Exceptions per run 0 0 0 ⚪ no significant change

Automation

On demand — comment /visual-tests on this PR to run the visual regression suite against its build.

@decentraland-bot decentraland-bot added the ext-contribution Identifies a contribution which was not initiated by a Unity Developer label Sep 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Slack notification sent to #explorer-ext-contributions for external review.
To re-send, delete this comment and re-add the ext-contribution label.

@decentraland-bot decentraland-bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review — PR #10127: feat: increase camera reel gallery capacity from 500 to 1000 photos

STEP 1 — Scope

Files changed: 1 (Explorer/Assets/DCL/InWorldCamera/CameraReelGallery/CameraReelGalleryController.cs)
Diff: +1 −1 — a single constant value change.

The GRID_POOL_MAX_SIZE constant is consumed once, passed to ReelGalleryPoolManager at construction as the upper bound for the month-grid object pool. THUMBNAIL_POOL_MAX_SIZE (10 000) is unchanged and already far above the new cap.

Subsystem docs and surrounding files reviewed: CameraReelGalleryController manages the gallery UI with infinite-scroll pagination (page size 100, triggered within 12 slots of the bottom). Textures are viewport-culled (nulled off-screen, restored from cache on re-entry). The pool ceiling is never pre-allocated — it only limits how many returned objects the pool will retain.

Deterministic lint pre-flight: scripts/lint/custom-rules.sh does not exist on this branch; the enforcement layer has not landed here. Machine-held rules checked by hand — none fire on this diff.

STEP 2 — Root-cause check ✅

Problem: The backend MAX_IMAGES_PER_USER is being raised from 500 to 1000 (separate ops task). The client-side grid-element pool ceiling must match so the pool can retain enough month-grid objects when a user scrolls through a larger gallery.

Assessment: This is a direct config alignment to a planned backend change — not a symptom-level fix. The constant is the correct place to express this limit. PASS.

STEP 3 — Design & integration ✅

No new units introduced — no system, plugin, manager, service, controller, or stateful helper. The change is a numeric constant on an existing class. No owner search required.

Teardown/consumption trace: No new subscriptions, callbacks, connections, buffers, or measurements. N/A.

PASS.

STEP 4 — Member audit

No public properties or accessors added or changed. N/A.

STEP 5 — Line-level review

Single constant change at line 62. Checked against all blocking-issue categories (R1–R24):

Category Result
R1 hot-path allocations No new allocations
R2 LINQ in hot paths No LINQ added
R3 class refs in structs N/A
R4 ECS lifecycle N/A — not an ECS system
R5 Entity by-ref N/A
R6 Acquire/release symmetry No new acquires
R7 Nullability honesty No nullability changes
R8 Root cause vs symptom Config alignment, not a fix
R9 Logging No logging changes
R10 Catch-scope No catch changes
R11 Cancellation/async No async changes
R12 Single-impl abstractions No new abstractions
R13 Reuse/centralize N/A
R14 Contract honesty N/A
R15 Dead weight N/A
R16–R17 Naming Constant name accurately describes its role
R18 Magic numbers Value is a named constant ✓
R19 File hygiene N/A
R20 .NET idiom cluster N/A
R21 MVC conventions N/A
R22 Tests Config ceiling change — no new behaviour to test; backend still serves 500 until the ops task lands
R23 AI comments No new comments in the diff
R24 Scope discipline Single file, single concern ✓

No blocking issues found.

Sub-agent review (security · architecture · simplicity)

Three parallel review agents (security audit, architecture review, simplicity pass) analyzed the diff. All returned no findings — the change is a bounded, proportional constant increase with no security, architectural, or over-engineering concerns.

STEP 8 — Non-blocking warnings

None. Main scene not modified.

Merge gates

  • R25 — Outstanding comments: 0 unresolved review threads (only bot CI-status comments present). ✅
  • R26 — QA sign-off: Awaiting QA. PR does not carry no QA needed.

REVIEW_RESULT: PASS ✅
COMPLEXITY: SIMPLE
COMPLEXITY_REASON: Single constant value change in a gallery UI controller — no ECS, async, lifecycle, or architectural surface touched.
QA_REQUIRED: YES


Reviewed by Jarvis 🤖 · Requested via GitHub

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext-contribution Identifies a contribution which was not initiated by a Unity Developer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Increase camera reel gallery capacity from 500 to 1000 photos

2 participants