Index: content/shell/renderer/test_runner/test_plugin.cc |
diff --git a/content/shell/renderer/test_runner/test_plugin.cc b/content/shell/renderer/test_runner/test_plugin.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2572c4abebcdbed3dabecefa6c72542cb67cef13 |
--- /dev/null |
+++ b/content/shell/renderer/test_runner/test_plugin.cc |
@@ -0,0 +1,763 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/shell/renderer/test_runner/test_plugin.h" |
+ |
+#include "base/basictypes.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" |
+#include "third_party/WebKit/public/web/WebFrame.h" |
+#include "third_party/WebKit/public/web/WebInputEvent.h" |
+#include "third_party/WebKit/public/web/WebKit.h" |
+#include "third_party/WebKit/public/web/WebPluginParams.h" |
+#include "third_party/WebKit/public/web/WebTouchPoint.h" |
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+// 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_DEPTH_TEST 0x0B71 |
+#define GL_BLEND 0x0BE2 |
+#define GL_SCISSOR_TEST 0x0B90 |
+#define GL_TEXTURE_2D 0x0DE1 |
+#define GL_FLOAT 0x1406 |
+#define GL_RGBA 0x1908 |
+#define GL_UNSIGNED_BYTE 0x1401 |
+#define GL_TEXTURE_MAG_FILTER 0x2800 |
+#define GL_TEXTURE_MIN_FILTER 0x2801 |
+#define GL_TEXTURE_WRAP_S 0x2802 |
+#define GL_TEXTURE_WRAP_T 0x2803 |
+#define GL_NEAREST 0x2600 |
+#define GL_COLOR_BUFFER_BIT 0x4000 |
+#define GL_CLAMP_TO_EDGE 0x812F |
+#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 |
+#define GL_COLOR_ATTACHMENT0 0x8CE0 |
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 |
+#define GL_FRAMEBUFFER 0x8D40 |
+ |
+void PremultiplyAlpha(const unsigned color_in[3], |
+ float alpha, |
+ float color_out[4]) { |
+ for (int i = 0; i < 3; ++i) |
+ color_out[i] = (color_in[i] / 255.0f) * alpha; |
+ |
+ color_out[3] = alpha; |
+} |
+ |
+const char* PointState(blink::WebTouchPoint::State state) { |
+ switch (state) { |
+ case blink::WebTouchPoint::StateReleased: |
+ return "Released"; |
+ case blink::WebTouchPoint::StatePressed: |
+ return "Pressed"; |
+ case blink::WebTouchPoint::StateMoved: |
+ return "Moved"; |
+ case blink::WebTouchPoint::StateCancelled: |
+ return "Cancelled"; |
+ default: |
+ return "Unknown"; |
+ } |
+} |
+ |
+void PrintTouchList(WebTestDelegate* delegate, |
+ const blink::WebTouchPoint* points, |
+ int length) { |
+ for (int i = 0; i < length; ++i) { |
+ delegate->printMessage(base::StringPrintf("* %.2f, %.2f: %s\n", |
+ points[i].position.x, |
+ points[i].position.y, |
+ PointState(points[i].state))); |
+ } |
+} |
+ |
+void PrintEventDetails(WebTestDelegate* delegate, |
+ const blink::WebInputEvent& event) { |
+ if (blink::WebInputEvent::isTouchEventType(event.type)) { |
+ const blink::WebTouchEvent& touch = |
+ static_cast<const blink::WebTouchEvent&>(event); |
+ PrintTouchList(delegate, touch.touches, touch.touchesLength); |
+ PrintTouchList(delegate, touch.changedTouches, touch.changedTouchesLength); |
+ PrintTouchList(delegate, touch.targetTouches, touch.targetTouchesLength); |
+ } else if (blink::WebInputEvent::isMouseEventType(event.type) || |
+ event.type == blink::WebInputEvent::MouseWheel) { |
+ const blink::WebMouseEvent& mouse = |
+ static_cast<const blink::WebMouseEvent&>(event); |
+ delegate->printMessage(base::StringPrintf("* %d, %d\n", mouse.x, mouse.y)); |
+ } else if (blink::WebInputEvent::isGestureEventType(event.type)) { |
+ const blink::WebGestureEvent& gesture = |
+ static_cast<const blink::WebGestureEvent&>(event); |
+ delegate->printMessage( |
+ base::StringPrintf("* %d, %d\n", gesture.x, gesture.y)); |
+ } |
+} |
+ |
+blink::WebPluginContainer::TouchEventRequestType ParseTouchEventRequestType( |
+ const blink::WebString& string) { |
+ if (string == blink::WebString::fromUTF8("raw")) |
+ return blink::WebPluginContainer::TouchEventRequestTypeRaw; |
+ if (string == blink::WebString::fromUTF8("synthetic")) |
+ return blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse; |
+ return blink::WebPluginContainer::TouchEventRequestTypeNone; |
+} |
+ |
+void DeferredDelete(void* context) { |
+ TestPlugin* plugin = static_cast<TestPlugin*>(context); |
+ delete plugin; |
+} |
+ |
+} // namespace |
+ |
+TestPlugin::TestPlugin(blink::WebFrame* frame, |
+ const blink::WebPluginParams& params, |
+ WebTestDelegate* delegate) |
+ : frame_(frame), |
+ delegate_(delegate), |
+ container_(0), |
+ context_(0), |
+ color_texture_(0), |
+ mailbox_changed_(false), |
+ framebuffer_(0), |
+ touch_event_request_( |
+ blink::WebPluginContainer::TouchEventRequestTypeNone), |
+ re_request_touch_events_(false), |
+ print_event_details_(false), |
+ print_user_gesture_status_(false), |
+ can_process_drag_(false), |
+ is_persistent_(params.mimeType == PluginPersistsMimeType()), |
+ can_create_without_renderer_(params.mimeType == |
+ CanCreateWithoutRendererMimeType()) { |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributePrimitive, ("primitive")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributeBackgroundColor, ("background-color")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributePrimitiveColor, ("primitive-color")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributeOpacity, ("opacity")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributeAcceptsTouch, ("accepts-touch")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributeReRequestTouchEvents, ("re-request-touch")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributePrintEventDetails, ("print-event-details")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kAttributeCanProcessDrag, ("can-process-drag")); |
+ const CR_DEFINE_STATIC_LOCAL(blink::WebString, |
+ kAttributePrintUserGestureStatus, |
+ ("print-user-gesture-status")); |
+ |
+ DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); |
+ size_t size = params.attributeNames.size(); |
+ for (size_t i = 0; i < size; ++i) { |
+ const blink::WebString& attribute_name = params.attributeNames[i]; |
+ const blink::WebString& attribute_value = params.attributeValues[i]; |
+ |
+ if (attribute_name == kAttributePrimitive) |
+ scene_.primitive = ParsePrimitive(attribute_value); |
+ else if (attribute_name == kAttributeBackgroundColor) |
+ ParseColor(attribute_value, scene_.background_color); |
+ else if (attribute_name == kAttributePrimitiveColor) |
+ ParseColor(attribute_value, scene_.primitive_color); |
+ else if (attribute_name == kAttributeOpacity) |
+ scene_.opacity = ParseOpacity(attribute_value); |
+ else if (attribute_name == kAttributeAcceptsTouch) |
+ touch_event_request_ = ParseTouchEventRequestType(attribute_value); |
+ else if (attribute_name == kAttributeReRequestTouchEvents) |
+ re_request_touch_events_ = ParseBoolean(attribute_value); |
+ else if (attribute_name == kAttributePrintEventDetails) |
+ print_event_details_ = ParseBoolean(attribute_value); |
+ else if (attribute_name == kAttributeCanProcessDrag) |
+ can_process_drag_ = ParseBoolean(attribute_value); |
+ else if (attribute_name == kAttributePrintUserGestureStatus) |
+ print_user_gesture_status_ = ParseBoolean(attribute_value); |
+ } |
+ if (can_create_without_renderer_) |
+ delegate_->printMessage( |
+ std::string("TestPlugin: canCreateWithoutRenderer\n")); |
+} |
+ |
+TestPlugin::~TestPlugin() { |
+} |
+ |
+bool TestPlugin::initialize(blink::WebPluginContainer* container) { |
+ blink::WebGraphicsContext3D::Attributes attrs; |
+ context_ = |
+ blink::Platform::current()->createOffscreenGraphicsContext3D(attrs); |
+ |
+ if (!InitScene()) |
+ return false; |
+ |
+ layer_ = cc::TextureLayer::CreateForMailbox(this); |
+ web_layer_ = make_scoped_ptr(InstantiateWebLayer(layer_)); |
+ container_ = container; |
+ container_->setWebLayer(web_layer_.get()); |
+ if (re_request_touch_events_) { |
+ container_->requestTouchEventType( |
+ blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse); |
+ container_->requestTouchEventType( |
+ blink::WebPluginContainer::TouchEventRequestTypeRaw); |
+ } |
+ container_->requestTouchEventType(touch_event_request_); |
+ container_->setWantsWheelEvents(true); |
+ return true; |
+} |
+ |
+void TestPlugin::destroy() { |
+ if (layer_.get()) |
+ layer_->ClearTexture(); |
+ if (container_) |
+ container_->setWebLayer(0); |
+ web_layer_.reset(); |
+ layer_ = NULL; |
+ DestroyScene(); |
+ |
+ delete context_; |
+ context_ = 0; |
+ |
+ container_ = 0; |
+ frame_ = 0; |
+ |
+ blink::Platform::current()->callOnMainThread(DeferredDelete, this); |
+} |
+ |
+NPObject* TestPlugin::scriptableObject() { |
+ return 0; |
+} |
+ |
+bool TestPlugin::canProcessDrag() const { |
+ return can_process_drag_; |
+} |
+ |
+void TestPlugin::updateGeometry( |
+ const blink::WebRect& frame_rect, |
+ const blink::WebRect& clip_rect, |
+ const blink::WebVector<blink::WebRect>& cut_outs_rects, |
+ bool is_visible) { |
+ if (clip_rect == rect_) |
+ return; |
+ rect_ = clip_rect; |
+ |
+ if (rect_.isEmpty()) { |
+ texture_mailbox_ = cc::TextureMailbox(); |
+ } else if (context_) { |
+ context_->viewport(0, 0, rect_.width, rect_.height); |
+ |
+ context_->bindTexture(GL_TEXTURE_2D, color_texture_); |
+ context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
+ context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
+ context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
+ context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
+ context_->texImage2D(GL_TEXTURE_2D, |
+ 0, |
+ GL_RGBA, |
+ rect_.width, |
+ rect_.height, |
+ 0, |
+ GL_RGBA, |
+ GL_UNSIGNED_BYTE, |
+ 0); |
+ context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer_); |
+ context_->framebufferTexture2D( |
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_, 0); |
+ |
+ DrawSceneGL(); |
+ |
+ gpu::Mailbox mailbox; |
+ context_->genMailboxCHROMIUM(mailbox.name); |
+ context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
+ context_->flush(); |
+ uint32 sync_point = context_->insertSyncPoint(); |
+ texture_mailbox_ = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point); |
+ } else { |
+ size_t bytes = 4 * rect_.width * rect_.height; |
+ scoped_ptr<base::SharedMemory> bitmap = |
+ RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes); |
+ if (!bitmap->Map(bytes)) { |
+ texture_mailbox_ = cc::TextureMailbox(); |
+ } else { |
+ DrawSceneSoftware(bitmap->memory(), bytes); |
+ texture_mailbox_ = cc::TextureMailbox( |
+ bitmap.get(), gfx::Size(rect_.width, rect_.height)); |
+ shared_bitmap_ = bitmap.Pass(); |
+ } |
+ } |
+ |
+ mailbox_changed_ = true; |
+ layer_->SetNeedsDisplay(); |
+} |
+ |
+bool TestPlugin::acceptsInputEvents() { |
+ return true; |
+} |
+ |
+bool TestPlugin::isPlaceholder() { |
+ return false; |
+} |
+ |
+static void IgnoreReleaseCallback(uint32 sync_point, bool lost) { |
+} |
+ |
+static void ReleaseSharedMemory(scoped_ptr<base::SharedMemory> bitmap, |
+ uint32 sync_point, |
+ bool lost) { |
+} |
+ |
+bool TestPlugin::PrepareTextureMailbox( |
+ cc::TextureMailbox* mailbox, |
+ scoped_ptr<cc::SingleReleaseCallback>* release_callback, |
+ bool use_shared_memory) { |
+ if (!mailbox_changed_) |
+ return false; |
+ *mailbox = texture_mailbox_; |
+ if (texture_mailbox_.IsTexture()) { |
+ *release_callback = |
+ cc::SingleReleaseCallback::Create(base::Bind(&IgnoreReleaseCallback)); |
+ } else { |
+ *release_callback = cc::SingleReleaseCallback::Create( |
+ base::Bind(&ReleaseSharedMemory, base::Passed(&shared_bitmap_))); |
+ } |
+ mailbox_changed_ = false; |
+ return true; |
+} |
+ |
+TestPlugin::Primitive TestPlugin::ParsePrimitive( |
+ const blink::WebString& string) { |
+ const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveNone, ("none")); |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kPrimitiveTriangle, ("triangle")); |
+ |
+ Primitive primitive = PrimitiveNone; |
+ if (string == kPrimitiveNone) |
+ primitive = PrimitiveNone; |
+ else if (string == kPrimitiveTriangle) |
+ primitive = PrimitiveTriangle; |
+ else |
+ NOTREACHED(); |
+ return primitive; |
+} |
+ |
+// FIXME: This method should already exist. Use it. |
+// For now just parse primary colors. |
+void TestPlugin::ParseColor(const blink::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 |
+ NOTREACHED(); |
+} |
+ |
+float TestPlugin::ParseOpacity(const blink::WebString& string) { |
+ return static_cast<float>(atof(string.utf8().data())); |
+} |
+ |
+bool TestPlugin::ParseBoolean(const blink::WebString& string) { |
+ const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveTrue, ("true")); |
+ return string == kPrimitiveTrue; |
+} |
+ |
+bool TestPlugin::InitScene() { |
+ if (!context_) |
+ return true; |
+ |
+ float color[4]; |
+ PremultiplyAlpha(scene_.background_color, scene_.opacity, color); |
+ |
+ color_texture_ = context_->createTexture(); |
+ framebuffer_ = context_->createFramebuffer(); |
+ |
+ context_->viewport(0, 0, rect_.width, rect_.height); |
+ context_->disable(GL_DEPTH_TEST); |
+ context_->disable(GL_SCISSOR_TEST); |
+ |
+ context_->clearColor(color[0], color[1], color[2], color[3]); |
+ |
+ context_->enable(GL_BLEND); |
+ context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
+ |
+ return scene_.primitive != PrimitiveNone ? InitProgram() && InitPrimitive() |
+ : true; |
+} |
+ |
+void TestPlugin::DrawSceneGL() { |
+ context_->viewport(0, 0, rect_.width, rect_.height); |
+ context_->clear(GL_COLOR_BUFFER_BIT); |
+ |
+ if (scene_.primitive != PrimitiveNone) |
+ DrawPrimitive(); |
+} |
+ |
+void TestPlugin::DrawSceneSoftware(void* memory, size_t bytes) { |
+ DCHECK_EQ(bytes, rect_.width * rect_.height * 4u); |
+ |
+ SkColor background_color = |
+ SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), |
+ scene_.background_color[0], |
+ scene_.background_color[1], |
+ scene_.background_color[2]); |
+ |
+ const SkImageInfo info = |
+ SkImageInfo::MakeN32Premul(rect_.width, rect_.height); |
+ SkBitmap bitmap; |
+ bitmap.installPixels(info, memory, info.minRowBytes()); |
+ SkCanvas canvas(bitmap); |
+ canvas.clear(background_color); |
+ |
+ if (scene_.primitive != PrimitiveNone) { |
+ DCHECK_EQ(PrimitiveTriangle, scene_.primitive); |
+ SkColor foreground_color = |
+ SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), |
+ scene_.primitive_color[0], |
+ scene_.primitive_color[1], |
+ scene_.primitive_color[2]); |
+ SkPath triangle_path; |
+ triangle_path.moveTo(0.5f * rect_.width, 0.9f * rect_.height); |
+ triangle_path.lineTo(0.1f * rect_.width, 0.1f * rect_.height); |
+ triangle_path.lineTo(0.9f * rect_.width, 0.1f * rect_.height); |
+ SkPaint paint; |
+ paint.setColor(foreground_color); |
+ paint.setStyle(SkPaint::kFill_Style); |
+ canvas.drawPath(triangle_path, paint); |
+ } |
+} |
+ |
+void TestPlugin::DestroyScene() { |
+ if (scene_.program) { |
+ context_->deleteProgram(scene_.program); |
+ scene_.program = 0; |
+ } |
+ if (scene_.vbo) { |
+ context_->deleteBuffer(scene_.vbo); |
+ scene_.vbo = 0; |
+ } |
+ |
+ if (framebuffer_) { |
+ context_->deleteFramebuffer(framebuffer_); |
+ framebuffer_ = 0; |
+ } |
+ |
+ if (color_texture_) { |
+ context_->deleteTexture(color_texture_); |
+ color_texture_ = 0; |
+ } |
+} |
+ |
+bool TestPlugin::InitProgram() { |
+ const std::string vertex_source( |
+ "attribute vec4 position; \n" |
+ "void main() { \n" |
+ " gl_Position = position; \n" |
+ "} \n"); |
+ |
+ const std::string fragment_source( |
+ "precision mediump float; \n" |
+ "uniform vec4 color; \n" |
+ "void main() { \n" |
+ " gl_FragColor = color; \n" |
+ "} \n"); |
+ |
+ scene_.program = LoadProgram(vertex_source, fragment_source); |
+ if (!scene_.program) |
+ return false; |
+ |
+ scene_.color_location = context_->getUniformLocation(scene_.program, "color"); |
+ scene_.position_location = |
+ context_->getAttribLocation(scene_.program, "position"); |
+ return true; |
+} |
+ |
+bool TestPlugin::InitPrimitive() { |
+ DCHECK_EQ(scene_.primitive, PrimitiveTriangle); |
+ |
+ scene_.vbo = context_->createBuffer(); |
+ if (!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}; |
+ context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); |
+ context_->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW); |
+ context_->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); |
+ return true; |
+} |
+ |
+void TestPlugin::DrawPrimitive() { |
+ DCHECK_EQ(scene_.primitive, PrimitiveTriangle); |
+ DCHECK(scene_.vbo); |
+ DCHECK(scene_.program); |
+ |
+ context_->useProgram(scene_.program); |
+ |
+ // Bind primitive color. |
+ float color[4]; |
+ PremultiplyAlpha(scene_.primitive_color, scene_.opacity, color); |
+ context_->uniform4f( |
+ scene_.color_location, color[0], color[1], color[2], color[3]); |
+ |
+ // Bind primitive vertices. |
+ context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); |
+ context_->enableVertexAttribArray(scene_.position_location); |
+ context_->vertexAttribPointer( |
+ scene_.position_location, 3, GL_FLOAT, GL_FALSE, 0, 0); |
+ context_->drawArrays(GL_TRIANGLES, 0, 3); |
+} |
+ |
+unsigned TestPlugin::LoadShader(unsigned type, const std::string& source) { |
+ unsigned shader = context_->createShader(type); |
+ if (shader) { |
+ context_->shaderSource(shader, source.data()); |
+ context_->compileShader(shader); |
+ |
+ int compiled = 0; |
+ context_->getShaderiv(shader, GL_COMPILE_STATUS, &compiled); |
+ if (!compiled) { |
+ context_->deleteShader(shader); |
+ shader = 0; |
+ } |
+ } |
+ return shader; |
+} |
+ |
+unsigned TestPlugin::LoadProgram(const std::string& vertex_source, |
+ const std::string& fragment_source) { |
+ unsigned vertex_shader = LoadShader(GL_VERTEX_SHADER, vertex_source); |
+ unsigned fragment_shader = LoadShader(GL_FRAGMENT_SHADER, fragment_source); |
+ unsigned program = context_->createProgram(); |
+ if (vertex_shader && fragment_shader && program) { |
+ context_->attachShader(program, vertex_shader); |
+ context_->attachShader(program, fragment_shader); |
+ context_->linkProgram(program); |
+ |
+ int linked = 0; |
+ context_->getProgramiv(program, GL_LINK_STATUS, &linked); |
+ if (!linked) { |
+ context_->deleteProgram(program); |
+ program = 0; |
+ } |
+ } |
+ if (vertex_shader) |
+ context_->deleteShader(vertex_shader); |
+ if (fragment_shader) |
+ context_->deleteShader(fragment_shader); |
+ |
+ return program; |
+} |
+ |
+bool TestPlugin::handleInputEvent(const blink::WebInputEvent& event, |
+ blink::WebCursorInfo& info) { |
+ const char* event_name = 0; |
+ switch (event.type) { |
+ case blink::WebInputEvent::Undefined: |
+ event_name = "unknown"; |
+ break; |
+ |
+ case blink::WebInputEvent::MouseDown: |
+ event_name = "MouseDown"; |
+ break; |
+ case blink::WebInputEvent::MouseUp: |
+ event_name = "MouseUp"; |
+ break; |
+ case blink::WebInputEvent::MouseMove: |
+ event_name = "MouseMove"; |
+ break; |
+ case blink::WebInputEvent::MouseEnter: |
+ event_name = "MouseEnter"; |
+ break; |
+ case blink::WebInputEvent::MouseLeave: |
+ event_name = "MouseLeave"; |
+ break; |
+ case blink::WebInputEvent::ContextMenu: |
+ event_name = "ContextMenu"; |
+ break; |
+ |
+ case blink::WebInputEvent::MouseWheel: |
+ event_name = "MouseWheel"; |
+ break; |
+ |
+ case blink::WebInputEvent::RawKeyDown: |
+ event_name = "RawKeyDown"; |
+ break; |
+ case blink::WebInputEvent::KeyDown: |
+ event_name = "KeyDown"; |
+ break; |
+ case blink::WebInputEvent::KeyUp: |
+ event_name = "KeyUp"; |
+ break; |
+ case blink::WebInputEvent::Char: |
+ event_name = "Char"; |
+ break; |
+ |
+ case blink::WebInputEvent::GestureScrollBegin: |
+ event_name = "GestureScrollBegin"; |
+ break; |
+ case blink::WebInputEvent::GestureScrollEnd: |
+ event_name = "GestureScrollEnd"; |
+ break; |
+ case blink::WebInputEvent::GestureScrollUpdateWithoutPropagation: |
+ case blink::WebInputEvent::GestureScrollUpdate: |
+ event_name = "GestureScrollUpdate"; |
+ break; |
+ case blink::WebInputEvent::GestureFlingStart: |
+ event_name = "GestureFlingStart"; |
+ break; |
+ case blink::WebInputEvent::GestureFlingCancel: |
+ event_name = "GestureFlingCancel"; |
+ break; |
+ case blink::WebInputEvent::GestureTap: |
+ event_name = "GestureTap"; |
+ break; |
+ case blink::WebInputEvent::GestureTapUnconfirmed: |
+ event_name = "GestureTapUnconfirmed"; |
+ break; |
+ case blink::WebInputEvent::GestureTapDown: |
+ event_name = "GestureTapDown"; |
+ break; |
+ case blink::WebInputEvent::GestureShowPress: |
+ event_name = "GestureShowPress"; |
+ break; |
+ case blink::WebInputEvent::GestureTapCancel: |
+ event_name = "GestureTapCancel"; |
+ break; |
+ case blink::WebInputEvent::GestureDoubleTap: |
+ event_name = "GestureDoubleTap"; |
+ break; |
+ case blink::WebInputEvent::GestureTwoFingerTap: |
+ event_name = "GestureTwoFingerTap"; |
+ break; |
+ case blink::WebInputEvent::GestureLongPress: |
+ event_name = "GestureLongPress"; |
+ break; |
+ case blink::WebInputEvent::GestureLongTap: |
+ event_name = "GestureLongTap"; |
+ break; |
+ case blink::WebInputEvent::GesturePinchBegin: |
+ event_name = "GesturePinchBegin"; |
+ break; |
+ case blink::WebInputEvent::GesturePinchEnd: |
+ event_name = "GesturePinchEnd"; |
+ break; |
+ case blink::WebInputEvent::GesturePinchUpdate: |
+ event_name = "GesturePinchUpdate"; |
+ break; |
+ |
+ case blink::WebInputEvent::TouchStart: |
+ event_name = "TouchStart"; |
+ break; |
+ case blink::WebInputEvent::TouchMove: |
+ event_name = "TouchMove"; |
+ break; |
+ case blink::WebInputEvent::TouchEnd: |
+ event_name = "TouchEnd"; |
+ break; |
+ case blink::WebInputEvent::TouchCancel: |
+ event_name = "TouchCancel"; |
+ break; |
+ } |
+ |
+ delegate_->printMessage(std::string("Plugin received event: ") + |
+ (event_name ? event_name : "unknown") + "\n"); |
+ if (print_event_details_) |
+ PrintEventDetails(delegate_, event); |
+ if (print_user_gesture_status_) |
+ delegate_->printMessage( |
+ std::string("* ") + |
+ (blink::WebUserGestureIndicator::isProcessingUserGesture() ? "" |
+ : "not ") + |
+ "handling user gesture\n"); |
+ if (is_persistent_) |
+ delegate_->printMessage(std::string("TestPlugin: isPersistent\n")); |
+ return false; |
+} |
+ |
+bool TestPlugin::handleDragStatusUpdate( |
+ blink::WebDragStatus drag_status, |
+ const blink::WebDragData& data, |
+ blink::WebDragOperationsMask mask, |
+ const blink::WebPoint& position, |
+ const blink::WebPoint& screen_position) { |
+ const char* drag_status_name = 0; |
+ switch (drag_status) { |
+ case blink::WebDragStatusEnter: |
+ drag_status_name = "DragEnter"; |
+ break; |
+ case blink::WebDragStatusOver: |
+ drag_status_name = "DragOver"; |
+ break; |
+ case blink::WebDragStatusLeave: |
+ drag_status_name = "DragLeave"; |
+ break; |
+ case blink::WebDragStatusDrop: |
+ drag_status_name = "DragDrop"; |
+ break; |
+ case blink::WebDragStatusUnknown: |
+ NOTREACHED(); |
+ } |
+ delegate_->printMessage(std::string("Plugin received event: ") + |
+ drag_status_name + "\n"); |
+ return false; |
+} |
+ |
+TestPlugin* TestPlugin::create(blink::WebFrame* frame, |
+ const blink::WebPluginParams& params, |
+ WebTestDelegate* delegate) { |
+ return new TestPlugin(frame, params, delegate); |
+} |
+ |
+const blink::WebString& TestPlugin::MimeType() { |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, kMimeType, ("application/x-webkit-test-webplugin")); |
+ return kMimeType; |
+} |
+ |
+const blink::WebString& TestPlugin::CanCreateWithoutRendererMimeType() { |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, |
+ kCanCreateWithoutRendererMimeType, |
+ ("application/x-webkit-test-webplugin-can-create-without-renderer")); |
+ return kCanCreateWithoutRendererMimeType; |
+} |
+ |
+const blink::WebString& TestPlugin::PluginPersistsMimeType() { |
+ const CR_DEFINE_STATIC_LOCAL( |
+ blink::WebString, |
+ kPluginPersistsMimeType, |
+ ("application/x-webkit-test-webplugin-persistent")); |
+ return kPluginPersistsMimeType; |
+} |
+ |
+bool TestPlugin::IsSupportedMimeType(const blink::WebString& mime_type) { |
+ return mime_type == TestPlugin::MimeType() || |
+ mime_type == PluginPersistsMimeType() || |
+ mime_type == CanCreateWithoutRendererMimeType(); |
+} |
+ |
+} // namespace content |