OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/shell/renderer/test_runner/test_plugin.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/bind.h" | |
9 #include "base/logging.h" | |
10 #include "base/memory/shared_memory.h" | |
11 #include "base/strings/stringprintf.h" | |
12 #include "cc/resources/shared_bitmap_manager.h" | |
13 #include "content/shell/renderer/test_runner/web_test_delegate.h" | |
14 #include "third_party/skia/include/core/SkBitmap.h" | |
15 #include "third_party/skia/include/core/SkCanvas.h" | |
16 #include "third_party/skia/include/core/SkColor.h" | |
17 #include "third_party/WebKit/public/platform/Platform.h" | |
18 #include "third_party/WebKit/public/platform/WebCompositorSupport.h" | |
19 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" | |
20 #include "third_party/WebKit/public/platform/WebThread.h" | |
21 #include "third_party/WebKit/public/platform/WebTraceLocation.h" | |
22 #include "third_party/WebKit/public/web/WebFrame.h" | |
23 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
24 #include "third_party/WebKit/public/web/WebKit.h" | |
25 #include "third_party/WebKit/public/web/WebPluginParams.h" | |
26 #include "third_party/WebKit/public/web/WebTouchPoint.h" | |
27 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | |
28 | |
29 namespace content { | |
30 | |
31 namespace { | |
32 | |
33 // GLenum values copied from gl2.h. | |
34 #define GL_FALSE 0 | |
35 #define GL_TRUE 1 | |
36 #define GL_ONE 1 | |
37 #define GL_TRIANGLES 0x0004 | |
38 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 | |
39 #define GL_DEPTH_TEST 0x0B71 | |
40 #define GL_BLEND 0x0BE2 | |
41 #define GL_SCISSOR_TEST 0x0B90 | |
42 #define GL_TEXTURE_2D 0x0DE1 | |
43 #define GL_FLOAT 0x1406 | |
44 #define GL_RGBA 0x1908 | |
45 #define GL_UNSIGNED_BYTE 0x1401 | |
46 #define GL_TEXTURE_MAG_FILTER 0x2800 | |
47 #define GL_TEXTURE_MIN_FILTER 0x2801 | |
48 #define GL_TEXTURE_WRAP_S 0x2802 | |
49 #define GL_TEXTURE_WRAP_T 0x2803 | |
50 #define GL_NEAREST 0x2600 | |
51 #define GL_COLOR_BUFFER_BIT 0x4000 | |
52 #define GL_CLAMP_TO_EDGE 0x812F | |
53 #define GL_ARRAY_BUFFER 0x8892 | |
54 #define GL_STATIC_DRAW 0x88E4 | |
55 #define GL_FRAGMENT_SHADER 0x8B30 | |
56 #define GL_VERTEX_SHADER 0x8B31 | |
57 #define GL_COMPILE_STATUS 0x8B81 | |
58 #define GL_LINK_STATUS 0x8B82 | |
59 #define GL_COLOR_ATTACHMENT0 0x8CE0 | |
60 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 | |
61 #define GL_FRAMEBUFFER 0x8D40 | |
62 | |
63 void PremultiplyAlpha(const unsigned color_in[3], | |
64 float alpha, | |
65 float color_out[4]) { | |
66 for (int i = 0; i < 3; ++i) | |
67 color_out[i] = (color_in[i] / 255.0f) * alpha; | |
68 | |
69 color_out[3] = alpha; | |
70 } | |
71 | |
72 const char* PointState(blink::WebTouchPoint::State state) { | |
73 switch (state) { | |
74 case blink::WebTouchPoint::StateReleased: | |
75 return "Released"; | |
76 case blink::WebTouchPoint::StatePressed: | |
77 return "Pressed"; | |
78 case blink::WebTouchPoint::StateMoved: | |
79 return "Moved"; | |
80 case blink::WebTouchPoint::StateCancelled: | |
81 return "Cancelled"; | |
82 default: | |
83 return "Unknown"; | |
84 } | |
85 } | |
86 | |
87 void PrintTouchList(WebTestDelegate* delegate, | |
88 const blink::WebTouchPoint* points, | |
89 int length) { | |
90 for (int i = 0; i < length; ++i) { | |
91 delegate->PrintMessage(base::StringPrintf("* %.2f, %.2f: %s\n", | |
92 points[i].position.x, | |
93 points[i].position.y, | |
94 PointState(points[i].state))); | |
95 } | |
96 } | |
97 | |
98 void PrintEventDetails(WebTestDelegate* delegate, | |
99 const blink::WebInputEvent& event) { | |
100 if (blink::WebInputEvent::isTouchEventType(event.type)) { | |
101 const blink::WebTouchEvent& touch = | |
102 static_cast<const blink::WebTouchEvent&>(event); | |
103 PrintTouchList(delegate, touch.touches, touch.touchesLength); | |
104 } else if (blink::WebInputEvent::isMouseEventType(event.type) || | |
105 event.type == blink::WebInputEvent::MouseWheel) { | |
106 const blink::WebMouseEvent& mouse = | |
107 static_cast<const blink::WebMouseEvent&>(event); | |
108 delegate->PrintMessage(base::StringPrintf("* %d, %d\n", mouse.x, mouse.y)); | |
109 } else if (blink::WebInputEvent::isGestureEventType(event.type)) { | |
110 const blink::WebGestureEvent& gesture = | |
111 static_cast<const blink::WebGestureEvent&>(event); | |
112 delegate->PrintMessage( | |
113 base::StringPrintf("* %d, %d\n", gesture.x, gesture.y)); | |
114 } | |
115 } | |
116 | |
117 blink::WebPluginContainer::TouchEventRequestType ParseTouchEventRequestType( | |
118 const blink::WebString& string) { | |
119 if (string == blink::WebString::fromUTF8("raw")) | |
120 return blink::WebPluginContainer::TouchEventRequestTypeRaw; | |
121 if (string == blink::WebString::fromUTF8("synthetic")) | |
122 return blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse; | |
123 return blink::WebPluginContainer::TouchEventRequestTypeNone; | |
124 } | |
125 | |
126 class DeferredDeleteTask : public blink::WebThread::Task { | |
127 public: | |
128 DeferredDeleteTask(scoped_ptr<TestPlugin> plugin) : plugin_(plugin.Pass()) {} | |
129 | |
130 void run() override {} | |
131 | |
132 private: | |
133 scoped_ptr<TestPlugin> plugin_; | |
134 }; | |
135 | |
136 } // namespace | |
137 | |
138 TestPlugin::TestPlugin(blink::WebFrame* frame, | |
139 const blink::WebPluginParams& params, | |
140 WebTestDelegate* delegate) | |
141 : frame_(frame), | |
142 delegate_(delegate), | |
143 container_(0), | |
144 context_(0), | |
145 color_texture_(0), | |
146 mailbox_changed_(false), | |
147 framebuffer_(0), | |
148 touch_event_request_( | |
149 blink::WebPluginContainer::TouchEventRequestTypeNone), | |
150 re_request_touch_events_(false), | |
151 print_event_details_(false), | |
152 print_user_gesture_status_(false), | |
153 can_process_drag_(false), | |
154 supports_keyboard_focus_(false), | |
155 is_persistent_(params.mimeType == PluginPersistsMimeType()), | |
156 can_create_without_renderer_(params.mimeType == | |
157 CanCreateWithoutRendererMimeType()) { | |
158 const CR_DEFINE_STATIC_LOCAL( | |
159 blink::WebString, kAttributePrimitive, ("primitive")); | |
160 const CR_DEFINE_STATIC_LOCAL( | |
161 blink::WebString, kAttributeBackgroundColor, ("background-color")); | |
162 const CR_DEFINE_STATIC_LOCAL( | |
163 blink::WebString, kAttributePrimitiveColor, ("primitive-color")); | |
164 const CR_DEFINE_STATIC_LOCAL( | |
165 blink::WebString, kAttributeOpacity, ("opacity")); | |
166 const CR_DEFINE_STATIC_LOCAL( | |
167 blink::WebString, kAttributeAcceptsTouch, ("accepts-touch")); | |
168 const CR_DEFINE_STATIC_LOCAL( | |
169 blink::WebString, kAttributeReRequestTouchEvents, ("re-request-touch")); | |
170 const CR_DEFINE_STATIC_LOCAL( | |
171 blink::WebString, kAttributePrintEventDetails, ("print-event-details")); | |
172 const CR_DEFINE_STATIC_LOCAL( | |
173 blink::WebString, kAttributeCanProcessDrag, ("can-process-drag")); | |
174 const CR_DEFINE_STATIC_LOCAL(blink::WebString, | |
175 kAttributeSupportsKeyboardFocus, | |
176 ("supports-keyboard-focus")); | |
177 const CR_DEFINE_STATIC_LOCAL(blink::WebString, | |
178 kAttributePrintUserGestureStatus, | |
179 ("print-user-gesture-status")); | |
180 | |
181 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); | |
182 size_t size = params.attributeNames.size(); | |
183 for (size_t i = 0; i < size; ++i) { | |
184 const blink::WebString& attribute_name = params.attributeNames[i]; | |
185 const blink::WebString& attribute_value = params.attributeValues[i]; | |
186 | |
187 if (attribute_name == kAttributePrimitive) | |
188 scene_.primitive = ParsePrimitive(attribute_value); | |
189 else if (attribute_name == kAttributeBackgroundColor) | |
190 ParseColor(attribute_value, scene_.background_color); | |
191 else if (attribute_name == kAttributePrimitiveColor) | |
192 ParseColor(attribute_value, scene_.primitive_color); | |
193 else if (attribute_name == kAttributeOpacity) | |
194 scene_.opacity = ParseOpacity(attribute_value); | |
195 else if (attribute_name == kAttributeAcceptsTouch) | |
196 touch_event_request_ = ParseTouchEventRequestType(attribute_value); | |
197 else if (attribute_name == kAttributeReRequestTouchEvents) | |
198 re_request_touch_events_ = ParseBoolean(attribute_value); | |
199 else if (attribute_name == kAttributePrintEventDetails) | |
200 print_event_details_ = ParseBoolean(attribute_value); | |
201 else if (attribute_name == kAttributeCanProcessDrag) | |
202 can_process_drag_ = ParseBoolean(attribute_value); | |
203 else if (attribute_name == kAttributeSupportsKeyboardFocus) | |
204 supports_keyboard_focus_ = ParseBoolean(attribute_value); | |
205 else if (attribute_name == kAttributePrintUserGestureStatus) | |
206 print_user_gesture_status_ = ParseBoolean(attribute_value); | |
207 } | |
208 if (can_create_without_renderer_) | |
209 delegate_->PrintMessage( | |
210 std::string("TestPlugin: canCreateWithoutRenderer\n")); | |
211 } | |
212 | |
213 TestPlugin::~TestPlugin() { | |
214 } | |
215 | |
216 bool TestPlugin::initialize(blink::WebPluginContainer* container) { | |
217 blink::WebGraphicsContext3D::Attributes attrs; | |
218 context_ = | |
219 blink::Platform::current()->createOffscreenGraphicsContext3D(attrs); | |
220 | |
221 if (!InitScene()) | |
222 return false; | |
223 | |
224 layer_ = delegate_->CreateTextureLayerForMailbox(this); | |
225 web_layer_ = make_scoped_ptr(delegate_->InstantiateWebLayer(layer_)); | |
226 container_ = container; | |
227 container_->setWebLayer(web_layer_.get()); | |
228 if (re_request_touch_events_) { | |
229 container_->requestTouchEventType( | |
230 blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse); | |
231 container_->requestTouchEventType( | |
232 blink::WebPluginContainer::TouchEventRequestTypeRaw); | |
233 } | |
234 container_->requestTouchEventType(touch_event_request_); | |
235 container_->setWantsWheelEvents(true); | |
236 return true; | |
237 } | |
238 | |
239 void TestPlugin::destroy() { | |
240 if (layer_.get()) | |
241 layer_->ClearTexture(); | |
242 if (container_) | |
243 container_->setWebLayer(0); | |
244 web_layer_.reset(); | |
245 layer_ = NULL; | |
246 DestroyScene(); | |
247 | |
248 delete context_; | |
249 context_ = 0; | |
250 | |
251 container_ = 0; | |
252 frame_ = 0; | |
253 | |
254 blink::Platform::current()->mainThread()->postTask( | |
255 blink::WebTraceLocation(__FUNCTION__, __FILE__), | |
256 new DeferredDeleteTask(make_scoped_ptr(this))); | |
257 } | |
258 | |
259 NPObject* TestPlugin::scriptableObject() { | |
260 return 0; | |
261 } | |
262 | |
263 bool TestPlugin::canProcessDrag() const { | |
264 return can_process_drag_; | |
265 } | |
266 | |
267 bool TestPlugin::supportsKeyboardFocus() const { | |
268 return supports_keyboard_focus_; | |
269 } | |
270 | |
271 void TestPlugin::updateGeometry( | |
272 const blink::WebRect& window_rect, | |
273 const blink::WebRect& clip_rect, | |
274 const blink::WebRect& unobscured_rect, | |
275 const blink::WebVector<blink::WebRect>& cut_outs_rects, | |
276 bool is_visible) { | |
277 if (clip_rect == rect_) | |
278 return; | |
279 rect_ = clip_rect; | |
280 | |
281 if (rect_.isEmpty()) { | |
282 texture_mailbox_ = cc::TextureMailbox(); | |
283 } else if (context_) { | |
284 context_->viewport(0, 0, rect_.width, rect_.height); | |
285 | |
286 context_->bindTexture(GL_TEXTURE_2D, color_texture_); | |
287 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
288 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
289 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
290 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
291 context_->texImage2D(GL_TEXTURE_2D, | |
292 0, | |
293 GL_RGBA, | |
294 rect_.width, | |
295 rect_.height, | |
296 0, | |
297 GL_RGBA, | |
298 GL_UNSIGNED_BYTE, | |
299 0); | |
300 context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer_); | |
301 context_->framebufferTexture2D( | |
302 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_, 0); | |
303 | |
304 DrawSceneGL(); | |
305 | |
306 gpu::Mailbox mailbox; | |
307 context_->genMailboxCHROMIUM(mailbox.name); | |
308 context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | |
309 context_->flush(); | |
310 uint32 sync_point = context_->insertSyncPoint(); | |
311 texture_mailbox_ = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point); | |
312 } else { | |
313 scoped_ptr<cc::SharedBitmap> bitmap = | |
314 delegate_->GetSharedBitmapManager()->AllocateSharedBitmap( | |
315 gfx::Rect(rect_).size()); | |
316 if (!bitmap) { | |
317 texture_mailbox_ = cc::TextureMailbox(); | |
318 } else { | |
319 DrawSceneSoftware(bitmap->pixels()); | |
320 texture_mailbox_ = cc::TextureMailbox( | |
321 bitmap.get(), gfx::Size(rect_.width, rect_.height)); | |
322 shared_bitmap_ = bitmap.Pass(); | |
323 } | |
324 } | |
325 | |
326 mailbox_changed_ = true; | |
327 layer_->SetNeedsDisplay(); | |
328 } | |
329 | |
330 bool TestPlugin::acceptsInputEvents() { | |
331 return true; | |
332 } | |
333 | |
334 bool TestPlugin::isPlaceholder() { | |
335 return false; | |
336 } | |
337 | |
338 static void IgnoreReleaseCallback(uint32 sync_point, bool lost) { | |
339 } | |
340 | |
341 static void ReleaseSharedMemory(scoped_ptr<cc::SharedBitmap> bitmap, | |
342 uint32 sync_point, | |
343 bool lost) { | |
344 } | |
345 | |
346 bool TestPlugin::PrepareTextureMailbox( | |
347 cc::TextureMailbox* mailbox, | |
348 scoped_ptr<cc::SingleReleaseCallback>* release_callback, | |
349 bool use_shared_memory) { | |
350 if (!mailbox_changed_) | |
351 return false; | |
352 *mailbox = texture_mailbox_; | |
353 if (texture_mailbox_.IsTexture()) { | |
354 *release_callback = | |
355 cc::SingleReleaseCallback::Create(base::Bind(&IgnoreReleaseCallback)); | |
356 } else if (texture_mailbox_.IsSharedMemory()) { | |
357 *release_callback = cc::SingleReleaseCallback::Create( | |
358 base::Bind(&ReleaseSharedMemory, base::Passed(&shared_bitmap_))); | |
359 } | |
360 mailbox_changed_ = false; | |
361 return true; | |
362 } | |
363 | |
364 TestPlugin::Primitive TestPlugin::ParsePrimitive( | |
365 const blink::WebString& string) { | |
366 const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveNone, ("none")); | |
367 const CR_DEFINE_STATIC_LOCAL( | |
368 blink::WebString, kPrimitiveTriangle, ("triangle")); | |
369 | |
370 Primitive primitive = PrimitiveNone; | |
371 if (string == kPrimitiveNone) | |
372 primitive = PrimitiveNone; | |
373 else if (string == kPrimitiveTriangle) | |
374 primitive = PrimitiveTriangle; | |
375 else | |
376 NOTREACHED(); | |
377 return primitive; | |
378 } | |
379 | |
380 // FIXME: This method should already exist. Use it. | |
381 // For now just parse primary colors. | |
382 void TestPlugin::ParseColor(const blink::WebString& string, unsigned color[3]) { | |
383 color[0] = color[1] = color[2] = 0; | |
384 if (string == "black") | |
385 return; | |
386 | |
387 if (string == "red") | |
388 color[0] = 255; | |
389 else if (string == "green") | |
390 color[1] = 255; | |
391 else if (string == "blue") | |
392 color[2] = 255; | |
393 else | |
394 NOTREACHED(); | |
395 } | |
396 | |
397 float TestPlugin::ParseOpacity(const blink::WebString& string) { | |
398 return static_cast<float>(atof(string.utf8().data())); | |
399 } | |
400 | |
401 bool TestPlugin::ParseBoolean(const blink::WebString& string) { | |
402 const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveTrue, ("true")); | |
403 return string == kPrimitiveTrue; | |
404 } | |
405 | |
406 bool TestPlugin::InitScene() { | |
407 if (!context_) | |
408 return true; | |
409 | |
410 float color[4]; | |
411 PremultiplyAlpha(scene_.background_color, scene_.opacity, color); | |
412 | |
413 color_texture_ = context_->createTexture(); | |
414 framebuffer_ = context_->createFramebuffer(); | |
415 | |
416 context_->viewport(0, 0, rect_.width, rect_.height); | |
417 context_->disable(GL_DEPTH_TEST); | |
418 context_->disable(GL_SCISSOR_TEST); | |
419 | |
420 context_->clearColor(color[0], color[1], color[2], color[3]); | |
421 | |
422 context_->enable(GL_BLEND); | |
423 context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | |
424 | |
425 return scene_.primitive != PrimitiveNone ? InitProgram() && InitPrimitive() | |
426 : true; | |
427 } | |
428 | |
429 void TestPlugin::DrawSceneGL() { | |
430 context_->viewport(0, 0, rect_.width, rect_.height); | |
431 context_->clear(GL_COLOR_BUFFER_BIT); | |
432 | |
433 if (scene_.primitive != PrimitiveNone) | |
434 DrawPrimitive(); | |
435 } | |
436 | |
437 void TestPlugin::DrawSceneSoftware(void* memory) { | |
438 SkColor background_color = | |
439 SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), | |
440 scene_.background_color[0], | |
441 scene_.background_color[1], | |
442 scene_.background_color[2]); | |
443 | |
444 const SkImageInfo info = | |
445 SkImageInfo::MakeN32Premul(rect_.width, rect_.height); | |
446 SkBitmap bitmap; | |
447 bitmap.installPixels(info, memory, info.minRowBytes()); | |
448 SkCanvas canvas(bitmap); | |
449 canvas.clear(background_color); | |
450 | |
451 if (scene_.primitive != PrimitiveNone) { | |
452 DCHECK_EQ(PrimitiveTriangle, scene_.primitive); | |
453 SkColor foreground_color = | |
454 SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), | |
455 scene_.primitive_color[0], | |
456 scene_.primitive_color[1], | |
457 scene_.primitive_color[2]); | |
458 SkPath triangle_path; | |
459 triangle_path.moveTo(0.5f * rect_.width, 0.9f * rect_.height); | |
460 triangle_path.lineTo(0.1f * rect_.width, 0.1f * rect_.height); | |
461 triangle_path.lineTo(0.9f * rect_.width, 0.1f * rect_.height); | |
462 SkPaint paint; | |
463 paint.setColor(foreground_color); | |
464 paint.setStyle(SkPaint::kFill_Style); | |
465 canvas.drawPath(triangle_path, paint); | |
466 } | |
467 } | |
468 | |
469 void TestPlugin::DestroyScene() { | |
470 if (scene_.program) { | |
471 context_->deleteProgram(scene_.program); | |
472 scene_.program = 0; | |
473 } | |
474 if (scene_.vbo) { | |
475 context_->deleteBuffer(scene_.vbo); | |
476 scene_.vbo = 0; | |
477 } | |
478 | |
479 if (framebuffer_) { | |
480 context_->deleteFramebuffer(framebuffer_); | |
481 framebuffer_ = 0; | |
482 } | |
483 | |
484 if (color_texture_) { | |
485 context_->deleteTexture(color_texture_); | |
486 color_texture_ = 0; | |
487 } | |
488 } | |
489 | |
490 bool TestPlugin::InitProgram() { | |
491 const std::string vertex_source( | |
492 "attribute vec4 position; \n" | |
493 "void main() { \n" | |
494 " gl_Position = position; \n" | |
495 "} \n"); | |
496 | |
497 const std::string fragment_source( | |
498 "precision mediump float; \n" | |
499 "uniform vec4 color; \n" | |
500 "void main() { \n" | |
501 " gl_FragColor = color; \n" | |
502 "} \n"); | |
503 | |
504 scene_.program = LoadProgram(vertex_source, fragment_source); | |
505 if (!scene_.program) | |
506 return false; | |
507 | |
508 scene_.color_location = context_->getUniformLocation(scene_.program, "color"); | |
509 scene_.position_location = | |
510 context_->getAttribLocation(scene_.program, "position"); | |
511 return true; | |
512 } | |
513 | |
514 bool TestPlugin::InitPrimitive() { | |
515 DCHECK_EQ(scene_.primitive, PrimitiveTriangle); | |
516 | |
517 scene_.vbo = context_->createBuffer(); | |
518 if (!scene_.vbo) | |
519 return false; | |
520 | |
521 const float vertices[] = {0.0f, 0.8f, 0.0f, -0.8f, -0.8f, | |
522 0.0f, 0.8f, -0.8f, 0.0f}; | |
523 context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); | |
524 context_->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW); | |
525 context_->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | |
526 return true; | |
527 } | |
528 | |
529 void TestPlugin::DrawPrimitive() { | |
530 DCHECK_EQ(scene_.primitive, PrimitiveTriangle); | |
531 DCHECK(scene_.vbo); | |
532 DCHECK(scene_.program); | |
533 | |
534 context_->useProgram(scene_.program); | |
535 | |
536 // Bind primitive color. | |
537 float color[4]; | |
538 PremultiplyAlpha(scene_.primitive_color, scene_.opacity, color); | |
539 context_->uniform4f( | |
540 scene_.color_location, color[0], color[1], color[2], color[3]); | |
541 | |
542 // Bind primitive vertices. | |
543 context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); | |
544 context_->enableVertexAttribArray(scene_.position_location); | |
545 context_->vertexAttribPointer( | |
546 scene_.position_location, 3, GL_FLOAT, GL_FALSE, 0, 0); | |
547 context_->drawArrays(GL_TRIANGLES, 0, 3); | |
548 } | |
549 | |
550 unsigned TestPlugin::LoadShader(unsigned type, const std::string& source) { | |
551 unsigned shader = context_->createShader(type); | |
552 if (shader) { | |
553 context_->shaderSource(shader, source.data()); | |
554 context_->compileShader(shader); | |
555 | |
556 int compiled = 0; | |
557 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compiled); | |
558 if (!compiled) { | |
559 context_->deleteShader(shader); | |
560 shader = 0; | |
561 } | |
562 } | |
563 return shader; | |
564 } | |
565 | |
566 unsigned TestPlugin::LoadProgram(const std::string& vertex_source, | |
567 const std::string& fragment_source) { | |
568 unsigned vertex_shader = LoadShader(GL_VERTEX_SHADER, vertex_source); | |
569 unsigned fragment_shader = LoadShader(GL_FRAGMENT_SHADER, fragment_source); | |
570 unsigned program = context_->createProgram(); | |
571 if (vertex_shader && fragment_shader && program) { | |
572 context_->attachShader(program, vertex_shader); | |
573 context_->attachShader(program, fragment_shader); | |
574 context_->linkProgram(program); | |
575 | |
576 int linked = 0; | |
577 context_->getProgramiv(program, GL_LINK_STATUS, &linked); | |
578 if (!linked) { | |
579 context_->deleteProgram(program); | |
580 program = 0; | |
581 } | |
582 } | |
583 if (vertex_shader) | |
584 context_->deleteShader(vertex_shader); | |
585 if (fragment_shader) | |
586 context_->deleteShader(fragment_shader); | |
587 | |
588 return program; | |
589 } | |
590 | |
591 bool TestPlugin::handleInputEvent(const blink::WebInputEvent& event, | |
592 blink::WebCursorInfo& info) { | |
593 const char* event_name = 0; | |
594 switch (event.type) { | |
595 case blink::WebInputEvent::Undefined: | |
596 event_name = "unknown"; | |
597 break; | |
598 | |
599 case blink::WebInputEvent::MouseDown: | |
600 event_name = "MouseDown"; | |
601 break; | |
602 case blink::WebInputEvent::MouseUp: | |
603 event_name = "MouseUp"; | |
604 break; | |
605 case blink::WebInputEvent::MouseMove: | |
606 event_name = "MouseMove"; | |
607 break; | |
608 case blink::WebInputEvent::MouseEnter: | |
609 event_name = "MouseEnter"; | |
610 break; | |
611 case blink::WebInputEvent::MouseLeave: | |
612 event_name = "MouseLeave"; | |
613 break; | |
614 case blink::WebInputEvent::ContextMenu: | |
615 event_name = "ContextMenu"; | |
616 break; | |
617 | |
618 case blink::WebInputEvent::MouseWheel: | |
619 event_name = "MouseWheel"; | |
620 break; | |
621 | |
622 case blink::WebInputEvent::RawKeyDown: | |
623 event_name = "RawKeyDown"; | |
624 break; | |
625 case blink::WebInputEvent::KeyDown: | |
626 event_name = "KeyDown"; | |
627 break; | |
628 case blink::WebInputEvent::KeyUp: | |
629 event_name = "KeyUp"; | |
630 break; | |
631 case blink::WebInputEvent::Char: | |
632 event_name = "Char"; | |
633 break; | |
634 | |
635 case blink::WebInputEvent::GestureScrollBegin: | |
636 event_name = "GestureScrollBegin"; | |
637 break; | |
638 case blink::WebInputEvent::GestureScrollEnd: | |
639 event_name = "GestureScrollEnd"; | |
640 break; | |
641 case blink::WebInputEvent::GestureScrollUpdate: | |
642 event_name = "GestureScrollUpdate"; | |
643 break; | |
644 case blink::WebInputEvent::GestureFlingStart: | |
645 event_name = "GestureFlingStart"; | |
646 break; | |
647 case blink::WebInputEvent::GestureFlingCancel: | |
648 event_name = "GestureFlingCancel"; | |
649 break; | |
650 case blink::WebInputEvent::GestureTap: | |
651 event_name = "GestureTap"; | |
652 break; | |
653 case blink::WebInputEvent::GestureTapUnconfirmed: | |
654 event_name = "GestureTapUnconfirmed"; | |
655 break; | |
656 case blink::WebInputEvent::GestureTapDown: | |
657 event_name = "GestureTapDown"; | |
658 break; | |
659 case blink::WebInputEvent::GestureShowPress: | |
660 event_name = "GestureShowPress"; | |
661 break; | |
662 case blink::WebInputEvent::GestureTapCancel: | |
663 event_name = "GestureTapCancel"; | |
664 break; | |
665 case blink::WebInputEvent::GestureDoubleTap: | |
666 event_name = "GestureDoubleTap"; | |
667 break; | |
668 case blink::WebInputEvent::GestureTwoFingerTap: | |
669 event_name = "GestureTwoFingerTap"; | |
670 break; | |
671 case blink::WebInputEvent::GestureLongPress: | |
672 event_name = "GestureLongPress"; | |
673 break; | |
674 case blink::WebInputEvent::GestureLongTap: | |
675 event_name = "GestureLongTap"; | |
676 break; | |
677 case blink::WebInputEvent::GesturePinchBegin: | |
678 event_name = "GesturePinchBegin"; | |
679 break; | |
680 case blink::WebInputEvent::GesturePinchEnd: | |
681 event_name = "GesturePinchEnd"; | |
682 break; | |
683 case blink::WebInputEvent::GesturePinchUpdate: | |
684 event_name = "GesturePinchUpdate"; | |
685 break; | |
686 | |
687 case blink::WebInputEvent::TouchStart: | |
688 event_name = "TouchStart"; | |
689 break; | |
690 case blink::WebInputEvent::TouchMove: | |
691 event_name = "TouchMove"; | |
692 break; | |
693 case blink::WebInputEvent::TouchEnd: | |
694 event_name = "TouchEnd"; | |
695 break; | |
696 case blink::WebInputEvent::TouchCancel: | |
697 event_name = "TouchCancel"; | |
698 break; | |
699 default: | |
700 NOTREACHED() << "Received unexpected event type: " << event.type; | |
701 event_name = "unknown"; | |
702 break; | |
703 } | |
704 | |
705 delegate_->PrintMessage(std::string("Plugin received event: ") + | |
706 (event_name ? event_name : "unknown") + "\n"); | |
707 if (print_event_details_) | |
708 PrintEventDetails(delegate_, event); | |
709 if (print_user_gesture_status_) | |
710 delegate_->PrintMessage( | |
711 std::string("* ") + | |
712 (blink::WebUserGestureIndicator::isProcessingUserGesture() ? "" | |
713 : "not ") + | |
714 "handling user gesture\n"); | |
715 if (is_persistent_) | |
716 delegate_->PrintMessage(std::string("TestPlugin: isPersistent\n")); | |
717 return false; | |
718 } | |
719 | |
720 bool TestPlugin::handleDragStatusUpdate( | |
721 blink::WebDragStatus drag_status, | |
722 const blink::WebDragData& data, | |
723 blink::WebDragOperationsMask mask, | |
724 const blink::WebPoint& position, | |
725 const blink::WebPoint& screen_position) { | |
726 const char* drag_status_name = 0; | |
727 switch (drag_status) { | |
728 case blink::WebDragStatusEnter: | |
729 drag_status_name = "DragEnter"; | |
730 break; | |
731 case blink::WebDragStatusOver: | |
732 drag_status_name = "DragOver"; | |
733 break; | |
734 case blink::WebDragStatusLeave: | |
735 drag_status_name = "DragLeave"; | |
736 break; | |
737 case blink::WebDragStatusDrop: | |
738 drag_status_name = "DragDrop"; | |
739 break; | |
740 case blink::WebDragStatusUnknown: | |
741 NOTREACHED(); | |
742 } | |
743 delegate_->PrintMessage(std::string("Plugin received event: ") + | |
744 drag_status_name + "\n"); | |
745 return false; | |
746 } | |
747 | |
748 TestPlugin* TestPlugin::create(blink::WebFrame* frame, | |
749 const blink::WebPluginParams& params, | |
750 WebTestDelegate* delegate) { | |
751 return new TestPlugin(frame, params, delegate); | |
752 } | |
753 | |
754 const blink::WebString& TestPlugin::MimeType() { | |
755 const CR_DEFINE_STATIC_LOCAL( | |
756 blink::WebString, kMimeType, ("application/x-webkit-test-webplugin")); | |
757 return kMimeType; | |
758 } | |
759 | |
760 const blink::WebString& TestPlugin::CanCreateWithoutRendererMimeType() { | |
761 const CR_DEFINE_STATIC_LOCAL( | |
762 blink::WebString, | |
763 kCanCreateWithoutRendererMimeType, | |
764 ("application/x-webkit-test-webplugin-can-create-without-renderer")); | |
765 return kCanCreateWithoutRendererMimeType; | |
766 } | |
767 | |
768 const blink::WebString& TestPlugin::PluginPersistsMimeType() { | |
769 const CR_DEFINE_STATIC_LOCAL( | |
770 blink::WebString, | |
771 kPluginPersistsMimeType, | |
772 ("application/x-webkit-test-webplugin-persistent")); | |
773 return kPluginPersistsMimeType; | |
774 } | |
775 | |
776 bool TestPlugin::IsSupportedMimeType(const blink::WebString& mime_type) { | |
777 return mime_type == TestPlugin::MimeType() || | |
778 mime_type == PluginPersistsMimeType() || | |
779 mime_type == CanCreateWithoutRendererMimeType(); | |
780 } | |
781 | |
782 } // namespace content | |
OLD | NEW |