Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-07-16 Thread Daniel Stone
Hi,

On 11 July 2015 at 02:05, Bryce Harrington br...@osg.samsung.com wrote:
 On Fri, Jun 26, 2015 at 02:16:55PM -0500, Derek Foreman wrote:
 On 22/06/15 11:25 AM, Daniel Stone wrote:
  Hi,
  Thanks to everyone who reviewed the previous series. This new series
  cleans up the previous patches, introduces a few fixes (e.g. not relying
  on a repaint to pull us out of DPMS), and crucially adds support for the
  libdrm TEST_ONLY interface (allowing us to check before we commit, e.g.
  that a particular plane combination is workable), using the new cursor
  API from libdrm.

 Everything up to and including 8/16 seems like beneficial clean-up or
 bug fix that could land independently of later bits?

 For that half,
 Reviewed-By: Derek Foreman der...@osg.samsung.com

 (The rest I haven't had a chance to look at yet)

 At least for patches 1-6 I tend to agree; they're good cleanup or
 refactoring, and no reason not to just get them landed.  Patch 7 started
 to look a bit more ambitious to me so I stopped there.  But with 1-6,
 might save time having to rebase them.  Unfortunately they already don't
 apply, but if you can split them out from the remainder of the patchset,
 I'd be +1 for just landing them immediately.

Thanks for this. I've rebased the first six across the libweston
divide and pushed those now. I think 7-10 should be very uninvasive
once rebased as well; it's only where we get to 11 and upwards that it
starts getting a bit hairy.

Cheers,
Daniel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-07-13 Thread Pekka Paalanen
On Fri, 10 Jul 2015 18:05:48 -0700
Bryce Harrington br...@osg.samsung.com wrote:

 On Fri, Jun 26, 2015 at 02:16:55PM -0500, Derek Foreman wrote:
  On 22/06/15 11:25 AM, Daniel Stone wrote:
   Hi,
   Thanks to everyone who reviewed the previous series. This new series
   cleans up the previous patches, introduces a few fixes (e.g. not relying
   on a repaint to pull us out of DPMS), and crucially adds support for the
   libdrm TEST_ONLY interface (allowing us to check before we commit, e.g.
   that a particular plane combination is workable), using the new cursor
   API from libdrm.
  
  Everything up to and including 8/16 seems like beneficial clean-up or
  bug fix that could land independently of later bits?
  
  For that half,
  Reviewed-By: Derek Foreman der...@osg.samsung.com
  
  (The rest I haven't had a chance to look at yet)
 
 At least for patches 1-6 I tend to agree; they're good cleanup or
 refactoring, and no reason not to just get them landed.  Patch 7 started
 to look a bit more ambitious to me so I stopped there.  But with 1-6,
 might save time having to rebase them.  Unfortunately they already don't
 apply, but if you can split them out from the remainder of the patchset,
 I'd be +1 for just landing them immediately.

Sure. I've been holding off on them with the prospect of landing Mario
Kleiner's compositor patches first, just in case there was any
conflict, but since I redid Mario's patches and I'm still waiting for
the final ack on my analysis which means I can (and probably already
need to) rebase them, I'm totally fine landing these
clean-up/preparation patches.

Of the current libweston series, there are still changes coming to
compositor-drm.c for config handling, but I don't think they should
conflict much.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-07-10 Thread Bryce Harrington
On Fri, Jun 26, 2015 at 02:16:55PM -0500, Derek Foreman wrote:
 On 22/06/15 11:25 AM, Daniel Stone wrote:
  Hi,
  Thanks to everyone who reviewed the previous series. This new series
  cleans up the previous patches, introduces a few fixes (e.g. not relying
  on a repaint to pull us out of DPMS), and crucially adds support for the
  libdrm TEST_ONLY interface (allowing us to check before we commit, e.g.
  that a particular plane combination is workable), using the new cursor
  API from libdrm.
 
 Everything up to and including 8/16 seems like beneficial clean-up or
 bug fix that could land independently of later bits?
 
 For that half,
 Reviewed-By: Derek Foreman der...@osg.samsung.com
 
 (The rest I haven't had a chance to look at yet)

At least for patches 1-6 I tend to agree; they're good cleanup or
refactoring, and no reason not to just get them landed.  Patch 7 started
to look a bit more ambitious to me so I stopped there.  But with 1-6,
might save time having to rebase them.  Unfortunately they already don't
apply, but if you can split them out from the remainder of the patchset,
I'd be +1 for just landing them immediately.

Bryce

  This still relies on support not yet mainlined. Currently I am using:
  git://git.collabora.co.uk/git/user/daniels/linux.git#wip/4.2.x/atomic-i915
  git://git.collabora.co.uk/git/user/daniels/libdrm.git#atomic
  
  Cheers,
  Daniel
  
  ___
  wayland-devel mailing list
  wayland-devel@lists.freedesktop.org
  http://lists.freedesktop.org/mailman/listinfo/wayland-devel
  
 
 ___
 wayland-devel mailing list
 wayland-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/wayland-devel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-29 Thread Daniel Stone
Hi,

On 29 June 2015 at 07:53, Pekka Paalanen ppaala...@gmail.com wrote:
 On Fri, 26 Jun 2015 14:27:48 +0100
 Daniel Stone dan...@fooishbar.org wrote:
 On 24 June 2015 at 13:11, Pekka Paalanen ppaala...@gmail.com wrote:
  I think the best way to cache state is to let it stay in the kernel,
  and avoid submitting a disable followed by the old state that's already
  there. If we manage that, maintaining cached atomic req pieces in
  weston would be moot.

 Can you expand a bit on what you mean here?

 Gaining anything from a req snippet cache

Yes, I don't think Weston would gain anything from caching request
snippets. As I said, it's not applicable to us, but I can certainly
imagine usecases _for other non-Weston users_ where req snippets would
come in handy, so I added it to the API as another way to go about
things. drmModeAtomic{Duplicate,Merge} are not relevant to Weston.

 depends on the need to submit
 already submitted state again. The only significant reason to do that,
 that I can imagine, would be if the algorithm unconditionally
 initialized the req with either that cached state or disabled state.

 If we avoid unconditionally initializing a req like that, I don't see
 what we would gain from a req snippet cache. And we can avoid it,
 because the kernel maintain all state we do not set.

 I assume the cases where we need to re-program all state are rare
 enough to not warrant this added code.

 Therefore, if we only program state that has changed, the cache would
 be a net cost rather than a win, as we'd (almost) never hit the cache.

Assuming this about Duplicate/Merge, I'll just leave it here, since we
agree that it's an inappropriate API to use for Weston, which is why I
haven't used it for Weston.

Cheers,
Daniel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-29 Thread Pekka Paalanen
On Fri, 26 Jun 2015 14:27:48 +0100
Daniel Stone dan...@fooishbar.org wrote:

 Hi,
 
 On 24 June 2015 at 13:11, Pekka Paalanen ppaala...@gmail.com wrote:

  I think the best way to cache state is to let it stay in the kernel,
  and avoid submitting a disable followed by the old state that's already
  there. If we manage that, maintaining cached atomic req pieces in
  weston would be moot.
 
 Can you expand a bit on what you mean here?

Gaining anything from a req snippet cache depends on the need to submit
already submitted state again. The only significant reason to do that,
that I can imagine, would be if the algorithm unconditionally
initialized the req with either that cached state or disabled state.

If we avoid unconditionally initializing a req like that, I don't see
what we would gain from a req snippet cache. And we can avoid it,
because the kernel maintain all state we do not set.

I assume the cases where we need to re-program all state are rare
enough to not warrant this added code.

Therefore, if we only program state that has changed, the cache would
be a net cost rather than a win, as we'd (almost) never hit the cache.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-26 Thread Derek Foreman
On 22/06/15 11:25 AM, Daniel Stone wrote:
 Hi,
 Thanks to everyone who reviewed the previous series. This new series
 cleans up the previous patches, introduces a few fixes (e.g. not relying
 on a repaint to pull us out of DPMS), and crucially adds support for the
 libdrm TEST_ONLY interface (allowing us to check before we commit, e.g.
 that a particular plane combination is workable), using the new cursor
 API from libdrm.

Everything up to and including 8/16 seems like beneficial clean-up or
bug fix that could land independently of later bits?

For that half,
Reviewed-By: Derek Foreman der...@osg.samsung.com

(The rest I haven't had a chance to look at yet)

 
 This still relies on support not yet mainlined. Currently I am using:
 git://git.collabora.co.uk/git/user/daniels/linux.git#wip/4.2.x/atomic-i915
 git://git.collabora.co.uk/git/user/daniels/libdrm.git#atomic
 
 Cheers,
 Daniel
 
 ___
 wayland-devel mailing list
 wayland-devel@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/wayland-devel
 

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-26 Thread Daniel Stone
Hi,

On 24 June 2015 at 13:11, Pekka Paalanen ppaala...@gmail.com wrote:
 On Wed, 24 Jun 2015 12:22:15 +0100
 Daniel Stone dan...@fooishbar.org wrote:
 On 23 June 2015 at 13:28, Pekka Paalanen ppaala...@gmail.com wrote:
  On Tue, 23 Jun 2015 11:48:56 +0100
  Daniel Stone dan...@fooishbar.org wrote:
   So, the DRM planes we have not assigned yet but were enabled, shouldn't
   they be disabled in the TEST_ONLY commit? Otherwise they will contain
   old state and we validate against some new DRM plane states with some
   previous DRM plane states? That might lead to unnecessary failures from
   TEST_ONLY commit if we would eventually end up disabling or updating
   the already enabled DRM planes.
 
  The relevant comment above leads to that, yeah. We really need to
  split the walk up into two passes: firstly find anything currently on
  a plane which shouldn't be and free those planes up, then walk through
  and assign everything. I suspect this will be particularly relevant
  for, e.g., using the primary plane to directly scan out a client
  buffer.
 
  But can you do that in two passes? How can you know if a view is no
  longer good for a plane if you don't already assing planes to begin
  with and try with TEST_ONLY commit?

 Easily: look at the battery of tests we have for prepare_overlay_view
 etc. Is it a SHM buffer? Is it partially occluded? Is the format
 compatible? And so on, and so forth. When we associate views with
 planes, we can work out in a first pass that the view currently being
 carried on a plane is no longer any good for that plane, and throw it
 away early.

 But that depends on also on whether the TEST_ONLY commit succeeds or
 not. The battery of tests is not sufficient alone, DRM may still reject
 something. That causes a new plane to be freed when you are doing the
 second(?) pass with test commits, and then that plane needs explicit
 disabling again to not affect the following tests.

 So yes, can find views that definitely are not good for planes anymore,
 but there could be even more of them.

Yes - it would be necessary but not sufficient. Think of it as an easy
first cull.

 I guess this really comes down to differing views on how plane
 assignment should work. At the moment, on every output repaint, we
 essentially throw away every single plane on the entire device (not
 just those currently on our output - naughty ...) and build a
 configuration back from scratch. In this case, the incremental/caching
 approach we have doesn't really buy us much, because every time we
 walk assign_planes(), the only thing we're caching is the modeset
 parameters, which aren't touched anyway.

 I started from trying to address the multiple-output problem (if a
 plane is assigned to output B, then don't touch it in output A's
 repaint loop, otherwise bad things happen), and ended up with a much
 stronger association between the current state and the drm_planes,
 e.g. tracking view/output. This naturally seemed to lead to a more
 incremental approach wrt how we generate DRM atomic state, and one of
 the things that jumped out from that was that you could then do a
 first pass to cull any assumptions that no longer held true (view A is
 suitable to display on plane B), giving you a baseline to build on.

 I don't have a strong opinion on which is ultimately better.

 Ok.

 Hmm, maybe I'm slowly getting to what you have been trying to explain...

 First pass is to just check the old plane assignments that still hold
 (nothing to atomic req for these, except state changes if needed), and
 free others (add disables to the req). Then a test commit will ensure
 they still hold. If not, start the 2nd pass from a all planes disabled
 req instead.

 Then the seconds pass will try to find additional views for free planes
 in a similar fashion to what the from-scratch algorithm would do: add
 one plane. Test. If ok, add another plane, repeat. If not ok, add
 disables for that plane instead, and stop (or try to find other views).

 The base req built on the first pass ensures all planes that have not
 already been assigned and tested ok, are to be disabled.

 Was this your idea?

 The point I kept missing was that we assumed the req already contained
 properties to disable all unused-at-this-point planes.

 A confusion between the code and what it should be.

I think that's a reasonable expression of where I was aiming with that
'XXX' comment block, yeah.

 I did indeed have exactly that in mind, where individual updates would
 build their own AtomicReq, and then merge them together, e.g.:
   - generate base req for CRTC/connector A
   - duplicate req
   - apply plane updates for that output into duplicated req
   - call TEST_ONLY on duplicated req
   - use duplicated req if possible, or failing that go back to original
   - do exactly the same for CRTC/connector/planes B
   - merge two reqs together
   - issue actual atomic modeset

 It's a little bit contrived perhaps, but there are other ways of
 

Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-24 Thread Pekka Paalanen
Hello

On Wed, 24 Jun 2015 12:22:15 +0100
Daniel Stone dan...@fooishbar.org wrote:

 Hi,
 
 On 23 June 2015 at 13:28, Pekka Paalanen ppaala...@gmail.com wrote:
  On Tue, 23 Jun 2015 11:48:56 +0100
  Daniel Stone dan...@fooishbar.org wrote:

   So, the DRM planes we have not assigned yet but were enabled, shouldn't
   they be disabled in the TEST_ONLY commit? Otherwise they will contain
   old state and we validate against some new DRM plane states with some
   previous DRM plane states? That might lead to unnecessary failures from
   TEST_ONLY commit if we would eventually end up disabling or updating
   the already enabled DRM planes.
 
  The relevant comment above leads to that, yeah. We really need to
  split the walk up into two passes: firstly find anything currently on
  a plane which shouldn't be and free those planes up, then walk through
  and assign everything. I suspect this will be particularly relevant
  for, e.g., using the primary plane to directly scan out a client
  buffer.
 
  But can you do that in two passes? How can you know if a view is no
  longer good for a plane if you don't already assing planes to begin
  with and try with TEST_ONLY commit?
 
 Easily: look at the battery of tests we have for prepare_overlay_view
 etc. Is it a SHM buffer? Is it partially occluded? Is the format
 compatible? And so on, and so forth. When we associate views with
 planes, we can work out in a first pass that the view currently being
 carried on a plane is no longer any good for that plane, and throw it
 away early.

But that depends on also on whether the TEST_ONLY commit succeeds or
not. The battery of tests is not sufficient alone, DRM may still reject
something. That causes a new plane to be freed when you are doing the
second(?) pass with test commits, and then that plane needs explicit
disabling again to not affect the following tests.

So yes, can find views that definitely are not good for planes anymore,
but there could be even more of them.

 I guess this really comes down to differing views on how plane
 assignment should work. At the moment, on every output repaint, we
 essentially throw away every single plane on the entire device (not
 just those currently on our output - naughty ...) and build a
 configuration back from scratch. In this case, the incremental/caching
 approach we have doesn't really buy us much, because every time we
 walk assign_planes(), the only thing we're caching is the modeset
 parameters, which aren't touched anyway.
 
 I started from trying to address the multiple-output problem (if a
 plane is assigned to output B, then don't touch it in output A's
 repaint loop, otherwise bad things happen), and ended up with a much
 stronger association between the current state and the drm_planes,
 e.g. tracking view/output. This naturally seemed to lead to a more
 incremental approach wrt how we generate DRM atomic state, and one of
 the things that jumped out from that was that you could then do a
 first pass to cull any assumptions that no longer held true (view A is
 suitable to display on plane B), giving you a baseline to build on.
 
 I don't have a strong opinion on which is ultimately better.

Ok.

Hmm, maybe I'm slowly getting to what you have been trying to explain...

First pass is to just check the old plane assignments that still hold
(nothing to atomic req for these, except state changes if needed), and
free others (add disables to the req). Then a test commit will ensure
they still hold. If not, start the 2nd pass from a all planes disabled
req instead.

Then the seconds pass will try to find additional views for free planes
in a similar fashion to what the from-scratch algorithm would do: add
one plane. Test. If ok, add another plane, repeat. If not ok, add
disables for that plane instead, and stop (or try to find other views).

The base req built on the first pass ensures all planes that have not
already been assigned and tested ok, are to be disabled.

Was this your idea?

The point I kept missing was that we assumed the req already contained
properties to disable all unused-at-this-point planes.

A confusion between the code and what it should be.

   If the TEST_ONLY commit succeeds, rewind to cursor B and try the next
   plane. If it fails, rewind to cursor A, fill in the rest of disables,
   and be done with it.
  
   Does this make sense?
 
  Hmm, I was thinking more of, build a list of disables first, then try
  to insert enables one-by-one, and apply them if they succeed.
 
  Yeah, that works too, I suppose, I didn't think of allowing the setting
  of the same properties multiple times in a single atomic req. Less
  rewinding, indeed.
 
  I just didn't spot any code doing the disables at all for TEST_ONLY. :-)
 
 Yeah, this is correct, so we will generate false negatives. Following
 the approach I've taken above, we would have to do a first pass to
 cull unused planes, followed by a second pass to add new planes;
 following the destroy-and-rebuild 

Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-24 Thread Daniel Stone
Hi,

On 23 June 2015 at 13:28, Pekka Paalanen ppaala...@gmail.com wrote:
 On Tue, 23 Jun 2015 11:48:56 +0100
 Daniel Stone dan...@fooishbar.org wrote:
 This is the reason for the large 'XXX' comment when calling
 populate_atomic_plane inside repaint_atomic. So far, my thought has
 been to add yet another parameter (ugh) to populate_atomic_plane, and
 thus to plane_add_atomic, which would just call SetProp and not fill
 the internal cache. A much more flexible solution would be to wrap
 every drmModeAtomicReq inside a new drm_atomic_state struct, which
 would contain our internal cache (wdrm_plane_properties etc), but I
 haven't yet seen anything so far which would demand this more complex
 solution. The main argument for taking the complex approach is that
 this is what the kernel does: drm_atomic_state (and its children for
 CRTC/plane/connector state) are duplicated internally for each
 request.

 I think all those problems go away, if you build the final atomic req
 once and for all, like I suggested below. I think it's fairly
 error-prone to build it once, test, and build (almost) the same again,
 not to mention a little wasteful.

That's a fair comment, yeah.

 There would be some fiddling still when you need to back up because a
 TEST commit said no, but then it'd be only that plane's worth of
 state.

Well, we already have that, in that if a test commit fails, we just
back the cursor up to where it was before. Committing a request only
commits up to the cursor, and merges get appended from the cursor. So
I don't see how it's really any more complicated than what we have
now, of:
  - add plane state A
  - test, success!
  - add plane state B
  - oh no, failed; back cursor up to A
  - add plane state C
  - test, success!
  - req now contains A + C

 We could simply add a pending value in addition to the current value
 stored in struct property_item, but yeah, this is all just details.

Mmm, yeah. Or just read everything back from the kernel any time a
request fails.

  So, the DRM planes we have not assigned yet but were enabled, shouldn't
  they be disabled in the TEST_ONLY commit? Otherwise they will contain
  old state and we validate against some new DRM plane states with some
  previous DRM plane states? That might lead to unnecessary failures from
  TEST_ONLY commit if we would eventually end up disabling or updating
  the already enabled DRM planes.

 The relevant comment above leads to that, yeah. We really need to
 split the walk up into two passes: firstly find anything currently on
 a plane which shouldn't be and free those planes up, then walk through
 and assign everything. I suspect this will be particularly relevant
 for, e.g., using the primary plane to directly scan out a client
 buffer.

 But can you do that in two passes? How can you know if a view is no
 longer good for a plane if you don't already assing planes to begin
 with and try with TEST_ONLY commit?

Easily: look at the battery of tests we have for prepare_overlay_view
etc. Is it a SHM buffer? Is it partially occluded? Is the format
compatible? And so on, and so forth. When we associate views with
planes, we can work out in a first pass that the view currently being
carried on a plane is no longer any good for that plane, and throw it
away early.

I guess this really comes down to differing views on how plane
assignment should work. At the moment, on every output repaint, we
essentially throw away every single plane on the entire device (not
just those currently on our output - naughty ...) and build a
configuration back from scratch. In this case, the incremental/caching
approach we have doesn't really buy us much, because every time we
walk assign_planes(), the only thing we're caching is the modeset
parameters, which aren't touched anyway.

I started from trying to address the multiple-output problem (if a
plane is assigned to output B, then don't touch it in output A's
repaint loop, otherwise bad things happen), and ended up with a much
stronger association between the current state and the drm_planes,
e.g. tracking view/output. This naturally seemed to lead to a more
incremental approach wrt how we generate DRM atomic state, and one of
the things that jumped out from that was that you could then do a
first pass to cull any assumptions that no longer held true (view A is
suitable to display on plane B), giving you a baseline to build on.

I don't have a strong opinion on which is ultimately better.

  If the TEST_ONLY commit succeeds, rewind to cursor B and try the next
  plane. If it fails, rewind to cursor A, fill in the rest of disables,
  and be done with it.
 
  Does this make sense?

 Hmm, I was thinking more of, build a list of disables first, then try
 to insert enables one-by-one, and apply them if they succeed.

 Yeah, that works too, I suppose, I didn't think of allowing the setting
 of the same properties multiple times in a single atomic req. Less
 rewinding, indeed.

 I just didn't spot any code doing the 

Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-23 Thread Pekka Paalanen
On Tue, 23 Jun 2015 11:48:56 +0100
Daniel Stone dan...@fooishbar.org wrote:

 Hi,
 
 On 23 June 2015 at 11:26, Pekka Paalanen ppaala...@gmail.com wrote:
  you asked me to take a look at the assing_planes code wrt. TEST_ONLY
  and backtracking.
 
 Thanks!
 
 As a general comment, carried over from IRC: I think we should get
 Mario's series reviewed and merged first. It looks like good work, and
 I don't have any objection to the DRM bits, but am entirely
 underqualified to review the shell patches. I'd look to get this
 merged in two parts, with the drm_plane and universal plane conversion
 coming first, and then the atomic conversion coming later when it's a
 bit more bedded down and some of those mega-comments have gone away.
 
  /* XXX: At this point, we need two runs through 
  assign_planes;
   *  one to prepare any necessary views, and see if there
   *  are any currently-unused planes. This process may
   *  actually free up some planes for other views to use;
   *  if any planes have been freed up, we should do 
  another
   *  pass to see if any planeless views can use any 
  planes
   *  which have just been freed. But we want to cache 
  what
   *  we can, so we're not, e.g., calling gbm_bo_import
   *  twice. */
 
 This is relevant ...
 
  Yeah, the logic for populating the atomic req seems mostly ok, but is
  it missing the primary weston_plane assignment to the primary DRM plane?
  Or if we are going to do a modeset, shouldn't that be here somehow too?
 
  I mean for cases where the primary DRM plane will actually change. If
  it doesn't change, then I'd assume DRM maintains the state that is not
  touched.
 
 Right, exactly. The atomic ioctl starts by duplicating existing state,
 and then all property changes are strictly additive; otherwise we
 wouldn't have any use for the cache at all.
 
 Mind you, the cache is broken, because it assumes a strictly linear
 set of changes, which this breaks, e.g.:
   + initial modeset
 - generate new req
 - populate internal cache with complete desired state
 - post new req to kernel
   + repaint
  - generate new req
  - populate internal cache with values for new primary fb
  - post new req to kernel
   + repaint
  - assign_planes
- generate new req
- populate internal cache with speculative values for checking plane
- submit req as TEST_ONLY
  - generate new req
  - populate internal cache with same values as previous; they're
 identical, so no change
  - req doesn't have plane values since our cache says they're unchanged
 
 This is the reason for the large 'XXX' comment when calling
 populate_atomic_plane inside repaint_atomic. So far, my thought has
 been to add yet another parameter (ugh) to populate_atomic_plane, and
 thus to plane_add_atomic, which would just call SetProp and not fill
 the internal cache. A much more flexible solution would be to wrap
 every drmModeAtomicReq inside a new drm_atomic_state struct, which
 would contain our internal cache (wdrm_plane_properties etc), but I
 haven't yet seen anything so far which would demand this more complex
 solution. The main argument for taking the complex approach is that
 this is what the kernel does: drm_atomic_state (and its children for
 CRTC/plane/connector state) are duplicated internally for each
 request.

I think all those problems go away, if you build the final atomic req
once and for all, like I suggested below. I think it's fairly
error-prone to build it once, test, and build (almost) the same again,
not to mention a little wasteful.

There would be some fiddling still when you need to back up because a
TEST commit said no, but then it'd be only that plane's worth of
state.

We could simply add a pending value in addition to the current value
stored in struct property_item, but yeah, this is all just details.

  So, the DRM planes we have not assigned yet but were enabled, shouldn't
  they be disabled in the TEST_ONLY commit? Otherwise they will contain
  old state and we validate against some new DRM plane states with some
  previous DRM plane states? That might lead to unnecessary failures from
  TEST_ONLY commit if we would eventually end up disabling or updating
  the already enabled DRM planes.
 
 The relevant comment above leads to that, yeah. We really need to
 split the walk up into two passes: firstly find anything currently on
 a plane which shouldn't be and free those planes up, then walk through
 and assign everything. I suspect this will be particularly relevant
 for, e.g., using the primary plane to directly scan out a client
 buffer.

But can you do that in two passes? How can you know if a view is no
longer good for a plane if you don't already assing planes to begin
with and try with TEST_ONLY commit?

  The TEST_ONLY call should 

Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-23 Thread Daniel Vetter
On Tue, Jun 23, 2015 at 12:48 PM, Daniel Stone dan...@fooishbar.org wrote:
 This is assuming we cannot do without the primary plane. If it was
 possible to drive truely universal planes, we would not know if we need
 a primary plane until we know if there is anything on it. You'd have to
 first assume the primary plane is needed, test the additional plane
 setups, and then if we don't need the primary plane, test once more
 without it.

 Sure, in theory the primary plane can be disabled, but that's not the
 reality of a lot of common hardware, so we'll have to deal with that
 assumption for a very long time to come.

Just a quick clarification discussed with Daniel on irc: Restrictions
on requiring an enabled primary plane are mostly just software since
the default primary plane enabled by universal planes can't do
anything else. It can also only do rgbx.

But atomic (and already even the transitional plane helpers) lift that
restriction, and drivers must take explicit action in their
atomic_check callbacks to refuse a config with enabled crtc but
disabled primary. The default assumption is that primary/cursor planes
aren't anything special at all compared to other planes and only used
for implementing backwards compatibility with old userspace.

The only thing where this differes is that for cursors and primary
planes we have dedicated properties to tell userspace the size limits,
for sprites there's nothing like that. But givin that max size is just
a small part of figuring out what kind of surfaces a driver supports I
don't think that's a big deal really ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-23 Thread Daniel Stone
Hi,

On 23 June 2015 at 11:26, Pekka Paalanen ppaala...@gmail.com wrote:
 you asked me to take a look at the assing_planes code wrt. TEST_ONLY
 and backtracking.

Thanks!

As a general comment, carried over from IRC: I think we should get
Mario's series reviewed and merged first. It looks like good work, and
I don't have any objection to the DRM bits, but am entirely
underqualified to review the shell patches. I'd look to get this
merged in two parts, with the drm_plane and universal plane conversion
coming first, and then the atomic conversion coming later when it's a
bit more bedded down and some of those mega-comments have gone away.

 /* XXX: At this point, we need two runs through assign_planes;
  *  one to prepare any necessary views, and see if there
  *  are any currently-unused planes. This process may
  *  actually free up some planes for other views to use;
  *  if any planes have been freed up, we should do another
  *  pass to see if any planeless views can use any planes
  *  which have just been freed. But we want to cache what
  *  we can, so we're not, e.g., calling gbm_bo_import
  *  twice. */

This is relevant ...

 Yeah, the logic for populating the atomic req seems mostly ok, but is
 it missing the primary weston_plane assignment to the primary DRM plane?
 Or if we are going to do a modeset, shouldn't that be here somehow too?

 I mean for cases where the primary DRM plane will actually change. If
 it doesn't change, then I'd assume DRM maintains the state that is not
 touched.

Right, exactly. The atomic ioctl starts by duplicating existing state,
and then all property changes are strictly additive; otherwise we
wouldn't have any use for the cache at all.

Mind you, the cache is broken, because it assumes a strictly linear
set of changes, which this breaks, e.g.:
  + initial modeset
- generate new req
- populate internal cache with complete desired state
- post new req to kernel
  + repaint
 - generate new req
 - populate internal cache with values for new primary fb
 - post new req to kernel
  + repaint
 - assign_planes
   - generate new req
   - populate internal cache with speculative values for checking plane
   - submit req as TEST_ONLY
 - generate new req
 - populate internal cache with same values as previous; they're
identical, so no change
 - req doesn't have plane values since our cache says they're unchanged

This is the reason for the large 'XXX' comment when calling
populate_atomic_plane inside repaint_atomic. So far, my thought has
been to add yet another parameter (ugh) to populate_atomic_plane, and
thus to plane_add_atomic, which would just call SetProp and not fill
the internal cache. A much more flexible solution would be to wrap
every drmModeAtomicReq inside a new drm_atomic_state struct, which
would contain our internal cache (wdrm_plane_properties etc), but I
haven't yet seen anything so far which would demand this more complex
solution. The main argument for taking the complex approach is that
this is what the kernel does: drm_atomic_state (and its children for
CRTC/plane/connector state) are duplicated internally for each
request.

 So, the DRM planes we have not assigned yet but were enabled, shouldn't
 they be disabled in the TEST_ONLY commit? Otherwise they will contain
 old state and we validate against some new DRM plane states with some
 previous DRM plane states? That might lead to unnecessary failures from
 TEST_ONLY commit if we would eventually end up disabling or updating
 the already enabled DRM planes.

The relevant comment above leads to that, yeah. We really need to
split the walk up into two passes: firstly find anything currently on
a plane which shouldn't be and free those planes up, then walk through
and assign everything. I suspect this will be particularly relevant
for, e.g., using the primary plane to directly scan out a client
buffer.

 The TEST_ONLY call should contain everything the final atomic commit
 call will, right? So once assign_planes is done, we should already have
 the complete atomic req, and in output_repaint what's left to do is to
 actually render the leftovers and commit.

 I suppose this means we need to prepare the next buffer for a primary
 weston_plane already at assign_planes start and use it in the TEST_ONLY
 commit, before we even render to it. I hope it won't screw up any
 fencing in DRM or EGL. But can we get it out of EGL/GBM *before* we
 render it? We need an equivalent buffer that the primary DRM plane's
 buffer is going to be for TEST_ONLY commits, so that we can check what
 can go to overlays, so we know what we will need to render.

Indeed; the key is an equivalent buffer, rather than a rendered
buffer, because we can't know what to render (think planes with alpha)
until we've 

Re: [PATCH v2 weston 00/16] Atomic modesetting support

2015-06-23 Thread Pekka Paalanen
On Mon, 22 Jun 2015 17:25:05 +0100
Daniel Stone dani...@collabora.com wrote:

 Hi,
 Thanks to everyone who reviewed the previous series. This new series
 cleans up the previous patches, introduces a few fixes (e.g. not relying
 on a repaint to pull us out of DPMS), and crucially adds support for the
 libdrm TEST_ONLY interface (allowing us to check before we commit, e.g.
 that a particular plane combination is workable), using the new cursor
 API from libdrm.
 
 This still relies on support not yet mainlined. Currently I am using:
 git://git.collabora.co.uk/git/user/daniels/linux.git#wip/4.2.x/atomic-i915
 git://git.collabora.co.uk/git/user/daniels/libdrm.git#atomic

Hi Daniel,

you asked me to take a look at the assing_planes code wrt. TEST_ONLY
and backtracking.

The selected code quotations below are from after the complete series.


static void
drm_plane_update_begin(struct drm_plane *plane)
{
plane-props.value_pend_mask = 0;
}

/**
 * Try to use the primary DRM plane to directly display a full-screen view
 *
 * If a surface covers an entire output and is unoccluded, attempt to directly
 * pageflip the primary DRM plane (not to be confused with the primary Weston
 * plane) to the buffer. In legacy DRM usage, this will use drmModePageFlip;
 * in atomic, this is just another plane.
 *
 * @param output Output to target
 * @param ev View to prospectively use the primary plane
 */
static struct weston_plane *
drm_output_prepare_scanout_view(struct drm_output *output,
struct weston_view *ev)
{
struct drm_compositor *c =
(struct drm_compositor *) output-base.compositor;
struct weston_buffer *buffer = ev-surface-buffer_ref.buffer;
struct weston_buffer_viewport *viewport = ev-surface-buffer_viewport;
struct gbm_bo *bo;
uint32_t format;

if (ev-geometry.x != output-base.x ||
ev-geometry.y != output-base.y ||
buffer == NULL || c-gbm == NULL ||
buffer-width != output-base.current_mode-width ||
buffer-height != output-base.current_mode-height ||
output-base.transform != viewport-buffer.transform ||
ev-transform.enabled)
return NULL;

if (ev-geometry.scissor_enabled)
return NULL;

bo = gbm_bo_import(c-gbm, GBM_BO_IMPORT_WL_BUFFER,
   buffer-resource, GBM_BO_USE_SCANOUT);

/* Unable to use the buffer for scanout */
if (!bo)
return NULL;

format = drm_output_check_scanout_format(output, ev-surface, bo);
if (format == 0) {
gbm_bo_destroy(bo);
return NULL;
}

output-primary_plane-next = drm_fb_get_from_bo(bo, c, format);
if (!output-primary_plane-next) {
gbm_bo_destroy(bo);
return NULL;
}

drm_fb_set_buffer(output-primary_plane-next, buffer);

return output-fb_plane;
}

static struct weston_plane *
drm_output_prepare_overlay_view(struct drm_output *output,
struct weston_view *ev)
{
struct weston_compositor *ec = output-base.compositor;
struct drm_compositor *c = (struct drm_compositor *)ec;
struct weston_buffer_viewport *viewport = ev-surface-buffer_viewport;
struct drm_plane *p;
struct drm_plane *cur = NULL;
int found = 0;
struct gbm_bo *bo;
pixman_region32_t dest_rect, src_rect;
pixman_box32_t *box, tbox;
uint32_t format;
wl_fixed_t sx1, sy1, sx2, sy2;

if (c-gbm == NULL)
return NULL;

if (viewport-buffer.transform != output-base.transform)
return NULL;

if (viewport-buffer.scale != output-base.current_scale)
return NULL;

if (c-sprites_are_broken)
return NULL;

if (ev-output_mask != (1u  output-base.id))
return NULL;

if (ev-surface-buffer_ref.buffer == NULL)
return NULL;

if (ev-alpha != 1.0f)
return NULL;

if (wl_shm_buffer_get(ev-surface-buffer_ref.buffer-resource))
return NULL;

if (!drm_view_transform_supported(ev))
return NULL;

/* Find the current view this plane is assigned to, if any. */
wl_list_for_each(p, c-plane_list, link) {
if (p-view != ev || p-output != output)
continue;

cur = p;
break;
}

bo = gbm_bo_import(c-gbm, GBM_BO_IMPORT_WL_BUFFER,
   ev-surface-buffer_ref.buffer-resource,
   GBM_BO_USE_SCANOUT);

wl_list_for_each(p, c-plane_list, link) {
if (!bo)
continue;

if (!drm_plane_crtc_supported(output, p-possible_crtcs))
continue;