Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / shell / renderer / test_runner / TestPlugin.cpp
index 2d53c2a..cb33167 100644 (file)
@@ -5,8 +5,15 @@
 #include "content/shell/renderer/test_runner/TestPlugin.h"
 
 #include "base/basictypes.h"
-#include "content/shell/renderer/test_runner/TestCommon.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/shared_memory.h"
+#include "base/strings/stringprintf.h"
+#include "content/public/renderer/render_thread.h"
 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/platform/WebCompositorSupport.h"
 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
@@ -18,9 +25,8 @@
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
 
 using namespace blink;
-using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -76,17 +82,15 @@ const char* pointState(WebTouchPoint::State state)
     default:
         return "Unknown";
     }
-
-    BLINK_ASSERT_NOT_REACHED();
-    return 0;
 }
 
 void printTouchList(WebTestDelegate* delegate, const WebTouchPoint* points, int length)
 {
     for (int i = 0; i < length; ++i) {
-        char buffer[100];
-        snprintf(buffer, sizeof(buffer), "* %d, %d: %s\n", points[i].position.x, points[i].position.y, pointState(points[i].state));
-        delegate->printMessage(buffer);
+      delegate->printMessage(base::StringPrintf("* %.2f, %.2f: %s\n",
+                                                points[i].position.x,
+                                                points[i].position.y,
+                                                pointState(points[i].state)));
     }
 }
 
@@ -99,14 +103,12 @@ void printEventDetails(WebTestDelegate* delegate, const WebInputEvent& event)
         printTouchList(delegate, touch.targetTouches, touch.targetTouchesLength);
     } else if (WebInputEvent::isMouseEventType(event.type) || event.type == WebInputEvent::MouseWheel) {
         const WebMouseEvent& mouse = static_cast<const WebMouseEvent&>(event);
-        char buffer[100];
-        snprintf(buffer, sizeof(buffer), "* %d, %d\n", mouse.x, mouse.y);
-        delegate->printMessage(buffer);
+        delegate->printMessage(
+            base::StringPrintf("* %d, %d\n", mouse.x, mouse.y));
     } else if (WebInputEvent::isGestureEventType(event.type)) {
         const WebGestureEvent& gesture = static_cast<const WebGestureEvent&>(event);
-        char buffer[100];
-        snprintf(buffer, sizeof(buffer), "* %d, %d\n", gesture.x, gesture.y);
-        delegate->printMessage(buffer);
+        delegate->printMessage(
+            base::StringPrintf("* %d, %d\n", gesture.x, gesture.y));
     }
 }
 
@@ -127,7 +129,6 @@ void deferredDelete(void* context)
 
 }
 
-
 TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
     : m_frame(frame)
     , m_delegate(delegate)
@@ -141,6 +142,8 @@ TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDe
     , m_printEventDetails(false)
     , m_printUserGestureStatus(false)
     , m_canProcessDrag(false)
+    , m_isPersistent(params.mimeType == pluginPersistsMimeType())
+    , m_canCreateWithoutRenderer(params.mimeType == canCreateWithoutRendererMimeType())
 {
     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrimitive, ("primitive"));
     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeBackgroundColor, ("background-color"));
@@ -152,7 +155,7 @@ TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDe
     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeCanProcessDrag, ("can-process-drag"));
     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrintUserGestureStatus, ("print-user-gesture-status"));
 
-    BLINK_ASSERT(params.attributeNames.size() == params.attributeValues.size());
+    DCHECK_EQ(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];
@@ -177,6 +180,8 @@ TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDe
         else if (attributeName == kAttributePrintUserGestureStatus)
             m_printUserGestureStatus = parseBoolean(attributeValue);
     }
+    if (m_canCreateWithoutRenderer)
+        m_delegate->printMessage(std::string("TestPlugin: canCreateWithoutRenderer\n"));
 }
 
 TestPlugin::~TestPlugin()
