Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: replace relative system/speed scale with user-defined transform callback #11539

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

expikr
Copy link
Contributor

@expikr expikr commented Nov 26, 2024

This is an accompanying Proof-of-Concept for #11449, requesting discussion on what to do with the relative speed scale hint (relative system scale hint should be replaced outright regardless):

Option 1: remove relative speed scale (this implementation)

This is my preference, as the scaling functionality can easily be folded into the developer-defined function. and the main problem raised in the issue is that developer may be surprised by the end-user being able to alter the behavior from environment variables, so it is necessary to move the control exclusively to the developer instead.

Option 2: apply relative speed scale if no custom transform

This is essentially the inverse of the current behavior but with custom rather than system transform. The end user alterable relative speed scale taking a lower precedence than developer-controlled transform function removes a large portion of the element of surprise for the developer. However, the issue might still exist for developers that want specific scaling values and expected to use the events system exclusively without knowing about this new callback functionality.

Option 3a: apply relative speed scale before custom transform

Essentially, this is a philosophical assertion that the end-user wants to have precedence over the behavior, that the inputs are uniformly scaled according to their specification before the developer code is made aware of it.

Option 3b: apply relative speed scale after custom transform

I cannot think of any good reason to do this, considering that this causes a divergence between what the developer expected from their transform output and when they receive the event by inserting an end-user configurable step in between.

@expikr expikr force-pushed the transform-function branch 8 times, most recently from 2cbc0c0 to 0b4cc83 Compare November 26, 2024 15:47
@expikr expikr force-pushed the transform-function branch from 75232a6 to 5ebda77 Compare December 19, 2024 07:12
@expikr
Copy link
Contributor Author

expikr commented Dec 19, 2024

Hmm, TIL Wayland sends accelerated and unaccelerated counts in the same message, so passing the default system transform might not make a lot of sense. Gonna think about how custom transform should fit in.

@Kontrabant
Copy link
Contributor

Kontrabant commented Dec 19, 2024

The backend could just pass a dummy function pointer for the system transform function, which, if set, tells the event callback to pass through the system accelerated values.

@expikr
Copy link
Contributor Author

expikr commented Dec 20, 2024

So something like:

typedef struct {
    float pending_scaled_dx;
    float pending_scaled_dy;
} Wayland_MouseData;

static Wayland_MouseData Wayland_system_scale_data;

void Wayland_OnMouseMessage(float rawX, float rawY, float scaleX, float scaleY) {
    Wayland_system_scale_data.pending_scaled_dx = scaleX;
    Wayland_system_scale_data.pending_scaled_dy = scaleY;
    SDL_SendMouseMotion(rawX, rawY);
}

static void Wayland_ApplySystemScale(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y) {
    Wayland_MouseData *data = internal;
    *x = data->pending_scaled_dx;
    *y = data->pending_scaled_dy;
    data->pending_scaled_dx = 0;
    data->pending_scaled_dy = 0;
}

void Wayland_InitMouse(SDL_VideoDevice *_this) {
    SDL_Mouse *mouse = SDL_GetMouse();
    mouse->ApplySystemScale = Wayland_ApplySystemScale;
    mouse->system_scale_data = &Wayland_system_scale_data;
    ...
}

@Kontrabant
Copy link
Contributor

Was thinking of something simpler, like this: Kontrabant@3e3dd6d

It just uses the system transformation function pointer as a flag for whether to pass accelerated or unaccelerated data, and the function itself is a no-op.

@slouken slouken added this to the 3.x milestone Dec 21, 2024
@expikr
Copy link
Contributor Author

expikr commented Dec 21, 2024

While this proposal pitches a deferable candidate solution, its lemmatic questions should be settled before the release of 3.2.0:

  • are Relative SystemScale/MultiplierScale Hints considered an irrevocable API/ABI committment?
  • are the current form of this interface ruling out certain solutions in the future/painting ourselves into a corner?
  • are there any middleground options that lets us avoid commitment for the time-being?

Considerations that may factor into the answers to the above:

  • is the GDC talk considered a committing promise?
  • what are the current state of utilization of these two hints from the:
    • end-user side, i.e. paranoid CS player config cargo cult
    • end-developer side, i.e. are they depending on it as a functionality, or treating them as something to be mitigated? A quick search on GitHub showed some emulator devs trying it out, finding it janky, and decides to do their own scaling instead.
    • library binding side
  • to what extent are certain API or ABI breakages acceptable within this major version?

@slouken
Copy link
Collaborator

slouken commented Dec 24, 2024

  • are Relative SystemScale/MultiplierScale Hints considered an irrevocable API/ABI committment?

No, hints are not part of the ABI/API commitment, however SDL changes should not completely break applications that use them. For example, if we don't use system scale, but provide a reasonable approximation, or implement the hint via new APIs we provide, that's fine.

  • are the current form of this interface ruling out certain solutions in the future/painting ourselves into a corner?

If by the current form, you mean the hints, the answer is no, see above.

  • are there any middleground options that lets us avoid commitment for the time-being?

I think any middle ground changes are likely to paint us into a smaller corner later, because we need to support everything that is in the current API going forward.

  • is the GDC talk considered a committing promise?

No.

  • what are the current state of utilization of these two hints from the:

    • end-user side, i.e. paranoid CS player config cargo cult

Excellent question. I don't have any data on this, but if users are relying on these hints as-is, then we will need to support them going forward.

  • end-developer side, i.e. are they depending on it as a functionality, or treating them as something to be mitigated? A quick search on GitHub showed some emulator devs trying it out, finding it janky, and decides to do their own scaling instead.

I think this is a pretty likely state of affairs.

  • library binding side

Library bindings should not be relying on hints.

  • to what extent are certain API or ABI breakages acceptable within this major version?

API and ABI breakages are not allowed. Hints can be added or removed as long as they do not completely break games in the process.

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