// 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/ca_layer_overlay.h"

#include <algorithm>

#include "base/metrics/histogram_macros.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/stream_video_draw_quad.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/resources/resource_provider.h"
#include "gpu/GLES2/gl2extchromium.h"

namespace cc {

namespace {

// If there are too many RenderPassDrawQuads, we shouldn't use Core Animation to
// present them as individual layers, since that potentially doubles the amount
// of work needed to present them. cc has to blit them into an IOSurface, and
// then Core Animation has to blit them to the final surface.
// https://crbug.com/636884.
const int kTooManyRenderPassDrawQuads = 30;

// This enum is used for histogram states and should only have new values added
// to the end before COUNT.
enum CALayerResult {
  CA_LAYER_SUCCESS = 0,
  CA_LAYER_FAILED_UNKNOWN,
  CA_LAYER_FAILED_IO_SURFACE_NOT_CANDIDATE,
  CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE,
  CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM,
  CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE,
  CA_LAYER_FAILED_TEXTURE_Y_FLIPPED,
  CA_LAYER_FAILED_TILE_NOT_CANDIDATE,
  CA_LAYER_FAILED_QUAD_BLEND_MODE,
  CA_LAYER_FAILED_QUAD_TRANSFORM,
  CA_LAYER_FAILED_QUAD_CLIPPING,
  CA_LAYER_FAILED_DEBUG_BORDER,
  CA_LAYER_FAILED_PICTURE_CONTENT,
  CA_LAYER_FAILED_RENDER_PASS,
  CA_LAYER_FAILED_SURFACE_CONTENT,
  CA_LAYER_FAILED_YUV_VIDEO_CONTENT,
  CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS,
  CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES,
  CA_LAYER_FAILED_RENDER_PASS_FILTER_SCALE,
  CA_LAYER_FAILED_RENDER_PASS_BACKGROUND_FILTERS,
  CA_LAYER_FAILED_RENDER_PASS_MASK,
  CA_LAYER_FAILED_RENDER_PASS_FILTER_OPERATION,
  CA_LAYER_FAILED_RENDER_PASS_SORTING_CONTEXT_ID,
  CA_LAYER_FAILED_TOO_MANY_RENDER_PASS_DRAW_QUADS,
  CA_LAYER_FAILED_COUNT,
};

bool FilterOperationSupported(const FilterOperation& operation) {
  switch (operation.type()) {
    case FilterOperation::GRAYSCALE:
    case FilterOperation::SEPIA:
    case FilterOperation::SATURATE:
    case FilterOperation::HUE_ROTATE:
    case FilterOperation::INVERT:
    case FilterOperation::BRIGHTNESS:
    case FilterOperation::CONTRAST:
    case FilterOperation::OPACITY:
    case FilterOperation::BLUR:
    case FilterOperation::DROP_SHADOW:
      return true;
    default:
      return false;
  }
}

static const FilterOperations* FiltersForPass(
    int render_pass_id,
    const RenderPassFilterList& filter_list) {
  auto it = std::lower_bound(
      filter_list.begin(), filter_list.end(),
      std::pair<int, FilterOperations*>(render_pass_id, nullptr));
  if (it != filter_list.end() && it->first == render_pass_id)
    return it->second;
  return nullptr;
}

CALayerResult FromRenderPassQuad(
    ResourceProvider* resource_provider,
    const RenderPassDrawQuad* quad,
    const RenderPassFilterList& render_pass_filters,
    const RenderPassFilterList& render_pass_background_filters,
    CALayerOverlay* ca_layer_overlay) {
  if (FiltersForPass(quad->render_pass_id, render_pass_background_filters)) {
    return CA_LAYER_FAILED_RENDER_PASS_BACKGROUND_FILTERS;
  }

  if (quad->shared_quad_state->sorting_context_id != 0)
    return CA_LAYER_FAILED_RENDER_PASS_SORTING_CONTEXT_ID;

  const FilterOperations* filters =
      FiltersForPass(quad->render_pass_id, render_pass_filters);
  if (filters) {
    for (const FilterOperation& operation : filters->operations()) {
      bool success = FilterOperationSupported(operation);
      if (!success)
        return CA_LAYER_FAILED_RENDER_PASS_FILTER_OPERATION;
    }
  }

  ca_layer_overlay->rpdq = quad;
  ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1);

  return CA_LAYER_SUCCESS;
}

CALayerResult FromStreamVideoQuad(ResourceProvider* resource_provider,
                                  const StreamVideoDrawQuad* quad,
                                  CALayerOverlay* ca_layer_overlay) {
  unsigned resource_id = quad->resource_id();
  if (!resource_provider->IsOverlayCandidate(resource_id))
    return CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE;
  ca_layer_overlay->contents_resource_id = resource_id;
  // TODO(ccameron): Support merging at least some basic transforms into the
  // layer transform.
  if (!quad->matrix.IsIdentity())
    return CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM;
  ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1);
  return CA_LAYER_SUCCESS;
}