@@ -187,18 +192,18 @@ bool TestPlugin::initialize(WebPluginContainer* container)
 {
     WebGraphicsContext3D::Attributes attrs;
     m_context = Platform::current()->createOffscreenGraphicsContext3D(attrs);
-    if (!m_context)
-        return false;
-
-    if (!m_context->makeContextCurrent())
-        return false;
+    if (m_context && !m_context->makeContextCurrent()) {
+        delete m_context;
+        m_context = 0;
+    }
 
     if (!initScene())
         return false;
 
-    m_layer = scoped_ptr<WebExternalTextureLayer>(Platform::current()->compositorSupport()->createExternalTextureLayer(this));
+    m_layer = cc::TextureLayer::CreateForMailbox(this);
+    m_webLayer = make_scoped_ptr(InstantiateWebLayer(m_layer));
     m_container = container;
-    m_container->setWebLayer(m_layer->layer());
+    m_container->setWebLayer(m_webLayer.get());
     if (m_reRequestTouchEvents) {
         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeSynthesizedMouse);
         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeRaw);
@@ -211,10 +216,11 @@ bool TestPlugin::initialize(WebPluginContainer* container)
 void TestPlugin::destroy()
 {
     if (m_layer.get())
-        m_layer->clearTexture();
+        m_layer->ClearTexture();
     if (m_container)
         m_container->setWebLayer(0);
-    m_layer.reset();
+    m_webLayer.reset();
+    m_layer = NULL;
     destroyScene();
 
     delete m_context;
@@ -241,28 +247,61 @@ void TestPlugin::updateGeometry(const WebRect& frameRect, const WebRect& clipRec
     if (clipRect == m_rect)
         return;
     m_rect = clipRect;
-    if (m_rect.isEmpty())
-        return;
 
-    m_context->viewport(0, 0, m_rect.width, m_rect.height);
-
-    m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture);
-    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rect.width, m_rect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-    m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
-    m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0);
-
-    drawScene();
-
-    m_context->genMailboxCHROMIUM(m_mailbox.name);
-    m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
+    if (m_rect.isEmpty()) {
+        m_textureMailbox = cc::TextureMailbox();
+    } else if (m_context) {
+        m_context->viewport(0, 0, m_rect.width, m_rect.height);
+
+        m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture);
+        m_context->texParameteri(
+            GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        m_context->texParameteri(
+            GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        m_context->texParameteri(
+            GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        m_context->texParameteri(
+            GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        m_context->texImage2D(GL_TEXTURE_2D,
+                              0,
+                              GL_RGBA,
+                              m_rect.width,
+                              m_rect.height,
+                              0,
+                              GL_RGBA,
+                              GL_UNSIGNED_BYTE,
+                              0);
+        m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+        m_context->framebufferTexture2D(GL_FRAMEBUFFER,
+                                        GL_COLOR_ATTACHMENT0,
+                                        GL_TEXTURE_2D,
+                                        m_colorTexture,
+                                        0);
+
+        drawSceneGL();
+
+        gpu::Mailbox mailbox;
+        m_context->genMailboxCHROMIUM(mailbox.name);
+        m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+        m_context->flush();
+        uint32 syncPoint = m_context->insertSyncPoint();
+        m_textureMailbox = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, syncPoint);
+    } else {
+        size_t bytes = 4 * m_rect.width * m_rect.height;
+        scoped_ptr<base::SharedMemory> bitmap =
+            RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes);
+        if (!bitmap->Map(bytes)) {
+            m_textureMailbox = cc::TextureMailbox();
+        } else {
+            drawSceneSoftware(bitmap->memory(), bytes);
+            m_textureMailbox = cc::TextureMailbox(
+                bitmap.get(), gfx::Size(m_rect.width, m_rect.height));
+            m_sharedBitmap = bitmap.Pass();
+        }
+    }
 
-    m_context->flush();
-    m_layer->layer()->invalidate();
     m_mailboxChanged = true;
+    m_layer->SetNeedsDisplay();
 }
 
 bool TestPlugin::acceptsInputEvents()
@@ -275,24 +314,30 @@ bool TestPlugin::isPlaceholder()
     return false;
 }
 
-blink::WebGraphicsContext3D* TestPlugin::context()
-{
-    return 0;
-}
+static void ignoreReleaseCallback(uint32 sync_point, bool lost) {}
 
