Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / HTMLVideoElement.cpp
index c79385a..a818309 100644 (file)
 #include "config.h"
 #include "core/html/HTMLVideoElement.h"
 
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/Settings.h"
 #include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
 #include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Settings.h"
 #include "core/rendering/RenderImage.h"
 #include "core/rendering/RenderVideo.h"
 #include "platform/UserGestureIndicator.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/gpu/Extensions3DUtil.h"
+#include "public/platform/WebCanvas.h"
+#include "public/platform/WebGraphicsContext3D.h"
 
-namespace WebCore {
+namespace blink {
 
 using namespace HTMLNames;
 
-inline HTMLVideoElement::HTMLVideoElement(Document& document, bool createdByParser)
-    : HTMLMediaElement(videoTag, document, createdByParser)
+inline HTMLVideoElement::HTMLVideoElement(Document& document)
+    : HTMLMediaElement(videoTag, document)
 {
-    ScriptWrappable::init(this);
     if (document.settings())
         m_defaultPosterURL = AtomicString(document.settings()->defaultVideoPosterURL());
 }
 
-PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document)
+{
+    RefPtrWillBeRawPtr<HTMLVideoElement> video = adoptRefWillBeNoop(new HTMLVideoElement(document));
+    video->ensureUserAgentShadowRoot();
+    video->suspendIfNeeded();
+    return video.release();
+}
+
+void HTMLVideoElement::trace(Visitor* visitor)
 {
-    RefPtr<HTMLVideoElement> videoElement(adoptRef(new HTMLVideoElement(document, createdByParser)));
-    videoElement->suspendIfNeeded();
-    return videoElement.release();
+    visitor->trace(m_imageLoader);
+    HTMLMediaElement::trace(visitor);
 }
 
 bool HTMLVideoElement::rendererIsNeeded(const RenderStyle& style)
@@ -75,7 +87,7 @@ void HTMLVideoElement::attach(const AttachContext& context)
     updateDisplayState();
     if (shouldDisplayPosterImage()) {
         if (!m_imageLoader)
-            m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+            m_imageLoader = HTMLImageLoader::create(this);
         m_imageLoader->updateFromElement();
         if (renderer())
             toRenderImage(renderer())->imageResource()->setImageResource(m_imageLoader->image());
@@ -107,14 +119,18 @@ void HTMLVideoElement::parseAttribute(const QualifiedName& name, const AtomicStr
         updateDisplayState();
         if (shouldDisplayPosterImage()) {
             if (!m_imageLoader)
-                m_imageLoader = adoptPtr(new HTMLImageLoader(this));
-            m_imageLoader->updateFromElementIgnoringPreviousError();
+                m_imageLoader = HTMLImageLoader::create(this);
+            m_imageLoader->updateFromElement(ImageLoader::UpdateIgnorePreviousError);
         } else {
             if (renderer())
                 toRenderImage(renderer())->imageResource()->setImageResource(0);
         }
-    } else
+        // Notify the player when the poster image URL changes.
+        if (webMediaPlayer())
+            webMediaPlayer()->setPoster(posterImageURL());
+    } else {
         HTMLMediaElement::parseAttribute(name, value);
+    }
 }
 
 bool HTMLVideoElement::supportsFullscreen() const
@@ -122,7 +138,7 @@ bool HTMLVideoElement::supportsFullscreen() const
     if (!document().page())
         return false;
 
-    if (!player())
+    if (!webMediaPlayer())
         return false;
 
     return true;
@@ -130,16 +146,16 @@ bool HTMLVideoElement::supportsFullscreen() const
 
 unsigned HTMLVideoElement::videoWidth() const
 {
-    if (!player())
+    if (!webMediaPlayer())
         return 0;
-    return player()->naturalSize().width();
+    return webMediaPlayer()->naturalSize().width;
 }
 
 unsigned HTMLVideoElement::videoHeight() const
 {
-    if (!player())
+    if (!webMediaPlayer())
         return 0;
-    return player()->naturalSize().height();
+    return webMediaPlayer()->naturalSize().height;
 }
 
 bool HTMLVideoElement::isURLAttribute(const Attribute& attribute) const
@@ -163,7 +179,9 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
     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 && !hasAvailableVideoFrame())
+        // Don't show the poster if there is a seek operation or
+        // the video has restarted because of loop attribute
+        if (mode == Video && oldMode == Poster && !hasAvailableVideoFrame())
             mode = PosterWaitingForVideo;
     }
 
