#ifndef FLUTTER_FLOW_SKIA_GPU_OBJECT_H_
#define FLUTTER_FLOW_SKIA_GPU_OBJECT_H_
#include <mutex>
#include <queue>
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/task_runner.h"
#include "include/core/SkRefCnt.h"
namespace flutter {
class SkiaUnrefQueue : public fml::RefCountedThreadSafe<SkiaUnrefQueue> {
public:
void Unref(SkRefCnt* object);
void Drain(bool finish = false);
private:
const fml::RefPtr<fml::TaskRunner> task_runner_;
const fml::TimeDelta drain_delay_;
std::mutex mutex_;
std::deque<SkRefCnt*> objects_;
bool drain_pending_;
bool invalid_ = false;
SkiaUnrefQueue(fml::RefPtr<fml::TaskRunner> task_runner,
fml::TimeDelta delay);
~SkiaUnrefQueue();
FML_FRIEND_REF_COUNTED_THREAD_SAFE(SkiaUnrefQueue);
FML_FRIEND_MAKE_REF_COUNTED(SkiaUnrefQueue);
FML_DISALLOW_COPY_AND_ASSIGN(SkiaUnrefQueue);
};
template <class T>
class SkiaGPUObject {
public:
using SkiaObjectType = T;
SkiaGPUObject() = default;
SkiaGPUObject(sk_sp<SkiaObjectType> object, fml::RefPtr<SkiaUnrefQueue> queue)
: object_(std::move(object)), queue_(std::move(queue)) {
FML_DCHECK(queue_ && object_);
}
SkiaGPUObject(SkiaGPUObject&&) = default;
~SkiaGPUObject() { reset(); }
SkiaGPUObject& operator=(SkiaGPUObject&&) = default;
sk_sp<SkiaObjectType> get() const { return object_; }
void reset() {
if (object_) {
queue_->Unref(object_.release());
}
queue_ = nullptr;
FML_DCHECK(object_ == nullptr);
}
private:
sk_sp<SkiaObjectType> object_;
fml::RefPtr<SkiaUnrefQueue> queue_;
FML_DISALLOW_COPY_AND_ASSIGN(SkiaGPUObject);
};
}
#endif