-bool TestPlugin::prepareMailbox(blink::WebExternalTextureMailbox* mailbox, blink::WebExternalBitmap*)
-{
+static void releaseSharedMemory(scoped_ptr<base::SharedMemory> bitmap,
+                                uint32 sync_point,
+                                bool lost) {}
+
+bool TestPlugin::PrepareTextureMailbox(
+    cc::TextureMailbox* mailbox,
+    scoped_ptr<cc::SingleReleaseCallback>* releaseCallback,
+    bool useSharedMemory) {
     if (!m_mailboxChanged)
         return false;
-    *mailbox = m_mailbox;
+    *mailbox = m_textureMailbox;
+    if (m_textureMailbox.IsTexture()) {
+      *releaseCallback =
+          cc::SingleReleaseCallback::Create(base::Bind(&ignoreReleaseCallback));
+    } else {
+      *releaseCallback = cc::SingleReleaseCallback::Create(
+          base::Bind(&releaseSharedMemory, base::Passed(&m_sharedBitmap)));
+    }
     m_mailboxChanged = false;
     return true;
 }
 
-void TestPlugin::mailboxReleased(const blink::WebExternalTextureMailbox&)
-{
-}
-
 TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string)
 {
     const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveNone, ("none"));
@@ -304,7 +349,7 @@ TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string)
     else if (string == kPrimitiveTriangle)
         primitive = PrimitiveTriangle;
     else
-        BLINK_ASSERT_NOT_REACHED();
+        NOTREACHED();
     return primitive;
 }
 
@@ -323,7 +368,7 @@ void TestPlugin::parseColor(const WebString& string, unsigned color[3])
     else if (string == "blue")
         color[2] = 255;
     else
-        BLINK_ASSERT_NOT_REACHED();
+        NOTREACHED();
 }
 
 float TestPlugin::parseOpacity(const WebString& string)
@@ -339,6 +384,9 @@ bool TestPlugin::parseBoolean(const WebString& string)
 
 bool TestPlugin::initScene()
 {
+    if (!m_context)
+        return true;
+
     float color[4];
     premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color);
 
@@ -357,8 +405,7 @@ bool TestPlugin::initScene()
     return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive() : true;
 }
 
