Commit 62178891 authored by simon.fraser@apple.com's avatar simon.fraser@apple.com
Browse files

2010-02-16 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Eric Carlson.

        Autoplaying video with poster doesn't reliably show up
        https://bugs.webkit.org/show_bug.cgi?id=34966

        A timing issue with compositing updates when replacing the poster image
        with the video could cause the video to not display.

        Fix by making video layer hook up more similar to WebGL etc, by having the
        video kick off a recalcStyle() via a SyntheticStyleChange. This requires
        vending a PlaformLayer* from the media player, up through the element.

        Test: media/video-replaces-poster.html

        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::mediaPlayerRenderingModeChanged): Use setNeedsStyleRecalc()
        to kick off a compositing update.

        * html/HTMLMediaElement.h:
        (WebCore::HTMLMediaElement::platformLayer): Export the media engine's layer.

        * platform/graphics/MediaPlayer.cpp:
        (WebCore::NullMediaPlayerPrivate::platformLayer): Method to vend the media layer.
        (WebCore::MediaPlayer::platformLayer):

        * platform/graphics/MediaPlayer.h:
        (WebCore::MediaPlayerClient::mediaPlayerRenderingModeChanged): New client callback
        to indicate that the rendering mode changed. The element uses this to kick off a
        recalcStyle.

        * platform/graphics/MediaPlayerPrivate.h:
        (WebCore::MediaPlayerPrivateInterface::platformLayer): Method to vend the media layer.
        * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Ditto
        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
        (WebCore::MediaPlayerPrivate::createQTMovieLayer): No longer parent the layer directly
        via setContentsToMedia().
        (WebCore::MediaPlayerPrivate::acceleratedRenderingStateChanged): Ditto.
        (WebCore::MediaPlayerPrivate::setUpVideoRendering): Tell the client that the
        rendering mode changed.
        (WebCore::MediaPlayerPrivate::platformLayer): Method to vend the media layer.
        * rendering/RenderLayerBacking.cpp:
        (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Call setContentsToMedia()
        here.

        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h: Add platformLayer().
        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
        (WebCore::MediaPlayerPrivate::platformLayer): Method to vend the media layer.
        (WebCore::MediaPlayerPrivate::setUpVideoRendering): Call mediaPlayerRenderingModeChanged()
        (WebCore::MediaPlayerPrivate::createLayerForMovie): Don't parent the layer ourselves any more.

        * rendering/RenderVideo.h: videoGraphicsLayer() is no longer needed.
        * rendering/RenderVideo.cpp: Ditto.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54826 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e31486d8
2010-02-16 Simon Fraser <simon.fraser@apple.com>
Reviewed by Eric Carlson.
Autoplaying video with poster doesn't reliably show up
https://bugs.webkit.org/show_bug.cgi?id=34966
Testcase that has an autoplaying video with a poster.
* media/video-replaces-poster.html: Added.
* platform/mac/media/video-replaces-poster-expected.checksum: Added.
* platform/mac/media/video-replaces-poster-expected.png: Added.
* platform/mac/media/video-replaces-poster-expected.txt: Added.
2010-02-16 Alexander Pavlov <apavlov@chromium.org>
Reviewed by Pavel Feldman.
......
<!DOCTYPE html>
<html>
<head>
<script src="video-paint-test.js"></script>
<script src="media-file.js"></script>
<script type="text/javascript" charset="utf-8">
function doSetup()
{
var video = document.getElementsByTagName('video')[0];
video.src = findMediaFile('video', 'content/test');
video.addEventListener("canplaythrough", function () {
video.pause();
video.currentTime = 1; // so the snapshot always has the same frame.
});
init();
}
window.addEventListener('load', doSetup, false);
</script>
</head>
<body>
<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34966">https://bugs.webkit.org/show_bug.cgi?id=34966</a>. <br>
You should see the video play below.</p>
<video width="480" height="270" poster="content/abe.png" autoplay></video>
</body>
</html>
0ac437a7fd55b1f509458bc27ff8a4b2
\ No newline at end of file
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x350
RenderBlock {HTML} at (0,0) size 800x350
RenderBody {BODY} at (8,16) size 784x326
RenderBlock {P} at (0,0) size 784x36
RenderText {#text} at (0,0) size 53x18
text run at (0,0) width 53: "Test for "
RenderInline {A} at (0,0) size 305x18 [color=#0000EE]
RenderText {#text} at (53,0) size 305x18
text run at (53,0) width 305: "https://bugs.webkit.org/show_bug.cgi?id=34966"
RenderText {#text} at (358,0) size 8x18
text run at (358,0) width 8: ". "
RenderBR {BR} at (366,0) size 0x18
RenderText {#text} at (0,18) size 238x18
text run at (0,18) width 238: "You should see the video play below."
RenderBlock (anonymous) at (0,52) size 784x274
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
layer at (8,68) size 480x270
RenderVideo {VIDEO} at (0,0) size 480x270
2010-02-16 Simon Fraser <simon.fraser@apple.com>
Reviewed by Eric Carlson.
Autoplaying video with poster doesn't reliably show up
https://bugs.webkit.org/show_bug.cgi?id=34966
A timing issue with compositing updates when replacing the poster image
with the video could cause the video to not display.
Fix by making video layer hook up more similar to WebGL etc, by having the
video kick off a recalcStyle() via a SyntheticStyleChange. This requires
vending a PlaformLayer* from the media player, up through the element.
Test: media/video-replaces-poster.html
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaPlayerRenderingModeChanged): Use setNeedsStyleRecalc()
to kick off a compositing update.
* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement::platformLayer): Export the media engine's layer.
* platform/graphics/MediaPlayer.cpp:
(WebCore::NullMediaPlayerPrivate::platformLayer): Method to vend the media layer.
(WebCore::MediaPlayer::platformLayer):
* platform/graphics/MediaPlayer.h:
(WebCore::MediaPlayerClient::mediaPlayerRenderingModeChanged): New client callback
to indicate that the rendering mode changed. The element uses this to kick off a
recalcStyle.
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::platformLayer): Method to vend the media layer.
* platform/graphics/mac/MediaPlayerPrivateQTKit.h: Ditto
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivate::createQTMovieLayer): No longer parent the layer directly
via setContentsToMedia().
(WebCore::MediaPlayerPrivate::acceleratedRenderingStateChanged): Ditto.
(WebCore::MediaPlayerPrivate::setUpVideoRendering): Tell the client that the
rendering mode changed.
(WebCore::MediaPlayerPrivate::platformLayer): Method to vend the media layer.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Call setContentsToMedia()
here.
* platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h: Add platformLayer().
* platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
(WebCore::MediaPlayerPrivate::platformLayer): Method to vend the media layer.
(WebCore::MediaPlayerPrivate::setUpVideoRendering): Call mediaPlayerRenderingModeChanged()
(WebCore::MediaPlayerPrivate::createLayerForMovie): Don't parent the layer ourselves any more.
* rendering/RenderVideo.h: videoGraphicsLayer() is no longer needed.
* rendering/RenderVideo.cpp: Ditto.
2010-02-12 Peter Kasting <pkasting@google.com>
Reviewed by Adam Barth.
......
......@@ -1529,11 +1529,10 @@ bool HTMLMediaElement::mediaPlayerRenderingCanBeAccelerated(MediaPlayer*)
return false;
}
GraphicsLayer* HTMLMediaElement::mediaPlayerGraphicsLayer(MediaPlayer*)
void HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
{
if (renderer() && renderer()->isVideo())
return toRenderVideo(renderer())->videoGraphicsLayer();
return 0;
// Kick off a fake recalcStyle that will update the compositing tree.
setNeedsStyleRecalc(SyntheticStyleChange);
}
#endif
......@@ -1878,6 +1877,13 @@ PlatformMedia HTMLMediaElement::platformMedia() const
return m_player ? m_player->platformMedia() : NoPlatformMedia;
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* HTMLMediaElement::platformLayer() const
{
return m_player ? m_player->platformLayer() : 0;
}
#endif
bool HTMLMediaElement::hasClosedCaptions() const
{
return m_player && m_player->hasClosedCaptions();
......
......@@ -75,6 +75,9 @@ public:
virtual bool supportsSave() const;
PlatformMedia platformMedia() const;
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
void scheduleLoad();
......@@ -200,7 +203,7 @@ private: // MediaPlayerClient
virtual void mediaPlayerSizeChanged(MediaPlayer*);
#if USE(ACCELERATED_COMPOSITING)
virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
virtual GraphicsLayer* mediaPlayerGraphicsLayer(MediaPlayer*);
virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
#endif
private:
......
......@@ -67,6 +67,9 @@ public:
virtual void pause() { }
virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const { return 0; }
#endif
virtual IntSize naturalSize() const { return IntSize(0, 0); }
......@@ -362,6 +365,13 @@ PlatformMedia MediaPlayer::platformMedia() const
return m_private->platformMedia();
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* MediaPlayer::platformLayer() const
{
return m_private->platformLayer();
}
#endif
MediaPlayer::NetworkState MediaPlayer::networkState()
{
return m_private->networkState();
......
......@@ -39,6 +39,10 @@
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayer.h"
#endif
#ifdef __OBJC__
@class QTMovie;
#else
......@@ -67,10 +71,6 @@ class MediaPlayerPrivateInterface;
class String;
class TimeRanges;
#if USE(ACCELERATED_COMPOSITING)
class GraphicsLayer;
#endif
class MediaPlayerClient {
public:
virtual ~MediaPlayerClient() { }
......@@ -112,8 +112,9 @@ public:
// whether the rendering system can accelerate the display of this MediaPlayer.
virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) { return false; }
// return the GraphicsLayer that will host the presentation for this MediaPlayer.
virtual GraphicsLayer* mediaPlayerGraphicsLayer(MediaPlayer*) { return 0; }
// called when the media player's rendering mode changed, which indicates a change in the
// availability of the platformLayer().
virtual void mediaPlayerRenderingModeChanged(MediaPlayer*) { }
#endif
};
......@@ -135,6 +136,9 @@ public:
bool supportsFullscreen() const;
bool supportsSave() const;
PlatformMedia platformMedia() const;
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
IntSize naturalSize();
bool hasVideo() const;
......
......@@ -45,6 +45,9 @@ public:
virtual void prepareToPlay() { }
virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const { return 0; }
#endif
virtual void play() = 0;
virtual void pause() = 0;
......
......@@ -78,6 +78,9 @@ private:
static bool isAvailable();
PlatformMedia platformMedia() const;
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
IntSize naturalSize() const;
bool hasVideo() const;
......
......@@ -445,12 +445,7 @@ void MediaPlayerPrivate::createQTMovieLayer()
#ifndef NDEBUG
[(CALayer *)m_qtVideoLayer.get() setName:@"Video layer"];
#endif
// Hang the video layer from the render layer, if we have one yet. If not, we'll do this
// later via acceleratedRenderingStateChanged().
GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
if (videoGraphicsLayer)
videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer.get());
// The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration().
}
#endif
}
......@@ -522,6 +517,9 @@ void MediaPlayerPrivate::setUpVideoRendering()
createQTMovieLayer();
break;
}
if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
}
void MediaPlayerPrivate::tearDownVideoRendering()
......@@ -576,6 +574,13 @@ PlatformMedia MediaPlayerPrivate::platformMedia() const
return plaftformMedia;
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* MediaPlayerPrivate::platformLayer() const
{
return m_qtVideoLayer.get();
}
#endif
void MediaPlayerPrivate::play()
{
if (!metaDataAvailable())
......@@ -1406,12 +1411,6 @@ void MediaPlayerPrivate::acceleratedRenderingStateChanged()
{
// Set up or change the rendering path if necessary.
setUpVideoRendering();
if (currentRenderingMode() == MediaRenderingMovieLayer) {
GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
if (videoGraphicsLayer)
videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer.get());
}
}
#endif
......
......@@ -108,6 +108,13 @@ PlatformMedia MediaPlayerPrivate::platformMedia() const
return p;
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* MediaPlayerPrivate::platformLayer() const
{
m_qtVideoLayer->platformLayer()
}
#endif
class TaskTimer : TimerBase {
public:
static void initialize();
......@@ -745,6 +752,9 @@ void MediaPlayerPrivate::setUpVideoRendering()
if (preferredMode == MediaRenderingMovieLayer)
createLayerForMovie();
if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
}
void MediaPlayerPrivate::tearDownVideoRendering()
......@@ -810,11 +820,6 @@ void MediaPlayerPrivate::createLayerForMovie()
if (!m_qtMovie || m_qtVideoLayer)
return;
// Do nothing if the parent layer hasn't been set up yet.
GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
if (!videoGraphicsLayer)
return;
// Create a GraphicsLayer that won't be inserted directly into the render tree, but will used
// as a wrapper for a WKCACFLayer which gets inserted as the content layer of the video
// renderer's GraphicsLayer.
......@@ -829,9 +834,7 @@ void MediaPlayerPrivate::createLayerForMovie()
#ifndef NDEBUG
m_qtVideoLayer->setName("Video layer");
#endif
// Hang the video layer from the render layer.
videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer->platformLayer());
// The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration().
#endif
}
......
......@@ -76,6 +76,9 @@ private:
virtual bool supportsFullscreen() const;
virtual PlatformMedia platformMedia() const;
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
IntSize naturalSize() const;
bool hasVideo() const;
......
......@@ -38,6 +38,7 @@
#include "GraphicsLayer.h"
#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
#include "KeyframeList.h"
......@@ -214,10 +215,12 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
if (renderer()->isEmbeddedObject() && toRenderEmbeddedObject(renderer())->allowsAcceleratedCompositing()) {
PluginWidget* pluginWidget = static_cast<PluginWidget*>(toRenderEmbeddedObject(renderer())->widget());
m_graphicsLayer->setContentsToMedia(pluginWidget->platformLayer());
} else if (renderer()->isVideo()) {
HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(renderer()->node());
m_graphicsLayer->setContentsToMedia(mediaElement->platformLayer());
}
#if ENABLE(3D_CANVAS)
if (is3DCanvas(renderer())) {
else if (is3DCanvas(renderer())) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
if (context->graphicsContext3D()->platformGraphicsContext3D())
......
......@@ -275,14 +275,6 @@ void RenderVideo::acceleratedRenderingStateChanged()
if (p)
p->acceleratedRenderingStateChanged();
}
GraphicsLayer* RenderVideo::videoGraphicsLayer() const
{
if (hasLayer() && layer()->isComposited())
return layer()->backing()->graphicsLayer();
return 0;
}
#endif // USE(ACCELERATED_COMPOSITING)
} // namespace WebCore
......
......@@ -34,9 +34,6 @@ namespace WebCore {
class HTMLMediaElement;
class HTMLVideoElement;
#if USE(ACCELERATED_COMPOSITING)
class GraphicsLayer;
#endif
class RenderVideo : public RenderMedia {
public:
......@@ -49,7 +46,6 @@ public:
#if USE(ACCELERATED_COMPOSITING)
bool supportsAcceleratedRendering() const;
void acceleratedRenderingStateChanged();
GraphicsLayer* videoGraphicsLayer() const;
#endif
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment