WebGL: Avoid unnecessary memory copy or conversion in texImage2D and texSubImage2D...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2012 01:35:42 +0000 (01:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2012 01:35:42 +0000 (01:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102161

Patch by Jun Jiang <jun.a.jiang@intel.com> on 2012-12-11
Reviewed by Kenneth Russell.

There are several memory copy or conversions in the texImage2D and texSubImage2D for HTMLVideoElement which may be avoided. This patch removes the redundant BackingStore copy if the corresponding Graphics port supports the DontCopyBackingStore behavior. Moreover, it optimizes the AlphaOp if the Image source is from HTMLVideoElement to avoid unnecessary Unmultiply or Premultiply operation in unpack/pack.

Already covered by current tests.

* html/canvas/WebGLRenderingContext.cpp:
(WebCore):
(WebCore::WebGLRenderingContext::texImage2DImpl):
(WebCore::WebGLRenderingContext::texImage2D):
(WebCore::WebGLRenderingContext::videoFrameToImage): add a parameter to choose BackingStore copy behavior.
(WebCore::WebGLRenderingContext::texSubImage2DImpl):
(WebCore::WebGLRenderingContext::texSubImage2D):
* html/canvas/WebGLRenderingContext.h:
(WebGLRenderingContext):
* platform/graphics/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::ImageExtractor):
* platform/graphics/GraphicsContext3D.h:
(ImageExtractor):
(WebCore::GraphicsContext3D::ImageExtractor::imageSourceUnpackAlignment):
(WebCore::GraphicsContext3D::ImageExtractor::imageHtmlDomSource):
* platform/graphics/ImageBuffer.h:
(ImageBuffer):
* platform/graphics/cairo/GraphicsContext3DCairo.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage): optimize the AlphaOp for HTMLVideoElement input.
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):
* platform/graphics/qt/ImageBufferQt.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):
* platform/graphics/skia/GraphicsContext3DSkia.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage): optimize the AlphaOp for HTMLVideoElement input.
* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):
* platform/graphics/wince/ImageBufferWinCE.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):
* platform/graphics/wx/ImageBufferWx.cpp:
(WebCore::ImageBuffer::fastCopyImageMode):
(WebCore):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@137397 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/canvas/WebGLRenderingContext.cpp
Source/WebCore/html/canvas/WebGLRenderingContext.h
Source/WebCore/platform/graphics/GraphicsContext3D.cpp
Source/WebCore/platform/graphics/GraphicsContext3D.h
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
Source/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp
Source/WebCore/platform/graphics/wx/ImageBufferWx.cpp

index 0ccc2f5..44cea85 100644 (file)
@@ -1,3 +1,54 @@
+2012-12-11  Jun Jiang  <jun.a.jiang@intel.com>
+
+        WebGL: Avoid unnecessary memory copy or conversion in texImage2D and texSubImage2D for HTMLVideoElement
+        https://bugs.webkit.org/show_bug.cgi?id=102161
+
+        Reviewed by Kenneth Russell.
+
+        There are several memory copy or conversions in the texImage2D and texSubImage2D for HTMLVideoElement which may be avoided. This patch removes the redundant BackingStore copy if the corresponding Graphics port supports the DontCopyBackingStore behavior. Moreover, it optimizes the AlphaOp if the Image source is from HTMLVideoElement to avoid unnecessary Unmultiply or Premultiply operation in unpack/pack. 
+
+        Already covered by current tests. 
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore):
+        (WebCore::WebGLRenderingContext::texImage2DImpl):
+        (WebCore::WebGLRenderingContext::texImage2D):
+        (WebCore::WebGLRenderingContext::videoFrameToImage): add a parameter to choose BackingStore copy behavior.
+        (WebCore::WebGLRenderingContext::texSubImage2DImpl):
+        (WebCore::WebGLRenderingContext::texSubImage2D):
+        * html/canvas/WebGLRenderingContext.h:
+        (WebGLRenderingContext):
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::ImageExtractor):
+        * platform/graphics/GraphicsContext3D.h:
+        (ImageExtractor):
+        (WebCore::GraphicsContext3D::ImageExtractor::imageSourceUnpackAlignment):
+        (WebCore::GraphicsContext3D::ImageExtractor::imageHtmlDomSource):
+        * platform/graphics/ImageBuffer.h:
+        (ImageBuffer):
+        * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): optimize the AlphaOp for HTMLVideoElement input.
+        * platform/graphics/cairo/ImageBufferCairo.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+        * platform/graphics/qt/ImageBufferQt.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+        * platform/graphics/skia/GraphicsContext3DSkia.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): optimize the AlphaOp for HTMLVideoElement input.
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+        * platform/graphics/wince/ImageBufferWinCE.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+        * platform/graphics/wx/ImageBufferWx.cpp:
+        (WebCore::ImageBuffer::fastCopyImageMode):
+        (WebCore):
+
 2012-12-11  Viatcheslav Ostapenko  <v.ostapenko@samsung.com>
 
         [EFL] Missing implementation of GraphicsContext3DPrivate::platformLayerSize()
