#ifndef ASH_CAPTURE_MODE_CAMERA_VIDEO_FRAME_RENDERER_H_
#define ASH_CAPTURE_MODE_CAMERA_VIDEO_FRAME_RENDERER_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/capture_mode/camera_video_frame_handler.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/size.h"
namespace cc {
class LayerTreeFrameSink;
}
namespace media {
class VideoResourceUpdater;
}
namespace viz {
class RasterContextProvider;
}
namespace ash {
class CameraVideoFrameRenderer
: public capture_mode::CameraVideoFrameHandler::Delegate,
public viz::BeginFrameObserverBase,
public cc::LayerTreeFrameSinkClient {
public:
CameraVideoFrameRenderer(
mojo::Remote<video_capture::mojom::VideoSource> camera_video_source,
const media::VideoCaptureFormat& capture_format,
bool should_flip_frames_horizontally);
CameraVideoFrameRenderer(const CameraVideoFrameRenderer&) = delete;
CameraVideoFrameRenderer& operator=(const CameraVideoFrameRenderer&) = delete;
~CameraVideoFrameRenderer() override;
aura::Window* host_window() { return &host_window_; }
bool should_flip_frames_horizontally() const {
return should_flip_frames_horizontally_;
}
void Initialize();
void OnCameraVideoFrame(scoped_refptr<media::VideoFrame> frame) override;
void OnFatalErrorOrDisconnection() override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
void SetBeginFrameSource(viz::BeginFrameSource* source) override;
std::optional<viz::HitTestRegionList> BuildHitTestData() override;
void ReclaimResources(std::vector<viz::ReturnedResource> resources) override;
void SetTreeActivationCallback(base::RepeatingClosure callback) override;
void DidReceiveCompositorFrameAck() override;
void DidPresentCompositorFrame(
uint32_t frame_token,
const viz::FrameTimingDetails& details) override;
void DidLoseLayerTreeFrameSink() override;
void OnDraw(const gfx::Transform& transform,
const gfx::Rect& viewport,
bool resourceless_software_draw,
bool skip_draw) override;
void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override;
void SetExternalTilePriorityConstraints(
const gfx::Rect& viewport_rect,
const gfx::Transform& transform) override;
private:
friend class CaptureModeTestApi;
viz::CompositorFrame CreateCompositorFrame(
const viz::BeginFrameAck& begin_frame_ack,
scoped_refptr<media::VideoFrame> video_frame);
aura::Window host_window_;
capture_mode::CameraVideoFrameHandler video_frame_handler_;
viz::ClientResourceProvider client_resource_provider_;
viz::FrameTokenGenerator compositor_frame_token_generator_;
scoped_refptr<media::VideoFrame> current_video_frame_;
gfx::Size last_compositor_frame_size_pixels_;
float last_compositor_frame_dsf_ = 1.0f;
scoped_refptr<viz::RasterContextProvider> context_provider_;
std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink_;
std::unique_ptr<media::VideoResourceUpdater> video_resource_updater_;
raw_ptr<viz::BeginFrameSource> begin_frame_source_ = nullptr;
base::OnceCallback<void(scoped_refptr<media::VideoFrame> frame)>
on_video_frame_rendered_for_test_;
bool pending_compositor_frame_ack_ = false;
bool should_flip_frames_horizontally_ = true;
};
}
#endif