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

Side by Side Diff: third_party/WebKit/Source/modules/vr/VRDisplay.cpp

Issue 2550863002: Prevent repeated VRDisplay.requestPresent calls from spamming the device (Closed)
Patch Set: Minor cleanup Created 4 years 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
« no previous file with comments | « third_party/WebKit/Source/modules/vr/VRDisplay.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "modules/vr/VRDisplay.h" 5 #include "modules/vr/VRDisplay.h"
6 6
7 #include "core/css/StylePropertySet.h" 7 #include "core/css/StylePropertySet.h"
8 #include "core/dom/DOMException.h" 8 #include "core/dom/DOMException.h"
9 #include "core/dom/DocumentUserGestureToken.h" 9 #include "core/dom/DocumentUserGestureToken.h"
10 #include "core/dom/FrameRequestCallback.h" 10 #include "core/dom/FrameRequestCallback.h"
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 m_layer.rightBounds().size() != 4)) { 358 m_layer.rightBounds().size() != 4)) {
359 forceExitPresent(); 359 forceExitPresent();
360 DOMException* exception = DOMException::create( 360 DOMException* exception = DOMException::create(
361 InvalidStateError, 361 InvalidStateError,
362 "Layer bounds must either be an empty array or have 4 values"); 362 "Layer bounds must either be an empty array or have 4 values");
363 resolver->reject(exception); 363 resolver->reject(exception);
364 ReportPresentationResult(PresentationResult::InvalidLayerBounds); 364 ReportPresentationResult(PresentationResult::InvalidLayerBounds);
365 return promise; 365 return promise;
366 } 366 }
367 367
368 if (firstPresent) { 368 if (!m_pendingPresentResolvers.isEmpty()) {
369 // If we are waiting on the results of a previous requestPresent call don't
370 // fire a new request, just cache the resolver and resolve it when the
371 // original request returns.
372 m_pendingPresentResolvers.append(resolver);
373 } else if (firstPresent) {
369 bool secureContext = scriptState->getExecutionContext()->isSecureContext(); 374 bool secureContext = scriptState->getExecutionContext()->isSecureContext();
370 if (!m_display) { 375 if (!m_display) {
371 forceExitPresent(); 376 forceExitPresent();
372 DOMException* exception = DOMException::create( 377 DOMException* exception = DOMException::create(
373 InvalidStateError, "The service is no longer active."); 378 InvalidStateError, "The service is no longer active.");
374 resolver->reject(exception); 379 resolver->reject(exception);
375 return promise; 380 return promise;
376 } 381 }
377 m_display->RequestPresent( 382
378 secureContext, convertToBaseCallback(WTF::bind( 383 m_pendingPresentResolvers.append(resolver);
379 &VRDisplay::onPresentComplete, wrapPersistent(this), 384 m_display->RequestPresent(secureContext, convertToBaseCallback(WTF::bind(
380 wrapPersistent(resolver)))); 385 &VRDisplay::onPresentComplete,
386 wrapPersistent(this))));
381 } else { 387 } else {
382 updateLayerBounds(); 388 updateLayerBounds();
383 resolver->resolve(); 389 resolver->resolve();
384 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting); 390 ReportPresentationResult(PresentationResult::SuccessAlreadyPresenting);
385 } 391 }
386 392
387 return promise; 393 return promise;
388 } 394 }
389 395
390 void VRDisplay::onPresentComplete(ScriptPromiseResolver* resolver, 396 void VRDisplay::onPresentComplete(bool success) {
391 bool success) {
392 if (success) { 397 if (success) {
393 this->beginPresent(resolver); 398 this->beginPresent();
394 } else { 399 } else {
395 this->forceExitPresent(); 400 this->forceExitPresent();
396 DOMException* exception = DOMException::create( 401 DOMException* exception = DOMException::create(
397 NotAllowedError, "Presentation request was denied."); 402 NotAllowedError, "Presentation request was denied.");
398 resolver->reject(exception); 403
404 while (!m_pendingPresentResolvers.isEmpty()) {
405 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
406 resolver->reject(exception);
407 }
399 } 408 }
400 } 409 }
401 410
402 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) { 411 ScriptPromise VRDisplay::exitPresent(ScriptState* scriptState) {
403 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 412 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
404 ScriptPromise promise = resolver->promise(); 413 ScriptPromise promise = resolver->promise();
405 414
406 if (!m_isPresenting) { 415 if (!m_isPresenting) {
407 // Can't stop presenting if we're not presenting. 416 // Can't stop presenting if we're not presenting.
408 DOMException* exception = 417 DOMException* exception =
(...skipping 10 matching lines...) Expand all
419 } 428 }
420 m_display->ExitPresent(); 429 m_display->ExitPresent();
421 430
422 resolver->resolve(); 431 resolver->resolve();
423 432
424 forceExitPresent(); 433 forceExitPresent();
425 434
426 return promise; 435 return promise;
427 } 436 }
428 437
429 void VRDisplay::beginPresent(ScriptPromiseResolver* resolver) { 438 void VRDisplay::beginPresent() {
430 Document* doc = m_navigatorVR->document(); 439 Document* doc = m_navigatorVR->document();
431 std::unique_ptr<UserGestureIndicator> gestureIndicator; 440 std::unique_ptr<UserGestureIndicator> gestureIndicator;
432 if (m_capabilities->hasExternalDisplay()) { 441 if (m_capabilities->hasExternalDisplay()) {
433 forceExitPresent(); 442 forceExitPresent();
434 DOMException* exception = DOMException::create( 443 DOMException* exception = DOMException::create(
435 InvalidStateError, 444 InvalidStateError,
436 "VR Presentation not implemented for this VRDisplay."); 445 "VR Presentation not implemented for this VRDisplay.");
437 resolver->reject(exception); 446 while (!m_pendingPresentResolvers.isEmpty()) {
447 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
448 resolver->reject(exception);
449 }
438 ReportPresentationResult( 450 ReportPresentationResult(
439 PresentationResult::PresentationNotSupportedByDisplay); 451 PresentationResult::PresentationNotSupportedByDisplay);
440 return; 452 return;
441 } else { 453 } else {
442 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but 454 // TODO(klausw,crbug.com/655722): Need a proper VR compositor, but
443 // for the moment on mobile we'll just make the canvas fullscreen 455 // for the moment on mobile we'll just make the canvas fullscreen
444 // so that VrShell can pick it up through the standard (high 456 // so that VrShell can pick it up through the standard (high
445 // latency) compositing path. 457 // latency) compositing path.
446 auto canvas = m_layer.source(); 458 auto canvas = m_layer.source();
447 auto inlineStyle = canvas->inlineStyle(); 459 auto inlineStyle = canvas->inlineStyle();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 if (doc) { 498 if (doc) {
487 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess", 499 Platform::current()->recordRapporURL("VR.WebVR.PresentSuccess",
488 WebURL(doc->url())); 500 WebURL(doc->url()));
489 } 501 }
490 502
491 m_isPresenting = true; 503 m_isPresenting = true;
492 ReportPresentationResult(PresentationResult::Success); 504 ReportPresentationResult(PresentationResult::Success);
493 505
494 updateLayerBounds(); 506 updateLayerBounds();
495 507
496 resolver->resolve(); 508 while (!m_pendingPresentResolvers.isEmpty()) {
509 ScriptPromiseResolver* resolver = m_pendingPresentResolvers.takeFirst();
510 resolver->resolve();
511 }
497 OnPresentChange(); 512 OnPresentChange();
498 } 513 }
499 514
500 void VRDisplay::forceExitPresent() { 515 void VRDisplay::forceExitPresent() {
501 if (m_isPresenting) { 516 if (m_isPresenting) {
502 if (!m_capabilities->hasExternalDisplay()) { 517 if (!m_capabilities->hasExternalDisplay()) {
503 auto canvas = m_layer.source(); 518 auto canvas = m_layer.source();
504 Fullscreen::fullyExitFullscreen(canvas->document()); 519 Fullscreen::fullyExitFullscreen(canvas->document());
505 m_fullscreenCheckTimer.stop(); 520 m_fullscreenCheckTimer.stop();
506 if (!m_fullscreenOrigWidth.isNull()) { 521 if (!m_fullscreenOrigWidth.isNull()) {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 743
729 DEFINE_TRACE(VRDisplay) { 744 DEFINE_TRACE(VRDisplay) {
730 visitor->trace(m_navigatorVR); 745 visitor->trace(m_navigatorVR);
731 visitor->trace(m_capabilities); 746 visitor->trace(m_capabilities);
732 visitor->trace(m_stageParameters); 747 visitor->trace(m_stageParameters);
733 visitor->trace(m_eyeParametersLeft); 748 visitor->trace(m_eyeParametersLeft);
734 visitor->trace(m_eyeParametersRight); 749 visitor->trace(m_eyeParametersRight);
735 visitor->trace(m_layer); 750 visitor->trace(m_layer);
736 visitor->trace(m_renderingContext); 751 visitor->trace(m_renderingContext);
737 visitor->trace(m_scriptedAnimationController); 752 visitor->trace(m_scriptedAnimationController);
753 visitor->trace(m_pendingPresentResolvers);
738 } 754 }
739 755
740 } // namespace blink 756 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/vr/VRDisplay.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698