[M47_2526] Chromium upversion to m47_2526 branch
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / content / browser / renderer_host / render_widget_host_view_efl.cc
1 // Copyright 2014-2015 Samsung Electronics. All rights reserved.
2 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "content/browser/renderer_host/render_widget_host_view_efl.h"
7
8 #include <Ecore.h>
9 #include <Ecore_Evas.h>
10 #include <Ecore_Input.h>
11 #include "ecore_x_wayland_wrapper.h"
12 #include <Elementary.h>
13
14 #include "base/auto_reset.h"
15 #include "base/basictypes.h"
16 #include "base/bind.h"
17 #include "base/command_line.h"
18 #include "base/callback_helpers.h"
19 #include "base/command_line.h"
20 #include "base/trace_event/trace_event.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/thread_task_runner_handle.h"
24 #include "base/logging.h"
25 #include "base/strings/utf_string_conversions.h"
26 #include "content/common/view_messages.h"
27 #include "content/browser/compositor/resize_lock.h"
28 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
29 #include "content/browser/gpu/compositor_util.h"
30 #if defined(TIZEN_DISABLE_GPU_THREAD)
31 #include "content/browser/gpu/gpu_data_manager_impl.h"
32 #endif
33 #include "content/browser/renderer_host/render_widget_host_impl.h"
34 #include "content/browser/renderer_host/ui_events_helper.h"
35 #include "content/browser/renderer_host/im_context_efl.h"
36 #include "content/browser/renderer_host/edge_effect.h"
37 #include "content/browser/renderer_host/event_with_latency_info.h"
38 #include "content/browser/renderer_host/context_factory_efl.h"
39 #include "content/browser/renderer_host/disambiguation_popup_efl.h"
40 #include "content/browser/renderer_host/web_event_factory_efl.h"
41 #include "content/browser/renderer_host/input/web_input_event_util.h"
42 #include "content/browser/renderer_host/render_view_host_impl.h"
43 #include "content/browser/gpu/gpu_process_host.h"
44 #include "content/common/gpu/client/gl_helper.h"
45 #include "content/common/input/did_overscroll_params.h"
46 #include "content/common/input_messages.h"
47 #include "content/common/gpu/gpu_messages.h"
48 #include "content/common/cursors/webcursor_efl.h"
49 #include "content/gpu/shared_mailbox_manager.h"
50 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
51 #include "content/public/browser/screen_orientation_dispatcher_host.h"
52 #include "content/public/browser/web_contents_delegate.h"
53 #include "content/public/browser/browser_thread.h"
54 #include "content/public/browser/context_factory.h"
55 #include "content/public/browser/render_process_host.h"
56 #include "content/public/common/content_switches.h"
57 #include "gpu/command_buffer/service/mailbox_manager.h"
58 #include "media/base/video_util.h"
59 #include "skia/ext/image_operations.h"
60 #include "third_party/WebKit/public/web/WebInputEvent.h"
61 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
62 #include "third_party/WebKit/public/web/WebTouchPoint.h"
63 #include "ui/base/clipboard/clipboard_helper_efl.h"
64 #include "ui/base/layout.h"
65 #include "ui/base/touch/selection_bound.h"
66 #include "ui/events/blink/blink_event_util.h"
67 #include "ui/events/event_switches.h"
68 #include "ui/events/event_utils.h"
69 #define private public
70 #include "ui/events/gestures/gesture_provider_aura.h"
71 #undef private
72 #include "ui/events/gestures/gesture_recognizer_impl_efl.h"
73 #include "ui/compositor/compositor.h"
74 #include "ui/gfx/display.h"
75 #include "ui/gfx/geometry/dip_util.h"
76 #include "ui/gfx/geometry/rect.h"
77 #include "ui/gfx/screen.h"
78 #include "ui/gl/gl_shared_context_efl.h"
79
80 #define EFL_MAX_WIDTH 10000
81 #define EFL_MAX_HEIGHT 10000  // borrowed from GTK+ port
82
83 #define MAX_SURFACE_WIDTH_EGL 4096 //max supported Framebuffer width
84 #define MAX_SURFACE_HEIGHT_EGL 4096 //max supported Framebuffer height
85
86 namespace content {
87
88 namespace {
89
90 ui::SelectionBound::Type ConvertSelectionBoundType(
91     cc::SelectionBoundType type) {
92   switch (type) {
93     case cc::SELECTION_BOUND_LEFT:
94       return ui::SelectionBound::LEFT;
95     case cc::SELECTION_BOUND_RIGHT:
96       return ui::SelectionBound::RIGHT;
97     case cc::SELECTION_BOUND_CENTER:
98       return ui::SelectionBound::CENTER;
99     case cc::SELECTION_BOUND_EMPTY:
100       return ui::SelectionBound::EMPTY;
101   }
102   NOTREACHED() << "Unknown selection bound type";
103   return ui::SelectionBound::EMPTY;
104 }
105
106 ui::SelectionBound ConvertSelectionBound(
107     const cc::ViewportSelectionBound& bound) {
108   ui::SelectionBound ui_bound;
109   ui_bound.set_type(ConvertSelectionBoundType(bound.type));
110   ui_bound.set_visible(bound.visible);
111   if (ui_bound.type() != ui::SelectionBound::EMPTY)
112     ui_bound.SetEdge(bound.edge_top, bound.edge_bottom);
113   return ui_bound;
114 }
115
116 bool IsShiftKey(const char * key) {
117   if (!key)
118     return false;
119   return !strcmp(key, "Shift_L") || !strcmp(key, "Shift_R");
120 }
121
122 } // namespace
123
124 class ScreenshotCapturedCallback {
125  public:
126       ScreenshotCapturedCallback(Screenshot_Captured_Callback func, void *user_data)
127           : func_(func), user_data_(user_data) {}
128   void Run(Evas_Object* image) {
129     if (func_ != NULL)
130       (func_)(image, user_data_);
131   }
132
133  private:
134   Screenshot_Captured_Callback func_;
135   void *user_data_;
136 };
137
138 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
139     blink::WebScreenInfo* results) {
140   const gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
141
142   results->rect = display.bounds();
143   results->availableRect = display.work_area();
144   results->deviceScaleFactor = display.device_scale_factor();
145   results->orientationAngle = display.RotationAsDegree();
146 #if defined(OS_TIZEN_MOBILE)
147   results->orientationType =
148       RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
149 #else
150   results->orientationType =
151       RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display);
152 #endif
153
154   // TODO(derat|oshima): Don't hardcode this. Get this from display object.
155   results->depth = 24;
156   results->depthPerComponent = 8;
157 }
158
159 RenderWidgetHostViewEfl::RenderWidgetHostViewEfl(RenderWidgetHost* widget,
160     WebContents& web_contents)
161   : host_(RenderWidgetHostImpl::From(widget)),
162     im_context_(NULL),
163     evas_(NULL),
164     parent_view_(NULL),
165     smart_parent_(NULL),
166     content_image_(NULL),
167     content_image_elm_host_(NULL),
168     evas_gl_initialized_(false),
169     device_scale_factor_(1.0f),
170     magnifier_(false),
171     is_loading_(false),
172     gesture_recognizer_(ui::GestureRecognizer::Create()),
173     current_orientation_(0),
174     evas_gl_(NULL),
175     evas_gl_api_(NULL),
176     evas_gl_context_(NULL),
177     evas_gl_surface_(NULL),
178     evas_gl_config_(NULL),
179     egl_image_(NULL),
180     current_pixmap_id_(0),
181     next_pixmap_id_(0),
182     texture_id_(0),
183     surface_id_(0),
184     is_modifier_key_(false),
185     touch_events_enabled_(false),
186     web_contents_(web_contents),
187     compositor_(NULL),
188     root_layer_(new ui::Layer(ui::LAYER_SOLID_COLOR)),
189     delegated_frame_host_(new DelegatedFrameHost(this)),
190     context_factory_(NULL) {
191
192   SetDoubleTapSupportEnabled(touch_events_enabled_);
193
194   device_scale_factor_ = gfx::Screen::GetNativeScreen()->
195       GetPrimaryDisplay().device_scale_factor();
196
197   host_->SetView(this);
198
199   set_layer_owner_delegate(delegated_frame_host_.get());
200
201   static bool scale_factor_initialized = false;
202   if (!scale_factor_initialized) {
203     std::vector<ui::ScaleFactor> supported_scale_factors;
204     supported_scale_factors.push_back(ui::SCALE_FACTOR_100P);
205     supported_scale_factors.push_back(ui::SCALE_FACTOR_200P);
206     ui::SetSupportedScaleFactors(supported_scale_factors);
207     scale_factor_initialized = true;
208   }
209
210   gesture_recognizer_->AddGestureEventHelper(this);
211 }
212
213 void RenderWidgetHostViewEfl::InitAsChild(gfx::NativeView parent_view) {
214   DCHECK(parent_view);
215   parent_view_ = static_cast<Evas_Object*>(parent_view);
216   evas_ = evas_object_evas_get(parent_view_);
217
218   content_image_elm_host_ = elm_bg_add(parent_view_);
219   content_image_ = evas_object_image_filled_add(evas_);
220   elm_object_part_content_set(content_image_elm_host_,
221                               "overlay", content_image_);
222   elm_object_focus_allow_set(content_image_elm_host_, EINA_TRUE);
223
224   Evas_Object* smart_parent = evas_object_smart_parent_get(parent_view_);
225   if (smart_parent) {
226     // If our parent is a member of some smart object we also want
227     // to join that group.
228     smart_parent_ = smart_parent;
229     evas_object_smart_member_add(content_image_elm_host_, smart_parent);
230   }
231
232   int x, y, width = 0, height = 0;
233   evas_object_geometry_get(parent_view_, &x, &y, &width, &height);
234   if (width == 0 || height == 0)
235     width = height = 1;
236   evas_object_image_size_set(content_image_, width, height);
237   evas_object_geometry_set(content_image_elm_host_, x, y, width, height);
238
239   evas_object_event_callback_add(parent_view_, EVAS_CALLBACK_RESIZE,
240       OnParentViewResize, this);
241   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_IN,
242       OnFocusIn, this);
243   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_OUT,
244       OnFocusOut, this);
245   evas_object_smart_callback_add(content_image_elm_host_,
246       "focused", OnHostFocusIn, this);
247   evas_object_smart_callback_add(content_image_elm_host_,
248       "unfocused", OnHostFocusOut, this);
249
250   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
251       OnMouseDown, this);
252   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_UP,
253       OnMouseUp, this);
254   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
255       OnMouseMove, this);
256   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
257       OnMouseWheel, this);
258   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_DOWN,
259       OnKeyDown, this);
260   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_UP,
261       OnKeyUp, this);
262
263   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_DOWN,
264       OnMultiTouchEvent, this);
265   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_MOVE,
266       OnMultiTouchEvent, this);
267   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MULTI_UP,
268       OnMultiTouchEvent, this);
269
270   // IMContext calls evas() getter on 'this' so it needs to be
271   // initialized after evas_ is valid
272   im_context_ = IMContextEfl::Create(this);
273
274   selection_controller_.reset(new SelectionControllerEfl(
275     smart_parent_, web_contents_));
276
277   Init_EvasGL(width, height);
278 }
279
280 RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
281   if (im_context_)
282     delete im_context_;
283
284   evas_object_event_callback_del(parent_view_, EVAS_CALLBACK_RESIZE,
285       OnParentViewResize);
286   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_IN,
287       OnFocusIn);
288   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_OUT,
289       OnFocusOut);
290   evas_object_smart_callback_del(content_image_elm_host_,
291       "focused", OnHostFocusIn);
292   evas_object_smart_callback_del(content_image_elm_host_,
293       "unfocused", OnHostFocusOut);
294
295   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
296       OnMouseDown);
297   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_UP,
298       OnMouseUp);
299   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
300       OnMouseMove);
301   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
302       OnMouseWheel);
303   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_DOWN,
304       OnKeyDown);
305   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_UP,
306       OnKeyUp);
307
308   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_DOWN,
309       OnMultiTouchEvent);
310   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_MOVE,
311       OnMultiTouchEvent);
312   evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_UP,
313       OnMultiTouchEvent);
314
315   evas_object_del(content_image_elm_host_);
316   content_image_elm_host_ = NULL;
317   content_image_ = NULL;
318   parent_view_ = NULL;
319
320   if (compositor_)
321     delete compositor_;
322
323   if (context_factory_)
324     delete context_factory_;
325 }
326
327 gfx::Point RenderWidgetHostViewEfl::ConvertPointInViewPix(gfx::Point point) {
328   return gfx::ToFlooredPoint(gfx::ScalePoint(point, device_scale_factor_));
329 }
330
331 gfx::Rect RenderWidgetHostViewEfl::GetViewBoundsInPix() const {
332   int x, y, w, h;
333   evas_object_geometry_get(content_image_elm_host_, &x, &y, &w, &h);
334   return gfx::Rect(x, y, w, h);
335 }
336
337 static const char kVertexShaderSourceSimple[] =
338   "attribute vec4 a_position;   \n"
339   "attribute vec2 a_texCoord;   \n"
340   "varying vec2 v_texCoord;     \n"
341   "void main() {                \n"
342   "  gl_Position = a_position;  \n"
343   "  v_texCoord = a_texCoord;   \n"
344   "}                            \n";
345
346 static const char kFragmentShaderSourceSimple[] =
347   "precision mediump float;                            \n"
348   "varying vec2 v_texCoord;                            \n"
349   "uniform sampler2D s_texture;                        \n"
350   "void main() {                                       \n"
351   "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
352   "}                                                   \n";
353
354 #if defined(NDEBUG)
355 #define GL_CHECK_HELPER(code, msg) \
356   ((code), false)
357 #else
358 static GLenum g_gl_err;
359 #define GL_CHECK_HELPER(code, msg) \
360   (((void)(code), ((g_gl_err = evas_gl_api_->glGetError()) == GL_NO_ERROR)) ? false : \
361       ((LOG(ERROR) << "GL Error: " << g_gl_err << "    " << msg), true))
362 #endif
363
364 #define GL_CHECK(code) GL_CHECK_HELPER(code, "")
365 #define GL_CHECK_STATUS(msg) GL_CHECK_HELPER(1, msg)
366
367 static void GLCheckProgramHelper(Evas_GL_API* api, GLuint program,
368                                  const char* file, int line) {
369   GLint status;
370   api->glGetProgramiv(program, GL_LINK_STATUS, &status);
371   if (!status) {
372     const GLsizei buf_length = 2048;
373     scoped_ptr<GLchar[]> log(new GLchar[buf_length]);
374     GLsizei length = 0;
375     api->glGetProgramInfoLog(program, buf_length, &length, log.get());
376     LOG(ERROR) << "GL program link failed in: " << file << ":" << line
377                << ": " << log.get();
378   }
379 }
380
381 #define GLCheckProgram(api, program) \
382     GLCheckProgramHelper(api, program, __FILE__, __LINE__)
383
384 static void GLCheckShaderHelper(
385     Evas_GL_API* api, GLuint shader, const char* file, int line) {
386   GLint status;
387   api->glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
388   if (!status) {
389     const GLsizei buf_length = 2048;
390     scoped_ptr<GLchar[]> log(new GLchar[buf_length]);
391     GLsizei length = 0;
392     api->glGetShaderInfoLog(shader, buf_length, &length, log.get());
393     LOG(ERROR) << "GL shader compile failed in " << file << ":" << line
394                << ": " << log.get();
395   }
396 }
397
398 #define GLCheckShader(api, shader) \
399     GLCheckShaderHelper((api), (shader), __FILE__, __LINE__)
400
401 void RenderWidgetHostViewEfl::initializeProgram() {
402   evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
403
404   GL_CHECK_STATUS("GL Error before program initialization");
405
406   const char* vertexShaderSourceProgram = kVertexShaderSourceSimple;
407   const char* fragmentShaderSourceProgram = kFragmentShaderSourceSimple;
408   GLuint vertexShader = evas_gl_api_->glCreateShader(GL_VERTEX_SHADER);
409   GL_CHECK_STATUS("vertex shader");
410   GLuint fragmentShader = evas_gl_api_->glCreateShader(GL_FRAGMENT_SHADER);
411   GL_CHECK_STATUS("fragment shader");
412
413   const GLfloat vertex_attributes[] = {
414       -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
415       -1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
416        1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
417        1.0f, -1.0f, 0.0f, 1.0f, 0.0f};
418
419   GL_CHECK(evas_gl_api_->glGenBuffers(1, &vertex_buffer_obj_));
420   GL_CHECK(evas_gl_api_->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj_));
421   GL_CHECK(evas_gl_api_->glBufferData(GL_ARRAY_BUFFER,
422                                       sizeof(vertex_attributes),
423                                       vertex_attributes, GL_STATIC_DRAW));
424
425   const GLushort index_attributes[] = {0, 1, 2, 0, 2, 3};
426   GL_CHECK(evas_gl_api_->glGenBuffers(1, &index_buffer_obj_));
427   GL_CHECK(
428       evas_gl_api_->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_obj_));
429   GL_CHECK(evas_gl_api_->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
430                                       sizeof(index_attributes),
431                                       index_attributes, GL_STATIC_DRAW));
432
433   GL_CHECK(evas_gl_api_->glShaderSource(vertexShader, 1, &vertexShaderSourceProgram, 0));
434   GL_CHECK(evas_gl_api_->glShaderSource(fragmentShader, 1, &fragmentShaderSourceProgram, 0));
435   GL_CHECK(program_id_ = evas_gl_api_->glCreateProgram());
436   GL_CHECK(evas_gl_api_->glCompileShader(vertexShader));
437   GLCheckShader(evas_gl_api_, vertexShader);
438   GL_CHECK(evas_gl_api_->glCompileShader(fragmentShader));
439   GLCheckShader(evas_gl_api_, fragmentShader);
440   GL_CHECK(evas_gl_api_->glAttachShader(program_id_, vertexShader));
441   GL_CHECK(evas_gl_api_->glAttachShader(program_id_, fragmentShader));
442   GL_CHECK(evas_gl_api_->glLinkProgram(program_id_));
443   GLCheckProgram(evas_gl_api_, program_id_);
444
445   GL_CHECK(position_attrib_ = evas_gl_api_->glGetAttribLocation(program_id_, "a_position"));
446   GL_CHECK(texcoord_attrib_ = evas_gl_api_->glGetAttribLocation(program_id_, "a_texCoord"));
447   GL_CHECK(source_texture_location_ = evas_gl_api_->glGetUniformLocation (program_id_, "s_texture" ));
448 }
449
450 #if defined(TIZEN_DISABLE_GPU_THREAD)
451 void RenderWidgetHostViewEfl::DoCompositeNow() {
452   evas_object_image_pixels_dirty_set(content_image_, true);
453   evas_render(evas_);
454 }
455
456 bool RenderWidgetHostViewEfl::MakeCurrent() {
457   return evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
458 }
459
460 void RenderWidgetHostViewEfl::PaintToSurface() {
461   Evas_GL_API* gl_api = evasGlApi();
462
463   Eina_Bool ret = evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
464   gfx::Rect bounds = GetViewBoundsInPix();
465
466   GL_CHECK(gl_api->glViewport(0, 0, bounds.width(), bounds.height()));
467   GL_CHECK(gl_api->glClearColor(1.0, 1.0, 1.0, 1.0));
468   GL_CHECK(gl_api->glClear(GL_COLOR_BUFFER_BIT));
469
470   if (BrowserGpuChannelHostFactory::instance()->GetGpuChannel())
471     compositor_->DoDraw();
472 }
473 #endif
474
475 void RenderWidgetHostViewEfl::PaintTextureToSurface(GLuint texture_id) {
476   Evas_GL_API* gl_api = evasGlApi();
477   DCHECK(gl_api);
478
479   evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
480
481   GL_CHECK_STATUS("GL error before texture paint.");
482
483   gfx::Rect bounds = GetViewBoundsInPix();
484   gfx::Size surface = surface_size_;
485   GL_CHECK(gl_api->glViewport(0, bounds.height() - surface.height(), surface.width(), surface.height()));
486   GL_CHECK(gl_api->glClearColor(1.0, 1.0, 1.0, 1.0));
487   GL_CHECK(gl_api->glClear(GL_COLOR_BUFFER_BIT));
488   GL_CHECK(gl_api->glUseProgram(program_id_));
489
490   current_orientation_ = ecore_evas_rotation_get(ecore_evas_ecore_evas_get(evas_));
491
492   GL_CHECK(gl_api->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj_));
493
494   GL_CHECK(gl_api->glEnableVertexAttribArray(position_attrib_));
495   // Below 5 * sizeof(GLfloat) value specifies the size of a vertex
496   // attribute (x, y, z, u, v).
497   GL_CHECK(gl_api->glVertexAttribPointer(position_attrib_, 3, GL_FLOAT,
498                                          GL_FALSE, 5 * sizeof(GLfloat), NULL));
499   GL_CHECK(gl_api->glEnableVertexAttribArray(texcoord_attrib_));
500   // Below 3 * sizeof(GLfloat) value specifies the location of texture
501   // coordinate in the vertex.
502   GL_CHECK(gl_api->glVertexAttribPointer(texcoord_attrib_, 2, GL_FLOAT,
503                                          GL_FALSE, 5 * sizeof(GLfloat),
504                                          (void*)(3 * sizeof(GLfloat))));
505   GL_CHECK(gl_api->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_obj_));
506
507   GL_CHECK(gl_api->glActiveTexture(GL_TEXTURE0));
508   GL_CHECK(gl_api->glBindTexture(GL_TEXTURE_2D, texture_id));
509   GL_CHECK(gl_api->glUniform1i(source_texture_location_, 0));
510   GL_CHECK(gl_api->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL));
511
512   GL_CHECK(gl_api->glBindTexture(GL_TEXTURE_2D, 0));
513   evas_gl_make_current(evas_gl_, 0, 0);
514 }
515
516 void RenderWidgetHostViewEfl::EvasObjectImagePixelsGetCallback(void* data, Evas_Object* obj) {
517   RenderWidgetHostViewEfl* rwhv_efl = reinterpret_cast<RenderWidgetHostViewEfl*>(data);
518 #if defined(TIZEN_DISABLE_GPU_THREAD)
519   if (GpuDataManagerImpl::GetInstance()->GpuThreadDisabled()) {
520     rwhv_efl->PaintToSurface();
521     return;
522   }
523 #endif
524   if (rwhv_efl->texture_id_)
525     rwhv_efl->PaintTextureToSurface(rwhv_efl->texture_id_);
526 }
527
528 void RenderWidgetHostViewEfl::Init_EvasGL(int width, int height) {
529   CHECK(width > 0 && height > 0);
530
531   setenv("EVAS_GL_DIRECT_OVERRIDE", "1", 1);
532   setenv("EVAS_GL_DIRECT_MEM_OPT", "1",1);
533
534   evas_gl_config_ = evas_gl_config_new();
535   evas_gl_config_->options_bits = EVAS_GL_OPTIONS_DIRECT;
536   evas_gl_config_->color_format = EVAS_GL_RGBA_8888;
537   evas_gl_config_->depth_bits = EVAS_GL_DEPTH_BIT_24;
538   evas_gl_config_->stencil_bits = EVAS_GL_STENCIL_BIT_8;
539
540   evas_gl_ = evas_gl_new(evas_);
541   evas_gl_api_ = evas_gl_api_get(evas_gl_);
542   evas_gl_context_ = evas_gl_context_create(
543       evas_gl_, GLSharedContextEfl::GetEvasGLContext());
544   if (!evas_gl_context_)
545     LOG(FATAL) << "Failed to create evas gl context";
546
547   if (width > MAX_SURFACE_WIDTH_EGL)
548     width = MAX_SURFACE_WIDTH_EGL;
549
550   if (height > MAX_SURFACE_HEIGHT_EGL)
551     height = MAX_SURFACE_HEIGHT_EGL;
552
553   CreateNativeSurface(width, height);
554   initializeProgram();
555
556   evas_gl_initialized_ = true;
557
558   context_factory_ = new ui::ContextFactoryEfl(this);
559
560   compositor_ = new ui::Compositor(context_factory_,
561                                    base::ThreadTaskRunnerHandle::Get());
562
563 #if defined(TIZEN_DISABLE_GPU_THREAD)
564   if (gpu_thread_disabled) {
565     compositor_->SetCompositorClient(this);
566     GLSharedContextEfl::SetDelegate(this);
567   }
568 #endif
569
570   compositor_->SetRootLayer(root_layer_.get());
571   gfx::Size size = GetViewBoundsInPix().size();
572   root_layer_->SetBounds(gfx::Rect(0, 0, size.width(), size.height()));
573   compositor_->SetScaleAndSize(device_scale_factor_, size);
574   compositor_->SetVisible(true);
575 }
576
577 void RenderWidgetHostViewEfl::ResizeCompositorLayer(int width, int height) {
578   root_layer_->SetBounds(gfx::Rect(0, 0, width, height));
579   compositor_->SetScaleAndSize(device_scale_factor_, gfx::Size(width, height));
580 }
581
582 void RenderWidgetHostViewEfl::CreateNativeSurface(int width, int height) {
583   if (width == 0 || height == 0) {
584     LOG(WARNING) << "Invalid surface size: " << width << "x" << height;
585     return;
586   }
587
588   if (evas_gl_surface_) {
589     evas_object_image_native_surface_set(content_image_, NULL);
590     evas_gl_surface_destroy(evas_gl_, evas_gl_surface_);
591   }
592
593   evas_gl_surface_ = evas_gl_surface_create(
594       evas_gl_, evas_gl_config_, width, height);
595   if (!evas_gl_surface_)
596     LOG(FATAL) << "Failed to create evas gl surface";
597
598   Evas_Native_Surface nativeSurface;
599   if (evas_gl_native_surface_get(evas_gl_, evas_gl_surface_, &nativeSurface)) {
600     evas_object_image_native_surface_set(content_image_, &nativeSurface);
601     evas_object_image_pixels_get_callback_set(content_image_,
602         EvasObjectImagePixelsGetCallback, this);
603     evas_object_image_pixels_dirty_set(content_image_, true);
604   } else {
605     LOG(FATAL) << "Failed to get natvie surface";
606   }
607 }
608
609 void RenderWidgetHostViewEfl::SetEvasHandler(scoped_refptr<EvasEventHandler> evas_event_handler) {
610   evas_event_handler_ = evas_event_handler;
611 }
612
613 bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
614   bool handled = true;
615   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewEfl, message)
616     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, OnTextInputStateChanged)
617     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputInFormStateChanged, OnTextInputInFormStateChanged)
618     IPC_MESSAGE_HANDLER(ViewHostMsg_SnapshotDataReceived, OnSnapshotDataReceived)
619 #if defined(OS_TIZEN)
620     IPC_MESSAGE_HANDLER(InputHostMsg_DidHandleKeyEvent, OnDidHandleKeyEvent);
621 #endif
622     IPC_MESSAGE_UNHANDLED(handled = false)
623   IPC_END_MESSAGE_MAP()
624   return handled;
625 }
626
627 bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
628   return host_->Send(message);
629 }
630
631 void RenderWidgetHostViewEfl::OnSnapshotDataReceived(
632     SkBitmap bitmap,
633     int snapshotId) {
634   Evas_Object* image = NULL;
635   if (!bitmap.empty()) {
636     image = evas_object_image_filled_add(evas_);
637     evas_object_image_size_set(image, bitmap.width(), bitmap.height());
638     evas_object_image_data_copy_set(image, bitmap.getPixels());
639   }
640
641   ScreenshotCapturedCallback* callback = screen_capture_cb_map_.Lookup(snapshotId);
642   if (!callback) {
643     return;
644   }
645   callback->Run(image);
646   screen_capture_cb_map_.Remove(snapshotId);
647 }
648
649 void RenderWidgetHostViewEfl::InitAsPopup(RenderWidgetHostView*, const gfx::Rect&) {
650   NOTIMPLEMENTED();
651 }
652
653 void RenderWidgetHostViewEfl::InitAsFullscreen(RenderWidgetHostView*) {
654   NOTIMPLEMENTED();
655 }
656
657 RenderWidgetHost* RenderWidgetHostViewEfl::GetRenderWidgetHost() const {
658   return host_;
659 }
660
661 #if defined(USE_WAYLAND)
662 Ecore_Wl_Window* RenderWidgetHostViewEfl::GetEcoreWlWindow() const {
663   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
664   return ecore_evas_wayland_window_get(ee);
665 }
666 #else
667 Ecore_X_Window RenderWidgetHostViewEfl::GetEcoreXWindow() const {
668   const Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
669   return ecore_evas_gl_x11_window_get(ee);
670 }
671 #endif
672
673 void RenderWidgetHostViewEfl::SetSize(const gfx::Size& size) {
674   // This is a hack. See WebContentsView::SizeContents
675   int width = std::min(size.width(), EFL_MAX_WIDTH);
676   int height = std::min(size.height(), EFL_MAX_HEIGHT);
677   if (popup_type_ != blink::WebPopupTypeNone) {
678     // We're a popup, honor the size request.
679 #if defined(USE_WAYLAND)
680     ecore_wl_window_resize(GetEcoreWlWindow(), width, height, 0);
681 #else
682     ecore_x_window_resize(GetEcoreXWindow(), width, height);
683 #endif
684   }
685
686   // Update the size of the RWH.
687   //if (requested_size_.width() != width ||
688   //    requested_size_.height() != height) {
689     // Disabled for now, will enable it while implementing InitAsPopUp (P1) API
690    //equested_size_ = gfx::Size(width, height);
691     host_->SendScreenRects();
692     host_->WasResized();
693   //}
694     gfx::Size bounds = GetViewBoundsInPix().size();
695     root_layer_->SetBounds(gfx::Rect(0, 0, bounds.width(), bounds.height()));
696     compositor_->SetScaleAndSize(device_scale_factor_, bounds);
697 }
698
699 void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
700   host_->WasResized();
701   delegated_frame_host_->WasResized();
702 }
703
704 gfx::Vector2dF RenderWidgetHostViewEfl::GetLastScrollOffset() const {
705   return last_scroll_offset_;
706 }
707
708 gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
709   return content_image_elm_host_;
710 }
711
712 gfx::NativeViewId RenderWidgetHostViewEfl::GetNativeViewId() const {
713   DCHECK(evas_gl_initialized_);
714   Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
715   return ecore_evas_window_get(ee);
716 }
717
718 gfx::NativeViewAccessible RenderWidgetHostViewEfl::GetNativeViewAccessible() {
719   NOTIMPLEMENTED();
720   return 0;
721 }
722
723 bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
724   return delegated_frame_host_->CanCopyToBitmap();
725 }
726
727 void RenderWidgetHostViewEfl::Show() {
728   evas_object_show(content_image_elm_host_);
729 }
730
731 void RenderWidgetHostViewEfl::Hide() {
732   evas_object_hide(content_image_elm_host_);
733 }
734
735 bool RenderWidgetHostViewEfl::IsShowing() {
736   return evas_object_visible_get(content_image_);
737 }
738
739 gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
740   return gfx::ConvertRectToDIP(device_scale_factor_, GetViewBoundsInPix());
741 }
742
743 bool RenderWidgetHostViewEfl::LockMouse() {
744   NOTIMPLEMENTED();
745   return false;
746 }
747
748 void RenderWidgetHostViewEfl::UnlockMouse() {
749   NOTIMPLEMENTED();
750 }
751
752 void RenderWidgetHostViewEfl::Focus() {
753   elm_object_focus_set(content_image_elm_host_, EINA_TRUE);
754   evas_object_focus_set(content_image_, EINA_TRUE);
755 }
756
757 bool RenderWidgetHostViewEfl::HasFocus() const {
758   return evas_object_focus_get(content_image_);
759 }
760
761 void RenderWidgetHostViewEfl::OnDidHandleKeyEvent(
762     const blink::WebInputEvent* input_event, bool processed) {
763   if (!im_context_)
764     return;
765
766   if (input_event->type == blink::WebInputEvent::KeyDown)
767     im_context_->HandleKeyEvent(processed);
768 }
769
770 void RenderWidgetHostViewEfl::MovePluginContainer(const WebPluginGeometry& move) {
771 #if defined(USE_WAYLAND)
772   Ecore_Wl_Window* surface_window = nullptr;
773   PluginWindowToWidgetMap::const_iterator i = plugin_window_to_widget_map_.find(move.window);
774
775   if (i != plugin_window_to_widget_map_.end())
776     surface_window = i->second;
777
778   if (!surface_window)
779     return;
780
781   if (!move.visible) {
782     ecore_wl_window_hide(surface_window);
783     return;
784   }
785
786   ecore_wl_window_show(surface_window);
787
788   if (!move.rects_valid)
789     return;
790
791   ecore_wl_window_move(surface_window, move.window_rect.x(), move.window_rect.y());
792   ecore_wl_window_resize(surface_window, move.window_rect.width(), move.window_rect.height(), 0);
793 #else
794   Ecore_X_Window surface_window = 0;
795   PluginWindowToWidgetMap::const_iterator i = plugin_window_to_widget_map_.find(move.window);
796
797   if (i != plugin_window_to_widget_map_.end())
798     surface_window = i->second;
799
800   if (!surface_window)
801     return;
802
803   if (!move.visible) {
804     ecore_x_window_hide(surface_window);
805     return;
806   }
807
808   ecore_x_window_show(surface_window);
809
810   if (!move.rects_valid)
811     return;
812
813   ecore_x_window_move(surface_window, move.window_rect.x(), move.window_rect.y());
814   ecore_x_window_resize(surface_window, move.window_rect.width(), move.window_rect.height());
815 #endif
816 }
817
818 void RenderWidgetHostViewEfl::MovePluginWindows(
819     const std::vector<WebPluginGeometry>& moves) {
820   for (size_t i = 0; i < moves.size(); i++)
821     MovePluginContainer(moves[i]);
822 }
823
824 void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& webcursor) {
825   if (is_loading_) {
826     // Setting native Loading cursor
827 #if defined(USE_WAYLAND)
828     ecore_wl_window_cursor_from_name_set(GetEcoreWlWindow(), "watch");
829 #else
830     ecore_x_window_cursor_set(GetEcoreXWindow(), ecore_x_cursor_shape_get(ECORE_X_CURSOR_CLOCK));
831 #endif
832   } else {
833     WebCursor::CursorInfo cursor_info;
834     webcursor.GetCursorInfo(&cursor_info);
835
836 #if defined(USE_WAYLAND)
837     ecore_wl_window_cursor_from_name_set(
838         GetEcoreWlWindow(), GetCursorName(cursor_info.type));
839 #else
840     int cursor_type = GetCursorType(cursor_info.type);
841     ecore_x_window_cursor_set(GetEcoreXWindow(), ecore_x_cursor_shape_get(cursor_type));
842 #endif
843   }
844   // Need to check for cursor visibility
845   //ecore_x_window_cursor_show(GetEcoreXWindow(), true);
846
847 }
848
849 void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
850   UpdateCursor(WebCursor());
851   if (disambiguation_popup_)
852     disambiguation_popup_->Dismiss();
853 }
854
855 void RenderWidgetHostViewEfl::TextInputStateChanged(
856     const ViewHostMsg_TextInputState_Params& params) {
857 #if !defined(EWK_BRINGUP)
858 // [M47_2526] Need to implement this API
859 //            FIXME: http://web.sec.samsung.net/bugzilla/show_bug.cgi?id=14518
860 #endif
861 }
862
863 void RenderWidgetHostViewEfl::OnTextInputStateChanged(
864     const ViewHostMsg_TextInputState_Params& params) {
865   if (GetSelectionController()) {
866     GetSelectionController()->SetSelectionEditable(
867         params.type != ui::TEXT_INPUT_TYPE_NONE);
868   }
869   if (!params.show_ime_if_needed) {
870     WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
871     WebContentsViewEfl* wcve = static_cast<WebContentsViewEfl*>(wci->GetView());
872     if (!wcve->UseKeyPadWithoutUserAction())
873       return;
874   }
875
876   if (im_context_) {
877     im_context_->UpdateInputMethodState(params.type, params.can_compose_inline,
878                                         params.show_ime_if_needed);
879
880     // The empty rect is not used as long as
881     // m_autoZoomFocusedNodeToLegibleScale in WebSettingsImpl
882     // is turned on
883     host_->ScrollFocusedEditableNodeIntoRect(gfx::Rect(0, 0, 0, 0));
884   }
885 }
886
887 void RenderWidgetHostViewEfl::OnTextInputInFormStateChanged(bool is_in_form_tag) {
888   if (im_context_)
889     im_context_->SetIsInFormTag(is_in_form_tag);
890 }
891
892 void RenderWidgetHostViewEfl::ImeCancelComposition() {
893   if (im_context_)
894     im_context_->CancelComposition();
895 }
896
897 void RenderWidgetHostViewEfl::ImeCompositionRangeChanged(
898   const gfx::Range& range,
899   const std::vector<gfx::Rect>& character_bounds) {
900
901   if (GetSelectionController()) {
902     GetSelectionController()->SetCaretSelectionStatus(false);
903     GetSelectionController()->HideHandleAndContextMenu();
904   }
905 }
906
907 void RenderWidgetHostViewEfl::FocusedNodeChanged(bool is_editable_node) {
908   if (GetSelectionController()) {
909     GetSelectionController()->SetCaretSelectionStatus(false);
910     GetSelectionController()->HideHandleAndContextMenu();
911   }
912   if (im_context_ && im_context_->IsShow() &&
913     ClipboardHelperEfl::GetInstance()->IsClipboardWindowOpened()) {
914     ClipboardHelperEfl::GetInstance()->CloseClipboardWindow();
915   }
916 }
917
918 void RenderWidgetHostViewEfl::Destroy() {
919   delete this;
920 }
921
922 void RenderWidgetHostViewEfl::SetTooltipText(const base::string16& text) {
923 }
924
925 void RenderWidgetHostViewEfl::SelectionChanged(const base::string16& text,
926   size_t offset,
927   const gfx::Range& range) {
928   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
929
930   if (!GetSelectionController())
931     return;
932
933   base::string16 selectedText;
934   if (!text.empty() && !range.is_empty())
935     selectedText = GetSelectedText();
936
937   GetSelectionController()->UpdateSelectionData(selectedText);
938 }
939
940 void RenderWidgetHostViewEfl::SelectionBoundsChanged(
941   const ViewHostMsg_SelectionBounds_Params& params) {
942   ViewHostMsg_SelectionBounds_Params guest_params(params);
943   guest_params.anchor_rect = ConvertRectToPixel(device_scale_factor_, params.anchor_rect);
944   guest_params.focus_rect = ConvertRectToPixel(device_scale_factor_, params.focus_rect);
945
946   if (im_context_)
947     im_context_->UpdateCaretBounds(gfx::UnionRects(guest_params.anchor_rect, guest_params.focus_rect));
948 }
949
950 void RenderWidgetHostViewEfl::DidStopFlinging() {
951   EnsureEdgeEffect().Hide();
952
953   SelectionControllerEfl* controller = GetSelectionController();
954   if (!controller)
955     return;
956
957   // Unhide Selection UI when scrolling with fling gesture
958   if (controller->GetScrollStatus())
959     controller->SetScrollStatus(false);
960
961   controller->UpdateSelectionDataAndShow(
962       controller->GetLeftRect(),
963       controller->GetRightRect(),
964       false /*show*/);
965 }
966
967 void RenderWidgetHostViewEfl::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
968   Evas_Coord tmpX, tmpY;
969   evas_object_geometry_get(smart_parent(), &tmpX, &tmpY, NULL, NULL);
970
971   if (view_x) {
972     *view_x = x - tmpX;
973     *view_x /= device_scale_factor_;
974   }
975
976   if (view_y) {
977     *view_y = y - tmpY;
978     *view_y /= device_scale_factor_;
979   }
980 }
981
982 void RenderWidgetHostViewEfl::SelectClosestWord(const gfx::Point& touch_point) {
983   int view_x, view_y;
984   EvasToBlinkCords(touch_point.x(), touch_point.y(), &view_x, &view_y);
985
986   Send(new ViewMsg_SelectClosestWord(
987       host_->GetRoutingID(), view_x, view_y));
988 }
989
990 void RenderWidgetHostViewEfl::ShowDisambiguationPopup(const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
991   if (!disambiguation_popup_)
992     disambiguation_popup_.reset(new DisambiguationPopupEfl(content_image_, this));
993
994   disambiguation_popup_->Show(rect_pixels, zoomed_bitmap);
995 }
996
997 void RenderWidgetHostViewEfl::HandleDisambiguationPopupMouseDownEvent(
998     Evas_Event_Mouse_Down* evas_event) {
999   blink::WebMouseEvent event = MakeWebMouseEvent(
1000       blink::WebInputEvent::MouseDown, content_image_, evas_event);
1001   host_->ForwardMouseEvent(event);
1002 }
1003
1004 void RenderWidgetHostViewEfl::HandleDisambiguationPopupMouseUpEvent(
1005     Evas_Event_Mouse_Up* evas_event) {
1006   blink::WebMouseEvent event = MakeWebMouseEvent(
1007       blink::WebInputEvent::MouseUp, content_image_, evas_event);
1008   host_->ForwardMouseEvent(event);
1009 }
1010
1011 bool RenderWidgetHostViewEfl::CanDispatchToConsumer(ui::GestureConsumer* consumer) {
1012   return this == consumer;
1013 }
1014
1015 void RenderWidgetHostViewEfl::DispatchCancelTouchEvent(ui::TouchEvent* event) {
1016 }
1017
1018 void RenderWidgetHostViewEfl::DispatchGestureEvent(ui::GestureEvent* event) {
1019   HandleGesture(event);
1020 }
1021
1022 void RenderWidgetHostViewEfl::CopyFromCompositingSurface(
1023     const gfx::Rect& src_subrect,
1024     const gfx::Size& output_size,
1025     const ReadbackRequestCallback& callback,
1026     const SkColorType color_type) {
1027   // FIXME(venu.musham): should find a way to do it effectively.
1028   delegated_frame_host_->CopyFromCompositingSurface(src_subrect, output_size,
1029                                                     callback, color_type);
1030 }
1031
1032 void RenderWidgetHostViewEfl::GetSnapshotAsync(const gfx::Rect& snapshot_area, int request_id) {
1033 #if !defined(EWK_BRINGUP)
1034 // [M47_2526] Temporary disabling the codes for switching to new chromium
1035 //            FIXME:
1036   if (!IsDelegatedRendererEnabled())
1037     Send(new ViewMsg_GetSnapshotFromRender(host_->GetRoutingID(), snapshot_area, request_id));
1038   else {
1039     // TODO: Add alternative way after porting delegated rendering
1040     // http://107.108.218.239/bugzilla/show_bug.cgi?id=9858
1041     NOTIMPLEMENTED();
1042   }
1043 #endif
1044 }
1045
1046 bool RenderWidgetHostViewEfl::RequestSnapshotAsync(const Eina_Rectangle rect,
1047     Screenshot_Captured_Callback callback,
1048     void* user_data) {
1049   int width = rect.w;
1050   int height = rect.h;
1051   int x = rect.x;
1052   int y = rect.y;
1053
1054   int device_x, device_y;
1055   int view_x, view_y;
1056
1057   evas_object_geometry_get(smart_parent(),
1058                            &device_x,
1059                            &device_y,
1060                            NULL,
1061                            NULL);
1062
1063   if (width > device_x + GetViewBoundsInPix().width() - rect.x)
1064     width = device_x + GetViewBoundsInPix().width() - rect.x;
1065   if (height > device_y + GetViewBoundsInPix().height() - rect.y)
1066     height = device_y + GetViewBoundsInPix().height() - rect.y;
1067
1068   EvasToBlinkCords(x, y, &view_x, &view_y);
1069
1070   width /= device_scale_factor_;
1071   height /= device_scale_factor_;
1072
1073   ScreenshotCapturedCallback* cb =
1074       new ScreenshotCapturedCallback(callback, user_data);
1075
1076   int cbId = screen_capture_cb_map_.Add(cb);
1077
1078   GetSnapshotAsync(gfx::Rect(view_x, view_y, width, height), cbId);
1079   return true;
1080 }
1081
1082 void RenderWidgetHostViewEfl::BeginFrameSubscription(
1083     scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
1084   delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
1085 }
1086
1087 void RenderWidgetHostViewEfl::EndFrameSubscription() {
1088   delegated_frame_host_->EndFrameSubscription();
1089 }
1090
1091 void RenderWidgetHostViewEfl::DidOverscroll(const DidOverscrollParams& params) {
1092   const gfx::Vector2dF& accumulated_overscroll = params.accumulated_overscroll;
1093   const gfx::Vector2dF& latest_overscroll_delta = params.latest_overscroll_delta;
1094
1095   if (!touch_events_enabled_)
1096     return;
1097
1098   if (latest_overscroll_delta.x() < 0 && (int)accumulated_overscroll.x() < 0)
1099     EnsureEdgeEffect().Show("edge,left");
1100   if (latest_overscroll_delta.x() > 0 && (int)accumulated_overscroll.x() > 0)
1101     EnsureEdgeEffect().Show("edge,right");
1102   if (latest_overscroll_delta.y() < 0 && (int)accumulated_overscroll.y() < 0)
1103     EnsureEdgeEffect().Show("edge,top");
1104   if (latest_overscroll_delta.y() > 0 && (int)accumulated_overscroll.y() > 0)
1105     EnsureEdgeEffect().Show("edge,bottom");
1106 }
1107
1108 void RenderWidgetHostViewEfl::ReturnSubscriberTexture(
1109     base::WeakPtr<RenderWidgetHostViewEfl> rwhvefl,
1110     scoped_refptr<OwnedMailbox> subscriber_texture,
1111     uint32 sync_point) {
1112   if (!subscriber_texture.get())
1113     return;
1114   if (!rwhvefl)
1115     return;
1116   DCHECK_NE(
1117       rwhvefl->active_frame_subscriber_textures_.count(subscriber_texture.get()),
1118       0u);
1119
1120   subscriber_texture->UpdateSyncPoint(sync_point);
1121
1122   rwhvefl->active_frame_subscriber_textures_.erase(subscriber_texture.get());
1123   if (rwhvefl->frame_subscriber_ && subscriber_texture->texture_id())
1124     rwhvefl->idle_frame_subscriber_textures_.push_back(subscriber_texture);
1125 }
1126
1127 void RenderWidgetHostViewEfl::CopyFromCompositingSurfaceFinishedForVideo(
1128     base::WeakPtr<RenderWidgetHostViewEfl> rwhvefl,
1129     const base::Callback<void(bool)>& callback,
1130     scoped_refptr<OwnedMailbox> subscriber_texture,
1131     scoped_ptr<cc::SingleReleaseCallback> release_callback,
1132     bool result) {
1133   callback.Run(result);
1134
1135   GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
1136   uint32 sync_point = gl_helper ? gl_helper->InsertSyncPoint() : 0;
1137   if (release_callback) {
1138     // A release callback means the texture came from the compositor, so there
1139     // should be no |subscriber_texture|.
1140     DCHECK(!subscriber_texture.get());
1141     release_callback->Run(sync_point, false);
1142   }
1143   ReturnSubscriberTexture(rwhvefl, subscriber_texture, sync_point);
1144 }
1145
1146 void RenderWidgetHostViewEfl::CopyFromCompositingSurfaceHasResultForVideo(
1147     base::WeakPtr<RenderWidgetHostViewEfl> rwhvefl,
1148     scoped_refptr<OwnedMailbox> subscriber_texture,
1149     scoped_refptr<media::VideoFrame> video_frame,
1150     const base::Callback<void(bool)>& callback,
1151     scoped_ptr<cc::CopyOutputResult> result) {
1152   base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
1153   base::ScopedClosureRunner scoped_return_subscriber_texture(
1154       base::Bind(&ReturnSubscriberTexture, rwhvefl, subscriber_texture, 0));
1155
1156   if (!rwhvefl)
1157     return;
1158   if (result->IsEmpty())
1159     return;
1160   if (result->size().IsEmpty())
1161     return;
1162
1163   // Compute the dest size we want after the letterboxing resize. Make the
1164   // coordinates and sizes even because we letterbox in YUV space
1165   // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
1166   // line up correctly.
1167   // The video frame's coded_size() and the result's size() are both physical
1168   // pixels.
1169   gfx::Rect region_in_frame =
1170       media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
1171                                     result->size());
1172   region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
1173                               region_in_frame.y() & ~1,
1174                               region_in_frame.width() & ~1,
1175                               region_in_frame.height() & ~1);
1176   if (region_in_frame.IsEmpty())
1177     return;
1178
1179   if (!result->HasTexture()) {
1180     DCHECK(result->HasBitmap());
1181     scoped_ptr<SkBitmap> bitmap = result->TakeBitmap();
1182     // Scale the bitmap to the required size, if necessary.
1183     SkBitmap scaled_bitmap;
1184     if (result->size().width() != region_in_frame.width() ||
1185         result->size().height() != region_in_frame.height()) {
1186       skia::ImageOperations::ResizeMethod method =
1187           skia::ImageOperations::RESIZE_GOOD;
1188       scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method,
1189                                                     region_in_frame.width(),
1190                                                     region_in_frame.height());
1191     } else {
1192       scaled_bitmap = *bitmap.get();
1193     }
1194
1195     {
1196       SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
1197
1198       media::CopyRGBToVideoFrame(
1199           reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
1200           scaled_bitmap.rowBytes(),
1201           region_in_frame,
1202           video_frame.get());
1203     }
1204     ignore_result(scoped_callback_runner.Release());
1205     callback.Run(true);
1206     return;
1207   }
1208
1209   ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1210   GLHelper* gl_helper = factory->GetGLHelper();
1211   if (!gl_helper)
1212     return;
1213   if (subscriber_texture.get() && !subscriber_texture->texture_id())
1214     return;
1215
1216   cc::TextureMailbox texture_mailbox;
1217   scoped_ptr<cc::SingleReleaseCallback> release_callback;
1218   result->TakeTexture(&texture_mailbox, &release_callback);
1219   DCHECK(texture_mailbox.IsTexture());
1220   if (!texture_mailbox.IsTexture())
1221     return;
1222
1223   gfx::Rect result_rect(result->size());
1224
1225   content::ReadbackYUVInterface* yuv_readback_pipeline =
1226       rwhvefl->yuv_readback_pipeline_.get();
1227   if (yuv_readback_pipeline == NULL ||
1228       yuv_readback_pipeline->scaler()->SrcSize() != result_rect.size() ||
1229       yuv_readback_pipeline->scaler()->SrcSubrect() != result_rect ||
1230       yuv_readback_pipeline->scaler()->DstSize() != region_in_frame.size()) {
1231     GLHelper::ScalerQuality quality = GLHelper::SCALER_QUALITY_FAST;
1232     std::string quality_switch = switches::kTabCaptureDownscaleQuality;
1233     // If we're scaling up, we can use the "best" quality.
1234     if (result_rect.size().width() < region_in_frame.size().width() &&
1235         result_rect.size().height() < region_in_frame.size().height())
1236       quality_switch = switches::kTabCaptureUpscaleQuality;
1237
1238     std::string switch_value =
1239         base::CommandLine::ForCurrentProcess()->
1240             GetSwitchValueASCII(quality_switch);
1241     if (switch_value == "fast")
1242       quality = GLHelper::SCALER_QUALITY_FAST;
1243     else if (switch_value == "good")
1244       quality = GLHelper::SCALER_QUALITY_GOOD;
1245     else if (switch_value == "best")
1246       quality = GLHelper::SCALER_QUALITY_BEST;
1247
1248     rwhvefl->yuv_readback_pipeline_.reset(
1249         gl_helper->CreateReadbackPipelineYUV(quality,
1250                                              result_rect.size(),
1251                                              result_rect,
1252                                              video_frame->coded_size(),
1253                                              true,
1254                                              true));
1255     yuv_readback_pipeline = rwhvefl->yuv_readback_pipeline_.get();
1256   }
1257
1258   ignore_result(scoped_callback_runner.Release());
1259   ignore_result(scoped_return_subscriber_texture.Release());
1260   base::Callback<void(bool result)> finished_callback = base::Bind(
1261       &RenderWidgetHostViewEfl::CopyFromCompositingSurfaceFinishedForVideo,
1262       rwhvefl->AsWeakPtr(),
1263       callback,
1264       subscriber_texture,
1265       base::Passed(&release_callback));
1266   yuv_readback_pipeline->ReadbackYUV(
1267       texture_mailbox.mailbox(),
1268       texture_mailbox.sync_point(),
1269       video_frame,
1270       video_frame->visible_rect().origin(),
1271       finished_callback);
1272 }
1273
1274 // Efl port - Implementation done, will enable this function after getting video test site to verify
1275 void RenderWidgetHostViewEfl::CopyFromCompositingSurfaceToVideoFrame(
1276   const gfx::Rect& src_subrect,
1277   const scoped_refptr<media::VideoFrame>& target,
1278   const base::Callback<void(bool)>& callback) {
1279   NOTIMPLEMENTED();
1280   callback.Run(false);
1281 }
1282
1283 bool RenderWidgetHostViewEfl::CanCopyToVideoFrame() const {
1284   return delegated_frame_host_->CanCopyToVideoFrame();
1285 }
1286
1287 bool RenderWidgetHostViewEfl::HasAcceleratedSurface(const gfx::Size&) {
1288   return false;
1289 }
1290
1291 void RenderWidgetHostViewEfl::GetScreenInfo(
1292     blink::WebScreenInfo* results) {
1293   RenderWidgetHostViewBase::GetDefaultScreenInfo(results);
1294 }
1295
1296 bool RenderWidgetHostViewEfl::GetScreenColorProfile(std::vector<char>* color_profile) {
1297   DCHECK(color_profile->empty());
1298   NOTREACHED();
1299   return false;
1300 }
1301
1302 gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
1303   Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
1304   int x, y, w, h;
1305   ecore_evas_geometry_get(ee, &x, &y, &w, &h);
1306   if (current_orientation_ == 90 || current_orientation_ == 270)
1307     return gfx::ConvertRectToDIP(device_scale_factor_, gfx::Rect(x, y, h, w));
1308   return gfx::ConvertRectToDIP(device_scale_factor_, gfx::Rect(x, y, w, h));
1309 }
1310
1311 void RenderWidgetHostViewEfl::RenderProcessGone(base::TerminationStatus, int error_code) {
1312   Destroy();
1313 }
1314
1315 void RenderWidgetHostViewEfl::OnParentViewResize(
1316     void* data, Evas*, Evas_Object* obj, void*) {
1317   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1318   int x, y, width, height;
1319   evas_object_geometry_get(obj, &x, &y, &width, &height);
1320   evas_object_geometry_set(thiz->content_image_elm_host_, x, y, width, height);
1321   evas_object_image_size_set(thiz->content_image_, width, height);
1322   thiz->CreateNativeSurface(width, height);
1323   thiz->ResizeCompositorLayer(width, height);
1324   thiz->host_->WasResized();
1325 }
1326
1327 void RenderWidgetHostViewEfl::OnFocusIn(
1328     void* data, Evas*, Evas_Object*, void*) {
1329   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1330   if (thiz->evas_event_handler_.get())
1331     if (thiz->evas_event_handler_->HandleEvent_FocusIn())
1332       return;
1333
1334   thiz->host_->SetActive(true);
1335   thiz->host_->GotFocus();
1336   thiz->host_->WasShown(ui::LatencyInfo());
1337
1338   Eina_Bool r = EINA_TRUE;
1339   r &= evas_object_key_grab(thiz->content_image_, "Left", 0, 0, EINA_TRUE);
1340   r &= evas_object_key_grab(thiz->content_image_, "Right", 0, 0, EINA_TRUE);
1341   r &= evas_object_key_grab(thiz->content_image_, "Up", 0, 0, EINA_TRUE);
1342   r &= evas_object_key_grab(thiz->content_image_, "Down", 0, 0, EINA_TRUE);
1343   DCHECK(r) << "Failed to grab arrow keys!";
1344 }
1345
1346 void RenderWidgetHostViewEfl::OnFocusOut(
1347     void* data, Evas*, Evas_Object*, void*) {
1348   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1349   if (thiz->evas_event_handler_.get())
1350     if (thiz->evas_event_handler_->HandleEvent_FocusOut())
1351       return;
1352
1353   thiz->host_->SetActive(false);
1354   thiz->host_->LostCapture();
1355   thiz->host_->Blur();
1356
1357   evas_object_key_ungrab(thiz->content_image_, "Left", 0, 0);
1358   evas_object_key_ungrab(thiz->content_image_, "Right", 0, 0);
1359   evas_object_key_ungrab(thiz->content_image_, "Up", 0, 0);
1360   evas_object_key_ungrab(thiz->content_image_, "Down", 0, 0);
1361 }
1362
1363 void RenderWidgetHostViewEfl::OnHostFocusIn(
1364     void* data, Evas_Object*, void*) {
1365   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1366   thiz->Focus();
1367 }
1368
1369 void RenderWidgetHostViewEfl::OnHostFocusOut(
1370     void* data, Evas_Object*, void*) {
1371   RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1372   thiz->host_->Blur();
1373 }
1374
1375 void RenderWidgetHostViewEfl::OnMouseDown(
1376     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1377   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1378   if (rwhv->evas_event_handler_.get())
1379     if (rwhv->evas_event_handler_->HandleEvent_MouseDown(static_cast<Evas_Event_Mouse_Down*>(event_info)))
1380       return;
1381
1382   rwhv->Focus();
1383
1384   if (!rwhv->touch_events_enabled_) {
1385     blink::WebMouseEvent event = MakeWebMouseEvent(
1386         blink::WebInputEvent::MouseDown, obj,
1387         static_cast<Evas_Event_Mouse_Down*>(event_info));
1388     rwhv->host_->ForwardMouseEvent(event);
1389   } else {
1390     rwhv->ProcessTouchEvents();
1391   }
1392 }
1393
1394 void RenderWidgetHostViewEfl::OnMouseUp(
1395     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1396   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1397   if (rwhv->evas_event_handler_.get())
1398     if (rwhv->evas_event_handler_->HandleEvent_MouseUp(static_cast<Evas_Event_Mouse_Up*>(event_info)))
1399       return;
1400
1401   if (!rwhv->touch_events_enabled_) {
1402     blink::WebMouseEvent event = MakeWebMouseEvent(
1403         blink::WebInputEvent::MouseUp, obj,
1404         static_cast<Evas_Event_Mouse_Up*>(event_info));
1405     rwhv->host_->ForwardMouseEvent(event);
1406   } else {
1407     rwhv->ProcessTouchEvents();
1408   }
1409 }
1410
1411 void RenderWidgetHostViewEfl::OnMouseMove(
1412     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1413   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1414   if (rwhv->evas_event_handler_.get())
1415     if (rwhv->evas_event_handler_->HandleEvent_MouseMove(static_cast<Evas_Event_Mouse_Move*>(event_info)))
1416       return;
1417
1418   if (!rwhv->touch_events_enabled_) {
1419     blink::WebMouseEvent event = MakeWebMouseEvent(obj,
1420         static_cast<Evas_Event_Mouse_Move*>(event_info));
1421     rwhv->host_->ForwardMouseEvent(event);
1422   } else {
1423     rwhv->ProcessTouchEvents();
1424   }
1425 }
1426
1427 void RenderWidgetHostViewEfl::OnMultiTouchEvent(
1428     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1429   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1430   CHECK(rwhv->touch_events_enabled_);
1431   rwhv->ProcessTouchEvents();
1432 }
1433
1434 void RenderWidgetHostViewEfl::OnKeyDown(
1435     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1436
1437   if (!event_info)
1438     return;
1439
1440   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1441   if (rwhv->evas_event_handler_.get())
1442     if (rwhv->evas_event_handler_->HandleEvent_KeyDown(static_cast<Evas_Event_Key_Down*>(event_info)))
1443       return;
1444
1445   // When upper case letter is entered there are two events
1446   // Shift + letter key
1447   // Do not forward shift key to prevent shift keydown event.
1448   if (IsShiftKey(static_cast<Evas_Event_Key_Down*>(event_info)->key))
1449     return;
1450
1451   NativeWebKeyboardEvent n_event = MakeWebKeyboardEvent(
1452       true, static_cast<Evas_Event_Key_Down*>(event_info));
1453
1454   if (!rwhv->im_context_) {
1455     rwhv->host_->ForwardKeyboardEvent(n_event);
1456     return;
1457   }
1458
1459   // Do not forward keyevent now if there is fake key event
1460   // handling at the moment to preserve orders of events as in Webkit
1461   if (rwhv->im_context_->IsPreeditQueueEmpty() ||
1462       rwhv->im_context_->IsKeyUpQueueEmpty() ) {
1463     rwhv->host_->ForwardKeyboardEvent(n_event);
1464     rwhv->im_context_->PushToKeyUpEventQueue(n_event.windowsKeyCode);
1465     return;
1466   }
1467
1468   rwhv->im_context_->PushToKeyDownEventQueue(n_event);
1469   rwhv->im_context_->PushToKeyUpEventQueue(n_event.windowsKeyCode);
1470 }
1471
1472 void RenderWidgetHostViewEfl::OnKeyUp(
1473     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1474
1475   if (!event_info)
1476     return;
1477
1478   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1479   if (rwhv->evas_event_handler_.get())
1480     if (rwhv->evas_event_handler_->HandleEvent_KeyUp(static_cast<Evas_Event_Key_Up*>(event_info)))
1481       return;
1482
1483   // When upper case letter is entered there are two events
1484   // Shift + letter key
1485   // Do not forward shift key to prevent shift keyup event.
1486   if (IsShiftKey(static_cast<Evas_Event_Key_Up*>(event_info)->key))
1487     return;
1488
1489   rwhv->host_->ForwardKeyboardEvent(MakeWebKeyboardEvent(
1490       false, static_cast<Evas_Event_Key_Up*>(event_info)));
1491 }
1492
1493 void RenderWidgetHostViewEfl::OnMouseWheel(
1494     void* data, Evas* evas, Evas_Object* obj, void* event_info) {
1495   RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(data);
1496   if (rwhv->evas_event_handler_.get())
1497     if (rwhv->evas_event_handler_->HandleEvent_MouseWheel(static_cast<Evas_Event_Mouse_Wheel*>(event_info)))
1498       return;
1499
1500   if (!rwhv->touch_events_enabled_) {
1501     blink::WebMouseWheelEvent event = MakeWebMouseEvent(
1502         obj, static_cast<Evas_Event_Mouse_Wheel*>(event_info));
1503     rwhv->host_->ForwardWheelEvent(event);
1504   }
1505 }
1506
1507 void RenderWidgetHostViewEfl::ProcessTouchEvents() {
1508   // These constants are used to map multi touch's touch id(s).
1509   // The poorly-written Tizen API document says:
1510   //  "0 for Mouse Event and device id for Multi Event."
1511   //  "The point which comes from Mouse Event has id 0 and"
1512   //  "The point which comes from Multi Event has id that is same as Multi Event's device id."
1513   // This constant is to map touch id 0 to 0, or [0] -> [0]
1514   static const int kMultiTouchIDMapPart0SingleIndex = 0;
1515   // This constant is to map [13, 23] -> [1, 11]
1516   static const int kMultiTouchIDMapPart1StartIndex = 13;
1517   // This constant is to map [13, 23] -> [1, 11]
1518   static const int kMultiTouchIDMapPart1EndIndex = 23;
1519   // 13 - 1 = 12, 23 - 11 = 12
1520   static const int kMultiTouchIDMapPart1DiffValue = 12;
1521
1522   unsigned count = evas_touch_point_list_count(evas_);
1523   if (!count) {
1524     return;
1525   }
1526
1527   int id;
1528   Evas_Coord_Point pt;
1529   Evas_Touch_Point_State state;
1530   for (unsigned i = 0; i < count; ++i) {
1531     // evas_touch_point_list_nth_id_get returns [0] or [13, )
1532     // Multi touch's touch id [[0], [13, 23]] should be mapped to [[0], [1, 11]]
1533     // Internet Blame URL:
1534     //   https://groups.google.com/d/msg/mailing-enlightenment-devel/-R-ezCzpkTk/HJ0KBCdz6CgJ
1535     id = evas_touch_point_list_nth_id_get(evas_, i);
1536     DCHECK(id == kMultiTouchIDMapPart0SingleIndex ||
1537            id >= kMultiTouchIDMapPart1StartIndex);
1538
1539     if (id >= kMultiTouchIDMapPart1StartIndex &&
1540         id <= kMultiTouchIDMapPart1EndIndex) {
1541       id -= kMultiTouchIDMapPart1DiffValue;
1542     } else if (id > kMultiTouchIDMapPart1EndIndex) {
1543       LOG(WARNING) << "evas_touch_point_list_nth_id_get() returned a value "
1544                      "greater than (" << kMultiTouchIDMapPart1EndIndex << ").";
1545     }
1546     evas_touch_point_list_nth_xy_get(evas_, i, &pt.x, &pt.y);
1547     state = evas_touch_point_list_nth_state_get(evas_, i);
1548
1549     ui::TouchEvent touch_event = MakeTouchEvent(pt, state, id, content_image_);
1550     HandleTouchEvent(&touch_event);
1551   }
1552 }
1553
1554 void RenderWidgetHostViewEfl::SetDoubleTapSupportEnabled(bool enabled) {
1555   ui::GestureRecognizerImplEfl* gesture_recognizer_efl =
1556       static_cast<ui::GestureRecognizerImplEfl*>(gesture_recognizer_.get());
1557   DCHECK(gesture_recognizer_efl);
1558   ui::GestureProviderAura* gesture_provider_aura =
1559       gesture_recognizer_efl->GetGestureProviderForConsumer(this);
1560   gesture_provider_aura->filtered_gesture_provider_.SetDoubleTapSupportForPlatformEnabled(enabled);
1561 }
1562
1563 void RenderWidgetHostViewEfl::SetTouchEventsEnabled(bool enabled) {
1564   touch_events_enabled_ = enabled;
1565   SetDoubleTapSupportEnabled(enabled);
1566 }
1567
1568 void RenderWidgetHostViewEfl::set_magnifier(bool status) {
1569    magnifier_ = status;
1570 }
1571
1572 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
1573   ui::LatencyInfo latency_info;
1574   // The latency number should only be added if the timestamp is valid.
1575   if (event.timeStampSeconds) {
1576     const int64 time_micros = static_cast<int64>(
1577         event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
1578     latency_info.AddLatencyNumberWithTimestamp(
1579         ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
1580         0,
1581         0,
1582         base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
1583         1);
1584   }
1585   return latency_info;
1586 }
1587
1588 void RenderWidgetHostViewEfl::SendGestureEvent(
1589     blink::WebGestureEvent& event) {
1590   HandleGesture(event);
1591   if (magnifier_ && event.type == blink::WebInputEvent::GestureScrollUpdate)
1592     return;
1593   if (host_ && event.type != blink::WebInputEvent::Undefined)
1594     host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1595 }
1596
1597 void RenderWidgetHostViewEfl::HandleGestureBegin() {
1598   EnsureEdgeEffect().Enable();
1599   if (GetSelectionController()) {
1600     GetSelectionController()->HandleGestureBegin();
1601   }
1602 }
1603
1604 void RenderWidgetHostViewEfl::HandleGestureEnd() {
1605   if (GetSelectionController())
1606     GetSelectionController()->HandleGestureEnd();
1607
1608   // Edge effect should be disabled upon scroll end/fling start.
1609   // Gesture end comes just after those events, so it's disabled here.
1610   EnsureEdgeEffect().Disable();
1611 }
1612
1613 void RenderWidgetHostViewEfl::HandleGesture(
1614     blink::WebGestureEvent& event) {
1615   SelectionControllerEfl* controller = GetSelectionController();
1616   if (controller)
1617     controller->HandleGesture(event);
1618
1619   if (event.type == blink::WebInputEvent::GestureDoubleTap ||
1620       event.type == blink::WebInputEvent::GesturePinchBegin ||
1621       event.type == blink::WebInputEvent::GesturePinchEnd) {
1622     WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
1623     WebContentsViewEfl* wcve = static_cast<WebContentsViewEfl*>(wci->GetView());
1624     wcve->HandleZoomGesture(event);
1625   }
1626
1627   if (event.type == blink::WebInputEvent::GestureTap ||
1628       event.type == blink::WebInputEvent::GestureTapCancel) {
1629     float size = 32.0f; // Default value
1630 #if defined(OS_TIZEN_MOBILE)
1631     size = elm_config_finger_size_get() / device_scale_factor_;
1632 #endif
1633     event.data.tap.width = size;
1634     event.data.tap.height = size;
1635   }
1636
1637   if (event.type == blink::WebInputEvent::GestureTapDown) {
1638     // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
1639     // event to stop any in-progress flings.
1640     blink::WebGestureEvent fling_cancel = event;
1641     fling_cancel.type = blink::WebInputEvent::GestureFlingCancel;
1642     fling_cancel.sourceDevice = blink::WebGestureDeviceTouchscreen;
1643     SendGestureEvent(fling_cancel);
1644   } else if (event.type == blink::WebInputEvent::GestureScrollUpdate) {
1645     if (event.data.scrollUpdate.deltaX < 0)
1646       EnsureEdgeEffect().Hide("edge,left");
1647     else if (event.data.scrollUpdate.deltaX > 0)
1648       EnsureEdgeEffect().Hide("edge,right");
1649     if (event.data.scrollUpdate.deltaY < 0)
1650       EnsureEdgeEffect().Hide("edge,top");
1651     else if (event.data.scrollUpdate.deltaY > 0)
1652       EnsureEdgeEffect().Hide("edge,bottom");
1653   } else if (event.type == blink::WebInputEvent::GesturePinchBegin) {
1654     EnsureEdgeEffect().Disable();
1655   } else if (event.type == blink::WebInputEvent::GesturePinchEnd) {
1656     EnsureEdgeEffect().Enable();
1657   }
1658 }
1659
1660 void RenderWidgetHostViewEfl::HandleGesture(ui::GestureEvent* event) {
1661   blink::WebGestureEvent gesture =
1662       content::MakeWebGestureEventFromUIEvent(*event);
1663   gesture.x = event->x();
1664   gesture.y = event->y();
1665
1666   const gfx::Point root_point = event->root_location();
1667   gesture.globalX = root_point.x();
1668   gesture.globalY = root_point.y();
1669
1670   if (event->type() == ui::ET_GESTURE_BEGIN)
1671     HandleGestureBegin();
1672   else if (event->type() == ui::ET_GESTURE_END)
1673     HandleGestureEnd();
1674
1675   SendGestureEvent(gesture);
1676   event->SetHandled();
1677 }
1678
1679 // Based on render_widget_host_view_aura.cc::OnTouchEvent
1680 void RenderWidgetHostViewEfl::HandleTouchEvent(ui::TouchEvent* event) {
1681   if (!gesture_recognizer_->ProcessTouchEventPreDispatch(event, this)) {
1682     event->StopPropagation();
1683     return;
1684   }
1685
1686   // Update the touch event first.
1687   if (!pointer_state_.OnTouch(*event)) {
1688     event->StopPropagation();
1689     return;
1690   }
1691
1692   blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent(
1693       pointer_state_, event->may_cause_scrolling());
1694   pointer_state_.CleanupRemovedTouchPoints(*event);
1695
1696   event->StopPropagation();
1697   host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
1698 }
1699
1700 void RenderWidgetHostViewEfl::ProcessAckedTouchEvent(
1701     const TouchEventWithLatencyInfo& touch,
1702     InputEventAckState ack_result) {
1703   ui::EventResult result = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) ?
1704       ui::ER_HANDLED : ui::ER_UNHANDLED;
1705
1706   scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
1707   gestures.reset(gesture_recognizer_->AckTouchEvent(
1708       touch.event.uniqueTouchEventId, result, this));
1709
1710   if (gestures) {
1711     for (size_t j = 0; j < gestures->size(); ++j) {
1712       ui::GestureEvent* event = gestures->get().at(j);
1713       HandleGesture(event);
1714     }
1715   }
1716 }
1717
1718 EdgeEffect& RenderWidgetHostViewEfl::EnsureEdgeEffect() {
1719   if (!edge_effect_)
1720     edge_effect_ = make_scoped_ptr(new EdgeEffect(content_image_elm_host_));
1721
1722   return *edge_effect_.get();
1723 }
1724
1725 void RenderWidgetHostViewEfl::OnOrientationChangeEvent(int orientation) {
1726   current_orientation_ = orientation;
1727 }
1728
1729 void RenderWidgetHostViewEfl::MoveCaret(const gfx::Point& point) {
1730   host_->MoveCaret(gfx::Point(point.x() / device_scale_factor_, point.y() / device_scale_factor_));
1731 }
1732
1733 void RenderWidgetHostViewEfl::SetComposition(const ui::CompositionText& composition_text) {
1734   const std::vector<blink::WebCompositionUnderline>& underlines =
1735       reinterpret_cast<const std::vector<blink::WebCompositionUnderline>&>(
1736       composition_text.underlines);
1737
1738   host_->ImeSetComposition(
1739       composition_text.text, underlines, composition_text.selection.start(),
1740       composition_text.selection.end());
1741 }
1742
1743 void RenderWidgetHostViewEfl::ConfirmComposition(base::string16& text) {
1744   host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
1745 }
1746
1747 // Defined in gl_current_context_efl.cc because of conflicts of
1748 // texture_manager.h with efl GL API wrappers.
1749 extern GLuint GetTextureIdFromTexture(gpu::gles2::Texture* texture);
1750
1751 void RenderWidgetHostViewEfl::GetTextureFromMailbox(gpu::Mailbox* mailbox,
1752                                                     gfx::Size surface_size) {
1753   gpu::gles2::MailboxManager* manager = SharedMailboxManager::GetMailboxManager();
1754   gpu::gles2::Texture* texture = manager->ConsumeTexture(*mailbox);
1755   if (texture != NULL) {
1756     surface_size_ = surface_size;
1757     texture_id_ = GetTextureIdFromTexture(texture);
1758     evas_object_image_pixels_dirty_set(content_image_, true);
1759     evas_render(evas_);
1760   }
1761 }
1762
1763 void RenderWidgetHostViewEfl::OnSwapCompositorFrame(
1764     uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) {
1765   cc::CompositorFrameAck ack;
1766   // TODO(prashant.n): Software frames not supported. So with
1767   // those frames black screen will appear.
1768   last_scroll_offset_ = frame->metadata.root_scroll_offset;
1769
1770   if (GetSelectionController()) {
1771     ui::SelectionBound start = ConvertSelectionBound(frame->metadata.selection.start);
1772     ui::SelectionBound end = ConvertSelectionBound(frame->metadata.selection.end);
1773     GetSelectionController()->OnSelectionChanged(start, end);
1774   }
1775
1776   if (frame->gl_frame_data) {
1777     ack.gl_frame_data = frame->gl_frame_data.Pass();
1778     surface_size_ = ack.gl_frame_data->size;
1779     if (evas_gl_initialized_) {
1780       std::swap(ack.gl_frame_data->mailbox, pending_mailbox_);
1781       gpu::gles2::MailboxManager* manager =
1782           SharedMailboxManager::GetMailboxManager();
1783
1784       gpu::gles2::Texture* texture =
1785           manager->ConsumeTexture(pending_mailbox_);
1786       if (texture != NULL) {
1787         texture_id_ = GetTextureIdFromTexture(texture);
1788         evas_object_image_pixels_dirty_set(content_image_, true);
1789       } else {
1790         LOG(ERROR) << "Frame produced without texture.";
1791       }
1792     }
1793
1794     ack.gl_frame_data->sync_point = 0;
1795   } else if (frame->delegated_frame_data) {
1796     // ack is sent by delegated frame host
1797     delegated_frame_host_->SwapDelegatedFrame(
1798         output_surface_id, frame->delegated_frame_data.Pass(),
1799         frame->metadata.device_scale_factor, frame->metadata.latency_info,
1800         &frame->metadata.satisfies_sequences);
1801     return;
1802   } else {
1803     NOTREACHED();
1804   }
1805
1806   // TODO(prashant.n): Check if ack should be sent after frame is drawn.
1807   host_->SendSwapCompositorFrameAck(host_->GetRoutingID(),
1808                                     output_surface_id,
1809                                     host_->GetProcess()->GetID(),
1810                                     ack);
1811 }
1812
1813 void RenderWidgetHostViewEfl::ClearCompositorFrame () {
1814   delegated_frame_host_->ClearDelegatedFrame();
1815 }
1816
1817 void RenderWidgetHostViewEfl::ScrollFocusedEditableNode() {
1818   host_->ScrollFocusedEditableNodeIntoRect(gfx::Rect(0, 0, 0, 0));
1819 }
1820
1821 bool RenderWidgetHostViewEfl::IsLastAvailableTextEmpty() const {
1822   return RenderWidgetHostViewBase::selection_text_.empty();
1823 }
1824
1825 bool RenderWidgetHostViewEfl::IsIMEShow() const {
1826   if (im_context_)
1827     return im_context_->IsShow();
1828
1829   return false;
1830 }
1831
1832 gfx::Rect RenderWidgetHostViewEfl::GetIMERect() const {
1833   if (im_context_)
1834     return im_context_->GetIMERect();
1835
1836   return gfx::Rect();
1837 }
1838
1839 ///////////////////////////////////////////////////////////////////////////
1840 // DelegatedFrameHost, public:
1841
1842 ui::Layer* RenderWidgetHostViewEfl::DelegatedFrameHostGetLayer() const {
1843   return root_layer_.get();
1844 }
1845
1846 bool RenderWidgetHostViewEfl::DelegatedFrameHostIsVisible() const {
1847   return !host_->is_hidden();
1848 }
1849
1850 gfx::Size RenderWidgetHostViewEfl::DelegatedFrameHostDesiredSizeInDIP() const{
1851   gfx::Rect bounds = GetViewBoundsInPix();
1852   return bounds.size();
1853 }
1854
1855 bool RenderWidgetHostViewEfl::DelegatedFrameCanCreateResizeLock() const {
1856   // On Windows and Linux, holding pointer moves will not help throttling
1857   // resizes.
1858   // TODO(piman): on Windows we need to block (nested message loop?) the
1859   // WM_SIZE event. On Linux we need to throttle at the WM level using
1860   // _NET_WM_SYNC_REQUESTm .
1861   return false;
1862 }
1863
1864 scoped_ptr<ResizeLock>
1865 RenderWidgetHostViewEfl::DelegatedFrameHostCreateResizeLock(
1866     bool defer_compositor_lock) {
1867   ResizeLock* lock = NULL;
1868   return scoped_ptr<ResizeLock>(lock);
1869 }
1870
1871 void RenderWidgetHostViewEfl::DelegatedFrameHostResizeLockWasReleased() {
1872   host_->WasResized();
1873 }
1874
1875 void RenderWidgetHostViewEfl::DelegatedFrameHostSendCompositorSwapAck(
1876     int output_surface_id,
1877     const cc::CompositorFrameAck& ack) {
1878   host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(),
1879                                                  output_surface_id, ack));
1880 }
1881
1882 void RenderWidgetHostViewEfl::DelegatedFrameHostSendReclaimCompositorResources(
1883     int output_surface_id,
1884     const cc::CompositorFrameAck& ack) {
1885   host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(),
1886                                                     output_surface_id, ack));
1887 }
1888
1889 void RenderWidgetHostViewEfl::DelegatedFrameHostOnLostCompositorResources() {
1890   host_->ScheduleComposite();
1891 }
1892
1893 void RenderWidgetHostViewEfl::DelegatedFrameHostUpdateVSyncParameters(
1894     const base::TimeTicks& timebase,
1895     const base::TimeDelta& interval) {
1896   host_->UpdateVSyncParameters(timebase, interval);
1897 }
1898 }  // namespace content