ponedjeljak, 27. lipnja 2016.

Week 5: Output unplug journey

I was doing some housework over the weekend and lost track of time. It might sound silly, but I thought yesterday was Saturday. That happens here when I go on Summer Vacation. But well, 24 hours isn't that behind, no? :)

Now, on to business. As mentioned in my previous blog post, I submitted my first batch of patches for review. The review was done quickly by my two mentors, Pekka and Quentin, so the second batch was already on the list on Wednesday.

Once that was done, I was exploring what was necessary to get weston to work when all outputs get unplugged at runtime after at least one was plugged in during the session.

The first thing I did was get the testing environment ready. I wrote a small module which weston loads at runtime and unplugs all outputs in the X11 (theoretically, in any backend, as there is no backend specific code) backend. The module initiates a timer, and only triggers the unplug after the timer counts down to zero. I set the timer to allow me to start a couple of test programs before all outputs disappear. So far, it has served me well.

By doing that, I uncovered one minor problem in the X11 backend. When I manually unload the outputs, X11 window(s) representing (each) output remain there, but frozen. The problem was that an xcb_flush was missing in the output destroy handler, but was called from the "x" button handler (close button).

Once that was fixed, I went on with testing. With help of another testing backend that I wrote in the past (this one is strictly X11 backend specific) which allows me to hotplug an X11 output after certain amount of time, I had a perfect "output unplug, output plug back in" scenario with the X11 backend.

After that was in place, and I started running tests, the crashes happened instantly after an output was unplugged and then plugged back in. The problem was that the views (objects which represent visible part(s) of a surface) were still using old (destroyed) outputs, and nothing was updating them. My idea was, when plugging in an output and there were no outputs present before, to simply force-move all views to a new output. This was simple enough and it just worked. At least I didn't notice any problems.

However, Pekka suggested that views shouldn't be force-moved to a new output only after new primary output gets attached. Instead, it should be done when any output gets attached just in case a surface happens to be in a region that's not part of the new primary output. By doing that, we would ensure that all surfaces remain displayed after a number of outputs gets unplugged and plugged back in. I still haven't considered this, but I'll sure take a look at it. I just need to verify if my testing environment can test this scenario.

That was my small journey last week. I didn't do anything else because, as mentioned above, I was doing work around the house and had family over. I still didn't finish the mentioned work, due to unpredictable complications that happened, but should be done by tomorrow, or in the worst case, at Wednesday.

I don't want to repeat myself regarding my goal for the following week. I already outlined in my previous post that the goal was to get the first part of GSoC done by end of the month. That's this week (well, it does stretch to the fist 3 days of July too), and I hope I can keep up on my promise (I'm looking at you, unexpected problems!).

And finally, last week was Midterms Week for GSoC. I hope I passed and will be able to continue to work on weston for the rest of GSoC.

nedjelja, 19. lipnja 2016.

Week 3 and 4: Starting with zero outputs: Done

First of all, I apologize for not writing a blog post last week. The thing is, I had many exams this week and spent the week before studying, so I didn't manage to tackle anything that was worth reporting.

While I didn't manage to complete my goal that I set before myself two weeks ago, I still did some work (largest amount yet) that's worth reporting. To be clear, I didn't manage to look at how to make weston behave when you unplug an output. The rest of what I set to do last week was done this week.

Now, on to business. This past week I spent a number of hours trying to tackle an issue in subsurface implementation that happens when a program that uses subsurfaces is started when no outputs were there. The issue was that a subsurface wasn't rendered properly and instead of subsurface, a main surface was rendered in its place. After hours of unsuccessful debugging, my mentor, Pekka, hinted that it might actually be an issue in gl-renderer. He was right.

Two weeks ago, I hinted at a problem when weston was started with zero outputs on how it would crash when an EGL extension is being used. The thing is that EGLSurface which was used for displaying rendered content was tied to an output, and only when an output gets plugged in, an EGLSurface would get created and there would be something you could an EGLContext to with eglMakeCurrent

Pekka gave me two ideas on how to solve this problem.

First idea was to use EGL_KHR_surfaceless_context if it was available. When EGL_KHR_surfaceless_context is available, eglMakeCurrent can attach EGLContext to EGL_NO_SURFACE.

The second idea was to use a PbufferSurface, a dummy surface which will always be created at gl-renderer initialization and can be used instead of EGL_NO_SURFACE when calling eglMakeCurrent.

In the end, we settled for both; Use  EGL_KHR_surfaceless_context if available, otherwise fall back to using PbufferSurface. By doing that, the issues in subsurface implementation and crashes when creating an EGL or DMABUF were gone.

But, that wasn't an end to subsurface issues. Another problem was that weston used outputs to indicate that a surface or a view is mapped. A mapped view or a surface is a view/surface which is ready to be displayed. The current logic is that if a view or a surface had an output assigned, it was ready to be displayed. That of course wouldn't work when there is no output present. So, I had lots of checks that were checking if a surface or view were mapped failing, which lead to another issues, especially in subsurface implementation.

In the end, I had to introduce a new, output independent check for checking if a surface or a view is mapped and change all the places that did the actual mapping to operate on new variables. That required me touching the compositor and various shells' code, but I managed to do it, and with that, solve all my problems with all demo applications.

But journey doesn't end there just yet. An issue that I didn't mention, but that was there ever since I got weston to work with zero output is weston-keyboard failing to start. When setting up a virtual keyboard, it tries to set an input method as toplevel, and that setting depends on a valid output. Since there is no valid output at startup, it can't be set as toplevel and instead it would just crash. I solved the problem by moving the toplevel setting into a separate function and called it only if there was an output present at runtime or if there was no output present at runtime, but an output was created later. This seems to work just fine and I have yet to find any issues with this implementation.

That covers the three major things I was doing this past week. I am proud to say that I have submitted my work so far for a review. With the midterms closing in, both Pekka and I thought that I should present what I did up to now.

As for future work, I won't rush myself this time and say "I'm going to do this ... I'm going to do that". So far, everything I've set out to work on had a "side quest" for me. So, I'll just say that the plan is to finish the remaining work for zero outputs case before end of the month. That includes getting weston to behave on all outputs being unplugged at runtime, and of course, an automated test suite to test all this.

My last exam this month is on Tuesday (2 days from now), and after that I'll have all the time I need to work on weston.

nedjelja, 5. lipnja 2016.

Week 2: Getting weston to work with zero outputs

While this week was also busy, I still have managed to get some work done.

This week, my goal was to get weston to run when there are no outputs present. Fixing this mostly required adding a couple of null pointer checks to prevent weston from crashing.

However, this also introduced some problems. When an output is NULL, weston subsurfaces don't get mapped correctly. Currently, the code for configuring a subsurface will assert when the output list is null and that leads weston to a crash.

Pekka pointed out in order to solve this, I need to fix mapping functions not to rely on an output member, which I will be working on in the following days.

Also, attaching an EGL or DMABUF will result in a crash when no outputs are present. I have tracked this down to a call to image_target_texture_2d. This might be a bug in Mesa's EGL implementation. So far, I've made the function abort attaching in case there are no outputs, but I need to find a way to reattach it when an output appears. Otherwise, nothing gets displayed.

With the fixes from above, minus the problems mentioned, weston seems to handle zero outputs nicely. I have tested all of the weston demo apps and they start with no outputs present and get displayed correctly when an output gets attached.

My goal for the next week is to fix all of the issues mentioned above and make weston behave correctly when an output gets removed at runtime.