OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 | |
5 #include "cc/output/overlay_strategy_sandwich.h" | |
6 | |
7 #include "cc/base/region.h" | |
8 #include "cc/output/overlay_candidate_validator.h" | |
9 #include "cc/quads/draw_quad.h" | |
10 #include "cc/quads/solid_color_draw_quad.h" | |
11 #include "ui/gfx/geometry/dip_util.h" | |
12 #include "ui/gfx/geometry/rect_conversions.h" | |
13 | |
14 namespace { | |
15 | |
16 gfx::Rect AlignPixelRectToDIP(float scale_factor, const gfx::Rect& pixel_rect) { | |
17 gfx::Rect dip_rect = | |
18 gfx::ToEnclosingRect(gfx::ScaleRect(pixel_rect, 1.0f / scale_factor)); | |
19 gfx::Rect new_pixel_rect = | |
20 gfx::ToEnclosingRect(gfx::ScaleRect(dip_rect, scale_factor)); | |
21 return new_pixel_rect; | |
22 } | |
23 | |
24 bool IsPixelRectAlignedToDIP(float scale_factor, const gfx::Rect& pixel_rect) { | |
25 return (pixel_rect == AlignPixelRectToDIP(scale_factor, pixel_rect)); | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 namespace cc { | |
31 | |
32 OverlayStrategySandwich::~OverlayStrategySandwich() {} | |
33 | |
34 bool OverlayStrategySandwich::TryOverlay( | |
35 OverlayCandidateValidator* capability_checker, | |
36 RenderPassList* render_passes_in_draw_order, | |
37 OverlayCandidateList* output_candidate_list, | |
38 const OverlayCandidate& candidate, | |
39 QuadList::Iterator candidate_iter_in_quad_list, | |
40 float device_scale_factor) { | |
41 RenderPass* root_render_pass = render_passes_in_draw_order->back(); | |
42 QuadList& quad_list = root_render_pass->quad_list; | |
43 gfx::Rect pixel_bounds = root_render_pass->output_rect; | |
44 | |
45 const DrawQuad* candidate_quad = *candidate_iter_in_quad_list; | |
46 const gfx::Transform& candidate_transform = | |
47 candidate_quad->shared_quad_state->quad_to_target_transform; | |
48 gfx::Transform candidate_inverse_transform; | |
49 if (!candidate_transform.GetInverse(&candidate_inverse_transform)) | |
50 return false; | |
51 | |
52 // Compute the candidate's rect in display space (pixels on the screen). The | |
53 // rect needs to be DIP-aligned, or we cannot use it. | |
54 gfx::Rect candidate_pixel_rect; | |
55 { | |
alexst (slow to review)
2015/08/25 18:49:38
Why the extra scope, there is nothing in there tha
ccameron
2015/08/26 21:36:13
Just a style choice -- removed.
| |
56 gfx::RectF candidate_pixel_rect_float = candidate_quad->rect; | |
57 candidate_transform.TransformRect(&candidate_pixel_rect_float); | |
58 candidate_pixel_rect = gfx::ToEnclosingRect(candidate_pixel_rect_float); | |
59 if (candidate_pixel_rect != candidate_pixel_rect_float) | |
alexst (slow to review)
2015/08/25 18:49:38
Is rect and recf directly comparable like that?
danakj
2015/08/25 18:50:42
The ints will become floats. That's lossy tho fwiw
ccameron
2015/08/26 21:36:13
True -- the thing I'm checking here is that candid
alexst (slow to review)
2015/08/26 21:54:18
Maybe promote your comment here to the code. When
ccameron
2015/08/26 22:52:57
Oh -- non-integers may be perfectly valid (for all
danakj
2015/08/27 18:20:03
Want to add a RectF::IsRepresentableAsRect?
| |
60 return false; | |
61 if (!IsPixelRectAlignedToDIP(device_scale_factor, candidate_pixel_rect)) | |
62 return false; | |
63 } | |
64 | |
65 // Iterate through the quads in front of |potential_candidate|, and compute | |
66 // the region of |potential_candidate| that is covered. | |
67 Region pixel_covered_region; | |
68 for (auto overlap_iter = quad_list.cbegin(); | |
69 overlap_iter != candidate_iter_in_quad_list; ++overlap_iter) { | |
70 if (OverlayStrategyCommon::IsInvisibleQuad(*overlap_iter)) | |
71 continue; | |
72 // Compute the quad's bounds in display space, and ensure that it is rounded | |
73 // up to be DIP-aligned. | |
74 gfx::RectF pixel_covered_rect_float = overlap_iter->rect; | |
75 overlap_iter->shared_quad_state->quad_to_target_transform.TransformRect( | |
76 &pixel_covered_rect_float); | |
77 gfx::Rect pixel_covered_rect = AlignPixelRectToDIP( | |
78 device_scale_factor, gfx::ToEnclosingRect(pixel_covered_rect_float)); | |
79 | |
80 // Include the intersection of that quad with the candidate's quad in the | |
81 // covered region. | |
82 pixel_covered_rect.Intersect(candidate_pixel_rect); | |
83 pixel_covered_region.Union(pixel_covered_rect); | |
84 } | |
85 | |
86 // Add our primary surface. | |
87 OverlayCandidateList new_candidate_list; | |
88 OverlayCandidate main_image; | |
89 main_image.display_rect = pixel_bounds; | |
90 new_candidate_list.push_back(main_image); | |
91 | |
92 // Add the candidate's overlay. | |
93 DCHECK(candidate.resource_id); | |
94 new_candidate_list.push_back(candidate); | |
95 new_candidate_list.back().plane_z_order = 1; | |
96 | |
97 // Add an overlay of the primary surface for any part of the candidate's | |
98 // quad that was covered. | |
99 // TODO(ccameron): Create an OverlayCandidate for each rect in the region. | |
100 gfx::Rect pixel_covered_rect = pixel_covered_region.bounds(); | |
101 DCHECK(IsPixelRectAlignedToDIP(device_scale_factor, pixel_covered_rect)); | |
102 if (!pixel_covered_rect.IsEmpty()) { | |
103 OverlayCandidate main_image_on_top; | |
104 main_image_on_top.display_rect = pixel_covered_rect; | |
105 main_image_on_top.uv_rect = pixel_covered_rect; | |
106 main_image_on_top.uv_rect.Scale(1.f / pixel_bounds.width(), | |
107 1.f / pixel_bounds.height()); | |
108 main_image_on_top.plane_z_order = 2; | |
109 main_image_on_top.transform = gfx::OVERLAY_TRANSFORM_NONE; | |
110 main_image_on_top.use_output_surface_for_resource = true; | |
111 new_candidate_list.push_back(main_image_on_top); | |
112 } | |
113 | |
114 // Check for support. | |
115 capability_checker->CheckOverlaySupport(&new_candidate_list); | |
116 for (const OverlayCandidate& candidate : new_candidate_list) { | |
117 if (candidate.plane_z_order > 0 && !candidate.overlay_handled) | |
118 return false; | |
119 } | |
120 | |
121 // Remove the quad for the overlay quad. Replace it with a transparent quad | |
122 // if we're putting a new overlay on top. | |
123 if (pixel_covered_rect.IsEmpty()) { | |
124 quad_list.EraseAndInvalidateAllPointers(candidate_iter_in_quad_list); | |
125 } else { | |
126 gfx::RectF quad_space_covered_rect_float = pixel_covered_rect; | |
127 candidate_inverse_transform.TransformRect(&quad_space_covered_rect_float); | |
128 gfx::Rect quad_space_covered_rect = | |
129 gfx::ToEnclosingRect(quad_space_covered_rect_float); | |
130 quad_space_covered_rect.Intersect(candidate_quad->rect); | |
131 | |
132 const SharedQuadState* shared_quad_state = | |
133 candidate_quad->shared_quad_state; | |
134 | |
135 SolidColorDrawQuad* replacement = | |
136 quad_list.ReplaceExistingElement<SolidColorDrawQuad>( | |
137 candidate_iter_in_quad_list); | |
138 replacement->SetAll(shared_quad_state, quad_space_covered_rect, | |
139 quad_space_covered_rect, quad_space_covered_rect, false, | |
140 SK_ColorTRANSPARENT, true); | |
141 } | |
142 | |
143 output_candidate_list->swap(new_candidate_list); | |
144 return true; | |
145 } | |
146 | |
147 } // namespace cc | |
OLD | NEW |