Skip to main content
Known Participant
Nov 2, 2026 7:22 AM UTC
Open for Voting

Detail view runs a transparent-area check on every photo, using 39–54% of Lightroom's CPU while culling

Description of Issue


- While culling in Detail view with the arrow keys, every photo step starts a Camera Raw task named "find transparent" on 6 worker threads. In three Time Profiler recordings it used 39%, 46% and 54% of all of Lightroom's CPU: more than decoding, demosaicing and rendering the photos put together.


- It happens with the Crop tool closed and no editing. In two of the recordings only D and the Left/Right arrow keys were pressed.


- It's specific to Detail view: moving through the same photos in Grid view with the same keys runs no check at all, and Lightroom uses 0.18 cores instead of 5.2


- It runs for every photo, whatever the camera, lens, file type or crop, and it found nothing: all 79 checks over 55 photos from a Sony A7R III, a Panasonic GH5 and four iPhones (ARW, RW2, HEIC and JPEG; three cropped, one of them also straightened 4.9°) left hasVisibleTransparentAreas false. Each check cost about the same, 1.5–2.2 CPU-seconds, for 12 MP and 42 MP photos alike.


- Its result only feeds the Crop panel's Generative Expand hint (cropController.hasVisibleTransparentAreas, read by CropSettingsPanel, GenerativeExpandOnboarding and EditParameters2), which isn't on screen while culling


- Why it's so expensive: 77–79% of the task's samples land right after one atomic add (ldaddal, acquire+release ordering) to a counter shared by all six threads. The loop maps each point through a 2D transform, tests it against the image bounds and increments that counter for every point inside (CameraRaw function at +0x462cac, the add at +0x462ee0, arm64 slice). All six threads fight over one cache line on every point.


- Cancelling a check doesn't stop it. When the next photo starts a new check, the previous one keeps running: passes overlap, and Lightroom reached 9.3 cores busy.


- Lua path (Lightroom 9.6 bytecode): ~0.3 s after each photo loads, DevelopCropController's delayed crop update (the _delayedUpdateUserCropAndSelectedCropItem timer) calls maybeCheckVisibleTransparentAreas; NiDevelopModel.applyUndoableChangesToCurrentDevelopEditSession calls it after every edit. maybeCheckVisibleTransparentAreas skips only videos; recheckVisibleTransparentAreasAsync cancels the previous task and posts negative:hasVisibleTransparentAreas(params) to a worker thread. The delayed update already tests whether the crop is the whole, unrotated image, but only to label the aspect "original"; it calls the check either way.

 

Step-by-step Reproduction Instructions


1. Launch Lightroom, open an album of photos (any camera; seen with Canon CR3, Sony ARW, Panasonic RW2 and iPhone HEIC/JPEG files), select a photo and press D for Detail view. Make sure the Crop tool is closed.


2. With Xcode installed, in Terminal:
   xcrun xctrace record --template "Time Profiler" --attach $(pgrep -x "Adobe Lightroom") --time-limit 60s --output lr.trace
   Switch to Lightroom right away and press the Right arrow about once a second until the recording ends.


3. Open lr.trace in Instruments. In the Time Profiler's call tree, choose Separate by Thread: threads named "find transparent (thread index 0)" to "(thread index 5)" appear, a new set for each photo, and together use the most CPU. Their heaviest stack ends in CameraRaw.

 

4. Without Xcode: while pressing the Right arrow once a second, run
   sample "Adobe Lightroom" 10 -file lr-sample.txt
   then grep -c "find transparent" lr-sample.txt (each photo step adds six such threads).

 

5. For comparison, record while Lightroom sits in Detail view with no key pressed (no "find transparent" threads after the last check finishes), or press G and move through the grid with the arrow keys (none at all)

 

The Expected Result


- Browsing photos doesn't run a transparent-area check. It runs when its answer is shown (the Crop panel / Generative Expand), or once per photo and settings, cached.


