Title: [87831] trunk/Source/WebKit2
Revision
87831
Author
[email protected]
Date
2011-06-01 11:39:19 -0700 (Wed, 01 Jun 2011)

Log Message

Render accelerated content into a web process-owned child HWND

This allows us to use WKCACFView's far more efficient kWKCACFViewDrawingDestinationWindow
mode, which gives us asynchronous rendering on a background thread and doesn't require us to
read bits off the GPU back into system memory.

A new class, WKCACFViewWindow, represents the child HWND. The child HWND is placed at the
bottom of the z-order so it won't obscure any other child HWNDs (i.e., windowed plugins).
The child HWND is made transparent to mouse events so that WKView will continue to receive
mouse events even though it is obscured by the child HWND.

There is now a bunch of dead code in DrawingAreaImpl to handle our old rendering model. I'll
remove that in a future patch.

Fixes <http://webkit.org/b/58054> <rdar://problem/9249839> REGRESSION (WebKit2): Accelerated
CSS animations have a lower framerate than in WebKit1

Reviewed by Anders Carlsson.

* Shared/LayerTreeContext.h: Added HWND member on Windows.

* Shared/win/CoalescedWindowGeometriesUpdater.cpp:
(WebKit::CoalescedWindowGeometriesUpdater::updateGeometries):
* Shared/win/CoalescedWindowGeometriesUpdater.h:
Added new BringToTopOrNot argument. Allows the caller to specify that all windows being
updated should also be brought to the top of the z-order.

* Shared/win/LayerTreeContextWin.cpp:
(WebKit::LayerTreeContext::LayerTreeContext):
(WebKit::LayerTreeContext::~LayerTreeContext):
(WebKit::LayerTreeContext::encode):
(WebKit::LayerTreeContext::decode):
(WebKit::LayerTreeContext::isEmpty):
(WebKit::operator==):
Implemented based on new window member.

* UIProcess/win/WebView.cpp:
(WebKit::WebView::WebView): Initialize new member.
(WebKit::WebView::onSizeEvent): Resize the layer host window to cover our entire view, if we
have one.
(WebKit::WebView::enterAcceleratedCompositingMode): Store, position, and show the layer host
window.
(WebKit::WebView::exitAcceleratedCompositingMode): Destroy the layer host window.
(WebKit::WebView::updateChildWindowGeometries): Updated for change to
CoalescedWindowGeometriesUpdater.

* UIProcess/win/WebView.h: Added m_layerHostWindow member.

* WebProcess/WebPage/LayerTreeHost.h: Added scheduleChildWindowGeometryUpdate.

* WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp:
(WebKit::LayerTreeHostCAWin::supportsAcceleratedCompositing): Simplified by using
WKCACFViewWindow.

(WebKit::LayerTreeHostCAWin::LayerTreeHostCAWin): Removed initialization of a removed
member.
(WebKit::LayerTreeHostCAWin::platformInitialize): Changed to use WKCACFViewWindow,
kWKCACFViewDrawingDestinationWindow, and to initialize the LayerTreeContext.
(WebKit::LayerTreeHostCAWin::invalidate): Leak our window and tell it to clean up after
itself. The UI process will take care of destroying the window when it finishes switching
out of accelerated compositing mode. Removed a WKCACFViewUpdate call that is now handled by
WKCACFViewWindow.
(WebKit::LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate): Added. Calls through to
m_geometriesUpdater.
(WebKit::LayerTreeHostCAWin::sizeDidChange): Updated to use WKCACFViewWindow.
(WebKit::LayerTreeHostCAWin::contextDidChange): Update child window geometries now to keep
them (almost) in sync with the accelerated content. <http://webkit.org/b/61867> covers the
slight asynchrony that still exists.
(WebKit::LayerTreeHostCAWin::setRootCompositingLayer): Don't flush any changes when we don't
have a root layer. This prevents a flash of white when switching out of compositing mode.

* WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h: Added m_window and m_geometriesUpdater.
Removed code related to the old, synchronous display model.

* WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp: Added.
(WebKit::WKCACFViewWindow::WKCACFViewWindow): Initialize members and create our window.
(WebKit::WKCACFViewWindow::~WKCACFViewWindow): Destroy our window if needed.
(WebKit::WKCACFViewWindow::onCustomDestroy): Just call ::DestroyWindow.
(WebKit::WKCACFViewWindow::onDestroy): Tell our view not to render into our window anymore.
(WebKit::WKCACFViewWindow::onEraseBackground): Tell Windows not to erase us.
(WebKit::WKCACFViewWindow::onNCDestroy): Clear out m_window since it's now pointing to a
destroy window, and destroy ourselves if requested.
(WebKit::WKCACFViewWindow::onPaint): Tell the view to draw, then clear our invalid region.
(WebKit::WKCACFViewWindow::onPrintClient): Tell our view to draw into the given HDC.
(WebKit::WKCACFViewWindow::registerClass): Register our class (duh).
(WebKit::WKCACFViewWindow::staticWndProc): Get the WKCACFViewWindow pointer, or store the
pointer if needed, then call through to wndProc.
(WebKit::WKCACFViewWindow::wndProc): Call out to the appropriate handler function.

