Nobody is holding the return shared_ptr<BufferHandle> so at the end of this scope, the buffer will be returned to the queue - possibly resulting in tearing artifacts.
In order for this to work correctly the caller of lock_compositor_buffer (i.e. SurfaceSnapshot) needs to be able to receive the BufferHandle object. That would pretty much make BufferStream a useless replicated interface - they should all just collapse to BufferBundle instead.
The weak_ptr_this is needed to ensure you won't be calling dead code if the BufferQueue gets destroyed before one of the BufferHandles. Alternatively, you could keep a shared_ptr instead to keep the buffer queue object alive but I would prefer the BufferHandle to not impose that requirement.
The above will require enabled_shared_from_this support in the BufferQueue class.
=== ptr<BufferHandl e> compositor_ acquire( void const* user_id) = 0; release( graphics: :Buffer* const buffer) = 0; ptr<BufferHandl e> snapshot_acquire() = 0; release( graphics: :Buffer* const buffer) = 0;
48 + virtual std::shared_
49 + virtual void compositor_
50 + virtual std::shared_
51 + virtual void snapshot_
==
I'd rather have compositor_acquire and snapshot_acquire return a BufferHandle by value.
BufferHandle should be a moveable only type.
The BufferHandle constructor could also be:
BufferHande( std::function< void()> const& release)
Then we can remove compositor_release and snapshot_release.
=== bundle- >compositor_ acquire( user_id) ->buffer( );
334 + return buffer_
===
Nobody is holding the return shared_ ptr<BufferHandl e> so at the end of this scope, the buffer will be returned to the queue - possibly resulting in tearing artifacts.
In order for this to work correctly the caller of lock_compositor _buffer (i.e. SurfaceSnapshot) needs to be able to receive the BufferHandle object. That would pretty much make BufferStream a useless replicated interface - they should all just collapse to BufferBundle instead.
=== BufferBundle* bundle, ptr<graphics: :Buffer> buffer);
160 + explicit BufferHandle(
161 + std::shared_
162 + BufferBundle* buffer_bundle;
===
As mentioned above this could probably be:
class BufferHandle void(graphics: :Buffer* buffer)> Callback; std::shared_ ptr<graphics: :Buffer> const& buffer,
Callback const& release);
{
public:
typedef std::function<
explicit BufferHandle(
//Move constructor e(BufferHandle& & other); (BufferHandle& & other);
BufferHandl
//Move assignment
BufferHandle& operator=
std: :shared_ ptr<graphics: :Buffer> buffer();
private: e(BufferHandle const&) = delete; (BufferHandle const&) = delete;
// Moveable only type
BufferHandl
BufferHandle& operator=
std: :shared_ ptr<graphics: :Buffer> wrapped;
Callback release;
};
=== ptr<mc: :BufferHandle> const acquired_buffer = shared< mc::CompositorB ufferHandle> (this, buffer_ for(current_ compositor_ buffer, buffers));
213 + std::shared_
214 + std::make_
===
With the BufferHandle above then this would become:
BufferHandle const handle{ buffer_ for(current_ compositor_ buffer, buffers), ptr_this] (Buffer* buffer) this.lock( ))
compositor_ release( buffer) ;
[weak_
{
if (auto self = weak_ptr_
{
}
}
The weak_ptr_this is needed to ensure you won't be calling dead code if the BufferQueue gets destroyed before one of the BufferHandles. Alternatively, you could keep a shared_ptr instead to keep the buffer queue object alive but I would prefer the BufferHandle to not impose that requirement.
The above will require enabled_ shared_ from_this support in the BufferQueue class.