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

Side by Side Diff: ui/compositor/compositor.cc

Issue 10690168: Aura: Resize locks with --ui-enable-threaded-compositing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: With a unittest (and minor compile fixes for other platforms). Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/compositor/compositor.h" 5 #include "ui/compositor/compositor.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h"
9 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/message_loop.h"
10 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
11 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" 14 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSuppor t.h" 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSuppor t.h"
14 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput Surface.h" 17 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput Surface.h"
16 #include "ui/compositor/compositor_observer.h" 18 #include "ui/compositor/compositor_observer.h"
17 #include "ui/compositor/compositor_switches.h" 19 #include "ui/compositor/compositor_switches.h"
18 #include "ui/compositor/dip_util.h" 20 #include "ui/compositor/dip_util.h"
19 #include "ui/compositor/layer.h" 21 #include "ui/compositor/layer.h"
(...skipping 13 matching lines...) Expand all
33 35
34 const double kDefaultRefreshRate = 60.0; 36 const double kDefaultRefreshRate = 60.0;
35 const double kTestRefreshRate = 100.0; 37 const double kTestRefreshRate = 100.0;
36 38
37 webkit_glue::WebThreadImpl* g_compositor_thread = NULL; 39 webkit_glue::WebThreadImpl* g_compositor_thread = NULL;
38 40
39 bool test_compositor_enabled = false; 41 bool test_compositor_enabled = false;
40 42
41 ui::ContextFactory* g_context_factory = NULL; 43 ui::ContextFactory* g_context_factory = NULL;
42 44
45 const int kCompositorLockTimeoutMs = 67;
46
43 } // namespace 47 } // namespace
44 48
45 namespace ui { 49 namespace ui {
46 50
47 // static 51 // static
48 ContextFactory* ContextFactory::GetInstance() { 52 ContextFactory* ContextFactory::GetInstance() {
49 // We leak the shared resources so that we don't race with 53 // We leak the shared resources so that we don't race with
50 // the tear down of the gl_bindings. 54 // the tear down of the gl_bindings.
51 if (!g_context_factory) { 55 if (!g_context_factory) {
52 DVLOG(1) << "Using DefaultSharedResource"; 56 DVLOG(1) << "Using DefaultSharedResource";
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 129
126 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) 130 Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
127 : flipped_(flipped), 131 : flipped_(flipped),
128 size_(size), 132 size_(size),
129 device_scale_factor_(device_scale_factor) { 133 device_scale_factor_(device_scale_factor) {
130 } 134 }
131 135
132 Texture::~Texture() { 136 Texture::~Texture() {
133 } 137 }
134 138
139 CompositorLock::CompositorLock(Compositor* compositor)
140 : compositor_(compositor) {
141 MessageLoop::current()->PostDelayedTask(
142 FROM_HERE,
143 base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
144 base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
145 }
146
147 CompositorLock::~CompositorLock() {
148 CancelLock();
149 }
150
151 void CompositorLock::CancelLock() {
152 if (!compositor_)
153 return;
154 compositor_->Unlock();
155 compositor_ = NULL;
156 }
157
135 Compositor::Compositor(CompositorDelegate* delegate, 158 Compositor::Compositor(CompositorDelegate* delegate,
136 gfx::AcceleratedWidget widget) 159 gfx::AcceleratedWidget widget)
137 : delegate_(delegate), 160 : delegate_(delegate),
138 root_layer_(NULL), 161 root_layer_(NULL),
139 widget_(widget), 162 widget_(widget),
140 swap_posted_(false), 163 swap_posted_(false),
141 device_scale_factor_(0.0f), 164 device_scale_factor_(0.0f),
142 last_started_frame_(0), 165 last_started_frame_(0),
143 last_ended_frame_(0), 166 last_ended_frame_(0),
144 disable_schedule_composite_(false) { 167 disable_schedule_composite_(false),
168 compositor_lock_(NULL) {
145 WebKit::WebCompositorSupport* compositor_support = 169 WebKit::WebCompositorSupport* compositor_support =
146 WebKit::Platform::current()->compositorSupport(); 170 WebKit::Platform::current()->compositorSupport();
147 root_web_layer_.reset(compositor_support->createLayer()); 171 root_web_layer_.reset(compositor_support->createLayer());
148 WebKit::WebLayerTreeView::Settings settings; 172 WebKit::WebLayerTreeView::Settings settings;
149 CommandLine* command_line = CommandLine::ForCurrentProcess(); 173 CommandLine* command_line = CommandLine::ForCurrentProcess();
150 settings.showFPSCounter = 174 settings.showFPSCounter =
151 command_line->HasSwitch(switches::kUIShowFPSCounter); 175 command_line->HasSwitch(switches::kUIShowFPSCounter);
152 settings.showPlatformLayerTree = 176 settings.showPlatformLayerTree =
153 command_line->HasSwitch(switches::kUIShowLayerTree); 177 command_line->HasSwitch(switches::kUIShowLayerTree);
154 settings.refreshRate = 178 settings.refreshRate =
155 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; 179 test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate;
156 180
157 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); 181 root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
158 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, 182 host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_,
159 settings)); 183 settings));
160 host_->setSurfaceReady(); 184 host_->setSurfaceReady();
161 } 185 }
162 186
163 Compositor::~Compositor() { 187 Compositor::~Compositor() {
188 if (compositor_lock_) {
189 compositor_lock_->CancelLock();
190 DCHECK(!compositor_lock_);
191 }
192
164 // Don't call |CompositorDelegate::ScheduleDraw| from this point. 193 // Don't call |CompositorDelegate::ScheduleDraw| from this point.
165 delegate_ = NULL; 194 delegate_ = NULL;
166 if (root_layer_) 195 if (root_layer_)
167 root_layer_->SetCompositor(NULL); 196 root_layer_->SetCompositor(NULL);
168 197
169 // Stop all outstanding draws before telling the ContextFactory to tear 198 // Stop all outstanding draws before telling the ContextFactory to tear
170 // down any contexts that the |host_| may rely upon. 199 // down any contexts that the |host_| may rely upon.
171 host_.reset(); 200 host_.reset();
172 201
173 if (!test_compositor_enabled) 202 if (!test_compositor_enabled)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 void Compositor::SetHostHasTransparentBackground( 252 void Compositor::SetHostHasTransparentBackground(
224 bool host_has_transparent_background) { 253 bool host_has_transparent_background) {
225 host_->setHasTransparentBackground(host_has_transparent_background); 254 host_->setHasTransparentBackground(host_has_transparent_background);
226 } 255 }
227 256
228 void Compositor::Draw(bool force_clear) { 257 void Compositor::Draw(bool force_clear) {
229 if (!root_layer_) 258 if (!root_layer_)
230 return; 259 return;
231 260
232 last_started_frame_++; 261 last_started_frame_++;
233 if (!g_compositor_thread) 262 if (!g_compositor_thread && !IsLocked()) {
234 FOR_EACH_OBSERVER(CompositorObserver, 263 // TODO(nduca): Temporary while compositor calls
235 observer_list_, 264 // compositeImmediately() directly.
236 OnCompositingWillStart(this)); 265 layout();
237 266 host_->composite();
238 // TODO(nduca): Temporary while compositor calls 267 }
239 // compositeImmediately() directly.
240 layout();
241 host_->composite();
242 if (!g_compositor_thread && !swap_posted_) 268 if (!g_compositor_thread && !swap_posted_)
243 NotifyEnd(); 269 NotifyEnd();
244 } 270 }
245 271
246 void Compositor::ScheduleFullDraw() { 272 void Compositor::ScheduleFullDraw() {
247 host_->setNeedsRedraw(); 273 host_->setNeedsRedraw();
248 } 274 }
249 275
250 bool Compositor::ReadPixels(SkBitmap* bitmap, 276 bool Compositor::ReadPixels(SkBitmap* bitmap,
251 const gfx::Rect& bounds_in_pixel) { 277 const gfx::Rect& bounds_in_pixel) {
252 if (bounds_in_pixel.right() > size().width() || 278 if (bounds_in_pixel.right() > size().width() ||
253 bounds_in_pixel.bottom() > size().height()) 279 bounds_in_pixel.bottom() > size().height())
254 return false; 280 return false;
255 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 281 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
256 bounds_in_pixel.width(), bounds_in_pixel.height()); 282 bounds_in_pixel.width(), bounds_in_pixel.height());
257 bitmap->allocPixels(); 283 bitmap->allocPixels();
258 SkAutoLockPixels lock_image(*bitmap); 284 SkAutoLockPixels lock_image(*bitmap);
259 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); 285 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
286 Unlock();
piman 2012/10/25 00:14:08 I think this should really be: if (compositor_lock
jonathan.backer 2012/10/25 15:19:04 Done.
260 return host_->compositeAndReadback(pixels, bounds_in_pixel); 287 return host_->compositeAndReadback(pixels, bounds_in_pixel);
261 } 288 }
262 289
263 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { 290 void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
264 DCHECK_GT(scale, 0); 291 DCHECK_GT(scale, 0);
265 if (size_in_pixel.IsEmpty() || scale <= 0) 292 if (size_in_pixel.IsEmpty() || scale <= 0)
266 return; 293 return;
267 size_ = size_in_pixel; 294 size_ = size_in_pixel;
268 host_->setViewportSize(size_in_pixel); 295 host_->setViewportSize(size_in_pixel);
269 root_web_layer_->setBounds(size_in_pixel); 296 root_web_layer_->setBounds(size_in_pixel);
(...skipping 10 matching lines...) Expand all
280 } 307 }
281 308
282 void Compositor::RemoveObserver(CompositorObserver* observer) { 309 void Compositor::RemoveObserver(CompositorObserver* observer) {
283 observer_list_.RemoveObserver(observer); 310 observer_list_.RemoveObserver(observer);
284 } 311 }
285 312
286 bool Compositor::HasObserver(CompositorObserver* observer) { 313 bool Compositor::HasObserver(CompositorObserver* observer) {
287 return observer_list_.HasObserver(observer); 314 return observer_list_.HasObserver(observer);
288 } 315 }
289 316
290 bool Compositor::IsThreaded() const {
291 return g_compositor_thread != NULL;
292 }
293
294 void Compositor::OnSwapBuffersPosted() { 317 void Compositor::OnSwapBuffersPosted() {
295 swap_posted_ = true; 318 swap_posted_ = true;
296 } 319 }
297 320
298 void Compositor::OnSwapBuffersComplete() { 321 void Compositor::OnSwapBuffersComplete() {
299 DCHECK(swap_posted_); 322 DCHECK(swap_posted_);
300 swap_posted_ = false; 323 swap_posted_ = false;
301 NotifyEnd(); 324 NotifyEnd();
302 } 325 }
303 326
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 return new WebGraphicsContextToOutputSurfaceAdapter(test_context); 400 return new WebGraphicsContextToOutputSurfaceAdapter(test_context);
378 } else { 401 } else {
379 return new WebGraphicsContextToOutputSurfaceAdapter( 402 return new WebGraphicsContextToOutputSurfaceAdapter(
380 ContextFactory::GetInstance()->CreateContext(this)); 403 ContextFactory::GetInstance()->CreateContext(this));
381 } 404 }
382 } 405 }
383 406
384 void Compositor::didRecreateOutputSurface(bool success) { 407 void Compositor::didRecreateOutputSurface(bool success) {
385 } 408 }
386 409
387 // Called once per draw in single-threaded compositor mode and potentially
388 // many times between draws in the multi-threaded compositor mode.
389 void Compositor::didCommit() { 410 void Compositor::didCommit() {
390 FOR_EACH_OBSERVER(CompositorObserver, 411 if (!IsLocked()) {
piman 2012/10/25 00:14:08 Is there actually a case where we'll call didCommi
jonathan.backer 2012/10/25 15:19:04 You are right. This is should no longer happen. I'
391 observer_list_, 412 FOR_EACH_OBSERVER(CompositorObserver,
392 OnCompositingDidCommit(this)); 413 observer_list_,
414 OnCompositingDidCommit(this));
415 }
393 } 416 }
394 417
395 void Compositor::didCommitAndDrawFrame() { 418 void Compositor::didCommitAndDrawFrame() {
396 // TODO(backer): Plumb through an earlier impl side will start.
397 if (g_compositor_thread)
398 FOR_EACH_OBSERVER(CompositorObserver,
399 observer_list_,
400 OnCompositingWillStart(this));
401
402 FOR_EACH_OBSERVER(CompositorObserver, 419 FOR_EACH_OBSERVER(CompositorObserver,
403 observer_list_, 420 observer_list_,
404 OnCompositingStarted(this)); 421 OnCompositingStarted(this));
405 } 422 }
406 423
407 void Compositor::didCompleteSwapBuffers() { 424 void Compositor::didCompleteSwapBuffers() {
408 NotifyEnd(); 425 NotifyEnd();
409 } 426 }
410 427
411 void Compositor::scheduleComposite() { 428 void Compositor::scheduleComposite() {
412 if (!disable_schedule_composite_) 429 if (!disable_schedule_composite_)
413 ScheduleDraw(); 430 ScheduleDraw();
414 } 431 }
415 432
433 scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
434 if (!compositor_lock_) {
435 compositor_lock_ = new CompositorLock(this);
436 if (g_compositor_thread)
437 host_->setDeferCommits(true);
438 FOR_EACH_OBSERVER(CompositorObserver,
439 observer_list_,
440 OnCompositingLockStateChanged(this));
441 }
442 return compositor_lock_;
443 }
444
445 void Compositor::Unlock() {
446 DCHECK(compositor_lock_);
447 compositor_lock_ = NULL;
448 if (g_compositor_thread)
449 host_->setDeferCommits(false);
450 FOR_EACH_OBSERVER(CompositorObserver,
451 observer_list_,
452 OnCompositingLockStateChanged(this));
453 }
454
416 void Compositor::NotifyEnd() { 455 void Compositor::NotifyEnd() {
417 last_ended_frame_++; 456 last_ended_frame_++;
418 FOR_EACH_OBSERVER(CompositorObserver, 457 FOR_EACH_OBSERVER(CompositorObserver,
419 observer_list_, 458 observer_list_,
420 OnCompositingEnded(this)); 459 OnCompositingEnded(this));
421 } 460 }
422 461
423 COMPOSITOR_EXPORT void SetupTestCompositor() { 462 COMPOSITOR_EXPORT void SetupTestCompositor() {
424 if (!CommandLine::ForCurrentProcess()->HasSwitch( 463 if (!CommandLine::ForCurrentProcess()->HasSwitch(
425 switches::kDisableTestCompositor)) { 464 switches::kDisableTestCompositor)) {
426 test_compositor_enabled = true; 465 test_compositor_enabled = true;
427 } 466 }
428 #if defined(OS_CHROMEOS) 467 #if defined(OS_CHROMEOS)
429 // If the test is running on the chromeos envrionment (such as 468 // If the test is running on the chromeos envrionment (such as
430 // device or vm bots), use the real compositor. 469 // device or vm bots), use the real compositor.
431 if (base::chromeos::IsRunningOnChromeOS()) 470 if (base::chromeos::IsRunningOnChromeOS())
432 test_compositor_enabled = false; 471 test_compositor_enabled = false;
433 #endif 472 #endif
434 } 473 }
435 474
436 COMPOSITOR_EXPORT void DisableTestCompositor() { 475 COMPOSITOR_EXPORT void DisableTestCompositor() {
437 test_compositor_enabled = false; 476 test_compositor_enabled = false;
438 } 477 }
439 478
440 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { 479 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() {
441 return test_compositor_enabled; 480 return test_compositor_enabled;
442 } 481 }
443 482
444 } // namespace ui 483 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698