Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Side by Side Diff: chrome/browser/media/native_desktop_media_list.cc

Issue 1808273002: Use DesktopCaptureDeviceAura for all aura windows in Windows and Linux (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media/native_desktop_media_list.h" 5 #include "chrome/browser/media/native_desktop_media_list.h"
6 6
7 #include "base/hash.h" 7 #include "base/hash.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "base/threading/sequenced_worker_pool.h" 9 #include "base/threading/sequenced_worker_pool.h"
10 #include "chrome/browser/media/desktop_media_list_observer.h" 10 #include "chrome/browser/media/desktop_media_list_observer.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_list.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/grit/generated_resources.h" 11 #include "chrome/grit/generated_resources.h"
15 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
16 #include "media/base/video_util.h" 13 #include "media/base/video_util.h"
17 #include "third_party/libyuv/include/libyuv/scale_argb.h" 14 #include "third_party/libyuv/include/libyuv/scale_argb.h"
18 #include "third_party/skia/include/core/SkBitmap.h" 15 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
20 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" 17 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
21 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" 18 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
22 #include "ui/aura/window.h" 19 #include "ui/aura/window.h"
23 #include "ui/aura/window_tree_host.h"
24 #include "ui/base/l10n/l10n_util.h" 20 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/gfx/native_widget_types.h"
26 #include "ui/snapshot/snapshot.h" 21 #include "ui/snapshot/snapshot.h"
27 22
23 #if defined(OS_WIN)
24 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
25 #endif // defined(OS_WIN)
26
27 #if defined(USE_X11) && !defined(OS_CHROMEOS)
28 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
29 #endif // defined(USE_X11) && !defined(OS_CHROMEOS)
30
28 using content::BrowserThread; 31 using content::BrowserThread;
29 using content::DesktopMediaID; 32 using content::DesktopMediaID;
30 33
31 namespace { 34 namespace {
32 35
33 // Update the list every second. 36 // Update the list every second.
34 const int kDefaultUpdatePeriod = 1000; 37 const int kDefaultUpdatePeriod = 1000;
35 38
36 // Returns a hash of a DesktopFrame content to detect when image for a desktop 39 // Returns a hash of a DesktopFrame content to detect when image for a desktop
37 // media source has changed. 40 // media source has changed.
(...skipping 29 matching lines...) Expand all
67 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] = 70 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] =
68 0xff; 71 0xff;
69 } 72 }
70 } 73 }
71 74
72 result.unlockPixels(); 75 result.unlockPixels();
73 76
74 return gfx::ImageSkia::CreateFrom1xBitmap(result); 77 return gfx::ImageSkia::CreateFrom1xBitmap(result);
75 } 78 }
76 79
77 #if defined(USE_AURA)
78
79 NativeDesktopMediaList::NativeAuraIdMap GetBrowserNativeAuraIdMap() {
80 NativeDesktopMediaList::NativeAuraIdMap id_map;
81 for (auto* browser : *BrowserList::GetInstance()) {
82 aura::Window* aura_window = browser->window()->GetNativeWindow();
83 if (!aura_window)
84 continue;
85 aura::WindowTreeHost* host = aura_window->GetHost();
86 if (!host)
87 continue;
88 gfx::AcceleratedWidget widget = host->GetAcceleratedWidget();
89 #if defined(OS_WIN)
90 DesktopMediaID::Id native_id = reinterpret_cast<DesktopMediaID::Id>(widget);
91 #else
92 DesktopMediaID::Id native_id = widget;
93 #endif
94 DesktopMediaID media_id = DesktopMediaID::RegisterAuraWindow(
95 DesktopMediaID::TYPE_WINDOW, aura_window);
96 id_map[native_id] = media_id.aura_id;
97 }
98
99 return id_map;
100 }
101
102 #endif // defined(USE_AURA)
103
104 } // namespace 80 } // namespace
105 81
106 class NativeDesktopMediaList::Worker 82 class NativeDesktopMediaList::Worker
107 : public webrtc::DesktopCapturer::Callback { 83 : public webrtc::DesktopCapturer::Callback {
108 public: 84 public:
109 Worker(base::WeakPtr<NativeDesktopMediaList> media_list, 85 Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
110 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, 86 scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
111 scoped_ptr<webrtc::WindowCapturer> window_capturer); 87 scoped_ptr<webrtc::WindowCapturer> window_capturer);
112 ~Worker() override; 88 ~Worker() override;
113 89
114 void Refresh(const gfx::Size& thumbnail_size, 90 void Refresh(const DesktopMediaID::Id& view_dialog_id);
115 const DesktopMediaID::Id& view_dialog_id, 91
116 const NativeAuraIdMap& native_aura_id_map); 92 void RefreshThumbnails(const std::vector<SourceDescription>& native_sources,
93 const gfx::Size& thumbnail_size);
117 94
118 private: 95 private:
119 typedef std::map<DesktopMediaID, uint32_t> ImageHashesMap; 96 typedef std::map<DesktopMediaID, uint32_t> ImageHashesMap;
120 97
121 // webrtc::DesktopCapturer::Callback interface. 98 // webrtc::DesktopCapturer::Callback interface.
122 void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; 99 void OnCaptureCompleted(webrtc::DesktopFrame* frame) override;
123 100
124 base::WeakPtr<NativeDesktopMediaList> media_list_; 101 base::WeakPtr<NativeDesktopMediaList> media_list_;
125 102
126 scoped_ptr<webrtc::ScreenCapturer> screen_capturer_; 103 scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
(...skipping 15 matching lines...) Expand all
142 window_capturer_(std::move(window_capturer)) { 119 window_capturer_(std::move(window_capturer)) {
143 if (screen_capturer_) 120 if (screen_capturer_)
144 screen_capturer_->Start(this); 121 screen_capturer_->Start(this);
145 if (window_capturer_) 122 if (window_capturer_)
146 window_capturer_->Start(this); 123 window_capturer_->Start(this);
147 } 124 }
148 125
149 NativeDesktopMediaList::Worker::~Worker() {} 126 NativeDesktopMediaList::Worker::~Worker() {}
150 127
151 void NativeDesktopMediaList::Worker::Refresh( 128 void NativeDesktopMediaList::Worker::Refresh(
152 const gfx::Size& thumbnail_size, 129 const DesktopMediaID::Id& view_dialog_id) {
153 const DesktopMediaID::Id& view_dialog_id,
154 const NativeAuraIdMap& native_aura_id_map) {
155 std::vector<SourceDescription> sources; 130 std::vector<SourceDescription> sources;
156 std::vector<DesktopMediaID> aura_media_ids;
157 131
158 if (screen_capturer_) { 132 if (screen_capturer_) {
159 webrtc::ScreenCapturer::ScreenList screens; 133 webrtc::ScreenCapturer::ScreenList screens;
160 if (screen_capturer_->GetScreenList(&screens)) { 134 if (screen_capturer_->GetScreenList(&screens)) {
161 bool mutiple_screens = screens.size() > 1; 135 bool mutiple_screens = screens.size() > 1;
162 base::string16 title; 136 base::string16 title;
163 for (size_t i = 0; i < screens.size(); ++i) { 137 for (size_t i = 0; i < screens.size(); ++i) {
164 if (mutiple_screens) { 138 if (mutiple_screens) {
165 title = l10n_util::GetStringFUTF16Int( 139 title = l10n_util::GetStringFUTF16Int(
166 IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME, 140 IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME,
167 static_cast<int>(i + 1)); 141 static_cast<int>(i + 1));
168 } else { 142 } else {
169 title = l10n_util::GetStringUTF16( 143 title = l10n_util::GetStringUTF16(
170 IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME); 144 IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME);
171 } 145 }
172 sources.push_back(SourceDescription(DesktopMediaID( 146 sources.push_back(SourceDescription(DesktopMediaID(
173 DesktopMediaID::TYPE_SCREEN, screens[i].id), title)); 147 DesktopMediaID::TYPE_SCREEN, screens[i].id), title));
174 } 148 }
175 } 149 }
176 } 150 }
177 151
178 if (window_capturer_) { 152 if (window_capturer_) {
179 webrtc::WindowCapturer::WindowList windows; 153 webrtc::WindowCapturer::WindowList windows;
180 if (window_capturer_->GetWindowList(&windows)) { 154 if (window_capturer_->GetWindowList(&windows)) {
181 for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin(); 155 for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin();
182 it != windows.end(); ++it) { 156 it != windows.end(); ++it) {
183 // Skip the picker dialog window. 157 // Skip the picker dialog window.
184 if (it->id != view_dialog_id) { 158 if (it->id == view_dialog_id)
185 DesktopMediaID media_id(DesktopMediaID::TYPE_WINDOW, it->id); 159 continue;
186 #if defined(USE_AURA) 160
187 // Associate aura id with native id. 161 DesktopMediaID media_id(DesktopMediaID::TYPE_WINDOW, it->id);
188 auto aura_id = native_aura_id_map.find(media_id.id); 162 sources.push_back(
189 if (aura_id != native_aura_id_map.end()) { 163 SourceDescription(media_id, base::UTF8ToUTF16(it->title)));
190 media_id.aura_id = aura_id->second;
191 aura_media_ids.push_back(media_id);
192 }
193 #endif
194 sources.push_back(
195 SourceDescription(media_id, base::UTF8ToUTF16(it->title)));
196 }
197 } 164 }
198 } 165 }
199 } 166 }
200 167
201 // Update list of windows before updating thumbnails. 168 BrowserThread::PostTask(
202 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 169 BrowserThread::UI, FROM_HERE,
203 base::Bind(&NativeDesktopMediaList::UpdateSourcesList, 170 base::Bind(&NativeDesktopMediaList::RefreshForAuraWindows, media_list_,
204 media_list_, sources)); 171 sources));
172 }
205 173
174 void NativeDesktopMediaList::Worker::RefreshThumbnails(
175 const std::vector<SourceDescription>& native_sources,
Sergey Ulanov 2016/03/21 19:18:01 nit: this can be a vector of DesktopMediaId instea
GeorgeZ 2016/03/21 20:04:32 Done.
176 const gfx::Size& thumbnail_size) {
206 ImageHashesMap new_image_hashes; 177 ImageHashesMap new_image_hashes;
207 178
208 // Get a thumbnail for each source. 179 // Get a thumbnail for each native source.
209 for (size_t i = 0; i < sources.size(); ++i) { 180 for (const auto& source : native_sources) {
210 SourceDescription& source = sources[i];
211
212 switch (source.id.type) { 181 switch (source.id.type) {
213 case DesktopMediaID::TYPE_SCREEN: 182 case DesktopMediaID::TYPE_SCREEN:
214 if (!screen_capturer_->SelectScreen(source.id.id)) 183 if (!screen_capturer_->SelectScreen(source.id.id))
215 continue; 184 continue;
216 screen_capturer_->Capture(webrtc::DesktopRegion()); 185 screen_capturer_->Capture(webrtc::DesktopRegion());
217 break; 186 break;
218 187
219 case DesktopMediaID::TYPE_WINDOW: 188 case DesktopMediaID::TYPE_WINDOW:
220 #if defined(USE_AURA)
221 // Aura window thumbmail capture is skipped here. It will be done
222 // asynchronously in the UI thread.
223 if (source.id.aura_id > DesktopMediaID::kNullId)
224 continue;
225 #endif
226 if (!window_capturer_->SelectWindow(source.id.id)) 189 if (!window_capturer_->SelectWindow(source.id.id))
227 continue; 190 continue;
228 window_capturer_->Capture(webrtc::DesktopRegion()); 191 window_capturer_->Capture(webrtc::DesktopRegion());
229 break; 192 break;
230 193
231 default: 194 default:
232 NOTREACHED(); 195 NOTREACHED();
233 } 196 }
234 197
235 // Expect that DesktopCapturer to always captures frames synchronously. 198 // Expect that DesktopCapturer to always captures frames synchronously.
236 // |current_frame_| may be NULL if capture failed (e.g. because window has 199 // |current_frame_| may be NULL if capture failed (e.g. because window has
237 // been closed). 200 // been closed).
238 if (current_frame_) { 201 if (current_frame_) {
239 uint32_t frame_hash = GetFrameHash(current_frame_.get()); 202 uint32_t frame_hash = GetFrameHash(current_frame_.get());
240 new_image_hashes[source.id] = frame_hash; 203 new_image_hashes[source.id] = frame_hash;
241 204
242 // Scale the image only if it has changed. 205 // Scale the image only if it has changed.
243 ImageHashesMap::iterator it = image_hashes_.find(source.id); 206 ImageHashesMap::iterator it = image_hashes_.find(source.id);
244 if (it == image_hashes_.end() || it->second != frame_hash) { 207 if (it == image_hashes_.end() || it->second != frame_hash) {
245 gfx::ImageSkia thumbnail = 208 gfx::ImageSkia thumbnail =
246 ScaleDesktopFrame(std::move(current_frame_), thumbnail_size); 209 ScaleDesktopFrame(std::move(current_frame_), thumbnail_size);
247 BrowserThread::PostTask( 210 BrowserThread::PostTask(
248 BrowserThread::UI, FROM_HERE, 211 BrowserThread::UI, FROM_HERE,
249 base::Bind(&NativeDesktopMediaList::OnSourceThumbnailCaptured, 212 base::Bind(&NativeDesktopMediaList::UpdateSourceThumbnail,
250 media_list_, i, thumbnail)); 213 media_list_, source.id, thumbnail));
251 } 214 }
252 } 215 }
253 } 216 }
254 217
255 image_hashes_.swap(new_image_hashes); 218 image_hashes_.swap(new_image_hashes);
256 219
257 // Aura thumbnail captures have to be done in UI thread. After they are done,
258 // a refresh will be scheduled.
259 BrowserThread::PostTask( 220 BrowserThread::PostTask(
260 BrowserThread::UI, FROM_HERE, 221 BrowserThread::UI, FROM_HERE,
261 base::Bind( 222 base::Bind(&NativeDesktopMediaList::UpdateNativeThumbnailsFinished,
262 &NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext, 223 media_list_));
263 media_list_, aura_media_ids));
264 } 224 }
265 225
266 void NativeDesktopMediaList::Worker::OnCaptureCompleted( 226 void NativeDesktopMediaList::Worker::OnCaptureCompleted(
267 webrtc::DesktopFrame* frame) { 227 webrtc::DesktopFrame* frame) {
268 current_frame_.reset(frame); 228 current_frame_.reset(frame);
269 } 229 }
270 230
271 NativeDesktopMediaList::NativeDesktopMediaList( 231 NativeDesktopMediaList::NativeDesktopMediaList(
272 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, 232 scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
273 scoped_ptr<webrtc::WindowCapturer> window_capturer) 233 scoped_ptr<webrtc::WindowCapturer> window_capturer)
274 : DesktopMediaListBase( 234 : DesktopMediaListBase(
275 base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), 235 base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),
276 weak_factory_(this) { 236 weak_factory_(this) {
277 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); 237 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
278 capture_task_runner_ = worker_pool->GetSequencedTaskRunner( 238 capture_task_runner_ = worker_pool->GetSequencedTaskRunner(
279 worker_pool->GetSequenceToken()); 239 worker_pool->GetSequenceToken());
280 240
281 worker_.reset(new Worker(weak_factory_.GetWeakPtr(), 241 worker_.reset(new Worker(weak_factory_.GetWeakPtr(),
282 std::move(screen_capturer), 242 std::move(screen_capturer),
283 std::move(window_capturer))); 243 std::move(window_capturer)));
284 } 244 }
285 245
286 NativeDesktopMediaList::~NativeDesktopMediaList() { 246 NativeDesktopMediaList::~NativeDesktopMediaList() {
287 capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); 247 capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release());
288 } 248 }
289 249
290 void NativeDesktopMediaList::Refresh() { 250 void NativeDesktopMediaList::Refresh() {
291 NativeAuraIdMap native_aura_id_map;
292 #if defined(USE_AURA) 251 #if defined(USE_AURA)
293 native_aura_id_map = GetBrowserNativeAuraIdMap();
294 pending_aura_capture_requests_ = 0; 252 pending_aura_capture_requests_ = 0;
295 new_aura_thumbnail_hashes_.clear(); 253 new_aura_thumbnail_hashes_.clear();
254 native_thumbnail_capture_completed = false;
Sergey Ulanov 2016/03/21 19:18:01 suggest replacing this with pending_native_thumbna
GeorgeZ 2016/03/21 20:04:33 Done.
296 #endif 255 #endif
297 256
298 capture_task_runner_->PostTask( 257 capture_task_runner_->PostTask(
299 FROM_HERE, 258 FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
300 base::Bind(&Worker::Refresh, base::Unretained(worker_.get()), 259 view_dialog_id_.id));
301 thumbnail_size_, view_dialog_id_.id, native_aura_id_map));
302 } 260 }
303 261
304 void NativeDesktopMediaList::OnSourceThumbnailCaptured( 262 void NativeDesktopMediaList::RefreshForAuraWindows(
305 int index, 263 std::vector<SourceDescription> sources) {
306 const gfx::ImageSkia& image) { 264 #if defined(USE_AURA)
307 UpdateSourceThumbnail(GetSource(index).id, image); 265 for (auto& source : sources) {
266 aura::Window* aura_window = NULL;
267 #if defined(OS_WIN)
268 aura_window = views::DesktopWindowTreeHostWin::GetContentWindowForHWND(
269 reinterpret_cast<HWND>(source.id.id));
270 #elif defined(USE_X11) && !defined(OS_CHROMEOS)
271 aura_window =
272 views::DesktopWindowTreeHostX11::GetContentWindowForXID(source.id.id);
273 #endif // defined(OS_WIN)
Sergey Ulanov 2016/03/21 19:18:01 this should be // defined(USE_X11) && !defined(OS_
GeorgeZ 2016/03/21 20:04:32 Done.
274 // Associate aura id with native id.
275 if (aura_window) {
276 DesktopMediaID aura_id = DesktopMediaID::RegisterAuraWindow(
277 DesktopMediaID::TYPE_WINDOW, aura_window);
278 source.id.aura_id = aura_id.aura_id;
279 }
280 }
281 #endif // defined(USE_AURA)
282
283 UpdateSourcesList(sources);
284
285 std::vector<SourceDescription> native_sources;
286 #if defined(USE_AURA)
287 for (const auto& source : sources) {
288 if (source.id.aura_id > DesktopMediaID::kNullId)
289 CaptureAuraWindowThumbnail(source.id);
290 else
291 native_sources.push_back(source);
292 }
293 #else
294 native_sources = sources;
295 #endif // defined(USE_AURA)
296
297 capture_task_runner_->PostTask(
298 FROM_HERE,
299 base::Bind(&Worker::RefreshThumbnails, base::Unretained(worker_.get()),
300 native_sources, thumbnail_size_));
308 } 301 }
309 302
310 void NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext( 303 void NativeDesktopMediaList::UpdateNativeThumbnailsFinished() {
311 const std::vector<DesktopMediaID>& aura_ids) { 304 #if defined(USE_AURA)
312 // Schedule a refresh here when there is no aura thumbanil capture or schedule 305 native_thumbnail_capture_completed = true;
Sergey Ulanov 2016/03/21 19:18:01 DCHECK(!native_thumbnail_capture_completed_)
GeorgeZ 2016/03/21 20:04:33 Done.
313 // a refresh in OnAuraThumbnailCaptured() after all aura thumbnails are 306 // Schedule next refresh if native thumbnail captures finished after aura
314 // captured. 307 // thumbnail captures.
315 if (aura_ids.size() == 0) { 308 if (pending_aura_capture_requests_ == 0)
316 ScheduleNextRefresh(); 309 ScheduleNextRefresh();
317 return; 310 #else
318 } 311 ScheduleNextRefresh();
319 312 #endif // defined(USE_AURA)
320 #if defined(USE_AURA)
321 DCHECK_EQ(pending_aura_capture_requests_, 0);
322 for (const auto& aura_id : aura_ids) {
323 CaptureAuraWindowThumbnail(aura_id);
324 }
325 #endif
326 } 313 }
327 314
328 #if defined(USE_AURA) 315 #if defined(USE_AURA)
329 316
330 void NativeDesktopMediaList::CaptureAuraWindowThumbnail( 317 void NativeDesktopMediaList::CaptureAuraWindowThumbnail(
331 const DesktopMediaID& id) { 318 const DesktopMediaID& id) {
332 gfx::NativeWindow window = DesktopMediaID::GetAuraWindowById(id); 319 gfx::NativeWindow window = DesktopMediaID::GetAuraWindowById(id);
333 if (!window) 320 if (!window)
334 return; 321 return;
335 322
(...skipping 17 matching lines...) Expand all
353 previous_aura_thumbnail_hashes_[id] != new_aura_thumbnail_hashes_[id]) { 340 previous_aura_thumbnail_hashes_[id] != new_aura_thumbnail_hashes_[id]) {
354 UpdateSourceThumbnail(id, image.AsImageSkia()); 341 UpdateSourceThumbnail(id, image.AsImageSkia());
355 } 342 }
356 } 343 }
357 344
358 // After all aura windows are processed, schedule next refresh; 345 // After all aura windows are processed, schedule next refresh;
359 pending_aura_capture_requests_--; 346 pending_aura_capture_requests_--;
360 DCHECK_GE(pending_aura_capture_requests_, 0); 347 DCHECK_GE(pending_aura_capture_requests_, 0);
361 if (pending_aura_capture_requests_ == 0) { 348 if (pending_aura_capture_requests_ == 0) {
362 previous_aura_thumbnail_hashes_ = std::move(new_aura_thumbnail_hashes_); 349 previous_aura_thumbnail_hashes_ = std::move(new_aura_thumbnail_hashes_);
363 ScheduleNextRefresh(); 350 // Schedule next refresh if aura thumbnail captures finished after native
351 // thumbnail captures.
352 if (native_thumbnail_capture_completed)
353 ScheduleNextRefresh();
364 } 354 }
365 } 355 }
366 356
367 #endif // defined(USE_AURA) 357 #endif // defined(USE_AURA)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698