| // 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/memory/sanitized_object.h" | |
| #include "base/threading/thread_checker.h" | |
| #include "base/types/pass_key.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 { | |
| // TODO(https://crbug.com/496519208): Remove this macro. | |
| SANITIZED_OBJECT(); | |
| public: | |
| ImageReaderGLOwner(base::PassKey<TextureOwner>, | |
| Mode secure_mode, | |
| scoped_refptr<SharedContextState> context_state, | |
| scoped_refptr<RefCountedLock> drdc_lock, | |
| TextureOwnerCodecType type_for_metrics); | |
| ImageReaderGLOwner(const ImageReaderGLOwner&) = delete; | |
| ImageReaderGLOwner& operator=(const ImageReaderGLOwner&) = delete; | |
| void SetFrameAvailableCallback( | |
| const base::RepeatingClosure& frame_available_cb) override; | |
| gl::ScopedJavaSurface CreateJavaSurface() const override; | |
| bool UpdateTexImage(bool discard) 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: | |
| 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() 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; | |
| 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_ |