DrawingBufferChromium.cpp [plain text]
#include "config.h"
#include "DrawingBuffer.h"
#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "SharedGraphicsContext3D.h"
#if USE(SKIA)
#include "GrContext.h"
#endif
#if USE(ACCELERATED_COMPOSITING)
#include "Canvas2DLayerChromium.h"
#endif
namespace WebCore {
struct DrawingBufferInternal {
unsigned offscreenColorTexture;
#if USE(ACCELERATED_COMPOSITING)
RefPtr<Canvas2DLayerChromium> platformLayer;
#endif
};
static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize& size)
{
unsigned offscreenColorTexture = context->createTexture();
if (!offscreenColorTexture)
return 0;
context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture);
context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE);
context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, offscreenColorTexture, 0);
return offscreenColorTexture;
}
DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
const IntSize& size,
bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported)
: m_context(context)
, m_size(-1, -1)
, m_multisampleExtensionSupported(multisampleExtensionSupported)
, m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported)
, m_fbo(0)
, m_colorBuffer(0)
, m_depthStencilBuffer(0)
, m_depthBuffer(0)
, m_stencilBuffer(0)
, m_multisampleFBO(0)
, m_multisampleColorBuffer(0)
, m_internal(adoptPtr(new DrawingBufferInternal))
#if USE(SKIA)
, m_grContext(0)
#endif
{
if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) {
m_context.clear();
return;
}
m_fbo = context->createFramebuffer();
context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
m_colorBuffer = generateColorTexture(context, size);
createSecondaryBuffers();
reset(size);
}
DrawingBuffer::~DrawingBuffer()
{
#if USE(ACCELERATED_COMPOSITING)
if (m_internal->platformLayer)
m_internal->platformLayer->setDrawingBuffer(0);
#endif
if (!m_context)
return;
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
m_context->deleteTexture(m_colorBuffer);
clear();
}
#if USE(ACCELERATED_COMPOSITING)
void DrawingBuffer::publishToPlatformLayer()
{
if (!m_context)
return;
if (m_callback)
m_callback->willPublish();
if (multisample())
commit();
unsigned parentTexture = m_internal->platformLayer->textureId();
m_context->makeContextCurrent();
#if USE(SKIA)
if (m_grContext)
m_grContext->flush(0);
#endif
static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_colorBuffer, parentTexture);
m_context->flush();
}
#endif
void DrawingBuffer::didReset()
{
#if USE(ACCELERATED_COMPOSITING)
if (m_internal->platformLayer)
m_internal->platformLayer->setTextureChanged();
#endif
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* DrawingBuffer::platformLayer()
{
if (!m_internal->platformLayer)
m_internal->platformLayer = Canvas2DLayerChromium::create(this, 0);
return m_internal->platformLayer.get();
}
#endif
Platform3DObject DrawingBuffer::platformColorBuffer() const
{
return m_colorBuffer;
}
#if USE(SKIA)
void DrawingBuffer::setGrContext(GrContext* context)
{
m_grContext = context;
}
void DrawingBuffer::getGrPlatformSurfaceDesc(GrPlatformSurfaceDesc* desc)
{
desc->fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType;
desc->fPlatformTexture = m_colorBuffer;
if (multisample()) {
desc->fRenderTargetFlags = kIsMultisampled_GrPlatformRenderTargetFlagBit | kGrCanResolve_GrPlatformRenderTargetFlagBit;
desc->fPlatformRenderTarget = m_multisampleFBO;
desc->fPlatformResolveDestination = m_fbo;
} else {
desc->fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
desc->fPlatformRenderTarget = m_fbo;
desc->fPlatformResolveDestination = 0;
}
desc->fWidth = m_size.width();
desc->fHeight = m_size.height();
desc->fConfig = kRGBA_8888_GrPixelConfig;
desc->fStencilBits = (m_depthStencilBuffer || m_stencilBuffer) ? 8 : 0;
}
#endif
}