// Copyright 2014 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/tiles/tiling_set_raster_queue_required.h"

#include <stddef.h>

#include <utility>

#include "cc/tiles/picture_layer_tiling_set.h"
#include "cc/tiles/tile.h"
#include "cc/tiles/tile_priority.h"

namespace cc {

TilingSetRasterQueueRequired::TilingSetRasterQueueRequired(
    PictureLayerTilingSet* tiling_set,
    RasterTilePriorityQueue::Type type)
    : type_(type) {
  DCHECK_NE(static_cast<int>(type),
            static_cast<int>(RasterTilePriorityQueue::Type::ALL));

  // Required tiles should only come from HIGH_RESOLUTION tilings. However, if
  // we want required for activation tiles on the active tree, then it will come
  // from tilings whose pending twin is high resolution.
  PictureLayerTiling* tiling = nullptr;
  if (type == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION &&
      tiling_set->tree() == ACTIVE_TREE) {
    for (size_t i = 0; i < tiling_set->num_tilings(); ++i) {
      PictureLayerTiling* active_tiling = tiling_set->tiling_at(i);
      const PictureLayerTiling* pending_twin =
          tiling_set->client()->GetPendingOrActiveTwinTiling(active_tiling);
      if (pending_twin && pending_twin->resolution() == HIGH_RESOLUTION) {
        tiling = active_tiling;
        break;
      }
    }
  } else {
    tiling = tiling_set->FindTilingWithResolution(HIGH_RESOLUTION);
  }

  // If we don't have a tiling, then this queue will yield no tiles. See
  // PictureLayerImpl::CanHaveTilings for examples of when a HIGH_RESOLUTION
  // tiling would not be generated.
  if (!tiling || tiling->all_tiles_done())
    return;

  if (type == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION) {
    iterator_ = TilingIterator(tiling, &tiling->tiling_data_,
                               tiling->pending_visible_rect());
  } else {
    iterator_ = TilingIterator(tiling, &tiling->tiling_data_,
                               tiling->current_visible_rect());
  }

  while (!iterator_.done() && !IsTileRequired(*iterator_))
    ++iterator_;
}

TilingSetRasterQueueRequired::~TilingSetRasterQueueRequired() {
}

bool TilingSetRasterQueueRequired::IsEmpty() const {
  return iterator_.done();
}

void TilingSetRasterQueueRequired::Pop() {
  DCHECK(!IsEmpty());
  ++iterator_;
  while (!iterator_.done() && !IsTileRequired(*iterator_))
    ++iterator_;
}

const PrioritizedTile& TilingSetRasterQueueRequired::Top() const {
  DCHECK(!IsEmpty());
  return *iterator_;
}

bool TilingSetRasterQueueRequired::IsTileRequired(
    const PrioritizedTile& prioritized_tile) const {
  return (type_ == RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION &&
          prioritized_tile.tile()->required_for_activation()) ||
         (type_ == RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW &&
          prioritized_tile.tile()->required_for_draw());
}

TilingSetRasterQueueRequired::TilingIterator::TilingIterator()
    : tiling_(nullptr) {
}

TilingSetRasterQueueRequired::TilingIterator::TilingIterator(
    PictureLayerTiling* tiling,
    TilingData* tiling_data,
    const gfx::Rect& rect)
    : tiling_(tiling), tiling_data_(tiling_data) {
  visible_iterator_ =
      TilingData::Iterator(tiling_data_, rect, false /* include_borders */);
  if (!visible_iterator_)
    return;

  Tile* tile =
      tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y());
  // If this is a valid tile, return it. Note that we have to use a tiling check
  // for occlusion, since the tile's internal state has not yet been updated.
  if (tile && tile->draw_info().NeedsRaster() &&
      !tiling_->IsTileOccluded(tile)) {
    tiling_->UpdateRequiredStatesOnTile(tile);
    current_tile_ = tiling_->MakePrioritizedTile(
        tile, tiling_->ComputePriorityRectTypeForTile(tile));
    return;
  }
  ++(*this);
}

TilingSetRasterQueueRequired::TilingIterator::~TilingIterator() {
}

TilingSetRasterQueueRequired::TilingIterator&
    TilingSetRasterQueueRequired::TilingIterator::
    operator++() {
  Tile* tile = nullptr;
  while (true) {
    ++visible_iterator_;
    if (!visible_iterator_) {
      current_tile_ = PrioritizedTile();
      return *this;
    }
    std::pair<int, int> next_index = visible_iterator_.index();
    tile = tiling_->TileAt(next_index.first, next_index.second);
    // If the tile doesn't exist or if it exists but doesn't need raster work,
    // we can move on to the next tile.
    if (!tile || !tile->draw_info().NeedsRaster())
      continue;

    // If the tile is occluded, we also can skip it. Note that we use the tiling
    // check for occlusion, since tile's internal state has not yet been updated
    // (by UpdateTilePriority). The tiling check does not rely on tile's
    // internal state (it is, in fact, used to determine the tile's state).
    if (tiling_->IsTileOccluded(tile))
      continue;

    // If we get here, that means we have a valid tile that needs raster and is
    // in the NOW bin, which means that it can be required.
    break;
  }

  tiling_->UpdateRequiredStatesOnTile(tile);
  current_tile_ = tiling_->MakePrioritizedTile(
      tile, tiling_->ComputePriorityRectTypeForTile(tile));
  return *this;
}

}  // namespace cc