* WebProcess/WebPage/ca/win/WKCACFViewWindow.h: Added.
(WebKit::WKCACFViewWindow::setDeletesSelfWhenWindowDestroyed): Simple setter.
(WebKit::WKCACFViewWindow::window): Simple getter.

* WebProcess/WebPage/win/DrawingAreaImplWin.cpp:
(WebKit::DrawingAreaImpl::scheduleChildWindowGeometryUpdate): Let the LayerTreeHost handle
the geometry update, if we have one.

* win/WebKit2.vcproj: Added WKCACFViewWindow files.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (87830 => 87831)


--- trunk/Source/WebKit2/ChangeLog	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/ChangeLog	2011-06-01 18:39:19 UTC (rev 87831)
@@ -1,5 +1,106 @@
 2011-06-01  Adam Roben  <[email protected]>
 
+        Render accelerated content into a web process-owned child HWND
+
+        This allows us to use WKCACFView's far more efficient kWKCACFViewDrawingDestinationWindow
+        mode, which gives us asynchronous rendering on a background thread and doesn't require us to
+        read bits off the GPU back into system memory.
+
+        A new class, WKCACFViewWindow, represents the child HWND. The child HWND is placed at the
+        bottom of the z-order so it won't obscure any other child HWNDs (i.e., windowed plugins).
+        The child HWND is made transparent to mouse events so that WKView will continue to receive
+        mouse events even though it is obscured by the child HWND.
+
+        There is now a bunch of dead code in DrawingAreaImpl to handle our old rendering model. I'll
+        remove that in a future patch.
+
+        Fixes <http://webkit.org/b/58054> <rdar://problem/9249839> REGRESSION (WebKit2): Accelerated
+        CSS animations have a lower framerate than in WebKit1
+
+        Reviewed by Anders Carlsson.
+
+        * Shared/LayerTreeContext.h: Added HWND member on Windows.
+
+        * Shared/win/CoalescedWindowGeometriesUpdater.cpp:
+        (WebKit::CoalescedWindowGeometriesUpdater::updateGeometries):
+        * Shared/win/CoalescedWindowGeometriesUpdater.h:
+        Added new BringToTopOrNot argument. Allows the caller to specify that all windows being
+        updated should also be brought to the top of the z-order.
+
+        * Shared/win/LayerTreeContextWin.cpp:
+        (WebKit::LayerTreeContext::LayerTreeContext):
+        (WebKit::LayerTreeContext::~LayerTreeContext):
+        (WebKit::LayerTreeContext::encode):
+        (WebKit::LayerTreeContext::decode):
+        (WebKit::LayerTreeContext::isEmpty):
+        (WebKit::operator==):
+        Implemented based on new window member.
+
+        * UIProcess/win/WebView.cpp:
+        (WebKit::WebView::WebView): Initialize new member.
+        (WebKit::WebView::onSizeEvent): Resize the layer host window to cover our entire view, if we
+        have one.
+        (WebKit::WebView::enterAcceleratedCompositingMode): Store, position, and show the layer host
+        window.
+        (WebKit::WebView::exitAcceleratedCompositingMode): Destroy the layer host window.
+        (WebKit::WebView::updateChildWindowGeometries): Updated for change to
+        CoalescedWindowGeometriesUpdater.
+
+        * UIProcess/win/WebView.h: Added m_layerHostWindow member.
+
+        * WebProcess/WebPage/LayerTreeHost.h: Added scheduleChildWindowGeometryUpdate.
+
+        * WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp:
+        (WebKit::LayerTreeHostCAWin::supportsAcceleratedCompositing): Simplified by using
+        WKCACFViewWindow.
+
+        (WebKit::LayerTreeHostCAWin::LayerTreeHostCAWin): Removed initialization of a removed
+        member.
+        (WebKit::LayerTreeHostCAWin::platformInitialize): Changed to use WKCACFViewWindow,
+        kWKCACFViewDrawingDestinationWindow, and to initialize the LayerTreeContext.
+        (WebKit::LayerTreeHostCAWin::invalidate): Leak our window and tell it to clean up after
+        itself. The UI process will take care of destroying the window when it finishes switching
+        out of accelerated compositing mode. Removed a WKCACFViewUpdate call that is now handled by
+        WKCACFViewWindow.
+        (WebKit::LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate): Added. Calls through to
+        m_geometriesUpdater.
+        (WebKit::LayerTreeHostCAWin::sizeDidChange): Updated to use WKCACFViewWindow.
+        (WebKit::LayerTreeHostCAWin::contextDidChange): Update child window geometries now to keep
+        them (almost) in sync with the accelerated content. <http://webkit.org/b/61867> covers the
+        slight asynchrony that still exists.
+        (WebKit::LayerTreeHostCAWin::setRootCompositingLayer): Don't flush any changes when we don't
+        have a root layer. This prevents a flash of white when switching out of compositing mode.
+
+        * WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h: Added m_window and m_geometriesUpdater.
+        Removed code related to the old, synchronous display model.
+
+        * WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp: Added.
+        (WebKit::WKCACFViewWindow::WKCACFViewWindow): Initialize members and create our window.
+        (WebKit::WKCACFViewWindow::~WKCACFViewWindow): Destroy our window if needed.
+        (WebKit::WKCACFViewWindow::onCustomDestroy): Just call ::DestroyWindow.
+        (WebKit::WKCACFViewWindow::onDestroy): Tell our view not to render into our window anymore.
+        (WebKit::WKCACFViewWindow::onEraseBackground): Tell Windows not to erase us.
+        (WebKit::WKCACFViewWindow::onNCDestroy): Clear out m_window since it's now pointing to a
+        destroy window, and destroy ourselves if requested.
+        (WebKit::WKCACFViewWindow::onPaint): Tell the view to draw, then clear our invalid region.
+        (WebKit::WKCACFViewWindow::onPrintClient): Tell our view to draw into the given HDC.
+        (WebKit::WKCACFViewWindow::registerClass): Register our class (duh).
+        (WebKit::WKCACFViewWindow::staticWndProc): Get the WKCACFViewWindow pointer, or store the
+        pointer if needed, then call through to wndProc.
+        (WebKit::WKCACFViewWindow::wndProc): Call out to the appropriate handler function.
+
+        * WebProcess/WebPage/ca/win/WKCACFViewWindow.h: Added.
+        (WebKit::WKCACFViewWindow::setDeletesSelfWhenWindowDestroyed): Simple setter.
+        (WebKit::WKCACFViewWindow::window): Simple getter.
+
+        * WebProcess/WebPage/win/DrawingAreaImplWin.cpp:
+        (WebKit::DrawingAreaImpl::scheduleChildWindowGeometryUpdate): Let the LayerTreeHost handle
+        the geometry update, if we have one.
+
+        * win/WebKit2.vcproj: Added WKCACFViewWindow files.
+
+2011-06-01  Adam Roben  <[email protected]>
+
         Route plugin window geometry updates through the DrawingArea
 
         This will allow the geometry updates to be handled by the LayerTreeHost in compositing mode

