[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / win / WKCACFViewLayerTreeHost.cpp
1 /*
2  * Copyright (C) 2011, 2012 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WKCACFViewLayerTreeHost.h"
28
29 #if USE(CA)
30
31 #include "GDIUtilities.h"
32 #include "PlatformCALayer.h"
33 #include <QuartzCore/CACFLayer.h>
34 #include <wtf/MainThread.h>
35 #include <wtf/SoftLinking.h>
36
37 typedef struct _CACFLayer* CACFLayerRef;
38
39 namespace WebCore {
40
41 #ifdef DEBUG_ALL
42 SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
43 #else
44 SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
45 #endif
46
47 enum WKCACFViewDrawingDestination {
48     kWKCACFViewDrawingDestinationWindow = 0,
49     kWKCACFViewDrawingDestinationImage,
50 };
51 typedef enum WKCACFViewDrawingDestination WKCACFViewDrawingDestination;
52
53 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (WKCACFViewDrawingDestination destination), (destination))
54 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetLayer, void, __cdecl, (WKCACFViewRef view, CACFLayerRef layer), (view, layer))
55 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewUpdate, void, __cdecl, (WKCACFViewRef view, HWND window, const CGRect* bounds), (view, window, bounds))
56 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCanDraw, bool, __cdecl, (WKCACFViewRef view), (view))
57 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDraw, void, __cdecl, (WKCACFViewRef view), (view))
58 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDrawIntoDC, void, __cdecl, (WKCACFViewRef view, HDC dc), (view, dc))
59 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewFlushContext, void, __cdecl, (WKCACFViewRef view), (view))
60 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewInvalidateRects, void, __cdecl, (WKCACFViewRef view, const CGRect rects[], size_t count), (view, rects, count))
61 typedef void (*WKCACFViewContextDidChangeCallback)(WKCACFViewRef view, void* info);
62 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextDidChangeCallback, void, __cdecl, (WKCACFViewRef view, WKCACFViewContextDidChangeCallback callback, void* info), (view, callback, info))
63 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewGetLastCommitTime, CFTimeInterval, __cdecl, (WKCACFViewRef view), (view))
64 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextUserData, void, __cdecl, (WKCACFViewRef view, void* userData), (view, userData))
65 SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewSetShouldInvertColors, void, _cdecl, (WKCACFViewRef view, bool shouldInvertColors))
66 SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewGetD3DDevice9, IDirect3DDevice9*, _cdecl, (WKCACFViewRef view))
67
68 RefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
69 {
70     if (!WebKitQuartzCoreAdditionsLibrary())
71         return nullptr;
72
73     return adoptRef(new WKCACFViewLayerTreeHost);
74 }
75
76 WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
77     : m_view(adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow)))
78     , m_viewNeedsUpdate(true)
79 {
80 }
81
82 void WKCACFViewLayerTreeHost::updateViewIfNeeded()
83 {
84     if (!m_viewNeedsUpdate)
85         return;
86     m_viewNeedsUpdate = false;
87
88     CGRect layerBounds = rootLayer()->bounds();
89
90     CGRect bounds = this->bounds();
91     WKCACFViewUpdate(m_view.get(), window(), &bounds);
92
93     if (CGRectEqualToRect(layerBounds, rootLayer()->bounds()))
94         return;
95
96     // Flush the context so the layer's rendered bounds will match our bounds.
97     flushContext();
98 }
99
100 void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void* info)
101 {
102     ASSERT_ARG(view, view);
103     ASSERT_ARG(info, info);
104
105     WKCACFViewLayerTreeHost* host = static_cast<WKCACFViewLayerTreeHost*>(info);
106     ASSERT_ARG(view, view == host->m_view);
107     host->contextDidChange();
108 }
109
110 void WKCACFViewLayerTreeHost::contextDidChange()
111 {
112     // This should only be called on a background thread when no changes have actually 
113     // been committed to the context, eg. when a video frame has been added to an image
114     // queue, so return without triggering animations etc.
115     if (!isMainThread())
116         return;
117
118     // Tell the WKCACFView to start rendering now that we have some contents to render.
119     updateViewIfNeeded();
120
121     CACFLayerTreeHost::contextDidChange();
122 }
123
124 void WKCACFViewLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
125 {
126     WKCACFViewSetContextUserData(m_view.get(), userData);
127     WKCACFViewSetLayer(m_view.get(), layer->platformLayer());
128     WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
129 }
130
131 void WKCACFViewLayerTreeHost::resize()
132 {
133     m_viewNeedsUpdate = true;
134 }
135
136 void WKCACFViewLayerTreeHost::setScaleFactor(float scaleFactor)
137 {
138 #if HAVE(CACFLAYER_SETCONTENTSSCALE)
139     CACFLayerSetTransform(rootLayer()->platformLayer(), CATransform3DMakeScale(scaleFactor, scaleFactor, 1));
140     CACFLayerSetContentsScale(rootLayer()->platformLayer(), scaleFactor);
141 #endif
142 }
143
144 bool WKCACFViewLayerTreeHost::createRenderer()
145 {
146     updateViewIfNeeded();
147     return WKCACFViewCanDraw(m_view.get());
148 }
149
150 void WKCACFViewLayerTreeHost::destroyRenderer()
151 {
152     m_viewNeedsUpdate = true;
153     WKCACFViewUpdate(m_view.get(), 0, 0);
154     WKCACFViewSetContextUserData(m_view.get(), 0);
155     WKCACFViewSetLayer(m_view.get(), 0);
156     WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
157
158     CACFLayerTreeHost::destroyRenderer();
159 }
160
161 CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
162 {
163     return WKCACFViewGetLastCommitTime(m_view.get());
164 }
165
166 void WKCACFViewLayerTreeHost::flushContext()
167 {
168     WKCACFViewFlushContext(m_view.get());
169 }
170
171 void WKCACFViewLayerTreeHost::paint(HDC dc)
172 {
173     updateViewIfNeeded();
174     CACFLayerTreeHost::paint(dc);
175 }
176
177 void WKCACFViewLayerTreeHost::render(const Vector<CGRect>& dirtyRects, HDC dc)
178 {
179     WKCACFViewInvalidateRects(m_view.get(), dirtyRects.data(), dirtyRects.size());
180     if (dc)
181         WKCACFViewDrawIntoDC(m_view.get(), dc);
182     else
183         WKCACFViewDraw(m_view.get());
184 }
185
186 void WKCACFViewLayerTreeHost::setShouldInvertColors(bool shouldInvertColors)
187 {
188     if (WKCACFViewSetShouldInvertColorsPtr())
189         WKCACFViewSetShouldInvertColorsPtr()(m_view.get(), shouldInvertColors);
190 }
191
192 #if USE(AVFOUNDATION)
193 GraphicsDeviceAdapter* WKCACFViewLayerTreeHost::graphicsDeviceAdapter() const
194 {
195     if (!WKCACFViewGetD3DDevice9Ptr())
196         return 0;
197
198     return reinterpret_cast<GraphicsDeviceAdapter*>(WKCACFViewGetD3DDevice9Ptr()(m_view.get()));
199 }
200 #endif
201
202 } // namespace WebCore
203
204 #endif