Stop using PassRefPtr in platform/graphics
[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 "SoftLinking.h"
34 #include <QuartzCore/CACFLayer.h>
35 #include <wtf/CurrentTime.h>
36 #include <wtf/MainThread.h>
37
38 typedef struct _CACFLayer* CACFLayerRef;
39
40 namespace WebCore {
41
42 #ifdef DEBUG_ALL
43 SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
44 #else
45 SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
46 #endif
47
48 enum WKCACFViewDrawingDestination {
49     kWKCACFViewDrawingDestinationWindow = 0,
50     kWKCACFViewDrawingDestinationImage,
51 };
52 typedef enum WKCACFViewDrawingDestination WKCACFViewDrawingDestination;
53
54 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (WKCACFViewDrawingDestination destination), (destination))
55 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetLayer, void, __cdecl, (WKCACFViewRef view, CACFLayerRef layer), (view, layer))
56 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewUpdate, void, __cdecl, (WKCACFViewRef view, HWND window, const CGRect* bounds), (view, window, bounds))
57 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCanDraw, bool, __cdecl, (WKCACFViewRef view), (view))
58 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDraw, void, __cdecl, (WKCACFViewRef view), (view))
59 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDrawIntoDC, void, __cdecl, (WKCACFViewRef view, HDC dc), (view, dc))
60 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewFlushContext, void, __cdecl, (WKCACFViewRef view), (view))
61 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewInvalidateRects, void, __cdecl, (WKCACFViewRef view, const CGRect rects[], size_t count), (view, rects, count))
62 typedef void (*WKCACFViewContextDidChangeCallback)(WKCACFViewRef view, void* info);
63 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextDidChangeCallback, void, __cdecl, (WKCACFViewRef view, WKCACFViewContextDidChangeCallback callback, void* info), (view, callback, info))
64 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewGetLastCommitTime, CFTimeInterval, __cdecl, (WKCACFViewRef view), (view))
65 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextUserData, void, __cdecl, (WKCACFViewRef view, void* userData), (view, userData))
66 SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewSetShouldInvertColors, void, _cdecl, (WKCACFViewRef view, bool shouldInvertColors))
67 SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewGetD3DDevice9, IDirect3DDevice9*, _cdecl, (WKCACFViewRef view))
68
69 RefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
70 {
71     if (!WebKitQuartzCoreAdditionsLibrary())
72         return nullptr;
73
74     return adoptRef(new WKCACFViewLayerTreeHost);
75 }
76
77 WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
78     : m_view(adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow)))
79     , m_viewNeedsUpdate(true)
80 {
81 }
82
83 void WKCACFViewLayerTreeHost::updateViewIfNeeded()
84 {
85     if (!m_viewNeedsUpdate)
86         return;
87     m_viewNeedsUpdate = false;
88
89     CGRect layerBounds = rootLayer()->bounds();
90
91     CGRect bounds = this->bounds();
92     WKCACFViewUpdate(m_view.get(), window(), &bounds);
93
94     if (CGRectEqualToRect(layerBounds, rootLayer()->bounds()))
95         return;
96
97     // Flush the context so the layer's rendered bounds will match our bounds.
98     flushContext();
99 }
100
101 void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void* info)
102 {
103     ASSERT_ARG(view, view);
104     ASSERT_ARG(info, info);
105
106     WKCACFViewLayerTreeHost* host = static_cast<WKCACFViewLayerTreeHost*>(info);
107     ASSERT_ARG(view, view == host->m_view);
108     host->contextDidChange();
109 }
110
111 void WKCACFViewLayerTreeHost::contextDidChange()
112 {
113     // This should only be called on a background thread when no changes have actually 
114     // been committed to the context, eg. when a video frame has been added to an image
115     // queue, so return without triggering animations etc.
116     if (!isMainThread())
117         return;
118
119     // Tell the WKCACFView to start rendering now that we have some contents to render.
120     updateViewIfNeeded();
121
122     CACFLayerTreeHost::contextDidChange();
123 }
124
125 void WKCACFViewLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
126 {
127     WKCACFViewSetContextUserData(m_view.get(), userData);
128     WKCACFViewSetLayer(m_view.get(), layer->platformLayer());
129     WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
130 }
131
132 void WKCACFViewLayerTreeHost::resize()
133 {
134     m_viewNeedsUpdate = true;
135 }
136
137 void WKCACFViewLayerTreeHost::setScaleFactor(float scaleFactor)
138 {
139 #if HAVE(CACFLAYER_SETCONTENTSSCALE)
140     CACFLayerSetTransform(rootLayer()->platformLayer(), CATransform3DMakeScale(scaleFactor, scaleFactor, 1));
141     CACFLayerSetContentsScale(rootLayer()->platformLayer(), scaleFactor);
142 #endif
143 }
144
145 bool WKCACFViewLayerTreeHost::createRenderer()
146 {
147     updateViewIfNeeded();
148     return WKCACFViewCanDraw(m_view.get());
149 }
150
151 void WKCACFViewLayerTreeHost::destroyRenderer()
152 {
153     m_viewNeedsUpdate = true;
154     WKCACFViewUpdate(m_view.get(), 0, 0);
155     WKCACFViewSetContextUserData(m_view.get(), 0);
156     WKCACFViewSetLayer(m_view.get(), 0);
157     WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
158
159     CACFLayerTreeHost::destroyRenderer();
160 }
161
162 CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
163 {
164     return WKCACFViewGetLastCommitTime(m_view.get());
165 }
166
167 void WKCACFViewLayerTreeHost::flushContext()
168 {
169     WKCACFViewFlushContext(m_view.get());
170 }
171
172 void WKCACFViewLayerTreeHost::paint(HDC dc)
173 {
174     updateViewIfNeeded();
175     CACFLayerTreeHost::paint(dc);
176 }
177
178 void WKCACFViewLayerTreeHost::render(const Vector<CGRect>& dirtyRects, HDC dc)
179 {
180     WKCACFViewInvalidateRects(m_view.get(), dirtyRects.data(), dirtyRects.size());
181     if (dc)
182         WKCACFViewDrawIntoDC(m_view.get(), dc);
183     else
184         WKCACFViewDraw(m_view.get());
185 }
186
187 void WKCACFViewLayerTreeHost::setShouldInvertColors(bool shouldInvertColors)
188 {
189     if (WKCACFViewSetShouldInvertColorsPtr())
190         WKCACFViewSetShouldInvertColorsPtr()(m_view.get(), shouldInvertColors);
191 }
192
193 #if USE(AVFOUNDATION)
194 GraphicsDeviceAdapter* WKCACFViewLayerTreeHost::graphicsDeviceAdapter() const
195 {
196     if (!WKCACFViewGetD3DDevice9Ptr())
197         return 0;
198
199     return reinterpret_cast<GraphicsDeviceAdapter*>(WKCACFViewGetD3DDevice9Ptr()(m_view.get()));
200 }
201 #endif
202
203 } // namespace WebCore
204
205 #endif