Modified: trunk/Source/WebKit2/Shared/LayerTreeContext.h (87830 => 87831)


--- trunk/Source/WebKit2/Shared/LayerTreeContext.h	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/Shared/LayerTreeContext.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -45,6 +45,8 @@
 
 #if PLATFORM(MAC)
     uint32_t contextID;
+#elif PLATFORM(WIN)
+    HWND window;
 #endif
 };
 

Modified: trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.cpp (87830 => 87831)


--- trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.cpp	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -55,7 +55,7 @@
     region.leakPtr();
 }
 
-void CoalescedWindowGeometriesUpdater::updateGeometries()
+void CoalescedWindowGeometriesUpdater::updateGeometries(BringToTopOrNot bringToTopOrNot)
 {
     HashMap<HWND, WindowGeometry> geometries;
     geometries.swap(m_geometries);
@@ -68,14 +68,22 @@
         if (!::IsWindow(geometry.window))
             continue;
 
-        UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER;
+        UINT flags = SWP_NOACTIVATE;
         if (geometry.visible)
             flags |= SWP_SHOWWINDOW;
         else
             flags |= SWP_HIDEWINDOW;
 
-        deferWindowPos = ::DeferWindowPos(deferWindowPos, geometry.window, 0, geometry.frame.x(), geometry.frame.y(), geometry.frame.width(), geometry.frame.height(), flags);
+        HWND hwndInsertAfter;
+        if (bringToTopOrNot == BringToTop)
+            hwndInsertAfter = HWND_TOP;
+        else {
+            hwndInsertAfter = 0;
+            flags |= SWP_NOOWNERZORDER | SWP_NOZORDER;
+        }
 
+        deferWindowPos = ::DeferWindowPos(deferWindowPos, geometry.window, hwndInsertAfter, geometry.frame.x(), geometry.frame.y(), geometry.frame.width(), geometry.frame.height(), flags);
+
         setWindowRegion(geometry.window, adoptPtr(::CreateRectRgn(geometry.clipRect.x(), geometry.clipRect.y(), geometry.clipRect.maxX(), geometry.clipRect.maxY())));
     }
 

Modified: trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.h (87830 => 87831)


--- trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.h	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -33,6 +33,8 @@
 
 struct WindowGeometry;
 
