Skip to content

[Win32] Extend GC.drawImage() handle selection with exact-zoom and monitor-zoom logic#3459

Merged
HeikoKlare merged 1 commit into
eclipse-platform:masterfrom
HeikoKlare:image-enhancement
Jul 22, 2026
Merged

[Win32] Extend GC.drawImage() handle selection with exact-zoom and monitor-zoom logic#3459
HeikoKlare merged 1 commit into
eclipse-platform:masterfrom
HeikoKlare:image-enhancement

Conversation

@HeikoKlare

@HeikoKlare HeikoKlare commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR extends the GC.drawImage() handle-selection logic with two improvements.

Exact imageZoom lookup before nearestAvailableZoom
Before consulting nearestAvailableZoom, the image's persistent handle manager is now queried at the exact imageZoom first. This ensures that a handle previously created for a specific zoom is found and reused even when the provider would not normally supply data at that zoom on its own. For example, a 200% handle pre-created for a 100%-only image is now returned when drawing at the 200%-equivalent pixel size rather than falling back to the 100% handle from nearestAvailableZoom.

Monitor-zoom persistence
The condition for eagerly persisting a handle is extended from nearestAvailableZoom == 100% to also cover any zoom that matches a current monitor's zoom. Monitor zooms are discovered from the zoom reported by each open Shell. When imageZoom or nearestAvailableZoom matches a monitor zoom, the image is likely being drawn repeatedly at that screen's native resolution, so persisting the handle avoids repeated allocations across consecutive draw calls.

As a minor cleanup, getAvailableMonitorZooms() is now called once per getExistingHandle() invocation rather than twice.

Two regression tests are added to ImagesWin32Tests covering both new behaviors.

Related issue

This contributes to #3454. The issue can be reproduced with the snippet provided there: the second line of text will appear non-antialiased.

Before #3429 was merged, the same artifact also appeared in the snippet when the image was loaded twice (once per draw operation); this PR fixes that case as well.

This PR is a prerequisite for #3431.

Screenshots

Before

image

After

image

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Test Results (win32)

   33 files  ±0     33 suites  ±0   4m 9s ⏱️ -42s
4 724 tests +2  4 648 ✅ +2  76 💤 ±0  0 ❌ ±0 
1 253 runs  +2  1 229 ✅ +2  24 💤 ±0  0 ❌ ±0 

Results for commit af3d754. ± Comparison against base commit 7429274.

♻️ This comment has been updated with latest results.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refines Win32 GC.drawImage() image-handle selection to better reuse and persist native image handles across zoom scenarios, addressing inconsistent scaling behavior at non-100% monitor zoom.

Changes:

  • Prefer an existing persistent handle at the exact computed imageZoom before falling back to nearestAvailableZoom.
  • Persist handles not only for nearestAvailableZoom == 100, but also when imageZoom or nearestAvailableZoom matches a zoom currently in use by available shells/monitors.
  • Add Win32 regression tests covering exact-zoom preference and monitor-zoom persistence.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java Extends handle lookup/persistence logic for GC.drawImage() with exact-zoom and monitor-zoom persistence behavior.
bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/ImagesWin32Tests.java Adds regression tests verifying handle selection at exact imageZoom and persistence at monitor zoom.

Comment thread bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java Outdated
@HeikoKlare
HeikoKlare marked this pull request as ready for review July 22, 2026 13:49
if (bestFittingHandle != null) {
return bestFittingHandle;
}
if (monitorZooms.contains(nearestAvailableZoom) || nearestAvailableZoom == 100) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I can see why persisting a handle matching the monitor zoom or 100% zoom would be beneficial here (since those will likely be reused multiple times), but is it really useful to persist a handle for the nearest available zoom if it matches neither of those zooms?

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.

You are right, those handles should not be persisted. I have removed this case. Now this PR just adds the exact-zoom retrieval from existing handles and for zooms that fit to one of the shell zooms.

GC.drawImage() operations use a temporary image handle mechanism that
selects the best-fitting native handle for each pixel size. A recent
change introduced the concept of "nearest available zoom" so that
handles can be reused when consecutive draw calls at different sizes map
to the same underlying image data, and eagerly persists handles when the
nearest available zoom is 100%.

This change extends the handle-selection logic in two ways.

Exact imageZoom lookup before nearestAvailableZoom:
Before consulting the nearestAvailableZoom, the image's persistent
handle manager is now queried at the exact imageZoom first. This ensures
that a handle explicitly created for a zoom — even one the provider
would not normally supply on its own — is found and reused. For example,
when win32_getHandle() has been called at 200% for a 100%-only image,
drawing at the 200%-equivalent pixel size now returns the pre-existing
200% handle rather than the 100% handle from nearestAvailableZoom.

Monitor-zoom persistence:
The condition for eagerly persisting a handle is extended from
"nearestAvailableZoom == 100%" to also include any zoom that matches a
current monitor. Monitor zooms are obtained from the zoom reported by
each open Shell via Display.getShells(). When imageZoom or
nearestAvailableZoom matches a monitor zoom, the image is likely being
drawn repeatedly at that screen's native resolution, so persisting the
handle avoids repeated allocations across consecutive draw calls. As a
minor cleanup, getAvailableMonitorZooms() is now called once and its
result reused within getExistingHandle() instead of being called twice.

Two regression tests are added to ImagesWin32Tests to cover the new
behaviors: one verifying that an existing handle at the exact imageZoom
is preferred over a nearestAvailableZoom handle, and one verifying that
drawing at the monitor zoom creates a persistent handle that is then
reused via win32_getHandle() without a second native allocation.

See eclipse-platform#3419

Contributes to
eclipse-platform#3454
@HeikoKlare
HeikoKlare merged commit 1835e73 into eclipse-platform:master Jul 22, 2026
18 checks passed
@HeikoKlare
HeikoKlare deleted the image-enhancement branch July 22, 2026 15:06
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.

3 participants