On Mon, May 19, 2014 at 9:24 PM, Alan Griffiths <email address hidden>
wrote:
> Review: Needs Information
>
> Apologies for meandering thoughts. But this is continuing the *Needs
> discussion*...
>
> Short version: while I'm in agreement with the approach this branch
> proposes I've hung up on a lack of design clarity around
> "FrameDroppingPolicy" which isn't really a policy and doesn't
> encapsulates the framedropping logic.
>
>> > 61 +class FrameDroppingPolicy
>> > ...
>> > 70 + /**
>> > 71 + * \brief Notify that a swap has blocked
>> > 72 + */
>> > 73 + virtual void swap_now_blocking() = 0;
>> > 74 + /**
>> > 75 + * \brief Notify that previous swap is no longer blocking
>> > 76 + */
>> > 77 + virtual void swap_unblocked() = 0;
>> >
>> > I don't immediately understand the role of a "policy" class that
>> > doesn't seem to be responsible for doing anything (it only has
>> these
>> > two member functions). Based on the functions it has is a
>> > SwapBlockageObserver not a FrameDroppingPolicy.
>>
>> It makes frame dropping decisions based upon notifications from the
>> buffer queue.
>>
>> The mechanism it uses for dropping frames is set at creation time,
>> which is why it doesn't appear in the interface.
>
> I don't think you've quite understood this concern. It isn't the role
> of TimeoutFrameDroppingPolicy I'm saying is unclear it is
> FrameDroppingPolicy that I'm doubtful about. The code that uses it
> looks like this:
>
> 711 + /* Can't give the client a buffer yet; they'll just have to wait
> 712 + * until the compositor is done with an old frame, or the policy
> 713 + * says they've waited long enough.
> 714 + */
> 715 + framedrop_policy->swap_now_blocking();
>
> and
>
> 724 + framedrop_policy->swap_unblocked();
> 725 give_buffer_to_client(buffer, std::move(lock));
>
> Neither fragment looks to me like a call to be handled by a "policy".
> (They look a bit more like state transitions - but if that that model
> is correct "enter_swap_blocked()/exit_swap_blocked() is probably
> clearer.)
It is a state transition, yes, with the wrinkle that it's recursive;
you can enter_swap_blocked() while currently in a swap_blocked state.
If we go this way, enter_swap_blocked()/exit_swap_blocked() would be a
reasonable rename.
The policy needs to know the state, and when the state changes, so it
does indeed look like a state observer.
>
>
> Actually, BufferQueue still has:
>
> /* Last resort, drop oldest buffer from the ready queue */
> if (frame_dropping_enabled && !ready_to_composite_queue.empty())
> {
> auto const buffer = pop(ready_to_composite_queue);
> give_buffer_to_client(buffer, std::move(lock));
>
> So we have both framedrop_policy and frame_dropping_enabled in
> BufferQueue. So we're not covering all the policy around
> framedropping in TimeoutFrameDroppingPolicy.
Hm, this is true. How about if we added virtual void
client_requests_framedropping(bool); to FrameDroppingPolicy. Then
FrameDroppingPolicy *would* be responsible for all the framedropping
decisions?
My concern with this is that we're extensively tying something that
we'll want to have in the exported-to-shell-API (“how do you want to
handle it when clients get blocked in swap_buffers”) with a the
deeply internal implementation detail of BufferQueue.
A shell won't want to deal with all of handling client swap_buffers
requests; “When should I framedrop” is a well-defined fairly
self-contained question that should have a fairly self-contained answer.
On Mon, May 19, 2014 at 9:24 PM, Alan Griffiths <email address hidden> olicy" which isn't really a policy and doesn't erver not a FrameDroppingPo licy. ppingPolicy I'm saying is unclear it is policy- >swap_now_ blocking( ); policy- >swap_unblocked (); to_client( buffer, std::move(lock)); swap_blocked( )/exit_ swap_blocked( ) is probably
wrote:
> Review: Needs Information
>
> Apologies for meandering thoughts. But this is continuing the *Needs
> discussion*...
>
> Short version: while I'm in agreement with the approach this branch
> proposes I've hung up on a lack of design clarity around
> "FrameDroppingP
> encapsulates the framedropping logic.
>
>> > 61 +class FrameDroppingPolicy
>> > ...
>> > 70 + /**
>> > 71 + * \brief Notify that a swap has blocked
>> > 72 + */
>> > 73 + virtual void swap_now_blocking() = 0;
>> > 74 + /**
>> > 75 + * \brief Notify that previous swap is no longer blocking
>> > 76 + */
>> > 77 + virtual void swap_unblocked() = 0;
>> >
>> > I don't immediately understand the role of a "policy" class that
>> > doesn't seem to be responsible for doing anything (it only has
>> these
>> > two member functions). Based on the functions it has is a
>> > SwapBlockageObs
>>
>> It makes frame dropping decisions based upon notifications from the
>> buffer queue.
>>
>> The mechanism it uses for dropping frames is set at creation time,
>> which is why it doesn't appear in the interface.
>
> I don't think you've quite understood this concern. It isn't the role
> of TimeoutFrameDro
> FrameDroppingPolicy that I'm doubtful about. The code that uses it
> looks like this:
>
> 711 + /* Can't give the client a buffer yet; they'll just have to wait
> 712 + * until the compositor is done with an old frame, or the policy
> 713 + * says they've waited long enough.
> 714 + */
> 715 + framedrop_
>
> and
>
> 724 + framedrop_
> 725 give_buffer_
>
> Neither fragment looks to me like a call to be handled by a "policy".
> (They look a bit more like state transitions - but if that that model
> is correct "enter_
> clearer.)
It is a state transition, yes, with the wrinkle that it's recursive; blocked( ) while currently in a swap_blocked state. blocked( )/exit_ swap_blocked( ) would be a
you can enter_swap_
If we go this way, enter_swap_
reasonable rename.
The policy needs to know the state, and when the state changes, so it
does indeed look like a state observer.
> dropping_ enabled && !ready_ to_composite_ queue.empty( )) to_composite_ queue); to_client( buffer, std::move(lock)); enabled in ppingPolicy.
>
> Actually, BufferQueue still has:
>
> /* Last resort, drop oldest buffer from the ready queue */
> if (frame_
> {
> auto const buffer = pop(ready_
> give_buffer_
>
> So we have both framedrop_policy and frame_dropping_
> BufferQueue. So we're not covering all the policy around
> framedropping in TimeoutFrameDro
Hm, this is true. How about if we added virtual void requests_ framedropping( bool); to FrameDroppingPo licy. Then
client_
FrameDroppingPolicy *would* be responsible for all the framedropping
decisions?
> … client_ acquire( graphics: :Buffer* >& free_buffers, graphics: :Buffer* >& ready_to_ composite_ queue, std::shared_ ptr<graphics: :Buffer> >& buffers, ::Callback complete) = 0; buffer_ available_ for_client( graphics: :Buffer* >& free_buffers) = 0; force_requests_ to_complete( graphics: :Buffer* >& free_buffers, graphics: :Buffer* >& ready_to_ composite_ queue) = 0;
> class SwapBuffersPolicy
> {
> public:
> virtual void handle_
> std::vector<
> std::deque<
> std::vector<
> mc::BufferQueue
>
> virtual void handle_
> mg::Buffer* buffer,
> std::vector<
>
> virtual void handle_
> std::vector<
> std::deque<
> };
My concern with this is that we're extensively tying something that to-shell- API (“how do you want to
we'll want to have in the exported-
handle it when clients get blocked in swap_buffers”) with a the
deeply internal implementation detail of BufferQueue.
A shell won't want to deal with all of handling client swap_buffers
requests; “When should I framedrop” is a well-defined fairly
self-contained question that should have a fairly self-contained answer.