+enum BringToTopOrNot { BringToTop, DoNotBringToTop };
+
 class CoalescedWindowGeometriesUpdater {
     WTF_MAKE_NONCOPYABLE(CoalescedWindowGeometriesUpdater);
 public:
@@ -40,7 +42,7 @@
     ~CoalescedWindowGeometriesUpdater();
 
     void addPendingUpdate(const WindowGeometry&);
-    void updateGeometries();
+    void updateGeometries(BringToTopOrNot);
 
 private:
     HashMap<HWND, WindowGeometry> m_geometries;

Modified: trunk/Source/WebKit2/Shared/win/LayerTreeContextWin.cpp (87830 => 87831)


--- trunk/Source/WebKit2/Shared/win/LayerTreeContextWin.cpp	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/Shared/win/LayerTreeContextWin.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -26,41 +26,42 @@
 #include "config.h"
 #include "LayerTreeContext.h"
 
-#include <WebCore/NotImplemented.h>
+#include "ArgumentCoders.h"
 
 namespace WebKit {
 
 LayerTreeContext::LayerTreeContext()
+    : window(0)
 {
-    notImplemented();
 }
 
 LayerTreeContext::~LayerTreeContext()
 {
-    notImplemented();
 }
 
-void LayerTreeContext::encode(CoreIPC::ArgumentEncoder*) const
+void LayerTreeContext::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
-    notImplemented();
+    encoder->encodeUInt64(reinterpret_cast<uint64_t>(window));
 }
 
-bool LayerTreeContext::decode(CoreIPC::ArgumentDecoder*, LayerTreeContext&)
+bool LayerTreeContext::decode(CoreIPC::ArgumentDecoder* decoder, LayerTreeContext& context)
 {
-    notImplemented();
+    uint64_t window;
+    if (!decoder->decode(window))
+        return false;
+
+    context.window = reinterpret_cast<HWND>(window);
     return true;
 }
 
 bool LayerTreeContext::isEmpty() const
 {
-    notImplemented();
-    return true;
+    return !window;
 }
 
-bool operator==(const LayerTreeContext&, const LayerTreeContext&)
+bool operator==(const LayerTreeContext& a, const LayerTreeContext& b)
 {
-    notImplemented();
-    return true;
+    return a.window == b.window;
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/win/WebView.cpp (87830 => 87831)


--- trunk/Source/WebKit2/UIProcess/win/WebView.cpp	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/UIProcess/win/WebView.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -35,6 +35,7 @@
 #include "Region.h"
 #include "RunLoop.h"
 #include "WKAPICast.h"
+#include "WKCACFViewWindow.h"
 #include "WebContext.h"
 #include "WebContextMenuProxyWin.h"
 #include "WebEditCommandProxy.h"
@@ -276,6 +277,9 @@
     , m_lastPanY(0)
     , m_overPanY(0)
     , m_gestureReachedScrollingLimit(false)
+#if USE(ACCELERATED_COMPOSITING)
+    , m_layerHostWindow(0)
+#endif
 {
     registerWebViewWindowClass();
 
@@ -729,6 +733,11 @@
         m_nextResizeScrollOffset = IntSize();
     }
 
+#if USE(ACCELERATED_COMPOSITING)
+    if (m_layerHostWindow)
+        ::MoveWindow(m_layerHostWindow, 0, 0, width, height, FALSE);
+#endif
+
     handled = true;
     return 0;
 }
@@ -1509,16 +1518,25 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
-void WebView::enterAcceleratedCompositingMode(const LayerTreeContext&)
+void WebView::enterAcceleratedCompositingMode(const LayerTreeContext& context)
 {
-    // FIXME: Implement.
-    ASSERT_NOT_REACHED();
+    ASSERT(!context.isEmpty());
+
+    m_layerHostWindow = context.window;
+
+    IntSize size = viewSize();
+    // Ensure the layer host window is behind all other child windows (since otherwise it would obscure them).
+    ::SetWindowPos(m_layerHostWindow, HWND_BOTTOM, 0, 0, size.width(), size.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE);
 }
 
 void WebView::exitAcceleratedCompositingMode()
 {
-    // FIXME: Implement.
-    ASSERT_NOT_REACHED();
+    ASSERT(m_layerHostWindow);
+
+    // Tell the WKCACFViewWindow to destroy itself. We can't call ::DestroyWindow directly because
+    // the window is owned by another thread.
+    ::PostMessageW(m_layerHostWindow, WKCACFViewWindow::customDestroyMessage, 0, 0);
+    m_layerHostWindow = 0;
 }
 
 #endif // USE(ACCELERATED_COMPOSITING)
@@ -1535,7 +1553,7 @@
 
 void WebView::updateChildWindowGeometries()
 {
-    m_geometriesUpdater.updateGeometries();
+    m_geometriesUpdater.updateGeometries(DoNotBringToTop);
 }
 
 // WebCore::WindowMessageListener

Modified: trunk/Source/WebKit2/UIProcess/win/WebView.h (87830 => 87831)


--- trunk/Source/WebKit2/UIProcess/win/WebView.h	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/UIProcess/win/WebView.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -280,6 +280,10 @@
 #if ENABLE(FULLSCREEN_API)
     OwnPtr<WebCore::FullScreenController> m_fullScreenController;
 #endif
+
+#if USE(ACCELERATED_COMPOSITING)
+    HWND m_layerHostWindow;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h (87830 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -41,6 +41,10 @@
 class UpdateInfo;
 class WebPage;
 
+#if PLATFORM(WIN)
+struct WindowGeometry;
+#endif
+
 class LayerTreeHost : public RefCounted<LayerTreeHost> {
 public:
     static PassRefPtr<LayerTreeHost> create(WebPage*);
@@ -74,6 +78,10 @@
     virtual double timeUntilNextDisplay() { ASSERT_NOT_REACHED(); return 0; }
     virtual void display(UpdateInfo&) { ASSERT_NOT_REACHED(); }
 
+#if PLATFORM(WIN)
+    virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&) = 0;
+#endif
+
 protected:
     explicit LayerTreeHost(WebPage*);
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp (87830 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -31,8 +31,8 @@
 #include "DrawingAreaImpl.h"
 #include "ShareableBitmap.h"
 #include "UpdateInfo.h"
+#include "WKCACFViewWindow.h"
 #include "WebPage.h"
-#include <WebCore/DefWndProcWindowClass.h>
 #include <WebCore/GraphicsLayerCA.h>
 #include <WebCore/LayerChangesFlusher.h>
 #include <WebCore/PlatformCALayer.h>
@@ -52,15 +52,6 @@
 
 namespace WebKit {
 
-static HWND dummyWindow;
-static size_t validLayerTreeHostCount;
-
-// This window is never shown. It is only needed so that D3D can determine the display mode, etc.
-static HWND createDummyWindow()
-{
-    return ::CreateWindowW(defWndProcWindowClassName(), 0, WS_POPUP, 0, 0, 10, 10, 0, 0, instanceHandle(), 0);
-}
-
 bool LayerTreeHostCAWin::supportsAcceleratedCompositing()
 {
     static bool initialized;
@@ -69,17 +60,14 @@
         return supportsAcceleratedCompositing;
     initialized = true;
 
-    ASSERT(!dummyWindow);
-    dummyWindow = createDummyWindow();
-    RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationImage));
+    RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
+    WKCACFViewWindow dummyWindow(view.get(), 0, 0);
     CGRect fakeBounds = CGRectMake(0, 0, 10, 10);
-    WKCACFViewUpdate(view.get(), dummyWindow, &fakeBounds);
+    WKCACFViewUpdate(view.get(), dummyWindow.window(), &fakeBounds);
 
     supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get());
 
     WKCACFViewUpdate(view.get(), 0, 0);
-    ::DestroyWindow(dummyWindow);
-    dummyWindow = 0;
 
     return supportsAcceleratedCompositing;
 }
@@ -94,7 +82,6 @@
 LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage)
     : LayerTreeHostCA(webPage)
     , m_isFlushingLayerChanges(false)
-    , m_nextDisplayTime(0)
 {
 }
 
@@ -102,36 +89,43 @@
 {
 }
 
-void LayerTreeHostCAWin::platformInitialize(LayerTreeContext&)
+void LayerTreeHostCAWin::platformInitialize(LayerTreeContext& context)
 {
-    ++validLayerTreeHostCount;
-    if (!dummyWindow)
-        dummyWindow = createDummyWindow();
-
-    m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationImage));
+    m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
     WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this));
     WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer());
     WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
 
+    // Passing WS_DISABLED makes the window invisible to mouse events, which lets WKView's normal
+    // event handling mechanism work even when this window is obscuring the entire WKView HWND.
+    // Note that m_webPage->nativeWindow() is owned by the UI process, so this creates a cross-
+    // process window hierarchy (and thus implicitly attaches the input queues of the UI and web
+    // processes' main threads).
+    m_window = adoptPtr(new WKCACFViewWindow(m_view.get(), m_webPage->nativeWindow(), WS_DISABLED));
+
     CGRect bounds = m_webPage->bounds();
-    WKCACFViewUpdate(m_view.get(), dummyWindow, &bounds);
+    WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
+
+    context.window = m_window->window();
 }
 
 void LayerTreeHostCAWin::invalidate()
 {
     LayerChangesFlusher::shared().cancelPendingFlush(this);
 
-    WKCACFViewUpdate(m_view.get(), 0, 0);
     WKCACFViewSetContextUserData(m_view.get(), 0);
     WKCACFViewSetLayer(m_view.get(), 0);
     WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
 
-    LayerTreeHostCA::invalidate();
+    // The UI process will destroy m_window's HWND when it gets the message to switch out of
+    // accelerated compositing mode. We don't want to destroy the HWND before then or we will get a
+    // flash of white before the UI process has a chance to display the non-composited content.
+    // Since the HWND needs to outlive us, we leak m_window here and tell it to clean itself up
+    // when its HWND is destroyed.
+    WKCACFViewWindow* window = m_window.leakPtr();
+    window->setDeletesSelfWhenWindowDestroyed(true);
 
-    if (--validLayerTreeHostCount)
-        return;
-    ::DestroyWindow(dummyWindow);
-    dummyWindow = 0;
+    LayerTreeHostCA::invalidate();
 }
 
 void LayerTreeHostCAWin::scheduleLayerFlush()
