summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp12
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.h3
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.cpp9
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h30
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h9
-rw-r--r--Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp102
-rw-r--r--Source/WebCore/platform/graphics/android/Extensions3DAndroid.h64
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp1368
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp1103
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h221
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp87
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h61
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp39
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h14
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/WebGLLayer.cpp82
-rw-r--r--Source/WebCore/platform/graphics/android/WebGLLayer.h62
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp14
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h4
25 files changed, 3301 insertions, 37 deletions
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
index 9e64904..43819b6 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -57,20 +57,20 @@ void ANGLEWebKitBridge::cleanupCompilers()
builtCompilers = false;
}
-
+
void ANGLEWebKitBridge::setResources(ShBuiltInResources resources)
{
// Resources are (possibly) changing - cleanup compilers if we had them already
cleanupCompilers();
-
+
m_resources = resources;
}
bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog)
{
if (!builtCompilers) {
- m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, &m_resources);
- m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, &m_resources);
+ m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, SH_GLSL_OUTPUT, &m_resources);
+ m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, SH_GLSL_OUTPUT, &m_resources);
if (!m_fragmentCompiler || !m_vertexCompiler) {
cleanupCompilers();
return false;
@@ -78,7 +78,7 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
builtCompilers = true;
}
-
+
ShHandle compiler;
if (shaderType == SHADER_TYPE_VERTEX)
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index a9d2238..e8008a7 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,7 +30,7 @@
#include "PlatformString.h"
#include <wtf/text/CString.h>
-#if !PLATFORM(GTK)
+#if !PLATFORM(GTK) && !PLATFORM(ANDROID)
#include "ANGLE/ShaderLang.h"
#else
#include "ShaderLang.h"
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
index 324fed8..03bcd9e 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -21,7 +21,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -56,10 +56,13 @@ namespace {
} // anonymous namespace
-
PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& size)
{
- return DrawingBuffer::create(this, size);
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ return DrawingBuffer::create(this, size);
+#else
+ return 0;
+#endif
}
bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 80226cf..b2a4d3a 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -88,6 +89,9 @@ class Extensions3D;
class Extensions3DOpenGL;
#endif
class HostWindow;
+#if PLATFORM(ANDROID)
+class HTMLCanvasElement;
+#endif
class Image;
class ImageData;
#if USE(CAIRO)
@@ -101,7 +105,7 @@ struct ActiveInfo {
};
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
class GraphicsContext3DInternal;
#endif
@@ -452,7 +456,12 @@ public:
void setContextLostCallback(PassOwnPtr<ContextLostCallback>);
+#if PLATFORM(ANDROID)
+ static PassRefPtr<GraphicsContext3D> create(HTMLCanvasElement*, Attributes,
+ HostWindow*, RenderStyle = RenderOffscreen);
+#else
static PassRefPtr<GraphicsContext3D> create(Attributes, HostWindow*, RenderStyle = RenderOffscreen);
+#endif
~GraphicsContext3D();
#if PLATFORM(MAC)
@@ -474,6 +483,12 @@ public:
#elif PLATFORM(GTK)
PlatformGraphicsContext3D platformGraphicsContext3D();
Platform3DObject platformTexture() const { return m_texture; }
+#elif PLATFORM(ANDROID)
+ PlatformGraphicsContext3D platformGraphicsContext3D();
+ Platform3DObject platformTexture() const;
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer() const;
+#endif
#else
PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
Platform3DObject platformTexture() const { return NullPlatform3DObject; }
@@ -770,12 +785,18 @@ public:
int canvasWidth, int canvasHeight, PlatformContextCairo* context);
#endif
+#if PLATFORM(ANDROID)
+ void recreateSurface();
+ void releaseSurface();
+#endif
+
void markContextChanged();
void markLayerComposited();
bool layerComposited() const;
void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
PassRefPtr<ImageData> paintRenderingResultsToImageData();
+ bool paintCompositedResultsToCanvas(CanvasRenderingContext* context);
#if PLATFORM(QT)
bool paintsIntoCanvasBuffer() const { return true; }
@@ -821,7 +842,12 @@ public:
IntSize getInternalFramebufferSize();
private:
+#if PLATFORM(ANDROID)
+ GraphicsContext3D(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow* hostWindow, bool renderDirectlyToHostWindow);
+#else
GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow);
+#endif
// Each platform must provide an implementation of this method.
//
@@ -929,7 +955,7 @@ public:
#endif
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
friend class GraphicsContext3DInternal;
OwnPtr<GraphicsContext3DInternal> m_internal;
#endif
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index c184bbe..fa546e3 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -33,6 +33,7 @@
#include "FloatRect.h"
#include "GraphicsTypes.h"
#include "IntSize.h"
+#include "ImageBuffer.h"
#include "ImageBufferData.h"
#include <wtf/ByteArray.h>
#include <wtf/Forward.h>
@@ -77,9 +78,9 @@ namespace WebCore {
const IntSize& size() const { return m_size; }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
-
+
size_t dataSize() const;
-
+
GraphicsContext* context() const;
bool isAccelerated() const { return m_accelerateRendering; }
@@ -91,7 +92,7 @@ namespace WebCore {
void putUnmultipliedImageData(ByteArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint);
void putPremultipliedImageData(ByteArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint);
-
+
String toDataURL(const String& mimeType, const double* quality = 0) const;
#if !USE(CG)
AffineTransform baseTransform() const { return AffineTransform(); }
@@ -129,7 +130,7 @@ namespace WebCore {
ImageBuffer(const IntSize&, ColorSpace colorSpace, RenderingMode renderingMode, bool& success);
};
-#if USE(CG) || USE(SKIA)
+#if USE(CG) || USE(SKIA) || PLATFORM(ANDROID)
String ImageDataToDataURL(const ImageData& input, const String& mimeType, const double* quality);
#endif
diff --git a/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp
new file mode 100644
index 0000000..36fbe15
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "Extensions3DAndroid.h"
+#include "GraphicsContext3D.h"
+
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+Extensions3DAndroid::Extensions3DAndroid(const String& extensions)
+ : m_extensions(extensions)
+{
+}
+
+Extensions3DAndroid::~Extensions3DAndroid()
+{
+}
+
+bool Extensions3DAndroid::supports(const String& ext)
+{
+ return m_extensions.contains(ext);
+}
+
+void Extensions3DAndroid::ensureEnabled(const String& name)
+{
+}
+
+bool Extensions3DAndroid::isEnabled(const String& name)
+{
+ return supports(name);
+}
+
+int Extensions3DAndroid::getGraphicsResetStatusARB()
+{
+ return GraphicsContext3D::NO_ERROR;
+}
+
+void Extensions3DAndroid::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1,
+ long dstX0, long dstY0, long dstX1, long dstY1,
+ unsigned long mask, unsigned long filter)
+{
+}
+
+void Extensions3DAndroid::renderbufferStorageMultisample(unsigned long target,
+ unsigned long samples,
+ unsigned long internalformat,
+ unsigned long width,
+ unsigned long height)
+{
+}
+
+Platform3DObject Extensions3DAndroid::createVertexArrayOES()
+{
+ return 0;
+}
+
+void Extensions3DAndroid::deleteVertexArrayOES(Platform3DObject)
+{
+}
+
+GC3Dboolean Extensions3DAndroid::isVertexArrayOES(Platform3DObject)
+{
+ return GL_FALSE;
+}
+
+void Extensions3DAndroid::bindVertexArrayOES(Platform3DObject)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h
new file mode 100644
index 0000000..ff50fa8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Extensions3DAndroid.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Extensions3DAndroid_h
+#define Extensions3DAndroid_h
+
+#include "Extensions3D.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Extensions3DAndroid : public Extensions3D {
+public:
+ Extensions3DAndroid(const String& extensions);
+ virtual ~Extensions3DAndroid();
+
+ // Extensions3D methods.
+ virtual bool supports(const String&);
+ virtual void ensureEnabled(const String&);
+ virtual bool isEnabled(const String&);
+ virtual int getGraphicsResetStatusARB();
+ virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1,
+ long dstX0, long dstY0, long dstX1, long dstY1,
+ unsigned long mask, unsigned long filter);
+ virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples,
+ unsigned long internalformat, unsigned long width,
+ unsigned long height);
+ virtual Platform3DObject createVertexArrayOES();
+ virtual void deleteVertexArrayOES(Platform3DObject);
+ virtual GC3Dboolean isVertexArrayOES(Platform3DObject);
+ virtual void bindVertexArrayOES(Platform3DObject);
+
+private:
+ String m_extensions;
+};
+
+} // namespace WebCore
+
+#endif // Extensions3DAndroid_h
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp
new file mode 100644
index 0000000..df706a2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DAndroid.cpp
@@ -0,0 +1,1368 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+#include "BitmapImage.h"
+#include "text/CString.h"
+#include "GraphicsContext3D.h"
+#include "GraphicsContext3DInternal.h"
+#include "Image.h"
+#include "ImageData.h"
+#include "ImageDecoder.h"
+#include "SkBitmap.h"
+#include "SkBitmapRef.h"
+
+namespace WebCore {
+
+
+PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow *win, RenderStyle style)
+{
+ GraphicsContext3D *context = new GraphicsContext3D(canvas, attrs, win, false);
+ if (!context->m_internal->isValid()) {
+ // Something failed during initialization
+ delete context;
+ return 0;
+ }
+ return adoptRef(context);
+}
+
+GraphicsContext3D::GraphicsContext3D(HTMLCanvasElement* canvas, Attributes attrs,
+ HostWindow* hostWindow, bool renderDirectlyToHostWindow)
+ : m_internal(new GraphicsContext3DInternal(canvas, attrs, hostWindow))
+{
+ LOGWEBGL("GraphicsContext3D() = %p", this);
+ m_currentWidth = m_internal->width();
+ m_currentHeight = m_internal->height();
+}
+
+GraphicsContext3D::~GraphicsContext3D()
+{
+ LOGWEBGL("~GraphicsContext3D()");
+}
+
+PlatformLayer* GraphicsContext3D::platformLayer() const
+{
+ return m_internal->platformLayer();
+}
+
+void GraphicsContext3D::makeContextCurrent() {
+ m_internal->makeContextCurrent();
+}
+
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+ return true;
+}
+
+void GraphicsContext3D::synthesizeGLError(GC3Denum error)
+{
+ m_internal->synthesizeGLError(error);
+}
+
+Extensions3D* GraphicsContext3D::getExtensions()
+{
+ return m_internal->getExtensions();
+}
+
+void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+ makeContextCurrent();
+ m_internal->paintRenderingResultsToCanvas(context);
+}
+
+PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
+{
+ makeContextCurrent();
+ return m_internal->paintRenderingResultsToImageData();
+}
+
+bool GraphicsContext3D::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
+{
+ makeContextCurrent();
+ return m_internal->paintCompositedResultsToCanvas(context);
+}
+
+bool GraphicsContext3D::getImageData(Image* image,
+ unsigned int format,
+ unsigned int type,
+ bool premultiplyAlpha,
+ bool ignoreGammaAndColorProfile,
+ Vector<uint8_t>& outputVector)
+{
+ LOGWEBGL("getImageData(%p, %u, %u, %s, %s)", image, format, type,
+ premultiplyAlpha ? "true" : "false", ignoreGammaAndColorProfile ? "true" : "false");
+ if (!image)
+ return false;
+
+ AlphaOp neededAlphaOp = AlphaDoNothing;
+ bool hasAlpha = (image->data() && image->isBitmapImage()) ?
+ static_cast<BitmapImage*>(image)->frameHasAlphaAtIndex(0) : true;
+ ImageDecoder* decoder = 0;
+ ImageFrame* buf = 0;
+
+ if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
+ // Attempt to get raw unpremultiplied image data
+ decoder = ImageDecoder::create(*(image->data()),
+ premultiplyAlpha ?
+ ImageSource::AlphaPremultiplied :
+ ImageSource::AlphaNotPremultiplied,
+ ignoreGammaAndColorProfile ?
+ ImageSource::GammaAndColorProfileIgnored :
+ ImageSource::GammaAndColorProfileApplied);
+ if (decoder) {
+ decoder->setData(image->data(), true);
+ buf = decoder->frameBufferAtIndex(0);
+ if (buf && buf->hasAlpha() && premultiplyAlpha)
+ neededAlphaOp = AlphaDoPremultiply;
+ }
+ }
+
+ SkBitmapRef* bitmapRef = 0;
+ if (!buf) {
+ bitmapRef = image->nativeImageForCurrentFrame();
+ if (!bitmapRef)
+ return false;
+ if (!premultiplyAlpha && hasAlpha)
+ neededAlphaOp = AlphaDoUnmultiply;
+ }
+
+ SkBitmap& bitmap = buf ? buf->bitmap() : bitmapRef->bitmap();
+ unsigned char* pixels = 0;
+ int rowBytes = 0;
+ uint32_t* tmpPixels = 0;
+
+ int width = bitmap.width();
+ int height = bitmap.height();
+ int iwidth = image->width();
+ int iheight = image->height();
+ LOGWEBGL(" bitmap.width() = %d, image->width() = %d, bitmap.height = %d, image->height() = %d",
+ width, iwidth, height, iheight);
+ if (width != iwidth || height != iheight) {
+ // This image has probably been subsampled because it was too big.
+ // Currently, we cannot handle this in WebGL: give up.
+ return false;
+ }
+ SkBitmap::Config skiaConfig = bitmap.getConfig();
+
+ bitmap.lockPixels();
+ if (skiaConfig == SkBitmap::kARGB_8888_Config) {
+ LOGWEBGL(" skiaConfig = kARGB_8888_Config");
+ pixels = reinterpret_cast<unsigned char*>(bitmap.getPixels());
+ rowBytes = bitmap.rowBytes();
+ if (!pixels) {
+ bitmap.unlockPixels();
+ return false;
+ }
+ }
+ else if (skiaConfig == SkBitmap::kIndex8_Config) {
+ LOGWEBGL(" skiaConfig = kIndex8_Config");
+ rowBytes = width * 4;
+ tmpPixels = (uint32_t*)fastMalloc(width * height * 4);
+ if (!tmpPixels) {
+ bitmap.unlockPixels();
+ return false;
+ }
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ SkPMColor c = bitmap.getIndex8Color(j, i);
+ tmpPixels[i * width + j] = c;//SkExpand_8888(c);
+ }
+ }
+ pixels = (unsigned char*)tmpPixels;
+ }
+
+ outputVector.resize(rowBytes * height);
+ LOGWEBGL("rowBytes() = %d, width() = %d, height() = %d", rowBytes, width, height);
+
+ bool res = packPixels(pixels,
+ SourceFormatRGBA8, width, height, 0,
+ format, type, neededAlphaOp, outputVector.data());
+ bitmap.unlockPixels();
+
+ if (decoder)
+ delete decoder;
+
+ if (tmpPixels)
+ fastFree(tmpPixels);
+
+ return res;
+}
+
+unsigned GraphicsContext3D::createBuffer()
+{
+ LOGWEBGL("glCreateBuffer()");
+ makeContextCurrent();
+ GLuint b = 0;
+ glGenBuffers(1, &b);
+ return b;
+}
+
+unsigned GraphicsContext3D::createFramebuffer()
+{
+ LOGWEBGL("glCreateFramebuffer()");
+ makeContextCurrent();
+ GLuint fb = 0;
+ glGenFramebuffers(1, &fb);
+ return fb;
+}
+
+unsigned GraphicsContext3D::createProgram()
+{
+ LOGWEBGL("glCreateProgram()");
+ makeContextCurrent();
+ return glCreateProgram();
+}
+
+unsigned GraphicsContext3D::createRenderbuffer()
+{
+ LOGWEBGL("glCreateRenderbuffer()");
+ makeContextCurrent();
+ GLuint rb = 0;
+ glGenRenderbuffers(1, &rb);
+ return rb;
+}
+
+unsigned GraphicsContext3D::createShader(GC3Denum type)
+{
+ LOGWEBGL("glCreateShader()");
+ makeContextCurrent();
+ return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
+}
+
+unsigned GraphicsContext3D::createTexture()
+{
+ LOGWEBGL("glCreateTexture()");
+ makeContextCurrent();
+ GLuint t = 0;
+ glGenTextures(1, &t);
+ return t;
+}
+
+void GraphicsContext3D::deleteBuffer(unsigned buffer)
+{
+ LOGWEBGL("glDeleteBuffers()");
+ makeContextCurrent();
+ glDeleteBuffers(1, &buffer);
+}
+
+void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
+{
+ LOGWEBGL("glDeleteFramebuffers()");
+ makeContextCurrent();
+ glDeleteFramebuffers(1, &framebuffer);
+}
+
+void GraphicsContext3D::deleteProgram(unsigned program)
+{
+ LOGWEBGL("glDeleteProgram()");
+ makeContextCurrent();
+ glDeleteProgram(program);
+}
+
+void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
+{
+ LOGWEBGL("glDeleteRenderbuffers()");
+ makeContextCurrent();
+ glDeleteRenderbuffers(1, &renderbuffer);
+}
+
+void GraphicsContext3D::deleteShader(unsigned shader)
+{
+ LOGWEBGL("glDeleteShader()");
+ makeContextCurrent();
+ glDeleteShader(shader);
+}
+
+void GraphicsContext3D::deleteTexture(unsigned texture)
+{
+ LOGWEBGL("glDeleteTextures()");
+ makeContextCurrent();
+ glDeleteTextures(1, &texture);
+}
+
+
+void GraphicsContext3D::activeTexture(GC3Denum texture)
+{
+ LOGWEBGL("glActiveTexture(%ld)", texture);
+ makeContextCurrent();
+ glActiveTexture(texture);
+}
+
+void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
+{
+ LOGWEBGL("glAttachShader(%d, %d)", program, shader);
+ makeContextCurrent();
+ glAttachShader(program, shader);
+}
+
+void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index,
+ const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glBindAttribLocation(%d, %d, %s)", program, index, cs.data());
+ if (!program)
+ return;
+ makeContextCurrent();
+ glBindAttribLocation(program, index, cs.data());
+}
+
+void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
+{
+ LOGWEBGL("glBindBuffer(%d, %d)", target, buffer);
+ makeContextCurrent();
+ glBindBuffer(target, buffer);
+}
+
+void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject framebuffer)
+{
+ LOGWEBGL("bindFrameBuffer(%d, %d)", target, framebuffer);
+ m_internal->bindFramebuffer(target, framebuffer);
+}
+
+void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glBindRenderBuffer(%d, %d)", target, renderbuffer);
+ makeContextCurrent();
+ glBindRenderbuffer(target, renderbuffer);
+}
+
+void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
+{
+ LOGWEBGL("glBindTexture(%d, %d)", target, texture);
+ makeContextCurrent();
+ glBindTexture(target, texture);
+}
+
+void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green,
+ GC3Dclampf blue, GC3Dclampf alpha)
+{
+ LOGWEBGL("glBlendColor(%lf, %lf, %lf, %lf)", red, green, blue, alpha);
+ makeContextCurrent();
+ glBlendColor(CLAMP(red), CLAMP(green), CLAMP(blue), CLAMP(alpha));
+}
+
+void GraphicsContext3D::blendEquation(GC3Denum mode)
+{
+ LOGWEBGL("glBlendEquation(%d)", mode);
+ makeContextCurrent();
+ glBlendEquation(mode);
+}
+
+void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
+{
+ LOGWEBGL("glBlendEquationSeparate(%d, %d)", modeRGB, modeAlpha);
+ makeContextCurrent();
+ glBlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
+{
+ LOGWEBGL("glBlendFunc(%d, %d)", sfactor, dfactor);
+ makeContextCurrent();
+ glBlendFunc(sfactor, dfactor);
+}
+
+void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB,
+ GC3Denum srcAlpha, GC3Denum dstAlpha)
+{
+ LOGWEBGL("glBlendFuncSeparate(%lu, %lu, %lu, %lu)", srcRGB, dstRGB, srcAlpha, dstAlpha);
+ makeContextCurrent();
+ glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
+{
+ LOGWEBGL("glBufferData(%lu, %d, %lu)", target, size, usage);
+ makeContextCurrent();
+ glBufferData(target, size, 0, usage);
+}
+
+void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size,
+ const void* data, GC3Denum usage)
+{
+ LOGWEBGL("glBufferData(%lu, %d, %p, %lu)", target, size, data, usage);
+ makeContextCurrent();
+ glBufferData(target, size, data, usage);
+}
+
+void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset,
+ GC3Dsizeiptr size, const void* data)
+{
+ LOGWEBGL("glBufferSubData(%lu, %ld, %d, %p)", target, offset, size, data);
+ makeContextCurrent();
+ glBufferSubData(target, offset, size, data);
+}
+
+GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
+{
+ LOGWEBGL("glCheckFramebufferStatus(%lu)", target);
+ makeContextCurrent();
+ return glCheckFramebufferStatus(target);
+}
+
+void GraphicsContext3D::clear(GC3Dbitfield mask)
+{
+ LOGWEBGL("glClear(%lu)", mask);
+ makeContextCurrent();
+ glClear(mask);
+}
+
+void GraphicsContext3D::clearColor(GC3Dclampf red, GC3Dclampf green,
+ GC3Dclampf blue, GC3Dclampf alpha)
+{
+ LOGWEBGL("glClearColor(%.2lf, %.2lf, %.2lf, %.2lf)", red, green, blue, alpha);
+ makeContextCurrent();
+ glClearColor(CLAMP(red), CLAMP(green), CLAMP(blue), CLAMP(alpha));
+}
+
+void GraphicsContext3D::clearDepth(GC3Dclampf depth)
+{
+ LOGWEBGL("glClearDepthf(%.2lf)", depth);
+ makeContextCurrent();
+ glClearDepthf(CLAMP(depth));
+}
+
+void GraphicsContext3D::clearStencil(GC3Dint s)
+{
+ LOGWEBGL("glClearStencil(%ld)", s);
+ makeContextCurrent();
+ glClearStencil(s);
+}
+
+void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green,
+ GC3Dboolean blue, GC3Dboolean alpha)
+{
+ LOGWEBGL("glColorMask(%s, %s, %s, %s)", red ? "true" : "false", green ? "true" : "false",
+ blue ? "true" : "false", alpha ? "true" : "false");
+ makeContextCurrent();
+ glColorMask(red, green, blue, alpha);
+}
+
+void GraphicsContext3D::compileShader(Platform3DObject shader)
+{
+ LOGWEBGL("compileShader(%lu)", shader);
+ makeContextCurrent();
+ m_internal->compileShader(shader);
+}
+
+void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dint x, GC3Dint y, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border)
+{
+ LOGWEBGL("glCopyTexImage2D(%lu, %ld, %lu, %ld, %ld, %lu, %lu, %ld",
+ target, level, internalformat, x, y, width, height, border);
+ makeContextCurrent();
+ glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset,
+ GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width,
+ GC3Dsizei height)
+{
+ LOGWEBGL("glCopyTexSubImage2D(%lu, %ld, %ld, %ld, %ld, %ld, %lu, %lu)",
+ target, level, xoffset, yoffset, x, y, width, height);
+ makeContextCurrent();
+ glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void GraphicsContext3D::cullFace(GC3Denum mode)
+{
+ LOGWEBGL("glCullFace(%lu)", mode);
+ makeContextCurrent();
+ glCullFace(mode);
+}
+
+void GraphicsContext3D::depthFunc(GC3Denum func)
+{
+ LOGWEBGL("glDepthFunc(%lu)", func);
+ makeContextCurrent();
+ glDepthFunc(func);
+}
+
+void GraphicsContext3D::depthMask(GC3Dboolean flag)
+{
+ LOGWEBGL("glDepthMask(%s)", flag ? "true" : "false");
+ makeContextCurrent();
+ glDepthMask(flag);
+}
+
+void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
+{
+ LOGWEBGL("glDepthRangef(%.2lf, %.2lf)", zNear, zFar);
+ makeContextCurrent();
+ glDepthRangef(CLAMP(zNear), CLAMP(zFar));
+}
+
+void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
+{
+ LOGWEBGL("glDetachShader(%lu, %lu)", program, shader);
+ makeContextCurrent();
+ glDetachShader(program, shader);
+}
+
+void GraphicsContext3D::disable(GC3Denum cap)
+{
+ LOGWEBGL("glDisable(%lu)", cap);
+ makeContextCurrent();
+ glDisable(cap);
+}
+
+void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
+{
+ LOGWEBGL("glDisableVertexAttribArray(%lu)", index);
+ makeContextCurrent();
+ glDisableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
+{
+ LOGWEBGL("glDrawArrays(%lu, %ld, %ld)", mode, first, count);
+ makeContextCurrent();
+ glDrawArrays(mode, first, count);
+}
+
+void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count,
+ GC3Denum type, GC3Dintptr offset)
+{
+ LOGWEBGL("glDrawElements(%lu, %lu, %lu, %ld)", mode, count, type, offset);
+ makeContextCurrent();
+ glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::enable(GC3Denum cap)
+{
+ LOGWEBGL("glEnable(0x%04x)", cap);
+ makeContextCurrent();
+ glEnable(cap);
+}
+
+void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
+{
+ LOGWEBGL("glEnableVertexAttribArray(%lu)", index);
+ makeContextCurrent();
+ glEnableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::finish()
+{
+ LOGWEBGL("glFinish()");
+ makeContextCurrent();
+ glFinish();
+}
+
+void GraphicsContext3D::flush()
+{
+ LOGWEBGL("glFlush()");
+ makeContextCurrent();
+ glFlush();
+}
+
+void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment,
+ GC3Denum renderbuffertarget,
+ Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glFramebufferRenderbuffer(%lu, %lu, %lu, %lu)", target, attachment,
+ renderbuffertarget, renderbuffer);
+ makeContextCurrent();
+ glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment,
+ GC3Denum textarget, Platform3DObject texture,
+ GC3Dint level)
+{
+ LOGWEBGL("glFramebufferTexture2D(%lu, %lu, %lu, %lu, %ld)",
+ target, attachment, textarget, texture, level);
+ makeContextCurrent();
+ glFramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void GraphicsContext3D::frontFace(GC3Denum mode)
+{
+ LOGWEBGL("glFrontFace(%lu)", mode);
+ makeContextCurrent();
+ glFrontFace(mode);
+}
+
+void GraphicsContext3D::generateMipmap(GC3Denum target)
+{
+ LOGWEBGL("glGenerateMipmap(%lu)", target);
+ makeContextCurrent();
+ glGenerateMipmap(target);
+}
+
+bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+ LOGWEBGL("glGetActiveAttrib(%lu, %lu)", program, index);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ GLint maxAttributeSize = 0;
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
+ GLchar name[maxAttributeSize];
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
+bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
+{
+ LOGWEBGL("glGetActiveUniform(%lu, %lu)", program, index);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ GLint maxUniformSize = 0;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
+ GLchar name[maxUniformSize];
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
+void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount,
+ GC3Dsizei* count, Platform3DObject* shaders)
+{
+ LOGWEBGL("glGetAttachedShaders(%lu, %d, %p, %p)", program, maxCount, count, shaders);
+ if (!program) {
+ synthesizeGLError(INVALID_VALUE);
+ return;
+ }
+ makeContextCurrent();
+ glGetAttachedShaders(program, maxCount, count, shaders);
+}
+
+GC3Dint GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glGetAttribLocation(%lu, %s)", program, cs.data());
+ if (!program) {
+ return -1;
+ }
+ makeContextCurrent();
+
+ return glGetAttribLocation(program, cs.data());
+}
+
+void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
+{
+ LOGWEBGL("glGetBooleanv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetBooleanv(pname, value);
+}
+
+void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetBufferParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetBufferParameteriv(target, pname, value);
+}
+
+GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
+{
+ LOGWEBGL("getContextAttributes()");
+ return m_internal->getContextAttributes();
+}
+
+GC3Denum GraphicsContext3D::getError()
+{
+ LOGWEBGL("getError()");
+ return m_internal->getError();
+}
+
+void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetFloatv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetFloatv(pname, value);
+}
+
+void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment,
+ GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetFramebufferAttachmentParameteriv(%lu, %lu, %lu, %p)",
+ target, attachment, pname, value);
+ makeContextCurrent();
+ if (attachment == DEPTH_STENCIL_ATTACHMENT)
+ attachment = DEPTH_ATTACHMENT;
+ glGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
+}
+
+void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetIntegerv(%lu, %p)", pname, value);
+ makeContextCurrent();
+ glGetIntegerv(pname, value);
+}
+
+void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetProgramiv(%lu, %lu, %p)", program, pname, value);
+ makeContextCurrent();
+ glGetProgramiv(program, pname, value);
+}
+
+String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
+{
+ LOGWEBGL("glGetProgramInfoLog(%lu)", program);
+ makeContextCurrent();
+ GLint length;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
+ if (!length)
+ return "";
+
+ GLsizei size;
+ GLchar* info = (GLchar*)fastMalloc(length);
+ glGetProgramInfoLog(program, length, &size, info);
+ String s(info);
+ fastFree(info);
+
+ return s;
+}
+
+void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetRenderbufferParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetRenderbufferParameteriv(target, pname, value);
+}
+
+void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetShaderiv(%lu, %lu, %p)", shader, pname, value);
+ makeContextCurrent();
+ glGetShaderiv(shader, pname, value);
+}
+
+String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderInfoLog(%lu)", shader);
+ makeContextCurrent();
+ return m_internal->getShaderInfoLog(shader);
+}
+
+String GraphicsContext3D::getShaderSource(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderSource(%lu)", shader);
+ makeContextCurrent();
+ return m_internal->getShaderSource(shader);
+}
+
+String GraphicsContext3D::getString(GC3Denum name)
+{
+ LOGWEBGL("glGetString(%lu)", name);
+ makeContextCurrent();
+ return String(reinterpret_cast<const char*>(glGetString(name)));
+}
+
+void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetTexParameterfv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetTexParameterfv(target, pname, value);
+}
+
+void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetTexParameteriv(%lu, %lu, %p)", target, pname, value);
+ makeContextCurrent();
+ glGetTexParameteriv(target, pname, value);
+}
+
+void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetUniformfv(%lu, %ld, %p)", program, location, value);
+ makeContextCurrent();
+ glGetUniformfv(program, location, value);
+}
+
+void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
+{
+ LOGWEBGL("glGetUniformiv(%lu, %ld, %p)", program, location, value);
+ makeContextCurrent();
+ glGetUniformiv(program, location, value);
+}
+
+GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
+{
+ CString cs = name.utf8();
+ LOGWEBGL("glGetUniformLocation(%lu, %s)", program, cs.data());
+ makeContextCurrent();
+ return glGetUniformLocation(program, cs.data());
+}
+
+void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
+{
+ LOGWEBGL("glGetVertexAttribfv(%lu, %lu, %p)", index, pname, value);
+ makeContextCurrent();
+ glGetVertexAttribfv(index, pname, value);
+}
+
+void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value)
+{
+ LOGWEBGL("glGetVertexAttribiv(%lu, %lu, %p)", index, pname, value);
+ makeContextCurrent();
+ glGetVertexAttribiv(index, pname, value);
+}
+
+GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
+{
+ LOGWEBGL("glGetVertexAttribOffset(%lu, %lu)", index, pname);
+ GLvoid* pointer = 0;
+ glGetVertexAttribPointerv(index, pname, &pointer);
+ return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
+}
+
+void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
+{
+ LOGWEBGL("glHint(%lu, %lu)", target, mode);
+ makeContextCurrent();
+ glHint(target, mode);
+}
+
+GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer)
+{
+ LOGWEBGL("glIsBuffer(%lu)", buffer);
+ if (!buffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsBuffer(buffer);
+}
+
+GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
+{
+ LOGWEBGL("glIsEnabled(%lu)", cap);
+ makeContextCurrent();
+ return glIsEnabled(cap);
+}
+
+GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer)
+{
+ LOGWEBGL("glIsFramebuffer(%lu)", framebuffer);
+ if (!framebuffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsFramebuffer(framebuffer);
+}
+
+GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program)
+{
+ LOGWEBGL("glIsProgram(%lu)", program);
+ if (!program)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsProgram(program);
+}
+
+GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer)
+{
+ LOGWEBGL("glIsRenderbuffer(%lu)", renderbuffer);
+ if (!renderbuffer)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsRenderbuffer(renderbuffer);
+}
+
+GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader)
+{
+ LOGWEBGL("glIsShader(%lu)", shader);
+ if (!shader)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsShader(shader);
+}
+
+GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture)
+{
+ LOGWEBGL("glIsTexture(%lu)", texture);
+ if (!texture)
+ return GL_FALSE;
+ makeContextCurrent();
+ return glIsTexture(texture);
+}
+
+void GraphicsContext3D::lineWidth(GC3Dfloat width)
+{
+ LOGWEBGL("glLineWidth(%.2lf)", width);
+ makeContextCurrent();
+ glLineWidth((GLfloat)width);
+}
+
+void GraphicsContext3D::linkProgram(Platform3DObject program)
+{
+ LOGWEBGL("glLinkProgram(%lu)", program);
+ makeContextCurrent();
+ glLinkProgram(program);
+}
+
+void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param)
+{
+ LOGWEBGL("glPixelStorei(%lu, %ld)", pname, param);
+ makeContextCurrent();
+ glPixelStorei(pname, param);
+}
+
+void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
+{
+ LOGWEBGL("glPolygonOffset(%.2lf, %.2lf)", factor, units);
+ makeContextCurrent();
+ glPolygonOffset((GLfloat)factor, (GLfloat)units);
+}
+
+void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, void* data)
+{
+ LOGWEBGL("glReadPixels(%ld, %ld, %lu, %lu, %lu, %lu, %p)",
+ x, y, width, height, format, type, data);
+ makeContextCurrent();
+ glReadPixels(x, y, width, height, format, type, data);
+}
+
+void GraphicsContext3D::releaseShaderCompiler()
+{
+ LOGWEBGL("glReleaseShaderCompiler()");
+ makeContextCurrent();
+ glReleaseShaderCompiler();
+}
+
+void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("glRenderbufferStorage(%lu, %lu, %lu, %lu)",
+ target, internalformat, width, height);
+ makeContextCurrent();
+ glRenderbufferStorage(target, internalformat, width, height);
+}
+
+void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
+{
+ LOGWEBGL("glSampleCoverage(%.2lf, %s)", value, invert ? "true" : "false");
+ makeContextCurrent();
+ glSampleCoverage(CLAMP(value), invert);
+}
+
+void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("glScissor(%ld, %ld, %lu, %lu)", x, y, width, height);
+ makeContextCurrent();
+ glScissor(x, y, width, height);
+}
+
+void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& source)
+{
+ LOGWEBGL("shaderSource(%lu, %s)", shader, source.utf8().data());
+ makeContextCurrent();
+ m_internal->shaderSource(shader, source);
+}
+
+void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ LOGWEBGL("glStencilFunc(%lu, %ld, %lu)", func, ref, mask);
+ makeContextCurrent();
+ glStencilFunc(func, ref, mask);
+}
+
+void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
+{
+ LOGWEBGL("glStencilFuncSeparate(%lu, %lu, %ld, %lu)", face, func, ref, mask);
+ makeContextCurrent();
+ glStencilFuncSeparate(face, func, ref, mask);
+}
+
+void GraphicsContext3D::stencilMask(GC3Duint mask)
+{
+ LOGWEBGL("glStencilMask(%lu)", mask);
+ makeContextCurrent();
+ glStencilMask(mask);
+}
+
+void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
+{
+ LOGWEBGL("glStencilMaskSeparate(%lu, %lu)", face, mask);
+ makeContextCurrent();
+ glStencilMaskSeparate(face, mask);
+}
+
+void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
+{
+ LOGWEBGL("glStencilOp(%lu, %lu, %lu)", fail, zfail, zpass);
+ makeContextCurrent();
+ glStencilOp(fail, zfail, zpass);
+}
+
+void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail,
+ GC3Denum zfail, GC3Denum zpass)
+{
+ LOGWEBGL("glStencilOpSeparate(%lu, %lu, %lu, %lu)", face, fail, zfail, zpass);
+ makeContextCurrent();
+ glStencilOpSeparate(face, fail, zfail, zpass);
+}
+
+bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type, const void* pixels)
+{
+ LOGWEBGL("glTexImage2D(%u, %u, %u, %u, %u, %u, %u, %u, %p)",
+ target, level, internalformat, width, height, border, format, type, pixels);
+ if (width && height && !pixels) {
+ synthesizeGLError(INVALID_VALUE);
+ return false;
+ }
+ makeContextCurrent();
+ glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ return true;
+}
+
+void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
+{
+ LOGWEBGL("glTexParameterf(%u, %u, %f)", target, pname, param);
+ makeContextCurrent();
+ glTexParameterf(target, pname, param);
+}
+
+void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
+{
+ LOGWEBGL("glTexParameteri(%u, %u, %d)", target, pname, param);
+ makeContextCurrent();
+ glTexParameteri(target, pname, param);
+}
+
+void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset,
+ GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, const void* pixels)
+{
+ LOGWEBGL("glTexSubImage2D(%u, %u, %u, %u, %u, %u, %u, %u, %p)", target, level, xoffset,
+ yoffset, width, height, format, type, pixels);
+ if (width && height && !pixels) {
+ synthesizeGLError(INVALID_VALUE);
+ return;
+ }
+ makeContextCurrent();
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat x)
+{
+ LOGWEBGL("glUniform1f(%ld, %f)", location, x);
+ makeContextCurrent();
+ glUniform1f(location, x);
+}
+
+void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform1fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform1fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint x)
+{
+ LOGWEBGL("glUniform1i(%ld, %d)", location, x);
+ makeContextCurrent();
+ glUniform1i(location, x);
+}
+
+void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform1iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform1iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat x, float y)
+{
+ LOGWEBGL("glUniform2f(%ld, %f, %f)", location, x, y);
+ makeContextCurrent();
+ glUniform2f(location, x, y);
+}
+
+void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform2fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform2fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint x, GC3Dint y)
+{
+ LOGWEBGL("glUniform2i(%ld, %d, %d)", location, x, y);
+ makeContextCurrent();
+ glUniform2i(location, x, y);
+}
+
+void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform2iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform2iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
+{
+ LOGWEBGL("glUniform3f(%ld, %f, %f, %f)", location, x, y, z);
+ makeContextCurrent();
+ glUniform3f(location, x, y, z);
+}
+
+void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform3fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform3fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z)
+{
+ LOGWEBGL("glUniform3i(%ld, %d, %d, %d)", location, x, y, z);
+ makeContextCurrent();
+ glUniform3i(location, x, y, z);
+}
+
+void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform3iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform3iv(location, size, v);
+}
+
+void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y,
+ GC3Dfloat z, GC3Dfloat w)
+{
+ LOGWEBGL("glUniform4f(%ld, %f, %f, %f, %f)", location, x, y, z, w);
+ makeContextCurrent();
+ glUniform4f(location, x, y, z, w);
+}
+
+void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dfloat* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform4fv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform4fv(location, size, v);
+}
+
+void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
+{
+ LOGWEBGL("glUniform4i(%ld, %d, %d, %d, %d)", location, x, y, z, w);
+ makeContextCurrent();
+ glUniform4i(location, x, y, z, w);
+}
+
+void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dint* v, GC3Dsizei size)
+{
+ LOGWEBGL("glUniform4iv(%ld, %p, %d)", location, v, size);
+ makeContextCurrent();
+ glUniform4iv(location, size, v);
+}
+
+void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix2fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix2fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix3fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix3fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dboolean transpose,
+ GC3Dfloat* value, GC3Dsizei size)
+{
+ LOGWEBGL("glUniformMatrix4fv(%ld, %s, %p, %d)",
+ location, transpose ? "true" : "false", value, size);
+ makeContextCurrent();
+ glUniformMatrix4fv(location, size, transpose, value);
+}
+
+void GraphicsContext3D::useProgram(Platform3DObject program)
+{
+ LOGWEBGL("glUseProgram(%lu)", program);
+ makeContextCurrent();
+ glUseProgram(program);
+}
+
+void GraphicsContext3D::validateProgram(Platform3DObject program)
+{
+ LOGWEBGL("glValidateProgram(%lu)", program);
+ makeContextCurrent();
+ glValidateProgram(program);
+}
+
+void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat x)
+{
+ LOGWEBGL("glVertexAttrib1f(%lu, %f)", index, x);
+ makeContextCurrent();
+ glVertexAttrib1f(index, x);
+}
+
+void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib1fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib1fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y)
+{
+ LOGWEBGL("glVertexAttrib2f(%lu, %f, %f)", index, x, y);
+ makeContextCurrent();
+ glVertexAttrib2f(index, x, y);
+}
+
+void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib2fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib2fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
+{
+ LOGWEBGL("glVertexAttrib3f(%lu, %f, %f, %f)", index, x, y, z);
+ makeContextCurrent();
+ glVertexAttrib3f(index, x, y, z);
+}
+
+void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib3fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib3fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y,
+ GC3Dfloat z, GC3Dfloat w)
+{
+ LOGWEBGL("glVertexAttrib4f(%lu, %f, %f, %f, %f)", index, x, y, z, w);
+ makeContextCurrent();
+ glVertexAttrib4f(index, x, y, z, w);
+}
+
+void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* values)
+{
+ LOGWEBGL("glVertexAttrib4fv(%lu, %p)", index, values);
+ makeContextCurrent();
+ glVertexAttrib4fv(index, values);
+}
+
+void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type,
+ GC3Dboolean normalized, GC3Dsizei stride,
+ GC3Dintptr offset)
+{
+ LOGWEBGL("glVertexAttribPointer(%lu, %d, %d, %s, %lu, %lu)", index, size, type,
+ normalized ? "true" : "false", stride, offset);
+ makeContextCurrent();
+ glVertexAttribPointer(index, size, type, normalized, stride,
+ reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
+{
+ LOGWEBGL("viewport(%ld, %ld, %lu, %lu)", x, y, width, height);
+ makeContextCurrent();
+ m_internal->viewport(x, y, width, height);
+}
+
+void GraphicsContext3D::reshape(int width, int height)
+{
+ LOGWEBGL("reshape(%d, %d)", width, height);
+ if ((width == m_currentWidth) && (height == m_currentHeight)) {
+ return;
+ }
+ m_internal->reshape(width, height);
+ m_currentWidth = m_internal->width();
+ m_currentHeight = m_internal->height();
+}
+
+void GraphicsContext3D::recreateSurface()
+{
+ LOGWEBGL("recreateSurface()");
+ m_internal->recreateSurface();
+}
+
+void GraphicsContext3D::releaseSurface()
+{
+ LOGWEBGL("releaseSurface()");
+ m_internal->releaseSurface();
+}
+
+IntSize GraphicsContext3D::getInternalFramebufferSize()
+{
+ return IntSize(m_currentWidth, m_currentHeight);
+}
+
+void GraphicsContext3D::markContextChanged()
+{
+ LOGWEBGL("markContextChanged()");
+ m_internal->markContextChanged();
+}
+
+void GraphicsContext3D::markLayerComposited()
+{
+ LOGWEBGL("markLayerComposited()");
+ m_internal->markLayerComposited();
+}
+
+bool GraphicsContext3D::layerComposited() const
+{
+ LOGWEBGL("layerComposited()");
+ return m_internal->layerComposited();
+}
+
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+{
+}
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp
new file mode 100644
index 0000000..7855739
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.cpp
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#include "GraphicsContext3DInternal.h"
+
+#include "CurrentTime.h"
+#include "Frame.h"
+#include "HostWindow.h"
+#include "HTMLCanvasElement.h"
+#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "PlatformGraphicsContext.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include "RenderObject.h"
+#include "TilesManager.h"
+#include "TransformationMatrix.h"
+#include "WebViewCore.h"
+
+#include "SkBitmap.h"
+#include "SkDevice.h"
+#include <binder/IBinder.h>
+#include <hardware/hardware.h>
+#include <private/gui/ComposerService.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <JNIUtility.h>
+
+#if ENABLE(WEBGL)
+namespace WebCore {
+
+class WebGLFPSTimer {
+public:
+ WebGLFPSTimer()
+ : m_ticks(0)
+ {
+ m_startTime = currentTime();
+ }
+
+ void tick()
+ {
+ if (++m_ticks == s_sampleRate)
+ reset();
+ }
+
+ void reset()
+ {
+ double totalTime = currentTime() - m_startTime;
+ if (totalTime > 0) {
+ double averageFPS = m_ticks / totalTime;
+ LOGWEBGL("Average FPS: %0.3f", averageFPS);
+ }
+
+ m_ticks = 0;
+ m_startTime = currentTime();
+ }
+
+private:
+ long m_ticks;
+ double m_startTime;
+
+ static const int s_sampleRate;
+};
+
+const int WebGLFPSTimer::s_sampleRate = 15;
+
+#define OLD_GRAPHICBUFFER_ALLOC
+class FBO {
+public:
+ static FBO* createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attrs);
+ ~FBO();
+
+ EGLSyncKHR sync() { return m_sync; }
+ void setSync(EGLSyncKHR sync) { m_sync = sync; }
+
+ GLuint fbo() { return m_fbo; }
+ EGLImageKHR image() { return m_image; }
+
+ bool isLocked() { return m_locked; }
+ void setLocked(bool locked) { m_locked = locked; }
+
+ bool lockGraphicBuffer(void** ptr) {
+ return (m_grBuffer.get() &&
+ (m_grBuffer->lock(GraphicBuffer::USAGE_SW_READ_RARELY, ptr) == NO_ERROR));
+ }
+ void unlockGraphicBuffer() {
+ if (m_grBuffer.get())
+ m_grBuffer->unlock();
+ }
+
+ int bytesPerRow() { return m_grBuffer.get() ? m_grBuffer->getStride() * 4 : 0; }
+
+private:
+ FBO(EGLDisplay dpy);
+ bool init(int width, int height, GraphicsContext3D::Attributes attrs);
+
+ GLuint createTexture(EGLImageKHR image, int width, int height);
+
+ EGLDisplay m_dpy;
+ GLuint m_texture;
+ GLuint m_fbo;
+ GLuint m_depthBuffer;
+ GLuint m_stencilBuffer;
+ EGLImageKHR m_image;
+ EGLSyncKHR m_sync;
+ sp<IGraphicBufferAlloc> m_graphicBufferAlloc;
+ sp<GraphicBuffer> m_grBuffer;
+ bool m_locked;
+};
+
+
+#define CANVAS_MAX_WIDTH 1280
+#define CANVAS_MAX_HEIGHT 1280
+
+bool GraphicsContext3DInternal::s_loggingEnabled = false;
+
+EGLint GraphicsContext3DInternal::checkEGLError(const char* s)
+{
+ EGLint error = eglGetError();
+ if (error == EGL_SUCCESS) {
+ LOGWEBGL("%s() OK", s);
+ }
+ else {
+ LOGWEBGL("after %s() eglError = 0x%x", s, error);
+ }
+
+ return error;
+}
+
+GLint GraphicsContext3DInternal::checkGLError(const char* s)
+{
+ GLint error = glGetError();
+ if (error == GL_NO_ERROR) {
+ LOGWEBGL("%s() OK", s);
+ }
+ else {
+ LOGWEBGL("after %s() glError (0x%x)", s, error);
+ }
+
+ return error;
+}
+
+GraphicsContext3DInternal::GraphicsContext3DInternal(HTMLCanvasElement* canvas,
+ GraphicsContext3D::Attributes attrs,
+ HostWindow* hostWindow)
+ : m_proxy(adoptRef(new GraphicsContext3DProxy()))
+ , m_compositingLayer(new WebGLLayer(m_proxy))
+ , m_canvas(canvas)
+ , m_attrs(attrs)
+ , m_layerComposited(false)
+ , m_canvasDirty(false)
+ , m_width(1)
+ , m_height(1)
+ , m_maxwidth(CANVAS_MAX_WIDTH)
+ , m_maxheight(CANVAS_MAX_HEIGHT)
+ , m_dpy(EGL_NO_DISPLAY)
+ , m_config(0)
+ , m_surface(EGL_NO_SURFACE)
+ , m_context(EGL_NO_CONTEXT)
+ , m_syncThread(0)
+ , m_threadState(THREAD_STATE_STOPPED)
+ , m_syncTimer(this, &GraphicsContext3DInternal::syncTimerFired)
+ , m_syncRequested(false)
+ , m_webGLFPSTimer(0)
+ , m_extensions(0)
+ , m_contextId(0)
+{
+ enableLogging();
+
+ //Need to initialize to a NULL state so that if you FBO creation fails later on, its in a valid state during destruction
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ m_fbo[i] = NULL;
+ }
+
+ LOGWEBGL("GraphicsContext3DInternal() = %p, m_compositingLayer = %p", this, m_compositingLayer);
+ m_proxy->setGraphicsContext(this);
+
+ if (!m_canvas || !m_canvas->document() || !m_canvas->document()->view())
+ return;
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ WebViewCore* core = WebViewCore::getWebViewCore(m_canvas->document()->view());
+ if (!core)
+ return;
+ jobject tmp = core->getWebViewJavaObject();
+ m_webView = env->NewGlobalRef(tmp);
+ if (!m_webView)
+ return;
+ jclass webViewClass = env->GetObjectClass(m_webView);
+ m_postInvalidate = env->GetMethodID(webViewClass, "postInvalidate", "()V");
+ env->DeleteLocalRef(webViewClass);
+ if (!m_postInvalidate)
+ return;
+
+ if (!initEGL())
+ return;
+
+ if (!createContext(true)) {
+ LOGWEBGL("Create context failed. Perform JS garbage collection and try again.");
+ // Probably too many contexts. Force a JS garbage collection, and then try again.
+ // This typically only happens in Khronos Conformance tests.
+ m_canvas->document()->frame()->script()->lowMemoryNotification();
+ if (!createContext(true)) {
+ LOGWEBGL("Create context still failed: aborting.");
+ return;
+ }
+ }
+
+ m_webGLFPSTimer.set(new WebGLFPSTimer());
+
+ const char *ext = (const char *)glGetString(GL_EXTENSIONS);
+ LOGWEBGL("GL_EXTENSIONS = %s", ext);
+ // Want to keep control of which extensions are used
+ String extensions = "";
+ if (strstr(ext, "GL_OES_texture_npot"))
+ extensions.append("GL_OES_texture_npot");
+ if (strstr(ext, "GL_OES_packed_depth_stencil"))
+ extensions.append(" GL_OES_packed_depth_stencil");
+ if (strstr(ext, "GL_OES_texture_float"))
+ extensions.append(" GL_OES_texture_float");
+ m_extensions.set(new Extensions3DAndroid(extensions));
+
+ // ANGLE initialization.
+ ShBuiltInResources resources;
+ ShInitBuiltInResources(&resources);
+
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs);
+ glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors);
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &resources.MaxVaryingVectors);
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &resources.MaxVertexTextureImageUnits);
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &resources.MaxCombinedTextureImageUnits);
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits);
+ glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &resources.MaxFragmentUniformVectors);
+
+ resources.MaxDrawBuffers = 1;
+ m_compiler.setResources(resources);
+
+ m_savedViewport.x = 0;
+ m_savedViewport.y = 0;
+ m_savedViewport.width = m_width;
+ m_savedViewport.height = m_height;
+
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ startSyncThread();
+
+ static int contextCounter = 1;
+ m_contextId = contextCounter++;
+}
+
+GraphicsContext3DInternal::~GraphicsContext3DInternal()
+{
+ LOGWEBGL("~GraphicsContext3DInternal(), this = %p", this);
+
+ stopSyncThread();
+
+ m_proxy->setGraphicsContext(0);
+ MutexLocker lock(m_fboMutex);
+ SkSafeUnref(m_compositingLayer);
+ m_compositingLayer = 0;
+ deleteContext(true);
+
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteGlobalRef(m_webView);
+}
+
+bool GraphicsContext3DInternal::initEGL()
+{
+ m_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_dpy == EGL_NO_DISPLAY)
+ return false;
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLBoolean returnValue = eglInitialize(m_dpy, &majorVersion, &minorVersion);
+ if (returnValue != EGL_TRUE)
+ return false;
+
+ LOGWEBGL("EGL version %d.%d", majorVersion, minorVersion);
+ const char *s = eglQueryString(m_dpy, EGL_VENDOR);
+ LOGWEBGL("EGL_VENDOR = %s", s);
+ s = eglQueryString(m_dpy, EGL_VERSION);
+ LOGWEBGL("EGL_VERSION = %s", s);
+ s = eglQueryString(m_dpy, EGL_EXTENSIONS);
+ LOGWEBGL("EGL_EXTENSIONS = %s", s);
+ s = eglQueryString(m_dpy, EGL_CLIENT_APIS);
+ LOGWEBGL("EGL_CLIENT_APIS = %s", s);
+
+ EGLint config_attribs[21];
+ int p = 0;
+ config_attribs[p++] = EGL_BLUE_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_GREEN_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_RED_SIZE;
+ config_attribs[p++] = 8;
+ config_attribs[p++] = EGL_SURFACE_TYPE;
+ config_attribs[p++] = EGL_PBUFFER_BIT;
+ config_attribs[p++] = EGL_RENDERABLE_TYPE;
+ config_attribs[p++] = EGL_OPENGL_ES2_BIT;
+ config_attribs[p++] = EGL_ALPHA_SIZE;
+ config_attribs[p++] = m_attrs.alpha ? 8 : 0;
+ if (m_attrs.depth) {
+ config_attribs[p++] = EGL_DEPTH_SIZE;
+ config_attribs[p++] = 16;
+ }
+ if (m_attrs.stencil) {
+ config_attribs[p++] = EGL_STENCIL_SIZE;
+ config_attribs[p++] = 8;
+ }
+ // Antialiasing currently is not supported.
+ m_attrs.antialias = false;
+ config_attribs[p] = EGL_NONE;
+
+ EGLint num_configs = 0;
+ return (eglChooseConfig(m_dpy, config_attribs, &m_config, 1, &num_configs) == EGL_TRUE);
+}
+
+bool GraphicsContext3DInternal::createContext(bool createEGLContext)
+{
+ LOGWEBGL("createContext()");
+ EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE};
+
+ if (createEGLContext) {
+ EGLint surface_attribs[] = {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_NONE};
+ m_surface = eglCreatePbufferSurface(m_dpy, m_config, surface_attribs);
+ m_context = eglCreateContext(m_dpy, m_config, EGL_NO_CONTEXT, context_attribs);
+ }
+ if (m_context == EGL_NO_CONTEXT) {
+ deleteContext(createEGLContext);
+ return false;
+ }
+
+ makeContextCurrent();
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ FBO* tmp = FBO::createFBO(m_dpy, m_width > 0 ? m_width : 1, m_height > 0 ? m_height : 1, m_attrs);
+ if (tmp == 0) {
+ LOGWEBGL("Failed to create FBO");
+ deleteContext(createEGLContext);
+ return false;
+ }
+ m_fbo[i] = tmp;
+ m_freeBuffers.append(tmp);
+ }
+
+ m_currentFBO = dequeueBuffer();
+ m_boundFBO = m_currentFBO->fbo();
+ m_frontFBO = 0;
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+
+ return true;
+}
+
+void GraphicsContext3DInternal::deleteContext(bool deleteEGLContext)
+{
+ LOGWEBGL("deleteContext(%s)", deleteEGLContext ? "true" : "false");
+
+ makeContextCurrent();
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ m_freeBuffers.clear();
+ m_queuedBuffers.clear();
+ m_preparedBuffers.clear();
+ for (int i = 0; i < NUM_BUFFERS; i++) {
+ if (m_fbo[i]) {
+ delete m_fbo[i];
+ m_fbo[i] = 0;
+ }
+ }
+ m_currentFBO = 0;
+ m_frontFBO = 0;
+
+ eglMakeCurrent(m_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (deleteEGLContext) {
+ if (m_surface != EGL_NO_SURFACE) {
+ eglDestroySurface(m_dpy, m_surface);
+ m_surface = EGL_NO_SURFACE;
+ }
+ if (m_context != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_dpy, m_context);
+ m_context = EGL_NO_CONTEXT;
+ }
+ }
+}
+
+void GraphicsContext3DInternal::makeContextCurrent()
+{
+ if (eglGetCurrentContext() != m_context && m_context != EGL_NO_CONTEXT) {
+ eglMakeCurrent(m_dpy, m_surface, m_surface, m_context);
+ }
+}
+
+GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes()
+{
+ return m_attrs;
+}
+
+unsigned long GraphicsContext3DInternal::getError()
+{
+ if (m_syntheticErrors.size() > 0) {
+ ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin();
+ unsigned long err = *iter;
+ m_syntheticErrors.remove(iter);
+ return err;
+ }
+ LOGWEBGL("glGetError()");
+ makeContextCurrent();
+ return glGetError();
+}
+
+void GraphicsContext3DInternal::synthesizeGLError(unsigned long error)
+{
+ m_syntheticErrors.add(error);
+}
+
+FBO* FBO::createFBO(EGLDisplay dpy, int width, int height, GraphicsContext3D::Attributes attributes)
+{
+ LOGWEBGL("createFBO()");
+ FBO* fbo = new FBO(dpy);
+
+ if (!fbo->init(width, height, attributes)) {
+ delete fbo;
+ return 0;
+ }
+ return fbo;
+}
+
+FBO::FBO(EGLDisplay dpy)
+ : m_dpy(dpy)
+ , m_texture(0)
+ , m_fbo(0)
+ , m_depthBuffer(0)
+ , m_image(0)
+ , m_sync(0)
+ , m_grBuffer(0)
+ , m_locked(false)
+{
+}
+
+bool FBO::init(int width, int height, GraphicsContext3D::Attributes attributes)
+{
+ // 1. Allocate a graphic buffer
+ sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+ m_graphicBufferAlloc = composer->createGraphicBufferAlloc();
+
+ status_t error;
+
+ PixelFormat format = attributes.alpha ? HAL_PIXEL_FORMAT_RGBA_8888 : HAL_PIXEL_FORMAT_RGBX_8888;
+
+ m_grBuffer = m_graphicBufferAlloc->createGraphicBuffer(width, height, format,
+ GRALLOC_USAGE_HW_TEXTURE, &error);
+ if (error != NO_ERROR) {
+ LOGWEBGL(" failed to allocate GraphicBuffer, error = %d", error);
+ return false;
+ }
+
+ void *addr = 0;
+ if (m_grBuffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, &addr) != NO_ERROR) {
+ LOGWEBGL(" failed to lock the GraphicBuffer");
+ return false;
+ }
+ // WebGL requires all buffers to be initialized to 0.
+ memset(addr, 0, width * height * 4);
+ m_grBuffer->unlock();
+
+ ANativeWindowBuffer* clientBuf = m_grBuffer->getNativeBuffer();
+ if (clientBuf->handle == 0) {
+ LOGWEBGL(" empty handle in GraphicBuffer");
+ return false;
+ }
+
+ // 2. Create an EGLImage from the graphic buffer
+ const EGLint attrs[] = {
+ EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE, EGL_NONE
+ };
+
+ m_image = eglCreateImageKHR(m_dpy,
+ EGL_NO_CONTEXT,
+ EGL_NATIVE_BUFFER_ANDROID,
+ (EGLClientBuffer)clientBuf,
+ attrs);
+ if (GraphicsContext3DInternal::checkEGLError("eglCreateImageKHR") != EGL_SUCCESS) {
+ LOGWEBGL("eglCreateImageKHR() failed");
+ return false;
+ }
+
+ // 3. Create a texture from the EGLImage
+ m_texture = createTexture(m_image, width, height);
+ if (m_texture == 0) {
+ LOGWEBGL("createTexture() failed");
+ return false;
+ }
+
+ // 4. Create the Framebuffer Object from the texture
+ glGenFramebuffers(1, &m_fbo);
+
+ if (attributes.depth) {
+ glGenRenderbuffers(1, &m_depthBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
+ if (GraphicsContext3DInternal::checkGLError("glRenderbufferStorage") != GL_NO_ERROR)
+ return false;
+ }
+
+ if (attributes.stencil) {
+ glGenRenderbuffers(1, &m_stencilBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
+ if (GraphicsContext3DInternal::checkGLError("glRenderbufferStorage") != GL_NO_ERROR)
+ return false;
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferTexture2D") != GL_NO_ERROR)
+ return false;
+
+ if (attributes.depth) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferRenderbuffer") != GL_NO_ERROR)
+ return false;
+ }
+
+ if (attributes.stencil) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
+ if (GraphicsContext3DInternal::checkGLError("glFramebufferRenderbuffer") != GL_NO_ERROR)
+ return false;
+ }
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOGWEBGL("Framebuffer incomplete: %d", status);
+ return false;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return true;
+}
+
+FBO::~FBO()
+{
+ LOGWEBGL("FBO::~FBO()");
+ if (m_image) {
+ eglDestroyImageKHR(m_dpy, m_image);
+ GraphicsContext3DInternal::checkEGLError("eglDestroyImageKHR");
+ }
+ if (m_texture)
+ glDeleteTextures(1, &m_texture);
+ if (m_depthBuffer)
+ glDeleteRenderbuffers(1, &m_depthBuffer);
+ if (m_stencilBuffer)
+ glDeleteRenderbuffers(1, &m_stencilBuffer);
+ if (m_fbo)
+ glDeleteFramebuffers(1, &m_fbo);
+}
+
+GLuint FBO::createTexture(EGLImageKHR image, int width, int height)
+{
+ LOGWEBGL("createTexture(image = %p)", image);
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ bool error = false;
+ if (image) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+ error = (GraphicsContext3DInternal::checkGLError("glEGLImageTargetTexture2DOES")
+ != GL_NO_ERROR);
+ }
+ else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ error = (GraphicsContext3DInternal::checkGLError("glTexImage2D()") != GL_NO_ERROR);
+ }
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if (error) {
+ glDeleteTextures(1, &texture);
+ texture = 0;
+ }
+
+ return texture;
+}
+
+void GraphicsContext3DInternal::startSyncThread()
+{
+ LOGWEBGL("+startSyncThread()");
+ MutexLocker lock(m_threadMutex);
+ m_threadState = THREAD_STATE_STOPPED;
+ m_syncThread = createThread(syncThreadStart, this, "GraphicsContext3DInternal");
+ // Wait for thread to start
+ while (m_threadState != THREAD_STATE_RUN) {
+ m_threadCondition.wait(m_threadMutex);
+ }
+ LOGWEBGL("-startSyncThread()");
+}
+
+void GraphicsContext3DInternal::stopSyncThread()
+{
+ LOGWEBGL("+stopSyncThread()");
+ MutexLocker lock(m_threadMutex);
+ if (m_syncThread) {
+ m_threadState = THREAD_STATE_STOP;
+ // Signal thread to wake up
+ m_threadCondition.broadcast();
+ // Wait for thread to stop
+ while (m_threadState != THREAD_STATE_STOPPED) {
+ m_threadCondition.wait(m_threadMutex);
+ }
+ m_syncThread = 0;
+ }
+ LOGWEBGL("-stopSyncThread()");
+}
+
+void* GraphicsContext3DInternal::syncThreadStart(void* ctx)
+{
+ GraphicsContext3DInternal* context = static_cast<GraphicsContext3DInternal*>(ctx);
+ context->runSyncThread();
+
+ return 0;
+}
+
+void GraphicsContext3DInternal::runSyncThread()
+{
+ LOGWEBGL("SyncThread: starting");
+ FBO* fbo = 0;
+
+ MutexLocker lock(m_threadMutex);
+ m_threadState = THREAD_STATE_RUN;
+ // Signal to creator that we are up and running
+ m_threadCondition.broadcast();
+
+ while (m_threadState == THREAD_STATE_RUN) {
+ while (m_threadState == THREAD_STATE_RUN) {
+ {
+ MutexLocker lock(m_fboMutex);
+ if (!m_queuedBuffers.isEmpty()) {
+ fbo = m_queuedBuffers.takeFirst();
+ break;
+ }
+ }
+ m_threadCondition.wait(m_threadMutex);
+ }
+ LOGWEBGL("SyncThread: woke after waiting for FBO, fbo = %p", fbo);
+ if (m_threadState != THREAD_STATE_RUN)
+ break;
+
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglClientWaitSyncKHR(m_dpy, fbo->sync(), 0, 0);
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ fbo->setSync(EGL_NO_SYNC_KHR);
+ LOGWEBGL("SyncThread: returned after waiting for Sync");
+ }
+
+ {
+ MutexLocker lock(m_fboMutex);
+ m_preparedBuffers.append(fbo);
+ LOGWEBGL("SyncThread: prepared buffer = %p", fbo);
+ updateFrontBuffer();
+ }
+
+ // Invalidate the canvas region
+ if (m_postInvalidate) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_webView, m_postInvalidate);
+ }
+ }
+
+ // Signal to calling thread that we have stopped
+ m_threadState = THREAD_STATE_STOPPED;
+ m_threadCondition.broadcast();
+ LOGWEBGL("SyncThread: terminating");
+}
+
+PlatformLayer* GraphicsContext3DInternal::platformLayer() const
+{
+ LOGWEBGL("platformLayer()");
+ return m_compositingLayer;
+}
+
+void GraphicsContext3DInternal::reshape(int width, int height)
+{
+ LOGWEBGL("reshape(%d, %d)", width, height);
+ bool mustRestoreFBO = (m_boundFBO != (m_currentFBO ? m_currentFBO->fbo() : 0));
+
+ m_width = width > m_maxwidth ? m_maxwidth : width;
+ m_height = height > m_maxheight ? m_maxheight : height;
+
+ stopSyncThread();
+ makeContextCurrent();
+ m_proxy->setGraphicsContext(0);
+ {
+ MutexLocker lock(m_fboMutex);
+ deleteContext(false);
+
+ if (createContext(false)) {
+ if (!mustRestoreFBO) {
+ m_boundFBO = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+ }
+ }
+ m_proxy->setGraphicsContext(this);
+ startSyncThread();
+}
+
+void GraphicsContext3DInternal::recreateSurface()
+{
+ LOGWEBGL("recreateSurface()");
+ if (m_currentFBO != 0)
+ // We already have a current surface
+ return;
+ reshape(m_width, m_height);
+ glViewport(m_savedViewport.x, m_savedViewport.y, m_savedViewport.width, m_savedViewport.height);
+}
+
+void GraphicsContext3DInternal::releaseSurface()
+{
+ LOGWEBGL("releaseSurface(%d)", m_contextId);
+ if (m_currentFBO == 0)
+ // We don't have any current surface
+ return;
+ stopSyncThread();
+ m_proxy->setGraphicsContext(0);
+ {
+ MutexLocker lock(m_fboMutex);
+ deleteContext(false);
+ }
+ makeContextCurrent();
+ m_proxy->setGraphicsContext(this);
+}
+
+void GraphicsContext3DInternal::syncTimerFired(Timer<GraphicsContext3DInternal>*)
+{
+ m_syncRequested = false;
+
+ // Do not perform the composition step if it is an offscreen canvas
+ if (m_canvas->renderer())
+ swapBuffers();
+}
+
+void GraphicsContext3DInternal::markContextChanged()
+{
+ if (!m_syncRequested) {
+ m_syncTimer.startOneShot(0);
+ m_syncRequested = true;
+ }
+ m_canvasDirty = true;
+ m_layerComposited = false;
+}
+
+/*
+ * Must hold m_fboMutex when calling this function.
+ */
+FBO* GraphicsContext3DInternal::dequeueBuffer()
+{
+ LOGWEBGL("GraphicsContext3DInternal::dequeueBuffer()");
+ while (m_freeBuffers.isEmpty()) {
+ m_fboCondition.wait(m_fboMutex);
+ }
+ FBO* fbo = m_freeBuffers.takeFirst();
+
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglClientWaitSyncKHR(m_dpy, fbo->sync(), 0, 0);
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ fbo->setSync(EGL_NO_SYNC_KHR);
+ }
+
+ return fbo;
+}
+
+void GraphicsContext3DInternal::swapBuffers()
+{
+ if (s_loggingEnabled)
+ m_webGLFPSTimer->tick();
+
+ LOGWEBGL("+swapBuffers()");
+
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_currentFBO;
+ if (fbo == 0)
+ return;
+
+ makeContextCurrent();
+
+ bool mustRestoreFBO = (m_boundFBO != fbo->fbo());
+ if (mustRestoreFBO) {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo());
+ }
+
+ // Create the fence sync and notify the sync thread
+ fbo->setSync(eglCreateSyncKHR(m_dpy, EGL_SYNC_FENCE_KHR, 0));
+ glFlush();
+ m_queuedBuffers.append(fbo);
+ m_threadCondition.broadcast();
+
+ // Dequeue a new buffer
+ fbo = dequeueBuffer();
+ m_currentFBO = fbo;
+
+ if (!mustRestoreFBO) {
+ m_boundFBO = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, m_boundFBO);
+ m_canvasDirty = false;
+ m_layerComposited = true;
+ LOGWEBGL("-swapBuffers()");
+}
+
+void GraphicsContext3DInternal::updateFrontBuffer()
+{
+ if (!m_preparedBuffers.isEmpty()) {
+ if (m_frontFBO == 0) {
+ m_frontFBO = m_preparedBuffers.takeFirst();
+ }
+ else if (!m_frontFBO->isLocked()) {
+ m_freeBuffers.append(m_frontFBO);
+ m_frontFBO = m_preparedBuffers.takeFirst();
+ m_fboCondition.broadcast();
+ }
+ }
+}
+
+bool GraphicsContext3DInternal::lockFrontBuffer(EGLImageKHR& image, SkRect& rect)
+{
+ LOGWEBGL("GraphicsContext3DInternal::lockFrontBuffer()");
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_frontFBO;
+
+ if (!fbo || !fbo->image()) {
+ LOGWEBGL("-GraphicsContext3DInternal::lockFrontBuffer(), fbo = %p", fbo);
+ return false;
+ }
+
+ fbo->setLocked(true);
+ image = fbo->image();
+
+ RenderObject* renderer = m_canvas->renderer();
+ if (renderer && renderer->isBox()) {
+ RenderBox* box = (RenderBox*)renderer;
+ rect.setXYWH(box->borderLeft() + box->paddingLeft(),
+ box->borderTop() + box->paddingTop(),
+ box->contentWidth(),
+ box->contentHeight());
+ }
+
+ return true;
+}
+
+void GraphicsContext3DInternal::releaseFrontBuffer()
+{
+ LOGWEBGL("GraphicsContext3DInternal::releaseFrontBuffer()");
+ MutexLocker lock(m_fboMutex);
+ FBO* fbo = m_frontFBO;
+
+ if (fbo) {
+ fbo->setLocked(false);
+ if (fbo->sync() != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(m_dpy, fbo->sync());
+ }
+ fbo->setSync(eglCreateSyncKHR(m_dpy, EGL_SYNC_FENCE_KHR, 0));
+ }
+ updateFrontBuffer();
+}
+
+void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+ LOGWEBGL("paintRenderingResultsToCanvas()");
+ ImageBuffer* imageBuffer = context->canvas()->buffer();
+ const SkBitmap& canvasBitmap =
+ imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false);
+ SkCanvas canvas(canvasBitmap);
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height);
+ bitmap.allocPixels();
+ unsigned char *pixels = static_cast<unsigned char*>(bitmap.getPixels());
+ glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ SkRect dstRect;
+ dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height());
+ canvas.drawBitmapRect(bitmap, 0, dstRect);
+}
+
+PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageData()
+{
+ LOGWEBGL("paintRenderingResultsToImageData()");
+
+ // Reading premultiplied alpha would involve unpremultiplying, which is lossy.
+ if (m_attrs.premultipliedAlpha)
+ return 0;
+
+ RefPtr<ImageData> imageData = ImageData::create(IntSize(m_width, m_height));
+ unsigned char* pixels = imageData->data()->data()->data();
+
+ glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ return imageData;
+}
+
+bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context)
+{
+ LOGWEBGL("paintCompositedResultsToCanvas()");
+ ImageBuffer* imageBuffer = context->canvas()->buffer();
+ const SkBitmap& canvasBitmap =
+ imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false);
+ SkCanvas canvas(canvasBitmap);
+
+ MutexLocker lock(m_fboMutex);
+
+ FBO* fbo = m_frontFBO;
+ if (!fbo)
+ return false;
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height, fbo->bytesPerRow());
+
+ unsigned char* bits = NULL;
+ if (fbo->lockGraphicBuffer((void**)&bits)) {
+ bitmap.setPixels(bits);
+
+ SkRect dstRect;
+ dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height());
+ canvas.save();
+ canvas.translate(0, SkIntToScalar(imageBuffer->size().height()));
+ canvas.scale(SK_Scalar1, -SK_Scalar1);
+ canvas.drawBitmapRect(bitmap, 0, dstRect);
+ canvas.restore();
+ bitmap.setPixels(0);
+ fbo->unlockGraphicBuffer();
+ }
+
+ return true;
+}
+
+void GraphicsContext3DInternal::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
+{
+ LOGWEBGL("glBindFrameBuffer(%d, %d)", target, buffer);
+ makeContextCurrent();
+ MutexLocker lock(m_fboMutex);
+ if (!buffer && m_currentFBO) {
+ buffer = m_currentFBO->fbo();
+ }
+ glBindFramebuffer(target, buffer);
+ m_boundFBO = buffer;
+}
+
+void GraphicsContext3DInternal::compileShader(Platform3DObject shader)
+{
+ LOGWEBGL("compileShader()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+ if (result == m_shaderSourceMap.end()) {
+ LOGWEBGL(" shader not found");
+ return;
+ }
+ ShaderSourceEntry& entry = result->second;
+
+ int shaderType;
+ glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);
+
+ ANGLEShaderType ast = shaderType == GL_VERTEX_SHADER ?
+ SHADER_TYPE_VERTEX : SHADER_TYPE_FRAGMENT;
+
+ String src;
+ String log;
+ bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), ast, src, log);
+
+ entry.log = log;
+ entry.isValid = isValid;
+
+ if (!isValid) {
+ LOGWEBGL(" shader validation failed");
+ return;
+ }
+ int len = entry.source.length();
+ CString cstr = entry.source.utf8();
+ const char* s = cstr.data();
+
+ LOGWEBGL("glShaderSource(%s)", cstr.data());
+ glShaderSource(shader, 1, &s, &len);
+
+ LOGWEBGL("glCompileShader()");
+ glCompileShader(shader);
+}
+
+String GraphicsContext3DInternal::getShaderInfoLog(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderInfoLog()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+ if (result == m_shaderSourceMap.end()) {
+ LOGWEBGL(" shader not found");
+ return "";
+ }
+
+ ShaderSourceEntry entry = result->second;
+
+ if (entry.isValid) {
+ LOGWEBGL(" validated shader, retrieve OpenGL log");
+ GLuint shaderID = shader;
+ GLint logLength;
+ glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
+ if (!logLength)
+ return "";
+
+ char* log = 0;
+ if ((log = (char *)fastMalloc(logLength * sizeof(char))) == 0)
+ return "";
+ GLsizei returnedLogLength;
+ glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log);
+ String res = String(log, returnedLogLength);
+ fastFree(log);
+
+ return res;
+ }
+ else {
+ LOGWEBGL(" non-validated shader, use ANGLE log");
+ return entry.log;
+ }
+}
+
+String GraphicsContext3DInternal::getShaderSource(Platform3DObject shader)
+{
+ LOGWEBGL("getShaderSource()");
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+ if (result == m_shaderSourceMap.end())
+ return "";
+
+ return result->second.source;
+}
+
+void GraphicsContext3DInternal::shaderSource(Platform3DObject shader, const String& string)
+{
+ LOGWEBGL("shaderSource()");
+ ShaderSourceEntry entry;
+
+ entry.source = string;
+
+ m_shaderSourceMap.set(shader, entry);
+}
+
+void GraphicsContext3DInternal::viewport(long x, long y, unsigned long width, unsigned long height)
+{
+ LOGWEBGL("glViewport(%d, %d, %d, %d)", x, y, width, height);
+ glViewport(x, y, width, height);
+ m_savedViewport.x = x;
+ m_savedViewport.y = y;
+ m_savedViewport.width = width;
+ m_savedViewport.height = height;
+}
+
+void GraphicsContext3DInternal::enableLogging()
+{
+ char value[PROPERTY_VALUE_MAX];
+ property_get("debug.webgl", value, "0");
+ s_loggingEnabled = atoi(value) ? true : false;
+}
+
+}
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h
new file mode 100644
index 0000000..513de49
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DInternal.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012, Sony Mobile Communications AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Sony Ericsson Mobile Communications AB nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsContext3DInternal_h
+#define GraphicsContext3D3DInternal_h
+
+#include "ANGLEWebKitBridge.h"
+#include "CanvasRenderingContext.h"
+#include "Extensions3DAndroid.h"
+#include "GraphicsContext3D.h"
+#include "HTMLCanvasElement.h"
+#include "SkRect.h"
+#include "Threading.h"
+#include "Timer.h"
+#include "TransformationMatrix.h"
+#include "WebGLLayer.h"
+
+#include <wtf/Deque.h>
+#include <wtf/RefPtr.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <ui/GraphicBuffer.h>
+
+// This can be increased to 3, for example, if that has a positive impact on performance.
+#define NUM_BUFFERS 2
+
+#include <cutils/properties.h>
+#include <cutils/log.h>
+
+#define LOGWEBGL(...) (GraphicsContext3DInternal::s_loggingEnabled ? \
+ (void)android_printLog(ANDROID_LOG_DEBUG, "WebGL", __VA_ARGS__) : (void)0)
+
+using namespace android;
+
+namespace WebCore {
+
+#define CLAMP(x) GraphicsContext3DInternal::clampValue(x)
+
+typedef enum {
+ THREAD_STATE_STOPPED,
+ THREAD_STATE_RUN,
+ THREAD_STATE_RESTART,
+ THREAD_STATE_STOP
+} thread_state_t;
+
+class WebGLFPSTimer;
+class GraphicsContext3DProxy;
+class FBO;
+
+class GraphicsContext3DInternal : public RefCounted<GraphicsContext3DInternal> {
+public:
+ GraphicsContext3DInternal(HTMLCanvasElement* canvas, GraphicsContext3D::Attributes attrs,
+ HostWindow* hostWindow);
+ ~GraphicsContext3DInternal();
+
+ bool isValid() { return m_contextId > 0; }
+
+ PlatformLayer* platformLayer() const;
+
+ void makeContextCurrent();
+ GraphicsContext3D::Attributes getContextAttributes();
+ void reshape(int width, int height);
+
+ unsigned long getError();
+ void synthesizeGLError(unsigned long error);
+
+ void recreateSurface();
+ void releaseSurface();
+
+ void markContextChanged();
+ void markLayerComposited() { m_layerComposited = true; }
+ bool layerComposited() const { return m_layerComposited; }
+
+ void updateFrontBuffer();
+ bool lockFrontBuffer(EGLImageKHR& image, SkRect& rect);
+ void releaseFrontBuffer();
+
+ void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
+ PassRefPtr<ImageData> paintRenderingResultsToImageData();
+ bool paintCompositedResultsToCanvas(CanvasRenderingContext* context);
+
+ // Shader handling, required since we validate shader source with ANGLE
+ void compileShader(Platform3DObject shader);
+ String getShaderInfoLog(Platform3DObject shader);
+ String getShaderSource(Platform3DObject shader);
+ void shaderSource(Platform3DObject shader, const String& string);
+
+ void viewport(long x, long y, unsigned long width, unsigned long height);
+
+ int width() { return m_width; }
+ int height() { return m_height; }
+
+ Extensions3D* getExtensions() { return m_extensions.get(); }
+
+ void bindFramebuffer(GC3Denum target, Platform3DObject buffer);
+
+ static GLclampf clampValue(GLclampf x) {
+ GLclampf tmp = x;
+ if (tmp < 0.0f)
+ tmp = 0.0f;
+ else if (tmp > 1.0f)
+ tmp = 1.0f;
+ return tmp;
+ }
+
+ static GLclampf clampValue(double d) {
+ GLclampf tmp = (GLclampf)d;
+ if (tmp < 0.0f)
+ tmp = 0.0f;
+ else if (tmp > 1.0f)
+ tmp = 1.0f;
+ return tmp;
+ }
+
+ static EGLint checkEGLError(const char* s);
+ static GLint checkGLError(const char* s);
+ static void enableLogging();
+ static bool s_loggingEnabled;
+
+private:
+ bool initEGL();
+ bool createContext(bool createEGLContext);
+ void deleteContext(bool deleteEGLContext);
+
+ RefPtr<GraphicsContext3DProxy> m_proxy;
+ WebGLLayer *m_compositingLayer;
+ HTMLCanvasElement* m_canvas;
+ GraphicsContext3D::Attributes m_attrs;
+ bool m_layerComposited;
+ bool m_canvasDirty;
+
+ int m_width;
+ int m_height;
+ int m_maxwidth;
+ int m_maxheight;
+
+ EGLDisplay m_dpy;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+ EGLContext m_context;
+
+ // Routines for FBOs
+ FBO* m_fbo[NUM_BUFFERS];
+ GLuint m_boundFBO;
+ FBO* m_currentFBO;
+ FBO* m_frontFBO;
+ Deque<FBO*> m_freeBuffers;
+ Deque<FBO*> m_queuedBuffers;
+ Deque<FBO*> m_preparedBuffers;
+ WTF::Mutex m_fboMutex;
+ WTF::ThreadCondition m_fboCondition;
+
+ void startSyncThread();
+ void stopSyncThread();
+ static void* syncThreadStart(void* ctx);
+ void runSyncThread();
+ ThreadIdentifier m_syncThread;
+ thread_state_t m_threadState;
+ WTF::Mutex m_threadMutex;
+ WTF::ThreadCondition m_threadCondition;
+
+ void syncTimerFired(Timer<GraphicsContext3DInternal>*);
+ FBO* dequeueBuffer();
+ void swapBuffers();
+ Timer<GraphicsContext3DInternal> m_syncTimer;
+ bool m_syncRequested;
+
+ OwnPtr<WebGLFPSTimer> m_webGLFPSTimer;
+
+ typedef struct {
+ String source;
+ String log;
+ bool isValid;
+ } ShaderSourceEntry;
+ HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
+ ANGLEWebKitBridge m_compiler;
+
+ // Errors raised by synthesizeGLError().
+ ListHashSet<unsigned long> m_syntheticErrors;
+
+ struct {
+ GLint x, y;
+ GLsizei width, height;
+ } m_savedViewport;
+ OwnPtr<Extensions3DAndroid> m_extensions;
+ int m_contextId;
+
+ // Java method used for invalidating the canvas area
+ jobject m_webView;
+ jmethodID m_postInvalidate;
+};
+
+} // namespace WebCore
+
+#endif // GraphicsContext3DInternal_h
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp
new file mode 100644
index 0000000..e2ab6f9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEBGL)
+
+#include "GraphicsContext3DProxy.h"
+#include "GraphicsContext3DInternal.h"
+
+namespace WebCore {
+
+GraphicsContext3DProxy::GraphicsContext3DProxy()
+ : m_texture(0)
+{
+ LOGWEBGL("GraphicsContext3DProxy::GraphicsContext3DProxy(), this = %p", this);
+}
+
+GraphicsContext3DProxy::~GraphicsContext3DProxy()
+{
+ LOGWEBGL("GraphicsContext3DProxy::~GraphicsContext3DProxy(), this = %p", this);
+}
+
+void GraphicsContext3DProxy::setGraphicsContext(GraphicsContext3DInternal* context)
+{
+ MutexLocker lock(m_mutex);
+ m_context = context;
+}
+
+bool GraphicsContext3DProxy::lockFrontBuffer(GLuint& texture, SkRect& rect)
+{
+ MutexLocker lock(m_mutex);
+ if (!m_context) {
+ return false;
+ }
+ EGLImageKHR image;
+ bool locked = m_context->lockFrontBuffer(image, rect);
+ if (locked) {
+ if (m_texture == 0)
+ glGenTextures(1, &m_texture);
+
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_texture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ texture = m_texture;
+ }
+
+ return locked;
+}
+
+void GraphicsContext3DProxy::releaseFrontBuffer()
+{
+ MutexLocker lock(m_mutex);
+ if (m_texture) {
+ glDeleteTextures(1, &m_texture);
+ m_texture = 0;
+ }
+ if (!m_context) {
+ return;
+ }
+ m_context->releaseFrontBuffer();
+}
+}
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h
new file mode 100644
index 0000000..1cc1453
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GraphicsContext3DProxy.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsContext3DProxy_h
+#define GraphicsContext3DProxy_h
+
+#include "config.h"
+
+#include "SkRect.h"
+#include "Threading.h"
+#include <wtf/RefCounted.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+class GraphicsContext3DInternal;
+
+class GraphicsContext3DProxy: public RefCounted<GraphicsContext3DProxy> {
+public:
+ GraphicsContext3DProxy();
+ ~GraphicsContext3DProxy();
+
+ void setGraphicsContext(GraphicsContext3DInternal* context);
+
+ bool lockFrontBuffer(GLuint& texture, SkRect& rect);
+ void releaseFrontBuffer();
+
+private:
+ WTF::Mutex m_mutex;
+ GraphicsContext3DInternal* m_context;
+ GLuint m_texture;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 6edbe6a..7d11030 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -106,6 +107,9 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_haveContents(false),
m_newImage(false),
m_image(0),
+#if ENABLE(WEBGL)
+ m_is3DCanvas(false),
+#endif
m_fixedBackgroundLayer(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
@@ -478,6 +482,14 @@ void GraphicsLayerAndroid::setNeedsDisplay()
setNeedsDisplayInRect(rect);
}
+#if ENABLE(WEBGL)
+void GraphicsLayerAndroid::setContentsNeedsDisplay()
+{
+ if (m_is3DCanvas)
+ setNeedsDisplay();
+}
+#endif
+
// Helper to set and clear the painting phase as well as auto restore the
// original phase.
class PaintingPhase {
@@ -1074,6 +1086,33 @@ void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
}
}
+#if ENABLE(WEBGL)
+void GraphicsLayerAndroid::setContentsToCanvas(PlatformLayer* canvasLayer)
+{
+ if (m_contentLayer != canvasLayer && canvasLayer) {
+ // Copy data from the original content layer to the new one
+ canvasLayer->setPosition(m_contentLayer->getPosition().fX,
+ m_contentLayer->getPosition().fY);
+ canvasLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
+ canvasLayer->setDrawTransform(*m_contentLayer->drawTransform());
+
+ canvasLayer->ref();
+ m_contentLayer->unref();
+ m_contentLayer = canvasLayer;
+
+ // If the parent exists then notify it to re-sync it's children
+ if (m_parent) {
+ GraphicsLayerAndroid* parent = static_cast<GraphicsLayerAndroid*>(m_parent);
+ parent->m_needsSyncChildren = true;
+ }
+ m_needsSyncChildren = true;
+ m_is3DCanvas = true;
+
+ setDrawsContent(true);
+ }
+}
+#endif
+
PlatformLayer* GraphicsLayerAndroid::platformLayer() const
{
ALOGV("platformLayer");
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 28d4b09..5418745 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011, Sony Ericsson Mobile Communications AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -92,6 +93,10 @@ public:
virtual void setNeedsDisplay();
virtual void setNeedsDisplayInRect(const FloatRect&);
+#if ENABLE(WEBGL)
+ virtual void setContentsNeedsDisplay();
+#endif
+
virtual bool addAnimation(const KeyframeValueList& valueList,
const IntSize& boxSize,
const Animation* anim,
@@ -116,6 +121,9 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
+#if ENABLE(WEBGL)
+ virtual void setContentsToCanvas(PlatformLayer*);
+#endif
virtual PlatformLayer* platformLayer() const;
void pauseDisplay(bool state);
@@ -165,6 +173,12 @@ private:
bool m_newImage;
Image* m_image;
+#if ENABLE(WEBGL)
+ bool m_is3DCanvas;
+#endif
+
+ SkRegion m_dirtyRegion;
+
LayerAndroid* m_contentLayer;
FixedBackgroundImageLayerAndroid* m_fixedBackgroundLayer;
LayerAndroid* m_foregroundLayer;
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index f36200d..9571ec2 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -30,6 +30,7 @@
#include "BitmapImage.h"
#include "ColorSpace.h"
#include "GraphicsContext.h"
+#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
#include "PlatformBridge.h"
#include "PlatformGraphicsContext.h"
@@ -43,6 +44,10 @@
#include "SkStream.h"
#include "SkUnPreMultiply.h"
+#include "image-encoders/skia/JPEGImageEncoder.h"
+#include "image-encoders/skia/PNGImageEncoder.h"
+#include <wtf/text/StringConcatenate.h>
+
using namespace std;
namespace WebCore {
@@ -245,8 +250,36 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
}
}
+template <typename T>
+static String ImageToDataURL(T& source, const String& mimeType, const double* quality)
+{
+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
+ Vector<unsigned char> encodedImage;
+ if (mimeType == "image/jpeg") {
+ int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
+ if (quality && *quality >= 0.0 && *quality <= 1.0)
+ compressionQuality = static_cast<int>(*quality * 100 + 0.5);
+ if (!JPEGImageEncoder::encode(source, compressionQuality, &encodedImage))
+ return "data:,";
+ } else {
+ if (!PNGImageEncoder::encode(source, &encodedImage))
+ return "data:,";
+ ASSERT(mimeType == "image/png");
+ }
+
+ Vector<char> base64Data;
+ base64Encode(*reinterpret_cast<Vector<char>*>(&encodedImage), base64Data);
+
+ return makeString("data:", mimeType, ";base64,", base64Data);
+}
+
+String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
+{
+ return ImageToDataURL(source, mimeType, quality);
+}
-String ImageBuffer::toDataURL(const String&, const double*) const
+String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
{
// Encode the image into a vector.
SkDynamicMemoryWStream pngStream;
diff --git a/Source/WebCore/platform/graphics/android/WebGLLayer.cpp b/Source/WebCore/platform/graphics/android/WebGLLayer.cpp
new file mode 100644
index 0000000..9feb2e1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/WebGLLayer.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#if ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+
+#include "WebGLLayer.h"
+
+#include "GraphicsContext3DInternal.h"
+#include "DrawQuadData.h"
+#include "SkRect.h"
+#include "TilesManager.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+WebGLLayer::WebGLLayer(PassRefPtr<GraphicsContext3DProxy> proxy)
+ : LayerAndroid((RenderLayer*)0)
+ , m_proxy(proxy)
+{
+}
+
+WebGLLayer::WebGLLayer(const WebGLLayer& layer)
+ : LayerAndroid(layer)
+ , m_proxy(layer.m_proxy)
+{
+}
+
+WebGLLayer::~WebGLLayer()
+{
+}
+
+bool WebGLLayer::drawGL(bool layerTilesDisabled)
+{
+ bool askScreenUpdate = false;
+
+ askScreenUpdate |= LayerAndroid::drawGL(layerTilesDisabled);
+
+ if (m_proxy.get()) {
+ GLuint texture;
+ SkRect localBounds;
+ bool locked = m_proxy->lockFrontBuffer(texture, localBounds);
+ if (locked) {
+ // Flip the y-coordinate
+ TransformationMatrix transform = m_drawTransform;
+ transform = transform.translate(0, 2 * localBounds.top() + localBounds.height());
+ transform = transform.scale3d(1.0, -1.0, 1.0);
+ TextureQuadData data(texture, GL_TEXTURE_EXTERNAL_OES, GL_LINEAR, LayerQuad, &transform, &localBounds);
+ TilesManager::instance()->shader()->drawQuad(&data);
+ m_proxy->releaseFrontBuffer();
+ }
+ }
+
+ return askScreenUpdate;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/WebGLLayer.h b/Source/WebCore/platform/graphics/android/WebGLLayer.h
new file mode 100644
index 0000000..6a69082
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/WebGLLayer.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011, 2012 Sony Ericsson Mobile Communications AB
+ * Copyright (C) 2012 Sony Mobile Communications AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLLayer_h
+#define WebGLLayer_h
+
+#include "config.h"
+
+#if ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+
+#include "GLUtils.h"
+#include "GraphicsContext3DProxy.h"
+#include "LayerAndroid.h"
+#include "PassRefPtr.h"
+#include "RefPtr.h"
+#include <jni.h>
+
+namespace WebCore {
+
+class GraphicsContext3DInternal;
+
+class WebGLLayer : public LayerAndroid {
+public:
+ WebGLLayer(PassRefPtr<GraphicsContext3DProxy> proxy);
+ WebGLLayer(const WebGLLayer& layer);
+ virtual ~WebGLLayer();
+
+ virtual LayerAndroid* copy() const { return new WebGLLayer(*this); }
+ virtual bool drawGL(bool layerTilesDisabled);
+ virtual bool isWebGL() const { return true; }
+
+private:
+ RefPtr<GraphicsContext3DProxy> m_proxy;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL) && USE(ACCELERATED_COMPOSITING)
+#endif // WebGLLayer_h
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 1064388..d58c4ee 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -27,7 +27,7 @@
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkTypeface.h"
-#include "Surface.h"
+#include "rendering/Surface.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -148,8 +148,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
}
if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) {
- Vector<LayerAndroid*> normalLayers;
- Vector<LayerAndroid*> absoluteLayers;
+ WTF::Vector<LayerAndroid*> normalLayers;
+ WTF::Vector<LayerAndroid*> absoluteLayers;
for (int i = 0; i < layer.countChildren(); i++) {
LayerAndroid* child = layer.getChild(i);
if (child->isPositionAbsolute()
@@ -307,7 +307,7 @@ void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim)
void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
{
KeyframesMap::const_iterator end = m_animations.end();
- Vector<pair<String, int> > toDelete;
+ WTF::Vector<pair<String, int> > toDelete;
for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
if ((it->second)->type() == property)
toDelete.append(it->first);
@@ -320,7 +320,7 @@ void LayerAndroid::removeAnimationsForProperty(AnimatedPropertyID property)
void LayerAndroid::removeAnimationsForKeyframes(const String& name)
{
KeyframesMap::const_iterator end = m_animations.end();
- Vector<pair<String, int> > toDelete;
+ WTF::Vector<pair<String, int> > toDelete;
for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) {
if ((it->second)->isNamed(name))
toDelete.append(it->first);
@@ -704,7 +704,7 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
int count = this->countChildren();
if (count > 0) {
mergeState->depth++;
- Vector <LayerAndroid*> sublayers;
+ WTF::Vector <LayerAndroid*> sublayers;
for (int i = 0; i < count; i++)
sublayers.append(getChild(i));
@@ -895,7 +895,7 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style)
bool askScreenUpdate = false;
int count = this->countChildren();
if (count > 0) {
- Vector <LayerAndroid*> sublayers;
+ WTF::Vector <LayerAndroid*> sublayers;
for (int i = 0; i < count; i++)
sublayers.append(this->getChild(i));
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 6c2e43d..b3518e9 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -243,6 +243,7 @@ public:
virtual bool isIFrame() const { return false; }
virtual bool isIFrameContent() const { return false; }
virtual bool isFixedBackground() const { return false; }
+ virtual bool isWebGL() const { return false; }
bool isPositionFixed() const { return m_fixedPosition; }
void setAbsolutePosition(bool isAbsolute) { m_isPositionAbsolute = isAbsolute; }
diff --git a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
index 346afe4..e0975ee 100644
--- a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
@@ -120,7 +120,7 @@ private:
// The retiredTextures is used to communicate between UI thread and webcore
// thread. Basically, GL textures are determined to retire in the webcore
// thread, and really get deleted in the UI thread.
- Vector<GLuint> m_retiredTextures;
+ WTF::Vector<GLuint> m_retiredTextures;
android::Mutex m_retiredTexturesLock;
GLuint createTextureFromImage(RenderSkinMediaButton::MediaButton buttonType);
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 6caf93b..24d8fc9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -419,14 +419,6 @@ bool Surface::blitFromContents(Tile* tile)
if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
return false;
- if (tile->frontTexture() != tile->lastDrawnTexture()) {
- // the below works around an issue where glTexSubImage2d can't update a
- // texture that hasn't drawn yet by drawing it off screen.
- // glFlush() and glFinish() work also, but are likely more wasteful.
- SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0);
- FloatRect fillPortion(0, 0, 0, 0);
- tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion);
- }
LayerContent* content = getFirstLayer()->content();
// Extract the dirty rect from the region. Note that this is *NOT* constrained
// to this tile
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
index 76be981..e2b9554 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
@@ -52,7 +52,6 @@ Tile::Tile(bool isLayerTile)
, m_y(-1)
, m_frontTexture(0)
, m_backTexture(0)
- , m_lastDrawnTexture(0)
, m_scale(1)
, m_dirty(true)
, m_repaintsPending(0)
@@ -240,7 +239,6 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale,
m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
forceBlending, usePointSampling, fillPortion);
- m_lastDrawnTexture = m_frontTexture;
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index f467bb0..1a50587 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h
@@ -127,7 +127,6 @@ public:
int y() const { return m_y; }
TileTexture* frontTexture() { return m_frontTexture; }
TileTexture* backTexture() { return m_backTexture; }
- TileTexture* lastDrawnTexture() { return m_lastDrawnTexture; }
// only used for prioritization - the higher, the more relevant the tile is
unsigned long long drawCount() { return m_drawCount; }
@@ -152,7 +151,6 @@ private:
TileTexture* m_frontTexture;
TileTexture* m_backTexture;
- TileTexture* m_lastDrawnTexture;
float m_scale;
// used to signal that the that the tile is out-of-date and needs to be
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index b15fa6d..fd7b92e 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -512,7 +512,11 @@ void TransferQueue::setTextureUploadType(TextureUploadType type)
setPendingDiscard();
+#ifdef FORCE_CPU_UPLOAD
+ m_currentUploadType = CpuUpload; // force to cpu upload mode for now until gpu upload mode is fixed
+#else
m_currentUploadType = type;
+#endif
ALOGD("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index 55011b0..4ced1ea 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -69,7 +69,11 @@ enum TextureUploadType {
GpuUpload = 1
};
+#ifdef FORCE_CPU_UPLOAD
+#define DEFAULT_UPLOAD_TYPE CpuUpload
+#else
#define DEFAULT_UPLOAD_TYPE GpuUpload
+#endif
class TileTransferData {
public: