RenderSurfaceChromium.cpp [plain text]
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
#include "RenderSurfaceChromium.h"
#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerChromium.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
#include "TextStream.h"
#include <wtf/text/CString.h>
namespace WebCore {
RenderSurfaceChromium::RenderSurfaceChromium(CCLayerImpl* owningLayer)
: m_owningLayer(owningLayer)
, m_maskLayer(0)
, m_skipsDraw(false)
{
}
RenderSurfaceChromium::~RenderSurfaceChromium()
{
cleanupResources();
}
void RenderSurfaceChromium::cleanupResources()
{
if (!m_contentsTexture)
return;
ASSERT(layerRenderer());
m_contentsTexture.clear();
}
LayerRendererChromium* RenderSurfaceChromium::layerRenderer()
{
ASSERT(m_owningLayer);
return m_owningLayer->layerRenderer();
}
FloatRect RenderSurfaceChromium::drawableContentRect() const
{
FloatRect localContentRect(-0.5 * m_contentRect.width(), -0.5 * m_contentRect.height(),
m_contentRect.width(), m_contentRect.height());
FloatRect drawableContentRect = m_drawTransform.mapRect(localContentRect);
if (m_owningLayer->replicaLayer())
drawableContentRect.unite(m_replicaDrawTransform.mapRect(localContentRect));
return drawableContentRect;
}
bool RenderSurfaceChromium::prepareContentsTexture()
{
IntSize requiredSize(m_contentRect.size());
TextureManager* textureManager = layerRenderer()->textureManager();
if (!m_contentsTexture)
m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager);
if (m_contentsTexture->isReserved())
return true;
if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) {
m_skipsDraw = true;
return false;
}
m_skipsDraw = false;
return true;
}
void RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform)
{
GraphicsContext3D* context3D = layerRenderer()->context();
int shaderMatrixLocation = -1;
int shaderAlphaLocation = -1;
const RenderSurfaceChromium::Program* program = layerRenderer()->renderSurfaceProgram();
const RenderSurfaceChromium::MaskProgram* maskProgram = layerRenderer()->renderSurfaceMaskProgram();
ASSERT(program && program->initialized());
bool useMask = false;
if (maskLayer && maskLayer->drawsContent()) {
if (!maskLayer->bounds().isEmpty()) {
context3D->makeContextCurrent();
layerRenderer()->useShader(maskProgram->program());
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().samplerLocation(), 0));
m_contentsTexture->bindTexture();
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1));
GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().maskSamplerLocation(), 1));
maskLayer->bindContentsTexture();
GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0));
shaderMatrixLocation = maskProgram->vertexShader().matrixLocation();
shaderAlphaLocation = maskProgram->fragmentShader().alphaLocation();
useMask = true;
}
}
if (!useMask) {
layerRenderer()->useShader(program->program());
m_contentsTexture->bindTexture();
GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0));
shaderMatrixLocation = program->vertexShader().matrixLocation();
shaderAlphaLocation = program->fragmentShader().alphaLocation();
}
LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform,
m_contentRect.width(), m_contentRect.height(), m_drawOpacity,
shaderMatrixLocation, shaderAlphaLocation);
}
void RenderSurfaceChromium::draw(const IntRect&)
{
if (m_skipsDraw || !m_contentsTexture)
return;
CCLayerImpl* replicaMaskLayer = m_maskLayer;
if (!m_maskLayer && m_owningLayer->replicaLayer())
replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer();
layerRenderer()->setScissorToRect(m_scissorRect);
if (m_owningLayer->replicaLayer())
drawSurface(replicaMaskLayer, m_replicaDrawTransform);
drawSurface(m_maskLayer, m_drawTransform);
}
String RenderSurfaceChromium::name() const
{
return String::format("RenderSurface(id=%d,owner=%s)", m_owningLayer->id(), m_owningLayer->name().utf8().data());
}
static void writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
ts << " ";
}
void RenderSurfaceChromium::dumpSurface(TextStream& ts, int indent) const
{
writeIndent(ts, indent);
ts << name() << "\n";
writeIndent(ts, indent+1);
ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n";
}
}
#endif // USE(ACCELERATED_COMPOSITING)