blob: 3b4fcbf27f80f908f5512aecc2c7f8b28f9f863b [file] [log] [blame]
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_VIDEO_FRAME_SUBMITTER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_VIDEO_FRAME_SUBMITTER_H_
#include <memory>
#include <utility>
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "components/viz/client/shared_bitmap_reporter.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/shared_bitmap.h"
#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/buffer.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
// This single-threaded class facilitates the communication between the media
// stack and browser renderer, providing compositor frames containing video
// frames and corresponding resources to the |compositor_frame_sink_|. This
// class has dependencies on classes that use the media thread's OpenGL
// ContextProvider, and thus, besides construction, should be consistently ran
// from the same media SingleThreadTaskRunner.
class PLATFORM_EXPORT VideoFrameSubmitter
: public WebVideoFrameSubmitter,
public viz::ContextLostObserver,
public viz::SharedBitmapReporter,
public viz::mojom::blink::CompositorFrameSinkClient {
public:
explicit VideoFrameSubmitter(WebContextProviderCallback,
std::unique_ptr<VideoFrameResourceProvider>);
~VideoFrameSubmitter() override;
bool Rendering() { return is_rendering_; }
cc::VideoFrameProvider* Provider() { return video_frame_provider_; }
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient>* Binding() {
return &binding_;
}
void OnReceivedContextProvider(bool, scoped_refptr<viz::ContextProvider>);
// cc::VideoFrameProvider::Client implementation.
void StopUsingProvider() override;
void StartRendering() override;
void StopRendering() override;
void DidReceiveFrame() override;
bool IsDrivingFrameUpdates() const override;
// WebVideoFrameSubmitter implementation.
void Initialize(cc::VideoFrameProvider*) override;
void SetRotation(media::VideoRotation) override;
void SetIsOpaque(bool) override;
void EnableSubmission(viz::SurfaceId,
base::TimeTicks local_surface_id_allocation_time,
WebFrameSinkDestroyedCallback) override;
void UpdateSubmissionState(bool is_visible) override;
void SetForceSubmit(bool) override;
// viz::ContextLostObserver implementation.
void OnContextLost() override;
// cc::mojom::CompositorFrameSinkClient implementation.
void DidReceiveCompositorFrameAck(
const WTF::Vector<viz::ReturnedResource>& resources) override;
void OnBeginFrame(
const viz::BeginFrameArgs&,
WTF::HashMap<uint32_t, ::gfx::mojom::blink::PresentationFeedbackPtr>)
override;
void OnBeginFramePausedChanged(bool paused) override {}
void ReclaimResources(
const WTF::Vector<viz::ReturnedResource>& resources) override;
// viz::SharedBitmapReporter implementation.
void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle,
const viz::SharedBitmapId&) override;
void DidDeleteSharedBitmap(const viz::SharedBitmapId&) override;
void SetCompositorFrameSinkPtrForTesting(
viz::mojom::blink::CompositorFrameSinkPtr* sink) {
compositor_frame_sink_ = std::move(*sink);
}
void SetSurfaceIdForTesting(const viz::SurfaceId&, base::TimeTicks);
private:
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest, ContextLostDuringSubmit);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
ShouldSubmitPreventsSubmission);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
SetForceSubmitForcesSubmission);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
FrameSizeChangeUpdatesLocalSurfaceId);
FRIEND_TEST_ALL_PREFIXES(VideoFrameSubmitterTest,
StopUsingProviderDuringContextLost);
void StartSubmitting();
void UpdateSubmissionStateInternal();
// Returns whether a frame was submitted.
bool SubmitFrame(const viz::BeginFrameAck&, scoped_refptr<media::VideoFrame>);
void SubmitEmptyFrame();
// Pulls frame and submits it to compositor.
// Used in cases like PaintSingleFrame, which occurs before video rendering
// has started to post a poster image, or to submit a final frame before
// ending rendering.
void SubmitSingleFrame();
// Return whether the submitter should submit frames based on its current
// state.
bool ShouldSubmit() const;
cc::VideoFrameProvider* video_frame_provider_ = nullptr;
scoped_refptr<viz::ContextProvider> context_provider_;
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
WebContextProviderCallback context_provider_callback_;
std::unique_ptr<VideoFrameResourceProvider> resource_provider_;
WebFrameSinkDestroyedCallback frame_sink_destroyed_callback_;
bool waiting_for_compositor_ack_ = false;
bool is_rendering_;
// If we are not on screen, we should not submit.
bool should_submit_internal_ = false;
// Whether frames should always be submitted, even if we're not visible.
bool force_submit_ = false;
media::VideoRotation rotation_;
bool is_opaque_ = true;
viz::FrameSinkId frame_sink_id_;
// Size of the video frame being submitted. It is set the first time a frame
// is submitted. Every time there is a change in the video frame size, the
// child component of the LocalSurfaceId will be updated.
gfx::Rect frame_size_;
// Used to updated the LocalSurfaceId when detecting a change in video frame
// size.
viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
THREAD_CHECKER(media_thread_checker_);
base::WeakPtrFactory<VideoFrameSubmitter> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(VideoFrameSubmitter);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_VIDEO_FRAME_SUBMITTER_H_