LayerTreeHostCAWin.cpp [plain text]
#include "config.h"
#include "LayerTreeHostCAWin.h"
#if HAVE(WKQCA)
#include "DrawingAreaImpl.h"
#include "ShareableBitmap.h"
#include "UpdateInfo.h"
#include "WKCACFViewWindow.h"
#include "WebPage.h"
#include <WebCore/GraphicsLayerCA.h>
#include <WebCore/LayerChangesFlusher.h>
#include <WebCore/PlatformCALayer.h>
#include <WebCore/SoftLinking.h>
#include <WebCore/WebCoreInstanceHandle.h>
#include <WebKitQuartzCoreAdditions/WKCACFImage.h>
#include <WebKitQuartzCoreAdditions/WKCACFView.h>
#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
#ifdef DEBUG_ALL
#define MODULE_NAME "WebKitQuartzCoreAdditions_debug"
#else
#define MODULE_NAME "WebKitQuartzCoreAdditions"
#endif
#pragma comment(lib, MODULE_NAME)
#if USE(AVFOUNDATION)
SOFT_LINK_LOADED_LIBRARY(MODULE_NAME, WKCACFViewGetD3DDevice9, IDirect3DDevice9*, _cdecl, (WKCACFViewRef view))
#endif
using namespace WebCore;
namespace WebKit {
bool LayerTreeHostCAWin::supportsAcceleratedCompositing()
{
static bool initialized;
static bool supportsAcceleratedCompositing;
if (initialized)
return supportsAcceleratedCompositing;
initialized = true;
RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
WKCACFViewWindow dummyWindow(view.get(), 0, 0);
CGRect fakeBounds = CGRectMake(0, 0, 10, 10);
WKCACFViewUpdate(view.get(), dummyWindow.window(), &fakeBounds);
supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get());
WKCACFViewUpdate(view.get(), 0, 0);
return supportsAcceleratedCompositing;
}
PassRefPtr<LayerTreeHostCAWin> LayerTreeHostCAWin::create(WebPage* webPage)
{
RefPtr<LayerTreeHostCAWin> host = adoptRef(new LayerTreeHostCAWin(webPage));
host->initialize();
return host.release();
}
LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage)
: LayerTreeHostCA(webPage)
, m_isFlushingLayerChanges(false)
{
}
LayerTreeHostCAWin::~LayerTreeHostCAWin()
{
}
void LayerTreeHostCAWin::platformInitialize()
{
m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this));
WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer());
WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
m_window = adoptPtr(new WKCACFViewWindow(m_view.get(), m_webPage->nativeWindow(), WS_DISABLED));
CGRect bounds = m_webPage->bounds();
WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
m_layerTreeContext.window = m_window->window();
}
void LayerTreeHostCAWin::invalidate()
{
LayerChangesFlusher::shared().cancelPendingFlush(this);
WKCACFViewSetContextUserData(m_view.get(), 0);
WKCACFViewSetLayer(m_view.get(), 0);
WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
WKCACFViewWindow* window = m_window.leakPtr();
window->setDeletesSelfWhenWindowDestroyed(true);
LayerTreeHostCA::invalidate();
}
void LayerTreeHostCAWin::scheduleLayerFlush()
{
if (!m_layerFlushSchedulingEnabled)
return;
LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
}
void LayerTreeHostCAWin::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
{
if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
return;
m_layerFlushSchedulingEnabled = layerFlushingEnabled;
if (m_layerFlushSchedulingEnabled) {
scheduleLayerFlush();
return;
}
LayerChangesFlusher::shared().cancelPendingFlush(this);
}
void LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
{
m_geometriesUpdater.addPendingUpdate(geometry);
}
void LayerTreeHostCAWin::sizeDidChange(const IntSize& newSize)
{
LayerTreeHostCA::sizeDidChange(newSize);
CGRect bounds = CGRectMake(0, 0, newSize.width(), newSize.height());
WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
WKCACFViewFlushContext(m_view.get());
}
void LayerTreeHostCAWin::forceRepaint()
{
LayerTreeHostCA::forceRepaint();
WKCACFViewFlushContext(m_view.get());
}
void LayerTreeHostCAWin::contextDidChangeCallback(WKCACFViewRef view, void* info)
{
if (!isMainThread())
return;
LayerTreeHostCAWin* host = static_cast<LayerTreeHostCAWin*>(info);
ASSERT_ARG(view, view == host->m_view);
host->contextDidChange();
}
void LayerTreeHostCAWin::contextDidChange()
{
double currentTime = WTF::currentTime();
HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it)
(*it)->animationStarted(currentTime);
m_pendingAnimatedLayers.clear();
m_geometriesUpdater.updateGeometries(BringToTop);
}
PlatformCALayer* LayerTreeHostCAWin::rootLayer() const
{
return static_cast<GraphicsLayerCA*>(LayerTreeHostCA::rootLayer())->platformCALayer();
}
void LayerTreeHostCAWin::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer)
{
m_pendingAnimatedLayers.add(layer);
}
void LayerTreeHostCAWin::layerTreeDidChange()
{
if (m_isFlushingLayerChanges) {
return;
}
LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
}
void LayerTreeHostCAWin::flushPendingLayerChangesNow()
{
RefPtr<LayerTreeHostCA> protector(this);
m_isFlushingLayerChanges = true;
performScheduledLayerFlush();
WKCACFViewFlushContext(m_view.get());
m_isFlushingLayerChanges = false;
}
void LayerTreeHostCAWin::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
{
setLayerFlushSchedulingEnabled(graphicsLayer);
if (graphicsLayer)
static_cast<GraphicsLayerCA*>(graphicsLayer)->platformCALayer()->ensureAnimationsSubmitted();
LayerTreeHostCA::setRootCompositingLayer(graphicsLayer);
}
#if USE(AVFOUNDATION)
WebCore::GraphicsDeviceAdapter* LayerTreeHostCAWin::graphicsDeviceAdapter() const
{
if (!WKCACFViewGetD3DDevice9Ptr())
return 0;
return reinterpret_cast<GraphicsDeviceAdapter*>(WKCACFViewGetD3DDevice9Ptr()(m_view.get()));
}
#endif
}
#endif // HAVE(WKQCA)