@@ -155,65 +149,16 @@
     LayerChangesFlusher::shared().cancelPendingFlush(this);
 }
 
-bool LayerTreeHostCAWin::participatesInDisplay()
+void LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
 {
-    return true;
+    m_geometriesUpdater.addPendingUpdate(geometry);
 }
 
-bool LayerTreeHostCAWin::needsDisplay()
-{
-    return timeUntilNextDisplay() <= 0;
-}
-
-double LayerTreeHostCAWin::timeUntilNextDisplay()
-{
-    return m_nextDisplayTime - currentTime();
-}
-
-static IntSize size(WKCACFImageRef image)
-{
-    return IntSize(WKCACFImageGetWidth(image), WKCACFImageGetHeight(image));
-}
-
-static PassRefPtr<ShareableBitmap> toShareableBitmap(WKCACFImageRef image)
-{
-    size_t fileMappingSize;
-    HANDLE mapping = WKCACFImageCopyFileMapping(image, &fileMappingSize);
-    if (!mapping)
-        return 0;
-
-    RefPtr<SharedMemory> sharedMemory = SharedMemory::adopt(mapping, fileMappingSize, SharedMemory::ReadWrite);
-    if (!sharedMemory) {
-        ::CloseHandle(mapping);
-        return 0;
-    }
-
-    // WKCACFImage never has an alpha channel.
-    return ShareableBitmap::create(size(image), 0, sharedMemory.release());
-}
-
-void LayerTreeHostCAWin::display(UpdateInfo& updateInfo)
-{
-    CGPoint imageOrigin;
-    CFTimeInterval nextDrawTime;
-    RetainPtr<WKCACFImageRef> image(AdoptCF, WKCACFViewCopyDrawnImage(m_view.get(), &imageOrigin, &nextDrawTime));
-    m_nextDisplayTime = nextDrawTime - CACurrentMediaTime() + currentTime();
-    if (!image)
-        return;
-    RefPtr<ShareableBitmap> bitmap = toShareableBitmap(image.get());
-    if (!bitmap)
-        return;
-    if (!bitmap->createHandle(updateInfo.bitmapHandle))
-        return;
-    updateInfo.updateRectBounds = IntRect(IntPoint(imageOrigin.x, m_webPage->size().height() - imageOrigin.y - bitmap->size().height()), bitmap->size());
-    updateInfo.updateRects.append(updateInfo.updateRectBounds);
-}
-
 void LayerTreeHostCAWin::sizeDidChange(const IntSize& newSize)
 {
     LayerTreeHostCA::sizeDidChange(newSize);
     CGRect bounds = CGRectMake(0, 0, newSize.width(), newSize.height());
-    WKCACFViewUpdate(m_view.get(), dummyWindow, &bounds);
+    WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
     WKCACFViewFlushContext(m_view.get());
 }
 
@@ -249,8 +194,11 @@
 
     m_pendingAnimatedLayers.clear();
 
-    m_nextDisplayTime = 0;
-    static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->setLayerHostNeedsDisplay();
+    // Update child window geometries now so that they stay mostly in sync with the accelerated content.
+    // FIXME: We should really be doing this when the changes we just flushed appear on screen. <http://webkit.org/b/61867>
+    // We also bring the child windows (i.e., plugins) to the top of the z-order to ensure they are above m_window.
+    // FIXME: We could do this just once per window when it is first shown. Maybe that would be more efficient?
+    m_geometriesUpdater.updateGeometries(BringToTop);
 }
 
 PlatformCALayer* LayerTreeHostCAWin::rootLayer() const
@@ -295,7 +243,11 @@
 }
 
 void LayerTreeHostCAWin::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
