video_layer_impl.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // Copyright 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "cc/layers/video_layer_impl.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/check.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "cc/base/features.h"
  12. #include "cc/layers/video_frame_provider_client_impl.h"
  13. #include "cc/trees/layer_tree_frame_sink.h"
  14. #include "cc/trees/layer_tree_impl.h"
  15. #include "cc/trees/occlusion.h"
  16. #include "cc/trees/task_runner_provider.h"
  17. #include "components/viz/client/client_resource_provider.h"
  18. #include "components/viz/common/quads/texture_draw_quad.h"
  19. #include "components/viz/common/quads/yuv_video_draw_quad.h"
  20. #include "media/base/video_frame.h"
  21. #include "media/renderers/video_resource_updater.h"
  22. #include "ui/gfx/color_space.h"
  23. namespace cc {
  24. // static
  25. std::unique_ptr<VideoLayerImpl> VideoLayerImpl::Create(
  26. LayerTreeImpl* tree_impl,
  27. int id,
  28. VideoFrameProvider* provider,
  29. const media::VideoTransformation& video_transform) {
  30. DCHECK(tree_impl->task_runner_provider()->IsMainThreadBlocked() ||
  31. base::FeatureList::IsEnabled(features::kNonBlockingCommit));
  32. DCHECK(tree_impl->task_runner_provider()->IsImplThread());
  33. scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl =
  34. VideoFrameProviderClientImpl::Create(
  35. provider, tree_impl->GetVideoFrameControllerClient());
  36. return base::WrapUnique(new VideoLayerImpl(
  37. tree_impl, id, std::move(provider_client_impl), video_transform));
  38. }
  39. VideoLayerImpl::VideoLayerImpl(
  40. LayerTreeImpl* tree_impl,
  41. int id,
  42. scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl,
  43. const media::VideoTransformation& video_transform)
  44. : LayerImpl(tree_impl, id),
  45. provider_client_impl_(std::move(provider_client_impl)),
  46. video_transform_(video_transform) {
  47. set_may_contain_video(true);
  48. }
  49. VideoLayerImpl::~VideoLayerImpl() {
  50. if (!provider_client_impl_->Stopped()) {
  51. // In impl side painting, we may have a pending and active layer
  52. // associated with the video provider at the same time. Both have a ref
  53. // on the VideoFrameProviderClientImpl, but we stop when the first
  54. // LayerImpl (the one on the pending tree) is destroyed since we know
  55. // the main thread is blocked for this commit.
  56. DCHECK(layer_tree_impl()->task_runner_provider()->IsMainThreadBlocked() ||
  57. base::FeatureList::IsEnabled(features::kNonBlockingCommit));
  58. DCHECK(layer_tree_impl()->task_runner_provider()->IsImplThread());
  59. provider_client_impl_->Stop();
  60. }
  61. }
  62. std::unique_ptr<LayerImpl> VideoLayerImpl::CreateLayerImpl(
  63. LayerTreeImpl* tree_impl) const {
  64. return base::WrapUnique(new VideoLayerImpl(
  65. tree_impl, id(), provider_client_impl_, video_transform_));
  66. }
  67. void VideoLayerImpl::DidBecomeActive() {
  68. provider_client_impl_->SetActiveVideoLayer(this);
  69. }
  70. bool VideoLayerImpl::WillDraw(DrawMode draw_mode,
  71. viz::ClientResourceProvider* resource_provider)
  72. NO_THREAD_SAFETY_ANALYSIS {
  73. if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
  74. return false;
  75. if (!LayerImpl::WillDraw(draw_mode, resource_provider))
  76. return false;
  77. // Explicitly acquire and release the provider mutex so it can be held from
  78. // WillDraw to DidDraw. Since the compositor thread is in the middle of
  79. // drawing, the layer will not be destroyed before DidDraw is called.
  80. // Therefore, the only thing that will prevent this lock from being released
  81. // is the GPU process locking it. As the GPU process can't cause the
  82. // destruction of the provider (calling StopUsingProvider), holding this
  83. // lock should not cause a deadlock.
  84. frame_ = provider_client_impl_->AcquireLockAndCurrentFrame();
  85. if (!frame_.get()) {
  86. // Drop any resources used by the updater if there is no frame to display.
  87. updater_ = nullptr;
  88. // NO_THREAD_SAFETY_ANALYSIS: Releasing the lock in some return paths only.
  89. provider_client_impl_->ReleaseLock();
  90. return false;
  91. }
  92. if (!updater_) {
  93. const LayerTreeSettings& settings = layer_tree_impl()->settings();
  94. // TODO(sergeyu): Pass RasterContextProvider when it's available. Then
  95. // remove ContextProvider parameter from VideoResourceUpdater.
  96. updater_ = std::make_unique<media::VideoResourceUpdater>(
  97. layer_tree_impl()->context_provider(),
  98. /*raster_context_provider=*/nullptr,
  99. layer_tree_impl()->layer_tree_frame_sink(),
  100. layer_tree_impl()->resource_provider(),
  101. settings.use_stream_video_draw_quad,
  102. settings.resource_settings.use_gpu_memory_buffer_resources,
  103. settings.resource_settings.use_r16_texture,
  104. layer_tree_impl()->max_texture_size());
  105. }
  106. updater_->ObtainFrameResources(frame_);
  107. return true;
  108. }
  109. void VideoLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
  110. AppendQuadsData* append_quads_data) {
  111. DCHECK(frame_);
  112. gfx::Transform transform = DrawTransform();
  113. // bounds() is in post-rotation space so quad rect in content space must be
  114. // in pre-rotation space
  115. gfx::Size rotated_size = bounds();
  116. // Prefer the frame level transform if set.
  117. auto media_transform =
  118. frame_->metadata().transformation.value_or(video_transform_);
  119. switch (media_transform.rotation) {
  120. case media::VIDEO_ROTATION_90:
  121. rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
  122. transform.RotateAboutZAxis(90.0);
  123. transform.Translate(0.0, -rotated_size.height());
  124. break;
  125. case media::VIDEO_ROTATION_180:
  126. transform.RotateAboutZAxis(180.0);
  127. transform.Translate(-rotated_size.width(), -rotated_size.height());
  128. break;
  129. case media::VIDEO_ROTATION_270:
  130. rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
  131. transform.RotateAboutZAxis(270.0);
  132. transform.Translate(-rotated_size.width(), 0);
  133. break;
  134. case media::VIDEO_ROTATION_0:
  135. break;
  136. }
  137. if (media_transform.mirrored) {
  138. transform.RotateAboutYAxis(180.0);
  139. transform.Translate(-rotated_size.width(), 0);
  140. }
  141. gfx::Rect quad_rect(rotated_size);
  142. Occlusion occlusion_in_video_space =
  143. draw_properties()
  144. .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
  145. transform);
  146. gfx::Rect visible_quad_rect =
  147. occlusion_in_video_space.GetUnoccludedContentRect(quad_rect);
  148. if (visible_quad_rect.IsEmpty())
  149. return;
  150. absl::optional<gfx::Rect> clip_rect_opt;
  151. if (is_clipped()) {
  152. clip_rect_opt = clip_rect();
  153. }
  154. updater_->AppendQuads(render_pass, frame_, transform, quad_rect,
  155. visible_quad_rect, draw_properties().mask_filter_info,
  156. clip_rect_opt, contents_opaque(), draw_opacity(),
  157. GetSortingContextId());
  158. }
  159. void VideoLayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
  160. provider_client_impl_->AssertLocked();
  161. LayerImpl::DidDraw(resource_provider);
  162. DCHECK(frame_.get());
  163. updater_->ReleaseFrameResources();
  164. provider_client_impl_->PutCurrentFrame();
  165. frame_ = nullptr;
  166. provider_client_impl_->ReleaseLock();
  167. }
  168. SimpleEnclosedRegion VideoLayerImpl::VisibleOpaqueRegion() const {
  169. // If we don't have a frame yet, then we don't have an opaque region.
  170. if (!provider_client_impl_->HasCurrentFrame())
  171. return SimpleEnclosedRegion();
  172. return LayerImpl::VisibleOpaqueRegion();
  173. }
  174. void VideoLayerImpl::ReleaseResources() {
  175. updater_ = nullptr;
  176. }
  177. gfx::ContentColorUsage VideoLayerImpl::GetContentColorUsage() const {
  178. gfx::ColorSpace frame_color_space;
  179. if (frame_)
  180. frame_color_space = frame_->ColorSpace();
  181. return frame_color_space.GetContentColorUsage();
  182. }
  183. void VideoLayerImpl::SetNeedsRedraw() {
  184. UnionUpdateRect(gfx::Rect(bounds()));
  185. layer_tree_impl()->SetNeedsRedraw();
  186. }
  187. const char* VideoLayerImpl::LayerTypeAsString() const {
  188. return "cc::VideoLayerImpl";
  189. }
  190. } // namespace cc