- When nothing in a photo's settings can expose transparent areas (crop inside the image, no rotation, no geometry transform), the answer is "no" without rendering anything.


- Cancelling a check stops its work.


- The pixel count uses per-thread counters, summed once at the end, not an atomic increment per point on one shared counter.

 

The Actual Result


- 2026-11-02 00:32 (UTC-6), 60.9 s Time Profiler. Crop tool closed; D, then Left/Right about once a second, sent by a script (no other keys, no mouse):
  - Lightroom used 318.3 CPU-seconds (5.2 cores on average, 5.7 while browsing).
  - "find transparent": 146.8 CPU-seconds (46.1%), 300 threads = 50 passes of 6 threads, for 44 photos loaded.
  - Next biggest: unnamed worker threads 40.4 CPU-s, InterpolateBayer 29.2, main thread 26.3, dng_read_tiles_task 16.0, xlase-DecodePlanes 15.6, cr_apply_opcode_list 14.2.
  - CPU per pass (all 6 threads): median 1.51 s (middle half 1.29–1.63 s), max 14.1 s.
  - None in the 5.5 s before the first key press.
  - Peak: 9.3 cores busy at 40.5 s, with two passes running together.
  - 81% of the task's samples in one CameraRaw function, 77% on the instruction right after the ldaddal.


- 2026-11-02 00:01, 30.8 s Time Profiler of normal manual culling (about 15 photo steps):
  - "find transparent": 34.8 of Lightroom's 88.9 CPU-seconds (39.2%), 13 passes.
  - For the last 3.5 s, with no key pressed, this task alone held 6 cores at 100%.
  - No mouse events were handled during the recording, so it isn't caused by cropping.

 

- 2026-11-02 01:02, 90.9 s Time Profiler over other cameras' photos, Crop tool closed, D then Left/Right about once a second (script). Lightroom was launched with -runLua code that logged, 10 times a second, the photo shown, the crop controller's crop values, _transparencyCheckGen (one step per check started) and hasVisibleTransparentAreas:
  - "find transparent": 132.4 of Lightroom's 245.1 CPU-seconds (54.0%), 78 passes; 79 checks started for 72 photo visits (55 photos). Most iPhone HEIC photos got two checks each.
  - CPU per check (median, all 6 threads): Sony A7R III ARW, 42 MP: 1.69 s (36 checks). Panasonic GH5 RW2, 20 MP: 1.49 s (17). iPhone 12 mini HEIC, 12 MP: 2.21 s (20). iPhone 15 Pro JPEG, 12–38 MP: 1.98 s (4).
  - Result: hasVisibleTransparentAreas was false after every check, including the three cropped photos (one also straightened by 4.9°).
- 2026-11-02 01:13, 60.8 s Time Profiler, Grid view control: the same Canon shoot and script as the 00:32 recording, but G instead of D, then Left/Right about once a second (42 selection steps):
  - No "find transparent" threads, and no Camera Raw worker threads at all.
  - Lightroom used 11.0 CPU-seconds (0.18 cores; 0.25 CPU-s per step), against 318.3 CPU-seconds (5.2 cores; 7.2 CPU-s per step) in Detail view.


- Each pass starts 6 new threads. Lightroom started 7,561 threads in the 60-second recording; Camera Raw creates a new set for each task pass (1,486 BuildPyramidLevel, 1,074 dng_linearization_image, 834 cr_apply_opcode_list, 684 dng_read_tiles_task, 300 find transparent).

 

System Details


- Lightroom 9.6 (Mac App Store), build 20260923-1659-a32d844, arm64
- macOS 27.0.1 (26A434), MacBook Pro 16" (MacBookPro18,2), Apple M1 Max (10 cores), 64 GB RAM
- Library: 41,490 photos, 211 albums, 4,818 stacks; local library 78–85 GB (40 GB originals, 29 GB proxies, 12 GB previews); all proxies stored locally, photo cache limit 50 GB