| // Copyright 2017 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_CODEC_IMAGE_H_ |
| #define MEDIA_GPU_ANDROID_CODEC_IMAGE_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "gpu/command_buffer/service/gl_stream_texture_image.h" |
| #include "media/gpu/android/codec_wrapper.h" |
| #include "media/gpu/android/promotion_hint_aggregator.h" |
| #include "media/gpu/android/surface_texture_gl_owner.h" |
| #include "media/gpu/media_gpu_export.h" |
| |
| namespace media { |
| |
| // A GLImage that renders MediaCodec buffers to a TextureOwner or overlay |
| // as needed in order to draw them. |
| class MEDIA_GPU_EXPORT CodecImage : public gpu::gles2::GLStreamTextureImage { |
| public: |
| // A callback for observing CodecImage destruction. This is a repeating cb |
| // since CodecImageGroup calls the same cb for multiple images. |
| using DestructionCb = base::RepeatingCallback<void(CodecImage*)>; |
| |
| CodecImage(std::unique_ptr<CodecOutputBuffer> output_buffer, |
| scoped_refptr<TextureOwner> texture_owner, |
| PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb); |
| |
| void SetDestructionCb(DestructionCb destruction_cb); |
| |
| // gl::GLImage implementation |
| gfx::Size GetSize() override; |
| unsigned GetInternalFormat() override; |
| bool BindTexImage(unsigned target) override; |
| void ReleaseTexImage(unsigned target) override; |
| bool CopyTexImage(unsigned target) override; |
| bool CopyTexSubImage(unsigned target, |
| const gfx::Point& offset, |
| const gfx::Rect& rect) override; |
| bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| int z_order, |
| gfx::OverlayTransform transform, |
| const gfx::Rect& bounds_rect, |
| const gfx::RectF& crop_rect, |
| bool enable_blend, |
| std::unique_ptr<gfx::GpuFence> gpu_fence) override; |
| void SetColorSpace(const gfx::ColorSpace& color_space) override {} |
| void Flush() override {} |
| void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, |
| uint64_t process_tracing_id, |
| const std::string& dump_name) override; |
| std::unique_ptr<ScopedHardwareBuffer> GetAHardwareBuffer() override; |
| // gpu::gles2::GLStreamTextureMatrix implementation |
| void GetTextureMatrix(float xform[16]) override; |
| void NotifyPromotionHint(bool promotion_hint, |
| int display_x, |
| int display_y, |
| int display_width, |
| int display_height) override; |
| |
| // Whether the codec buffer has been rendered to the front buffer. |
| bool was_rendered_to_front_buffer() const { |
| return phase_ == Phase::kInFrontBuffer; |
| } |
| |
| // Whether this image is backed by a texture owner. |
| bool is_texture_owner_backed() const { return !!texture_owner_; } |
| |
| scoped_refptr<TextureOwner> texture_owner() const { return texture_owner_; } |
| |
| // Renders this image to the front buffer of its backing surface. |
| // Returns true if the buffer is in the front buffer. Returns false if the |
| // buffer was invalidated. After an image is invalidated it's no longer |
| // possible to render it. |
| bool RenderToFrontBuffer(); |
| |
| // Renders this image to the back buffer of its texture owner. Only valid if |
| // is_texture_owner_backed(). Returns true if the buffer is in the back |
| // buffer. Returns false if the buffer was invalidated. |
| bool RenderToTextureOwnerBackBuffer(); |
| |
| // Release any codec buffer without rendering, if we have one. |
| virtual void ReleaseCodecBuffer(); |
| |
| protected: |
| ~CodecImage() override; |
| |
| private: |
| // The lifecycle phases of an image. |
| // The only possible transitions are from left to right. Both |
| // kInFrontBuffer and kInvalidated are terminal. |
| enum class Phase { kInCodec, kInBackBuffer, kInFrontBuffer, kInvalidated }; |
| |
| // Renders this image to the texture owner front buffer by first rendering |
| // it to the back buffer if it's not already there, and then waiting for the |
| // frame available event before calling UpdateTexImage(). Passing |
| // BindingsMode::kDontRestore skips the work of restoring the current texture |
| // bindings if the texture owner's context is already current. Otherwise, |
| // this switches contexts and preserves the texture bindings. |
| // Returns true if the buffer is in the front buffer. Returns false if the |
| // buffer was invalidated. |
| enum class BindingsMode { kRestore, kDontRestore }; |
| bool RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode); |
| |
| // Renders this image to the overlay. Returns true if the buffer is in the |
| // overlay front buffer. Returns false if the buffer was invalidated. |
| bool RenderToOverlay(); |
| |
| // The phase of the image buffer's lifecycle. |
| Phase phase_; |
| |
| // The buffer backing this image. |
| std::unique_ptr<CodecOutputBuffer> output_buffer_; |
| |
| // The TextureOwner that |output_buffer_| will be rendered to. Or null, if |
| // this image is backed by an overlay. |
| scoped_refptr<TextureOwner> texture_owner_; |
| |
| // The bounds last sent to the overlay. |
| gfx::Rect most_recent_bounds_; |
| |
| // Callback to notify about promotion hints and overlay position. |
| PromotionHintAggregator::NotifyPromotionHintCB promotion_hint_cb_; |
| |
| DestructionCb destruction_cb_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CodecImage); |
| }; |
| |
| } // namespace media |
| |
| #endif // MEDIA_GPU_ANDROID_CODEC_IMAGE_H_ |