GraphicsContext3DBlackBerry.cpp [plain text]
#include "config.h"
#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
#include "BitmapImageSingleFrameSkia.h"
#include "Extensions3DOpenGL.h"
#include "GraphicsContext.h"
#include "WebGLLayerWebKitThread.h"
#include <BlackBerryPlatformGraphics.h>
namespace WebCore {
PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(Attributes attribs, HostWindow* hostWindow, RenderStyle renderStyle)
{
if (renderStyle == RenderDirectlyToHostWindow)
return 0;
return adoptRef(new GraphicsContext3D(attribs, hostWindow, false));
}
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow)
: m_currentWidth(0)
, m_currentHeight(0)
, m_hostWindow(hostWindow)
, m_context(BlackBerry::Platform::Graphics::createWebGLContext())
, m_extensions(adoptPtr(new Extensions3DOpenGL(this)))
, m_attrs(attrs)
, m_texture(0)
, m_fbo(0)
, m_depthStencilBuffer(0)
, m_boundFBO(0)
, m_activeTexture(GL_TEXTURE0)
, m_boundTexture0(0)
, m_multisampleFBO(0)
, m_multisampleDepthStencilBuffer(0)
, m_multisampleColorBuffer(0)
{
if (!renderDirectlyToHostWindow) {
#if USE(ACCELERATED_COMPOSITING)
m_compositingLayer = WebGLLayerWebKitThread::create();
#endif
makeContextCurrent();
Extensions3D* extensions = getExtensions();
if (!extensions->supports("GL_IMG_multisampled_render_to_texture"))
m_attrs.antialias = false;
::glGenTextures(1, &m_texture);
::glBindTexture(GL_TEXTURE_2D, m_texture);
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
::glBindTexture(GL_TEXTURE_2D, 0);
::glGenFramebuffers(1, &m_fbo);
::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
if (m_attrs.stencil || m_attrs.depth)
::glGenRenderbuffers(1, &m_depthStencilBuffer);
m_boundFBO = m_fbo;
#if USE(ACCELERATED_COMPOSITING)
static_cast<WebGLLayerWebKitThread*>(m_compositingLayer.get())->setWebGLContext(this);
#endif
}
makeContextCurrent();
::glClearColor(0, 0, 0, 0);
}
GraphicsContext3D::~GraphicsContext3D()
{
if (m_texture) {
makeContextCurrent();
::glDeleteTextures(1, &m_texture);
if (m_attrs.stencil || m_attrs.depth)
::glDeleteRenderbuffers(1, &m_depthStencilBuffer);
::glDeleteFramebuffers(1, &m_fbo);
}
BlackBerry::Platform::Graphics::destroyWebGLContext(m_context);
}
bool GraphicsContext3D::paintsIntoCanvasBuffer() const
{
return true;
}
bool GraphicsContext3D::makeContextCurrent()
{
BlackBerry::Platform::Graphics::useWebGLContext(m_context);
return true;
}
bool GraphicsContext3D::isGLES2Compliant() const
{
return true;
}
bool GraphicsContext3D::isGLES2NPOTStrict() const
{
return true;
}
bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const
{
return false;
}
Platform3DObject GraphicsContext3D::platformTexture() const
{
return m_texture;
}
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* GraphicsContext3D::platformLayer() const
{
return m_compositingLayer.get();
}
#endif
void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight,
GraphicsContext* context, bool flipY)
{
unsigned char* tempPixels = new unsigned char[imageWidth * imageHeight * 4];
if (flipY) {
for (int y = 0; y < imageHeight; y++) {
const unsigned char *srcRow = imagePixels + (imageWidth * 4 * y);
unsigned char *destRow = tempPixels + (imageWidth * 4 * (imageHeight - y - 1));
for (int i = 0; i < imageWidth * 4; i += 4) {
destRow[i + 0] = srcRow[i + 2];
destRow[i + 1] = srcRow[i + 1];
destRow[i + 2] = srcRow[i + 0];
destRow[i + 3] = srcRow[i + 3];
}
}
} else {
for (int i = 0; i < imageWidth * imageHeight * 4; i += 4) {
tempPixels[i + 0] = imagePixels[i + 2];
tempPixels[i + 1] = imagePixels[i + 1];
tempPixels[i + 2] = imagePixels[i + 0];
tempPixels[i + 3] = imagePixels[i + 3];
}
}
SkBitmap canvasBitmap;
canvasBitmap.setConfig(SkBitmap::kARGB_8888_Config, canvasWidth, canvasHeight);
canvasBitmap.allocPixels(0, 0);
canvasBitmap.lockPixels();
memcpy(canvasBitmap.getPixels(), tempPixels, imageWidth * imageHeight * 4);
canvasBitmap.unlockPixels();
delete [] tempPixels;
FloatRect src(0, 0, canvasWidth, canvasHeight);
FloatRect dst(0, 0, imageWidth, imageHeight);
RefPtr<BitmapImageSingleFrameSkia> bitmapImage = BitmapImageSingleFrameSkia::create(canvasBitmap, false);
context->drawImage(bitmapImage.get(), ColorSpaceDeviceRGB, dst, src, CompositeCopy, DoNotRespectImageOrientation, false);
}
void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
{
}
void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr<ErrorMessageCallback>)
{
}
}
#endif // ENABLE(WEBGL)