blob: ec5af129f9df06f20fe451fe1cf338f766624f53 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_UI_LIB_ESCHER_RESOURCES_RESOURCE_RECYCLER_H_
#define SRC_UI_LIB_ESCHER_RESOURCES_RESOURCE_RECYCLER_H_
#include <mutex>
#include <unordered_map>
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/ui/lib/escher/impl/command_buffer_sequencer.h"
#include "src/ui/lib/escher/resources/resource_manager.h"
namespace escher {
// Simple manager that keeps resources alive until they are no longer referenced
// by a pending command-buffer, then recycles them. It does this by comparing
// the sequence numbers from a CommandBufferSequencer with the sequence numbers
// of resources that it is keeping alive. The default implementation does not
// recycle resources, instead destroying them as soon as it is safe.
class ResourceRecycler : public ResourceManager, public impl::CommandBufferSequencerListener {
public:
explicit ResourceRecycler(EscherWeakPtr escher);
virtual ~ResourceRecycler();
fxl::WeakPtr<ResourceRecycler> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
private:
// Gives subclasses a chance to recycle the resource. Default implementation
// immediately destroys resource.
// Note that if OnCommandBufferFinished() and OnReceiveOwnable() is called from multiple threads,
// RecycleResource() will also be called from multiple threads, so the implementers should
// guarantee thread-safety.
virtual void RecycleResource(std::unique_ptr<Resource> resource) {}
// Implement impl::CommandBufferSequenceListener::CommandBufferFinished().
// Checks whether it is safe to recycle any of |unused_resources_|.
void OnCommandBufferFinished(uint64_t sequence_number) final;
// Implement Owner::OnReceiveOwnable(). Call RecycleOwnable() immediately if
// it is safe to do so. Otherwise, adds the resource to a set of resources
// to be recycled later; see CommandBufferFinished().
void OnReceiveOwnable(std::unique_ptr<Resource> resource) final;
uint64_t last_finished_sequence_number_ = 0;
// This mutex protects access to |unused_resources_|. These class methods
// may be called from multiple threads.
mutable std::mutex lock_;
// We need to use an unordered_map instead of an unordered_set because you
// can't modify elements of an unordered_set, which prevents us from
// removing a unique_ptr.
std::unordered_map<Resource*, std::unique_ptr<Resource>> unused_resources_ FXL_GUARDED_BY(lock_);
fxl::WeakPtrFactory<ResourceRecycler> weak_factory_; // must be last
FXL_DISALLOW_COPY_AND_ASSIGN(ResourceRecycler);
};
} // namespace escher
#endif // SRC_UI_LIB_ESCHER_RESOURCES_RESOURCE_RECYCLER_H_