• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. ``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 COMPUTER, 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(ACCELERATED_COMPOSITING)
30 
31 #include "PlatformCALayer.h"
32 #include "SoftLinking.h"
33 #include <wtf/CurrentTime.h>
34 #include <wtf/Threading.h>
35 
36 typedef struct _CACFLayer* CACFLayerRef;
37 
38 namespace WebCore {
39 
40 #ifdef DEBUG_ALL
41 SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
42 #else
43 SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
44 #endif
45 
46 enum WKCACFViewDrawingDestination {
47     kWKCACFViewDrawingDestinationWindow = 0,
48     kWKCACFViewDrawingDestinationImage,
49 };
50 typedef enum WKCACFViewDrawingDestination WKCACFViewDrawingDestination;
51 
52 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (WKCACFViewDrawingDestination destination), (destination))
53 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetLayer, void, __cdecl, (WKCACFViewRef view, CACFLayerRef layer), (view, layer))
54 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewUpdate, void, __cdecl, (WKCACFViewRef view, HWND window, const CGRect* bounds), (view, window, bounds))
55 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCanDraw, bool, __cdecl, (WKCACFViewRef view), (view))
56 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDraw, void, __cdecl, (WKCACFViewRef view), (view))
57 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewFlushContext, void, __cdecl, (WKCACFViewRef view), (view))
58 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewInvalidateRects, void, __cdecl, (WKCACFViewRef view, const CGRect rects[], size_t count), (view, rects, count))
59 typedef void (*WKCACFViewContextDidChangeCallback)(WKCACFViewRef view, void* info);
60 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextDidChangeCallback, void, __cdecl, (WKCACFViewRef view, WKCACFViewContextDidChangeCallback callback, void* info), (view, callback, info))
61 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewGetLastCommitTime, CFTimeInterval, __cdecl, (WKCACFViewRef view), (view))
62 SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextUserData, void, __cdecl, (WKCACFViewRef view, void* userData), (view, userData))
63 
create()64 PassRefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
65 {
66     if (!WebKitQuartzCoreAdditionsLibrary())
67         return 0;
68 
69     return adoptRef(new WKCACFViewLayerTreeHost);
70 }
71 
WKCACFViewLayerTreeHost()72 WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
73     : m_view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow))
74     , m_viewNeedsUpdate(true)
75 {
76 }
77 
updateViewIfNeeded()78 void WKCACFViewLayerTreeHost::updateViewIfNeeded()
79 {
80     if (!m_viewNeedsUpdate)
81         return;
82     m_viewNeedsUpdate = false;
83 
84     CGRect layerBounds = rootLayer()->bounds();
85 
86     CGRect bounds = this->bounds();
87     WKCACFViewUpdate(m_view.get(), window(), &bounds);
88 
89     if (CGRectEqualToRect(layerBounds, rootLayer()->bounds()))
90         return;
91 
92     // Flush the context so the layer's rendered bounds will match our bounds.
93     flushContext();
94 }
95 
contextDidChangeCallback(WKCACFViewRef view,void * info)96 void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void* info)
97 {
98     ASSERT_ARG(view, view);
99     ASSERT_ARG(info, info);
100 
101     WKCACFViewLayerTreeHost* host = static_cast<WKCACFViewLayerTreeHost*>(info);
102     ASSERT_ARG(view, view == host->m_view);
103     host->contextDidChange();
104 }
105 
contextDidChange()106 void WKCACFViewLayerTreeHost::contextDidChange()
107 {
108     // This should only be called on a background thread when no changes have actually
109     // been committed to the context, eg. when a video frame has been added to an image
110     // queue, so return without triggering animations etc.
111     if (!isMainThread())
112         return;
113 
114     // Tell the WKCACFView to start rendering now that we have some contents to render.
115     updateViewIfNeeded();
116 
117     CACFLayerTreeHost::contextDidChange();
118 }
119 
initializeContext(void * userData,PlatformCALayer * layer)120 void WKCACFViewLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
121 {
122     WKCACFViewSetContextUserData(m_view.get(), userData);
123     WKCACFViewSetLayer(m_view.get(), layer->platformLayer());
124     WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
125 }
126 
resize()127 void WKCACFViewLayerTreeHost::resize()
128 {
129     m_viewNeedsUpdate = true;
130 }
131 
createRenderer()132 bool WKCACFViewLayerTreeHost::createRenderer()
133 {
134     updateViewIfNeeded();
135     return WKCACFViewCanDraw(m_view.get());
136 }
137 
destroyRenderer()138 void WKCACFViewLayerTreeHost::destroyRenderer()
139 {
140     m_viewNeedsUpdate = true;
141     WKCACFViewUpdate(m_view.get(), 0, 0);
142     WKCACFViewSetContextUserData(m_view.get(), 0);
143     WKCACFViewSetLayer(m_view.get(), 0);
144     WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
145 
146     CACFLayerTreeHost::destroyRenderer();
147 }
148 
lastCommitTime() const149 CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
150 {
151     return WKCACFViewGetLastCommitTime(m_view.get());
152 }
153 
flushContext()154 void WKCACFViewLayerTreeHost::flushContext()
155 {
156     WKCACFViewFlushContext(m_view.get());
157 }
158 
paint()159 void WKCACFViewLayerTreeHost::paint()
160 {
161     updateViewIfNeeded();
162     CACFLayerTreeHost::paint();
163 }
164 
render(const Vector<CGRect> & dirtyRects)165 void WKCACFViewLayerTreeHost::render(const Vector<CGRect>& dirtyRects)
166 {
167     WKCACFViewInvalidateRects(m_view.get(), dirtyRects.data(), dirtyRects.size());
168     WKCACFViewDraw(m_view.get());
169 }
170 
171 } // namespace WebCore
172 
173 #endif // USE(ACCELERATED_COMPOSITING)
174