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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/dc_layer_overlay.cc
diff --git a/cc/output/dc_layer_overlay.cc b/cc/output/dc_layer_overlay.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3523c4519ac489361cf0f0a03a1df4dbd11b45c1
--- /dev/null
+++ b/cc/output/dc_layer_overlay.cc
@@ -0,0 +1,184 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/output/dc_layer_overlay.h"
+
+#include "cc/base/math_util.h"
+#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/quads/yuv_video_draw_quad.h"
+#include "cc/resources/resource_provider.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+
+namespace cc {
+
+namespace {
+
+DCLayerOverlayProcessor::DCLayerResult FromYUVQuad(
+ ResourceProvider* resource_provider,
+ const YUVVideoDrawQuad* quad,
+ DCLayerOverlay* ca_layer_overlay) {
+ unsigned resource_id = quad->y_plane_resource_id();
+ if (!resource_provider->IsOverlayCandidate(resource_id))
+ return DCLayerOverlayProcessor::DC_LAYER_FAILED_TEXTURE_NOT_CANDIDATE;
+ ca_layer_overlay->contents_resource_id = resource_id;
+ ca_layer_overlay->contents_rect = quad->ya_tex_coord_rect;
+ ca_layer_overlay->filter = GL_LINEAR;
+ return DCLayerOverlayProcessor::DC_LAYER_SUCCESS;
+}
+
+// Find a rectangle containing all the quads in a list that occlude the area
+// in target_quad.
+gfx::RectF GetOcclusionBounds(const gfx::RectF& target_quad,
+ QuadList::ConstIterator quad_list_begin,
+ QuadList::ConstIterator quad_list_end) {
+ gfx::RectF occlusion_bounding_box;
+ for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end;
+ ++overlap_iter) {
+ gfx::RectF overlap_rect = MathUtil::MapClippedRect(
+ overlap_iter->shared_quad_state->quad_to_target_transform,
+ gfx::RectF(overlap_iter->rect));
+ float opacity = overlap_iter->shared_quad_state->opacity;
+ if (opacity < std::numeric_limits<float>::epsilon())
+ continue;
+ const DrawQuad* quad = *overlap_iter;
+ if (quad->material == DrawQuad::SOLID_COLOR) {
+ SkColor color = SolidColorDrawQuad::MaterialCast(quad)->color;
+ float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
+ if (quad->ShouldDrawWithBlending() &&
+ alpha < std::numeric_limits<float>::epsilon())
+ continue;
+ }
+ overlap_rect.Intersect(target_quad);
+ if (!overlap_rect.IsEmpty()) {
+ occlusion_bounding_box.Union(overlap_rect);
+ }
+ }
+ return occlusion_bounding_box;
+}
+
+} // namespace
+
+DCLayerOverlay::DCLayerOverlay() : filter(GL_LINEAR) {}
+
+DCLayerOverlay::DCLayerOverlay(const DCLayerOverlay& other) = default;
+
+DCLayerOverlay::~DCLayerOverlay() {}
+
+DCLayerOverlayProcessor::DCLayerResult DCLayerOverlayProcessor::FromDrawQuad(
+ ResourceProvider* resource_provider,
+ const gfx::RectF& display_rect,
+ QuadList::ConstIterator quad_list_begin,
+ QuadList::ConstIterator quad,
+ DCLayerOverlay* ca_layer_overlay) {
+ if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
+ return DC_LAYER_FAILED_QUAD_BLEND_MODE;
+
+ DCLayerResult result = DC_LAYER_FAILED_UNKNOWN;
+ switch (quad->material) {
+ case DrawQuad::YUV_VIDEO_CONTENT:
+ result =
+ FromYUVQuad(resource_provider, YUVVideoDrawQuad::MaterialCast(*quad),
+ ca_layer_overlay);
+ break;
+ default:
+ return DC_LAYER_FAILED_UNKNOWN;
+ }
+ if (result != DC_LAYER_SUCCESS)
+ return result;
+
+ scoped_refptr<DCLayerOverlaySharedState> overlay_shared_state(
+ new DCLayerOverlaySharedState);
+ overlay_shared_state->z_order = 1;
+
+ overlay_shared_state->is_clipped = quad->shared_quad_state->is_clipped;
+ overlay_shared_state->clip_rect =
+ gfx::RectF(quad->shared_quad_state->clip_rect);
+
+ overlay_shared_state->opacity = quad->shared_quad_state->opacity;
+ overlay_shared_state->transform =
+ quad->shared_quad_state->quad_to_target_transform.matrix();
+
+ ca_layer_overlay->shared_state = overlay_shared_state;
+ ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect);
+
+ return result;
+}
+
+void DCLayerOverlayProcessor::Process(ResourceProvider* resource_provider,
+ const gfx::RectF& display_rect,
+ QuadList* quad_list,
+ gfx::Rect* overlay_damage_rect,
+ gfx::Rect* damage_rect,
+ DCLayerOverlayList* ca_layer_overlays) {
+ gfx::Rect this_frame_underlay_rect;
+ for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
+ DCLayerOverlay ca_layer;
+ DCLayerResult result = FromDrawQuad(resource_provider, display_rect,
+ quad_list->begin(), it, &ca_layer);
+ if (result != DC_LAYER_SUCCESS)
+ continue;
+ gfx::Rect quad_rectangle = MathUtil::MapEnclosingClippedRect(
+ it->shared_quad_state->quad_to_target_transform, it->rect);
+ gfx::RectF occlusion_bounding_box =
+ GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
+
+ if (occlusion_bounding_box.IsEmpty()) {
+ // The quad is on top, so promote it to an overlay and remove all damage
+ // underneath it.
+ if (it->shared_quad_state->quad_to_target_transform
+ .Preserves2dAxisAlignment()) {
+ damage_rect->Subtract(quad_rectangle);
+ overlay_damage_rect->Union(quad_rectangle);
+ }
+ quad_list->EraseAndInvalidateAllPointers(it);
+ } else {
+ // The quad is occluded, so replace it with a black solid color quad and
+ // place the overlay itself under the quad.
+ if (it->shared_quad_state->quad_to_target_transform
+ .IsIdentityOrIntegerTranslation()) {
+ this_frame_underlay_rect = quad_rectangle;
+ }
+ ca_layer.shared_state->z_order = -1;
+ const SharedQuadState* shared_quad_state = it->shared_quad_state;
+ gfx::Rect rect = it->visible_rect;
+ SolidColorDrawQuad* replacement =
+ quad_list->ReplaceExistingElement<SolidColorDrawQuad>(it);
+ replacement->SetAll(shared_quad_state, rect, rect, rect, false,
+ SK_ColorTRANSPARENT, true);
+
+ if (this_frame_underlay_rect == previous_frame_underlay_rect_) {
+ // If this underlay rect is the same as for last frame, subtract its
+ // area from the damage of the main surface, as the cleared area was
+ // already cleared last frame. Add back the damage from the occluded
+ // area for this and last frame, as that may have changed.
+ if (it->shared_quad_state->quad_to_target_transform
+ .Preserves2dAxisAlignment()) {
+ gfx::Rect occluding_damage_rect = *damage_rect;
+ occluding_damage_rect.Intersect(quad_rectangle);
+ damage_rect->Subtract(quad_rectangle);
+ gfx::Rect new_occlusion_bounding_box =
+ gfx::ToEnclosingRect(occlusion_bounding_box);
+ new_occlusion_bounding_box.Union(previous_occlusion_bounding_box_);
+ occluding_damage_rect.Intersect(new_occlusion_bounding_box);
+
+ damage_rect->Union(occluding_damage_rect);
+ overlay_damage_rect->Union(quad_rectangle);
+ }
+ } else {
+ // Entire replacement quad must be redrawn.
+ damage_rect->Union(quad_rectangle);
+ }
+ previous_occlusion_bounding_box_ =
+ gfx::ToEnclosingRect(occlusion_bounding_box);
+ }
+
+ ca_layer_overlays->push_back(ca_layer);
+ // Only allow one overlay for now.
+ break;
+ }
+ previous_frame_underlay_rect_ = this_frame_underlay_rect;
+}
+
+} // namespace cc
« 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