76c5f5cc8a
In the GN build, libchromiumcontent is no longer a distinct library, but merely a container for a set of scripts and patches. Maintaining those patches in a separate repository is tedious and error-prone, so merge them into the main repo. Once this is merged and GN is the default way to build Electron, the libchromiumcontent repository can be archived.
117 lines
4.2 KiB
Diff
117 lines
4.2 KiB
Diff
diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm
|
|
index df18777226..6a1e3da6ab 100644
|
|
--- a/modules/desktop_capture/mac/screen_capturer_mac.mm
|
|
+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm
|
|
@@ -16,6 +16,7 @@
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/constructormagic.h"
|
|
#include "rtc_base/logging.h"
|
|
+#include "rtc_base/synchronization/rw_lock_wrapper.h"
|
|
#include "rtc_base/timeutils.h"
|
|
#include "sdk/objc/Framework/Classes/Common/scoped_cftyperef.h"
|
|
|
|
@@ -28,18 +29,31 @@ namespace webrtc {
|
|
// destroy itself once it's done.
|
|
class DisplayStreamManager {
|
|
public:
|
|
- int GetUniqueId() { return ++unique_id_generator_; }
|
|
- void DestroyStream(int unique_id) {
|
|
- auto it = display_stream_wrappers_.find(unique_id);
|
|
- RTC_CHECK(it != display_stream_wrappers_.end());
|
|
- RTC_CHECK(!it->second.active);
|
|
- CFRelease(it->second.stream);
|
|
- display_stream_wrappers_.erase(it);
|
|
+ DisplayStreamManager() : rw_lock_(RWLockWrapper::CreateRWLock()) {}
|
|
+ RWLockWrapper* GetLock() {return rw_lock_.get();};
|
|
|
|
- if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) delete this;
|
|
+ int GetUniqueId() {
|
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
|
+ return ++unique_id_generator_;
|
|
+ }
|
|
+ void DestroyStream(int unique_id) {
|
|
+ bool finalize;
|
|
+ {
|
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
|
+ auto it = display_stream_wrappers_.find(unique_id);
|
|
+ RTC_CHECK(it != display_stream_wrappers_.end());
|
|
+ RTC_CHECK(!it->second.active);
|
|
+ CFRelease(it->second.stream);
|
|
+ display_stream_wrappers_.erase(it);
|
|
+ finalize = ready_for_self_destruction_ && display_stream_wrappers_.empty();
|
|
+ }
|
|
+ if (finalize) {
|
|
+ delete this;
|
|
+ }
|
|
}
|
|
|
|
void SaveStream(int unique_id, CGDisplayStreamRef stream) {
|
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
|
RTC_CHECK(unique_id <= unique_id_generator_);
|
|
DisplayStreamWrapper wrapper;
|
|
wrapper.stream = stream;
|
|
@@ -47,6 +61,7 @@ class DisplayStreamManager {
|
|
}
|
|
|
|
void UnregisterActiveStreams() {
|
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
|
for (auto& pair : display_stream_wrappers_) {
|
|
DisplayStreamWrapper& wrapper = pair.second;
|
|
if (wrapper.active) {
|
|
@@ -61,12 +76,23 @@ class DisplayStreamManager {
|
|
void PrepareForSelfDestruction() {
|
|
ready_for_self_destruction_ = true;
|
|
|
|
- if (display_stream_wrappers_.empty()) delete this;
|
|
+ bool finalize;
|
|
+ {
|
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
|
+ ready_for_self_destruction_ = true;
|
|
+ finalize = display_stream_wrappers_.empty();
|
|
+ }
|
|
+ if (finalize) {
|
|
+ delete this;
|
|
+ }
|
|
}
|
|
|
|
// Once the DisplayStreamManager is ready for destruction, the
|
|
// ScreenCapturerMac is no longer present. Any updates should be ignored.
|
|
- bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; }
|
|
+ // Note: not thread-safe! Acquire and release a lock manually.
|
|
+ bool ShouldIgnoreUpdates() {
|
|
+ return ready_for_self_destruction_;
|
|
+ }
|
|
|
|
private:
|
|
struct DisplayStreamWrapper {
|
|
@@ -81,6 +107,7 @@ class DisplayStreamManager {
|
|
std::map<int, DisplayStreamWrapper> display_stream_wrappers_;
|
|
int unique_id_generator_ = 0;
|
|
bool ready_for_self_destruction_ = false;
|
|
+ std::unique_ptr<RWLockWrapper> rw_lock_;
|
|
};
|
|
|
|
namespace {
|
|
@@ -507,8 +534,6 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() {
|
|
return;
|
|
}
|
|
|
|
- if (manager->ShouldIgnoreUpdates()) return;
|
|
-
|
|
// Only pay attention to frame updates.
|
|
if (status != kCGDisplayStreamFrameStatusFrameComplete) return;
|
|
|
|
@@ -518,7 +543,12 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() {
|
|
if (count != 0) {
|
|
// According to CGDisplayStream.h, it's safe to call
|
|
// CGDisplayStreamStop() from within the callback.
|
|
- ScreenRefresh(count, rects, display_origin);
|
|
+ manager->GetLock()->AcquireLockShared();
|
|
+ bool screen_capturer_mac_invalidated = manager->ShouldIgnoreUpdates();
|
|
+ if (!screen_capturer_mac_invalidated) {
|
|
+ ScreenRefresh(count, rects, display_origin);
|
|
+ }
|
|
+ manager->GetLock()->ReleaseLockShared();
|
|
}
|
|
};
|
|
|