/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/screen_capturer_helper.h"

#include <assert.h>
#include <algorithm>

namespace webrtc {

ScreenCapturerHelper::ScreenCapturerHelper()
    : invalid_region_lock_(RWLockWrapper::CreateRWLock()),
      log_grid_size_(0) {
}

ScreenCapturerHelper::~ScreenCapturerHelper() {
}

void ScreenCapturerHelper::ClearInvalidRegion() {
  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
  invalid_region_.Clear();
}

void ScreenCapturerHelper::InvalidateRegion(
    const DesktopRegion& invalid_region) {
  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
  invalid_region_.AddRegion(invalid_region);
}

void ScreenCapturerHelper::InvalidateScreen(const DesktopSize& size) {
  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
  invalid_region_.AddRect(DesktopRect::MakeSize(size));
}

void ScreenCapturerHelper::TakeInvalidRegion(
    DesktopRegion* invalid_region) {
  invalid_region->Clear();

  {
    WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
    invalid_region->Swap(&invalid_region_);
  }

  if (log_grid_size_ > 0) {
    DesktopRegion expanded_region;
    ExpandToGrid(*invalid_region, log_grid_size_, &expanded_region);
    expanded_region.Swap(invalid_region);

    invalid_region->IntersectWith(DesktopRect::MakeSize(size_most_recent_));
  }
}

void ScreenCapturerHelper::SetLogGridSize(int log_grid_size) {
  log_grid_size_ = log_grid_size;
}

const DesktopSize& ScreenCapturerHelper::size_most_recent() const {
  return size_most_recent_;
}

void ScreenCapturerHelper::set_size_most_recent(
    const DesktopSize& size) {
  size_most_recent_ = size;
}

// Returns the largest multiple of |n| that is <= |x|.
// |n| must be a power of 2. |nMask| is ~(|n| - 1).
static int DownToMultiple(int x, int nMask) {
  return (x & nMask);
}

// Returns the smallest multiple of |n| that is >= |x|.
// |n| must be a power of 2. |nMask| is ~(|n| - 1).
static int UpToMultiple(int x, int n, int nMask) {
  return ((x + n - 1) & nMask);
}

void ScreenCapturerHelper::ExpandToGrid(const DesktopRegion& region,
                                        int log_grid_size,
                                        DesktopRegion* result) {
  assert(log_grid_size >= 1);
  int grid_size = 1 << log_grid_size;
  int grid_size_mask = ~(grid_size - 1);

  result->Clear();
  for (DesktopRegion::Iterator it(region); !it.IsAtEnd(); it.Advance()) {
    int left = DownToMultiple(it.rect().left(), grid_size_mask);
    int right = UpToMultiple(it.rect().right(), grid_size, grid_size_mask);
    int top = DownToMultiple(it.rect().top(), grid_size_mask);
    int bottom = UpToMultiple(it.rect().bottom(), grid_size, grid_size_mask);
    result->AddRect(DesktopRect::MakeLTRB(left, top, right, bottom));
  }
}

}  // namespace webrtc
