| /* |
| * 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> |
| |
| #include "webrtc/system_wrappers/interface/logging.h" |
| |
| 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 |