e30a69a970cdeccea54a2480b9e9a901cefc0800
[WebKit-https.git] / WebKit2 / WebProcess / WebPage / mac / LayerBackedDrawingAreaMac.mm
1 /*
2  * Copyright (C) 2010 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 #if USE(ACCELERATED_COMPOSITING)
27
28 #include "LayerBackedDrawingArea.h"
29
30 #include "DrawingAreaProxyMessageKinds.h"
31 #include "WebKitSystemInterface.h"
32 #include "WebPage.h"
33 #include "WebProcess.h"
34 #include <WebCore/AnimationTimeController.h>
35 #include <WebCore/Frame.h>
36 #include <WebCore/FrameView.h>
37 #include <WebCore/GraphicsLayer.h>
38 #include <WebCore/Page.h>
39
40 using namespace WebCore;
41
42 namespace WebKit {
43
44 void LayerBackedDrawingArea::platformInit()
45 {
46     setUpUpdateLayoutRunLoopObserver();
47
48     [m_backingLayer->platformLayer() setGeometryFlipped:YES];
49 #if HAVE(HOSTED_CORE_ANIMATION)
50     attachCompositingContext();
51 #endif
52
53     scheduleCompositingLayerSync();
54 }
55
56 void LayerBackedDrawingArea::platformClear()
57 {
58     if (!m_attached)
59         return;
60
61     if (m_updateLayoutRunLoopObserver) {
62         CFRunLoopObserverInvalidate(m_updateLayoutRunLoopObserver.get());
63         m_updateLayoutRunLoopObserver = 0;
64     }
65
66 #if HAVE(HOSTED_CORE_ANIMATION)
67     WKCARemoteLayerClientInvalidate(m_remoteLayerRef.get());
68     m_remoteLayerRef = nullptr;
69 #endif
70
71     m_attached = false;
72 }
73
74 void LayerBackedDrawingArea::attachCompositingContext()
75 {
76     if (m_attached)
77         return;
78
79     m_attached = true;
80
81 #if HAVE(HOSTED_CORE_ANIMATION)
82     mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
83     m_remoteLayerRef = WKCARemoteLayerClientMakeWithServerPort(serverPort);
84     WKCARemoteLayerClientSetLayer(m_remoteLayerRef.get(), m_backingLayer->platformLayer());
85     
86     uint32_t contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerRef.get());
87     WebProcess::shared().connection()->sendSync(DrawingAreaProxyLegacyMessage::AttachCompositingContext, m_webPage->pageID(), CoreIPC::In(contextID), CoreIPC::Out());
88 #endif
89 }
90
91 void LayerBackedDrawingArea::detachCompositingContext()
92 {
93     m_backingLayer->removeAllChildren();
94
95     scheduleCompositingLayerSync();
96 }
97
98 void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer)
99 {
100     m_backingLayer->removeAllChildren();
101     if (layer)
102         m_backingLayer->addChild(layer);
103
104     scheduleCompositingLayerSync();
105 }
106
107 void LayerBackedDrawingArea::scheduleCompositingLayerSync()
108 {
109 //    if (m_syncTimer.isActive())
110 //        return;
111 //
112 //    m_syncTimer.startOneShot(0);
113
114     scheduleUpdateLayoutRunLoopObserver();
115 }
116
117 void LayerBackedDrawingArea::syncCompositingLayers()
118 {
119     m_backingLayer->syncCompositingStateForThisLayerOnly();
120
121     bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateRecursive();
122     if (!didSync) {
123     
124     }
125
126     m_webPage->corePage()->animationTime()->clearCurrentAnimationTime();
127 }
128
129 void LayerBackedDrawingArea::setUpUpdateLayoutRunLoopObserver()
130 {
131     if (m_updateLayoutRunLoopObserver)
132         return;
133
134     // Run before Core Animations commit observer, which has order 2000000.
135     const CFIndex runLoopOrder = 2000000 - 1;
136     CFRunLoopObserverContext context = { 0, this, 0, 0, 0 };
137     m_updateLayoutRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0,
138         kCFRunLoopBeforeWaiting | kCFRunLoopExit, true /* repeats */,
139         runLoopOrder, updateLayoutRunLoopObserverCallback, &context));
140 }
141
142 void LayerBackedDrawingArea::scheduleUpdateLayoutRunLoopObserver()
143 {
144     CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
145     CFRunLoopWakeUp(currentRunLoop);
146
147     if (CFRunLoopContainsObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes))
148         return;
149
150     CFRunLoopAddObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes);
151 }
152
153 void LayerBackedDrawingArea::removeUpdateLayoutRunLoopObserver()
154 {
155     // FIXME: cache the run loop ref?
156     CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes);
157 }
158
159 void LayerBackedDrawingArea::updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* info)
160 {
161     // Keep the drawing area alive while running the callback, since that does layout,
162     // which might replace this drawing area with one of another type.
163     RefPtr<LayerBackedDrawingArea> drawingArea = reinterpret_cast<LayerBackedDrawingArea*>(info);
164     drawingArea->updateLayoutRunLoopObserverFired();
165 }
166
167 void LayerBackedDrawingArea::updateLayoutRunLoopObserverFired()
168 {
169     // Laying out the page can cause the drawing area to change so we keep an extra reference.
170     RefPtr<LayerBackedDrawingArea> protect(this);
171
172     m_webPage->layoutIfNeeded();
173
174     if (m_webPage->drawingArea() != this)
175         return;
176     
177     if (m_attached)
178         syncCompositingLayers();
179 }
180
181 void LayerBackedDrawingArea::onPageClose()
182 {
183     platformClear();
184 }
185
186 } // namespace WebKit
187
188 #endif // USE(ACCELERATED_COMPOSITING)