summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
blob: de63be8779de63aba372bb2c51622a8753fcdae1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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 "third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h"

#include <memory>
#include "base/bind.h"
#include "base/trace_event/trace_event.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_) {
    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;

  resource_provider_ = std::make_unique<cc::LayerTreeResourceProvider>(
      media_context_provider, shared_bitmap_manager_,
      gpu_memory_buffer_manager_, true, settings_.resource_settings);

  // TODO(kylechar): VideoResourceUpdater needs something it can notify about
  // SharedBitmaps that isn't a LayerTreeFrameSink. https://crbug.com/730660#c88
  resource_updater_ = std::make_unique<cc::VideoResourceUpdater>(
      context_provider_, nullptr, resource_provider_.get(),
      settings_.use_stream_video_draw_quad,
      settings_.resource_settings.use_gpu_memory_buffer_resources);
}

void VideoFrameResourceProvider::AppendQuads(
    viz::RenderPass* render_pass,
    scoped_refptr<media::VideoFrame> frame,
    media::VideoRotation rotation) {
  TRACE_EVENT0("media", "VideoFrameResourceProvider::AppendQuads");
  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;
  }

  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() {
  resource_updater_->ReleaseFrameResources();
}

void VideoFrameResourceProvider::PrepareSendToParent(
    const cc::LayerTreeResourceProvider::ResourceIdArray& resource_ids,
    std::vector<viz::TransferableResource>* transferable_resources) {
  resource_provider_->PrepareSendToParent(resource_ids, transferable_resources);
}

void VideoFrameResourceProvider::ReceiveReturnsFromParent(
    const std::vector<viz::ReturnedResource>& transferable_resources) {
  resource_provider_->ReceiveReturnsFromParent(transferable_resources);
}

}  // namespace blink