REGRESSION(78201): Windowless Flash plug-ins are transparent on some sites
authorjhoneycutt@apple.com <jhoneycutt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jun 2011 22:19:01 +0000 (22:19 +0000)
committerjhoneycutt@apple.com <jhoneycutt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jun 2011 22:19:01 +0000 (22:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=62690
<rdar://problem/9512026>

Reviewed by Ada Chan.

The bug arises when mixing CoreGraphics and GDI. When we create a Windows
bitmap for a windowless plug-in to draw into, we first fill it with "clear",
or all 0s. If the plug-in uses GDI to draw, the GDI calls will ignore the
alpha channel, and if we then use CG to blend this bitmap onto the
GraphicsContext for the rest of the page, CG will treat the 0-filled
alpha channel as being transparent.

To fix this, on Windows, use a GDI-backed GraphicsContext to paint the
page in the WebProcess, and use GDI to blit from the UpdateInfo to the
backing store in the UI process.

* Platform/SharedMemory.h:
(WebKit::SharedMemory::handle):
Return the handle for the memory.

* Shared/ShareableBitmap.h:
Declared windowsContext() to return a HDC with the bitmap selected into it.
Added members to store the HDC and the HBITMAP.

* Shared/win/ShareableBitmapWin.cpp: Added.
(WebKit::ShareableBitmap::windowsContext):
Get the screen DC, and create a compatible DC from it. Create a DIB
section backed by the shared memory, select it into the context, and
return it.

* UIProcess/win/BackingStoreWin.cpp:
(WebKit::BackingStore::incorporateUpdate):
Use GDI to blit from the update info's bitmap into the backing store bitmap.

* WebProcess/WebPage/DrawingAreaImpl.cpp:
(WebKit::DrawingAreaImpl::createGraphicsContext):
Return a GraphicsContext from the ShareableBitmap.
(WebKit::DrawingAreaImpl::display):
Call createGraphicsContext(), and pass the ShareableBitmap.

* WebProcess/WebPage/DrawingAreaImpl.h:
Declare createGraphicsContext(), which on Windows will create a GDI-backed
GraphicsContext.

* WebProcess/WebPage/win/DrawingAreaImplWin.cpp: Added.
(WebKit::DrawingAreaImpl::createGraphicsContext):
Get a Windows context for the bitmap, and create and return a new
GraphicsContext using the DC.

* win/WebKit2.vcproj:
Added new files.

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

Source/WebKit2/ChangeLog
Source/WebKit2/Platform/SharedMemory.h
Source/WebKit2/Shared/ShareableBitmap.h
Source/WebKit2/Shared/win/ShareableBitmapWin.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/win/BackingStoreWin.cpp
Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp
Source/WebKit2/win/WebKit2.vcproj

index 4d7def5..2d7e5f3 100644 (file)
@@ -1,3 +1,58 @@
+2011-06-14  Jon Honeycutt  <jhoneycutt@apple.com>
+
+        REGRESSION(78201): Windowless Flash plug-ins are transparent on some sites
+        https://bugs.webkit.org/show_bug.cgi?id=62690
+        <rdar://problem/9512026>
+
+        Reviewed by Ada Chan.
+
+        The bug arises when mixing CoreGraphics and GDI. When we create a Windows
+        bitmap for a windowless plug-in to draw into, we first fill it with "clear",
+        or all 0s. If the plug-in uses GDI to draw, the GDI calls will ignore the
+        alpha channel, and if we then use CG to blend this bitmap onto the
+        GraphicsContext for the rest of the page, CG will treat the 0-filled
+        alpha channel as being transparent.
+
+        To fix this, on Windows, use a GDI-backed GraphicsContext to paint the
+        page in the WebProcess, and use GDI to blit from the UpdateInfo to the
+        backing store in the UI process.
+
+        * Platform/SharedMemory.h:
+        (WebKit::SharedMemory::handle):
+        Return the handle for the memory.
+
+        * Shared/ShareableBitmap.h:
+        Declared windowsContext() to return a HDC with the bitmap selected into it.
+        Added members to store the HDC and the HBITMAP.
+
+        * Shared/win/ShareableBitmapWin.cpp: Added.
+        (WebKit::ShareableBitmap::windowsContext):
+        Get the screen DC, and create a compatible DC from it. Create a DIB
+        section backed by the shared memory, select it into the context, and
+        return it.
+
+        * UIProcess/win/BackingStoreWin.cpp:
+        (WebKit::BackingStore::incorporateUpdate):
+        Use GDI to blit from the update info's bitmap into the backing store bitmap.
+
+        * WebProcess/WebPage/DrawingAreaImpl.cpp:
+        (WebKit::DrawingAreaImpl::createGraphicsContext):
+        Return a GraphicsContext from the ShareableBitmap.
+        (WebKit::DrawingAreaImpl::display):
+        Call createGraphicsContext(), and pass the ShareableBitmap.
+
+        * WebProcess/WebPage/DrawingAreaImpl.h:
+        Declare createGraphicsContext(), which on Windows will create a GDI-backed
+        GraphicsContext.
+
+        * WebProcess/WebPage/win/DrawingAreaImplWin.cpp: Added.
+        (WebKit::DrawingAreaImpl::createGraphicsContext):
+        Get a Windows context for the bitmap, and create and return a new
+        GraphicsContext using the DC.
+
+        * win/WebKit2.vcproj:
+        Added new files.
+
 2011-06-15  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Sam Weinig.
index efbc6b5..2fe6b5d 100644 (file)
@@ -94,6 +94,9 @@ public:
 
     size_t size() const { return m_size; }
     void* data() const { return m_data; }
+#if PLATFORM(WIN)
+    HANDLE handle() const { return m_handle; }
+#endif
 
     // Creates a copy-on-write copy of the first |size| bytes.
     PassRefPtr<SharedMemory> createCopyOnWriteCopy(size_t) const;
index dca2432..15868f7 100644 (file)
@@ -111,6 +111,9 @@ public:
     // This is only safe to use when we know that the contents of the shareable bitmap won't change.
     PassRefPtr<WebCore::Image> createImage();
 
+#if PLATFORM(WIN)
+    HDC windowsContext() const;
+#endif
 #if USE(CG)
     // This creates a copied CGImageRef (most likely a copy-on-write) of the shareable bitmap.
     RetainPtr<CGImageRef> makeCGImageCopy();
@@ -155,6 +158,10 @@ private:
 
     // If the shareable bitmap is backed by fastMalloced memory, this points to the data.
     void* m_data;
+#if PLATFORM(WIN)
+    mutable OwnPtr<HDC> m_windowsContext;
+    mutable OwnPtr<HBITMAP> m_windowsBitmap;
+#endif
 };
 
 } // namespace WebKit
