• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_FLOW_SKIA_GPU_OBJECT_H_
6 #define FLUTTER_FLOW_SKIA_GPU_OBJECT_H_
7 
8 #include <mutex>
9 #include <queue>
10 
11 #include "flutter/fml/memory/ref_counted.h"
12 #include "flutter/fml/memory/weak_ptr.h"
13 #include "flutter/fml/task_runner.h"
14 #include "third_party/skia/include/core/SkRefCnt.h"
15 
16 namespace flutter {
17 
18 // A queue that holds Skia objects that must be destructed on the the given task
19 // runner.
20 class SkiaUnrefQueue : public fml::RefCountedThreadSafe<SkiaUnrefQueue> {
21  public:
22   void Unref(SkRefCnt* object);
23 
24   // Usually, the drain is called automatically. However, during IO manager
25   // shutdown (when the platform side reference to the OpenGL context is about
26   // to go away), we may need to pre-emptively drain the unref queue. It is the
27   // responsibility of the caller to ensure that no further unrefs are queued
28   // after this call.
29   void Drain(bool finish = false);
30 
31  private:
32   const fml::RefPtr<fml::TaskRunner> task_runner_;
33   const fml::TimeDelta drain_delay_;
34   std::mutex mutex_;
35   std::deque<SkRefCnt*> objects_;
36   bool drain_pending_;
37   bool invalid_ = false;
38 
39   SkiaUnrefQueue(fml::RefPtr<fml::TaskRunner> task_runner,
40                  fml::TimeDelta delay);
41 
42   ~SkiaUnrefQueue();
43 
44   FML_FRIEND_REF_COUNTED_THREAD_SAFE(SkiaUnrefQueue);
45   FML_FRIEND_MAKE_REF_COUNTED(SkiaUnrefQueue);
46   FML_DISALLOW_COPY_AND_ASSIGN(SkiaUnrefQueue);
47 };
48 
49 /// An object whose deallocation needs to be performed on an specific unref
50 /// queue. The template argument U need to have a call operator that returns
51 /// that unref queue.
52 template <class T>
53 class SkiaGPUObject {
54  public:
55   using SkiaObjectType = T;
56 
57   SkiaGPUObject() = default;
58 
SkiaGPUObject(sk_sp<SkiaObjectType> object,fml::RefPtr<SkiaUnrefQueue> queue)59   SkiaGPUObject(sk_sp<SkiaObjectType> object, fml::RefPtr<SkiaUnrefQueue> queue)
60       : object_(std::move(object)), queue_(std::move(queue)) {
61     FML_DCHECK(queue_ && object_);
62   }
63 
64   SkiaGPUObject(SkiaGPUObject&&) = default;
65 
~SkiaGPUObject()66   ~SkiaGPUObject() { reset(); }
67 
68   SkiaGPUObject& operator=(SkiaGPUObject&&) = default;
69 
get()70   sk_sp<SkiaObjectType> get() const { return object_; }
71 
reset()72   void reset() {
73     if (object_) {
74       queue_->Unref(object_.release());
75     }
76     queue_ = nullptr;
77     FML_DCHECK(object_ == nullptr);
78   }
79 
80  private:
81   sk_sp<SkiaObjectType> object_;
82   fml::RefPtr<SkiaUnrefQueue> queue_;
83 
84   FML_DISALLOW_COPY_AND_ASSIGN(SkiaGPUObject);
85 };
86 
87 }  // namespace flutter
88 
89 #endif  // FLUTTER_FLOW_SKIA_GPU_OBJECT_H_
90