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