blob: 146d2a2038e18039f5156da03e6ed4030defac85 [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.
#include "platform/graphics/VideoFrameResourceProvider.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "cc/resources/layer_tree_resource_provider.h"
#include "cc/resources/video_resource_updater.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/quads/render_pass.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "media/base/video_frame.h"
namespace cc {
class VideoFrameExternalResources;
} // namespace cc
namespace blink {
VideoFrameResourceProvider::VideoFrameResourceProvider(
WebContextProviderCallback context_provider_callback,
viz::SharedBitmapManager* shared_bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const cc::LayerTreeSettings& settings)
: context_provider_callback_(std::move(context_provider_callback)),
shared_bitmap_manager_(shared_bitmap_manager),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
settings_(settings),
weak_ptr_factory_(this) {}
VideoFrameResourceProvider::~VideoFrameResourceProvider() {
if (context_provider_) {
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_updater_ = nullptr;
resource_provider_ = nullptr;
}
}
void VideoFrameResourceProvider::ObtainContextProvider() {
context_provider_callback_.Run(base::BindOnce(
&VideoFrameResourceProvider::Initialize, weak_ptr_factory_.GetWeakPtr()));
}
void VideoFrameResourceProvider::Initialize(
viz::ContextProvider* media_context_provider) {
// TODO(lethalantidote): Need to handle null contexts.
// https://crbug/768565
CHECK(media_context_provider);
context_provider_ = media_context_provider;
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_provider_ = std::make_unique<cc::LayerTreeResourceProvider>(
media_context_provider, shared_bitmap_manager_,
gpu_memory_buffer_manager_, true, settings_.resource_settings);
resource_updater_ = std::make_unique<cc::VideoResourceUpdater>(
media_context_provider, resource_provider_.get(),
settings_.use_stream_video_draw_quad);
}
void VideoFrameResourceProvider::AppendQuads(
viz::RenderPass* render_pass,
scoped_refptr<media::VideoFrame> frame,
media::VideoRotation rotation) {
gfx::Transform transform = gfx::Transform();
gfx::Size rotated_size = frame->coded_size();
switch (rotation) {
case media::VIDEO_ROTATION_90:
rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
transform.Rotate(90.0);
transform.Translate(0.0, -rotated_size.height());
break;
case media::VIDEO_ROTATION_180:
transform.Rotate(180.0);
transform.Translate(-rotated_size.width(), -rotated_size.height());
break;
case media::VIDEO_ROTATION_270:
rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
transform.Rotate(270.0);
transform.Translate(-rotated_size.width(), 0);
break;
case media::VIDEO_ROTATION_0:
break;
}
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_updater_->ObtainFrameResources(frame);
// TODO(lethalantidote) : update with true value;
bool contents_opaque = true;
gfx::Rect visible_layer_rect = gfx::Rect(rotated_size);
gfx::Rect clip_rect = gfx::Rect(frame->coded_size());
bool is_clipped = false;
float draw_opacity = 1.0f;
int sorting_context_id = 0;
// Internal to this compositor frame, this video quad is never occluded,
// thus the full quad is visible.
gfx::Rect visible_quad_rect = gfx::Rect(rotated_size);
resource_updater_->AppendQuads(render_pass, std::move(frame), transform,
rotated_size, visible_layer_rect, clip_rect,
is_clipped, contents_opaque, draw_opacity,
sorting_context_id, visible_quad_rect);
}
void VideoFrameResourceProvider::ReleaseFrameResources() {
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_updater_->ReleaseFrameResources();
}
void VideoFrameResourceProvider::PrepareSendToParent(
const cc::LayerTreeResourceProvider::ResourceIdArray& resource_ids,
std::vector<viz::TransferableResource>* transferable_resources) {
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_provider_->PrepareSendToParent(resource_ids, transferable_resources);
}
void VideoFrameResourceProvider::ReceiveReturnsFromParent(
const std::vector<viz::ReturnedResource>& transferable_resources) {
viz::ContextProvider::ScopedContextLock lock(context_provider_);
resource_provider_->ReceiveReturnsFromParent(transferable_resources);
}
} // namespace blink