index a3f7fac..de2e22e 100644 (file)
@@ -3609,15 +3609,13 @@ void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3De
     cleanupAfterGraphicsCall(false);
 }
 
-void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat,
-                                           GC3Denum format, GC3Denum type, Image* image,
-                                           bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
 {
     ec = 0;
     if (!validateSettableTexFormat("texImage2D", internalformat))
         return;
     Vector<uint8_t> data;
-    GraphicsContext3D::ImageExtractor imageExtractor(image, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+    GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
     if (!imageExtractor.extractSucceeded()) {
         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
         return;
@@ -3702,8 +3700,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
         return;
     }
 
-    texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->imageForRenderer(image->renderer()),
-                   m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+    texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->imageForRenderer(image->renderer()), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
@@ -3741,12 +3738,11 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
     if (imageData)
         texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
     else
-        texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(),
-                       m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+        texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 #if ENABLE(VIDEO)
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy, ExceptionCode& ec)
 {
     if (!video || !video->videoWidth() || !video->videoHeight()) {
         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "no video");
@@ -3765,7 +3761,7 @@ PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* vid
     IntRect destRect(0, 0, size.width(), size.height());
     // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
     video->paintCurrentFrameInContext(buf->context(), destRect);
-    return buf->copyImage(CopyBackingStore);
+    return buf->copyImage(backingStoreCopy);
 }
 
 void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
@@ -3774,10 +3770,10 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
     ec = 0;
     if (isContextLost())
         return;
-    RefPtr<Image> image = videoFrameToImage(video, ec);
+    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
     if (!image)
         return;
-    texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+    texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 #endif
 
@@ -3857,15 +3853,13 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC
     cleanupAfterGraphicsCall(false);
 }
 
-void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                                              GC3Denum format, GC3Denum type,
-                                              Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
 {
     ec = 0;
     if (isContextLost())
         return;
     Vector<uint8_t> data;
-    GraphicsContext3D::ImageExtractor imageExtractor(image, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);  
+    GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);  
     if (!imageExtractor.extractSucceeded()) {
         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
         return;
@@ -3948,8 +3942,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
         ec = SECURITY_ERR;
         return;
     }
-    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->imageForRenderer(image->renderer()),
-                      m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->imageForRenderer(image->renderer()), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
@@ -3970,8 +3963,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
     if (imageData)
         texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
     else
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(),
-                          m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 
 #if ENABLE(VIDEO)
@@ -3981,10 +3973,10 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
     ec = 0;
     if (isContextLost())
         return;
-    RefPtr<Image> image = videoFrameToImage(video, ec);
+    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
     if (!image)
         return;
-    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
 }
 #endif
 
index 2dae23d..7ddfc2c 100644 (file)
@@ -29,6 +29,7 @@
 #include "CanvasRenderingContext.h"
 #include "DrawingBuffer.h"
 #include "GraphicsContext3D.h"
+#include "ImageBuffer.h"
 #include "Timer.h"
 #include "WebGLGetInfo.h"
 
@@ -372,7 +373,7 @@ public:
     void addCompressedTextureFormat(GC3Denum);
 
 #if ENABLE(VIDEO)
-    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
+    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&);
 #endif
 
     RefPtr<GraphicsContext3D> m_context;
@@ -531,13 +532,9 @@ public:
     void restoreStateAfterClear();
 
     void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
-    void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat,
-                        GC3Denum format, GC3Denum type, Image*,
-                        bool flipY, bool premultiplyAlpha, ExceptionCode&);
+    void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
     void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
-    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                           GC3Denum format, GC3Denum type,
-                           Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode&);
+    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
 
     void handleNPOTTextures(const char*, bool);
 
index ffa8ec6..770f4d1 100644 (file)
@@ -168,9 +168,10 @@ GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum ty
     return GraphicsContext3D::NO_ERROR;
 }
 
-GraphicsContext3D::ImageExtractor::ImageExtractor(Image* image, bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
+GraphicsContext3D::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
 {
     m_image = image;
+    m_imageHtmlDomSource = imageHtmlDomSource;
     m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
 }
 
index 31f603c..8c326f6 100644 (file)
@@ -875,6 +875,13 @@ public:
         AlphaDoUnmultiply = 2
     };
 
+    enum ImageHtmlDomSource {
+        HtmlDomImage = 0,
+        HtmlDomCanvas = 1,
+        HtmlDomVideo = 2,
+        HtmlDomNone = 3
+    };
+
     // Packs the contents of the given Image which is passed in |pixels| into the passed Vector
     // according to the given format and type, and obeying the flipY and AlphaOp flags.
     // Returns true upon success.
