2011-02-03 Anders Carlsson <andersca@apple.com>
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / mac / LayerTreeHostMac.mm
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "LayerTreeHostMac.h"
28
29 #import "WebPage.h"
30 #import "WebProcess.h"
31 #import <WebCore/Frame.h>
32 #import <WebCore/FrameView.h>
33 #import <WebCore/Page.h>
34 #import <WebCore/Settings.h>
35 #import <WebKitSystemInterface.h>
36
37 using namespace WebCore;
38
39 namespace WebKit {
40
41 PassRefPtr<LayerTreeHostMac> LayerTreeHostMac::create(WebPage* webPage, GraphicsLayer* graphicsLayer)
42 {
43     return adoptRef(new LayerTreeHostMac(webPage, graphicsLayer));
44 }
45
46 LayerTreeHostMac::LayerTreeHostMac(WebPage* webPage, GraphicsLayer* graphicsLayer)
47     : LayerTreeHost(webPage)
48     , m_layerTreeContext(LayerTreeContext::makeWithSeed())
49     , m_isValid(true)
50 {
51     mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
52     m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort);
53
54     // Create a root layer.
55     m_rootLayer = GraphicsLayer::create(this);
56 #ifndef NDEBUG
57     m_rootLayer->setName("LayerTreeHost root layer");
58 #endif
59     m_rootLayer->setDrawsContent(false);
60     m_rootLayer->setSize(webPage->size());
61
62     // Add the accelerated layer tree hierarchy.
63     m_rootLayer->addChild(graphicsLayer);
64     
65     WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer());
66
67     scheduleLayerFlush();
68
69     m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
70 }
71
72 LayerTreeHostMac::~LayerTreeHostMac()
73 {
74     ASSERT(!m_isValid);
75     ASSERT(!m_flushPendingLayerChangesRunLoopObserver);
76     ASSERT(!m_remoteLayerClient);
77     ASSERT(!m_rootLayer);
78 }
79
80 const LayerTreeContext& LayerTreeHostMac::layerTreeContext()
81 {
82     return m_layerTreeContext;
83 }
84
85 void LayerTreeHostMac::scheduleLayerFlush()
86 {
87     CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
88     
89     // Make sure we wake up the loop or the observer could be delayed until some other source fires.
90     CFRunLoopWakeUp(currentRunLoop);
91
92     if (m_flushPendingLayerChangesRunLoopObserver)
93         return;
94
95     // Run before the Core Animation commit observer, which has order 2000000.
96     const CFIndex runLoopOrder = 2000000 - 1;
97     CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
98     m_flushPendingLayerChangesRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, true, runLoopOrder, flushPendingLayerChangesRunLoopObserverCallback, &context));
99
100     CFRunLoopAddObserver(currentRunLoop, m_flushPendingLayerChangesRunLoopObserver.get(), kCFRunLoopCommonModes);
101 }
102
103 void LayerTreeHostMac::invalidate()
104 {
105     ASSERT(m_isValid);
106
107     if (m_flushPendingLayerChangesRunLoopObserver) {
108         CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
109         m_flushPendingLayerChangesRunLoopObserver = nullptr;
110     }
111
112     WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get());
113     m_remoteLayerClient = nullptr;
114     m_rootLayer = nullptr;
115     m_isValid = false;
116 }
117
118 void LayerTreeHostMac::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
119 {
120 }
121
122 void LayerTreeHostMac::notifySyncRequired(const WebCore::GraphicsLayer*)
123 {
124 }
125
126 void LayerTreeHostMac::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
127 {
128 }
129
130 bool LayerTreeHostMac::showDebugBorders() const
131 {
132     return m_webPage->corePage()->settings()->showDebugBorders();
133 }
134
135 bool LayerTreeHostMac::showRepaintCounter() const
136 {
137     return m_webPage->corePage()->settings()->showRepaintCounter();
138 }
139
140 void LayerTreeHostMac::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context)
141 {
142     static_cast<LayerTreeHostMac*>(context)->flushPendingLayerChangesRunLoopObserverCallback();
143 }
144
145 void LayerTreeHostMac::flushPendingLayerChangesRunLoopObserverCallback()
146 {
147     if (!flushPendingLayerChanges())
148         return;
149
150     // We successfully flushed the pending layer changes, remove the run loop observer.
151     ASSERT(m_flushPendingLayerChangesRunLoopObserver);
152     CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
153     m_flushPendingLayerChangesRunLoopObserver = 0;
154 }
155
156 bool LayerTreeHostMac::flushPendingLayerChanges()
157 {
158     m_rootLayer->syncCompositingStateForThisLayerOnly();
159
160     return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
161 }
162
163     
164 } // namespace WebKit