Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: cc/output/dc_layer_overlay.cc

Issue 2736643004: Add DCLayerOverlayProcessor and supporting DCLayer structures. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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/dc_layer_overlay.h"
6
7 #include "cc/base/math_util.h"
8 #include "cc/quads/solid_color_draw_quad.h"
9 #include "cc/quads/yuv_video_draw_quad.h"
10 #include "cc/resources/resource_provider.h"
11 #include "gpu/GLES2/gl2extchromium.h"
12 #include "ui/gfx/geometry/rect_conversions.h"
13
14 namespace cc {
15
16 namespace {
17
18 DCLayerOverlayProcessor::DCLayerResult FromYUVQuad(
19 ResourceProvider* resource_provider,
20 const YUVVideoDrawQuad* quad,
21 CALayerOverlay* ca_layer_overlay) {
22 unsigned resource_id = quad->y_plane_resource_id();
23 if (!resource_provider->IsOverlayCandidate(resource_id))
24 return DCLayerOverlayProcessor::DC_LAYER_FAILED_TEXTURE_NOT_CANDIDATE;
25 ca_layer_overlay->contents_resource_id = resource_id;
26 ca_layer_overlay->contents_rect = quad->ya_tex_coord_rect;
27 ca_layer_overlay->filter = GL_LINEAR;
28 return DCLayerOverlayProcessor::DC_LAYER_SUCCESS;
29 }
30
31 // Find a rectangle containing all the quads in a list that occlude the area
32 // in target_quad.
33 gfx::RectF GetOcclusionBounds(const gfx::RectF& target_quad,
34 QuadList::ConstIterator quad_list_begin,
35 QuadList::ConstIterator quad_list_end) {
36 gfx::RectF occlusion_bounding_box;
37 for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end;
38 ++overlap_iter) {
39 gfx::RectF overlap_rect = MathUtil::MapClippedRect(
40 overlap_iter->shared_quad_state->quad_to_target_transform,
41 gfx::RectF(overlap_iter->rect));
42 float opacity = overlap_iter->shared_quad_state->opacity;
43 if (opacity < std::numeric_limits<float>::epsilon())
44 continue;
45 const DrawQuad* quad = *overlap_iter;
46 if (quad->material == DrawQuad::SOLID_COLOR) {
47 SkColor color = SolidColorDrawQuad::MaterialCast(quad)->color;
48 float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
49 if (quad->ShouldDrawWithBlending() &&
50 alpha < std::numeric_limits<float>::epsilon())
51 continue;
52 }
53 overlap_rect.Intersect(target_quad);
54 if (!overlap_rect.IsEmpty()) {
55 occlusion_bounding_box.Union(overlap_rect);
56 }
57 }
58 return occlusion_bounding_box;
59 }
60
61 } // namespace
62
63 DCLayerOverlayProcessor::DCLayerResult DCLayerOverlayProcessor::FromDrawQuad(
64 ResourceProvider* resource_provider,
65 const gfx::RectF& display_rect,
66 QuadList::ConstIterator quad_list_begin,
67 QuadList::ConstIterator quad,
68 CALayerOverlay* ca_layer_overlay) {
69 if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
70 return DC_LAYER_FAILED_QUAD_BLEND_MODE;
71
72 DCLayerResult result = DC_LAYER_FAILED_UNKNOWN;
73 switch (quad->material) {
74 case DrawQuad::YUV_VIDEO_CONTENT:
75 result =
76 FromYUVQuad(resource_provider, YUVVideoDrawQuad::MaterialCast(*quad),
77 ca_layer_overlay);
78 break;
79 default:
80 return DC_LAYER_FAILED_UNKNOWN;
81 }
82 if (result != DC_LAYER_SUCCESS)
83 return result;
84
85 scoped_refptr<CALayerOverlaySharedState> overlay_shared_state(
86 new CALayerOverlaySharedState);
87 // For the purposes of this method, the sorting context id is the
88 // z-order.
89 overlay_shared_state->sorting_context_id = 1;
90
91 overlay_shared_state->is_clipped = quad->shared_quad_state->is_clipped;
92 overlay_shared_state->clip_rect =
93 gfx::RectF(quad->shared_quad_state->clip_rect);
94
95 overlay_shared_state->opacity = quad->shared_quad_state->opacity;
96 overlay_shared_state->transform =
97 quad->shared_quad_state->quad_to_target_transform.matrix();
98
99 ca_layer_overlay->shared_state = overlay_shared_state;
100 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect);
101
102 return result;
103 }
104
105 void DCLayerOverlayProcessor::Process(ResourceProvider* resource_provider,
106 const gfx::RectF& display_rect,
107 QuadList* quad_list,
108 gfx::Rect* overlay_damage_rect,
109 gfx::Rect* damage_rect,
110 CALayerOverlayList* ca_layer_overlays) {
111 gfx::Rect this_frame_underlay_rect;
112 for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
113 CALayerOverlay ca_layer;
114 DCLayerResult result = FromDrawQuad(resource_provider, display_rect,
115 quad_list->begin(), it, &ca_layer);
116 if (result != DC_LAYER_SUCCESS)
117 continue;
118 gfx::Rect quad_rectangle = MathUtil::MapEnclosingClippedRect(
119 it->shared_quad_state->quad_to_target_transform, it->rect);
120 gfx::RectF occlusion_bounding_box =
121 GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
122
123 if (occlusion_bounding_box.IsEmpty()) {
124 // The quad is on top, so promote it to an overlay and remove all damage
125 // underneath it.
126 if (it->shared_quad_state->quad_to_target_transform
127 .Preserves2dAxisAlignment()) {
128 damage_rect->Subtract(quad_rectangle);
129 overlay_damage_rect->Union(quad_rectangle);
130 }
131 quad_list->EraseAndInvalidateAllPointers(it);
132 } else {
133 // The quad is occluded, so replace it with a black solid color quad and
134 // place the overlay itself under the quad.
135 if (it->shared_quad_state->quad_to_target_transform
136 .IsIdentityOrIntegerTranslation()) {
137 this_frame_underlay_rect = quad_rectangle;
138 }
139 ca_layer.shared_state->sorting_context_id = static_cast<unsigned int>(-1);
140 const SharedQuadState* shared_quad_state = it->shared_quad_state;
141 gfx::Rect rect = it->visible_rect;
142 SolidColorDrawQuad* replacement =
143 quad_list->ReplaceExistingElement<SolidColorDrawQuad>(it);
144 replacement->SetAll(shared_quad_state, rect, rect, rect, false,
145 SK_ColorTRANSPARENT, true);
146
147 if (this_frame_underlay_rect == previous_frame_underlay_rect_) {
148 // If this underlay rect is the same as for last frame, subtract its
149 // area from the damage of the main surface, as the cleared area was
150 // already cleared last frame. Add back the damage from the occluded
151 // area for this and last frame, as that may have changed.
152 if (it->shared_quad_state->quad_to_target_transform
153 .Preserves2dAxisAlignment()) {
154 gfx::Rect occluding_damage_rect = *damage_rect;
155 occluding_damage_rect.Intersect(quad_rectangle);
156 damage_rect->Subtract(quad_rectangle);
157 gfx::Rect new_occlusion_bounding_box =
158 gfx::ToEnclosingRect(occlusion_bounding_box);
159 new_occlusion_bounding_box.Union(previous_occlusion_bounding_box_);
160 occluding_damage_rect.Intersect(new_occlusion_bounding_box);
161
162 damage_rect->Union(occluding_damage_rect);
163 overlay_damage_rect->Union(quad_rectangle);
164 }
165 } else {
166 // Entire replacement quad must be redrawn.
167 damage_rect->Union(quad_rectangle);
168 }
169 previous_occlusion_bounding_box_ =
170 gfx::ToEnclosingRect(occlusion_bounding_box);
171 }
172
173 ca_layer_overlays->push_back(ca_layer);
174 // Only allow one overlay for now.
175 break;
176 }
177 previous_frame_underlay_rect_ = this_frame_underlay_rect;
178 }
179
180 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698