diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/ca')
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 |