surface_layer_impl.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. // Copyright 2014 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/surface_layer_impl.h"
  5. #include <stdint.h>
  6. #include <algorithm>
  7. #include <utility>
  8. #include "base/memory/ptr_util.h"
  9. #include "base/synchronization/waitable_event.h"
  10. #include "base/trace_event/traced_value.h"
  11. #include "cc/debug/debug_colors.h"
  12. #include "cc/layers/append_quads_data.h"
  13. #include "cc/trees/layer_tree_impl.h"
  14. #include "cc/trees/occlusion.h"
  15. #include "components/viz/common/quads/solid_color_draw_quad.h"
  16. #include "components/viz/common/quads/surface_draw_quad.h"
  17. namespace cc {
  18. // static
  19. std::unique_ptr<SurfaceLayerImpl> SurfaceLayerImpl::Create(
  20. LayerTreeImpl* tree_impl,
  21. int id,
  22. UpdateSubmissionStateCB update_submission_state_callback) {
  23. return base::WrapUnique(new SurfaceLayerImpl(
  24. tree_impl, id, std::move(update_submission_state_callback)));
  25. }
  26. // static
  27. std::unique_ptr<SurfaceLayerImpl> SurfaceLayerImpl::Create(
  28. LayerTreeImpl* tree_impl,
  29. int id) {
  30. return base::WrapUnique(new SurfaceLayerImpl(
  31. tree_impl, id, base::BindRepeating([](bool, base::WaitableEvent* event) {
  32. if (event)
  33. event->Signal();
  34. })));
  35. }
  36. SurfaceLayerImpl::SurfaceLayerImpl(
  37. LayerTreeImpl* tree_impl,
  38. int id,
  39. UpdateSubmissionStateCB update_submission_state_callback)
  40. : LayerImpl(tree_impl, id),
  41. update_submission_state_callback_(
  42. std::move(update_submission_state_callback)) {}
  43. SurfaceLayerImpl::~SurfaceLayerImpl() {
  44. if (update_submission_state_callback_)
  45. update_submission_state_callback_.Run(false, nullptr);
  46. }
  47. std::unique_ptr<LayerImpl> SurfaceLayerImpl::CreateLayerImpl(
  48. LayerTreeImpl* tree_impl) const {
  49. return SurfaceLayerImpl::Create(tree_impl, id(),
  50. std::move(update_submission_state_callback_));
  51. }
  52. void SurfaceLayerImpl::SetRange(const viz::SurfaceRange& surface_range,
  53. absl::optional<uint32_t> deadline_in_frames) {
  54. if (surface_range_ == surface_range &&
  55. deadline_in_frames_ == deadline_in_frames) {
  56. return;
  57. }
  58. if (surface_range_.end() != surface_range.end() &&
  59. surface_range.end().local_surface_id().is_valid()) {
  60. TRACE_EVENT_WITH_FLOW2(
  61. TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
  62. "LocalSurfaceId.Embed.Flow",
  63. TRACE_ID_GLOBAL(
  64. surface_range.end().local_surface_id().embed_trace_id()),
  65. TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
  66. "ImplSetSurfaceId", "surface_id", surface_range.end().ToString());
  67. }
  68. surface_range_ = surface_range;
  69. deadline_in_frames_ = deadline_in_frames;
  70. NoteLayerPropertyChanged();
  71. }
  72. void SurfaceLayerImpl::SetStretchContentToFillBounds(bool stretch_content) {
  73. if (stretch_content_to_fill_bounds_ == stretch_content)
  74. return;
  75. stretch_content_to_fill_bounds_ = stretch_content;
  76. NoteLayerPropertyChanged();
  77. }
  78. void SurfaceLayerImpl::SetSurfaceHitTestable(bool surface_hit_testable) {
  79. if (surface_hit_testable_ == surface_hit_testable)
  80. return;
  81. surface_hit_testable_ = surface_hit_testable;
  82. NoteLayerPropertyChanged();
  83. }
  84. void SurfaceLayerImpl::SetHasPointerEventsNone(bool has_pointer_events_none) {
  85. if (has_pointer_events_none_ == has_pointer_events_none)
  86. return;
  87. has_pointer_events_none_ = has_pointer_events_none;
  88. NoteLayerPropertyChanged();
  89. }
  90. void SurfaceLayerImpl::SetIsReflection(bool is_reflection) {
  91. if (is_reflection_ == is_reflection)
  92. return;
  93. is_reflection_ = is_reflection;
  94. NoteLayerPropertyChanged();
  95. }
  96. void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
  97. LayerImpl::PushPropertiesTo(layer);
  98. SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
  99. layer_impl->SetRange(surface_range_, std::move(deadline_in_frames_));
  100. // Unless the client explicitly specifies otherwise, don't block on
  101. // |surface_range_| more than once.
  102. deadline_in_frames_ = 0u;
  103. layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
  104. layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
  105. layer_impl->SetHasPointerEventsNone(has_pointer_events_none_);
  106. layer_impl->SetIsReflection(is_reflection_);
  107. }
  108. bool SurfaceLayerImpl::WillDraw(
  109. DrawMode draw_mode,
  110. viz::ClientResourceProvider* resource_provider) {
  111. bool will_draw = LayerImpl::WillDraw(draw_mode, resource_provider);
  112. // If we have a change in WillDraw (meaning that visibility has changed), we
  113. // want to inform the VideoFrameSubmitter to start or stop submitting
  114. // compositor frames.
  115. if (will_draw_ != will_draw) {
  116. will_draw_ = will_draw;
  117. if (update_submission_state_callback_) {
  118. // If we're in synchronous composite mode, ensure that we finish running
  119. // the update submission state callback. This is important to avoid race
  120. // conditions in web_tests which results from a thread hop that happens in
  121. // the callback.
  122. if (layer_tree_impl()->IsInSynchronousComposite()) {
  123. base::WaitableEvent event;
  124. update_submission_state_callback_.Run(will_draw, &event);
  125. event.Wait();
  126. } else {
  127. update_submission_state_callback_.Run(will_draw, nullptr);
  128. }
  129. }
  130. }
  131. return will_draw;
  132. }
  133. void SurfaceLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
  134. AppendQuadsData* append_quads_data) {
  135. AppendRainbowDebugBorder(render_pass);
  136. float device_scale_factor = layer_tree_impl()->device_scale_factor();
  137. gfx::Rect quad_rect(gfx::ScaleToEnclosingRect(
  138. gfx::Rect(bounds()), device_scale_factor, device_scale_factor));
  139. gfx::Rect visible_quad_rect =
  140. draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
  141. gfx::Rect(bounds()));
  142. visible_quad_rect = gfx::ScaleToEnclosingRect(
  143. visible_quad_rect, device_scale_factor, device_scale_factor);
  144. visible_quad_rect = gfx::IntersectRects(quad_rect, visible_quad_rect);
  145. if (visible_quad_rect.IsEmpty())
  146. return;
  147. viz::SharedQuadState* shared_quad_state =
  148. render_pass->CreateAndAppendSharedQuadState();
  149. PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor,
  150. contents_opaque());
  151. if (surface_range_.IsValid()) {
  152. auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
  153. quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
  154. surface_range_, background_color(),
  155. stretch_content_to_fill_bounds_);
  156. quad->is_reflection = is_reflection_;
  157. // Add the primary surface ID as a dependency.
  158. append_quads_data->activation_dependencies.push_back(surface_range_.end());
  159. if (deadline_in_frames_) {
  160. if (!append_quads_data->deadline_in_frames)
  161. append_quads_data->deadline_in_frames = 0u;
  162. append_quads_data->deadline_in_frames = std::max(
  163. *append_quads_data->deadline_in_frames, *deadline_in_frames_);
  164. } else {
  165. append_quads_data->use_default_lower_bound_deadline = true;
  166. }
  167. } else {
  168. auto* quad =
  169. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  170. quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
  171. background_color(), false /* force_anti_aliasing_off */);
  172. }
  173. // Unless the client explicitly specifies otherwise, don't block on
  174. // |surface_range_| more than once.
  175. deadline_in_frames_ = 0u;
  176. }
  177. bool SurfaceLayerImpl::is_surface_layer() const {
  178. return true;
  179. }
  180. gfx::Rect SurfaceLayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
  181. return GetScaledEnclosingVisibleRectInTargetSpace(
  182. layer_tree_impl()->device_scale_factor());
  183. }
  184. void SurfaceLayerImpl::GetDebugBorderProperties(SkColor4f* color,
  185. float* width) const {
  186. if (color)
  187. *color = DebugColors::SurfaceLayerBorderColor();
  188. if (width)
  189. *width = DebugColors::SurfaceLayerBorderWidth(
  190. layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1);
  191. }
  192. void SurfaceLayerImpl::AppendRainbowDebugBorder(
  193. viz::CompositorRenderPass* render_pass) {
  194. if (!ShowDebugBorders(DebugBorderType::SURFACE))
  195. return;
  196. viz::SharedQuadState* shared_quad_state =
  197. render_pass->CreateAndAppendSharedQuadState();
  198. PopulateSharedQuadState(shared_quad_state, contents_opaque());
  199. float border_width = DebugColors::SurfaceLayerBorderWidth(
  200. layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1);
  201. SkColor4f colors[] = {
  202. {1.0f, 0.0f, 0.0f, 0.5f}, // Red.
  203. {1.0f, 0.65f, 0.0f, 0.5f}, // Orange.
  204. {1.0f, 1.0f, 0.0f, 0.5f}, // Yellow.
  205. {0.0f, 0.5f, 0.0f, 0.5f}, // Green.
  206. {0.0f, 0.0f, 1.0f, 0.50f}, // Blue.
  207. {0.93f, 0.51f, 0.93f, 0.5f}, // Violet.
  208. };
  209. const int kNumColors = std::size(colors);
  210. const int kStripeWidth = 300;
  211. const int kStripeHeight = 300;
  212. for (int i = 0;; ++i) {
  213. // For horizontal lines.
  214. int x = kStripeWidth * i;
  215. int width = std::min(kStripeWidth, bounds().width() - x - 1);
  216. // For vertical lines.
  217. int y = kStripeHeight * i;
  218. int height = std::min(kStripeHeight, bounds().height() - y - 1);
  219. gfx::Rect top(x, 0, width, border_width);
  220. gfx::Rect bottom(x, bounds().height() - border_width, width, border_width);
  221. gfx::Rect left(0, y, border_width, height);
  222. gfx::Rect right(bounds().width() - border_width, y, border_width, height);
  223. if (top.IsEmpty() && left.IsEmpty())
  224. break;
  225. if (!top.IsEmpty()) {
  226. bool force_anti_aliasing_off = false;
  227. auto* top_quad =
  228. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  229. top_quad->SetNew(shared_quad_state, top, top, colors[i % kNumColors],
  230. force_anti_aliasing_off);
  231. auto* bottom_quad =
  232. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  233. bottom_quad->SetNew(shared_quad_state, bottom, bottom,
  234. colors[kNumColors - 1 - (i % kNumColors)],
  235. force_anti_aliasing_off);
  236. if (contents_opaque()) {
  237. // Draws a stripe filling the layer vertically with the same color and
  238. // width as the horizontal stipes along the layer's top border.
  239. auto* solid_quad =
  240. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  241. // The inner fill is more transparent then the border.
  242. static const float kFillOpacity = 0.1f;
  243. SkColor4f fill_color = colors[i % kNumColors];
  244. fill_color.fA *= kFillOpacity;
  245. gfx::Rect fill_rect(x, 0, width, bounds().height());
  246. solid_quad->SetNew(shared_quad_state, fill_rect, fill_rect, fill_color,
  247. force_anti_aliasing_off);
  248. }
  249. }
  250. if (!left.IsEmpty()) {
  251. bool force_anti_aliasing_off = false;
  252. auto* left_quad =
  253. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  254. left_quad->SetNew(shared_quad_state, left, left,
  255. colors[kNumColors - 1 - (i % kNumColors)],
  256. force_anti_aliasing_off);
  257. auto* right_quad =
  258. render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
  259. right_quad->SetNew(shared_quad_state, right, right,
  260. colors[i % kNumColors], force_anti_aliasing_off);
  261. }
  262. }
  263. }
  264. void SurfaceLayerImpl::AsValueInto(base::trace_event::TracedValue* dict) const {
  265. LayerImpl::AsValueInto(dict);
  266. dict->SetString("surface_range", surface_range_.ToString());
  267. }
  268. const char* SurfaceLayerImpl::LayerTypeAsString() const {
  269. return "cc::SurfaceLayerImpl";
  270. }
  271. } // namespace cc