CALayerResult FromSolidColorDrawQuad(const SolidColorDrawQuad* quad,
                                     CALayerOverlay* ca_layer_overlay,
                                     bool* skip) {
  // Do not generate quads that are completely transparent.
  if (SkColorGetA(quad->color) == 0) {
    *skip = true;
    return CA_LAYER_SUCCESS;
  }
  ca_layer_overlay->background_color = quad->color;
  return CA_LAYER_SUCCESS;
}

CALayerResult FromTextureQuad(ResourceProvider* resource_provider,
                              const TextureDrawQuad* quad,
                              CALayerOverlay* ca_layer_overlay) {
  unsigned resource_id = quad->resource_id();
  if (!resource_provider->IsOverlayCandidate(resource_id))
    return CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE;
  if (quad->y_flipped) {
    // The anchor point is at the bottom-left corner of the CALayer. The
    // transformation that flips the contents of the layer without changing its
    // frame is the composition of a vertical flip about the anchor point, and a
    // translation by the height of the layer.
    ca_layer_overlay->shared_state->transform.preTranslate(
        0, ca_layer_overlay->bounds_rect.height(), 0);
    ca_layer_overlay->shared_state->transform.preScale(1, -1, 1);
  }
  ca_layer_overlay->contents_resource_id = resource_id;
  ca_layer_overlay->contents_rect =
      BoundingRect(quad->uv_top_left, quad->uv_bottom_right);
  ca_layer_overlay->background_color = quad->background_color;
  for (int i = 1; i < 4; ++i) {
    if (quad->vertex_opacity[i] != quad->vertex_opacity[0])
      return CA_LAYER_FAILED_DIFFERENT_VERTEX_OPACITIES;
  }
  ca_layer_overlay->shared_state->opacity *= quad->vertex_opacity[0];
  ca_layer_overlay->filter = quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR;
  return CA_LAYER_SUCCESS;
}

CALayerResult FromTileQuad(ResourceProvider* resource_provider,
                           const TileDrawQuad* quad,
                           CALayerOverlay* ca_layer_overlay) {
  unsigned resource_id = quad->resource_id();
  if (!resource_provider->IsOverlayCandidate(resource_id))
    return CA_LAYER_FAILED_TILE_NOT_CANDIDATE;
  ca_layer_overlay->contents_resource_id = resource_id;
  ca_layer_overlay->contents_rect = quad->tex_coord_rect;
  ca_layer_overlay->contents_rect.Scale(1.f / quad->texture_size.width(),
                                        1.f / quad->texture_size.height());
  return CA_LAYER_SUCCESS;
}

class CALayerOverlayProcessor {
 public:
  CALayerResult FromDrawQuad(
      ResourceProvider* resource_provider,
      const gfx::RectF& display_rect,
      const DrawQuad* quad,
      const RenderPassFilterList& render_pass_filters,
      const RenderPassFilterList& render_pass_background_filters,
      CALayerOverlay* ca_layer_overlay,
      bool* skip,
      bool* render_pass_draw_quad) {
    if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
      return CA_LAYER_FAILED_QUAD_BLEND_MODE;

    // Early-out for invisible quads.
    if (quad->shared_quad_state->opacity == 0.f) {
      *skip = true;
      return CA_LAYER_SUCCESS;
    }

    // Enable edge anti-aliasing only on layer boundaries.
    ca_layer_overlay->edge_aa_mask = 0;
    if (quad->IsLeftEdge())
      ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_LEFT_CHROMIUM;
    if (quad->IsRightEdge())
      ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_RIGHT_CHROMIUM;
    if (quad->IsBottomEdge())
      ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM;
    if (quad->IsTopEdge())
      ca_layer_overlay->edge_aa_mask |= GL_CA_LAYER_EDGE_TOP_CHROMIUM;

    if (most_recent_shared_quad_state_ != quad->shared_quad_state) {
      most_recent_shared_quad_state_ = quad->shared_quad_state;
      most_recent_overlay_shared_state_ = new CALayerOverlaySharedState;
      // Set rect clipping and sorting context ID.
      most_recent_overlay_shared_state_->sorting_context_id =
          quad->shared_quad_state->sorting_context_id;
      most_recent_overlay_shared_state_->is_clipped =
          quad->shared_quad_state->is_clipped;
      most_recent_overlay_shared_state_->clip_rect =
          gfx::RectF(quad->shared_quad_state->clip_rect);

      most_recent_overlay_shared_state_->opacity =
          quad->shared_quad_state->opacity;
      most_recent_overlay_shared_state_->transform =
          quad->shared_quad_state->quad_to_target_transform.matrix();
    }
    ca_layer_overlay->shared_state = most_recent_overlay_shared_state_;

    ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect);

