AcceleratedCompositingContextGL.cpp [plain text]
#include "config.h"
#include "AcceleratedCompositingContext.h"
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL)
#include "CairoUtilities.h"
#include "Chrome.h"
#include "ChromeClientGtk.h"
#include "Frame.h"
#include "FrameView.h"
#include "PlatformContextCairo.h"
#include "TextureMapperGL.h"
#include "TextureMapperLayer.h"
#include "webkitwebviewprivate.h"
#include <GL/gl.h>
#include <cairo.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
using namespace WebCore;
namespace WebKit {
AcceleratedCompositingContext::AcceleratedCompositingContext(WebKitWebView* webView)
: m_webView(webView)
, m_syncTimerCallbackId(0)
, m_rootTextureMapperLayer(0)
{
}
AcceleratedCompositingContext::~AcceleratedCompositingContext()
{
if (m_syncTimerCallbackId)
g_source_remove(m_syncTimerCallbackId);
}
bool AcceleratedCompositingContext::enabled()
{
return m_rootTextureMapperLayer && m_textureMapper;
}
GLContext* AcceleratedCompositingContext::glContext()
{
GLContext* context = GLContext::getContextForWidget(GTK_WIDGET(m_webView));
if (!context->canRenderToDefaultFramebuffer())
return 0;
return context;
}
bool AcceleratedCompositingContext::renderLayersToWindow(const IntRect& clipRect)
{
if (!enabled())
return false;
GLContext* context = glContext();
if (!context)
return false;
if (!context->makeContextCurrent())
return false;
GtkAllocation allocation;
gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
glViewport(0, 0, allocation.width, allocation.height);
m_textureMapper->beginPainting();
m_rootTextureMapperLayer->paint();
m_textureMapper->endPainting();
context->swapBuffers();
return true;
}
void AcceleratedCompositingContext::attachRootGraphicsLayer(GraphicsLayer* graphicsLayer)
{
if (!graphicsLayer) {
m_rootGraphicsLayer.clear();
m_rootTextureMapperLayer = 0;
return;
}
m_rootGraphicsLayer = GraphicsLayer::create(this);
m_rootTextureMapperLayer = toTextureMapperLayer(m_rootGraphicsLayer.get());
m_rootGraphicsLayer->addChild(graphicsLayer);
m_rootGraphicsLayer->setDrawsContent(true);
m_rootGraphicsLayer->setMasksToBounds(false);
m_rootGraphicsLayer->setNeedsDisplay();
m_rootGraphicsLayer->setSize(core(m_webView)->mainFrame()->view()->frameRect().size());
GLContext* context = glContext();
if (!context)
return;
if (!context->makeContextCurrent())
return;
GtkAllocation allocation;
gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
glViewport(0, 0, allocation.width, allocation.height);
m_textureMapper = TextureMapperGL::create();
m_rootTextureMapperLayer->setTextureMapper(m_textureMapper.get());
m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
}
void AcceleratedCompositingContext::scheduleRootLayerRepaint(const IntRect& rect)
{
if (!m_rootGraphicsLayer)
return;
if (rect.isEmpty()) {
m_rootGraphicsLayer->setNeedsDisplay();
return;
}
m_rootGraphicsLayer->setNeedsDisplayInRect(rect);
}
void AcceleratedCompositingContext::resizeRootLayer(const IntSize& size)
{
if (!m_rootGraphicsLayer)
return;
m_rootGraphicsLayer->setSize(size);
m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
}
static gboolean syncLayersTimeoutCallback(AcceleratedCompositingContext* context)
{
context->syncLayersTimeout();
return FALSE;
}
void AcceleratedCompositingContext::markForSync()
{
if (m_syncTimerCallbackId)
return;
m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
}
void AcceleratedCompositingContext::syncLayersNow()
{
if (m_rootGraphicsLayer)
m_rootGraphicsLayer->syncCompositingStateForThisLayerOnly();
core(m_webView)->mainFrame()->view()->syncCompositingStateIncludingSubframes();
}
void AcceleratedCompositingContext::syncLayersTimeout()
{
m_syncTimerCallbackId = 0;
syncLayersNow();
if (!m_rootGraphicsLayer)
return;
renderLayersToWindow(IntRect());
if (toTextureMapperLayer(m_rootGraphicsLayer.get())->descendantsOrSelfHaveRunningAnimations())
m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 1000.0 / 60.0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
}
void AcceleratedCompositingContext::notifyAnimationStarted(const GraphicsLayer*, double time)
{
}
void AcceleratedCompositingContext::notifySyncRequired(const GraphicsLayer*)
{
}
void AcceleratedCompositingContext::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& rectToPaint)
{
cairo_t* cr = context.platformContext()->cr();
copyRectFromCairoSurfaceToContext(m_webView->priv->backingStore->cairoSurface(), cr,
IntSize(), rectToPaint);
}
bool AcceleratedCompositingContext::showDebugBorders(const GraphicsLayer*) const
{
return false;
}
bool AcceleratedCompositingContext::showRepaintCounter(const GraphicsLayer*) const
{
return false;
}
}
#endif // USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL)