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/TestPlugin.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 "content/public/renderer/render_thread.h" | |
13 #include "content/shell/renderer/test_runner/WebTestDelegate.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/web/WebFrame.h" | |
21 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
22 #include "third_party/WebKit/public/web/WebKit.h" | |
23 #include "third_party/WebKit/public/web/WebPluginParams.h" | |
24 #include "third_party/WebKit/public/web/WebTouchPoint.h" | |
25 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | |
26 | |
27 using namespace blink; | |
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 colorIn[3], float alpha, float colorOut[4]) | |
64 { | |
65 for (int i = 0; i < 3; ++i) | |
66 colorOut[i] = (colorIn[i] / 255.0f) * alpha; | |
67 | |
68 colorOut[3] = alpha; | |
69 } | |
70 | |
71 const char* pointState(WebTouchPoint::State state) | |
72 { | |
73 switch (state) { | |
74 case WebTouchPoint::StateReleased: | |
75 return "Released"; | |
76 case WebTouchPoint::StatePressed: | |
77 return "Pressed"; | |
78 case WebTouchPoint::StateMoved: | |
79 return "Moved"; | |
80 case WebTouchPoint::StateCancelled: | |
81 return "Cancelled"; | |
82 default: | |
83 return "Unknown"; | |
84 } | |
85 } | |
86 | |
87 void printTouchList(WebTestDelegate* delegate, const WebTouchPoint* points, int
length) | |
88 { | |
89 for (int i = 0; i < length; ++i) { | |
90 delegate->printMessage(base::StringPrintf("* %.2f, %.2f: %s\n", | |
91 points[i].position.x, | |
92 points[i].position.y, | |
93 pointState(points[i].state))); | |
94 } | |
95 } | |
96 | |
97 void printEventDetails(WebTestDelegate* delegate, const WebInputEvent& event) | |
98 { | |
99 if (WebInputEvent::isTouchEventType(event.type)) { | |
100 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(event); | |
101 printTouchList(delegate, touch.touches, touch.touchesLength); | |
102 printTouchList(delegate, touch.changedTouches, touch.changedTouchesLengt
h); | |
103 printTouchList(delegate, touch.targetTouches, touch.targetTouchesLength)
; | |
104 } else if (WebInputEvent::isMouseEventType(event.type) || event.type == WebI
nputEvent::MouseWheel) { | |
105 const WebMouseEvent& mouse = static_cast<const WebMouseEvent&>(event); | |
106 delegate->printMessage( | |
107 base::StringPrintf("* %d, %d\n", mouse.x, mouse.y)); | |
108 } else if (WebInputEvent::isGestureEventType(event.type)) { | |
109 const WebGestureEvent& gesture = static_cast<const WebGestureEvent&>(eve
nt); | |
110 delegate->printMessage( | |
111 base::StringPrintf("* %d, %d\n", gesture.x, gesture.y)); | |
112 } | |
113 } | |
114 | |
115 WebPluginContainer::TouchEventRequestType parseTouchEventRequestType(const WebSt
ring& string) | |
116 { | |
117 if (string == WebString::fromUTF8("raw")) | |
118 return WebPluginContainer::TouchEventRequestTypeRaw; | |
119 if (string == WebString::fromUTF8("synthetic")) | |
120 return WebPluginContainer::TouchEventRequestTypeSynthesizedMouse; | |
121 return WebPluginContainer::TouchEventRequestTypeNone; | |
122 } | |
123 | |
124 void deferredDelete(void* context) | |
125 { | |
126 TestPlugin* plugin = static_cast<TestPlugin*>(context); | |
127 delete plugin; | |
128 } | |
129 | |
130 } | |
131 | |
132 TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDe
legate* delegate) | |
133 : m_frame(frame) | |
134 , m_delegate(delegate) | |
135 , m_container(0) | |
136 , m_context(0) | |
137 , m_colorTexture(0) | |
138 , m_mailboxChanged(false) | |
139 , m_framebuffer(0) | |
140 , m_touchEventRequest(WebPluginContainer::TouchEventRequestTypeNone) | |
141 , m_reRequestTouchEvents(false) | |
142 , m_printEventDetails(false) | |
143 , m_printUserGestureStatus(false) | |
144 , m_canProcessDrag(false) | |
145 , m_isPersistent(params.mimeType == pluginPersistsMimeType()) | |
146 , m_canCreateWithoutRenderer(params.mimeType == canCreateWithoutRendererMime
Type()) | |
147 { | |
148 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrimitive, ("primitive")); | |
149 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeBackgroundColor, ("backgro
und-color")); | |
150 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrimitiveColor, ("primitiv
e-color")); | |
151 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeOpacity, ("opacity")); | |
152 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeAcceptsTouch, ("accepts-to
uch")); | |
153 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeReRequestTouchEvents, ("re
-request-touch")); | |
154 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrintEventDetails, ("print
-event-details")); | |
155 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeCanProcessDrag, ("can-proc
ess-drag")); | |
156 const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrintUserGestureStatus, ("
print-user-gesture-status")); | |
157 | |
158 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); | |
159 size_t size = params.attributeNames.size(); | |
160 for (size_t i = 0; i < size; ++i) { | |
161 const WebString& attributeName = params.attributeNames[i]; | |
162 const WebString& attributeValue = params.attributeValues[i]; | |
163 | |
164 if (attributeName == kAttributePrimitive) | |
165 m_scene.primitive = parsePrimitive(attributeValue); | |
166 else if (attributeName == kAttributeBackgroundColor) | |
167 parseColor(attributeValue, m_scene.backgroundColor); | |
168 else if (attributeName == kAttributePrimitiveColor) | |
169 parseColor(attributeValue, m_scene.primitiveColor); | |
170 else if (attributeName == kAttributeOpacity) | |
171 m_scene.opacity = parseOpacity(attributeValue); | |
172 else if (attributeName == kAttributeAcceptsTouch) | |
173 m_touchEventRequest = parseTouchEventRequestType(attributeValue); | |
174 else if (attributeName == kAttributeReRequestTouchEvents) | |
175 m_reRequestTouchEvents = parseBoolean(attributeValue); | |
176 else if (attributeName == kAttributePrintEventDetails) | |
177 m_printEventDetails = parseBoolean(attributeValue); | |
178 else if (attributeName == kAttributeCanProcessDrag) | |
179 m_canProcessDrag = parseBoolean(attributeValue); | |
180 else if (attributeName == kAttributePrintUserGestureStatus) | |
181 m_printUserGestureStatus = parseBoolean(attributeValue); | |
182 } | |
183 if (m_canCreateWithoutRenderer) | |
184 m_delegate->printMessage(std::string("TestPlugin: canCreateWithoutRender
er\n")); | |
185 } | |
186 | |
187 TestPlugin::~TestPlugin() | |
188 { | |
189 } | |
190 | |
191 bool TestPlugin::initialize(WebPluginContainer* container) | |
192 { | |
193 WebGraphicsContext3D::Attributes attrs; | |
194 m_context = Platform::current()->createOffscreenGraphicsContext3D(attrs); | |
195 | |
196 if (!initScene()) | |
197 return false; | |
198 | |
199 m_layer = cc::TextureLayer::CreateForMailbox(this); | |
200 m_webLayer = make_scoped_ptr(InstantiateWebLayer(m_layer)); | |
201 m_container = container; | |
202 m_container->setWebLayer(m_webLayer.get()); | |
203 if (m_reRequestTouchEvents) { | |
204 m_container->requestTouchEventType(WebPluginContainer::TouchEventRequest
TypeSynthesizedMouse); | |
205 m_container->requestTouchEventType(WebPluginContainer::TouchEventRequest
TypeRaw); | |
206 } | |
207 m_container->requestTouchEventType(m_touchEventRequest); | |
208 m_container->setWantsWheelEvents(true); | |
209 return true; | |
210 } | |
211 | |
212 void TestPlugin::destroy() | |
213 { | |
214 if (m_layer.get()) | |
215 m_layer->ClearTexture(); | |
216 if (m_container) | |
217 m_container->setWebLayer(0); | |
218 m_webLayer.reset(); | |
219 m_layer = NULL; | |
220 destroyScene(); | |
221 | |
222 delete m_context; | |
223 m_context = 0; | |
224 | |
225 m_container = 0; | |
226 m_frame = 0; | |
227 | |
228 Platform::current()->callOnMainThread(deferredDelete, this); | |
229 } | |
230 | |
231 NPObject* TestPlugin::scriptableObject() | |
232 { | |
233 return 0; | |
234 } | |
235 | |
236 bool TestPlugin::canProcessDrag() const | |
237 { | |
238 return m_canProcessDrag; | |
239 } | |
240 | |
241 void TestPlugin::updateGeometry(const WebRect& frameRect, const WebRect& clipRec
t, const WebVector<WebRect>& cutOutsRects, bool isVisible) | |
242 { | |
243 if (clipRect == m_rect) | |
244 return; | |
245 m_rect = clipRect; | |
246 | |
247 if (m_rect.isEmpty()) { | |
248 m_textureMailbox = cc::TextureMailbox(); | |
249 } else if (m_context) { | |
250 m_context->viewport(0, 0, m_rect.width, m_rect.height); | |
251 | |
252 m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture); | |
253 m_context->texParameteri( | |
254 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
255 m_context->texParameteri( | |
256 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
257 m_context->texParameteri( | |
258 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
259 m_context->texParameteri( | |
260 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
261 m_context->texImage2D(GL_TEXTURE_2D, | |
262 0, | |
263 GL_RGBA, | |
264 m_rect.width, | |
265 m_rect.height, | |
266 0, | |
267 GL_RGBA, | |
268 GL_UNSIGNED_BYTE, | |
269 0); | |
270 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); | |
271 m_context->framebufferTexture2D(GL_FRAMEBUFFER, | |
272 GL_COLOR_ATTACHMENT0, | |
273 GL_TEXTURE_2D, | |
274 m_colorTexture, | |
275 0); | |
276 | |
277 drawSceneGL(); | |
278 | |
279 gpu::Mailbox mailbox; | |
280 m_context->genMailboxCHROMIUM(mailbox.name); | |
281 m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | |
282 m_context->flush(); | |
283 uint32 syncPoint = m_context->insertSyncPoint(); | |
284 m_textureMailbox = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, syncPoint)
; | |
285 } else { | |
286 size_t bytes = 4 * m_rect.width * m_rect.height; | |
287 scoped_ptr<base::SharedMemory> bitmap = | |
288 RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes); | |
289 if (!bitmap->Map(bytes)) { | |
290 m_textureMailbox = cc::TextureMailbox(); | |
291 } else { | |
292 drawSceneSoftware(bitmap->memory(), bytes); | |
293 m_textureMailbox = cc::TextureMailbox( | |
294 bitmap.get(), gfx::Size(m_rect.width, m_rect.height)); | |
295 m_sharedBitmap = bitmap.Pass(); | |
296 } | |
297 } | |
298 | |
299 m_mailboxChanged = true; | |
300 m_layer->SetNeedsDisplay(); | |
301 } | |
302 | |
303 bool TestPlugin::acceptsInputEvents() | |
304 { | |
305 return true; | |
306 } | |
307 | |
308 bool TestPlugin::isPlaceholder() | |
309 { | |
310 return false; | |
311 } | |
312 | |
313 static void ignoreReleaseCallback(uint32 sync_point, bool lost) {} | |
314 | |
315 static void releaseSharedMemory(scoped_ptr<base::SharedMemory> bitmap, | |
316 uint32 sync_point, | |
317 bool lost) {} | |
318 | |
319 bool TestPlugin::PrepareTextureMailbox( | |
320 cc::TextureMailbox* mailbox, | |
321 scoped_ptr<cc::SingleReleaseCallback>* releaseCallback, | |
322 bool useSharedMemory) { | |
323 if (!m_mailboxChanged) | |
324 return false; | |
325 *mailbox = m_textureMailbox; | |
326 if (m_textureMailbox.IsTexture()) { | |
327 *releaseCallback = | |
328 cc::SingleReleaseCallback::Create(base::Bind(&ignoreReleaseCallback)); | |
329 } else { | |
330 *releaseCallback = cc::SingleReleaseCallback::Create( | |
331 base::Bind(&releaseSharedMemory, base::Passed(&m_sharedBitmap))); | |
332 } | |
333 m_mailboxChanged = false; | |
334 return true; | |
335 } | |
336 | |
337 TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string) | |
338 { | |
339 const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveNone, ("none")); | |
340 const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveTriangle, ("triangle")); | |
341 | |
342 Primitive primitive = PrimitiveNone; | |
343 if (string == kPrimitiveNone) | |
344 primitive = PrimitiveNone; | |
345 else if (string == kPrimitiveTriangle) | |
346 primitive = PrimitiveTriangle; | |
347 else | |
348 NOTREACHED(); | |
349 return primitive; | |
350 } | |
351 | |
352 // FIXME: This method should already exist. Use it. | |
353 // For now just parse primary colors. | |
354 void TestPlugin::parseColor(const WebString& string, unsigned color[3]) | |
355 { | |
356 color[0] = color[1] = color[2] = 0; | |
357 if (string == "black") | |
358 return; | |
359 | |
360 if (string == "red") | |
361 color[0] = 255; | |
362 else if (string == "green") | |
363 color[1] = 255; | |
364 else if (string == "blue") | |
365 color[2] = 255; | |
366 else | |
367 NOTREACHED(); | |
368 } | |
369 | |
370 float TestPlugin::parseOpacity(const WebString& string) | |
371 { | |
372 return static_cast<float>(atof(string.utf8().data())); | |
373 } | |
374 | |
375 bool TestPlugin::parseBoolean(const WebString& string) | |
376 { | |
377 const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveTrue, ("true")); | |
378 return string == kPrimitiveTrue; | |
379 } | |
380 | |
381 bool TestPlugin::initScene() | |
382 { | |
383 if (!m_context) | |
384 return true; | |
385 | |
386 float color[4]; | |
387 premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color); | |
388 | |
389 m_colorTexture = m_context->createTexture(); | |
390 m_framebuffer = m_context->createFramebuffer(); | |
391 | |
392 m_context->viewport(0, 0, m_rect.width, m_rect.height); | |
393 m_context->disable(GL_DEPTH_TEST); | |
394 m_context->disable(GL_SCISSOR_TEST); | |
395 | |
396 m_context->clearColor(color[0], color[1], color[2], color[3]); | |
397 | |
398 m_context->enable(GL_BLEND); | |
399 m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | |
400 | |
401 return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive()
: true; | |
402 } | |
403 | |
404 void TestPlugin::drawSceneGL() { | |
405 m_context->viewport(0, 0, m_rect.width, m_rect.height); | |
406 m_context->clear(GL_COLOR_BUFFER_BIT); | |
407 | |
408 if (m_scene.primitive != PrimitiveNone) | |
409 drawPrimitive(); | |
410 } | |
411 | |
412 void TestPlugin::drawSceneSoftware(void* memory, size_t bytes) { | |
413 DCHECK_EQ(bytes, m_rect.width * m_rect.height * 4u); | |
414 | |
415 SkColor backgroundColor = | |
416 SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255), | |
417 m_scene.backgroundColor[0], | |
418 m_scene.backgroundColor[1], | |
419 m_scene.backgroundColor[2]); | |
420 | |
421 const SkImageInfo info = SkImageInfo::MakeN32Premul(m_rect.width, | |
422 m_rect.height); | |
423 SkBitmap bitmap; | |
424 bitmap.installPixels(info, memory, info.minRowBytes()); | |
425 SkCanvas canvas(bitmap); | |
426 canvas.clear(backgroundColor); | |
427 | |
428 if (m_scene.primitive != PrimitiveNone) { | |
429 DCHECK_EQ(PrimitiveTriangle, m_scene.primitive); | |
430 SkColor foregroundColor = | |
431 SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255), | |
432 m_scene.primitiveColor[0], | |
433 m_scene.primitiveColor[1], | |
434 m_scene.primitiveColor[2]); | |
435 SkPath trianglePath; | |
436 trianglePath.moveTo(0.5f * m_rect.width, 0.9f * m_rect.height); | |
437 trianglePath.lineTo(0.1f * m_rect.width, 0.1f * m_rect.height); | |
438 trianglePath.lineTo(0.9f * m_rect.width, 0.1f * m_rect.height); | |
439 SkPaint paint; | |
440 paint.setColor(foregroundColor); | |
441 paint.setStyle(SkPaint::kFill_Style); | |
442 canvas.drawPath(trianglePath, paint); | |
443 } | |
444 } | |
445 | |
446 void TestPlugin::destroyScene() | |
447 { | |
448 if (m_scene.program) { | |
449 m_context->deleteProgram(m_scene.program); | |
450 m_scene.program = 0; | |
451 } | |
452 if (m_scene.vbo) { | |
453 m_context->deleteBuffer(m_scene.vbo); | |
454 m_scene.vbo = 0; | |
455 } | |
456 | |
457 if (m_framebuffer) { | |
458 m_context->deleteFramebuffer(m_framebuffer); | |
459 m_framebuffer = 0; | |
460 } | |
461 | |
462 if (m_colorTexture) { | |
463 m_context->deleteTexture(m_colorTexture); | |
464 m_colorTexture = 0; | |
465 } | |
466 } | |
467 | |
468 bool TestPlugin::initProgram() | |
469 { | |
470 const std::string vertexSource( | |
471 "attribute vec4 position; \n" | |
472 "void main() { \n" | |
473 " gl_Position = position; \n" | |
474 "} \n" | |
475 ); | |
476 | |
477 const std::string fragmentSource( | |
478 "precision mediump float; \n" | |
479 "uniform vec4 color; \n" | |
480 "void main() { \n" | |
481 " gl_FragColor = color; \n" | |
482 "} \n" | |
483 ); | |
484 | |
485 m_scene.program = loadProgram(vertexSource, fragmentSource); | |
486 if (!m_scene.program) | |
487 return false; | |
488 | |
489 m_scene.colorLocation = m_context->getUniformLocation(m_scene.program, "colo
r"); | |
490 m_scene.positionLocation = m_context->getAttribLocation(m_scene.program, "po
sition"); | |
491 return true; | |
492 } | |
493 | |
494 bool TestPlugin::initPrimitive() | |
495 { | |
496 DCHECK_EQ(m_scene.primitive, PrimitiveTriangle); | |
497 | |
498 m_scene.vbo = m_context->createBuffer(); | |
499 if (!m_scene.vbo) | |
500 return false; | |
501 | |
502 const float vertices[] = { | |
503 0.0f, 0.8f, 0.0f, | |
504 -0.8f, -0.8f, 0.0f, | |
505 0.8f, -0.8f, 0.0f }; | |
506 m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo); | |
507 m_context->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW); | |
508 m_context->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | |
509 return true; | |
510 } | |
511 | |
512 void TestPlugin::drawPrimitive() | |
513 { | |
514 DCHECK_EQ(m_scene.primitive, PrimitiveTriangle); | |
515 DCHECK(m_scene.vbo); | |
516 DCHECK(m_scene.program); | |
517 | |
518 m_context->useProgram(m_scene.program); | |
519 | |
520 // Bind primitive color. | |
521 float color[4]; | |
522 premultiplyAlpha(m_scene.primitiveColor, m_scene.opacity, color); | |
523 m_context->uniform4f(m_scene.colorLocation, color[0], color[1], color[2], co
lor[3]); | |
524 | |
525 // Bind primitive vertices. | |
526 m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo); | |
527 m_context->enableVertexAttribArray(m_scene.positionLocation); | |
528 m_context->vertexAttribPointer(m_scene.positionLocation, 3, GL_FLOAT, GL_FAL
SE, 0, 0); | |
529 m_context->drawArrays(GL_TRIANGLES, 0, 3); | |
530 } | |
531 | |
532 unsigned TestPlugin::loadShader(unsigned type, const std::string& source) | |
533 { | |
534 unsigned shader = m_context->createShader(type); | |
535 if (shader) { | |
536 m_context->shaderSource(shader, source.data()); | |
537 m_context->compileShader(shader); | |
538 | |
539 int compiled = 0; | |
540 m_context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled); | |
541 if (!compiled) { | |
542 m_context->deleteShader(shader); | |
543 shader = 0; | |
544 } | |
545 } | |
546 return shader; | |
547 } | |
548 | |
549 unsigned TestPlugin::loadProgram(const std::string& vertexSource, const std::str
ing& fragmentSource) | |
550 { | |
551 unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource); | |
552 unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource); | |
553 unsigned program = m_context->createProgram(); | |
554 if (vertexShader && fragmentShader && program) { | |
555 m_context->attachShader(program, vertexShader); | |
556 m_context->attachShader(program, fragmentShader); | |
557 m_context->linkProgram(program); | |
558 | |
559 int linked = 0; | |
560 m_context->getProgramiv(program, GL_LINK_STATUS, &linked); | |
561 if (!linked) { | |
562 m_context->deleteProgram(program); | |
563 program = 0; | |
564 } | |
565 } | |
566 if (vertexShader) | |
567 m_context->deleteShader(vertexShader); | |
568 if (fragmentShader) | |
569 m_context->deleteShader(fragmentShader); | |
570 | |
571 return program; | |
572 } | |
573 | |
574 bool TestPlugin::handleInputEvent(const WebInputEvent& event, WebCursorInfo& inf
o) | |
575 { | |
576 const char* eventName = 0; | |
577 switch (event.type) { | |
578 case WebInputEvent::Undefined: eventName = "unknown"; break; | |
579 | |
580 case WebInputEvent::MouseDown: eventName = "MouseDown"; break; | |
581 case WebInputEvent::MouseUp: eventName = "MouseUp"; break; | |
582 case WebInputEvent::MouseMove: eventName = "MouseMove"; break; | |
583 case WebInputEvent::MouseEnter: eventName = "MouseEnter"; break; | |
584 case WebInputEvent::MouseLeave: eventName = "MouseLeave"; break; | |
585 case WebInputEvent::ContextMenu: eventName = "ContextMenu"; break; | |
586 | |
587 case WebInputEvent::MouseWheel: eventName = "MouseWheel"; break; | |
588 | |
589 case WebInputEvent::RawKeyDown: eventName = "RawKeyDown"; break; | |
590 case WebInputEvent::KeyDown: eventName = "KeyDown"; break; | |
591 case WebInputEvent::KeyUp: eventName = "KeyUp"; break; | |
592 case WebInputEvent::Char: eventName = "Char"; break; | |
593 | |
594 case WebInputEvent::GestureScrollBegin: eventName = "GestureScrollBegin"; b
reak; | |
595 case WebInputEvent::GestureScrollEnd: eventName = "GestureScrollEnd"; bre
ak; | |
596 case WebInputEvent::GestureScrollUpdateWithoutPropagation: | |
597 case WebInputEvent::GestureScrollUpdate: eventName = "GestureScrollUpdate";
break; | |
598 case WebInputEvent::GestureFlingStart: eventName = "GestureFlingStart"; br
eak; | |
599 case WebInputEvent::GestureFlingCancel: eventName = "GestureFlingCancel"; b
reak; | |
600 case WebInputEvent::GestureTap: eventName = "GestureTap"; break; | |
601 case WebInputEvent::GestureTapUnconfirmed: | |
602 eventName = "GestureTapUnconfirmed"
; break; | |
603 case WebInputEvent::GestureTapDown: eventName = "GestureTapDown"; break
; | |
604 case WebInputEvent::GestureShowPress: eventName = "GestureShowPress"; bre
ak; | |
605 case WebInputEvent::GestureTapCancel: eventName = "GestureTapCancel"; bre
ak; | |
606 case WebInputEvent::GestureDoubleTap: eventName = "GestureDoubleTap"; bre
ak; | |
607 case WebInputEvent::GestureTwoFingerTap: eventName = "GestureTwoFingerTap";
break; | |
608 case WebInputEvent::GestureLongPress: eventName = "GestureLongPress"; bre
ak; | |
609 case WebInputEvent::GestureLongTap: eventName = "GestureLongTap"; break
; | |
610 case WebInputEvent::GesturePinchBegin: eventName = "GesturePinchBegin"; br
eak; | |
611 case WebInputEvent::GesturePinchEnd: eventName = "GesturePinchEnd"; brea
k; | |
612 case WebInputEvent::GesturePinchUpdate: eventName = "GesturePinchUpdate"; b
reak; | |
613 | |
614 case WebInputEvent::TouchStart: eventName = "TouchStart"; break; | |
615 case WebInputEvent::TouchMove: eventName = "TouchMove"; break; | |
616 case WebInputEvent::TouchEnd: eventName = "TouchEnd"; break; | |
617 case WebInputEvent::TouchCancel: eventName = "TouchCancel"; break; | |
618 } | |
619 | |
620 m_delegate->printMessage(std::string("Plugin received event: ") + (eventName
? eventName : "unknown") + "\n"); | |
621 if (m_printEventDetails) | |
622 printEventDetails(m_delegate, event); | |
623 if (m_printUserGestureStatus) | |
624 m_delegate->printMessage(std::string("* ") + (WebUserGestureIndicator::i
sProcessingUserGesture() ? "" : "not ") + "handling user gesture\n"); | |
625 if (m_isPersistent) | |
626 m_delegate->printMessage(std::string("TestPlugin: isPersistent\n")); | |
627 return false; | |
628 } | |
629 | |
630 bool TestPlugin::handleDragStatusUpdate(WebDragStatus dragStatus, const WebDragD
ata&, WebDragOperationsMask, const WebPoint& position, const WebPoint& screenPos
ition) | |
631 { | |
632 const char* dragStatusName = 0; | |
633 switch (dragStatus) { | |
634 case WebDragStatusEnter: | |
635 dragStatusName = "DragEnter"; | |
636 break; | |
637 case WebDragStatusOver: | |
638 dragStatusName = "DragOver"; | |
639 break; | |
640 case WebDragStatusLeave: | |
641 dragStatusName = "DragLeave"; | |
642 break; | |
643 case WebDragStatusDrop: | |
644 dragStatusName = "DragDrop"; | |
645 break; | |
646 case WebDragStatusUnknown: | |
647 NOTREACHED(); | |
648 } | |
649 m_delegate->printMessage(std::string("Plugin received event: ") + dragStatus
Name + "\n"); | |
650 return false; | |
651 } | |
652 | |
653 TestPlugin* TestPlugin::create(WebFrame* frame, const WebPluginParams& params, W
ebTestDelegate* delegate) | |
654 { | |
655 return new TestPlugin(frame, params, delegate); | |
656 } | |
657 | |
658 const WebString& TestPlugin::mimeType() | |
659 { | |
660 const CR_DEFINE_STATIC_LOCAL(WebString, kMimeType, ("application/x-webkit-te
st-webplugin")); | |
661 return kMimeType; | |
662 } | |
663 | |
664 const WebString& TestPlugin::canCreateWithoutRendererMimeType() | |
665 { | |
666 const CR_DEFINE_STATIC_LOCAL(WebString, kCanCreateWithoutRendererMimeType, (
"application/x-webkit-test-webplugin-can-create-without-renderer")); | |
667 return kCanCreateWithoutRendererMimeType; | |
668 } | |
669 | |
670 const WebString& TestPlugin::pluginPersistsMimeType() | |
671 { | |
672 const CR_DEFINE_STATIC_LOCAL(WebString, kPluginPersistsMimeType, ("applicati
on/x-webkit-test-webplugin-persistent")); | |
673 return kPluginPersistsMimeType; | |
674 } | |
675 | |
676 bool TestPlugin::isSupportedMimeType(const WebString& mimeType) | |
677 { | |
678 return mimeType == TestPlugin::mimeType() | |
679 || mimeType == pluginPersistsMimeType() | |
680 || mimeType == canCreateWithoutRendererMimeType(); | |
681 } | |
682 | |
683 } // namespace content | |
OLD | NEW |