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

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

Issue 2736643004: Add DCLayerOverlayProcessor and supporting DCLayer structures. (Closed)
Patch Set: split CALayerOverlay into DCLayerOverlay 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
« no previous file with comments | « cc/output/dc_layer_overlay.h ('k') | cc/output/direct_renderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 DCLayerOverlay* 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 DCLayerOverlay::DCLayerOverlay() : filter(GL_LINEAR) {}
64
65 DCLayerOverlay::DCLayerOverlay(const DCLayerOverlay& other) = default;
66
67 DCLayerOverlay::~DCLayerOverlay() {}
68
69 DCLayerOverlayProcessor::DCLayerResult DCLayerOverlayProcessor::FromDrawQuad(
70 ResourceProvider* resource_provider,
71 const gfx::RectF& display_rect,
72 QuadList::ConstIterator quad_list_begin,
73 QuadList::ConstIterator quad,
74 DCLayerOverlay* ca_layer_overlay) {
75 if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
76 return DC_LAYER_FAILED_QUAD_BLEND_MODE;
77
78 DCLayerResult result = DC_LAYER_FAILED_UNKNOWN;
79 switch (quad->material) {
80 case DrawQuad::YUV_VIDEO_CONTENT:
81 result =
82 FromYUVQuad(resource_provider, YUVVideoDrawQuad::MaterialCast(*quad),
83 ca_layer_overlay);
84 break;
85 default:
86 return DC_LAYER_FAILED_UNKNOWN;
87 }
88 if (result != DC_LAYER_SUCCESS)
89 return result;
90
91 scoped_refptr<DCLayerOverlaySharedState> overlay_shared_state(
92 new DCLayerOverlaySharedState);
93 overlay_shared_state->z_order = 1;
94
95 overlay_shared_state->is_clipped = quad->shared_quad_state->is_clipped;
96 overlay_shared_state->clip_rect =
97 gfx::RectF(quad->shared_quad_state->clip_rect);
98
99 overlay_shared_state->opacity = quad->shared_quad_state->opacity;
100 overlay_shared_state->transform =
101 quad->shared_quad_state->quad_to_target_transform.matrix();
102
103 ca_layer_overlay->shared_state = overlay_shared_state;
104 ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect);
105
106 return result;
107 }
108
109 void DCLayerOverlayProcessor::Process(ResourceProvider* resource_provider,
110 const gfx::RectF& display_rect,
111 QuadList* quad_list,
112 gfx::Rect* overlay_damage_rect,
113 gfx::Rect* damage_rect,
114 DCLayerOverlayList* ca_layer_overlays) {
115 gfx::Rect this_frame_underlay_rect;
116 for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
117 DCLayerOverlay ca_layer;
118 DCLayerResult result = FromDrawQuad(resource_provider, display_rect,
119 quad_list->begin(), it, &ca_layer);
120 if (result != DC_LAYER_SUCCESS)
121 continue;
122 gfx::Rect quad_rectangle = MathUtil::MapEnclosingClippedRect(
123 it->shared_quad_state->quad_to_target_transform, it->rect);
124 gfx::RectF occlusion_bounding_box =
125 GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
126
127 if (occlusion_bounding_box.IsEmpty()) {
128 // The quad is on top, so promote it to an overlay and remove all damage
129 // underneath it.
130 if (it->shared_quad_state->quad_to_target_transform
131 .Preserves2dAxisAlignment()) {
132 damage_rect->Subtract(quad_rectangle);
133 overlay_damage_rect->Union(quad_rectangle);
134 }
135 quad_list->EraseAndInvalidateAllPointers(it);
136 } else {
137 // The quad is occluded, so replace it with a black solid color quad and
138 // place the overlay itself under the quad.
139 if (it->shared_quad_state->quad_to_target_transform
140 .IsIdentityOrIntegerTranslation()) {
141 this_frame_underlay_rect = quad_rectangle;
142 }
143 ca_layer.shared_state->z_order = -1;
144 const SharedQuadState* shared_quad_state = it->shared_quad_state;
145 gfx::Rect rect = it->visible_rect;
146 SolidColorDrawQuad* replacement =
147 quad_list->ReplaceExistingElement<SolidColorDrawQuad>(it);
148 replacement->SetAll(shared_quad_state, rect, rect, rect, false,
149 SK_ColorTRANSPARENT, true);
150
151 if (this_frame_underlay_rect == previous_frame_underlay_rect_) {
152 // If this underlay rect is the same as for last frame, subtract its
153 // area from the damage of the main surface, as the cleared area was
154 // already cleared last frame. Add back the damage from the occluded
155 // area for this and last frame, as that may have changed.
156 if (it->shared_quad_state->quad_to_target_transform
157 .Preserves2dAxisAlignment()) {
158 gfx::Rect occluding_damage_rect = *damage_rect;
159 occluding_damage_rect.Intersect(quad_rectangle);
160 damage_rect->Subtract(quad_rectangle);
161 gfx::Rect new_occlusion_bounding_box =
162 gfx::ToEnclosingRect(occlusion_bounding_box);
163 new_occlusion_bounding_box.Union(previous_occlusion_bounding_box_);
164 occluding_damage_rect.Intersect(new_occlusion_bounding_box);
165
166 damage_rect->Union(occluding_damage_rect);
167 overlay_damage_rect->Union(quad_rectangle);
168 }
169 } else {
170 // Entire replacement quad must be redrawn.
171 damage_rect->Union(quad_rectangle);
172 }
173 previous_occlusion_bounding_box_ =
174 gfx::ToEnclosingRect(occlusion_bounding_box);
175 }
176
177 ca_layer_overlays->push_back(ca_layer);
178 // Only allow one overlay for now.
179 break;
180 }
181 previous_frame_underlay_rect_ = this_frame_underlay_rect;
182 }
183
184 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/dc_layer_overlay.h ('k') | cc/output/direct_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698