// Copyright 2013 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/test/fake_picture_layer_impl.h"

#include <stddef.h>

#include <vector>

#include "base/memory/ptr_util.h"
#include "cc/tiles/tile.h"
#include "cc/trees/layer_tree_impl.h"

namespace cc {

FakePictureLayerImpl::FakePictureLayerImpl(
    LayerTreeImpl* tree_impl,
    int id,
    scoped_refptr<RasterSource> raster_source,
    Layer::LayerMaskType mask_type)
    : PictureLayerImpl(tree_impl, id, mask_type) {
  SetBounds(raster_source->GetSize());
  SetRasterSourceOnPending(raster_source, Region());
}

FakePictureLayerImpl::FakePictureLayerImpl(
    LayerTreeImpl* tree_impl,
    int id,
    scoped_refptr<RasterSource> raster_source,
    Layer::LayerMaskType mask_type,
    const gfx::Size& layer_bounds)
    : PictureLayerImpl(tree_impl, id, mask_type) {
  SetBounds(layer_bounds);
  SetRasterSourceOnPending(raster_source, Region());
}

FakePictureLayerImpl::FakePictureLayerImpl(LayerTreeImpl* tree_impl,
                                           int id,
                                           Layer::LayerMaskType mask_type)
    : PictureLayerImpl(tree_impl, id, mask_type) {}

std::unique_ptr<LayerImpl> FakePictureLayerImpl::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return base::WrapUnique(
      new FakePictureLayerImpl(tree_impl, id(), mask_type_));
}

void FakePictureLayerImpl::PushPropertiesTo(LayerImpl* layer_impl) {
  FakePictureLayerImpl* picture_layer_impl =
      static_cast<FakePictureLayerImpl*>(layer_impl);
  picture_layer_impl->fixed_tile_size_ = fixed_tile_size_;
  PictureLayerImpl::PushPropertiesTo(layer_impl);
}

void FakePictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
                                       AppendQuadsData* append_quads_data) {
  PictureLayerImpl::AppendQuads(render_pass, append_quads_data);
  ++append_quads_count_;
}

gfx::Size FakePictureLayerImpl::CalculateTileSize(
    const gfx::Size& content_bounds) const {
  if (fixed_tile_size_.IsEmpty()) {
    return PictureLayerImpl::CalculateTileSize(content_bounds);
  }

  return fixed_tile_size_;
}

PictureLayerTiling* FakePictureLayerImpl::HighResTiling() const {
  PictureLayerTiling* result = nullptr;
  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    PictureLayerTiling* tiling = tilings_->tiling_at(i);
    if (tiling->resolution() == HIGH_RESOLUTION) {
      // There should be only one high res tiling.
      CHECK(!result);
      result = tiling;
    }
  }
  return result;
}

PictureLayerTiling* FakePictureLayerImpl::LowResTiling() const {
  PictureLayerTiling* result = nullptr;
  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    PictureLayerTiling* tiling = tilings_->tiling_at(i);
    if (tiling->resolution() == LOW_RESOLUTION) {
      // There should be only one low res tiling.
      CHECK(!result);
      result = tiling;
    }
  }
  return result;
}

void FakePictureLayerImpl::SetRasterSourceOnPending(
    scoped_refptr<RasterSource> raster_source,
    const Region& invalidation) {
  DCHECK(layer_tree_impl()->IsPendingTree());
  Region invalidation_temp = invalidation;
  const PictureLayerTilingSet* pending_set = nullptr;
  set_gpu_raster_max_texture_size(layer_tree_impl()->device_viewport_size());
  UpdateRasterSource(raster_source, &invalidation_temp, pending_set);
}

void FakePictureLayerImpl::CreateAllTiles() {
  for (size_t i = 0; i < num_tilings(); ++i)
    tilings_->tiling_at(i)->CreateAllTilesForTesting();
}

void FakePictureLayerImpl::SetAllTilesReady() {
  for (size_t tiling_idx = 0; tiling_idx < tilings_->num_tilings();
       ++tiling_idx) {
    PictureLayerTiling* tiling = tilings_->tiling_at(tiling_idx);
    SetAllTilesReadyInTiling(tiling);
  }
}

void FakePictureLayerImpl::SetAllTilesReadyInTiling(
    PictureLayerTiling* tiling) {
  std::vector<Tile*> tiles = tiling->AllTilesForTesting();
  for (size_t tile_idx = 0; tile_idx < tiles.size(); ++tile_idx) {
    Tile* tile = tiles[tile_idx];
    SetTileReady(tile);
  }
}

void FakePictureLayerImpl::SetTileReady(Tile* tile) {
  TileDrawInfo& draw_info = tile->draw_info();
  draw_info.SetSolidColorForTesting(true);
  DCHECK(draw_info.IsReadyToDraw());
}

void FakePictureLayerImpl::DidBecomeActive() {
  PictureLayerImpl::DidBecomeActive();
  ++did_become_active_call_count_;
}

bool FakePictureLayerImpl::HasValidTilePriorities() const {
  return use_set_valid_tile_priorities_flag_
             ? has_valid_tile_priorities_
             : PictureLayerImpl::HasValidTilePriorities();
}

size_t FakePictureLayerImpl::CountTilesRequired(
    TileRequirementCheck is_tile_required_callback) const {
  if (!HasValidTilePriorities())
    return 0;

  if (!tilings_)
    return 0;

  if (visible_layer_rect().IsEmpty())
    return 0;

  gfx::Rect rect = viewport_rect_for_tile_priority_in_content_space_;
  rect.Intersect(visible_layer_rect());

  size_t count = 0;

  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
    PictureLayerTiling* tiling = tilings_->tiling_at(i);
    if (tiling->resolution() != HIGH_RESOLUTION &&
        tiling->resolution() != LOW_RESOLUTION)
      continue;

    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
         ++iter) {
      const Tile* tile = *iter;
      // A null tile (i.e. missing recording) can just be skipped.
      // TODO(vmpstr): Verify this is true if we create tiles in raster
      // iterators.
      if (!tile)
        continue;

      // We can't check tile->required_for_activation, because that value might
      // be out of date. It is updated in the raster/eviction iterators.
      // TODO(vmpstr): Remove the comment once you can't access this information
      // from the tile.
      if ((tiling->*is_tile_required_callback)(tile))
        ++count;
    }
  }

  return count;
}

size_t FakePictureLayerImpl::CountTilesRequiredForActivation() const {
  if (!layer_tree_impl()->IsPendingTree())
    return 0;

  return CountTilesRequired(&PictureLayerTiling::IsTileRequiredForActivation);
}

size_t FakePictureLayerImpl::CountTilesRequiredForDraw() const {
  if (!layer_tree_impl()->IsActiveTree())
    return 0;

  return CountTilesRequired(&PictureLayerTiling::IsTileRequiredForDraw);
}

void FakePictureLayerImpl::ReleaseResources() {
  PictureLayerImpl::ReleaseResources();
  ++release_resources_count_;
}

void FakePictureLayerImpl::ReleaseTileResources() {
  PictureLayerImpl::ReleaseTileResources();
  ++release_tile_resources_count_;
}

}  // namespace cc
