text:
namespace cc {
namespace {

// Flag to indicate whether we should try and detect that
// a tile is of solid color.
const bool kUseColorEstimator = true;

// TODO(enne): remove this histogram and its monitoring in M58 once there is
// enough new data from the other two raster task timers.
DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
    ScopedGeneralRasterTaskTimer,
    "Compositing.%s.RasterTask.RasterUs",
    "Compositing.%s.RasterTask.RasterPixelsPerMs");

DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
    ScopedSoftwareRasterTaskTimer,
    "Compositing.%s.RasterTask.RasterUs.Software",
    "Compositing.%s.RasterTask.RasterPixelsPerMs.Software");

DEFINE_SCOPED_UMA_HISTOGRAM_AREA_TIMER(
    ScopedGpuRasterTaskTimer,
    "Compositing.%s.RasterTask.RasterUs.Gpu",
    "Compositing.%s.RasterTask.RasterPixelsPerMs.Gpu");

class ScopedRasterTaskTimer {
 public:
  explicit ScopedRasterTaskTimer(bool use_gpu_rasterization) {
    if (use_gpu_rasterization)
      gpu_timer_.emplace();
    else
      software_timer_.emplace();
  }

  void SetArea(int area) {
    general_timer_.SetArea(area);
    if (software_timer_)
      software_timer_->SetArea(area);
    if (gpu_timer_)
      gpu_timer_->SetArea(area);
  }

 private:
  ScopedGeneralRasterTaskTimer general_timer_;
  base::Optional<ScopedSoftwareRasterTaskTimer> software_timer_;
  base::Optional<ScopedGpuRasterTaskTimer> gpu_timer_;
};

class RasterTaskImpl : public TileTask {
 public:
  RasterTaskImpl(TileManager* tile_manager,
                 Tile* tile,
                 Resource* resource,
                 scoped_refptr<RasterSource> raster_source,
                 const RasterSource::PlaybackSettings& playback_settings,
                 TileResolution tile_resolution,
                 gfx::Rect invalidated_rect,
                 uint64_t source_prepare_tiles_id,
                 std::unique_ptr<RasterBuffer> raster_buffer,
                 TileTask::Vector* dependencies,
                 bool is_gpu_rasterization)
      : TileTask(!is_gpu_rasterization, dependencies),
        tile_manager_(tile_manager),
        tile_(tile),
        resource_(resource),
        raster_source_(std::move(raster_source)),
        content_rect_(tile->content_rect()),
        invalid_content_rect_(invalidated_rect),
        raster_scales_(tile->raster_scales()),
        playback_settings_(playback_settings),
        tile_resolution_(tile_resolution),
        layer_id_(tile->layer_id()),
        source_prepare_tiles_id_(source_prepare_tiles_id),
        tile_tracing_id_(static_cast<void*>(tile)),
        new_content_id_(tile->id()),
        source_frame_number_(tile->source_frame_number()),
        is_gpu_rasterization_(is_gpu_rasterization),
        raster_buffer_(std::move(raster_buffer)) {
    DCHECK(origin_thread_checker_.CalledOnValidThread());
  }

  // Overridden from Task:
  void RunOnWorkerThread() override {
    TRACE_EVENT1("cc", "RasterizerTaskImpl::RunOnWorkerThread",
                 "source_prepare_tiles_id", source_prepare_tiles_id_);

    DCHECK(raster_source_.get());
    DCHECK(raster_buffer_);

    frame_viewer_instrumentation::ScopedRasterTask raster_task(
        tile_tracing_id_, tile_resolution_, source_frame_number_, layer_id_);
    ScopedRasterTaskTimer timer(is_gpu_rasterization_);
    timer.SetArea(content_rect_.size().GetArea());

    DCHECK(raster_source_);

    raster_buffer_->Playback(raster_source_.get(), content_rect_,
                             invalid_content_rect_, new_content_id_,
                             raster_scales_, playback_settings_);
  }

  // Overridden from TileTask:
  void OnTaskCompleted() override {
    DCHECK(origin_thread_checker_.CalledOnValidThread());

    // Here calling state().IsCanceled() is thread-safe, because this task is
    // already concluded as FINISHED or CANCELLED and no longer will be worked
    // upon by task graph runner.
    tile_manager_->OnRasterTaskCompleted(std::move(raster_buffer_), tile_,
                                         resource_, state().IsCanceled());
  }

 protected:
  ~RasterTaskImpl() override {
    DCHECK(origin_thread_checker_.CalledOnValidThread());
    DCHECK(!raster_buffer_);
  }

 private:
  base::ThreadChecker origin_thread_checker_;

  // The following members are needed for processing completion of this task on
  // origin thread. These are not thread-safe and should be accessed only in
  // origin thread. Ensure their access by checking CalledOnValidThread().
  TileManager* tile_manager_;
  Tile* tile_;
  Resource* resource_;

  // The following members should be used for running the task.
  scoped_refptr<RasterSource> raster_source_;
  gfx::Rect content_rect_;
  gfx::Rect invalid_content_rect_;
  gfx::SizeF raster_scales_;
  RasterSource::PlaybackSettings playback_settings_;
  TileResolution tile_resolution_;
  int layer_id_;
  uint64_t source_prepare_tiles_id_;
  void* tile_tracing_id_;
  uint64_t new_content_id_;
  int source_frame_number_;
  bool is_gpu_rasterization_;
  std::unique_ptr<RasterBuffer> raster_buffer_;

  DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl);
};

TaskCategory TaskCategoryForTileTask(TileTask* task,
                                     bool use_foreground_category) {
  if (!task->supports_concurrent_execution())
    return TASK_CATEGORY_NONCONCURRENT_FOREGROUND;

  if (use_foreground_category)
    return TASK_CATEGORY_FOREGROUND;

  return TASK_CATEGORY_BACKGROUND;
}

bool IsForegroundCategory(uint16_t category) {
  TaskCategory enum_category = static_cast<TaskCategory>(category);
  switch (enum_category) {
    case TASK_CATEGORY_NONCONCURRENT_FOREGROUND:
    case TASK_CATEGORY_FOREGROUND:
      return true;
    case TASK_CATEGORY_BACKGROUND:
      return false;
  }

  DCHECK(false);
  return false;
}

// Task priorities that make sure that the task set done tasks run before any
// other remaining tasks.
const size_t kRequiredForActivationDoneTaskPriority = 1u;
const size_t kRequiredForDrawDoneTaskPriority = 2u;
const size_t kAllDoneTaskPriority = 3u;

// For correctness, |kTileTaskPriorityBase| must be greater than
// all task set done task priorities.
size_t kTileTaskPriorityBase = 10u;

void InsertNodeForTask(TaskGraph* graph,
                       TileTask* task,
                       uint16_t category,
                       uint16_t priority,
                       size_t dependencies) {
  DCHECK(std::find_if(graph->nodes.begin(), graph->nodes.end(),
                      [&task](const TaskGraph::Node& node) {
                        return node.task == task;
                      }) == graph->nodes.end());
  graph->nodes.emplace_back(task, category, priority, dependencies);
}

void InsertNodeForDecodeTask(TaskGraph* graph,
                             TileTask* task,
                             bool use_foreground_category,
                             uint16_t priority) {
  uint32_t dependency_count = 0u;
  if (task->dependencies().size()) {
    DCHECK_EQ(task->dependencies().size(), 1u);
    auto* dependency = task->dependencies()[0].get();
    if (!dependency->HasCompleted()) {
      InsertNodeForDecodeTask(graph, dependency, use_foreground_category,
                              priority);
      graph->edges.push_back(TaskGraph::Edge(dependency, task));
      dependency_count = 1u;
    }
  }
  InsertNodeForTask(graph, task,
                    TaskCategoryForTileTask(task, use_foreground_category),
                    priority, dependency_count);
}

void InsertNodesForRasterTask(TaskGraph* graph,
                              TileTask* raster_task,
                              const TileTask::Vector& decode_tasks,
                              size_t priority,
                              bool use_foreground_category) {
  size_t dependencies = 0u;

  // Insert image decode tasks.
  for (TileTask::Vector::const_iterator it = decode_tasks.begin();
       it != decode_tasks.end(); ++it) {
    TileTask* decode_task = it->get();

    // Skip if already decoded.
    if (decode_task->HasCompleted())
      continue;

    dependencies++;

    // Add decode task if it doesn't already exist in graph.
    TaskGraph::Node::Vector::iterator decode_it =
        std::find_if(graph->nodes.begin(), graph->nodes.end(),
                     [decode_task](const TaskGraph::Node& node) {
                       return node.task == decode_task;
                     });

    // In rare circumstances, a background category task may come in before a
    // foreground category task. In these cases, upgrade any background category
    // dependencies of the current task.
    // TODO(ericrk): Task iterators should be updated to avoid this.
    // crbug.com/594851
    // TODO(ericrk): This should handle dependencies recursively.
    // crbug.com/605234
    if (decode_it != graph->nodes.end() && use_foreground_category &&
        !IsForegroundCategory(decode_it->category)) {
      decode_it->category = TASK_CATEGORY_FOREGROUND;
    }

    if (decode_it == graph->nodes.end()) {
      InsertNodeForDecodeTask(graph, decode_task, use_foreground_category,
                              priority);
    }

    graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task));
  }

  InsertNodeForTask(
      graph, raster_task,
      TaskCategoryForTileTask(raster_task, use_foreground_category), priority,
      dependencies);
}

class TaskSetFinishedTaskImpl : public TileTask {
 public:
  explicit TaskSetFinishedTaskImpl(
      base::SequencedTaskRunner* task_runner,
      const base::Closure& on_task_set_finished_callback)
      : TileTask(true),
        task_runner_(task_runner),
        on_task_set_finished_callback_(on_task_set_finished_callback) {}

  // Overridden from Task:
  void RunOnWorkerThread() override {
    TRACE_EVENT0("cc", "TaskSetFinishedTaskImpl::RunOnWorkerThread");
    TaskSetFinished();
  }

  // Overridden from TileTask:
  void OnTaskCompleted() override {}

 protected:
  ~TaskSetFinishedTaskImpl() override {}

  void TaskSetFinished() {
    task_runner_->PostTask(FROM_HERE, on_task_set_finished_callback_);
  }

 private:
  base::SequencedTaskRunner* task_runner_;
  const base::Closure on_task_set_finished_callback_;

  DISALLOW_COPY_AND_ASSIGN(TaskSetFinishedTaskImpl);
};

}  // namespace

RasterTaskCompletionStats::RasterTaskCompletionStats()
    : completed_count(0u), canceled_count(0u) {}

std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
  std::unique_ptr<base::trace_event::TracedValue> state(
      new base::trace_event::TracedValue());
  state->SetInteger("completed_count",
                    base::saturated_cast<int>(stats.completed_count));
  state->SetInteger("canceled_count",
                    base::saturated_cast<int>(stats.canceled_count));
  return std::move(state);
}

TileManager::TileManager(TileManagerClient* client,
                         base::SequencedTaskRunner* task_runner,
                         size_t scheduled_raster_task_limit,
                         bool use_partial_raster)
    : client_(client),
      task_runner_(task_runner),
      resource_pool_(nullptr),
      tile_task_manager_(nullptr),
      scheduled_raster_task_limit_(scheduled_raster_task_limit),
      use_partial_raster_(use_partial_raster),
      use_gpu_rasterization_(false),
      all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
      did_check_for_completed_tasks_since_last_schedule_tasks_(true),
      did_oom_on_last_assign_(false),
      more_tiles_need_prepare_check_notifier_(
          task_runner_,
          base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared,
                     base::Unretained(this))),
      signals_check_notifier_(task_runner_,
                              base::Bind(&TileManager::CheckAndIssueSignals,
                                         base::Unretained(this))),
      has_scheduled_tile_tasks_(false),
      prepare_tiles_count_(0u),
      next_tile_id_(0u),
      task_set_finished_weak_ptr_factory_(this) {}

TileManager::~TileManager() {
  FinishTasksAndCleanUp();
}

void TileManager::FinishTasksAndCleanUp() {
  if (!tile_task_manager_)
    return;

  global_state_ = GlobalStateThatImpactsTilePriority();

  // This cancels tasks if possible, finishes pending tasks, and release any
  // uninitialized resources.
  tile_task_manager_->Shutdown();

  raster_buffer_provider_->Shutdown();

  tile_task_manager_->CheckForCompletedTasks();

  // Now that all tasks have been finished, we can clear any |orphan_tasks_|.
  orphan_tasks_.clear();

  FreeResourcesForReleasedTiles();
  CleanUpReleasedTiles();

  tile_task_manager_ = nullptr;
  resource_pool_ = nullptr;
  more_tiles_need_prepare_check_notifier_.Cancel();
  signals_check_notifier_.Cancel();
  task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs();

  image_manager_.SetImageDecodeController(nullptr);
  locked_image_tasks_.clear();
}

void TileManager::SetResources(ResourcePool* resource_pool,
                               ImageDecodeController* image_decode_controller,
                               TaskGraphRunner* task_graph_runner,
                               RasterBufferProvider* raster_buffer_provider,
                               size_t scheduled_raster_task_limit,
                               bool use_gpu_rasterization) {
  DCHECK(!tile_task_manager_);
  DCHECK(task_graph_runner);

  use_gpu_rasterization_ = use_gpu_rasterization;
  scheduled_raster_task_limit_ = scheduled_raster_task_limit;
  resource_pool_ = resource_pool;
  image_manager_.SetImageDecodeController(image_decode_controller);
  tile_task_manager_ = TileTaskManagerImpl::Create(task_graph_runner);
  raster_buffer_provider_ = raster_buffer_provider;
}

void TileManager::Release(Tile* tile) {
  released_tiles_.push_back(tile);
}

void TileManager::FreeResourcesForReleasedTiles() {
  for (auto* tile : released_tiles_)
    FreeResourcesForTile(tile);
}

void TileManager::CleanUpReleasedTiles() {
  std::vector<Tile*> tiles_to_retain;
  for (auto* tile : released_tiles_) {
    if (tile->HasRasterTask()) {
      tiles_to_retain.push_back(tile);
      continue;
    }

    DCHECK(!tile->draw_info().has_resource());
    DCHECK(tiles_.find(tile->id()) != tiles_.end());
    tiles_.erase(tile->id());

    delete tile;
  }
  released_tiles_.swap(tiles_to_retain);
}

void TileManager::DidFinishRunningTileTasksRequiredForActivation() {
  TRACE_EVENT0("cc",
               "TileManager::DidFinishRunningTileTasksRequiredForActivation");
  TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state",
                               ScheduledTasksStateAsValue());
  // TODO(vmpstr): Temporary check to debug crbug.com/642927.
  CHECK(tile_task_manager_);
  signals_.ready_to_activate = true;
  signals_check_notifier_.Schedule();
}

void TileManager::DidFinishRunningTileTasksRequiredForDraw() {
  TRACE_EVENT0("cc", "TileManager::DidFinishRunningTileTasksRequiredForDraw");
  TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state",
                               ScheduledTasksStateAsValue());
  // TODO(vmpstr): Temporary check to debug crbug.com/642927.
  CHECK(tile_task_manager_);
  signals_.ready_to_draw = true;
  signals_check_notifier_.Schedule();
}

void TileManager::DidFinishRunningAllTileTasks() {
  TRACE_EVENT0("cc", "TileManager::DidFinishRunningAllTileTasks");
  TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
  DCHECK(resource_pool_);
  DCHECK(tile_task_manager_);

  has_scheduled_tile_tasks_ = false;

  if (all_tiles_that_need_to_be_rasterized_are_scheduled_ &&
      !resource_pool_->ResourceUsageTooHigh()) {
    // TODO(ericrk): We should find a better way to safely handle re-entrant
    // notifications than always having to schedule a new task.
    // http://crbug.com/498439
    // TODO(vmpstr): Temporary check to debug crbug.com/642927.
    CHECK(tile_task_manager_);
    signals_.all_tile_tasks_completed = true;
    signals_check_notifier_.Schedule();
    return;
  }

  more_tiles_need_prepare_check_notifier_.Schedule();
}

bool TileManager::PrepareTiles(
    const GlobalStateThatImpactsTilePriority& state) {
  ++prepare_tiles_count_;

  TRACE_EVENT1("cc", "TileManager::PrepareTiles", "prepare_tiles_id",
               prepare_tiles_count_);

  if (!tile_task_manager_) {
    TRACE_EVENT_INSTANT0("cc", "PrepareTiles aborted",
                         TRACE_EVENT_SCOPE_THREAD);
    return false;
  }

  signals_.reset();
  global_state_ = state;

  // We need to call CheckForCompletedTasks() once in-between each call
  // to ScheduleTasks() to prevent canceled tasks from being scheduled.
  if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
    tile_task_manager_->CheckForCompletedTasks();
    did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
  }

  FreeResourcesForReleasedTiles();
  CleanUpReleasedTiles();

  PrioritizedWorkToSchedule prioritized_work = AssignGpuMemoryToTiles();

  // Inform the client that will likely require a draw if the highest priority
  // tile that will be rasterized is required for draw.
  client_->SetIsLikelyToRequireADraw(
      !prioritized_work.tiles_to_raster.empty() &&
      prioritized_work.tiles_to_raster.front().tile()->required_for_draw());

  // Schedule tile tasks.
  ScheduleTasks(prioritized_work);

  TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
                       "state", BasicStateAsValue());
  return true;
}

void TileManager::Flush() {
  TRACE_EVENT0("cc", "TileManager::Flush");

  if (!tile_task_manager_) {
    TRACE_EVENT_INSTANT0("cc", "Flush aborted", TRACE_EVENT_SCOPE_THREAD);
    return;
  }

  tile_task_manager_->CheckForCompletedTasks();
  did_check_for_completed_tasks_since_last_schedule_tasks_ = true;

  TRACE_EVENT_INSTANT1("cc", "DidFlush", TRACE_EVENT_SCOPE_THREAD, "stats",
                       RasterTaskCompletionStatsAsValue(flush_stats_));
  flush_stats_ = RasterTaskCompletionStats();
}

std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
TileManager::BasicStateAsValue() const {
  std::unique_ptr<base::trace_event::TracedValue> value(
      new base::trace_event::TracedValue());
  BasicStateAsValueInto(value.get());
  return std::move(value);
}

void TileManager::BasicStateAsValueInto(
    base::trace_event::TracedValue* state) const {
  state->SetInteger("tile_count", base::saturated_cast<int>(tiles_.size()));
  state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
  state->BeginDictionary("global_state");
  global_state_.AsValueInto(state);
  state->EndDictionary();
}

std::unique_ptr<EvictionTilePriorityQueue>
TileManager::FreeTileResourcesUntilUsageIsWithinLimit(
    std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
    const MemoryUsage& limit,
    MemoryUsage* usage) {
  while (usage->Exceeds(limit)) {
    if (!eviction_priority_queue) {
      eviction_priority_queue =
          client_->BuildEvictionQueue(global_state_.tree_priority);
    }
    if (eviction_priority_queue->IsEmpty())
      break;

    Tile* tile = eviction_priority_queue->Top().tile();
    *usage -= MemoryUsage::FromTile(tile);
    FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
    eviction_priority_queue->Pop();
  }
  return eviction_priority_queue;
}

std::unique_ptr<EvictionTilePriorityQueue>
TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
    std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue,
    const MemoryUsage& limit,
    const TilePriority& other_priority,
    MemoryUsage* usage) {
  while (usage->Exceeds(limit)) {
    if (!eviction_priority_queue) {
      eviction_priority_queue =
          client_->BuildEvictionQueue(global_state_.tree_priority);
    }
    if (eviction_priority_queue->IsEmpty())
      break;

    const PrioritizedTile& prioritized_tile = eviction_priority_queue->Top();
    if (!other_priority.IsHigherPriorityThan(prioritized_tile.priority()))
      break;

    Tile* tile = prioritized_tile.tile();
    *usage -= MemoryUsage::FromTile(tile);
    FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
    eviction_priority_queue->Pop();
  }
  return eviction_priority_queue;
}

bool TileManager::TilePriorityViolatesMemoryPolicy(
    const TilePriority& priority) {
  switch (global_state_.memory_limit_policy) {
    case ALLOW_NOTHING:
      return true;
    case ALLOW_ABSOLUTE_MINIMUM:
      return priority.priority_bin > TilePriority::NOW;
    case ALLOW_PREPAINT_ONLY:
      return priority.priority_bin > TilePriority::SOON;
    case ALLOW_ANYTHING:
      return priority.distance_to_visible ==
             std::numeric_limits<float>::infinity();
  }
  NOTREACHED();
  return true;
}

TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
  TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");

  DCHECK(resource_pool_);
  DCHECK(tile_task_manager_);

  // Maintain the list of released resources that can potentially be re-used
  // or deleted. If this operation becomes expensive too, only do this after
  // some resource(s) was returned. Note that in that case, one also need to
  // invalidate when releasing some resource from the pool.
  resource_pool_->CheckBusyResources();

  // Now give memory out to the tiles until we're out, and build
  // the needs-to-be-rasterized queue.
  unsigned schedule_priority = 1u;
  all_tiles_that_need_to_be_rasterized_are_scheduled_ = true;
  bool had_enough_memory_to_schedule_tiles_needed_now = true;

  MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes,
                                global_state_.num_resources_limit);
  MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes,
                                global_state_.num_resources_limit);
  MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(),
                           resource_pool_->resource_count());

  std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue(
      client_->BuildRasterQueue(global_state_.tree_priority,
                                RasterTilePriorityQueue::Type::ALL));
  std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue;
  PrioritizedWorkToSchedule work_to_schedule;
  for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
    const PrioritizedTile& prioritized_tile = raster_priority_queue->Top();
    Tile* tile = prioritized_tile.tile();
    TilePriority priority = prioritized_tile.priority();

    if (TilePriorityViolatesMemoryPolicy(priority)) {
      TRACE_EVENT_INSTANT0(
          "cc", "TileManager::AssignGpuMemory tile violates memory policy",
          TRACE_EVENT_SCOPE_THREAD);
      break;
    }

    bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW;
    if (!tile->is_solid_color_analysis_performed() &&
        tile->use_picture_analysis() && kUseColorEstimator) {
      // We analyze for solid color here, to decide to continue
      // or drop the tile for scheduling and raster.
      // TODO(sohanjg): Check if we could use a shared analysis
      // canvas which is reset between tiles.
      tile->set_solid_color_analysis_performed(true);
      SkColor color = SK_ColorTRANSPARENT;
      bool is_solid_color =
          prioritized_tile.raster_source()->PerformSolidColorAnalysis(
              tile->content_rect(), tile->raster_scales(), &color);
      if (is_solid_color) {
        tile->draw_info().set_solid_color(color);
        tile->draw_info().set_was_ever_ready_to_draw();
        if (!tile_is_needed_now)
          tile->draw_info().set_was_a_prepaint_tile();
        client_->NotifyTileStateChanged(tile);
        continue;
      }
    }

    // Prepaint tiles that are far away are only processed for images.
    if (!tile->required_for_activation() && !tile->required_for_draw() &&
        prioritized_tile.is_process_for_images_only()) {
      work_to_schedule.tiles_to_process_for_images.push_back(prioritized_tile);
      continue;
    }

    // We won't be able to schedule this tile, so break out early.
    if (work_to_schedule.tiles_to_raster.size() >=
        scheduled_raster_task_limit_) {
      all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
      break;
    }

    tile->scheduled_priority_ = schedule_priority++;

    DCHECK(tile->draw_info().mode() == TileDrawInfo::OOM_MODE ||
           !tile->draw_info().IsReadyToDraw());

    // If the tile already has a raster_task, then the memory used by it is
    // already accounted for in memory_usage. Otherwise, we'll have to acquire
    // more memory to create a raster task.
    MemoryUsage memory_required_by_tile_to_be_scheduled;
    if (!tile->raster_task_.get()) {
      memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig(
          tile->desired_texture_size(), DetermineResourceFormat(tile));
    }

    // This is the memory limit that will be used by this tile. Depending on
    // the tile priority, it will be one of hard_memory_limit or
    // soft_memory_limit.
    MemoryUsage& tile_memory_limit =
        tile_is_needed_now ? hard_memory_limit : soft_memory_limit;

    const MemoryUsage& scheduled_tile_memory_limit =
        tile_memory_limit - memory_required_by_tile_to_be_scheduled;
    eviction_priority_queue =
        FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
            std::move(eviction_priority_queue), scheduled_tile_memory_limit,
            priority, &memory_usage);
    bool memory_usage_is_within_limit =
        !memory_usage.Exceeds(scheduled_tile_memory_limit);

    // If we couldn't fit the tile into our current memory limit, then we're
    // done.
    if (!memory_usage_is_within_limit) {
      if (tile_is_needed_now)
        had_enough_memory_to_schedule_tiles_needed_now = false;
      all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
      break;
    }

    memory_usage += memory_required_by_tile_to_be_scheduled;
    work_to_schedule.tiles_to_raster.push_back(prioritized_tile);

    // Since we scheduled the tile, set whether it was a prepaint or not
    // assuming that the tile will successfully finish running. We don't have
    // priority information at the time the tile completes, so it should be done
    // here.
    if (!tile_is_needed_now)
      tile->draw_info().set_was_a_prepaint_tile();
  }

  // Note that we should try and further reduce memory in case the above loop
  // didn't reduce memory. This ensures that we always release as many resources
  // as possible to stay within the memory limit.
  eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit(
      std::move(eviction_priority_queue), hard_memory_limit, &memory_usage);

  UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget",
                        !had_enough_memory_to_schedule_tiles_needed_now);
  did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now;

  memory_stats_from_last_assign_.total_budget_in_bytes =
      global_state_.hard_memory_limit_in_bytes;
  memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes();
  DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0);
  memory_stats_from_last_assign_.had_enough_memory =
      had_enough_memory_to_schedule_tiles_needed_now;

  TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles",
                   "all_tiles_that_need_to_be_rasterized_are_scheduled",
                   all_tiles_that_need_to_be_rasterized_are_scheduled_,
                   "had_enough_memory_to_schedule_tiles_needed_now",
                   had_enough_memory_to_schedule_tiles_needed_now);
  return work_to_schedule;
}

void TileManager::FreeResourcesForTile(Tile* tile) {
  TileDrawInfo& draw_info = tile->draw_info();
  if (draw_info.resource_) {
    resource_pool_->ReleaseResource(draw_info.resource_);
    draw_info.resource_ = nullptr;
  }
}

void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
    Tile* tile) {
  bool was_ready_to_draw = tile->draw_info().IsReadyToDraw();
  FreeResourcesForTile(tile);
  if (was_ready_to_draw)
    client_->NotifyTileStateChanged(tile);
}

void TileManager::ScheduleTasks(
    const PrioritizedWorkToSchedule& work_to_schedule) {
  const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized =
      work_to_schedule.tiles_to_raster;
  TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count",
               tiles_that_need_to_be_rasterized.size());

  DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_);

  if (!has_scheduled_tile_tasks_) {
    TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
  }

  // Cancel existing OnTaskSetFinished callbacks.
  task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs();

  // Even when scheduling an empty set of tiles, the TTWP does some work, and
  // will always trigger a DidFinishRunningTileTasks notification. Because of
  // this we unconditionally set |has_scheduled_tile_tasks_| to true.
  has_scheduled_tile_tasks_ = true;

  // Track the number of dependents for each *_done task.
  size_t required_for_activate_count = 0;
  size_t required_for_draw_count = 0;
  size_t all_count = 0;

  size_t priority = kTileTaskPriorityBase;

  graph_.Reset();

  gfx::ColorSpace color_space = client_->GetTileColorSpace();

  scoped_refptr<TileTask> required_for_activation_done_task =
      CreateTaskSetFinishedTask(
          &TileManager::DidFinishRunningTileTasksRequiredForActivation);
  scoped_refptr<TileTask> required_for_draw_done_task =
      CreateTaskSetFinishedTask(
          &TileManager::DidFinishRunningTileTasksRequiredForDraw);
  scoped_refptr<TileTask> all_done_task =
      CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks);

  // Build a new task queue containing all task currently needed. Tasks
  // are added in order of priority, highest priority task first.
  for (auto& prioritized_tile : tiles_that_need_to_be_rasterized) {
    Tile* tile = prioritized_tile.tile();

    DCHECK(tile->draw_info().requires_resource());
    DCHECK(!tile->draw_info().resource_);

    if (!tile->raster_task_)
      tile->raster_task_ = CreateRasterTask(prioritized_tile, color_space);

    TileTask* task = tile->raster_task_.get();

    DCHECK(!task->HasCompleted());

    if (tile->required_for_activation()) {
      required_for_activate_count++;
      graph_.edges.push_back(
          TaskGraph::Edge(task, required_for_activation_done_task.get()));
    }
    if (tile->required_for_draw()) {
      required_for_draw_count++;
      graph_.edges.push_back(
          TaskGraph::Edge(task, required_for_draw_done_task.get()));
    }
    all_count++;
    graph_.edges.push_back(TaskGraph::Edge(task, all_done_task.get()));

    // A tile should use a foreground task cateogry if it is either blocking
    // future compositing (required for draw or required for activation), or if
    // it has a priority bin of NOW for another reason (low resolution tiles).
    bool use_foreground_category =
        tile->required_for_draw() || tile->required_for_activation() ||
        prioritized_tile.priority().priority_bin == TilePriority::NOW;
    InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++,
                             use_foreground_category);
  }

  const std::vector<PrioritizedTile>& tiles_to_process_for_images =
      work_to_schedule.tiles_to_process_for_images;
  std::vector<DrawImage> new_locked_images;
  for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) {
    Tile* tile = prioritized_tile.tile();

    std::vector<DrawImage> images;
    prioritized_tile.raster_source()->GetDiscardableImagesInRect(
        tile->enclosing_layer_rect(), tile->raster_scales(), &images);
    new_locked_images.insert(new_locked_images.end(), images.begin(),
                             images.end());
  }

  // TODO(vmpstr): SOON is misleading here, but these images can come from
  // several diffent tiles. Rethink what we actually want to trace here. Note
  // that I'm using SOON, since it can't be NOW (these are prepaint).
  ImageDecodeController::TracingInfo tracing_info(prepare_tiles_count_,
                                                  TilePriority::SOON);
  std::vector<scoped_refptr<TileTask>> new_locked_image_tasks =
      image_manager_.SetPredecodeImages(std::move(new_locked_images),
                                        tracing_info);

  for (auto& task : new_locked_image_tasks) {
    auto decode_it = std::find_if(graph_.nodes.begin(), graph_.nodes.end(),
                                  [&task](const TaskGraph::Node& node) {
                                    return node.task == task.get();
                                  });
    // If this task is already in the graph, then we don't have to insert it.
    if (decode_it != graph_.nodes.end())
      continue;

    InsertNodeForDecodeTask(&graph_, task.get(), false, priority++);
    all_count++;
    graph_.edges.push_back(TaskGraph::Edge(task.get(), all_done_task.get()));
  }

  // The old locked images tasks have to stay around until past the
  // ScheduleTasks call below, so we do a swap instead of a move.
  // TODO(crbug.com/647402): Have the tile_task_manager keep a ref on the tasks,
  // since it makes it awkward for the callers to keep refs on tasks that only
  // exist within the task graph runner.
  locked_image_tasks_.swap(new_locked_image_tasks);

  // We must reduce the amount of unused resources before calling
  // ScheduleTasks to prevent usage from rising above limits.
  resource_pool_->ReduceResourceUsage();
  image_manager_.ReduceMemoryUsage();

  // Insert nodes for our task completion tasks. We enqueue these using
  // NONCONCURRENT_FOREGROUND category this is the highest prioirty category and
  // we'd like to run these tasks as soon as possible.
  InsertNodeForTask(&graph_, required_for_activation_done_task.get(),
                    TASK_CATEGORY_NONCONCURRENT_FOREGROUND,
                    kRequiredForActivationDoneTaskPriority,
                    required_for_activate_count);
  InsertNodeForTask(&graph_, required_for_draw_done_task.get(),
                    TASK_CATEGORY_NONCONCURRENT_FOREGROUND,
                    kRequiredForDrawDoneTaskPriority, required_for_draw_count);
  InsertNodeForTask(&graph_, all_done_task.get(),
                    TASK_CATEGORY_NONCONCURRENT_FOREGROUND,
                    kAllDoneTaskPriority, all_count);

  // Synchronize worker with compositor.
  raster_buffer_provider_->OrderingBarrier();

  // Schedule running of |raster_queue_|. This replaces any previously
  // scheduled tasks and effectively cancels all tasks not present
  // in |raster_queue_|.
  tile_task_manager_->ScheduleTasks(&graph_);

  // It's now safe to clean up orphan tasks as raster worker pool is not
  // allowed to keep around unreferenced raster tasks after ScheduleTasks() has
  // been called.
  orphan_tasks_.clear();

  // It's also now safe to replace our *_done_task_ tasks.
  required_for_activation_done_task_ =
      std::move(required_for_activation_done_task);
  required_for_draw_done_task_ = std::move(required_for_draw_done_task);
  all_done_task_ = std::move(all_done_task);

  did_check_for_completed_tasks_since_last_schedule_tasks_ = false;

  TRACE_EVENT_ASYNC_STEP_INTO1("cc", "ScheduledTasks", this, "running", "state",
                               ScheduledTasksStateAsValue());
}

scoped_refptr<TileTask> TileManager::CreateRasterTask(
    const PrioritizedTile& prioritized_tile,
    const gfx::ColorSpace& color_space) {
  Tile* tile = prioritized_tile.tile();

  // Get the resource.
  uint64_t resource_content_id = 0;
  Resource* resource = nullptr;
  gfx::Rect invalidated_rect = tile->invalidated_content_rect();
  if (UsePartialRaster() && tile->invalidated_id()) {
    resource = resource_pool_->TryAcquireResourceForPartialRaster(
        tile->id(), tile->invalidated_content_rect(), tile->invalidated_id(),
        &invalidated_rect);
  }

  if (resource) {
    resource_content_id = tile->invalidated_id();
    DCHECK_EQ(DetermineResourceFormat(tile), resource->format());
  } else {
    resource = resource_pool_->AcquireResource(tile->desired_texture_size(),
                                               DetermineResourceFormat(tile),
                                               color_space);
  }

  // For LOW_RESOLUTION tiles, we don't draw or predecode images.
  RasterSource::PlaybackSettings playback_settings;
  playback_settings.skip_images =
      prioritized_tile.priority().resolution == LOW_RESOLUTION;

  // Create and queue all image decode tasks that this tile depends on.
  TileTask::Vector decode_tasks;
  std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()];
  images.clear();
  if (!playback_settings.skip_images) {
    prioritized_tile.raster_source()->GetDiscardableImagesInRect(
        tile->enclosing_layer_rect(), tile->raster_scales(), &images);
  }

  // We can skip the image hijack canvas if we have no images.
  playback_settings.use_image_hijack_canvas = !images.empty();

  // Get the tasks for the required images.
  ImageDecodeController::TracingInfo tracing_info(
      prepare_tiles_count_, prioritized_tile.priority().priority_bin);
  image_manager_.GetTasksForImagesAndRef(&images, &decode_tasks, tracing_info);

  std::unique_ptr<RasterBuffer> raster_buffer =
      raster_buffer_provider_->AcquireBufferForRaster(
          resource, resource_content_id, tile->invalidated_id());
  return make_scoped_refptr(new RasterTaskImpl(
      this, tile, resource, prioritized_tile.raster_source(), playback_settings,
      prioritized_tile.priority().resolution, invalidated_rect,
      prepare_tiles_count_, std::move(raster_buffer), &decode_tasks,
      use_gpu_rasterization_));
}

void TileManager::OnRasterTaskCompleted(
    std::unique_ptr<RasterBuffer> raster_buffer,
    Tile* tile,
    Resource* resource,
    bool was_canceled) {
  DCHECK(tile);
  DCHECK(tiles_.find(tile->id()) != tiles_.end());
  raster_buffer_provider_->ReleaseBufferForRaster(std::move(raster_buffer));

  TileDrawInfo& draw_info = tile->draw_info();
  DCHECK(tile->raster_task_.get());
  orphan_tasks_.push_back(tile->raster_task_);
  tile->raster_task_ = nullptr;

  // Unref all the images.
  auto images_it = scheduled_draw_images_.find(tile->id());
  image_manager_.UnrefImages(images_it->second);
  scheduled_draw_images_.erase(images_it);

  if (was_canceled) {
    ++flush_stats_.canceled_count;
    resource_pool_->ReleaseResource(resource);
    return;
  }

  resource_pool_->OnContentReplaced(resource->id(), tile->id());
  ++flush_stats_.completed_count;

  draw_info.set_use_resource();
  draw_info.resource_ = resource;
  draw_info.contents_swizzled_ = DetermineResourceRequiresSwizzle(tile);

  DCHECK(draw_info.IsReadyToDraw());
  draw_info.set_was_ever_ready_to_draw();

  client_->NotifyTileStateChanged(tile);
}

ScopedTilePtr TileManager::CreateTile(const Tile::CreateInfo& info,
                                      int layer_id,
                                      int source_frame_number,
                                      int flags) {
  // We need to have a tile task worker pool to do anything meaningful with
  // tiles.
  DCHECK(tile_task_manager_);
  ScopedTilePtr tile(
      new Tile(this, info, layer_id, source_frame_number, flags));
  DCHECK(tiles_.find(tile->id()) == tiles_.end());

  tiles_[tile->id()] = tile.get();
  return tile;
}

bool TileManager::AreRequiredTilesReadyToDraw(
    RasterTilePriorityQueue::Type type) const {
  std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue(
      client_->BuildRasterQueue(global_state_.tree_priority, type));
  // It is insufficient to check whether the raster queue we constructed is
  // empty. The reason for this is that there are situations (rasterize on
  // demand) when the tile both needs raster and it's ready to draw. Hence, we
  // have to iterate the queue to check whether the required tiles are ready to
  // draw.
  for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
    if (!raster_priority_queue->Top().tile()->draw_info().IsReadyToDraw())
      return false;
  }

#if DCHECK_IS_ON()
  std::unique_ptr<RasterTilePriorityQueue> all_queue(
      client_->BuildRasterQueue(global_state_.tree_priority, type));
  for (; !all_queue->IsEmpty(); all_queue->Pop()) {
    Tile* tile = all_queue->Top().tile();
    DCHECK(!tile->required_for_activation() ||
           tile->draw_info().IsReadyToDraw());
  }
#endif
  return true;
}

bool TileManager::IsReadyToActivate() const {
  TRACE_EVENT0("cc", "TileManager::IsReadyToActivate");
  return AreRequiredTilesReadyToDraw(
      RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
}

bool TileManager::IsReadyToDraw() const {
  TRACE_EVENT0("cc", "TileManager::IsReadyToDraw");
  return AreRequiredTilesReadyToDraw(
      RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
}

void TileManager::CheckAndIssueSignals() {
  TRACE_EVENT0("cc", "TileManager::CheckAndIssueSignals");
  tile_task_manager_->CheckForCompletedTasks();
  did_check_for_completed_tasks_since_last_schedule_tasks_ = true;

  // Ready to activate.
  if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) {
    signals_.ready_to_activate = false;
    if (IsReadyToActivate()) {
      TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                   "TileManager::CheckAndIssueSignals - ready to activate");
      signals_.did_notify_ready_to_activate = true;
      client_->NotifyReadyToActivate();
    }
  }

  // Ready to draw.
  if (signals_.ready_to_draw && !signals_.did_notify_ready_to_draw) {
    signals_.ready_to_draw = false;
    if (IsReadyToDraw()) {
      TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                   "TileManager::CheckAndIssueSignals - ready to draw");
      signals_.did_notify_ready_to_draw = true;
      client_->NotifyReadyToDraw();
    }
  }

  // All tile tasks completed.
  if (signals_.all_tile_tasks_completed &&
      !signals_.did_notify_all_tile_tasks_completed) {
    signals_.all_tile_tasks_completed = false;
    if (!has_scheduled_tile_tasks_) {
      TRACE_EVENT0(
          TRACE_DISABLED_BY_DEFAULT("cc.debug"),
          "TileManager::CheckAndIssueSignals - all tile tasks completed");
      signals_.did_notify_all_tile_tasks_completed = true;
      client_->NotifyAllTileTasksCompleted();
    }
  }
}

void TileManager::CheckIfMoreTilesNeedToBePrepared() {
  tile_task_manager_->CheckForCompletedTasks();
  did_check_for_completed_tasks_since_last_schedule_tasks_ = true;

  // When OOM, keep re-assigning memory until we reach a steady state
  // where top-priority tiles are initialized.
  PrioritizedWorkToSchedule work_to_schedule = AssignGpuMemoryToTiles();

  // Inform the client that will likely require a draw if the highest priority
  // tile that will be rasterized is required for draw.
  client_->SetIsLikelyToRequireADraw(
      !work_to_schedule.tiles_to_raster.empty() &&
      work_to_schedule.tiles_to_raster.front().tile()->required_for_draw());

  // |tiles_that_need_to_be_rasterized| will be empty when we reach a
  // steady memory state. Keep scheduling tasks until we reach this state.
  if (!work_to_schedule.tiles_to_raster.empty()) {
    ScheduleTasks(work_to_schedule);
    return;
  }

  // If we're not in SMOOTHNESS_TAKES_PRIORITY  mode, we should unlock all
  // images since we're technically going idle here at least for this frame.
  if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) {
    image_manager_.SetPredecodeImages(std::vector<DrawImage>(),
                                      ImageDecodeController::TracingInfo());
    locked_image_tasks_.clear();
  }

  FreeResourcesForReleasedTiles();

  resource_pool_->ReduceResourceUsage();
  image_manager_.ReduceMemoryUsage();

  // TODO(vmpstr): Temporary check to debug crbug.com/642927.
  CHECK(tile_task_manager_);
  signals_.all_tile_tasks_completed = true;
  signals_check_notifier_.Schedule();

  // We don't reserve memory for required-for-activation tiles during
  // accelerated gestures, so we just postpone activation when we don't
  // have these tiles, and activate after the accelerated gesture.
  // Likewise if we don't allow any tiles (as is the case when we're
  // invisible), if we have tiles that aren't ready, then we shouldn't
  // activate as activation can cause checkerboards.
  bool wait_for_all_required_tiles =
      global_state_.tree_priority == SMOOTHNESS_TAKES_PRIORITY ||
      global_state_.memory_limit_policy == ALLOW_NOTHING;

  // If we have tiles left to raster for activation, and we don't allow
  // activating without them, then skip activation and return early.
  if (wait_for_all_required_tiles)
    return;

  // Mark any required tiles that have not been been assigned memory after
  // reaching a steady memory state as OOM. This ensures that we activate/draw
  // even when OOM. Note that we can't reuse the queue we used for
  // AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call could have
  // evicted some tiles that would not be picked up by the old raster queue.
  bool need_to_signal_activate = MarkTilesOutOfMemory(client_->BuildRasterQueue(
      global_state_.tree_priority,
      RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION));
  bool need_to_signal_draw = MarkTilesOutOfMemory(client_->BuildRasterQueue(
      global_state_.tree_priority,
      RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW));

  // TODO(vmpstr): Temporary check to debug crbug.com/642927.
  CHECK(tile_task_manager_);
  DCHECK(IsReadyToActivate());
  DCHECK(IsReadyToDraw());
  // Signals notifier is already scheduled above in the same function.
  signals_.ready_to_activate = need_to_signal_activate;
  signals_.ready_to_draw = need_to_signal_draw;
}

bool TileManager::MarkTilesOutOfMemory(
    std::unique_ptr<RasterTilePriorityQueue> queue) const {
  // Mark required tiles as OOM so that we can activate/draw without them.
  if (queue->IsEmpty())
    return false;

  for (; !queue->IsEmpty(); queue->Pop()) {
    Tile* tile = queue->Top().tile();
    if (tile->draw_info().IsReadyToDraw())
      continue;
    tile->draw_info().set_oom();
    client_->NotifyTileStateChanged(tile);
  }
  return true;
}

ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const {
  return raster_buffer_provider_->GetResourceFormat(!tile->is_opaque());
}

bool TileManager::DetermineResourceRequiresSwizzle(const Tile* tile) const {
  return raster_buffer_provider_->IsResourceSwizzleRequired(!tile->is_opaque());
}

std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
TileManager::ScheduledTasksStateAsValue() const {
  std::unique_ptr<base::trace_event::TracedValue> state(
      new base::trace_event::TracedValue());
  state->BeginDictionary("tasks_pending");
  state->SetBoolean("ready_to_activate", signals_.ready_to_activate);
  state->SetBoolean("ready_to_draw", signals_.ready_to_draw);
  state->SetBoolean("all_tile_tasks_completed",
                    signals_.all_tile_tasks_completed);
  state->EndDictionary();
  return std::move(state);
}

bool TileManager::UsePartialRaster() const {
  return use_partial_raster_ &&
         raster_buffer_provider_->CanPartialRasterIntoProvidedResource();
}

// Utility function that can be used to create a "Task set finished" task that
// posts |callback| to |task_runner| when run.
scoped_refptr<TileTask> TileManager::CreateTaskSetFinishedTask(
    void (TileManager::*callback)()) {
  return make_scoped_refptr(new TaskSetFinishedTaskImpl(
      task_runner_,
      base::Bind(callback, task_set_finished_weak_ptr_factory_.GetWeakPtr())));
}

TileManager::MemoryUsage::MemoryUsage()
    : memory_bytes_(0), resource_count_(0) {}

TileManager::MemoryUsage::MemoryUsage(size_t memory_bytes,
                                      size_t resource_count)
    : memory_bytes_(static_cast<int64_t>(memory_bytes)),
      resource_count_(static_cast<int>(resource_count)) {
  // MemoryUsage is constructed using size_ts, since it deals with memory and
  // the inputs are typically size_t. However, during the course of usage (in
  // particular operator-=) can cause internal values to become negative. Thus,
  // member variables are signed.
  DCHECK_LE(memory_bytes,
            static_cast<size_t>(std::numeric_limits<int64_t>::max()));
  DCHECK_LE(resource_count,
            static_cast<size_t>(std::numeric_limits<int>::max()));
}

// static
TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig(
    const gfx::Size& size,
    ResourceFormat format) {
  // We can use UncheckedSizeInBytes here since this is used with a tile
  // size which is determined by the compositor (it's at most max texture size).
  return MemoryUsage(ResourceUtil::UncheckedSizeInBytes<size_t>(size, format),
                     1);
}

// static
TileManager::MemoryUsage TileManager::MemoryUsage::FromTile(const Tile* tile) {
  const TileDrawInfo& draw_info = tile->draw_info();
  if (draw_info.resource_) {
    return MemoryUsage::FromConfig(draw_info.resource_->size(),
                                   draw_info.resource_->format());
  }
  return MemoryUsage();
}

TileManager::MemoryUsage& TileManager::MemoryUsage::operator+=(
    const MemoryUsage& other) {
  memory_bytes_ += other.memory_bytes_;
  resource_count_ += other.resource_count_;
  return *this;
}

TileManager::MemoryUsage& TileManager::MemoryUsage::operator-=(
    const MemoryUsage& other) {
  memory_bytes_ -= other.memory_bytes_;
  resource_count_ -= other.resource_count_;
  return *this;
}

TileManager::MemoryUsage TileManager::MemoryUsage::operator-(
    const MemoryUsage& other) {
  MemoryUsage result = *this;
  result -= other;
  return result;
}

bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const {
  return memory_bytes_ > limit.memory_bytes_ ||
         resource_count_ > limit.resource_count_;
}

TileManager::Signals::Signals() {
  reset();
}

void TileManager::Signals::reset() {
  ready_to_activate = false;
  did_notify_ready_to_activate = false;
  ready_to_draw = false;
  did_notify_ready_to_draw = false;
  all_tile_tasks_completed = false;
  did_notify_all_tile_tasks_completed = false;
}

TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule() = default;
TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule(
    PrioritizedWorkToSchedule&& other) = default;
TileManager::PrioritizedWorkToSchedule::~PrioritizedWorkToSchedule() = default;

}  // namespace cc


text:
require "formula"

class AppscaleTools < Formula
  homepage 'https://github.com/AppScale/appscale-tools'
  url "https://github.com/AppScale/appscale-tools/archive/1.14.0.tar.gz"
  sha1 "ee2363bf6b8f464f0a7847d965e5fce2e143acd2"
  head "https://github.com/AppScale/appscale-tools.git"

  depends_on :python if MacOS.version <= :snow_leopard
  depends_on 'libyaml'

  resource 'termcolor' do
    url 'https://pypi.python.org/packages/source/t/termcolor/termcolor-1.1.0.tar.gz'
    sha1 '52045880a05c0fbd192343d9c9aad46a73d20e8c'
  end

  resource 'SOAPpy' do
    url 'https://pypi.python.org/packages/source/S/SOAPpy/SOAPpy-0.12.5.tar.gz'
    sha1 'dd2245aced212a7e333a594c8b4be5cf4d1c89ff'
  end

  resource 'pyyaml' do
    url 'https://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.10.tar.gz'
    sha1 '476dcfbcc6f4ebf3c06186229e8e2bd7d7b20e73'
  end

  resource 'boto' do
    url 'https://pypi.python.org/packages/source/b/boto/boto-2.23.0.tar.gz'
    sha1 'f09be44dfbc2601c523272eff424b947f9551146'
  end

  resource 'argparse' do
    url 'https://argparse.googlecode.com/files/argparse-1.2.1.tar.gz'
    sha1 'caadac82aa2576d6b445058c1fcf6ef0b14dbaa1'
  end

  resource 'oauth2client' do
    url 'https://pypi.python.org/packages/source/o/oauth2client/oauth2client-1.2.tar.gz'
    sha1 'd38bf2d5392e4e4eea66b039a408079f6fe008d0'
  end

  resource 'google-api-python-client' do
    url 'https://pypi.python.org/packages/source/g/google-api-python-client/google-api-python-client-1.2.tar.gz'
    sha1 '31ddb6e125b0683d29493c9f486d48a4f63c913b'
  end

  resource 'httplib2' do
    url 'https://pypi.python.org/packages/source/h/httplib2/httplib2-0.8.tar.gz'
    sha1 '3821350a9612b3e1fb382d55484b2465cb8fb9c5'
  end

  resource 'python-gflags' do
    url 'https://pypi.python.org/packages/source/p/python-gflags/python-gflags-2.0.tar.gz'
    sha1 '1529a1102da2fc671f2a9a5e387ebabd1ceacbbf'
  end

  def install
    ENV.prepend_create_path 'PYTHONPATH', libexec+'lib/python2.7/site-packages'
    install_args = [ "setup.py", "install", "--prefix=#{libexec}" ]

    resource('termcolor').stage { system "python", *install_args }
    resource('pyyaml').stage { system "python", *install_args }
    resource('SOAPpy').stage { system "python", *install_args }
    resource('boto').stage { system "python", *install_args }
    resource('argparse').stage { system "python", *install_args }
    resource('oauth2client').stage { system "python", *install_args }
    resource('google-api-python-client').stage { system "python", *install_args }
    resource('httplib2').stage { system "python", *install_args }
    resource('python-gflags').stage { system "python", *install_args }

    inreplace Dir["bin/appscale*"] do |s|
      s.gsub! /^lib = os.*/, "lib = '#{libexec}'"
    end

    prefix.install 'bin', 'templates', 'LICENSE', 'README.md'
    libexec.install Dir['lib/*']

    bin.env_script_all_files(libexec+'bin', :PYTHONPATH => "#{libexec}/lib/python2.7/site-packages")
  end

  test do
    system bin/'appscale', 'help'
  end
end

redpajama_set_name: RedPajamaGithub


text:
<?php

session_start();
require_once "include/beContent.inc.php";
require_once(realpath(dirname(__FILE__)).'/include/view/template/InitGraphic.php');
//require_once(realpath(dirname(__FILE__)) . '/contents/system/entities/entitySlider.php');
/* recupero delle entity necessarie */
$sliderEntity = $GLOBALS['sys_slider'];
$imageEntity = $GLOBALS['sys_image'];
$imageSliderRelation = $GLOBALS['sys_image_sys_slider'];
$offertaEntity = $GLOBALS[Config::getInstance()->getConfigurations()['database']['prefix'].'offerta'];
$cameraEntity = $GLOBALS[Config::getInstance()->getConfigurations()['database']['prefix'].'room'];
$main = new Skin("theme");
InitGraphic::getInstance()->createGraphic($main);

$welcomePage = new Skinlet('welcome');
$page = new Content($pageEntity, $imageEntity);
$page->setFilter('title', 'Il B&B');
$page->forceSingle();
$page->apply($welcomePage);

$offertaPage = new Skinlet("offerta_home");
$offertaContent = new Content($offertaEntity);
$offertaContent->setLimit(1);
$offertaContent->setOrderFields("id DESC");
$offertaContent->forceSingle();
$offertaContent->apply($offertaPage);

$servicePage = new Skinlet('servizi_offerti');
$page2 = new Content($serviziCameraEntity);
$page2->setLimit(7);
$page2->apply($servicePage);

$homeTemplate = new Skinlet("home");
$homeTemplate->setContent("welcomePage", $welcomePage->get());
$homeTemplate->setContent("servicePage", $servicePage->get());
$homeTemplate->setContent("offertaPage", $offertaPage->get());

/*skinlet slider: skins/theme/sliderHome.html*/
$sliderTemplate = new Skinlet('sliderHome');
$slider = new Content($sliderEntity, $imageSliderRelation, $imageEntity);
$slider->forceSingle();
$slider->setFilter('titolo', 'sliderHome');
$slider->apply($sliderTemplate, 'slider');

/*retrieve all room*/
$cameraContent = new Content($cameraEntity);
$cameraContent->apply($sliderTemplate,'room');

$main->setContent('slider', $sliderTemplate->get());
$main->setContent("body", $homeTemplate->get());

$main->close();


text:
cask v1: 'sqlworkbenchj' do
  version '117'
  sha256 '3d9698c9a0c8e939789e3407c55dfbd963e73cd430e5caf8d66627abae5a14d7'

  url "http://www.sql-workbench.net/Workbench-Build#{version}-MacJava7.tgz"
  name 'SQL Workbench/J'
  homepage 'http://www.sql-workbench.net'
  license :apache

  app 'SQLWorkbenchJ.app'

  caveats <<-EOS.undent
    #{token} requires Java. You can install the latest version with
      brew cask install java
  EOS
end


text:
package com.iluwatar.poison.pill;

import com.iluwatar.poison.pill.Message.Headers;

/**
 * Class responsible for receiving and handling submitted to the queue messages
 */
public class Consumer {

  private final MqSubscribePoint queue;
  private final String name;

  public Consumer(String name, MqSubscribePoint queue) {
    this.name = name;
    this.queue = queue;
  }

  /**
   * Consume message
   */
  public void consume() {
    while (true) {
      Message msg;
      try {
        msg = queue.take();
        if (msg == Message.POISON_PILL) {
          System.out.println(String.format("Consumer %s receive request to terminate.", name));
          break;
        }
      } catch (InterruptedException e) {
        // allow thread to exit
        System.err.println(e);
        return;
      }

      String sender = msg.getHeader(Headers.SENDER);
      String body = msg.getBody();
      System.out.println(String.format("Message [%s] from [%s] received by [%s]", body, sender,
          name));
    }
  }
}


text:
from arffreader.ArffProcessor import ArffProcessor, utils

class NaiveBayesClassifier():
    def __init__(self, training_arff):
        if not isinstance(training_arff, ArffProcessor):
            raise TypeError("The training_arff argument must be an ArffProcessor")
        self.arff = training_arff

    def build_model(self, core_attribute):
        # Make sure that the core_attribute to classify on is categorical
        if not isinstance(self.arff.attributes[self.arff.attr_position[core_attribute]][1], list):
            raise TypeError("The core_attribute must be categorical")
        self.core_attribute = core_attribute
        # Compute all of the probabilities
        self.core_probabilities = {}
        for attr_value in self.arff.attributes[self.arff.attr_position[core_attribute]][1]:
            self.core_probabilities[attr_value] = 0
        for entry in self.arff.data:
            entry_core_value = entry[self.arff.attr_position[core_attribute]]
            self.core_probabilities[entry_core_value] += 1
        # Compute the attribute value probabilities
        self.probabilities = {}
        for core_value in self.arff.attributes[self.arff.attr_position[core_attribute]][1]:
            self.probabilities[core_value] = {}
            for attribute in self.arff.attributes:
                # Make sure we are not on the core attribute
                attr_name = attribute[0]
                if attr_name != self.core_attribute:
                    for attr_value in attribute[1]:
                        self.probabilities[core_value][attr_value] = 0.5
                        # We set .5 to prevent 0 probabilities from destroying everything
                        # "Data Smoothing" - Google it man
        for entry in self.arff.data:
            entry_core_value = entry[self.arff.attr_position[self.core_attribute]]
            for i in range(len(entry)):
                if i != self.arff.attr_position[self.core_attribute]:
                    entry_attr_value = entry[i]
                    self.probabilities[entry_core_value][entry_attr_value] += 1

    def pc(self, core_attribute_value):
        return self.core_probabilities[core_attribute_value] / len(self.arff.data)

    def pxc(self, attr_value, core_attribute_value):
        # The following smooths these probabilities
        if self.core_probabilities[core_attribute_value] == 0:
            return self.probabilities[core_attribute_value][attr_value]
        else:
            return self.probabilities[core_attribute_value][attr_value]/self.core_probabilities[core_attribute_value]

    def classify_record(self, record):
        """Record is an array that must match the format of the arff data records"""
        classifications = {}
        for core_value in self.arff.attributes[self.arff.attr_position[self.core_attribute]][1]:
            classifications[core_value] = self.pc(core_value)
            for i in range(len(record)):
                if i != self.arff.attr_position[self.core_attribute]:
                    classifications[core_value] *= self.pxc(record[i], core_value)
        best_classifier = ""
        best_classifier_score = 0
        for core_value in classifications:
            if classifications[core_value] > best_classifier_score:
                best_classifier_score = classifications[core_value]
                best_classifier = core_value
        return best_classifier


text:
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "handle_scope-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "scoped_thread_state_change.h"

namespace art {
namespace gc {

class HeapTest : public CommonRuntimeTest {};

TEST_F(HeapTest, ClearGrowthLimit) {
  Heap* heap = Runtime::Current()->GetHeap();
  int64_t max_memory_before = heap->GetMaxMemory();
  int64_t total_memory_before = heap->GetTotalMemory();
  heap->ClearGrowthLimit();
  int64_t max_memory_after = heap->GetMaxMemory();
  int64_t total_memory_after = heap->GetTotalMemory();
  EXPECT_GE(max_memory_after, max_memory_before);
  EXPECT_GE(total_memory_after, total_memory_before);
}

TEST_F(HeapTest, GarbageCollectClassLinkerInit) {
  {
    ScopedObjectAccess soa(Thread::Current());
    // garbage is created during ClassLinker::Init

    StackHandleScope<1> hs(soa.Self());
    Handle<mirror::Class> c(
        hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
    for (size_t i = 0; i < 1024; ++i) {
      StackHandleScope<1> hs2(soa.Self());
      Handle<mirror::ObjectArray<mirror::Object>> array(hs2.NewHandle(
          mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), 2048)));
      for (size_t j = 0; j < 2048; ++j) {
        mirror::String* string = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!");
        // handle scope operator -> deferences the handle scope before running the method.
        array->Set<false>(j, string);
      }
    }
  }
  Runtime::Current()->GetHeap()->CollectGarbage(false);
}

TEST_F(HeapTest, HeapBitmapCapacityTest) {
  uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x1000);
  const size_t heap_capacity = kObjectAlignment * (sizeof(intptr_t) * 8 + 1);
  std::unique_ptr<accounting::ContinuousSpaceBitmap> bitmap(
      accounting::ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
  mirror::Object* fake_end_of_heap_object =
      reinterpret_cast<mirror::Object*>(&heap_begin[heap_capacity - kObjectAlignment]);
  bitmap->Set(fake_end_of_heap_object);
}

class ZygoteHeapTest : public CommonRuntimeTest {
  void SetUpRuntimeOptions(RuntimeOptions* options) {
    CommonRuntimeTest::SetUpRuntimeOptions(options);
    options->push_back(std::make_pair("-Xzygote", nullptr));
  }
};

TEST_F(ZygoteHeapTest, PreZygoteFork) {
  // Exercise Heap::PreZygoteFork() to check it does not crash.
  Runtime::Current()->GetHeap()->PreZygoteFork();
}

}  // namespace gc
}  // namespace art


text:
<?php
class OpenSearch_Block_Meta extends Mage_Core_Block_Template {
  public function getOpenSearchUrl() {
    return '/opensearch';
  }

  public function getTitle() {
    return Mage::app()->getStore()->getName();
  }
}


text:
#import "DynamoDBTableDescription.h"

@implementation DynamoDBTableDescription

@synthesize attributeDefinitions;
@synthesize tableName;
@synthesize keySchema;
@synthesize tableStatus;
@synthesize creationDateTime;
@synthesize provisionedThroughput;
@synthesize tableSizeBytes;
@synthesize itemCount;
@synthesize localSecondaryIndexes;
@synthesize globalSecondaryIndexes;

-(id)init
{
    if (self = [super init]) {
        attributeDefinitions   = [[NSMutableArray alloc] initWithCapacity:1];
        tableName              = nil;
        keySchema              = [[NSMutableArray alloc] initWithCapacity:1];
        tableStatus            = nil;
        creationDateTime       = nil;
        provisionedThroughput  = nil;
        tableSizeBytes         = nil;
        itemCount              = nil;
        localSecondaryIndexes  = [[NSMutableArray alloc] initWithCapacity:1];
        globalSecondaryIndexes = [[NSMutableArray alloc] initWithCapacity:1];
    }

    return self;
}

-(void)addAttributeDefinition:(DynamoDBAttributeDefinition *)attributeDefinitionObject
{
    if (attributeDefinitions == nil) {
        attributeDefinitions = [[NSMutableArray alloc] initWithCapacity:1];
    }

    [attributeDefinitions addObject:attributeDefinitionObject];
}

-(void)addKeySchema:(DynamoDBKeySchemaElement *)keySchemaObject
{
    if (keySchema == nil) {
        keySchema = [[NSMutableArray alloc] initWithCapacity:1];
    }

    [keySchema addObject:keySchemaObject];
}

-(void)addLocalSecondaryIndexe:(DynamoDBLocalSecondaryIndexDescription *)localSecondaryIndexeObject
{
    if (localSecondaryIndexes == nil) {
        localSecondaryIndexes = [[NSMutableArray alloc] initWithCapacity:1];
    }

    [localSecondaryIndexes addObject:localSecondaryIndexeObject];
}

-(void)addGlobalSecondaryIndexe:(DynamoDBGlobalSecondaryIndexDescription *)globalSecondaryIndexeObject
{
    if (globalSecondaryIndexes == nil) {
        globalSecondaryIndexes = [[NSMutableArray alloc] initWithCapacity:1];
    }

    [globalSecondaryIndexes addObject:globalSecondaryIndexeObject];
}

-(NSString *)description
{
    NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity:256];

    [buffer appendString:@"{"];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"AttributeDefinitions: %@,", attributeDefinitions] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"TableName: %@,", tableName] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"KeySchema: %@,", keySchema] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"TableStatus: %@,", tableStatus] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"CreationDateTime: %@,", creationDateTime] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"ProvisionedThroughput: %@,", provisionedThroughput] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"TableSizeBytes: %@,", tableSizeBytes] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"ItemCount: %@,", itemCount] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"LocalSecondaryIndexes: %@,", localSecondaryIndexes] autorelease]];
    [buffer appendString:[[[NSString alloc] initWithFormat:@"GlobalSecondaryIndexes: %@,", globalSecondaryIndexes] autorelease]];
    [buffer appendString:[super description]];
    [buffer appendString:@"}"];

    return [buffer autorelease];
}

-(void)dealloc
{
    [attributeDefinitions release];
    [tableName release];
    [keySchema release];
    [tableStatus release];
    [creationDateTime release];
    [provisionedThroughput release];
    [tableSizeBytes release];
    [itemCount release];
    [localSecondaryIndexes release];
    [globalSecondaryIndexes release];

    [super dealloc];
}

@end


text:
template <class To, class From>
To safe_reinterpret_cast(From from)
{
    STATIC_CHECK(sizeof(From) <= sizeof(To));
    return reinterpret_cast<To>(from);
}

int main() {
    int intValue = 5;
    char c = safe_reinterpret_cast<char>(intValue);

    return 0;
}


text:
var vscode = require('vscode');
var opener = require('opener');
var resultTodo;
var Workspace = vscode.workspace;
var Window = vscode.window;
var Commands = vscode.commands;
var Languages = vscode.languages;
var issue = 'https://github.com/MattiasPernhult/vscode-todo/issues';
var statusBarItem;
var usersChoosenLanguage;
var usersWorkspaceConfig;
var configurationChanged;
var openBrowser = Commands.registerCommand('extension.openBrowser', function() {
    opener(issue);
});

var language = require('./language');
var helper = require('./helper');

function activate(context) {

    if (statusBarItem === undefined) {
        statusBarItem = helper.createStatusBarItem();
    }

    usersWorkspaceConfig = helper.getUsersWorkspaceConfigurations();

    // need to register listener for when workspace configurations is changed because
    // it may change which file to exclude when searching for todo:s
    Workspace.onDidChangeConfiguration(function() {
        console.log('onDidChangeConfiguration')
        usersWorkspaceConfig = helper.getUsersWorkspaceConfigurations();
        configurationChanged = true;
    });

    setDefaultValues();

    var disposable = Commands.registerCommand('extension.chooseLanguageTodo', function() {
        var availableLanguages = language.allName;

        Window.showQuickPick(availableLanguages, {}).then(function(userLanguage) {
            if (userLanguage === undefined) {
                return;
            }
            usersChoosenLanguage = userLanguage;
            if (!statusBarItem) {
                statusBarItem = helper.createStatusBarItem();
            }
            if (language === 'All') {
                statusBarItem.text = 'TODO:s';
            } else {
                statusBarItem.text = 'TODO:s for ' + usersChoosenLanguage;
            }
            statusBarItem.tooltip = 'Show TODO:s for ' + usersChoosenLanguage;
        });
    });

    var openQuickPick = Commands.registerCommand('extension.showTodos', function() {
        var fileExtensionForLanguage = helper.getFileExtensionForLanguage(usersChoosenLanguage);
        var fileExcludeForLanguage = helper.getFileExludeForLanguage(usersChoosenLanguage, usersWorkspaceConfig);
        var scanRegex = helper.getScanRegexForLanguage(usersChoosenLanguage, usersWorkspaceConfig);
        console.log(fileExcludeForLanguage);
        configurationChanged = false;
        helper.findFiles(fileExtensionForLanguage, fileExcludeForLanguage, usersChoosenLanguage, scanRegex, foundFiles);
    });
    context.subscriptions.push(openQuickPick);
    context.subscriptions.push(disposable);
}

var foundFiles = function(err, todos, todosList) {
    if (err) {
        console.log(err);
        return;
    }
    if (todosList.length === 0) {
        Window.showInformationMessage('Couldn\'t find any TODO:s when searching in **' + usersChoosenLanguage + '** files');
        return;
    }
    Window.showQuickPick(todosList, {}).then(function(response) {
        if (!response) return;
        var nameSplit = String(response.fileName);
        var file = 'file://' + nameSplit;
        var fileUri = vscode.Uri.parse(file);
        Workspace.openTextDocument(fileUri).then(function(textDocument) {
            Window.showTextDocument(textDocument, vscode.ViewColumn.One).then(function(textEditor) {
                var line = response.line;
                var resultObjects = todos[nameSplit];
                var startPos;
                var endPos;
                for (var i = 0; i < resultObjects.length; i++) {
                    var object = resultObjects[i];
                    if (object.line === line) {
                        startPos = new vscode.Position(object.line, 0);
                        endPos = new vscode.Position(object.line, 100);
                        break;
                    }
                }
                var newSelection = new vscode.Selection(startPos, endPos);
                Window.activeTextEditor.selection = newSelection;
                Window.activeTextEditor.revealRange(newSelection, vscode.TextEditorRevealType.InCenter);
            });
        });
    });
};

function setDefaultValues() {
    usersChoosenLanguage = 'All';
    configurationChanged = true;
    findUsersFileExcludes = '';
}

exports.activate = activate;


text:
import test from 'tape';
import createBootstrapImport from '../../../src/utils/createBootstrapImport';

test('createBootstrapImport creates valid import address for Bootstrap 2', (assert) => {
  assert.equals(createBootstrapImport('module', 2, '/'), '@import "/scss/_module";');
  assert.end();
});

test('createBootstrapImport creates valid import address for Bootstrap 3', (assert) => {
  assert.equals(
    createBootstrapImport('module', 3, '/'),
    '@import "/assets/stylesheets/bootstrap/_module";'
  );
  assert.end();
});


text:
using HomeCinema.Entities;

namespace HomeCinema.Data.Configurations
{
    public class CustomerConfiguration : EntityBaseConfiguration<Customer>
    {
        public CustomerConfiguration()
        {
            Property(u => u.FirstName).IsRequired().HasMaxLength(100);
            Property(u => u.LastName).IsRequired().HasMaxLength(100);
            Property(u => u.IdentityCard).IsRequired().HasMaxLength(50);
            Property(u => u.UniqueKey).IsRequired();
            Property(c => c.Mobile).HasMaxLength(10);
            Property(c => c.Email).IsRequired().HasMaxLength(200);
            Property(c => c.DateOfBirth).IsRequired();
        }
    }
}


text:
'use strict';

describe('lib/helpers/block', function() {
    var block;
    var handlebars = require('handlebars');
    var helpers = require('../../../../helpers');

    var SafeString = handlebars.SafeString;
    var template = helpers.template;

    function makeOptions(hash, fn, inverse) {
        return {
            fn: fn || function() {
                return true;
            },
            hash: hash || {},
            inverse: inverse || function() {
                return false;
            }
        };
    }

    helpers.setup();
    block = require('../../../../../lib/helpers/block');

    it('should export a function', function() {
        expect(block).toBeFunction();
    });

    it('should return an object', function() {
        expect(block(template)).toBeObject();
    });

    describe('helpers', function() {
        var instance = block(template);

        function testBlockHelper(helper, args, hash) {
            var result;
            var options = makeOptions(hash);

            args = args || [];
            args.push(options);

            result = instance[helper].apply(instance, args);

            return result;
        }

        describe('all', function() {
            it('should use the inverse condition for an empty list of items', function() {
                var result = testBlockHelper('all', [], {});

                expect(result).toBeFalse();
            });

            it('should use the normal condition for a list of truthy items', function() {
                var result = testBlockHelper('all', [true, 7], {});

                expect(result).toBeTrue();
            });

            it('should use the inverse condition for a list that contains a falsy item', function() {
                var result = testBlockHelper('all', [true, ''], {});

                expect(result).toBeFalse();
            });
        });

        describe('any', function() {
            it('should use the inverse condition for an empty list of items', function() {
                var result = testBlockHelper('any', [[]], {});

                expect(result).toBeFalse();
            });

            it('should use the normal condition for a list of truthy items', function() {
                var result = testBlockHelper('any', [[true, 7]], {});

                expect(result).toBeTrue();
            });

            it('should use the normal condition for a list with truthy and falsy items', function() {
                var result = testBlockHelper('any', [[true, '']], {});

                expect(result).toBeTrue();
            });

            it('should use the normal condition for a list of falsy items', function() {
                var result = testBlockHelper('any', [[false, '']], {});

                expect(result).toBeTrue();
            });
        });

        describe('blockHelperMissing', function() {
            it('should throw an error when called', function() {
                function callMissing() {
                    return instance.blockHelperMissing({});
                }

                expect(callMissing).toThrow();
            });

            it('should include the missing block name in the error message', function() {
                try {
                    instance.blockHelperMissing({name: 'foo'});
                } catch (e) {
                    expect(e.message).toContain('foo');
                }
            });
        });

        describe('contains', function() {
            it('should throw an error if called without a value to search for', function() {
                function callWithoutValue() {
                    return instance.contains({
                        hash: {}
                    });
                }

                expect(callWithoutValue).toThrow();
            });

            it('should say that an empty list of search terms does not contain the value', function() {
                var result = testBlockHelper('contains', [], {
                    value: 'foo'
                });

                expect(result).toBeFalse();
            });

            it('should say that a list of search terms with no match does not contain the value', function() {
                var result = testBlockHelper('contains', ['bar', 'baz'], {
                    value: 'foo'
                });

                expect(result).toBeFalse();
            });

            it('should be able to find the value within the search terms', function() {
                var result = testBlockHelper('contains', ['foo', 'bar'], {
                    value: 'foo'
                });

                expect(result).toBeTrue();
            });

            it('should flatten nested arrays', function() {
                var result = testBlockHelper('contains', ['foo', ['bar', 'baz']], {
                    value: 'baz'
                });

                expect(result).toBeTrue();
            });
        });

        xdescribe('eachIndexGroup', function() {
            // TODO
        });

        describe('first', function() {
            it('should use the first item from the list as the thisObj', function() {
                var options = makeOptions({}, function(thisObj) {
                    return thisObj;
                });
                var result = instance.first(['foo', 'bar'], options);

                expect(result).toBe('foo');
            });
        });

        describe('is', function() {
            it('should use the normal condition if the items are identical', function() {
                var obj1 = {};
                var obj2 = obj1;
                var options = makeOptions();
                var result = instance.is(obj1, obj2, options);

                expect(result).toBeTrue();
            });

            it('should use the inverse condition if the items are not identical', function() {
                var obj1 = {};
                var obj2 = {};
                var options = makeOptions();
                var result = instance.is(obj1, obj2, options);

                expect(result).toBeFalse();
            });
        });

        describe('isnt', function() {
            it('should use the normal condition if the items are not identical', function() {
                var obj1 = {};
                var obj2 = {};
                var options = makeOptions();
                var result = instance.isnt(obj1, obj2, options);

                expect(result).toBeTrue();
            });

            it('should use the inverse condition if the items are identical', function() {
                var obj1 = {};
                var obj2 = obj1;
                var options = makeOptions();
                var result = instance.isnt(obj1, obj2, options);

                expect(result).toBeFalse();
            });
        });

        describe('last', function() {
            it('should use the last item from the list as the thisObj', function() {
                var options = makeOptions({}, function(thisObj) {
                    return thisObj;
                });
                var result = instance.last(['foo', 'bar'], options);

                expect(result).toBe('bar');
            });
        });

        describe('markdown', function() {
            var options = makeOptions({}, function() {
                return '**foo**';
            });
            var useMarkdown = !!template.config.markdown;

            afterEach(function() {
                template.config.markdown = useMarkdown;
            });

            it('should use a Markdown parser by default', function() {
                var text = instance.markdown(options);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
foo
');
            });

            it('should not use a Markdown parser when the user disables Markdown', function() {
                var text;
                var tempInstance;

                template.config.markdown = false;
                tempInstance = block(template);
                text = tempInstance.markdown(options);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
**foo**
');
            });

            it('should automatically expand standalone
 tags into proper markup when Markdown ' +
                'is disabled', function() {
                var text;
                var tempInstance;
                var tempOptions = makeOptions({}, function() {
                    return 'foo
bar
baz';
                });

                template.config.markdown = false;
                tempInstance = block(template);
                text = tempInstance.markdown(tempOptions);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
foo

bar

baz
');
            });

            it('should not wrap text in an extra
 tag when Markdown is disabled', function() {
                var text;
                var tempInstance;
                var tempOptions = makeOptions({}, function() {
                    return '
**foo**
';
                });

                template.config.markdown = false;
                tempInstance = block(template);
                text = tempInstance.markdown(tempOptions);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
**foo**
');
            });
        });

        describe('markdownLinks', function() {
            var options = makeOptions({}, function() {
                return '[Mr. Macintosh]' +
                    '(http://www.folklore.org/StoryView.py?story=Mister_Macintosh.txt)';
            });
            var useMarkdown = !!template.config.markdown;

            afterEach(function() {
                template.config.markdown = useMarkdown;
            });

            it('should convert Markdown links to HTML links by default', function() {
                var text = instance.markdownLinks(options);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
Mr. Macintosh
');
            });

            it('should not convert Markdown text with no links', function() {
                var tempOptions = makeOptions({}, function() {
                    return '**foo**';
                });
                var text = instance.markdownLinks(tempOptions);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
**foo**
');
            });

            it('should not convert Markdown links if Markdown is disabled', function() {
                var text;
                var tempInstance;

                template.config.markdown = false;
                tempInstance = block(template);
                text = tempInstance.markdownLinks(options);

                expect(text).toBeInstanceOf(SafeString);
                expect(text.toString()).toBe('
[Mr. Macintosh]' +
                    '(http://www.folklore.org/StoryView.py?story=Mister_Macintosh.txt)
');
            });
        });

        describe('withOnly', function() {
            it('should create a context with the options hash values as properties', function() {
                var options = makeOptions({
                    test: 'foo'
                }, function(ctx) {
                    return ctx.test;
                });
                var text = instance.withOnly(options);

                expect(text).toBe('foo');
            });
        });
    });
});


text:
from flask import Blueprint, current_app, render_template, abort, request,  \
    redirect, flash, url_for
from jinja2 import TemplateNotFound
# from flask.ext.uploads import UploadSet, IMAGES, configure_uploads
from saef_app.core.database import db
from saef_app.core.config import photos
from saef_app.core.forms import AddUserForm, EditUserForm, AddCategoryForm, \
    AddServiceForm
from saef_app.core.models import User, Category, Service
bundle = Blueprint('admin', __name__, template_folder='templates',
                   static_folder='static')

@bundle.route('/admin', methods=['GET', 'POST'])
def index():
    try:
        return render_template('admin/index.html')
    except TemplateNotFound:
        abort(404)

@bundle.route('/admin/user', methods=['GET', 'POST'])
@bundle.route('/admin/user/<int:page>', methods=['GET', 'POST'])
def user(page=1):
    users = User.query.paginate(page, current_app.config['RESULTS_PER_PAGE'],
                                False)
    try:
        return render_template('admin/user.html',
                               title=u'Listar usuarios',
                               users=users)
    except TemplateNotFound:
        abort(404)

@bundle.route('/admin/user/add', methods=['GET', 'POST'])
def adduser():
    form = AddUserForm()
    form_action = url_for('admin.adduser')
    if request.method == 'POST' and form.validate():
        user = User(form.name.data,
                    form.surname.data,
                    form.username.data,
                    form.email.data,
                    form.password.data,
                    form.role.data,
                    form.active.data
                    )
        db.session.add(user)
        db.session.commit()
        flash(u'Usuario Creado')
        return redirect(url_for('admin.user'))
    return render_template('admin/add_user.html',
                           title=u"Crear usuario",
                           form_action=form_action,
                           form=form)

@bundle.route('/admin/user/edit/<user_id>', methods=['GET', 'POST'])
def edituser(user_id):
    quser = User.query.filter(User.username == user_id).first_or_404()
    form = EditUserForm(obj=quser)
    form_action = url_for('admin.edituser', user_id=user_id)
    if request.method == 'POST' and form.validate():
        form.populate_obj(quser)
        db.session.commit()
        flash(u'Usuario actualizado')
        return redirect(url_for('admin.user'))
    return render_template('admin/add_user.html',
                           title=u"Editar usuario",
                           form_action=form_action,
                           form=form,
                           user_id=user_id)

@bundle.route('/admin/user/delete', methods=['GET', 'POST'])
def deleteuser():
    ret_data = request.args.get('item')
    duser = User.query.filter(User.username == ret_data).first_or_404()
    if request.method == 'GET':
        db.session.delete(duser)
        db.session.commit()
        flash(u'Usuario eliminado')
    return "OK"

@bundle.route('/admin/categories', methods=['GET', 'POST'])
@bundle.route('/admin/categories/<int:page>', methods=['GET', 'POST'])
def category(page=1):
    categories = (Category.query.paginate(page,
                  current_app.config['RESULTS_PER_PAGE'],
                  False))
    try:
        return render_template('admin/category.html',
                               title=u'Listar categorias',
                               categories=categories)
    except TemplateNotFound:
        abort(404)

@bundle.route('/admin/category/add', methods=['GET', 'POST'])
def addcategory():
    form = AddCategoryForm()
    form_action = url_for('admin.addcategory')
    if request.method == 'POST' and form.validate():
        category = Category(form.name.data,
                            form.description.data,
                            form.active.data
                            )
        db.session.add(category)
        db.session.commit()
        flash(u'categoria Creada')
        return redirect(url_for('admin.category'))
    return render_template('admin/category_forms.html',
                           title=u"Crear Categoria",
                           form_action=form_action,
                           form=form)

@bundle.route('/admin/category/edit/<category_id>', methods=['GET', 'POST'])
def editcategory(category_id):
    qcategory = Category.query.filter(Category.id ==
                                      category_id).first_or_404()
    form = AddCategoryForm(obj=qcategory)
    form_action = url_for('admin.editcategory', category_id=category_id)
    if request.method == 'POST' and form.validate():
        form.populate_obj(qcategory)
        db.session.commit()
        flash(u'Categoria actualizada')
        return redirect(url_for('admin.category'))
    return render_template('admin/category_forms.html',
                           title=u"Editar categoria",
                           form_action=form_action,
                           form=form,
                           category_id=category_id)

@bundle.route('/admin/category/delete', methods=['GET', 'POST'])
def deletecategory():
    ret_data = request.args.get('item')
    duser = Category.query.filter(Category.id == ret_data).first_or_404()
    if request.method == 'GET':
        db.session.delete(duser)
        db.session.commit()
        flash(u'Categoria eliminada')
    return "OK"

@bundle.route('/admin/service', methods=['GET', 'POST'])
@bundle.route('/admin/service/<int:page>', methods=['GET', 'POST'])
def service(page=1):
    services = (Service.query.paginate(page,
                current_app.config['RESULTS_PER_PAGE'],
                False))
    try:
        return render_template('admin/service.html',
                               title=u'Listar Servicios',
                               services=services)
    except TemplateNotFound:
        abort(404)

@bundle.route('/admin/service/add', methods=['GET', 'POST'])
def addservice():
    form = AddServiceForm()
    form_action = url_for('admin.addservice')
    form.category_id.choices = ([(g.id, g.name) for g in
                                Category.query.order_by('name')])
    if (request.method == 'POST' and form.validate()
            and 'image_url' in request.files):
        filename = photos.save(request.files['image_url'])
        # rec = Photo(filename=filename, user=g.user.id)
        # rec.store()
        service = Service(form.title.data,
                          form.slug.data,
                          form.description.data,
                          form.date.data,
                          filename,
                          form.category_id.data,
                          form.active.data
                          )
        db.session.add(service)
        db.session.commit()
        flash(u'Servicio Creado')
        return redirect(url_for('admin.service', filename=filename))
    return render_template('admin/service_forms.html',
                           title=u"Crear Servicio",
                           form_action=form_action,
                           form=form)

@bundle.route('/admin/service/edit/<service_id>', methods=['GET', 'POST'])
def editservice(service_id):
    qservice = Service.query.filter(Service.id ==
                                    service.id).first_or_404
    form = AddServiceForm(obj=qservice)
    form_action = url_for('admin.editservice', service_id=service_id)
    if (request.method == 'POST' and form.validate()):
        filename = photos.save(request.files['image_url'])


text:
{-# LANGUAGE ConstraintKinds #-}

module HGE2D.Classes where

import HGE2D.Types
import HGE2D.Datas

--------------------------------------------------------------------------------

-- | For types which are affected by time
class Dynamic a where
    moveInTime :: Millisecond -> a -> a

--------------------------------------------------------------------------------

-- | For types than can be directly rendered to GL (only required by the engine)
--   Use GlInstructable to define your rendereble types
class GlRender a where
    glRender :: a -> IO ()

--------------------------------------------------------------------------------

-- | For types which can be turned into render instructions to be rendered by the engine
class GlInstructable a where
    toGlInstruction :: a -> RenderInstruction

--------------------------------------------------------------------------------

-- | For types which have a bounding box
class HasBoundingBox a where
    getBB :: a -> BoundingBox

--------------------------------------------------------------------------------

-- | For types which have / are a physical object
class IsPhysicalObject a where
    getPhys :: a -> PhysicalObject
    setPhys :: PhysicalObject -> a -> a

--------------------------------------------------------------------------------

-- | For types which are positioned in space
class Positioned a where
    getPos :: a -> RealPosition
    getX   :: a -> Double
    getY   :: a -> Double

--------------------------------------------------------------------------------

-- | For types which can be moved in space
class Moveable a where
    moveBy :: RealPosition -> a -> a
    moveTo :: RealPosition -> a -> a

--------------------------------------------------------------------------------

-- | For types which can be accelerated
class Acceleratable a where
    accBy :: Velocity -> a -> a
    accTo :: Velocity -> a -> a


text:
// Copyright 2016 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.

/**
 * @fileoverview Fake implementation of chrome.quickUnlockPrivate for testing.
 */
cr.define('settings', function() {
  /**
   * Fake of the chrome.quickUnlockPrivate API.
   * @constructor
   * @implements {QuickUnlockPrivate}
   */
  function FakeQuickUnlockPrivate() {
    /** @type {!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>} */
        this.availableModes = [chrome.quickUnlockPrivate.QuickUnlockMode.PIN];
    /** @type {!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>} */
        this.activeModes = [];
    /** @type {!Array<string>} */ this.credentials = [];
    /** @type {string} */ this.accountPassword = '';
  }

  FakeQuickUnlockPrivate.prototype = {
    // Public testing methods.
    /**
     * @override
     * @param {function(
     *     !Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void} onComplete
     */
    getAvailableModes: function(onComplete) {
      onComplete(this.availableModes);
    },

    /**
     * @override
     * @param {function(
     *     !Array<!chrome.quickUnlockPrivate.QuickUnlockMode>):void} onComplete
     */
    getActiveModes: function(onComplete) {
      onComplete(this.activeModes);
    },

    /**
     * @override
     * @param {string} accountPassword
     * @param {!Array<!chrome.quickUnlockPrivate.QuickUnlockMode>} modes
     * @param {!Array<string>} credentials
     * @param {function(boolean):void} onComplete
     */
    setModes: function(accountPassword, modes, credentials, onComplete) {
      // Even if the account password is wrong we still update activeModes and
      // credentials so that the mock owner has a chance to see what was given
      // to the API.
      this.activeModes = modes;
      this.credentials = credentials;
      onComplete(this.accountPassword == accountPassword);
    }
  };

  /** @type {!ChromeEvent} */
  FakeQuickUnlockPrivate.prototype.onActiveModesChanged = new FakeChromeEvent();

  return {FakeQuickUnlockPrivate: FakeQuickUnlockPrivate};
});


text:
lucid.html.base.tags.menuitem = function(factory){
	this.factory = factory;
	lucid.html.tag.apply(this, arguments);
	this.tag = 'menuitem';
	this.allowedAttributes.push('checked');
	this.allowedAttributes.push('default');
	this.allowedAttributes.push('disabled');
	this.allowedAttributes.push('icon');
	this.allowedAttributes.push('label');
	this.allowedAttributes.push('radiogroup');
	this.allowedAttributes.push('type');
};
lucid.html.base.tags.menuitem.prototype = Object.create(lucid.html.tag.prototype);
lucid.html.factory.tags.menuitem = lucid.html.base.tags.menuitem;


text:
"""Pops a message from a queue."""
# :license: MIT, see LICENSE for more details.

import SoftLayer
from SoftLayer.CLI import environment
from SoftLayer.CLI import mq

import click

@click.command()
@click.argument('account-id')
@click.argument('queue-name')
@click.option('--count',
              default=1,
              type=click.INT,
              help="Count of messages to pop")
@click.option('--delete-after',
              is_flag=True,
              help="Remove popped messages from the queue")
@click.option('--datacenter', help="Datacenter, E.G.: dal05")
@click.option('--network',
              type=click.Choice(['public', 'private']),
              help="Network type")
@environment.pass_env
def cli(env, account_id, queue_name, count, delete_after, datacenter, network):
    """Pops a message from a queue."""

    manager = SoftLayer.MessagingManager(env.client)
    mq_client = manager.get_connection(account_id,
                                       datacenter=datacenter, network=network)

    messages = mq_client.pop_messages(queue_name, count)
    formatted_messages = []
    for message in messages['items']:
        formatted_messages.append(mq.message_table(message))

    if delete_after:
        for message in messages['items']:
            mq_client.delete_message(queue_name, message['id'])
    env.fout(formatted_messages)


text:
@interface PTVehiclesOnRouteLoader : PTBaseLoader
@property (nonatomic, assign) enum PTCity city;
@property (nonatomic, assign) enum PTVehicleTypes vehicleType;
@property (nonatomic, retain) NSString *routeIdentifier;
@property (nonatomic, assign) NSObject<PTVehiclesOnRouteLoaderDelegate> *delegate;
- (id)initWithCity:(enum PTCity)city vehicleType:(enum PTVehicleTypes)vehicleType routeIdentifier:(NSString *)routeIdentifier delegate:(NSObject<PTVehiclesOnRouteLoaderDelegate> *)delegate;
@end


text:
Lopputili on kirjanpitoon ja laskutukseen tarkoitettu sovellus.

Lopputili on pystytetty [tänne](http://lopputili.viski.me/)

## Dokumentaatio

[Markdown-muotoisena](https://github.com/theikkila/lopputili/blob/master/doc/generated/documentation.md)
[Esittelysivu](http://lopputili.viski.me/esittelysivu)