Fix half-pixel offsets in scaling renderer (#231)

* Fix half-pixel offsets in scaling renderer

- This bug was very subtle. It can be hard to notice!
- Context: When the scaling renderer transformation matrix is created,
  it needs to center the image within the border.
- The previous code always evaluated the translation to (0, 0)
- This PR makes half-pixel adjustments to the translation when needed,
  making it impossible to rasterize the texture on a half-pixel
  boundary.
- I spotted this while working on pixel-aspect-ratio support, but it can
  most easily be witnessed in the `conway` example by grabbing the top
  or bottom resize handle on the window and slow dragging it up and down
  by 1-pixel-at-a-time. When you hit a half-pixel bug the entire texture
  will change slightly; some pixels will become hidden or duplicated.

* Bump MSRV
This commit is contained in:
Jay Oster 2021-12-01 21:36:56 -08:00 committed by GitHub
parent b2b8f1140d
commit 2a4ebbf19d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 5 additions and 4 deletions

View file

@ -13,7 +13,7 @@ jobs:
rust: rust:
- stable - stable
- beta - beta
- 1.52.0 - 1.53.0
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -73,7 +73,7 @@ jobs:
rust: rust:
- stable - stable
- beta - beta
- 1.52.0 - 1.53.0
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v2 uses: actions/checkout@v2

View file

@ -2,6 +2,7 @@
| `pixels` version | `rustc` version | | `pixels` version | `rustc` version |
|------------------|-----------------| |------------------|-----------------|
| `0.9.0` | `1.53.0` |
| `0.8.0` | `1.52.0` | | `0.8.0` | `1.52.0` |
| `0.7.0` | `1.52.0` | | `0.7.0` | `1.52.0` |
| `0.6.0` | `1.52.0` | | `0.6.0` | `1.52.0` |

View file

@ -243,8 +243,8 @@ impl ScalingMatrix {
// Create a transformation matrix // Create a transformation matrix
let sw = scaled_width / screen_width; let sw = scaled_width / screen_width;
let sh = scaled_height / screen_height; let sh = scaled_height / screen_height;
let tx = (texture_width / screen_width - 1.0).max(0.0); let tx = (screen_width / 2.0).fract() / screen_width;
let ty = (1.0 - texture_height / screen_height).min(0.0); let ty = (screen_height / 2.0).fract() / screen_height;
#[rustfmt::skip] #[rustfmt::skip]
let transform: [f32; 16] = [ let transform: [f32; 16] = [
sw, 0.0, 0.0, 0.0, sw, 0.0, 0.0, 0.0,