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