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

Merges context creation code. #1029

Merged
merged 11 commits into from
Sep 11, 2018

Conversation

goddessfreya
Copy link
Contributor

@goddessfreya goddessfreya commented Jun 13, 2018

Signed-off-by: Hal Gentz [email protected]

Does #1028

Currently only 4 platforms need testing and one platform needs to get working.

Compiles with the following backends:

  • Linux | X11 | EGL
  • Linux | X11 | GLX
  • Linux | Wayland | EGL
  • Linux | OSMesa
  • Windows | WGL
  • Windows | EGL
  • Web | Emscripten
  • macOS
  • iOS
  • Android

Has been tested with the following backends:

  • Linux | X11 | EGL
  • Linux | X11 | GLX
  • Linux | Wayland | EGL
  • Linux | OSMesa
  • Windows | WGL
  • Windows | EGL
  • Web | Emscripten
  • macOS
  • iOS
  • Android

@goddessfreya goddessfreya changed the title Merges context creation code. [WIP] [Help Requested] Merges context creation code. Jun 13, 2018
@keringar
Copy link

I have a windows desktop and android device so I can help. My finals are almost over so I'll be able to help soon.

@kvark
Copy link
Contributor

kvark commented Jul 6, 2018

@zegentzy your PR is not configured for me to edit, so here is the iOS fix - kvark@5eb2598
Not tested, just built.

@goddessfreya
Copy link
Contributor Author

Thank you @kvark!

@francesca64 Unless someone wants to volunteer for testing these changes on the remaining platforms, I think this is as complete as it can get. Can you review/merge it?

@francesca64
Copy link
Member

