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
5#include "cc/output/overlay_strategy_single_on_top.h"
6
7#include "cc/output/output_surface.h"
8#include "cc/quads/draw_quad.h"
9#include "cc/quads/texture_draw_quad.h"
10#include "ui/gfx/rect_conversions.h"
11#include "ui/gfx/transform.h"
12
13namespace cc {
14
15OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
16    OverlayCandidateValidator* capability_checker,
17    ResourceProvider* resource_provider)
18    : capability_checker_(capability_checker),
19      resource_provider_(resource_provider) {}
20
21bool OverlayStrategySingleOnTop::Attempt(
22    RenderPassList* render_passes_in_draw_order,
23    OverlayCandidateList* candidate_list) {
24  // Only attempt to handle very simple case for now.
25  if (!capability_checker_)
26    return false;
27
28  RenderPass* root_render_pass = render_passes_in_draw_order->back();
29  DCHECK(root_render_pass);
30
31  QuadList& quad_list = root_render_pass->quad_list;
32  const DrawQuad* candidate_quad = quad_list.front();
33  if (candidate_quad->material != DrawQuad::TEXTURE_CONTENT)
34    return false;
35
36  const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(candidate_quad);
37  if (!resource_provider_->AllowOverlay(quad.resource_id))
38    return false;
39
40  // Simple quads only.
41  gfx::OverlayTransform overlay_transform =
42      OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped);
43  if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID ||
44      !quad.quadTransform().IsIdentityOrTranslation() || quad.needs_blending ||
45      quad.shared_quad_state->opacity != 1.f ||
46      quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode ||
47      quad.premultiplied_alpha || quad.background_color != SK_ColorTRANSPARENT)
48    return false;
49
50  // Add our primary surface.
51  OverlayCandidateList candidates;
52  OverlayCandidate main_image;
53  main_image.display_rect = root_render_pass->output_rect;
54  main_image.format = RGBA_8888;
55  candidates.push_back(main_image);
56
57  // Add the overlay.
58  OverlayCandidate candidate;
59  candidate.transform = overlay_transform;
60  candidate.display_rect =
61      OverlayCandidate::GetOverlayRect(quad.quadTransform(), quad.rect);
62  candidate.uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
63  candidate.format = RGBA_8888;
64  candidate.resource_id = quad.resource_id;
65  candidate.plane_z_order = 1;
66  candidates.push_back(candidate);
67
68  // Check for support.
69  capability_checker_->CheckOverlaySupport(&candidates);
70
71  // If the candidate can be handled by an overlay, create a pass for it.
72  if (candidates[1].overlay_handled) {
73    scoped_ptr<DrawQuad> overlay_quad = quad_list.take(quad_list.begin());
74    quad_list.erase(quad_list.begin());
75    candidate_list->swap(candidates);
76    return true;
77  }
78  return false;
79}
80
81}  // namespace cc
82