13d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org/*
23d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
33d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *
43d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  Use of this source code is governed by a BSD-style license
53d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  that can be found in the LICENSE file in the root of the source
63d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  tree. An additional intellectual property rights grant can be found
73d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  in the file PATENTS.  All contributing project authors may
83d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org *  be found in the AUTHORS file in the root of the source tree.
93d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org */
103d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
113d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
123d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
13f2aafe4355c4b7ecbd122798f08a5c5ec5d2693ahenrike@webrtc.org#include <assert.h>
143d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org#include <algorithm>
153d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
1698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/logging.h"
173d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
183d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgnamespace webrtc {
193d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
203d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgScreenCapturerHelper::ScreenCapturerHelper()
213d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    : invalid_region_lock_(RWLockWrapper::CreateRWLock()),
223d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org      log_grid_size_(0) {
233d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
243d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
253d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgScreenCapturerHelper::~ScreenCapturerHelper() {
263d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
273d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
283d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::ClearInvalidRegion() {
293d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
303d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  invalid_region_.Clear();
313d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
323d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
333d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::InvalidateRegion(
343d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    const DesktopRegion& invalid_region) {
353d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
363d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  invalid_region_.AddRegion(invalid_region);
373d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
383d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
393d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::InvalidateScreen(const DesktopSize& size) {
403d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
413d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  invalid_region_.AddRect(DesktopRect::MakeSize(size));
423d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
433d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
443d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::TakeInvalidRegion(
453d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    DesktopRegion* invalid_region) {
463d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  invalid_region->Clear();
473d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
483d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  {
493d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    WriteLockScoped scoped_invalid_region_lock(*invalid_region_lock_);
503d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    invalid_region->Swap(&invalid_region_);
513d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  }
523d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
533d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  if (log_grid_size_ > 0) {
543d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    DesktopRegion expanded_region;
553d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    ExpandToGrid(*invalid_region, log_grid_size_, &expanded_region);
563d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    expanded_region.Swap(invalid_region);
573d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
583d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    invalid_region->IntersectWith(DesktopRect::MakeSize(size_most_recent_));
593d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  }
603d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
613d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
623d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::SetLogGridSize(int log_grid_size) {
633d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  log_grid_size_ = log_grid_size;
643d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
653d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
663d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgconst DesktopSize& ScreenCapturerHelper::size_most_recent() const {
673d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  return size_most_recent_;
683d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
693d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
703d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::set_size_most_recent(
713d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    const DesktopSize& size) {
723d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  size_most_recent_ = size;
733d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
743d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
753d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// Returns the largest multiple of |n| that is <= |x|.
763d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// |n| must be a power of 2. |nMask| is ~(|n| - 1).
773d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgstatic int DownToMultiple(int x, int nMask) {
783d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  return (x & nMask);
793d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
803d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
813d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// Returns the smallest multiple of |n| that is >= |x|.
823d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org// |n| must be a power of 2. |nMask| is ~(|n| - 1).
833d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgstatic int UpToMultiple(int x, int n, int nMask) {
843d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  return ((x + n - 1) & nMask);
853d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
863d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
873d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.orgvoid ScreenCapturerHelper::ExpandToGrid(const DesktopRegion& region,
883d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org                                        int log_grid_size,
893d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org                                        DesktopRegion* result) {
903d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  assert(log_grid_size >= 1);
913d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int grid_size = 1 << log_grid_size;
923d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  int grid_size_mask = ~(grid_size - 1);
933d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
943d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  result->Clear();
953d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  for (DesktopRegion::Iterator it(region); !it.IsAtEnd(); it.Advance()) {
963d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    int left = DownToMultiple(it.rect().left(), grid_size_mask);
973d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    int right = UpToMultiple(it.rect().right(), grid_size, grid_size_mask);
983d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    int top = DownToMultiple(it.rect().top(), grid_size_mask);
993d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    int bottom = UpToMultiple(it.rect().bottom(), grid_size, grid_size_mask);
1003d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org    result->AddRect(DesktopRect::MakeLTRB(left, top, right, bottom));
1013d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org  }
1023d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}
1033d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org
1043d34f66292ad4d3950d94026d08c3659880d30e2sergeyu@chromium.org}  // namespace webrtc
105