GraphicsSurfaceCommon.cpp [plain text]
#include "config.h"
#include "GraphicsSurface.h"
#include "GLPlatformContext.h"
#include "GLTransportSurface.h"
#include "NotImplemented.h"
#include "TextureMapperGL.h"
namespace WebCore {
struct GraphicsSurfacePrivate {
GraphicsSurfacePrivate()
{
}
GraphicsSurfacePrivate(PlatformBufferHandle winId, const IntSize& size, GraphicsSurface::Flags flags)
: m_flags(0)
, m_rect(FloatPoint::zero(), size)
, m_size(size)
, m_sharedHandle(winId)
{
if (flags & GraphicsSurface::SupportsAlpha)
m_flags |= TextureMapperGL::ShouldBlend;
}
~GraphicsSurfacePrivate()
{
}
void destroy()
{
if (m_client)
m_client->destroy();
if (m_sharedContext && m_sharedContext->handle() && m_sharedSurface)
makeContextCurrent();
if (m_sharedSurface)
m_sharedSurface->destroy();
if (m_sharedContext) {
m_sharedContext->destroy();
m_sharedContext->releaseCurrent();
}
}
bool initializeTransportSurface(const IntSize& size, GraphicsSurface::Flags flags, const PlatformGraphicsContext3D shareContext)
{
GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatformSurface::Default;
m_size = size;
if (flags & GraphicsSurface::SupportsAlpha)
sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha;
m_sharedSurface = GLTransportSurface::createTransportSurface(size, sharedSurfaceAttributes);
if (!m_sharedSurface)
return false;
m_sharedContext = GLPlatformContext::createContext(GraphicsContext3D::RenderOffscreen);
if (!m_sharedContext)
return false;
if (!m_sharedContext->initialize(m_sharedSurface.get(), static_cast<PlatformContext>(shareContext)))
return false;
if (!makeContextCurrent())
return false;
return true;
}
bool makeContextCurrent() const
{
return m_sharedContext->makeCurrent(m_sharedSurface.get());
}
void copyFromTexture(GLuint textureId)
{
if (!makeContextCurrent())
return;
m_sharedSurface->updateContents(textureId);
}
PlatformBufferHandle handle() const
{
return m_sharedSurface->handle();
}
void updateClientBuffer()
{
if (!m_client)
return;
m_client->prepareTexture();
}
TextureMapperGL::Flags flags() const { return m_flags; }
const FloatRect& rect() const { return m_rect; }
const IntSize& size() const { return m_size; }
GLuint textureId() const
{
if (!m_client)
const_cast<GraphicsSurfacePrivate*>(this)->initializeClient();
return m_client ? m_client->texture() : 0;
}
private:
void initializeClient()
{
m_client = GLTransportSurfaceClient::createTransportSurfaceClient(m_sharedHandle, m_size, m_flags & TextureMapperGL::ShouldBlend);
if (!m_client)
return;
}
TextureMapperGL::Flags m_flags;
FloatRect m_rect;
IntSize m_size;
PlatformBufferHandle m_sharedHandle;
std::unique_ptr<GLTransportSurfaceClient> m_client;
std::unique_ptr<GLPlatformContext> m_sharedContext;
std::unique_ptr<GLTransportSurface> m_sharedSurface;
};
GraphicsSurfaceToken GraphicsSurface::platformExport()
{
return m_private->handle();
}
uint32_t GraphicsSurface::platformGetTextureID()
{
return m_private->textureId();
}
void GraphicsSurface::platformCopyToGLTexture(uint32_t , uint32_t , const IntRect& , const IntPoint& )
{
notImplemented();
}
void GraphicsSurface::platformCopyFromTexture(uint32_t textureId, const IntRect&)
{
if (!m_private)
return;
m_private->copyFromTexture(textureId);
}
void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
{
uint32_t texture = platformGetTextureID();
if (!texture)
return;
TransformationMatrix adjustedTransform = transform;
adjustedTransform.multiply(TransformationMatrix::rectToRect(m_private->rect(), targetRect));
static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private->flags(), m_private->size(), m_private->rect(), adjustedTransform, opacity);
}
uint32_t GraphicsSurface::platformFrontBuffer() const
{
return 0;
}
uint32_t GraphicsSurface::platformSwapBuffers()
{
m_private->updateClientBuffer();
return 0;
}
IntSize GraphicsSurface::platformSize() const
{
return m_private->size();
}
PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext)
{
if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
return PassRefPtr<GraphicsSurface>();
RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
surface->m_private = new GraphicsSurfacePrivate();
if (surface->m_private->initializeTransportSurface(size, flags, shareContext))
return surface;
return PassRefPtr<GraphicsSurface>();
}
PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
{
if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
return PassRefPtr<GraphicsSurface>();
RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
surface->m_private = new GraphicsSurfacePrivate(token.frontBufferHandle, size, flags);
return surface;
}
char* GraphicsSurface::platformLock(const IntRect&, int* , LockOptions)
{
return 0;
}
void GraphicsSurface::platformUnlock()
{
}
void GraphicsSurface::platformDestroy()
{
if (!m_private)
return;
m_private->destroy();
delete m_private;
m_private = 0;
}
std::unique_ptr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize&, char*, int)
{
notImplemented();
return nullptr;
}
PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect&)
{
notImplemented();
return 0;
}
}