I can test on macOS, iOS, and Android (though that's part of review anyway). I'll start working my way through this tomorrow.

CHANGELOG.md Outdated
@@ -1,4 +1,6 @@
# Unreleased
- ***BREAKING*** Headless contexts have been removed. Please instead use
Copy link
Member

@francesca64 francesca64 Jul 8, 2018

Choose a reason for hiding this comment

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

  • There should be a newline between the header and the entry list
  • This BREAKING doesn't conform to the style precedent set by winit's CHANGELOG, which is Breaking:
  • This sounds a bit misleading, as in, it makes it sound like the functionality has been removed, rather than that the separate API has been removed
  • Adding an example program makes API migrations nicer for everyone

(whoops, I was supposed to "Start a review" instead of commenting... well, enjoy this early preview)

Copy link
Member

@francesca64 francesca64 left a comment

Choose a reason for hiding this comment

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

Alright, spending 3 hours reviewing this should be enough for one day...

So far I've only tested on X11 and Android. X11 is broken, but Android appears fine. However, I didn't test any headless stuff.

I can't test things definitively until you've created a suitable example program.

src/lib.rs Outdated
//!
//! - `window` allows you to create regular windows and enables the `WindowBuilder` object.
//! - `headless` allows you to do headless rendering, and enables
//! the `HeadlessRendererBuilder` object.
//!
//! By default only `window` is enabled.
Copy link
Member

Choose a reason for hiding this comment

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

The use of the word "only" no longer makes sense.

unsafe {
match self.context {
GlContext::Egl(_) | GlContext::Glx(_) => {
assert_eq!((self.display.xlib.XResizeWindow)(
Copy link
Member

@francesca64 francesca64 Jul 8, 2018

Choose a reason for hiding this comment

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

This assertion fails when running the window example! I can tell you neither researched nor tested this, since Xlib functions return 1 upon success: https://github.com/mirror/libX11/blob/78851f6a03130e3c720b60c3cbf96f8eb216d741/src/ChWindow.c#L53

Anyway, why are you resizing the window? resize is supposed to be called to resize the context after the window itself has been resized by other means.

Also, please include trailing commas after all match arms. It's also preferable for unsafe blocks to be tighter, since this encloses more than it needs to.

Copy link
Contributor Author

@goddessfreya goddessfreya Jul 9, 2018

Choose a reason for hiding this comment

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

This was "tested" by seeing if this panics: gfx-rs/gfx@5399982 . I've now discovered that it incorrectly doesn't call the resize function. This was "researched" by referring to http://xfree86.org/current/XResizeWindow.3.html, which doesn't make it clear that it will return a 1 upon success. I assumed 0 upon success because, well, isn't that the standard?

I was under the impression that resize is what you call to resize the window.

Edit: Anyways, with this info I know that X11 doesn't need a resize function.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry if I was mean about this. I tend to take mistakes in PRs personally.

match *self {
Context::X(ref _ctxt) => (),
Context::X11(ref ctxt) => ctxt.resize(window.get_xlib_window().unwrap(), width, height),
Copy link
Member

Choose a reason for hiding this comment

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

Why is a no-op no longer adequate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I (incorrectly) added resizing support. Not actually necessary to be part of this PR.

Context::Wayland(ref ctxt) => ctxt.get_pixel_format()
Context::X11(ref ctxt) | Context::X11Context(_, ref ctxt) => ctxt.get_pixel_format(),
Context::Wayland(ref ctxt) | Context::WaylandContext(_, ref ctxt) => ctxt.get_pixel_format(),
Context::OsMesa(ref _ctxt) => panic!(),
Copy link
Member

Choose a reason for hiding this comment

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

What is the purpose of this panic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OSMesa doesn't expose a swap_buffers. OSMesa's get_pixel_format panics. OSMesa has no resize function. I just realized the headless ones should be panicking the same.

pixel_format: PixelFormat,
}

pub struct HeadlessContext {
context: id,
Copy link
Member

Choose a reason for hiding this comment

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

This context appears to never be release'd (meaning, it leaks). Using IdRef instead would fix that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Neither was the old one. I guess the headless one received less scrutiny. Will fix.

src/lib.rs Outdated
/// surface is resized.
///
/// The easiest way of doing this is to call this method for each `Resized` window event that
/// is received with the width and height given by the event.
Copy link
Member

Choose a reason for hiding this comment

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

This is also a good opportunity to update this line, since these days you take the LogicalSize from Resized, convert it into a PhysicalSize, and pass that.

src/lib.rs Outdated
let gl_attr = gl_attr.map_sharing(|ctxt| &ctxt.context);
platform::Context::new_context(el, &pf_reqs, &gl_attr, shareable_with_windowed_contexts)
.map(|context| Context {
context: context,
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer Context { context } for maximum cleanliness.

src/lib.rs Outdated
/// out of memory, etc.
/// The generated gl context is of course shareable with other contexts
/// made from this function. It is possible to also share it with a headless
/// context made with the shareable_with_windowed_contexts flag set to true.
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer "gl" be changed to "OpenGL", and both shareable_with_windowed_contexts and true should be in backticks.

I'm not sure how appropriate "of course" is here, since it seems to take the feature for granted. Considering that context sharing is never explained, the implication that this functionality is inherently expected could seem odd to readers.

pub trait GlContext {
pub trait GlContext
where
Self: Sized,
Copy link
Member

Choose a reason for hiding this comment

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

This added constraint is a breaking change, so must be mentioned in the CHANGELOG.

//! # Features
//!
//! This crate has two Cargo features: `window` and `headless`.
//! This crate has one Cargo feature: `window`.
Copy link
Member

Choose a reason for hiding this comment

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

The removal of a feature can cause build failures, so it must be mentioned in the CHANGELOG.

@goddessfreya
Copy link
Contributor Author

goddessfreya commented Jul 9, 2018

swap_buffers, get_pixel_format and resize, under my understanding, should be panicking for headless contexts. It's nonsensical to, for example, call eglSwapBuffers when there is no visible native window to swap with, even if valid.

(In egl's case, if surface isn't a native window, the function silently does nothing.)

@kvark
Copy link
Contributor

kvark commented Jul 9, 2018

@francesca64

Alright, spending 3 hours reviewing this should be enough for one day...

Thank you for such a detailed and thoughtful review, as well as testing. Hope you aren't getting burned by this, and it the issues are to be resolved nicely.

@francesca64
Copy link
Member

@zegentzy I get what you're saying about the panics, but at bare minimum these panics would have to print explanations and have accompanying documentation notes. Though, what this tells me is that this API design is fairly problematic. I don't think it's reasonable for the API to misrepresent the context's capabilities.

@kvark I won't deny that I'm pushing myself harder than I should, but no one will want to contribute to glutin if PRs don't get reviewed. Just make sure I don't try to become the maintainer of any more of tomaka's repos!

@goddessfreya
Copy link
Contributor Author

I'd like to note that users can only call those three functions from GlWindow, which they won't have if they used a headless context. Anyways, I'll add messages and notes to the documentation.

@francesca64
Copy link
Member

Alright, that sounds reasonable then. If it's outright impossible for a GlWindow to be constructed with a headless context, then you don't even need to mention it in the docs, and it could be unreachable.

@goddessfreya goddessfreya force-pushed the merge-contexes branch 2 times, most recently from 68a0c71 to 83d0768 Compare July 10, 2018 01:28
@goddessfreya
Copy link
Contributor Author

@francesca64 Ok, I've replaced the panics with unreachable and haven't touched the docs.

@goddessfreya
Copy link
Contributor Author

I just noticed you added iOS support to the CI, @francesca64. Thank you! I'll be sure to fix the compile failure.

@goddessfreya goddessfreya force-pushed the merge-contexes branch 2 times, most recently from 3b115ad to 880bca2 Compare July 24, 2018 07:51
@goddessfreya
Copy link
Contributor Author

@francesca64 I'm like 98% certain the x11-dl build failure isn't caused by me. Can you check it out?

@francesca64
Copy link
Member

Yup: AltF02/x11-rs#88

Is this PR considered complete now? I would still like to see an example program added.

@goddessfreya goddessfreya changed the title [WIP] [Help Requested] Merges context creation code. [Help Requested] Merges context creation code. Jul 26, 2018
> different device context than the one referenced by , or if the contexts are
> otherwise incompatible (for example, one context being associated with a
> hardware device driver and the other with a software renderer), then
> ERROR_INVALID_OPERATION is generated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing some stuff due to <...> getting removed. Original sections:

  * If <hShareContext> is neither zero nor a valid context handle, then
    ERROR_INVALID_OPERATION is generated.

...

  * If the OpenGL server context state for <hShareContext> exists in an
    address space that cannot be shared with the newly created context,
    if <shareContext> was created on a different device context than the
    one referenced by <hDC>, or if the contexts are otherwise
    incompatible (for example, one context being associated with a
    hardware device driver and the other with a software renderer), then
    ERROR_INVALID_OPERATION is generated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch, my bad.

CHANGELOG.md Outdated
@@ -1,5 +1,9 @@
# Unreleased

- ***Breaking*** The entire api for Headless contexts have been removed. Please instead use `Context::new()` when trying to make a context without a visible window. Also removed `headless` feature.
Copy link
Member

Choose a reason for hiding this comment

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

"api" should be capitalized, "Headless" should be lowercase.

Copy link
Contributor

Choose a reason for hiding this comment

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

... contexts [have -> has] been removed ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks.

CHANGELOG.md Outdated
@@ -1,5 +1,9 @@
# Unreleased

- ***Breaking*** The entire api for Headless contexts have been removed. Please instead use `Context::new()` when trying to make a context without a visible window. Also removed `headless` feature.
- ***Breaking*** Structs implementing the `GlContext` trait must now be sized.
Copy link
Member

Choose a reason for hiding this comment

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

Structs aren't the only thing that can implement traits, so "Types" is probably better. Changing "sized" to Sized could also be clearer.

src/lib.rs Outdated
) -> Result<Self, CreationError>
{
let ContextBuilder { pf_reqs, gl_attr } = context_builder;
let gl_attr = gl_attr.map_sharing(|ctxt| panic!());
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this panic! have a nice little message? Ideally referring the user to the docs.

Copy link
Member

Choose a reason for hiding this comment

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

Also, ctxt is an unused var. You should go with _ctxt so everyone doesn't see a warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks


fn main() {
let mut events_loop = glutin::EventsLoop::new();
let mut size = glutin::dpi::PhysicalSize {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason you chose this over PhysicalSize::new?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I didn't check if a PhysicalSize::new function exists. Updated.

src/lib.rs Outdated
pub fn new(
window_builder: WindowBuilder,
context_builder: ContextBuilder,
events_loop: &EventsLoop,
) -> Result<Self, CreationError>
{
let ContextBuilder { pf_reqs, gl_attr } = context_builder;
let gl_attr = gl_attr.map_sharing(|ctxt| panic!());
Copy link
Member

Choose a reason for hiding this comment

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

ctxt is unused and generates a warning.

src/lib.rs Outdated
unsafe {
platform::Context::new(window_builder, events_loop, &pf_reqs, &gl_attr)
.map(|(window, context)| GlWindow {
window: window,
Copy link
Member

Choose a reason for hiding this comment

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

window: window -> window (the same goes for the context: context below)

@@ -10,13 +10,12 @@ use winit;
use Api;
Copy link
Member

Choose a reason for hiding this comment

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

Api, ContextError, and PixelFormat are all unused.

@francesca64
Copy link
Member

I'm starting to go through and give this a final round of testing on all platforms. So far this looks pretty much ready, though it seems like the EGL module has several unused items now.

Signed-off-by: Hal Gentz <[email protected]>
@goddessfreya goddessfreya mentioned this pull request Aug 15, 2018
14 tasks
src/lib.rs Outdated
context: Context { context },
})
}
platform::Context::new(window_builder, events_loop, &pf_reqs, &gl_attr)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@francesca64 Not all the platforms are safe. Some platforms have unsafe "new" functions (the platforms which support context sharing). Now it won't compile.

@goddessfreya
Copy link
Contributor Author

@francesca64 The platforms which currently support context sharing had their "new" functions marked unsafe. Your latest commit stops this PR from compiling.

@francesca64
Copy link
Member

Oh, I see. Having that be inconsistent seems rather surprising; is there a better way you can handle that?

@goddessfreya
Copy link
Contributor Author

@francesca64 We can mark them all unsafe or we could disable the warning. The second is probably better.

@francesca64
Copy link
Member

I'm in favor of disabling the warning (assuming I'm correct in understanding that this doesn't affect the public API) with the proviso that a comment also be added explaining why the warning was disabled.

@goddessfreya
Copy link
Contributor Author

@francesca64 Done.

@goddessfreya
Copy link
Contributor Author

@francesca64 What's the progress on getting this merged?

@francesca64
Copy link
Member

Super sorry for the repeated delays! I was going through a tough time emotionally for a while, and I've only just recently returned to being active on glutin and winit. I think we're ready to merge now; thanks so much for all the hard work!

@francesca64 francesca64 merged commit 209ab92 into rust-windowing:master Sep 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants