Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / frame_buffer_pool.h
1 // Copyright 2017 The Chromium Authors
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 MEDIA_FILTERS_FRAME_BUFFER_POOL_H_
6 #define MEDIA_FILTERS_FRAME_BUFFER_POOL_H_
7
8 #include <stdint.h>
9
10 #include <vector>
11
12 #include "base/functional/callback_forward.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/synchronization/lock.h"
16 #include "base/time/default_tick_clock.h"
17 #include "base/trace_event/memory_dump_provider.h"
18 #include "media/base/media_export.h"
19
20 namespace base {
21 class SequencedTaskRunner;
22 }
23
24 namespace media {
25
26 // FrameBufferPool is a pool of simple CPU memory. This class needs to be ref-
27 // counted since frames created using this memory may live beyond the lifetime
28 // of the caller to this class.
29 //
30 // This class is thread-safe, with the exception that it must be constructed on
31 // the same thread that `Shutdown()` is called on.  Destruction may happen on
32 // any thread after `Shutdown()` returns. All other methods may be called on any
33 // thread safely, unless noted.
34 class MEDIA_EXPORT FrameBufferPool
35     : public base::RefCountedThreadSafe<FrameBufferPool>,
36       public base::trace_event::MemoryDumpProvider {
37  public:
38   // Must be called on the same thread that `Shutdown()` is called on.  If
39   // `zero_initialize_memory` is true, then initial allocations will be
40   // cleared.  This does not affect reused buffers, which are never cleared.
41   explicit FrameBufferPool(bool zero_initialize_memory = false);
42
43   FrameBufferPool(const FrameBufferPool&) = delete;
44   FrameBufferPool& operator=(const FrameBufferPool&) = delete;
45
46   // Called when a frame buffer allocation is needed. Upon return |fb_priv| will
47   // be set to a private value used to identify the buffer in future calls and a
48   // buffer of at least |min_size| will be returned.
49   uint8_t* GetFrameBuffer(size_t min_size, void** fb_priv);
50
51   // Called when a frame buffer allocation is no longer needed.
52   void ReleaseFrameBuffer(void* fb_priv);
53
54   // Allocates (or reuses) room for an alpha plane on a given frame buffer.
55   // |fb_priv| must be a value previously returned by GetFrameBuffer().
56   uint8_t* AllocateAlphaPlaneForFrameBuffer(size_t min_size, void* fb_priv);
57
58   // Generates a "no_longer_needed" closure that holds a reference to this pool;
59   // |fb_priv| must be a value previously returned by GetFrameBuffer(). The
60   // callback may be called on any thread.
61   base::OnceClosure CreateFrameCallback(void* fb_priv);
62
63   size_t get_pool_size_for_testing() const {
64     base::AutoLock lock(lock_);
65     return frame_buffers_.size();
66   }
67
68   void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
69     base::AutoLock lock(lock_);
70     tick_clock_ = tick_clock;
71   }
72
73   void force_allocation_error_for_testing() {
74     base::AutoLock lock(lock_);
75     force_allocation_error_ = true;
76   }
77
78   // Called when no more GetFrameBuffer() calls are expected. All unused memory
79   // is released at this time. As frames are returned their memory is released.
80   // This should not be called until anything that might call GetFrameBuffer()
81   // has been destroyed. Must be called on the same thread as the ctor.
82   void Shutdown();
83
84   enum { kStaleFrameLimitSecs = 10 };
85
86  private:
87   friend class base::RefCountedThreadSafe<FrameBufferPool>;
88   ~FrameBufferPool() override;
89
90   // Internal structure holding memory for decoding.
91   struct FrameBuffer;
92
93   // base::MemoryDumpProvider.
94   // Will always be called on `task_runner_`, though it is actually thread-safe.
95   bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
96                     base::trace_event::ProcessMemoryDump* pmd) override;
97
98   // Not safe to concurrent modifications to `buf`.  While the method is static,
99   // it's expected, but unchecked, that the caller holds `locked_` to prevent
100   // any modifications to `buf` during this call.
101   static bool IsUsedLocked(const FrameBuffer* buf);
102
103   // Drop all entries in |frame_buffers_| that report !IsUsedLocked().  Must be
104   // called with `lock_` held.
105   void EraseUnusedResourcesLocked();
106
107   // Method that gets called when a VideoFrame that references this pool gets
108   // destroyed.
109   void OnVideoFrameDestroyed(FrameBuffer* frame_buffer);
110
111   // Should we allocate memory and clear it, or just allocate it?  Note that
112   // memory is never cleared when reusing a previously returned buffer; only
113   // the initial allocation is affected.
114   const bool zero_initialize_memory_ = false;
115
116   // Here at the framebuffer cafe, all our dining philosophers share one fork.
117   mutable base::Lock lock_;
118
119   // Allocated frame buffers.
120   std::vector<std::unique_ptr<FrameBuffer>> frame_buffers_ GUARDED_BY(lock_);
121
122   bool in_shutdown_ GUARDED_BY(lock_) = false;
123
124   bool registered_dump_provider_ GUARDED_BY(lock_) = false;
125
126   bool force_allocation_error_ GUARDED_BY(lock_) = false;
127
128   // |tick_clock_| is always a DefaultTickClock outside of testing.
129   raw_ptr<const base::TickClock> tick_clock_ GUARDED_BY(lock_);
130
131   // Task runner that we tell the `MemoryDumpManager` about.  It is the task
132   // runner on which we'll be asked to provide a memory dump, and the one on
133   // which `Shutdown()` should be called.  It is set during construction.
134   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
135 };
136
137 }  // namespace media
138
139 #endif  // MEDIA_FILTERS_FRAME_BUFFER_POOL_H_