1 // Copyright 2019 The Chromium 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 MEDIA_GPU_ANDROID_POOLED_SHARED_IMAGE_VIDEO_PROVIDER_H_
6 #define MEDIA_GPU_ANDROID_POOLED_SHARED_IMAGE_VIDEO_PROVIDER_H_
7 
8 #include "base/memory/weak_ptr.h"
9 #include "base/threading/sequence_bound.h"
10 #include "gpu/ipc/service/command_buffer_stub.h"
11 #include "media/gpu/android/shared_image_video_provider.h"
12 #include "media/gpu/command_buffer_helper.h"
13 
14 namespace media {
15 
16 class PooledSharedImageVideoProviderTest;
17 
18 // Provider class for shared images.
19 class MEDIA_GPU_EXPORT PooledSharedImageVideoProvider
20     : public SharedImageVideoProvider {
21  public:
22   // Helper class that processes image returns on the gpu thread.
23   class GpuHelper {
24    public:
25     GpuHelper() = default;
26     virtual ~GpuHelper() = default;
27 
28     // Called (on the gpu thread) to handle image return.
29     virtual void OnImageReturned(
30         const gpu::SyncToken& sync_token,
31         scoped_refptr<CodecImageHolder> codec_image_holder,
32         base::OnceClosure cb) = 0;
33 
34    private:
35     DISALLOW_COPY_AND_ASSIGN(GpuHelper);
36   };
37 
38   // Create a default implementation.  |provider| is the underlying provider to
39   // create shared images.
40   static std::unique_ptr<PooledSharedImageVideoProvider> Create(
41       scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
42       GetStubCB get_stub_cb,
43       std::unique_ptr<SharedImageVideoProvider> provider);
44 
45   ~PooledSharedImageVideoProvider() override;
46 
47   // SharedImageVideoProvider
48   void Initialize(GpuInitCB gpu_init_cb) override;
49   void RequestImage(ImageReadyCB cb,
50                     const ImageSpec& spec,
51                     scoped_refptr<gpu::TextureOwner> texture_owner) override;
52 
53  private:
54   friend class PooledSharedImageVideoProviderTest;
55 
56   PooledSharedImageVideoProvider(
57       base::SequenceBound<GpuHelper> gpu_helper,
58       std::unique_ptr<SharedImageVideoProvider> provider);
59 
60   class GpuHelperImpl : public GpuHelper {
61    public:
62     GpuHelperImpl(GetStubCB get_stub_cb);
63     ~GpuHelperImpl() override;
64 
65     // GpuHelper
66     void OnImageReturned(const gpu::SyncToken& sync_token,
67                          scoped_refptr<CodecImageHolder> codec_image_holder,
68                          base::OnceClosure cb) override;
69 
70    private:
71     void OnSyncTokenCleared(scoped_refptr<CodecImageHolder> codec_image_holder,
72                             base::OnceClosure cb);
73 
74     scoped_refptr<CommandBufferHelper> command_buffer_helper_;
75     base::WeakPtrFactory<GpuHelperImpl> weak_factory_;
76   };
77 
78   // Record of on image from |provider|.
79   class PooledImage : public base::RefCounted<PooledImage> {
80    public:
81     PooledImage(const ImageSpec& spec, ImageRecord record);
82 
83     ImageSpec spec;
84     // The original record, including the original reuse callback.
85     ImageRecord record;
86 
87    private:
88     virtual ~PooledImage();
89 
90     friend class base::RefCounted<PooledImage>;
91   };
92 
93   // One request from the client that's pending an image.
94   class PendingRequest {
95    public:
96     PendingRequest(const ImageSpec& spec, ImageReadyCB cb);
97     ~PendingRequest();
98     ImageSpec spec;
99     ImageReadyCB cb;
100   };
101 
102   // Called by |provider_| when a new image is created.
103   void OnImageCreated(ImageSpec spec, ImageRecord record);
104 
105   // Called by our client when it runs the release cb, to notify us that the
106   // image is no longer in use.
107   void OnImageReturned(scoped_refptr<PooledImage> pooled_image,
108                        const gpu::SyncToken& sync_token);
109 
110   // Given a free image |pooled_image| that is not in our pool, use it to either
111   // fulfill a pending request, add it to the pool, or discard it.
112   void ProcessFreePooledImage(scoped_refptr<PooledImage> pooled_image);
113 
114   // Underlying provider that we use to construct images.
115   std::unique_ptr<SharedImageVideoProvider> provider_;
116 
117   // All currently unused images.
118   std::list<scoped_refptr<PooledImage>> pool_;
119 
120   // Spec for all images in |pool_|.
121   ImageSpec pool_spec_;
122 
123   std::list<PendingRequest> pending_requests_;
124 
125   base::SequenceBound<GpuHelper> gpu_helper_;
126 
127   base::WeakPtrFactory<PooledSharedImageVideoProvider> weak_factory_;
128 
129   DISALLOW_COPY_AND_ASSIGN(PooledSharedImageVideoProvider);
130 };
131 
132 }  // namespace media
133 
134 #endif  // MEDIA_GPU_ANDROID_POOLED_SHARED_IMAGE_VIDEO_PROVIDER_H_
135