    *render_pass_draw_quad = quad->material == DrawQuad::RENDER_PASS;
    switch (quad->material) {
      case DrawQuad::TEXTURE_CONTENT:
        return FromTextureQuad(resource_provider,
                               TextureDrawQuad::MaterialCast(quad),
                               ca_layer_overlay);
      case DrawQuad::TILED_CONTENT:
        return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad),
                            ca_layer_overlay);
      case DrawQuad::SOLID_COLOR:
        return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad),
                                      ca_layer_overlay, skip);
      case DrawQuad::STREAM_VIDEO_CONTENT:
        return FromStreamVideoQuad(resource_provider,
                                   StreamVideoDrawQuad::MaterialCast(quad),
                                   ca_layer_overlay);
      case DrawQuad::DEBUG_BORDER:
        return CA_LAYER_FAILED_DEBUG_BORDER;
      case DrawQuad::PICTURE_CONTENT:
        return CA_LAYER_FAILED_PICTURE_CONTENT;
      case DrawQuad::RENDER_PASS:
        return FromRenderPassQuad(
            resource_provider, RenderPassDrawQuad::MaterialCast(quad),
            render_pass_filters, render_pass_background_filters,
            ca_layer_overlay);
      case DrawQuad::SURFACE_CONTENT:
        return CA_LAYER_FAILED_SURFACE_CONTENT;
      case DrawQuad::YUV_VIDEO_CONTENT:
        return CA_LAYER_FAILED_YUV_VIDEO_CONTENT;
      default:
        break;
    }

    return CA_LAYER_FAILED_UNKNOWN;
  }

 private:
  const SharedQuadState* most_recent_shared_quad_state_ = nullptr;
  scoped_refptr<CALayerOverlaySharedState> most_recent_overlay_shared_state_;
};

}  // namespace

CALayerOverlay::CALayerOverlay() : filter(GL_LINEAR) {}

CALayerOverlay::CALayerOverlay(const CALayerOverlay& other) = default;

CALayerOverlay::~CALayerOverlay() {}

bool ProcessForCALayerOverlays(
    ResourceProvider* resource_provider,
    const gfx::RectF& display_rect,
    const QuadList& quad_list,
    const RenderPassFilterList& render_pass_filters,
    const RenderPassFilterList& render_pass_background_filters,
    CALayerOverlayList* ca_layer_overlays) {
  CALayerResult result = CA_LAYER_SUCCESS;
  ca_layer_overlays->reserve(quad_list.size());

  int render_pass_draw_quad_count = 0;
  CALayerOverlayProcessor processor;
  for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd();
       ++it) {
    const DrawQuad* quad = *it;
    CALayerOverlay ca_layer;
    bool skip = false;
    bool render_pass_draw_quad = false;
    result = processor.FromDrawQuad(resource_provider, display_rect, quad,
                                    render_pass_filters,
                                    render_pass_background_filters, &ca_layer,
                                    &skip, &render_pass_draw_quad);
    if (result != CA_LAYER_SUCCESS)
      break;

    if (render_pass_draw_quad) {
      ++render_pass_draw_quad_count;
      if (render_pass_draw_quad_count > kTooManyRenderPassDrawQuads) {
        result = CA_LAYER_FAILED_TOO_MANY_RENDER_PASS_DRAW_QUADS;
        break;
      }
    }

    if (skip)
      continue;

    // It is not possible to correctly represent two different clipping settings
    // within one sorting context.
    if (!ca_layer_overlays->empty()) {
      const CALayerOverlay& previous_ca_layer = ca_layer_overlays->back();
      if (ca_layer.shared_state->sorting_context_id &&
          previous_ca_layer.shared_state->sorting_context_id ==
              ca_layer.shared_state->sorting_context_id) {
        if (previous_ca_layer.shared_state->is_clipped !=
                ca_layer.shared_state->is_clipped ||
            previous_ca_layer.shared_state->clip_rect !=
                ca_layer.shared_state->clip_rect) {
          result = CA_LAYER_FAILED_DIFFERENT_CLIP_SETTINGS;
          break;
        }
      }
    }

    ca_layer_overlays->push_back(ca_layer);
  }

  UMA_HISTOGRAM_ENUMERATION("Compositing.Renderer.CALayerResult", result,
                            CA_LAYER_FAILED_COUNT);

  if (result != CA_LAYER_SUCCESS) {
    ca_layer_overlays->clear();
    return false;
  }
  return true;
}

}  // namespace cc