@@ -181,27 +199,33 @@ void HTMLVideoElement::updateDisplayState()
         setDisplayMode(Poster);
 }
 
-void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect) const
 {
-    MediaPlayer* player = HTMLMediaElement::player();
-    if (!player)
+    if (!webMediaPlayer())
         return;
-    player->paint(context, destRect);
+
+    WebCanvas* canvas = context->canvas();
+    SkXfermode::Mode mode = WebCoreCompositeToSkiaComposite(context->compositeOperation(), context->blendModeOperation());
+    webMediaPlayer()->paint(canvas, destRect, context->getNormalizedAlpha(), mode);
 }
 
-bool HTMLVideoElement::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject texture, GLint level, GLenum type, GLenum internalFormat, bool premultiplyAlpha, bool flipY)
+bool HTMLVideoElement::copyVideoTextureToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLint level, GLenum internalFormat, GLenum type, bool premultiplyAlpha, bool flipY)
 {
-    if (!player())
+    if (!webMediaPlayer())
         return false;
-    return player()->copyVideoTextureToPlatformTexture(context, texture, level, type, internalFormat, premultiplyAlpha, flipY);
+
+    if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, type, level))
+        return false;
+
+    return webMediaPlayer()->copyVideoTextureToPlatformTexture(context, texture, level, internalFormat, type, premultiplyAlpha, flipY);
 }
 
 bool HTMLVideoElement::hasAvailableVideoFrame() const
 {
-    if (!player())
+    if (!webMediaPlayer())
         return false;
 
-    return player()->hasVideo() && player()->readyState() >= MediaPlayer::HaveCurrentData;
+    return webMediaPlayer()->hasVideo() && webMediaPlayer()->readyState() >= blink::WebMediaPlayer::ReadyStateHaveCurrentData;
 }
 
 void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
@@ -209,12 +233,6 @@ void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
     if (isFullscreen())
         return;
 
-    // Generate an exception if this isn't called in response to a user gesture, or if the
-    // element does not support fullscreen.
-    if (userGestureRequiredForFullscreen() && !UserGestureIndicator::processingUserGesture()) {
-        exceptionState.throwDOMException(InvalidStateError, "This element may only enter fullscreen mode in response to a user gesture ('click', for example).");
-        return;
-    }
     if (!supportsFullscreen()) {
         exceptionState.throwDOMException(InvalidStateError, "This element does not support fullscreen mode.");
         return;
@@ -248,18 +266,18 @@ void HTMLVideoElement::didMoveToNewDocument(Document& oldDocument)
 
 unsigned HTMLVideoElement::webkitDecodedFrameCount() const
 {
-    if (!player())
+    if (!webMediaPlayer())
         return 0;
 
-    return player()->decodedFrameCount();
+    return webMediaPlayer()->decodedFrameCount();
 }
 
 unsigned HTMLVideoElement::webkitDroppedFrameCount() const
 {
-    if (!player())
+    if (!webMediaPlayer())
         return 0;
 
-    return player()->droppedFrameCount();
+    return webMediaPlayer()->droppedFrameCount();
 }
 
 KURL HTMLVideoElement::posterImageURL() const
@@ -270,4 +288,39 @@ KURL HTMLVideoElement::posterImageURL() const
     return document().completeURL(url);
 }
 
+KURL HTMLVideoElement::mediaPlayerPosterURL()
+{
+    return posterImageURL();
+}
+
+PassRefPtr<Image> HTMLVideoElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+    if (!hasAvailableVideoFrame()) {
+        *status = InvalidSourceImageStatus;
+        return nullptr;
+    }
+
+    IntSize intrinsicSize(videoWidth(), videoHeight());
+    OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(intrinsicSize);
+    if (!imageBuffer) {
+        *status = InvalidSourceImageStatus;
+        return nullptr;
+    }
+
+    paintCurrentFrameInContext(imageBuffer->context(), IntRect(IntPoint(0, 0), intrinsicSize));
+
+    *status = NormalSourceImageStatus;
+    return imageBuffer->copyImage(mode == CopySourceImageIfVolatile ? CopyBackingStore : DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLVideoElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+    return !hasSingleSecurityOrigin() || (!(webMediaPlayer() && webMediaPlayer()->didPassCORSAccessCheck()) && destinationSecurityOrigin->taintsCanvas(currentSrc()));
+}
+
+FloatSize HTMLVideoElement::sourceSize() const
+{
+    return FloatSize(videoWidth(), videoHeight());
+}
+
 }