Home | History | Annotate | Download | only in win
      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 
     64 PassRefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
     65 {
     66     if (!WebKitQuartzCoreAdditionsLibrary())
     67         return 0;
     68 
     69     return adoptRef(new WKCACFViewLayerTreeHost);
     70 }
     71 
     72 WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
     73     : m_view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow))
     74     , m_viewNeedsUpdate(true)
     75 {
     76 }
     77 
     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 
     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 
    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 
    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 
    127 void WKCACFViewLayerTreeHost::resize()
    128 {
    129     m_viewNeedsUpdate = true;
    130 }
    131 
    132 bool WKCACFViewLayerTreeHost::createRenderer()
    133 {
    134     updateViewIfNeeded();
    135     return WKCACFViewCanDraw(m_view.get());
    136 }
    137 
    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 
    149 CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
    150 {
    151     return WKCACFViewGetLastCommitTime(m_view.get());
    152 }
    153 
    154 void WKCACFViewLayerTreeHost::flushContext()
    155 {
    156     WKCACFViewFlushContext(m_view.get());
    157 }
    158 
    159 void WKCACFViewLayerTreeHost::paint()
    160 {
    161     updateViewIfNeeded();
    162     CACFLayerTreeHost::paint();
    163 }
    164 
    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