-void TestPlugin::drawScene()
-{
+void TestPlugin::drawSceneGL() {
     m_context->viewport(0, 0, m_rect.width, m_rect.height);
     m_context->clear(GL_COLOR_BUFFER_BIT);
 
@@ -366,6 +413,40 @@ void TestPlugin::drawScene()
         drawPrimitive();
 }
 
+void TestPlugin::drawSceneSoftware(void* memory, size_t bytes) {
+    DCHECK_EQ(bytes, m_rect.width * m_rect.height * 4u);
+
+    SkColor backgroundColor =
+            SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255),
+                           m_scene.backgroundColor[0],
+                           m_scene.backgroundColor[1],
+                           m_scene.backgroundColor[2]);
+
+    const SkImageInfo info = SkImageInfo::MakeN32Premul(m_rect.width,
+                                                        m_rect.height);
+    SkBitmap bitmap;
+    bitmap.installPixels(info, memory, info.minRowBytes());
+    SkCanvas canvas(bitmap);
+    canvas.clear(backgroundColor);
+
+    if (m_scene.primitive != PrimitiveNone) {
+        DCHECK_EQ(PrimitiveTriangle, m_scene.primitive);
+        SkColor foregroundColor =
+                SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255),
+                               m_scene.primitiveColor[0],
+                               m_scene.primitiveColor[1],
+                               m_scene.primitiveColor[2]);
+        SkPath trianglePath;
+        trianglePath.moveTo(0.5f * m_rect.width, 0.9f * m_rect.height);
+        trianglePath.lineTo(0.1f * m_rect.width, 0.1f * m_rect.height);
+        trianglePath.lineTo(0.9f * m_rect.width, 0.1f * m_rect.height);
+        SkPaint paint;
+        paint.setColor(foregroundColor);
+        paint.setStyle(SkPaint::kFill_Style);
+        canvas.drawPath(trianglePath, paint);
+    }
+}
+
 void TestPlugin::destroyScene()
 {
     if (m_scene.program) {
@@ -390,14 +471,14 @@ void TestPlugin::destroyScene()
 
 bool TestPlugin::initProgram()
 {
-    const string vertexSource(
+    const std::string vertexSource(
         "attribute vec4 position;  \n"
         "void main() {             \n"
         "  gl_Position = position; \n"
         "}                         \n"
     );
 
-    const string fragmentSource(
+    const std::string fragmentSource(
         "precision mediump float; \n"
         "uniform vec4 color;      \n"
         "void main() {            \n"
@@ -416,7 +497,7 @@ bool TestPlugin::initProgram()
 
 bool TestPlugin::initPrimitive()
 {
-    BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);
+    DCHECK_EQ(m_scene.primitive, PrimitiveTriangle);
 
     m_scene.vbo = m_context->createBuffer();
     if (!m_scene.vbo)
@@ -434,9 +515,9 @@ bool TestPlugin::initPrimitive()
 
 void TestPlugin::drawPrimitive()
 {
-    BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);
-    BLINK_ASSERT(m_scene.vbo);
-    BLINK_ASSERT(m_scene.program);
+    DCHECK_EQ(m_scene.primitive, PrimitiveTriangle);
+    DCHECK(m_scene.vbo);
+    DCHECK(m_scene.program);
 
     m_context->useProgram(m_scene.program);
 
@@ -452,7 +533,7 @@ void TestPlugin::drawPrimitive()
     m_context->drawArrays(GL_TRIANGLES, 0, 3);
 }
 
-unsigned TestPlugin::loadShader(unsigned type, const string& source)
+unsigned TestPlugin::loadShader(unsigned type, const std::string& source)
 {
     unsigned shader = m_context->createShader(type);
     if (shader) {
@@ -469,7 +550,7 @@ unsigned TestPlugin::loadShader(unsigned type, const string& source)
     return shader;
 }
 
-unsigned TestPlugin::loadProgram(const string& vertexSource, const string& fragmentSource)
+unsigned TestPlugin::loadProgram(const std::string& vertexSource, const std::string& fragmentSource)
 {
     unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
     unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
@@ -545,6 +626,8 @@ bool TestPlugin::handleInputEvent(const WebInputEvent& event, WebCursorInfo& inf
         printEventDetails(m_delegate, event);
     if (m_printUserGestureStatus)
         m_delegate->printMessage(std::string("* ") + (WebUserGestureIndicator::isProcessingUserGesture() ? "" : "not ") + "handling user gesture\n");
+    if (m_isPersistent)
+        m_delegate->printMessage(std::string("TestPlugin: isPersistent\n"));
     return false;
 }
 
@@ -565,7 +648,7 @@ bool TestPlugin::handleDragStatusUpdate(WebDragStatus dragStatus, const WebDragD
         dragStatusName = "DragDrop";
         break;
     case WebDragStatusUnknown:
-        BLINK_ASSERT_NOT_REACHED();
+        NOTREACHED();
     }
     m_delegate->printMessage(std::string("Plugin received event: ") + dragStatusName + "\n");
     return false;
@@ -582,4 +665,23 @@ const WebString& TestPlugin::mimeType()
     return kMimeType;
 }
 
+const WebString& TestPlugin::canCreateWithoutRendererMimeType()
+{
+    const CR_DEFINE_STATIC_LOCAL(WebString, kCanCreateWithoutRendererMimeType, ("application/x-webkit-test-webplugin-can-create-without-renderer"));
+    return kCanCreateWithoutRendererMimeType;
+}
+
+const WebString& TestPlugin::pluginPersistsMimeType()
+{
+    const CR_DEFINE_STATIC_LOCAL(WebString, kPluginPersistsMimeType, ("application/x-webkit-test-webplugin-persistent"));
+    return kPluginPersistsMimeType;
 }
+
+bool TestPlugin::isSupportedMimeType(const WebString& mimeType)
+{
+    return mimeType == TestPlugin::mimeType()
+           || mimeType == pluginPersistsMimeType()
+           || mimeType == canCreateWithoutRendererMimeType();
+}
+
+}  // namespace content