@@ -882,7 +889,7 @@ public:
 
     class ImageExtractor {
     public:
-        ImageExtractor(Image*, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
+        ImageExtractor(Image*, ImageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
 
         // Each platform must provide an implementation of this method to deallocate or release resources
         // associated with the image if needed.
@@ -894,7 +901,8 @@ public:
         unsigned imageHeight() { return m_imageHeight; }
         SourceDataFormat imageSourceFormat() { return m_imageSourceFormat; }
         AlphaOp imageAlphaOp() { return m_alphaOp; }
-        unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; } 
+        unsigned imageSourceUnpackAlignment() { return m_imageSourceUnpackAlignment; }
+        ImageHtmlDomSource imageHtmlDomSource() { return m_imageHtmlDomSource; }
     private:
         // Each platform must provide an implementation of this method.
         // Extracts the image and keeps track of its status, such as width, height, Source Alignment, format and AlphaOp etc,
@@ -915,6 +923,7 @@ public:
         QImage m_qtImage;
 #endif
         Image* m_image;
+        ImageHtmlDomSource m_imageHtmlDomSource;
         bool m_extractSucceeded;
         const void* m_imagePixelData;
         unsigned m_imageWidth;
index 4561140..9c5e63a 100644 (file)
@@ -104,6 +104,9 @@ namespace WebCore {
         GraphicsContext* context() const;
 
         PassRefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, ScaleBehavior = Scaled) const;
+        // Give hints on the faster copyImage Mode, return DontCopyBackingStore if it supports the DontCopyBackingStore behavior
+        // or return CopyBackingStore if it doesn't.  
+        static BackingStoreCopy fastCopyImageMode();
 
         enum CoordinateSystem { LogicalCoordinateSystem, BackingStoreCoordinateSystem };
 
index bd3bdfd..3d5a1e2 100644 (file)
@@ -189,7 +189,11 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool
     } else {
         NativeImageCairo* nativeImage = m_image->nativeImageForCurrentFrame();
         m_imageSurface = (nativeImage) ? nativeImage->surface() : 0;
-        if (!premultiplyAlpha)
+        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel,
+        // which is true at present and may be changed in the future and needs adjustment accordingly.
+        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port, 
+        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
+        if (!premultiplyAlpha && m_imageHtmlDomSource != HtmlDomVideo)
             m_alphaOp = AlphaDoUnmultiply;
     }
 
index b3d13fd..6953932 100644 (file)
@@ -91,6 +91,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return BitmapImage::create(cairo_surface_reference(m_data.m_surface));
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return DontCopyBackingStore;
+}
+
 void ImageBuffer::clip(GraphicsContext* context, const FloatRect& maskRect) const
 {
     context->platformContext()->pushImageMask(m_data.m_surface, maskRect);
index 5457174..1d99e08 100644 (file)
@@ -231,6 +231,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return BitmapImage::create(image.get());
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return DontCopyBackingStore;
+}
+
 NativeImagePtr ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const
 {
     CGImageRef image = 0;
index 0c2eef4..8b0b32a 100644 (file)
@@ -125,6 +125,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return StillImage::createForRendering(&m_data.m_pixmap);
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return DontCopyBackingStore;
+}
+
 void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
     CompositeOperator op, BlendMode, bool useLowQualityScale)
 {
index b3d1ea7..5bd9a3b 100644 (file)
@@ -78,8 +78,14 @@ bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool
         m_skiaImage = m_nativeImage.get();
         if (hasAlpha && premultiplyAlpha)
             m_alphaOp = AlphaDoPremultiply;
-    } else if (!premultiplyAlpha && hasAlpha)
-        m_alphaOp = AlphaDoUnmultiply;
+    } else if (!premultiplyAlpha && hasAlpha) {
+        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value for each pixel is 0xFF
+        // which is true at present and may be changed in the future and needs adjustment accordingly.
+        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
+        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
+        if (m_imageHtmlDomSource != HtmlDomVideo)
+            m_alphaOp = AlphaDoUnmultiply;
+    }
     if (!m_skiaImage)
         return false;
 
index 9954d76..fbf7359 100644 (file)
@@ -201,6 +201,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), copyBehavior == CopyBackingStore, m_resolutionScale);
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return DontCopyBackingStore;
+}
+
 PlatformLayer* ImageBuffer::platformLayer() const
 {
     return m_data.m_layerBridge ? m_data.m_layerBridge->layer() : 0;
index 32a2263..8815407 100644 (file)
@@ -100,6 +100,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return adoptRef(new BufferedImage(&m_data));
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return CopyBackingStore;
+}
+
 void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const
 {
     notImplemented();
index e5c4e7a..4f41ed1 100644 (file)
@@ -152,6 +152,11 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
     return img.release();
 }
 
+BackingStoreCopy ImageBuffer::fastCopyImageMode()
+{
+    return CopyBackingStore;
+}
+
 void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
 {
     context->clip(rect);