// Copyright 2015 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/overlay_strategy_sandwich.h"

#include "cc/base/math_util.h"
#include "cc/base/region.h"
#include "cc/output/overlay_candidate_validator.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"

namespace cc {

namespace {

void ClipDisplayAndUVRects(gfx::Rect* display_rect,
                           gfx::RectF* uv_rect,
                           const gfx::Rect& clip_rect) {
  gfx::Rect display_cropped_rect =
      gfx::IntersectRects(*display_rect, clip_rect);

  gfx::RectF uv_cropped_rect = gfx::RectF(display_cropped_rect);
  uv_cropped_rect -= gfx::Vector2dF(display_rect->x(), display_rect->y());
  uv_cropped_rect.Scale(uv_rect->width() / display_rect->width(),
                        uv_rect->height() / display_rect->height());
  uv_cropped_rect += gfx::Vector2dF(uv_rect->x(), uv_rect->y());

  *display_rect = display_cropped_rect;
  *uv_rect = uv_cropped_rect;
}

}  // namespace

OverlayStrategySandwich::OverlayStrategySandwich(
    OverlayCandidateValidator* capability_checker)
    : capability_checker_(capability_checker) {
  DCHECK(capability_checker);
}

OverlayStrategySandwich::~OverlayStrategySandwich() {}

bool OverlayStrategySandwich::Attempt(ResourceProvider* resource_provider,
                                      RenderPassList* render_passes,
                                      OverlayCandidateList* candidate_list) {
  QuadList& quad_list = render_passes->back()->quad_list;
  for (auto it = quad_list.begin(); it != quad_list.end();) {
    OverlayCandidate candidate;
    if (OverlayCandidate::FromDrawQuad(resource_provider, *it, &candidate)) {
      it = TryOverlay(render_passes->back().get(), candidate_list, candidate,
                      it);
    } else {
      ++it;
    }
  }

  return candidate_list->size() > 1;
}

QuadList::Iterator OverlayStrategySandwich::TryOverlay(
    RenderPass* render_pass,
    OverlayCandidateList* candidate_list,
    const OverlayCandidate& candidate,
    QuadList::Iterator candidate_iter_in_quad_list) {
  QuadList& quad_list = render_pass->quad_list;
  gfx::Rect pixel_bounds = render_pass->output_rect;

  const DrawQuad* candidate_quad = *candidate_iter_in_quad_list;
  const gfx::Transform& candidate_transform =
      candidate_quad->shared_quad_state->quad_to_target_transform;
  gfx::Transform candidate_inverse_transform;
  if (!candidate_transform.GetInverse(&candidate_inverse_transform))
    return ++candidate_iter_in_quad_list;

  // Compute the candidate's rect in display space (pixels on the screen).
  gfx::Rect candidate_pixel_rect = candidate.quad_rect_in_target_space;
  gfx::RectF candidate_uv_rect = candidate.uv_rect;
  if (candidate.is_clipped &&
      !candidate.clip_rect.Contains(candidate_pixel_rect)) {
    ClipDisplayAndUVRects(&candidate_pixel_rect, &candidate_uv_rect,
                          candidate.clip_rect);
  }

  // Don't allow overlapping overlays for now.
  for (const OverlayCandidate& other_candidate : *candidate_list) {
    if (other_candidate.display_rect.Intersects(candidate.display_rect) &&
        other_candidate.plane_z_order == 1) {
      return ++candidate_iter_in_quad_list;
    }
  }

  // Iterate through the quads in front of |candidate|, and compute the region
  // of |candidate| that is covered.
  Region pixel_covered_region;
  for (auto overlap_iter = quad_list.cbegin();
       overlap_iter != candidate_iter_in_quad_list; ++overlap_iter) {
    if (OverlayCandidate::IsInvisibleQuad(*overlap_iter))
      continue;
    // Compute the quad's bounds in display space.
    gfx::Rect pixel_covered_rect = MathUtil::MapEnclosingClippedRect(
        overlap_iter->shared_quad_state->quad_to_target_transform,
        overlap_iter->rect);

    // Include the intersection of that quad with the candidate's quad in the
    // covered region.
    pixel_covered_rect.Intersect(candidate_pixel_rect);
    pixel_covered_region.Union(pixel_covered_rect);
  }

  // Add the candidate's overlay.
  DCHECK(candidate.resource_id);
  OverlayCandidateList new_candidate_list = *candidate_list;
  new_candidate_list.push_back(candidate);
  OverlayCandidate& new_candidate = new_candidate_list.back();
  new_candidate.plane_z_order = 1;
  new_candidate.display_rect = gfx::RectF(candidate_pixel_rect);
  new_candidate.quad_rect_in_target_space = candidate_pixel_rect;
  new_candidate.uv_rect = candidate_uv_rect;

  // Add an overlay of the primary surface for any part of the candidate's
  // quad that was covered.
  std::vector<gfx::Rect> pixel_covered_rects;
  for (Region::Iterator it(pixel_covered_region); it.has_rect(); it.next())
    pixel_covered_rects.push_back(it.rect());
  for (const gfx::Rect& pixel_covered_rect : pixel_covered_rects) {
    OverlayCandidate main_image_on_top;
    main_image_on_top.display_rect = gfx::RectF(pixel_covered_rect);
    main_image_on_top.uv_rect = gfx::RectF(pixel_covered_rect);
    main_image_on_top.uv_rect.Scale(1.f / pixel_bounds.width(),
                                    1.f / pixel_bounds.height());
    main_image_on_top.plane_z_order = 2;
    main_image_on_top.transform = gfx::OVERLAY_TRANSFORM_NONE;
    main_image_on_top.use_output_surface_for_resource = true;
    new_candidate_list.push_back(main_image_on_top);
  }

  // Check for support.
  capability_checker_->CheckOverlaySupport(&new_candidate_list);
  for (const OverlayCandidate& candidate : new_candidate_list) {
    if (!candidate.overlay_handled)
      return ++candidate_iter_in_quad_list;
  }

  // Remove the quad for the overlay quad. Replace it with a transparent quad
  // if we're putting a new overlay on top.
  if (pixel_covered_rects.empty()) {
    candidate_iter_in_quad_list =
        quad_list.EraseAndInvalidateAllPointers(candidate_iter_in_quad_list);
  } else {
    // Cache the information from the candidate quad that we'll need to
    // construct the solid color quads.
    const SharedQuadState* candidate_shared_quad_state =
        candidate_quad->shared_quad_state;
    const gfx::Rect candidate_rect = candidate_quad->rect;

    // Reserve space in the quad list for the transparent quads.
    quad_list.ReplaceExistingElement<SolidColorDrawQuad>(
        candidate_iter_in_quad_list);
    candidate_iter_in_quad_list =
        quad_list.InsertBeforeAndInvalidateAllPointers<SolidColorDrawQuad>(
            candidate_iter_in_quad_list, pixel_covered_rects.size() - 1);

    // Cover the region with transparent quads.
    for (const gfx::Rect& pixel_covered_rect : pixel_covered_rects) {
      gfx::Rect quad_space_covered_rect = MathUtil::MapEnclosingClippedRect(
          candidate_inverse_transform, pixel_covered_rect);
      quad_space_covered_rect.Intersect(candidate_rect);

      SolidColorDrawQuad* transparent_quad =
          static_cast<SolidColorDrawQuad*>(*candidate_iter_in_quad_list);
      transparent_quad->SetAll(candidate_shared_quad_state,
                               quad_space_covered_rect, quad_space_covered_rect,
                               quad_space_covered_rect, false,
                               SK_ColorTRANSPARENT, true);
      ++candidate_iter_in_quad_list;
    }
  }

  candidate_list->swap(new_candidate_list);
  return candidate_iter_in_quad_list;
}

}  // namespace cc
