summaryrefslogtreecommitdiff
path: root/Tools/DumpRenderTree/chromium/TestWebPlugin.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Tools/DumpRenderTree/chromium/TestWebPlugin.cpp
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Tools/DumpRenderTree/chromium/TestWebPlugin.cpp')
-rw-r--r--Tools/DumpRenderTree/chromium/TestWebPlugin.cpp326
1 files changed, 326 insertions, 0 deletions
diff --git a/Tools/DumpRenderTree/chromium/TestWebPlugin.cpp b/Tools/DumpRenderTree/chromium/TestWebPlugin.cpp
new file mode 100644
index 000000000..ac2336664
--- /dev/null
+++ b/Tools/DumpRenderTree/chromium/TestWebPlugin.cpp
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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 APPLE AND ITS 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 APPLE OR ITS 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"
+#include "TestWebPlugin.h"
+
+#include "WebFrame.h"
+#include "platform/WebGraphicsContext3D.h"
+#include "WebKit.h"
+#include "platform/WebKitPlatformSupport.h"
+#include "WebPluginContainer.h"
+#include "WebPluginParams.h"
+#include <wtf/Assertions.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+// GLenum values copied from gl2.h.
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_ONE 1
+#define GL_TRIANGLES 0x0004
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_BLEND 0x0BE2
+#define GL_FLOAT 0x1406
+#define GL_COLOR_BUFFER_BIT 0x4000
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_STATIC_DRAW 0x88E4
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+
+static void premultiplyAlpha(const unsigned colorIn[3], float alpha, float colorOut[4])
+{
+ for (int i = 0; i < 3; ++i)
+ colorOut[i] = (colorIn[i] / 255.0f) * alpha;
+
+ colorOut[3] = alpha;
+}
+
+TestWebPlugin::TestWebPlugin(WebKit::WebFrame* frame,
+ const WebKit::WebPluginParams& params)
+ : m_frame(frame)
+ , m_container(0)
+ , m_context(0)
+{
+ static const WebString kAttributePrimitive = WebString::fromUTF8("primitive");
+ static const WebString kAttributeBackgroundColor = WebString::fromUTF8("background-color");
+ static const WebString kAttributePrimitiveColor = WebString::fromUTF8("primitive-color");
+ static const WebString kAttributeOpacity = WebString::fromUTF8("opacity");
+
+ ASSERT(params.attributeNames.size() == params.attributeValues.size());
+ size_t size = params.attributeNames.size();
+ for (size_t i = 0; i < size; ++i) {
+ const WebString& attributeName = params.attributeNames[i];
+ const WebString& attributeValue = params.attributeValues[i];
+
+ if (attributeName == kAttributePrimitive)
+ m_scene.primitive = parsePrimitive(attributeValue);
+ else if (attributeName == kAttributeBackgroundColor)
+ parseColor(attributeValue, m_scene.backgroundColor);
+ else if (attributeName == kAttributePrimitiveColor)
+ parseColor(attributeValue, m_scene.primitiveColor);
+ else if (attributeName == kAttributeOpacity)
+ m_scene.opacity = parseOpacity(attributeValue);
+ }
+}
+
+TestWebPlugin::~TestWebPlugin()
+{
+}
+
+const WebString& TestWebPlugin::mimeType()
+{
+ static const WebString kMimeType = WebString::fromUTF8("application/x-webkit-test-webplugin");
+ return kMimeType;
+}
+
+bool TestWebPlugin::initialize(WebPluginContainer* container)
+{
+ m_context = webKitPlatformSupport()->createGraphicsContext3D();
+ if (!m_context)
+ return false;
+
+ WebGraphicsContext3D::Attributes attrs;
+ if (!m_context->initialize(attrs, m_frame->view(), false))
+ return false;
+
+ if (!m_context->makeContextCurrent())
+ return false;
+
+ if (!initScene())
+ return false;
+
+ m_container = container;
+ m_container->setBackingTextureId(m_context->getPlatformTextureId());
+ return true;
+}
+
+void TestWebPlugin::destroy()
+{
+ destroyScene();
+
+ delete m_context;
+ m_context = 0;
+
+ m_container = 0;
+ m_frame = 0;
+}
+
+void TestWebPlugin::updateGeometry(const WebRect& frameRect,
+ const WebRect& clipRect,
+ const WebVector<WebRect>& cutOutsRects,
+ bool isVisible)
+{
+ if (clipRect == m_rect)
+ return;
+ m_rect = clipRect;
+
+ m_context->reshape(m_rect.width, m_rect.height);
+ drawScene();
+ m_context->prepareTexture();
+
+ m_container->commitBackingTexture();
+}
+
+TestWebPlugin::Primitive TestWebPlugin::parsePrimitive(const WebString& string)
+{
+ static const WebString kPrimitiveNone = WebString::fromUTF8("none");
+ static const WebString kPrimitiveTriangle = WebString::fromUTF8("triangle");
+
+ Primitive primitive = PrimitiveNone;
+ if (string == kPrimitiveNone)
+ primitive = PrimitiveNone;
+ else if (string == kPrimitiveTriangle)
+ primitive = PrimitiveTriangle;
+ else
+ ASSERT_NOT_REACHED();
+ return primitive;
+}
+
+// FIXME: This method should already exist. Use it.
+// For now just parse primary colors.
+void TestWebPlugin::parseColor(const WebString& string, unsigned color[3])
+{
+ color[0] = color[1] = color[2] = 0;
+ if (string == "black")
+ return;
+
+ if (string == "red")
+ color[0] = 255;
+ else if (string == "green")
+ color[1] = 255;
+ else if (string == "blue")
+ color[2] = 255;
+ else
+ ASSERT_NOT_REACHED();
+}
+
+float TestWebPlugin::parseOpacity(const WebString& string)
+{
+ return static_cast<float>(atof(string.utf8().data()));
+}
+
+bool TestWebPlugin::initScene()
+{
+ float color[4];
+ premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color);
+ m_context->clearColor(color[0], color[1], color[2], color[3]);
+
+ m_context->enable(GL_BLEND);
+ m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive() : true;
+}
+
+void TestWebPlugin::drawScene()
+{
+ m_context->viewport(0, 0, m_rect.width, m_rect.height);
+ m_context->clear(GL_COLOR_BUFFER_BIT);
+
+ if (m_scene.primitive != PrimitiveNone)
+ drawPrimitive();
+}
+
+void TestWebPlugin::destroyScene()
+{
+ if (m_scene.program) {
+ m_context->deleteProgram(m_scene.program);
+ m_scene.program = 0;
+ }
+ if (m_scene.vbo) {
+ m_context->deleteBuffer(m_scene.vbo);
+ m_scene.vbo = 0;
+ }
+}
+
+bool TestWebPlugin::initProgram()
+{
+ const CString vertexSource(
+ "attribute vec4 position; \n"
+ "void main() { \n"
+ " gl_Position = position; \n"
+ "} \n"
+ );
+
+ const CString fragmentSource(
+ "precision mediump float; \n"
+ "uniform vec4 color; \n"
+ "void main() { \n"
+ " gl_FragColor = color; \n"
+ "} \n"
+ );
+
+ m_scene.program = loadProgram(vertexSource, fragmentSource);
+ if (!m_scene.program)
+ return false;
+
+ m_scene.colorLocation = m_context->getUniformLocation(m_scene.program, "color");
+ m_scene.positionLocation = m_context->getAttribLocation(m_scene.program, "position");
+ return true;
+}
+
+bool TestWebPlugin::initPrimitive()
+{
+ ASSERT(m_scene.primitive == PrimitiveTriangle);
+
+ m_scene.vbo = m_context->createBuffer();
+ if (!m_scene.vbo)
+ return false;
+
+ const float vertices[] = { 0.0f, 0.8f, 0.0f,
+ -0.8f, -0.8f, 0.0f,
+ 0.8f, -0.8f, 0.0f };
+ m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
+ m_context->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW);
+ m_context->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
+ return true;
+}
+
+void TestWebPlugin::drawPrimitive()
+{
+ ASSERT(m_scene.primitive == PrimitiveTriangle);
+ ASSERT(m_scene.vbo);
+ ASSERT(m_scene.program);
+
+ m_context->useProgram(m_scene.program);
+
+ // Bind primitive color.
+ float color[4];
+ premultiplyAlpha(m_scene.primitiveColor, m_scene.opacity, color);
+ m_context->uniform4f(m_scene.colorLocation, color[0], color[1], color[2], color[3]);
+
+ // Bind primitive vertices.
+ m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
+ m_context->enableVertexAttribArray(m_scene.positionLocation);
+ m_context->vertexAttribPointer(m_scene.positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ m_context->drawArrays(GL_TRIANGLES, 0, 3);
+}
+
+unsigned TestWebPlugin::loadShader(unsigned type, const CString& source)
+{
+ unsigned shader = m_context->createShader(type);
+ if (shader) {
+ m_context->shaderSource(shader, source.data());
+ m_context->compileShader(shader);
+
+ int compiled = 0;
+ m_context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ m_context->deleteShader(shader);
+ shader = 0;
+ }
+ }
+ return shader;
+}
+
+unsigned TestWebPlugin::loadProgram(const CString& vertexSource,
+ const CString& fragmentSource)
+{
+ unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
+ unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
+ unsigned program = m_context->createProgram();
+ if (vertexShader && fragmentShader && program) {
+ m_context->attachShader(program, vertexShader);
+ m_context->attachShader(program, fragmentShader);
+ m_context->linkProgram(program);
+
+ int linked = 0;
+ m_context->getProgramiv(program, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ m_context->deleteProgram(program);
+ program = 0;
+ }
+ }
+ if (vertexShader)
+ m_context->deleteShader(vertexShader);
+ if (fragmentShader)
+ m_context->deleteShader(fragmentShader);
+
+ return program;
+}
+