-{    
+{
+    // Don't flush any changes when we don't have a root layer. This will prevent flashes of white
+    // when switching out of compositing mode.
+    setLayerFlushSchedulingEnabled(graphicsLayer);
+
     // Resubmit all existing animations. CACF does not remember running animations
     // When the layer tree is removed and then added back to the hierarchy
     if (graphicsLayer)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h (87830 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -30,6 +30,7 @@
 
 #if HAVE(WKQCA)
 
+#include "CoalescedWindowGeometriesUpdater.h"
 #include "LayerTreeHostCA.h"
 #include <WebCore/AbstractCACFLayerTreeHost.h>
 #include <wtf/HashSet.h>
@@ -39,6 +40,8 @@
 
 namespace WebKit {
 
+class WKCACFViewWindow;
+
 class LayerTreeHostCAWin : public LayerTreeHostCA, private WebCore::AbstractCACFLayerTreeHost {
 public:
     static bool supportsAcceleratedCompositing();
@@ -58,10 +61,7 @@
     virtual void sizeDidChange(const WebCore::IntSize& newSize);
     virtual void scheduleLayerFlush();
     virtual void setLayerFlushSchedulingEnabled(bool);
-    virtual bool participatesInDisplay();
-    virtual bool needsDisplay();
-    virtual double timeUntilNextDisplay();
-    virtual void display(UpdateInfo&);
+    virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&);
 
     // LayerTreeHostCA
     virtual void platformInitialize(LayerTreeContext&);
@@ -73,10 +73,11 @@
     virtual void layerTreeDidChange();
     virtual void flushPendingLayerChangesNow();
 
+    OwnPtr<WKCACFViewWindow> m_window;
     RetainPtr<WKCACFViewRef> m_view;
     HashSet<RefPtr<WebCore::PlatformCALayer> > m_pendingAnimatedLayers;
     bool m_isFlushingLayerChanges;
-    double m_nextDisplayTime;
+    CoalescedWindowGeometriesUpdater m_geometriesUpdater;
 };
 
 } // namespace WebKit

Added: trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp (0 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -0,0 +1,164 @@
+/*
+ * 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 "WKCACFViewWindow.h"
+
+#if HAVE(WKQCA)
+
+#include <WebCore/WebCoreInstanceHandle.h>
+#include <WebKitQuartzCoreAdditions/WKCACFView.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static LPCWSTR windowClassName = L"WKCACFViewWindowClass";
+
+WKCACFViewWindow::WKCACFViewWindow(WKCACFViewRef view, HWND parentWindow, DWORD additionalStyles)
+    : m_window(0)
+    , m_view(view)
+    , m_deletesSelfWhenWindowDestroyed(false)
+{
+    ASSERT_ARG(view, view);
+
+    registerClass();
+
+    UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | additionalStyles;
+    if (parentWindow)
+        style |= WS_CHILD;
+    else
+        style |= WS_POPUP;
+
+    m_window = ::CreateWindowExW(0, windowClassName, L"WKCACFViewWindow", style, 0, 0, 0, 0, parentWindow, 0, instanceHandle(), this);
+    ASSERT_WITH_MESSAGE(m_window, "::CreateWindowExW failed with error %lu", ::GetLastError());
+}
+
+WKCACFViewWindow::~WKCACFViewWindow()
+{
+    if (!m_window)
+        return;
+
+    ASSERT(!m_deletesSelfWhenWindowDestroyed);
+    ::DestroyWindow(m_window);
+}
+
+LRESULT WKCACFViewWindow::onCustomDestroy(WPARAM, LPARAM)
+{
+    ::DestroyWindow(m_window);
+    return 0;
+}
+
+LRESULT WKCACFViewWindow::onDestroy(WPARAM, LPARAM)
+{
+    WKCACFViewUpdate(m_view.get(), 0, 0);
+    return 0;
+}
+
+LRESULT WKCACFViewWindow::onEraseBackground(WPARAM, LPARAM)
+{
+    // Tell Windows not to erase us.
+    return 1;
+}
+
+LRESULT WKCACFViewWindow::onNCDestroy(WPARAM, LPARAM)
+{
+    m_window = 0;
+
+    if (!m_deletesSelfWhenWindowDestroyed)
+        return 0;
+
+    delete this;
+    return 0;
+}
+
+LRESULT WKCACFViewWindow::onPaint(WPARAM, LPARAM)
+{
+    WKCACFViewDraw(m_view.get());
+    ::ValidateRect(m_window, 0);
+    return 0;
+}
+
+LRESULT WKCACFViewWindow::onPrintClient(WPARAM wParam, LPARAM lParam)
+{
+    if (!(lParam & PRF_CLIENT))
+        return 0;
+
+    WKCACFViewDrawIntoDC(m_view.get(), reinterpret_cast<HDC>(wParam));
+    return 0;
+}
+
+void WKCACFViewWindow::registerClass()
+{
+    static bool didRegister;
+    if (didRegister)
+        return;
+    didRegister = true;
+
+    WNDCLASSW wndClass = {0};
+    wndClass.lpfnWndProc = staticWndProc;
+    wndClass.hInstance = instanceHandle();
+    wndClass.lpszClassName = windowClassName;
+
+    ::RegisterClassW(&wndClass);
+}
+
+LRESULT WKCACFViewWindow::staticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    WKCACFViewWindow* window = reinterpret_cast<WKCACFViewWindow*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
+    if (!window) {
+        if (message != WM_CREATE)
+            return ::DefWindowProcW(hWnd, message, wParam, lParam);
+        CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam);
+        window = static_cast<WKCACFViewWindow*>(createStruct->lpCreateParams);
+        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(window));
+    }
+
+    return window->wndProc(message, wParam, lParam);
+}
+
+LRESULT WKCACFViewWindow::wndProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+    switch (message) {
+    case customDestroyMessage:
+        return onCustomDestroy(wParam, lParam);
+    case WM_DESTROY:
+        return onDestroy(wParam, lParam);
+    case WM_ERASEBKGND:
+        return onEraseBackground(wParam, lParam);
+    case WM_NCDESTROY:
+        return onNCDestroy(wParam, lParam);
+    case WM_PAINT:
+        return onPaint(wParam, lParam);
+    case WM_PRINTCLIENT:
+        return onPrintClient(wParam, lParam);
+    default:
+        return ::DefWindowProcW(m_window, message, wParam, lParam);
+    }
+}
+
+} // namespace WebKit
+
+#endif // USE(ACCELERATED_COMPOSITING)
Property changes on: trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp
___________________________________________________________________

Added: svn:eol-style

Copied: trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h (from rev 87806, trunk/Source/WebKit2/Shared/win/CoalescedWindowGeometriesUpdater.h) (0 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h	2011-06-01 18:39:19 UTC (rev 87831)
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef WKCACFViewWindow_h
+#define WKCACFViewWindow_h
+
+#include "HeaderDetection.h"
+
+#if HAVE(WKQCA)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct _WKCACFView* WKCACFViewRef;
+
+namespace WebKit {
+
+// FIXME: Move this class down to WebCore. (Maybe it can even replace some of WKCACFViewLayerTreeHost.)
+class WKCACFViewWindow {
+    WTF_MAKE_NONCOPYABLE(WKCACFViewWindow);
+public:
+    // WKCACFViewWindow will destroy its HWND when this message is received.
+    static const UINT customDestroyMessage = WM_USER + 1;
+
+    WKCACFViewWindow(WKCACFViewRef, HWND parentWindow, DWORD additionalStyles);
+    ~WKCACFViewWindow();
+
+    void setDeletesSelfWhenWindowDestroyed(bool deletes) { m_deletesSelfWhenWindowDestroyed = deletes; }
+
+    HWND window() const { return m_window; }
+
+private:
+    LRESULT onCustomDestroy(WPARAM, LPARAM);
+    LRESULT onDestroy(WPARAM, LPARAM);
+    LRESULT onEraseBackground(WPARAM, LPARAM);
+    LRESULT onNCDestroy(WPARAM, LPARAM);
+    LRESULT onPaint(WPARAM, LPARAM);
+    LRESULT onPrintClient(WPARAM, LPARAM);
+    static void registerClass();
+    static LRESULT CALLBACK staticWndProc(HWND, UINT, WPARAM, LPARAM);
+    LRESULT wndProc(UINT, WPARAM, LPARAM);
+
+    HWND m_window;
+    RetainPtr<WKCACFViewRef> m_view;
+    bool m_deletesSelfWhenWindowDestroyed;
+};
+
+} // namespace WebKit
+
+#endif // HAVE(WKQCA)
+
+#endif // WKCACFViewWindow_h

Modified: trunk/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp (87830 => 87831)


--- trunk/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp	2011-06-01 18:39:19 UTC (rev 87831)
@@ -34,9 +34,16 @@
 
 void DrawingAreaImpl::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
 {
+#if USE(ACCELERATED_COMPOSITING)
+    if (m_layerTreeHost) {
+        m_layerTreeHost->scheduleChildWindowGeometryUpdate(geometry);
+        return;
+    }
+#endif
+
     // FIXME: This should be a Messages::DrawingAreaProxy, and DrawingAreaProxy should pass the
     // data off to the WebPageProxy.
     m_webPage->send(Messages::WebPageProxy::ScheduleChildWindowGeometryUpdate(geometry));
 }
 
-} // namespace WebKit
\ No newline at end of file
+} // namespace WebKit

Modified: trunk/Source/WebKit2/win/WebKit2.vcproj (87830 => 87831)


--- trunk/Source/WebKit2/win/WebKit2.vcproj	2011-06-01 18:38:35 UTC (rev 87830)
+++ trunk/Source/WebKit2/win/WebKit2.vcproj	2011-06-01 18:39:19 UTC (rev 87831)
@@ -2047,6 +2047,14 @@
 							RelativePath="..\WebProcess\WebPage\ca\win\LayerTreeHostCAWin.h"
 							>
 						</File>
+						<File
+							RelativePath="..\WebProcess\WebPage\ca\win\WKCACFViewWindow.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\WebProcess\WebPage\ca\win\WKCACFViewWindow.h"
+							>
+						</File>
 					</Filter>
 				</Filter>
 			</Filter>
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to