f8fdde428c20da084aa838012f2d28ed0b3f39c3
[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 "DrawingAreaProxyMessages.h"
30 #import "WebPage.h"
31 #import "WebProcess.h"
32 #import <WebCore/Frame.h>
33 #import <WebCore/FrameView.h>
34 #import <WebCore/Page.h>
35 #import <WebCore/Settings.h>
36 #import <WebKitSystemInterface.h>
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
42 PassRefPtr<LayerTreeHostMac> LayerTreeHostMac::create(WebPage* webPage, GraphicsLayer* graphicsLayer)
43 {
44     return adoptRef(new LayerTreeHostMac(webPage, graphicsLayer));
45 }
46
47 LayerTreeHostMac::LayerTreeHostMac(WebPage* webPage, GraphicsLayer* graphicsLayer)
48     : LayerTreeHost(webPage)
49     , m_layerTreeContext(LayerTreeContext::makeWithSeed())
50     , m_isValid(true)
51 {
52     mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
53     m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort);
54
55     // Create a root layer.
56     m_rootLayer = GraphicsLayer::create(this);
57 #ifndef NDEBUG
58     m_rootLayer->setName("LayerTreeHost root layer");
59 #endif
60     m_rootLayer->setDrawsContent(false);
61     m_rootLayer->setSize(webPage->size());
62
63     // Add the accelerated layer tree hierarchy.
64     m_rootLayer->addChild(graphicsLayer);
65     
66     WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer());
67
68     scheduleLayerFlush();
69
70     m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
71
72     // FIXME: Don't send this if we enter accelerated compositing as a result of setSize.
73     m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_layerTreeContext));
74 }
75
76 LayerTreeHostMac::~LayerTreeHostMac()
77 {
78     ASSERT(!m_isValid);
79     ASSERT(!m_flushPendingLayerChangesRunLoopObserver);
80     ASSERT(!m_remoteLayerClient);
81     ASSERT(!m_rootLayer);
82 }
83
84 void LayerTreeHostMac::scheduleLayerFlush()
85 {
86     CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
87     
88     // Make sure we wake up the loop or the observer could be delayed until some other source fires.
89     CFRunLoopWakeUp(currentRunLoop);
90
91     if (m_flushPendingLayerChangesRunLoopObserver)
92         return;
93
94     // Run before the Core Animation commit observer, which has order 2000000.
95     const CFIndex runLoopOrder = 2000000 - 1;
96     CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
97     m_flushPendingLayerChangesRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0, kCFRunLoopBeforeWaiting | kCFRunLoopExit, true, runLoopOrder, flushPendingLayerChangesRunLoopObserverCallback, &context));
98
99     CFRunLoopAddObserver(currentRunLoop, m_flushPendingLayerChangesRunLoopObserver.get(), kCFRunLoopCommonModes);
100 }
101
102 void LayerTreeHostMac::invalidate()
103 {
104     ASSERT(m_isValid);
105
106     if (m_flushPendingLayerChangesRunLoopObserver) {
107         CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
108         m_flushPendingLayerChangesRunLoopObserver = nullptr;
109     }
110
111     WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get());
112     m_remoteLayerClient = nullptr;
113     m_rootLayer = nullptr;
114     m_isValid = false;
115
116     // FIXME: Don't send this if we enter accelerated compositing as a result of setSize.
117     m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode());
118 }
119
120 void LayerTreeHostMac::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
121 {
122 }
123
124 void LayerTreeHostMac::notifySyncRequired(const WebCore::GraphicsLayer*)
125 {
126 }
127
128 void LayerTreeHostMac::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
129 {
130 }
131
132 bool LayerTreeHostMac::showDebugBorders() const
133 {
134     return m_webPage->corePage()->settings()->showDebugBorders();
135 }
136
137 bool LayerTreeHostMac::showRepaintCounter() const
138 {
139     return m_webPage->corePage()->settings()->showRepaintCounter();
140 }
141
142 void LayerTreeHostMac::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context)
143 {
144     static_cast<LayerTreeHostMac*>(context)->flushPendingLayerChangesRunLoopObserverCallback();
145 }
146
147 void LayerTreeHostMac::flushPendingLayerChangesRunLoopObserverCallback()
148 {
149     if (!flushPendingLayerChanges())
150         return;
151
152     // We successfully flushed the pending layer changes, remove the run loop observer.
153     ASSERT(m_flushPendingLayerChangesRunLoopObserver);
154     CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get());
155     m_flushPendingLayerChangesRunLoopObserver = 0;
156 }
157
158 bool LayerTreeHostMac::flushPendingLayerChanges()
159 {
160     m_rootLayer->syncCompositingStateForThisLayerOnly();
161
162     return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
163 }
164
165     
166 } // namespace WebKit