1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
gpu / command_buffer / service / image_reader_gl_owner.h [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_IMAGE_READER_GL_OWNER_H_
#define GPU_COMMAND_BUFFER_SERVICE_IMAGE_READER_GL_OWNER_H_
#include <media/NdkImageReader.h>
#include <memory>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/threading/thread_checker.h"
#include "gpu/command_buffer/service/ref_counted_lock.h"
#include "gpu/command_buffer/service/texture_owner.h"
#include "gpu/gpu_gles2_export.h"
#include "ui/gl/gl_fence_egl.h"
namespace base {
namespace android {
class ScopedHardwareBufferFenceSync;
} // namespace android
} // namespace base
namespace gpu {
// This class wraps the AImageReader usage and is used to create a GL texture
// using the current platform GL context and returns a new ImageReaderGLOwner
// attached to it. The surface handle of the AImageReader is attached to
// decoded media frames. Media frames can update the attached surface handle
// with image data and this class helps to create an eglImage using that image
// data present in the surface.
class GPU_GLES2_EXPORT ImageReaderGLOwner : public TextureOwner,
public RefCountedLockHelperDrDc {
public:
ImageReaderGLOwner(const ImageReaderGLOwner&) = delete;
ImageReaderGLOwner& operator=(const ImageReaderGLOwner&) = delete;
gl::GLContext* GetContext() const override;
gl::GLSurface* GetSurface() const override;
void SetFrameAvailableCallback(
const base::RepeatingClosure& frame_available_cb) override;
gl::ScopedJavaSurface CreateJavaSurface() const override;
void UpdateTexImage() override;
void ReleaseBackBuffers() override;
std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
GetAHardwareBuffer() override;
bool GetCodedSizeAndVisibleRect(gfx::Size rotated_visible_size,
gfx::Size* coded_size,
gfx::Rect* visible_rect) override;
void RunWhenBufferIsAvailable(base::OnceClosure callback) override;
const AImageReader* image_reader_for_testing() const
NO_THREAD_SAFETY_ANALYSIS {
return image_reader_;
}
int32_t max_images_for_testing() const { return max_images_; }
// MemoryDumpProvider:
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
protected:
void ReleaseResources() override;
private:
friend class TextureOwner;
friend class ImageReaderGLOwnerTest;
class ScopedHardwareBufferImpl;
// Manages ownership of the latest image retrieved from AImageReader and
// ensuring synchronization of its use in GL using fences.
class ScopedCurrentImageRef {
public:
ScopedCurrentImageRef(ImageReaderGLOwner* texture_owner,
AImage* image,
base::ScopedFD ready_fence);
ScopedCurrentImageRef(const ScopedCurrentImageRef&) = delete;
ScopedCurrentImageRef& operator=(const ScopedCurrentImageRef&) = delete;
~ScopedCurrentImageRef();
AImage* image() const { return image_; }
base::ScopedFD GetReadyFence() const;
private:
raw_ptr<ImageReaderGLOwner> texture_owner_;
raw_ptr<AImage> image_;
base::ScopedFD ready_fence_;
};
ImageReaderGLOwner(std::unique_ptr<AbstractTextureAndroid> texture,
Mode secure_mode,
scoped_refptr<SharedContextState> context_state,
scoped_refptr<RefCountedLock> drdc_lock,
TextureOwnerCodecType type_for_metrics);
~ImageReaderGLOwner() override;
// Registers and releases a ref on the image. Once the ref-count for an image
// goes to 0, it is released back to the AImageReader with an optional release
// fence if needed.
void RegisterRefOnImageLocked(AImage* image);
void ReleaseRefOnImageLocked(AImage* image, base::ScopedFD fence_fd);
// This method acquires |lock_| and calls ReleaseRefOnImageLocked().
void ReleaseRefOnImage(AImage* image, base::ScopedFD fence_fd);
gfx::Rect GetCropRectLocked();
static void OnFrameAvailable(void* context, AImageReader* reader);
// All members which can be concurrently accessed from multiple threads will
// be guarded by |lock_|.
mutable base::Lock lock_;
// AImageReader instance.
raw_ptr<AImageReader> image_reader_ GUARDED_BY(lock_);
// Most recently acquired image using image reader. This works like a cached
// image until next new image is acquired which overwrites this.
std::optional<ScopedCurrentImageRef> current_image_ref_ GUARDED_BY(lock_);
std::unique_ptr<AImageReader_ImageListener> listener_;
// A map consisting of pending refs on an AImage. If an image has any refs, it
// is automatically released once the ref-count is 0.
struct ImageRef {
ImageRef();
ImageRef(const ImageRef&) = delete;
ImageRef& operator=(const ImageRef&) = delete;
~ImageRef();
ImageRef(ImageRef&& other);
ImageRef& operator=(ImageRef&& other);
size_t count = 0u;
base::ScopedFD release_fence_fd;
gfx::Size size;
size_t estimated_size_in_bytes = 0;
};
using AImageRefMap = base::flat_map<AImage*, ImageRef>;
AImageRefMap image_refs_ GUARDED_BY(lock_);
std::atomic<size_t> total_estimated_size_in_bytes_ = 0;
// The context and surface that were used to create |texture_id_|.
scoped_refptr<gl::GLContext> context_;
scoped_refptr<gl::GLSurface> surface_;
int32_t max_images_ = 0;
// Frame available callback handling. ImageListener registered with
// AImageReader is notified when there is a new frame available which
// in turns runs the callback function.
base::RepeatingClosure frame_available_cb_;
// Runs when free buffer is available.
base::OnceClosure buffer_available_cb_ GUARDED_BY(lock_);
// This class is created on gpu main thread.
THREAD_CHECKER(gpu_main_thread_checker_);
const TextureOwnerCodecType type_for_metrics_;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_IMAGE_READER_GL_OWNER_H_