summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/WebProcess/WebPage/ca
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/ca')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp29
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h49
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h64
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm66
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp270
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h84
6 files changed, 478 insertions, 84 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp
index 2460607..42a2dc9 100644
--- a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp
@@ -31,39 +31,41 @@
#include "WebProcess.h"
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsLayerCA.h>
#include <WebCore/Page.h>
+#include <WebCore/PlatformCALayer.h>
#include <WebCore/Settings.h>
using namespace WebCore;
namespace WebKit {
-PassRefPtr<LayerTreeHostCA> LayerTreeHostCA::create(WebPage* webPage)
-{
- return adoptRef(new LayerTreeHostCA(webPage));
-}
-
LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage)
: LayerTreeHost(webPage)
, m_isValid(true)
, m_notifyAfterScheduledLayerFlush(false)
{
+}
+void LayerTreeHostCA::initialize()
+{
// Create a root layer.
m_rootLayer = GraphicsLayer::create(this);
#ifndef NDEBUG
m_rootLayer->setName("LayerTreeHost root layer");
#endif
m_rootLayer->setDrawsContent(false);
- m_rootLayer->setSize(webPage->size());
+ m_rootLayer->setSize(m_webPage->size());
+ static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true);
m_nonCompositedContentLayer = GraphicsLayer::create(this);
+ static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false);
#ifndef NDEBUG
m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content");
#endif
m_nonCompositedContentLayer->setDrawsContent(true);
m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
- m_nonCompositedContentLayer->setSize(webPage->size());
+ m_nonCompositedContentLayer->setSize(m_webPage->size());
if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled())
m_nonCompositedContentLayer->setAcceleratesDrawing(true);
@@ -72,7 +74,7 @@ LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage)
if (m_webPage->hasPageOverlay())
createPageOverlayLayer();
- platformInitialize();
+ platformInitialize(m_layerTreeContext);
scheduleLayerFlush();
}
@@ -81,10 +83,6 @@ LayerTreeHostCA::~LayerTreeHostCA()
{
ASSERT(!m_isValid);
ASSERT(!m_rootLayer);
-#if PLATFORM(MAC)
- ASSERT(!m_flushPendingLayerChangesRunLoopObserver);
- ASSERT(!m_remoteLayerClient);
-#endif
}
const LayerTreeContext& LayerTreeHostCA::layerTreeContext()
@@ -109,7 +107,6 @@ void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
void LayerTreeHostCA::invalidate()
{
ASSERT(m_isValid);
- platformInvalidate();
m_rootLayer = nullptr;
m_isValid = false;
}
@@ -138,16 +135,12 @@ void LayerTreeHostCA::sizeDidChange(const IntSize& newSize)
scheduleLayerFlush();
flushPendingLayerChanges();
-
- platformSizeDidChange();
}
void LayerTreeHostCA::forceRepaint()
{
scheduleLayerFlush();
flushPendingLayerChanges();
-
- platformForceRepaint();
}
void LayerTreeHostCA::didInstallPageOverlay()
@@ -218,8 +211,6 @@ void LayerTreeHostCA::performScheduledLayerFlush()
void LayerTreeHostCA::didPerformScheduledLayerFlush()
{
- platformDidPerformScheduledLayerFlush();
-
if (m_notifyAfterScheduledLayerFlush) {
// Let the drawing area know that we've done a flush of the layer changes.
static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h
index ba4e33a..3a62d15 100644
--- a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h
+++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h
@@ -31,35 +31,36 @@
#include <WebCore/GraphicsLayerClient.h>
#include <wtf/OwnPtr.h>
-#if PLATFORM(MAC)
-#include <wtf/RetainPtr.h>
-#endif
-
-#if PLATFORM(MAC)
-typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef;
-#endif
-
namespace WebKit {
class LayerTreeHostCA : public LayerTreeHost, WebCore::GraphicsLayerClient {
public:
- static PassRefPtr<LayerTreeHostCA> create(WebPage*);
- ~LayerTreeHostCA();
+ virtual ~LayerTreeHostCA();
-private:
+protected:
explicit LayerTreeHostCA(WebPage*);
+ WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); }
+
+ void initialize();
+ void performScheduledLayerFlush();
+
+ // LayerTreeHost.
+ virtual void invalidate();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void forceRepaint();
+
+ // LayerTreeHostCA
+ virtual void didPerformScheduledLayerFlush();
+
+private:
// LayerTreeHost.
virtual const LayerTreeContext& layerTreeContext();
- virtual void scheduleLayerFlush();
virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool);
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
- virtual void invalidate();
virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&);
virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
- virtual void sizeDidChange(const WebCore::IntSize& newSize);
- virtual void forceRepaint();
virtual void didInstallPageOverlay();
virtual void didUninstallPageOverlay();
@@ -72,23 +73,14 @@ private:
virtual bool showDebugBorders() const;
virtual bool showRepaintCounter() const;
- void platformInitialize();
- void platformInvalidate();
- void platformSizeDidChange();
- void platformForceRepaint();
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&) = 0;
- void performScheduledLayerFlush();
- void didPerformScheduledLayerFlush();
- void platformDidPerformScheduledLayerFlush();
bool flushPendingLayerChanges();
void createPageOverlayLayer();
void destroyPageOverlayLayer();
-#if PLATFORM(MAC)
- static void flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*);
-#endif
-
// The context for this layer tree.
LayerTreeContext m_layerTreeContext;
@@ -107,11 +99,6 @@ private:
// The page overlay layer. Will be null if there's no page overlay.
OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer;
-
-#if PLATFORM(MAC)
- RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient;
- RetainPtr<CFRunLoopObserverRef> m_flushPendingLayerChangesRunLoopObserver;
-#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h
new file mode 100644
index 0000000..e3a0160
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h
@@ -0,0 +1,64 @@
+/*
+ * 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 LayerTreeHostCAMac_h
+#define LayerTreeHostCAMac_h
+
+#include "LayerTreeHostCA.h"
+#include <wtf/RetainPtr.h>
+
+typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef;
+
+namespace WebKit {
+
+class LayerTreeHostCAMac : public LayerTreeHostCA {
+public:
+ static PassRefPtr<LayerTreeHostCAMac> create(WebPage*);
+ virtual ~LayerTreeHostCAMac();
+
+private:
+ explicit LayerTreeHostCAMac(WebPage*);
+
+ // LayerTreeHost.
+ virtual void scheduleLayerFlush();
+ virtual void invalidate();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void forceRepaint();
+ virtual void pauseRendering();
+ virtual void resumeRendering();
+
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&);
+ virtual void didPerformScheduledLayerFlush();
+
+ static void flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*);
+
+ RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient;
+ RetainPtr<CFRunLoopObserverRef> m_flushPendingLayerChangesRunLoopObserver;
+};
+
+} // namespace WebKit
+
+#endif // LayerTreeHostCAMac_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm
index 50776d7..69cfa44 100644
--- a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm
+++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm
@@ -24,32 +24,50 @@
*/
#import "config.h"
-#import "LayerTreeHostCA.h"
+#import "LayerTreeHostCAMac.h"
#import "WebProcess.h"
#import <QuartzCore/CATransaction.h>
#import <WebCore/GraphicsLayer.h>
#import <WebKitSystemInterface.h>
+using namespace WebCore;
+
@interface CATransaction (Details)
+ (void)synchronize;
@end
namespace WebKit {
-void LayerTreeHostCA::platformInitialize()
+PassRefPtr<LayerTreeHostCAMac> LayerTreeHostCAMac::create(WebPage* webPage)
+{
+ RefPtr<LayerTreeHostCAMac> host = adoptRef(new LayerTreeHostCAMac(webPage));
+ host->initialize();
+ return host.release();
+}
+
+LayerTreeHostCAMac::LayerTreeHostCAMac(WebPage* webPage)
+ : LayerTreeHostCA(webPage)
+{
+}
+
+LayerTreeHostCAMac::~LayerTreeHostCAMac()
+{
+ ASSERT(!m_flushPendingLayerChangesRunLoopObserver);
+ ASSERT(!m_remoteLayerClient);
+}
+
+void LayerTreeHostCAMac::platformInitialize(LayerTreeContext& layerTreeContext)
{
mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort);
- [m_rootLayer->platformLayer() setGeometryFlipped:YES];
+ WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), rootLayer()->platformLayer());
- WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer());
-
- m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
+ layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
}
-void LayerTreeHostCA::scheduleLayerFlush()
+void LayerTreeHostCAMac::scheduleLayerFlush()
{
CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
@@ -67,7 +85,7 @@ void LayerTreeHostCA::scheduleLayerFlush()
CFRunLoopAddObserver(currentRunLoop, m_flushPendingLayerChangesRunLoopObserver.get(), kCFRunLoopCommonModes);
}
-void LayerTreeHostCA::platformInvalidate()
+void LayerTreeHostCAMac::invalidate()
{
if (m_flushPendingLayerChangesRunLoopObserver) {
CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
@@ -76,34 +94,54 @@ void LayerTreeHostCA::platformInvalidate()
WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get());
m_remoteLayerClient = nullptr;
+
+ LayerTreeHostCA::invalidate();
}
-void LayerTreeHostCA::platformSizeDidChange()
+void LayerTreeHostCAMac::sizeDidChange(const IntSize& newSize)
{
+ LayerTreeHostCA::sizeDidChange(newSize);
[CATransaction flush];
[CATransaction synchronize];
}
-void LayerTreeHostCA::platformForceRepaint()
+void LayerTreeHostCAMac::forceRepaint()
{
+ LayerTreeHostCA::forceRepaint();
[CATransaction flush];
[CATransaction synchronize];
-}
+}
+
+void LayerTreeHostCAMac::pauseRendering()
+{
+ CALayer* root = rootLayer()->platformLayer();
+ [root setValue:(id)kCFBooleanTrue forKey:@"NSCAViewRenderPaused"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidPauseNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]];
+}
-void LayerTreeHostCA::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context)
+void LayerTreeHostCAMac::resumeRendering()
+{
+ CALayer* root = rootLayer()->platformLayer();
+ [root setValue:(id)kCFBooleanFalse forKey:@"NSCAViewRenderPaused"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidResumeNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]];
+}
+
+void LayerTreeHostCAMac::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context)
{
// This gets called outside of the normal event loop so wrap in an autorelease pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- static_cast<LayerTreeHostCA*>(context)->performScheduledLayerFlush();
+ static_cast<LayerTreeHostCAMac*>(context)->performScheduledLayerFlush();
[pool drain];
}
-void LayerTreeHostCA::platformDidPerformScheduledLayerFlush()
+void LayerTreeHostCAMac::didPerformScheduledLayerFlush()
{
// We successfully flushed the pending layer changes, remove the run loop observer.
ASSERT(m_flushPendingLayerChangesRunLoopObserver);
CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
m_flushPendingLayerChangesRunLoopObserver = 0;
+
+ LayerTreeHostCA::didPerformScheduledLayerFlush();
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp
index 81db03e..699a1fe 100644
--- a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp
@@ -24,46 +24,276 @@
*/
#include "config.h"
-#include "LayerTreeHostCA.h"
+#include "LayerTreeHostCAWin.h"
-#include <WebCore/NotImplemented.h>
+#if HAVE(WKQCA)
+
+#include "DrawingAreaImpl.h"
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
+#include "WebPage.h"
+#include <WebCore/GraphicsLayerCA.h>
+#include <WebCore/LayerChangesFlusher.h>
+#include <WebCore/PlatformCALayer.h>
+#include <WebCore/WebCoreInstanceHandle.h>
+#include <WebKitQuartzCoreAdditions/WKCACFImage.h>
+#include <WebKitQuartzCoreAdditions/WKCACFView.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/Threading.h>
+
+#ifdef DEBUG_ALL
+#pragma comment(lib, "WebKitQuartzCoreAdditions_debug")
+#else
+#pragma comment(lib, "WebKitQuartzCoreAdditions")
+#endif
+
+using namespace WebCore;
namespace WebKit {
-void LayerTreeHostCA::platformInitialize()
+static HWND dummyWindow;
+static LPCWSTR dummyWindowClass = L"LayerTreeHostCAWindowClass";
+static size_t validLayerTreeHostCount;
+
+static void registerDummyWindowClass()
+{
+ static bool didRegister;
+ if (didRegister)
+ return;
+ didRegister = true;
+
+ WNDCLASSW wndClass = {0};
+ wndClass.lpszClassName = dummyWindowClass;
+ wndClass.lpfnWndProc = ::DefWindowProcW;
+ wndClass.hInstance = instanceHandle();
+
+ ::RegisterClassW(&wndClass);
+}
+
+// This window is never shown. It is only needed so that D3D can determine the display mode, etc.
+static HWND createDummyWindow()
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
+ registerDummyWindowClass();
+ return ::CreateWindowW(dummyWindowClass, 0, WS_POPUP, 0, 0, 10, 10, 0, 0, instanceHandle(), 0);
}
-void LayerTreeHostCA::scheduleLayerFlush()
+bool LayerTreeHostCAWin::supportsAcceleratedCompositing()
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
+ static bool initialized;
+ static bool supportsAcceleratedCompositing;
+ if (initialized)
+ return supportsAcceleratedCompositing;
+ initialized = true;
+
+ ASSERT(!dummyWindow);
+ dummyWindow = createDummyWindow();
+ RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationImage));
+ CGRect fakeBounds = CGRectMake(0, 0, 10, 10);
+ WKCACFViewUpdate(view.get(), dummyWindow, &fakeBounds);
+
+ supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get());
+
+ WKCACFViewUpdate(view.get(), 0, 0);
+ ::DestroyWindow(dummyWindow);
+ dummyWindow = 0;
+
+ return supportsAcceleratedCompositing;
}
-void LayerTreeHostCA::platformInvalidate()
+PassRefPtr<LayerTreeHostCAWin> LayerTreeHostCAWin::create(WebPage* webPage)
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
+ RefPtr<LayerTreeHostCAWin> host = adoptRef(new LayerTreeHostCAWin(webPage));
+ host->initialize();
+ return host.release();
}
-void LayerTreeHostCA::platformSizeDidChange()
+LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage)
+ : LayerTreeHostCA(webPage)
+ , m_isFlushingLayerChanges(false)
+ , m_nextDisplayTime(0)
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
}
-void LayerTreeHostCA::platformForceRepaint()
+LayerTreeHostCAWin::~LayerTreeHostCAWin()
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
}
-void LayerTreeHostCA::platformDidPerformScheduledLayerFlush()
+void LayerTreeHostCAWin::platformInitialize(LayerTreeContext&)
{
- // FIXME: <http://webkit.org/b/45567> Implement this!
- notImplemented();
+ ++validLayerTreeHostCount;
+ if (!dummyWindow)
+ dummyWindow = createDummyWindow();
+
+ m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationImage));
+ WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this));
+ WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer());
+ WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
+
+ CGRect bounds = m_webPage->bounds();
+ WKCACFViewUpdate(m_view.get(), dummyWindow, &bounds);
+}
+
+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();
+
+ if (--validLayerTreeHostCount)
+ return;
+ ::DestroyWindow(dummyWindow);
+ dummyWindow = 0;
+}
+
+void LayerTreeHostCAWin::scheduleLayerFlush()
+{
+ LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
+}
+
+bool LayerTreeHostCAWin::participatesInDisplay()
+{
+ return true;
+}
+
+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);
+ WKCACFViewFlushContext(m_view.get());
+}
+
+void LayerTreeHostCAWin::forceRepaint()
+{
+ LayerTreeHostCA::forceRepaint();
+ WKCACFViewFlushContext(m_view.get());
+}
+
+void LayerTreeHostCAWin::contextDidChangeCallback(WKCACFViewRef view, void* info)
+{
+ // This should only be called on a background thread when no changes have actually
+ // been committed to the context, eg. when a video frame has been added to an image
+ // queue, so return without triggering animations etc.
+ if (!isMainThread())
+ return;
+
+ LayerTreeHostCAWin* host = static_cast<LayerTreeHostCAWin*>(info);
+ ASSERT_ARG(view, view == host->m_view);
+ host->contextDidChange();
+}
+
+void LayerTreeHostCAWin::contextDidChange()
+{
+ // Send currentTime to the pending animations. This function is called by CACF in a callback
+ // which occurs after the drawInContext calls. So currentTime is very close to the time
+ // the animations actually start
+ double currentTime = WTF::currentTime();
+
+ HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
+ for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it)
+ (*it)->animationStarted(currentTime);
+
+ m_pendingAnimatedLayers.clear();
+
+ m_nextDisplayTime = 0;
+ static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->setLayerHostNeedsDisplay();
+}
+
+PlatformCALayer* LayerTreeHostCAWin::rootLayer() const
+{
+ return static_cast<GraphicsLayerCA*>(LayerTreeHostCA::rootLayer())->platformCALayer();
+}
+
+void LayerTreeHostCAWin::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer)
+{
+ m_pendingAnimatedLayers.add(layer);
+}
+
+void LayerTreeHostCAWin::layerTreeDidChange()
+{
+ if (m_isFlushingLayerChanges) {
+ // The layer tree is changing as a result of flushing GraphicsLayer changes to their
+ // underlying PlatformCALayers. We'll flush those changes to the context as part of that
+ // process, so there's no need to schedule another flush here.
+ return;
+ }
+
+ // The layer tree is changing as a result of someone modifying a PlatformCALayer that doesn't
+ // have a corresponding GraphicsLayer. Schedule a flush since we won't schedule one through the
+ // normal GraphicsLayer mechanisms.
+ LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
+}
+
+void LayerTreeHostCAWin::flushPendingLayerChangesNow()
+{
+ RefPtr<LayerTreeHostCA> protector(this);
+
+ m_isFlushingLayerChanges = true;
+
+ // Flush changes stored up in GraphicsLayers to their underlying PlatformCALayers, if
+ // requested.
+ performScheduledLayerFlush();
+
+ // Flush changes stored up in PlatformCALayers to the context so they will be rendered.
+ WKCACFViewFlushContext(m_view.get());
+
+ m_isFlushingLayerChanges = false;
}
} // namespace WebKit
+
+#endif // HAVE(WKQCA)
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h
new file mode 100644
index 0000000..2232b08
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h
@@ -0,0 +1,84 @@
+/*
+ * 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 LayerTreeHostCAWin_h
+#define LayerTreeHostCAWin_h
+
+#include "HeaderDetection.h"
+
+#if HAVE(WKQCA)
+
+#include "LayerTreeHostCA.h"
+#include <WebCore/AbstractCACFLayerTreeHost.h>
+#include <wtf/HashSet.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct _WKCACFView* WKCACFViewRef;
+
+namespace WebKit {
+
+class LayerTreeHostCAWin : public LayerTreeHostCA, private WebCore::AbstractCACFLayerTreeHost {
+public:
+ static bool supportsAcceleratedCompositing();
+
+ static PassRefPtr<LayerTreeHostCAWin> create(WebPage*);
+ virtual ~LayerTreeHostCAWin();
+
+private:
+ explicit LayerTreeHostCAWin(WebPage*);
+
+ static void contextDidChangeCallback(WKCACFViewRef, void* info);
+ void contextDidChange();
+
+ // LayerTreeHost
+ virtual void invalidate();
+ virtual void forceRepaint();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void scheduleLayerFlush();
+ virtual bool participatesInDisplay();
+ virtual bool needsDisplay();
+ virtual double timeUntilNextDisplay();
+ virtual void display(UpdateInfo&);
+
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&);
+
+ // AbstractCACFLayerTreeHost
+ virtual WebCore::PlatformCALayer* rootLayer() const;
+ virtual void addPendingAnimatedLayer(PassRefPtr<WebCore::PlatformCALayer>);
+ virtual void layerTreeDidChange();
+ virtual void flushPendingLayerChangesNow();
+
+ RetainPtr<WKCACFViewRef> m_view;
+ HashSet<RefPtr<WebCore::PlatformCALayer> > m_pendingAnimatedLayers;
+ bool m_isFlushingLayerChanges;
+ double m_nextDisplayTime;
+};
+
+} // namespace WebKit
+
+#endif // HAVE(WKQCA)
+
+#endif // LayerTreeHostCAWin_h