blob: 397f45ae6bd4865b8fd0f5f7b78f48d9ebdcce6c [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_ANDROID_IMAGE_READER_GL_OWNER_H_
#define MEDIA_GPU_ANDROID_IMAGE_READER_GL_OWNER_H_
#include <memory>
#include "base/android/android_image_reader_compat.h"
#include "base/containers/flat_map.h"
#include "media/gpu/android/texture_owner.h"
#include "ui/gl/gl_fence_egl.h"
#include "ui/gl/gl_image_ahardwarebuffer.h"
namespace base {
namespace android {
class ScopedHardwareBufferFenceSync;
} // namespace android
} // namespace base
namespace media {
// 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 MEDIA_GPU_EXPORT ImageReaderGLOwner : public TextureOwner {
public:
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 EnsureTexImageBound() override;
void GetTransformMatrix(float mtx[16]) override;
void ReleaseBackBuffers() override;
std::unique_ptr<base::android::ScopedHardwareBufferFenceSync>
GetAHardwareBuffer() override;
const AImageReader* image_reader_for_testing() const { return image_reader_; }
int32_t max_images_for_testing() const { return max_images_; }
protected:
void OnTextureDestroyed(gpu::gles2::AbstractTexture*) override;
private:
friend class TextureOwner;
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();
AImage* image() const { return image_; }
base::ScopedFD GetReadyFence() const;
void EnsureBound();
private:
ImageReaderGLOwner* texture_owner_;
AImage* image_;
base::ScopedFD ready_fence_;
// Set to true if the current image is bound to |texture_id_|.
bool image_bound_ = false;
DISALLOW_COPY_AND_ASSIGN(ScopedCurrentImageRef);
};
ImageReaderGLOwner(std::unique_ptr<gpu::gles2::AbstractTexture> texture,
Mode secure_mode);
~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 RegisterRefOnImage(AImage* image);
void ReleaseRefOnImage(AImage* image, base::ScopedFD fence_fd);
static void OnFrameAvailable(void* context, AImageReader* reader);
// AImageReader instance
AImageReader* image_reader_;
// Most recently acquired image using image reader. This works like a cached
// image until next new image is acquired which overwrites this.
base::Optional<ScopedCurrentImageRef> current_image_ref_;
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();
ImageRef(ImageRef&& other);
ImageRef& operator=(ImageRef&& other);
size_t count = 0u;
base::ScopedFD release_fence_fd;
DISALLOW_COPY_AND_ASSIGN(ImageRef);
};
using AImageRefMap = base::flat_map<AImage*, ImageRef>;
AImageRefMap image_refs_;
// reference to the class instance which is used to dynamically
// load the functions in android libraries at runtime.
base::android::AndroidImageReader& loader_;
// 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_;
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(ImageReaderGLOwner);
};
} // namespace media
#endif // MEDIA_GPU_ANDROID_IMAGE_READER_GL_OWNER_H_