[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
eric.carlson at apple.com
eric.carlson at apple.com
Wed Dec 22 11:47:52 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 2e9a595fe029fa45dd780ec2d705d94ad6562616
Author: eric.carlson at apple.com <eric.carlson at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Aug 6 23:35:55 2010 +0000
2010-08-06 Eric Carlson <eric.carlson at apple.com>
Reviewed by Simon Fraser.
HTML5 "video" tag with poster frame defined "flashes" right before movie displays
https://bugs.webkit.org/show_bug.cgi?id=37591
<rdar://problem/5650561>
If a video element has a poster frame, display it until the playback is requested or the movie's
time is changed.
Test: compositing/video/video-poster.html
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_displayMode.
(WebCore::HTMLMediaElement::prepareForLoad): Set m_displayMode to Unknown.
(WebCore::HTMLMediaElement::loadResource): Call updateDisplayState to let it set configure
the poster, if necessary.
(WebCore::HTMLMediaElement::noneSupported): updatePosterImage -> updateDisplayState.
(WebCore::HTMLMediaElement::setNetworkState): Ditto.
(WebCore::HTMLMediaElement::setReadyState): Ditto.
(WebCore::HTMLMediaElement::finishSeek): Set display mode to Video so a video frame will be
displayed if a poster is currently visible.
(WebCore::HTMLMediaElement::mediaPlayerRepaint): updatePosterImage -> updateDisplayState.
(WebCore::HTMLMediaElement::updatePlayState): Set display mode to Video.
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::displayMode): New.
(WebCore::HTMLMediaElement::setDisplayMode): Ditto.
(WebCore::HTMLMediaElement::updateDisplayState): Ditto.
* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::HTMLVideoElement): Remove m_shouldDisplayPosterImage.
(WebCore::HTMLVideoElement::attach): Call shouldDisplayPosterImage instead of checking
m_shouldDisplayPosterImage directly.
(WebCore::HTMLVideoElement::detach): Ditto.
(WebCore::HTMLVideoElement::parseMappedAttribute): Set m_displayMode to Unknown before calling
updateDisplayState so shouldDisplayPosterImage() will return the correct result. Remove the
PLUGIN_PROXY_FOR_VIDEO code, it is now in updateDisplayState.
(WebCore::HTMLVideoElement::setDisplayMode): Renamed from updatePosterImage and rework logic
so we tell the media engine it is OK to display video frames when there is no poster, or
once the media engine has something to display and the movie has started or seeked.
(WebCore::HTMLVideoElement::updateDisplayState): New, manage display mode based on poster
attribute.
* html/HTMLVideoElement.h:
(WebCore::HTMLVideoElement::shouldDisplayPosterImage):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::prepareForRendering): New, call media engine's prepareForRendering.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::prepareForRendering):
* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_isAllowedToRender.
(WebCore::MediaPlayerPrivate::setUpVideoRendering):
(WebCore::MediaPlayerPrivate::isReadyForVideoSetup): Renamed from isReadyForRendering.
(WebCore::MediaPlayerPrivate::prepareForRendering): New, set m_isAllowedToRender and
inform the client that render tree should be updated so we correctly switch from showing
the poster, which often doens't use a layer, to showing video frames, which do.
(WebCore::MediaPlayerPrivate::updateStates): Don't call setUpVideoRendering until
isReadyForVideoSetup() returns true.
(WebCore::MediaPlayerPrivate::supportsAcceleratedRendering): isReadyForRendering -> isReadyForVideoSetup
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::containsPaintedContent): Only consider video when displaying
video frames so a poster won't force compositing mode.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForVideo): Ditto.
* rendering/RenderVideo.cpp:
(WebCore::RenderVideo::shouldDisplayVideo): New, return true when not displaying a poster.
* rendering/RenderVideo.h:
2010-08-06 Eric Carlson <eric.carlson at apple.com>
Reviewed by Simon Fraser.
HTML5 "video" tag with poster frame defined "flashes" right before movie displays
https://bugs.webkit.org/show_bug.cgi?id=37591
<rdar://problem/5650561>
If a video element has a poster frame, display it until the playback is requested or the movie's
time is changed. Test this by ensuring that an element with a poster doesn't have layers while
and element with one does.
* compositing/video/video-poster-expected.txt: Added.
* compositing/video/video-poster.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64884 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 943e9c8..bd433be 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2010-08-06 Eric Carlson <eric.carlson at apple.com>
+
+ Reviewed by Simon Fraser.
+
+ HTML5 "video" tag with poster frame defined "flashes" right before movie displays
+ https://bugs.webkit.org/show_bug.cgi?id=37591
+ <rdar://problem/5650561>
+
+ If a video element has a poster frame, display it until the playback is requested or the movie's
+ time is changed. Test this by ensuring that an element with a poster doesn't have layers while
+ and element with one does.
+
+ * compositing/video/video-poster-expected.txt: Added.
+ * compositing/video/video-poster.html: Added.
+
2010-08-06 Dimitri Glazkov <dglazkov at chromium.org>
[Chromium/DRT] Update expectation overrides for Windows.
diff --git a/LayoutTests/compositing/video/video-poster-expected.txt b/LayoutTests/compositing/video/video-poster-expected.txt
new file mode 100644
index 0000000..cf29f9e
--- /dev/null
+++ b/LayoutTests/compositing/video/video-poster-expected.txt
@@ -0,0 +1,13 @@
+A <video> should not have a layer until playback begins.
+This test can not be run manually, it requires layoutTestController.layerTreeAsText.
+
+No src, no poster
+ PASS: wants layers = false, has layers = false
+
+Displaying poster
+ PASS: wants layers = false, has layers = false
+
+Playing movie
+ PASS: wants layers = true, has layers = true
+
+
diff --git a/LayoutTests/compositing/video/video-poster.html b/LayoutTests/compositing/video/video-poster.html
new file mode 100644
index 0000000..6f62010
--- /dev/null
+++ b/LayoutTests/compositing/video/video-poster.html
@@ -0,0 +1,66 @@
+<!DOCTYPE>
+<html>
+ <head>
+ <title>Video with poster</title>
+ <script>
+
+ var count = 0;
+ function log(str)
+ {
+ document.getElementById('result').innerHTML += str + "<br>";
+ }
+
+ function hasLayers()
+ {
+ if (window.layoutTestController)
+ return layoutTestController.layerTreeAsText() != "";
+ return false;
+ }
+
+ function checkLayers(prefix, wantsLayers)
+ {
+ var layers = hasLayers();
+ log(prefix + " <br> " + (wantsLayers == layers ? "PASS" : "FAIL") + ": wants layers = " + wantsLayers + ", has layers = " + layers);
+ log("");
+ }
+
+ function layerTest()
+ {
+ var video = document.getElementsByTagName('video')[0];
+
+ switch (event.type)
+ {
+ case "load":
+ checkLayers("No src, no poster", false);
+ video.src = "../resources/video.mp4"
+ video.poster = "../resources/apple.jpg";
+ break;
+ case "canplaythrough":
+ checkLayers("Displaying poster", false);
+ video.play();
+ break;
+ case "playing":
+ checkLayers("Playing movie", true);
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ break;
+ }
+ }
+
+ if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ }
+ window.addEventListener('load', layerTest, false);
+ </script>
+ </head>
+ <body>
+
+ <video oncanplaythrough="layerTest()" onplaying="layerTest()"></video>
+
+ <p>A <video> should not have a layer until playback begins.<br>
+ This test can not be run manually, it requires layoutTestController.layerTreeAsText.</p>
+ <p id="result"></p>
+
+ </body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 2b756d6..68e2271 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,78 @@
+2010-08-06 Eric Carlson <eric.carlson at apple.com>
+
+ Reviewed by Simon Fraser.
+
+ HTML5 "video" tag with poster frame defined "flashes" right before movie displays
+ https://bugs.webkit.org/show_bug.cgi?id=37591
+ <rdar://problem/5650561>
+
+ If a video element has a poster frame, display it until the playback is requested or the movie's
+ time is changed.
+
+ Test: compositing/video/video-poster.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_displayMode.
+ (WebCore::HTMLMediaElement::prepareForLoad): Set m_displayMode to Unknown.
+ (WebCore::HTMLMediaElement::loadResource): Call updateDisplayState to let it set configure
+ the poster, if necessary.
+ (WebCore::HTMLMediaElement::noneSupported): updatePosterImage -> updateDisplayState.
+ (WebCore::HTMLMediaElement::setNetworkState): Ditto.
+ (WebCore::HTMLMediaElement::setReadyState): Ditto.
+ (WebCore::HTMLMediaElement::finishSeek): Set display mode to Video so a video frame will be
+ displayed if a poster is currently visible.
+ (WebCore::HTMLMediaElement::mediaPlayerRepaint): updatePosterImage -> updateDisplayState.
+ (WebCore::HTMLMediaElement::updatePlayState): Set display mode to Video.
+ * html/HTMLMediaElement.h:
+ (WebCore::HTMLMediaElement::displayMode): New.
+ (WebCore::HTMLMediaElement::setDisplayMode): Ditto.
+ (WebCore::HTMLMediaElement::updateDisplayState): Ditto.
+
+ * html/HTMLVideoElement.cpp:
+ (WebCore::HTMLVideoElement::HTMLVideoElement): Remove m_shouldDisplayPosterImage.
+ (WebCore::HTMLVideoElement::attach): Call shouldDisplayPosterImage instead of checking
+ m_shouldDisplayPosterImage directly.
+ (WebCore::HTMLVideoElement::detach): Ditto.
+ (WebCore::HTMLVideoElement::parseMappedAttribute): Set m_displayMode to Unknown before calling
+ updateDisplayState so shouldDisplayPosterImage() will return the correct result. Remove the
+ PLUGIN_PROXY_FOR_VIDEO code, it is now in updateDisplayState.
+ (WebCore::HTMLVideoElement::setDisplayMode): Renamed from updatePosterImage and rework logic
+ so we tell the media engine it is OK to display video frames when there is no poster, or
+ once the media engine has something to display and the movie has started or seeked.
+ (WebCore::HTMLVideoElement::updateDisplayState): New, manage display mode based on poster
+ attribute.
+ * html/HTMLVideoElement.h:
+ (WebCore::HTMLVideoElement::shouldDisplayPosterImage):
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::prepareForRendering): New, call media engine's prepareForRendering.
+ * platform/graphics/MediaPlayer.h:
+ * platform/graphics/MediaPlayerPrivate.h:
+ (WebCore::MediaPlayerPrivateInterface::prepareForRendering):
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_isAllowedToRender.
+ (WebCore::MediaPlayerPrivate::setUpVideoRendering):
+ (WebCore::MediaPlayerPrivate::isReadyForVideoSetup): Renamed from isReadyForRendering.
+ (WebCore::MediaPlayerPrivate::prepareForRendering): New, set m_isAllowedToRender and
+ inform the client that render tree should be updated so we correctly switch from showing
+ the poster, which often doens't use a layer, to showing video frames, which do.
+ (WebCore::MediaPlayerPrivate::updateStates): Don't call setUpVideoRendering until
+ isReadyForVideoSetup() returns true.
+ (WebCore::MediaPlayerPrivate::supportsAcceleratedRendering): isReadyForRendering -> isReadyForVideoSetup
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::containsPaintedContent): Only consider video when displaying
+ video frames so a poster won't force compositing mode.
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::requiresCompositingForVideo): Ditto.
+
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::shouldDisplayVideo): New, return true when not displaying a poster.
+ * rendering/RenderVideo.h:
+
2010-08-06 James Robinson <jamesr at chromium.org>
Reviewed by Simon Fraser.
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 34f54aa..ecd6c03 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -108,8 +108,9 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
#endif
, m_restrictions(NoRestrictions)
, m_preload(MediaPlayer::Auto)
- , m_playing(false)
+ , m_displayMode(Unknown)
, m_processingMediaPlayerCallback(0)
+ , m_playing(false)
, m_isWaitingUntilMediaCanStart(false)
, m_processingLoad(false)
, m_delayingTheLoadEvent(false)
@@ -494,6 +495,7 @@ void HTMLMediaElement::prepareForLoad()
m_sentStalledEvent = false;
m_haveFiredLoadedData = false;
m_completelyLoaded = false;
+ m_displayMode = Unknown;
// 1 - Abort any already-running instance of the resource selection algorithm for this element.
m_currentSourceNode = 0;
@@ -533,7 +535,6 @@ void HTMLMediaElement::prepareForLoad()
m_playedTimeRanges = TimeRanges::create();
m_lastSeekTime = 0;
m_closedCaptionsVisible = false;
-
}
void HTMLMediaElement::loadInternal()
@@ -665,11 +666,9 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
m_player->load(m_currentSrc, contentType);
- if (isVideo() && m_player->canLoadPoster()) {
- KURL posterURL = getNonEmptyURLAttribute(posterAttr);
- if (!posterURL.isEmpty())
- m_player->setPoster(posterURL);
- }
+ // If there is no poster to display, allow the media engine to render video frames as soon as
+ // they are available.
+ updateDisplayState();
if (renderer())
renderer()->updateFromElement();
@@ -740,7 +739,7 @@ void HTMLMediaElement::noneSupported()
// 9 -Abort these steps. Until the load() method is invoked, the element won't attempt to load another resource.
- updatePosterImage();
+ updateDisplayState();
if (renderer())
renderer()->updateFromElement();
@@ -829,7 +828,7 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
else if (state == MediaPlayer::FormatError && m_loadState == LoadingFromSrcAttr)
noneSupported();
- updatePosterImage();
+ updateDisplayState();
return;
}
@@ -921,7 +920,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
m_player->seek(0);
}
- bool shouldUpdatePosterImage = false;
+ bool shouldUpdateDisplayState = false;
// 4.8.10.7 says loadeddata is sent only when the new state *is* HAVE_CURRENT_DATA: "If the
// previous ready state was HAVE_METADATA and the new ready state is HAVE_CURRENT_DATA",
@@ -930,7 +929,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
// We go with the later because it seems useful to count on getting this event
if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
m_haveFiredLoadedData = true;
- shouldUpdatePosterImage = true;
+ shouldUpdateDisplayState = true;
scheduleEvent(eventNames().loadeddataEvent);
}
@@ -939,7 +938,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
scheduleEvent(eventNames().canplayEvent);
if (isPotentiallyPlaying)
scheduleEvent(eventNames().playingEvent);
- shouldUpdatePosterImage = true;
+ shouldUpdateDisplayState = true;
}
if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) {
@@ -957,11 +956,11 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
scheduleEvent(eventNames().playingEvent);
}
- shouldUpdatePosterImage = true;
+ shouldUpdateDisplayState = true;
}
- if (shouldUpdatePosterImage)
- updatePosterImage();
+ if (shouldUpdateDisplayState)
+ updateDisplayState();
updatePlayState();
}
@@ -1065,7 +1064,6 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
m_player->seek(time);
// 10-15 are handled, if necessary, when the engine signals a readystate change.
-
}
void HTMLMediaElement::finishSeek()
@@ -1075,6 +1073,8 @@ void HTMLMediaElement::finishSeek()
// 4.8.10.10 Seeking step 13
scheduleEvent(eventNames().seekedEvent);
+
+ setDisplayMode(Video);
}
HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
@@ -1613,10 +1613,9 @@ void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
+ updateDisplayState();
if (renderer())
renderer()->repaint();
-
- updatePosterImage();
endProcessingMediaPlayerCallback();
}
@@ -1777,6 +1776,8 @@ void HTMLMediaElement::updatePlayState()
bool shouldBePlaying = potentiallyPlaying();
bool playerPaused = m_player->paused();
if (shouldBePlaying && playerPaused) {
+ setDisplayMode(Video);
+
// Set rate before calling play in case the rate was set before the media engine wasn't setup.
// The media engine should just stash the rate since it isn't already playing.
m_player->setRate(m_playbackRate);
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index eede363..aeec188 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -178,6 +178,10 @@ protected:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
+ enum DisplayMode { Unknown, None, Poster, Video };
+ DisplayMode displayMode() const { return m_displayMode; }
+ virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
+
private:
virtual bool checkDTD(const Node* newChild);
virtual void attributeChanged(Attribute*, bool preserveDecls);
@@ -195,7 +199,8 @@ private:
virtual void documentWillBecomeInactive();
virtual void documentDidBecomeActive();
virtual void mediaVolumeDidChange();
- virtual void updatePosterImage() { }
+
+ virtual void updateDisplayState() { }
void setReadyState(MediaPlayer::ReadyState);
void setNetworkState(MediaPlayer::NetworkState);
@@ -254,7 +259,8 @@ private:
void pauseInternal();
void prepareForLoad();
-
+ void allowVideoRendering();
+
bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
@@ -326,14 +332,14 @@ private:
MediaPlayer::Preload m_preload;
- bool m_playing;
+ DisplayMode m_displayMode;
// Counter incremented while processing a callback from the media player, so we can avoid
// calling the media engine recursively.
int m_processingMediaPlayerCallback;
- bool m_isWaitingUntilMediaCanStart;
-
+ bool m_playing : 1;
+ bool m_isWaitingUntilMediaCanStart : 1;
bool m_processingLoad : 1;
bool m_delayingTheLoadEvent : 1;
bool m_haveFiredLoadedData : 1;
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index bfdf241..fc74d32 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -47,7 +47,6 @@ using namespace HTMLNames;
inline HTMLVideoElement::HTMLVideoElement(const QualifiedName& tagName, Document* document)
: HTMLMediaElement(tagName, document)
- , m_shouldDisplayPosterImage(false)
{
ASSERT(hasTagName(videoTag));
}
@@ -74,8 +73,8 @@ void HTMLVideoElement::attach()
HTMLMediaElement::attach();
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- updatePosterImage();
- if (m_shouldDisplayPosterImage) {
+ updateDisplayState();
+ if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
@@ -91,9 +90,8 @@ void HTMLVideoElement::detach()
{
HTMLMediaElement::detach();
- if (!m_shouldDisplayPosterImage)
- if (m_imageLoader)
- m_imageLoader.clear();
+ if (!shouldDisplayPosterImage() && m_imageLoader)
+ m_imageLoader.clear();
}
void HTMLVideoElement::parseMappedAttribute(Attribute* attr)
@@ -101,15 +99,14 @@ void HTMLVideoElement::parseMappedAttribute(Attribute* attr)
const QualifiedName& attrName = attr->name();
if (attrName == posterAttr) {
- updatePosterImage();
- if (m_shouldDisplayPosterImage) {
+ // Force a poster recalc by setting m_displayMode to Unknown directly before calling updateDisplayState.
+ HTMLMediaElement::setDisplayMode(Unknown);
+ updateDisplayState();
+ if (shouldDisplayPosterImage()) {
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (!m_imageLoader)
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
-#else
- if (player())
- player()->setPoster(getNonEmptyURLAttribute(posterAttr));
#endif
}
} else if (attrName == widthAttr)
@@ -172,20 +169,42 @@ const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
return posterAttr;
}
-void HTMLVideoElement::updatePosterImage()
+void HTMLVideoElement::setDisplayMode(DisplayMode mode)
{
-#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- bool oldShouldShowPosterImage = m_shouldDisplayPosterImage;
-#endif
+ DisplayMode oldMode = displayMode();
+ KURL poster = getNonEmptyURLAttribute(posterAttr);
+
+ if (!poster.isEmpty()) {
+ // We have a poster path, but only show it until the user triggers display by playing or seeking and the
+ // media engine has something to display.
+ if (mode == Video) {
+ if (oldMode != Video && player())
+ player()->prepareForRendering();
+ if (!hasAvailableVideoFrame())
+ mode = Poster;
+ }
+ } else if (oldMode != Video && player())
+ player()->prepareForRendering();
+
+ HTMLMediaElement::setDisplayMode(mode);
- m_shouldDisplayPosterImage = !getAttribute(posterAttr).isEmpty() && !hasAvailableVideoFrame();
+ if (player() && player()->canLoadPoster())
+ player()->setPoster(poster);
#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- if (renderer() && oldShouldShowPosterImage != m_shouldDisplayPosterImage)
+ if (renderer() && displayMode() != oldMode)
renderer()->updateFromElement();
#endif
}
+void HTMLVideoElement::updateDisplayState()
+{
+ if (getNonEmptyURLAttribute(posterAttr).isEmpty())
+ setDisplayMode(Video);
+ else if (displayMode() < Poster)
+ setDisplayMode(Poster);
+}
+
void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
{
MediaPlayer* player = HTMLMediaElement::player();
diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h
index e7c3f34..04a0beb 100644
--- a/WebCore/html/HTMLVideoElement.h
+++ b/WebCore/html/HTMLVideoElement.h
@@ -55,11 +55,11 @@ public:
void webkitEnterFullScreen(bool isUserGesture, ExceptionCode& ec) { webkitEnterFullscreen(isUserGesture, ec); }
void webkitExitFullScreen() { webkitExitFullscreen(); }
- bool shouldDisplayPosterImage() const { return m_shouldDisplayPosterImage; }
-
// Used by canvas to gain raw pixel access
void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+ bool shouldDisplayPosterImage() const { return displayMode() == Poster; }
+
private:
HTMLVideoElement(const QualifiedName&, Document*);
@@ -78,11 +78,14 @@ private:
virtual const QualifiedName& imageSourceAttributeName() const;
virtual bool hasAvailableVideoFrame() const;
- virtual void updatePosterImage();
+ virtual void updateDisplayState();
+
virtual void willMoveToNewOwnerDocument();
+ virtual void setDisplayMode(DisplayMode);
+
OwnPtr<HTMLImageLoader> m_imageLoader;
- bool m_shouldDisplayPosterImage;
+
};
} //namespace
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 4fb01c8..0732116 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -292,6 +292,11 @@ bool MediaPlayer::hasAvailableVideoFrame() const
return m_private->hasAvailableVideoFrame();
}
+void MediaPlayer::prepareForRendering()
+{
+ return m_private->prepareForRendering();
+}
+
bool MediaPlayer::canLoadPoster() const
{
return m_private->canLoadPoster();
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 6945872..be4f672 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -246,6 +246,7 @@ public:
MediaPlayerClient* mediaPlayerClient() const { return m_mediaPlayerClient; }
bool hasAvailableVideoFrame() const;
+ void prepareForRendering();
bool canLoadPoster() const;
void setPoster(const String&);
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index 40aeacb..37e3ced 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -123,6 +123,8 @@ public:
virtual MediaPlayer::MovieLoadType movieLoadType() const { return MediaPlayer::Unknown; }
+ virtual void prepareForRendering() { }
+
};
}
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 2636aeb..3895a00 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -59,7 +59,6 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
public:
static void registerMediaEngine(MediaEngineRegistrar);
-
void repaint();
void loadStateChanged();
void rateChanged();
@@ -127,6 +126,8 @@ private:
void paint(GraphicsContext*, const IntRect&);
void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+ virtual void prepareForRendering();
+
#if USE(ACCELERATED_COMPOSITING)
bool supportsAcceleratedRendering() const;
@@ -170,7 +171,7 @@ private:
void cacheMovieScale();
bool metaDataAvailable() const { return m_qtMovie && m_readyState >= MediaPlayer::HaveMetadata; }
- bool isReadyForRendering() const;
+ bool isReadyForVideoSetup() const;
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
@@ -197,6 +198,7 @@ private:
bool m_hasUnsupportedTracks;
bool m_videoFrameHasDrawn;
bool m_delayingLoad;
+ bool m_isAllowedToRender;
#if DRAW_FRAME_RATE
int m_frameCountWhilePlaying;
double m_timeStartedPlaying;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 5c327f9..435e56e 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -217,6 +217,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_visible(false)
, m_hasUnsupportedTracks(false)
, m_videoFrameHasDrawn(false)
+ , m_isAllowedToRender(false)
#if DRAW_FRAME_RATE
, m_frameCountWhilePlaying(0)
, m_timeStartedPlaying(0)
@@ -495,7 +496,7 @@ MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::preferredRenderingMod
void MediaPlayerPrivate::setUpVideoRendering()
{
- if (!isReadyForRendering())
+ if (!isReadyForVideoSetup())
return;
MediaRenderingMode currentMode = currentRenderingMode();
@@ -519,10 +520,9 @@ void MediaPlayerPrivate::setUpVideoRendering()
break;
}
-#if USE(ACCELERATED_COMPOSITING)
+ // If using a movie layer, inform the client so the compositing tree is updated.
if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
-#endif
}
void MediaPlayerPrivate::tearDownVideoRendering()
@@ -915,11 +915,26 @@ void MediaPlayerPrivate::cacheMovieScale()
m_scaleFactor.setHeight(initialSize.height / naturalSize.height);
}
-bool MediaPlayerPrivate::isReadyForRendering() const
+bool MediaPlayerPrivate::isReadyForVideoSetup() const
{
return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
}
+void MediaPlayerPrivate::prepareForRendering()
+{
+ if (m_isAllowedToRender)
+ return;
+ m_isAllowedToRender = true;
+
+ if (!hasSetUpVideoRendering())
+ setUpVideoRendering();
+
+ // If using a movie layer, inform the client so the compositing tree is updated. This is crucial if the movie
+ // has a poster, as it will most likely not have a layer and we will now be rendering frames to the movie layer.
+ if (currentRenderingMode() == MediaRenderingMovieLayer || preferredRenderingMode() == MediaRenderingMovieLayer)
+ m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
+}
+
void MediaPlayerPrivate::updateStates()
{
MediaPlayer::NetworkState oldNetworkState = m_networkState;
@@ -1009,7 +1024,7 @@ void MediaPlayerPrivate::updateStates()
}
}
- if (!hasSetUpVideoRendering())
+ if (isReadyForVideoSetup() && !hasSetUpVideoRendering())
setUpVideoRendering();
if (seeking())
@@ -1443,8 +1458,9 @@ void MediaPlayerPrivate::sawUnsupportedTracks()
#if USE(ACCELERATED_COMPOSITING)
bool MediaPlayerPrivate::supportsAcceleratedRendering() const
{
- // When in the media document we render via QTMovieView, which is already accelerated.
- return isReadyForRendering() && getQTMovieLayerClass() != Nil && !m_player->inMediaDocument();
+ // Also don't claim to support accelerated rendering when in the media document, as we will then render
+ // via QTMovieView which is already accelerated.
+ return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil && !m_player->inMediaDocument();
}
void MediaPlayerPrivate::acceleratedRenderingStateChanged()
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index b3a7917..68dc4d8 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -759,7 +759,7 @@ bool RenderLayerBacking::containsPaintedContent() const
// FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
// and set background color on the layer in that case, instead of allocating backing store and painting.
- if (renderer()->isVideo())
+ if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
return hasBoxDecorationsOrBackground(renderer());
#if ENABLE(3D_CANVAS) || ENABLE(ACCELERATED_2D_CANVAS)
if (isAcceleratedCanvas(renderer()))
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 7798dfb..a8cf4e9 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1163,7 +1163,7 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer)
#if ENABLE(VIDEO)
if (renderer->isVideo()) {
RenderVideo* video = toRenderVideo(renderer);
- return canAccelerateVideoRendering(video);
+ return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
}
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
else if (renderer->isRenderPart()) {
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index 610fb5f..1e0adc4 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -155,7 +155,12 @@ IntRect RenderVideo::videoBox() const
return renderBox;
}
-
+
+bool RenderVideo::shouldDisplayVideo() const
+{
+ return !videoElement()->shouldDisplayPosterImage();
+}
+
void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
MediaPlayer* mediaPlayer = player();
@@ -174,6 +179,7 @@ void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
if (rect.isEmpty())
return;
rect.move(tx, ty);
+
if (displayingPoster)
paintIntoRect(paintInfo.context, rect);
else
diff --git a/WebCore/rendering/RenderVideo.h b/WebCore/rendering/RenderVideo.h
index bb2b05c..d2f0ed4 100644
--- a/WebCore/rendering/RenderVideo.h
+++ b/WebCore/rendering/RenderVideo.h
@@ -50,6 +50,8 @@ public:
void acceleratedRenderingStateChanged();
#endif
+ virtual bool shouldDisplayVideo() const;
+
private:
virtual void updateFromElement();
inline HTMLVideoElement* videoElement() const;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list