OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 #endif | 361 #endif |
362 , m_initialPlayWithoutUserGestures(false) | 362 , m_initialPlayWithoutUserGestures(false) |
363 , m_autoplayMediaCounted(false) | 363 , m_autoplayMediaCounted(false) |
364 , m_audioTracks(AudioTrackList::create(*this)) | 364 , m_audioTracks(AudioTrackList::create(*this)) |
365 , m_videoTracks(VideoTrackList::create(*this)) | 365 , m_videoTracks(VideoTrackList::create(*this)) |
366 , m_textTracks(nullptr) | 366 , m_textTracks(nullptr) |
367 #if ENABLE(WEB_AUDIO) | 367 #if ENABLE(WEB_AUDIO) |
368 , m_audioSourceNode(nullptr) | 368 , m_audioSourceNode(nullptr) |
369 #endif | 369 #endif |
370 { | 370 { |
371 #if ENABLE(OILPAN) | |
372 ThreadState::current()->registerPreFinalizer(*this); | |
373 #endif | |
371 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); | 374 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); |
372 | 375 |
373 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 376 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
374 | 377 |
375 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) | 378 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) |
376 m_userGestureRequiredForPlay = true; | 379 m_userGestureRequiredForPlay = true; |
377 | 380 |
378 setHasCustomStyleCallbacks(); | 381 setHasCustomStyleCallbacks(); |
379 addElementToDocumentMap(this, &document); | 382 addElementToDocumentMap(this, &document); |
380 } | 383 } |
381 | 384 |
382 HTMLMediaElement::~HTMLMediaElement() | 385 HTMLMediaElement::~HTMLMediaElement() |
383 { | 386 { |
384 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); | 387 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); |
385 | 388 |
386 #if ENABLE(OILPAN) | 389 #if ENABLE(OILPAN) |
387 // If the HTMLMediaElement dies with the document we are not | 390 if (m_closeMediaSourceWhenFinalizing) |
haraken
2015/06/17 20:29:02
I guess this hack could be moved to the pre-finali
sof
2015/06/17 20:40:46
I don't think it can be, as it allocates & fires a
haraken
2015/06/17 20:47:15
Allocation is allowed in pre-finalizers.
closeMed
| |
388 // allowed to touch the document to adjust delay load event counts | 391 closeMediaSource(); |
389 // because the document could have been already | 392 |
390 // destructed. However, if the HTMLMediaElement dies with the | 393 // Oilpan: the player must be released, but the player object |
391 // document there is no need to change the delayed load counts | 394 // cannot safely access this player client any longer as parts of |
392 // because no load event will fire anyway. If the document is | 395 // it may have been finalized already (like the media element's |
393 // still alive we do have to decrement the load delay counts. We | 396 // supplementable table.) Handled for now by entering an |
394 // determine if the document is alive via the ActiveDOMObject | 397 // is-finalizing state, which is explicitly checked for if the |
395 // which is a context lifecycle observer. If the Document has been | 398 // player tries to access the media element during shutdown. |
396 // destructed ActiveDOMObject::executionContext() returns 0. | 399 // |
397 if (ActiveDOMObject::executionContext()) | 400 // FIXME: Oilpan: move the media player to the heap instead and |
398 setShouldDelayLoadEvent(false); | 401 // avoid having to finalize it from here; this whole #if block |
402 // could then be removed (along with the state bit it depends on.) | |
403 // crbug.com/378229 | |
404 m_isFinalizing = true; | |
399 #else | 405 #else |
400 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 406 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
401 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in | 407 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in |
402 // the same GC. We don't need to close it explicitly in Oilpan. | 408 // the same GC. We don't need to close it explicitly in Oilpan. |
403 m_asyncEventQueue->close(); | 409 m_asyncEventQueue->close(); |
404 | 410 |
405 setShouldDelayLoadEvent(false); | 411 setShouldDelayLoadEvent(false); |
406 | 412 |
407 if (m_textTracks) | 413 if (m_textTracks) |
408 m_textTracks->clearOwner(); | 414 m_textTracks->clearOwner(); |
409 m_audioTracks->shutdown(); | 415 m_audioTracks->shutdown(); |
410 m_videoTracks->shutdown(); | 416 m_videoTracks->shutdown(); |
411 | 417 |
412 if (m_mediaController) { | 418 if (m_mediaController) { |
413 m_mediaController->removeMediaElement(this); | 419 m_mediaController->removeMediaElement(this); |
414 m_mediaController = nullptr; | 420 m_mediaController = nullptr; |
415 } | 421 } |
416 #endif | |
417 | |
418 #if ENABLE(OILPAN) | |
419 if (m_closeMediaSourceWhenFinalizing) | |
420 closeMediaSource(); | |
421 #else | |
422 closeMediaSource(); | 422 closeMediaSource(); |
423 | 423 |
424 removeElementFromDocumentMap(this, &document()); | 424 removeElementFromDocumentMap(this, &document()); |
425 #endif | 425 #endif |
426 | 426 |
427 // Destroying the player may cause a resource load to be canceled, | 427 // Destroying the player may cause a resource load to be canceled, |
428 // which could result in userCancelledLoad() being called back. | 428 // which could result in userCancelledLoad() being called back. |
429 // Setting m_completelyLoaded ensures that such a call will not cause | 429 // Setting m_completelyLoaded ensures that such a call will not cause |
430 // us to dispatch an abort event, which would result in a crash. | 430 // us to dispatch an abort event, which would result in a crash. |
431 // See http://crbug.com/233654 for more details. | 431 // See http://crbug.com/233654 for more details. |
432 m_completelyLoaded = true; | 432 m_completelyLoaded = true; |
433 | 433 |
434 // With Oilpan load events on the Document are always delayed during | 434 // With Oilpan load events on the Document are always delayed during |
435 // sweeping so we don't need to explicitly increment and decrement | 435 // sweeping so we don't need to explicitly increment and decrement |
436 // load event delay counts. | 436 // load event delay counts. |
437 #if !ENABLE(OILPAN) | 437 #if !ENABLE(OILPAN) |
438 // Destroying the player may cause a resource load to be canceled, | 438 // Destroying the player may cause a resource load to be canceled, |
439 // which could result in Document::dispatchWindowLoadEvent() being | 439 // which could result in Document::dispatchWindowLoadEvent() being |
440 // called via ResourceFetch::didLoadResource() then | 440 // called via ResourceFetch::didLoadResource() then |
441 // FrameLoader::checkCompleted(). To prevent load event dispatching during | 441 // FrameLoader::checkCompleted(). To prevent load event dispatching during |
442 // object destruction, we use Document::incrementLoadEventDelayCount(). | 442 // object destruction, we use Document::incrementLoadEventDelayCount(). |
443 // See http://crbug.com/275223 for more details. | 443 // See http://crbug.com/275223 for more details. |
444 document().incrementLoadEventDelayCount(); | 444 document().incrementLoadEventDelayCount(); |
445 #endif | 445 #endif |
446 | 446 |
447 #if ENABLE(OILPAN) | |
448 // Oilpan: the player must be released, but the player object | |
449 // cannot safely access this player client any longer as parts of | |
450 // it may have been finalized already (like the media element's | |
451 // supplementable table.) Handled for now by entering an | |
452 // is-finalizing state, which is explicitly checked for if the | |
453 // player tries to access the media element during shutdown. | |
454 // | |
455 // FIXME: Oilpan: move the media player to the heap instead and | |
456 // avoid having to finalize it from here; this whole #if block | |
457 // could then be removed (along with the state bit it depends on.) | |
458 // crbug.com/378229 | |
459 m_isFinalizing = true; | |
460 #endif | |
461 | |
462 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). | 447 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). |
463 // Since AudioNode::dispose() is guaranteed to be always called before | 448 // Since AudioNode::dispose() is guaranteed to be always called before |
464 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared | 449 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared |
465 // even if the AudioNode and the HTMLMediaElement die together. | 450 // even if the AudioNode and the HTMLMediaElement die together. |
466 #if ENABLE(WEB_AUDIO) | 451 #if ENABLE(WEB_AUDIO) |
467 ASSERT(!m_audioSourceNode); | 452 ASSERT(!m_audioSourceNode); |
468 #endif | 453 #endif |
469 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 454 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
470 | 455 |
471 #if !ENABLE(OILPAN) | 456 #if !ENABLE(OILPAN) |
472 document().decrementLoadEventDelayCount(); | 457 document().decrementLoadEventDelayCount(); |
473 #endif | 458 #endif |
474 } | 459 } |
475 | 460 |
476 #if ENABLE(OILPAN) | 461 #if ENABLE(OILPAN) |
462 void HTMLMediaElement::dispose() | |
463 { | |
464 // If the HTMLMediaElement dies with the Document we are not | |
465 // allowed to touch the Document to adjust delay load event counts | |
466 // from the destructor, as the Document could have been already | |
467 // destructed. | |
468 // | |
469 // Work around that restriction by accessing the Document from | |
470 // a prefinalizer action instead, updating its delayed load count. | |
471 // If needed - if the Document has been detached and informed its | |
472 // ContextLifecycleObservers (which HTMLMediaElement is) that | |
473 // it is being destroyed, the connection to the Document will | |
474 // have been severed already, but in that case there is no need | |
475 // to update the delayed load count. But if the Document hasn't | |
476 // been detached cleanly from any frame or it isn't dying in the | |
477 // same GC, we do update the delayed load count from the prefinalizer. | |
478 if (ActiveDOMObject::executionContext()) | |
479 setShouldDelayLoadEvent(false); | |
480 } | |
481 | |
477 void HTMLMediaElement::setCloseMediaSourceWhenFinalizing() | 482 void HTMLMediaElement::setCloseMediaSourceWhenFinalizing() |
478 { | 483 { |
479 ASSERT(!m_closeMediaSourceWhenFinalizing); | 484 ASSERT(!m_closeMediaSourceWhenFinalizing); |
480 m_closeMediaSourceWhenFinalizing = true; | 485 m_closeMediaSourceWhenFinalizing = true; |
481 } | 486 } |
482 #endif | 487 #endif |
483 | 488 |
484 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) | 489 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) |
485 { | 490 { |
486 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); | 491 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); |
(...skipping 3180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3667 | 3672 |
3668 #if ENABLE(WEB_AUDIO) | 3673 #if ENABLE(WEB_AUDIO) |
3669 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 3674 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
3670 { | 3675 { |
3671 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider()) | 3676 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider()) |
3672 audioSourceProvider()->setClient(nullptr); | 3677 audioSourceProvider()->setClient(nullptr); |
3673 } | 3678 } |
3674 #endif | 3679 #endif |
3675 | 3680 |
3676 } | 3681 } |
OLD | NEW |