// Copyright 2012 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/layers/solid_color_layer_impl.h"

#include <algorithm>

#include "cc/layers/append_quads_data.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/trees/occlusion.h"

namespace cc {

namespace {
const int kSolidQuadTileSize = 256;
}

SolidColorLayerImpl::SolidColorLayerImpl(LayerTreeImpl* tree_impl, int id)
    : LayerImpl(tree_impl, id) {
}

SolidColorLayerImpl::~SolidColorLayerImpl() {}

std::unique_ptr<LayerImpl> SolidColorLayerImpl::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return SolidColorLayerImpl::Create(tree_impl, id());
}

void SolidColorLayerImpl::AppendSolidQuads(
    RenderPass* render_pass,
    const Occlusion& occlusion_in_layer_space,
    SharedQuadState* shared_quad_state,
    const gfx::Rect& visible_layer_rect,
    SkColor color,
    AppendQuadsData* append_quads_data) {
  float alpha =
      (SkColorGetA(color) * (1.0f / 255.0f)) * shared_quad_state->opacity;
  DCHECK_EQ(SkBlendMode::kSrcOver, shared_quad_state->blend_mode);
  if (alpha < std::numeric_limits<float>::epsilon())
    return;
  // We create a series of smaller quads instead of just one large one so that
  // the culler can reduce the total pixels drawn.
  int right = visible_layer_rect.right();
  int bottom = visible_layer_rect.bottom();
  for (int x = visible_layer_rect.x(); x < visible_layer_rect.right();
       x += kSolidQuadTileSize) {
    for (int y = visible_layer_rect.y(); y < visible_layer_rect.bottom();
         y += kSolidQuadTileSize) {
      gfx::Rect quad_rect(x,
                          y,
                          std::min(right - x, kSolidQuadTileSize),
                          std::min(bottom - y, kSolidQuadTileSize));
      gfx::Rect visible_quad_rect =
          occlusion_in_layer_space.GetUnoccludedContentRect(quad_rect);
      if (visible_quad_rect.IsEmpty())
        continue;

      append_quads_data->visible_layer_area +=
          visible_quad_rect.width() * visible_quad_rect.height();

      SolidColorDrawQuad* quad =
          render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
      quad->SetNew(
          shared_quad_state, quad_rect, visible_quad_rect, color, false);
    }
  }
}

void SolidColorLayerImpl::AppendQuads(
    RenderPass* render_pass,
    AppendQuadsData* append_quads_data) {
  SharedQuadState* shared_quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  PopulateSharedQuadState(shared_quad_state);

  AppendDebugBorderQuad(render_pass, bounds(), shared_quad_state,
                        append_quads_data);

  // TODO(hendrikw): We need to pass the visible content rect rather than
  // |bounds()| here.
  AppendSolidQuads(render_pass, draw_properties().occlusion_in_content_space,
                   shared_quad_state, gfx::Rect(bounds()), background_color(),
                   append_quads_data);
}

const char* SolidColorLayerImpl::LayerTypeAsString() const {
  return "cc::SolidColorLayerImpl";
}

}  // namespace cc