diff --git a/Source/WebKit2/Shared/win/ShareableBitmapWin.cpp b/Source/WebKit2/Shared/win/ShareableBitmapWin.cpp
new file mode 100644 (file)
index 0000000..bf23dcd
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ShareableBitmap.h"
+
+#include <WebCore/BitmapInfo.h>
+#include <WebCore/GraphicsContext.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+HDC ShareableBitmap::windowsContext() const
+{
+    ASSERT(isBackedBySharedMemory());
+    if (m_windowsContext)
+        return m_windowsContext.get();
+
+    OwnPtr<HDC> screenDC = adoptPtr(::GetDC(0));
+    BitmapInfo bmInfo = BitmapInfo::createBottomUp(m_size);
+
+    m_windowsContext = adoptPtr(::CreateCompatibleDC(screenDC.get()));
+    m_windowsBitmap = adoptPtr(CreateDIBSection(m_windowsContext.get(), &bmInfo, DIB_RGB_COLORS, 0, m_sharedMemory->handle(), 0));
+    ::SelectObject(m_windowsContext.get(), m_windowsBitmap.get());
+
+    return m_windowsContext.get();
+}
+
+} // namespace WebKit
index 801376f..60bba75 100644 (file)
@@ -84,8 +84,8 @@ void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo&
 
     IntPoint updateRectLocation = updateInfo.updateRectBounds.location();
 
-    BitmapDC dc(m_bitmap.get(), 0);
-    GraphicsContext graphicsContext(dc);
+    BitmapDC backingStoreDC(m_bitmap.get(), 0);
+    HDC bitmapDC = bitmap->windowsContext();
 
     // Paint all update rects.
     for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) {
@@ -93,7 +93,8 @@ void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo&
         IntRect srcRect = updateRect;
         srcRect.move(-updateRectLocation.x(), -updateRectLocation.y());
 
-        bitmap->paint(graphicsContext, updateRect.location(), srcRect);
+        ::BitBlt(backingStoreDC, updateRect.location().x(), updateRect.location().y(), updateRect.size().width(), updateRect.size().height(),
+            bitmapDC, srcRect.x(), srcRect.y(), SRCCOPY);
     }
 }
 
index e704f6f..7049505 100644 (file)
@@ -585,6 +585,13 @@ static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>&
     return wastedSpace <= wastedSpaceThreshold;
 }
 
+#if !PLATFORM(WIN)
+PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap)
+{
+    return bitmap->createGraphicsContext();
+}
+#endif
+
 void DrawingAreaImpl::display(UpdateInfo& updateInfo)
 {
     ASSERT(!m_isPaintingSuspended);
@@ -631,8 +638,8 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo)
     m_scrollRect = IntRect();
     m_scrollOffset = IntSize();
 
-    OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
-    
+    OwnPtr<GraphicsContext> graphicsContext = createGraphicsContext(bitmap.get());
+
     updateInfo.updateRectBounds = bounds;
 
     graphicsContext->translate(-bounds.x(), -bounds.y());
index 235faa5..346305f 100644 (file)
 #include "Region.h"
 #include "RunLoop.h"
 
+namespace WebCore {
+    class GraphicsContext;
+}
+
 namespace WebKit {
 
+class ShareableBitmap;
 class UpdateInfo;
 
 class DrawingAreaImpl : public DrawingArea {
@@ -83,6 +88,7 @@ private:
     void displayTimerFired();
     void display();
     void display(UpdateInfo&);
+    PassOwnPtr<WebCore::GraphicsContext> createGraphicsContext(ShareableBitmap*);
 
     uint64_t m_backingStoreStateID;
 
index 6d527c4..b355b78 100644 (file)
 #include "config.h"
 #include "DrawingAreaImpl.h"
 
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include "WindowGeometry.h"
+#include <WebCore/GraphicsContext.h>
+
+using namespace WebCore;
 
 namespace WebKit {
 
@@ -46,4 +51,11 @@ void DrawingAreaImpl::scheduleChildWindowGeometryUpdate(const WindowGeometry& ge
     m_webPage->send(Messages::WebPageProxy::ScheduleChildWindowGeometryUpdate(geometry));
 }
 
+PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap)
+{
+    HDC bitmapDC = bitmap->windowsContext();
+    return adoptPtr(new GraphicsContext(bitmapDC, true));
+}
+
 } // namespace WebKit
+
index b0816e6..d4d79d0 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\Shared\win\ShareableBitmapWin.cpp"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\Shared\win\WebCoreArgumentCodersWin.cpp"
                                        >
                                </File>