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.
6 #include "content/browser/renderer_host/render_widget_host_view_efl.h"
9 #include <Ecore_Evas.h>
10 #include <Ecore_Input.h>
11 #include "ecore_x_wayland_wrapper.h"
12 #include <Elementary.h>
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"
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"
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"
80 #define EFL_MAX_WIDTH 10000
81 #define EFL_MAX_HEIGHT 10000 // borrowed from GTK+ port
83 #define MAX_SURFACE_WIDTH_EGL 4096 //max supported Framebuffer width
84 #define MAX_SURFACE_HEIGHT_EGL 4096 //max supported Framebuffer height
90 ui::SelectionBound::Type ConvertSelectionBoundType(
91 cc::SelectionBoundType 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;
102 NOTREACHED() << "Unknown selection bound type";
103 return ui::SelectionBound::EMPTY;
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);
116 bool IsShiftKey(const char * key) {
119 return !strcmp(key, "Shift_L") || !strcmp(key, "Shift_R");
124 class ScreenshotCapturedCallback {
126 ScreenshotCapturedCallback(Screenshot_Captured_Callback func, void *user_data)
127 : func_(func), user_data_(user_data) {}
128 void Run(Evas_Object* image) {
130 (func_)(image, user_data_);
134 Screenshot_Captured_Callback func_;
138 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
139 blink::WebScreenInfo* results) {
140 const gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
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);
150 results->orientationType =
151 RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display);
154 // TODO(derat|oshima): Don't hardcode this. Get this from display object.
156 results->depthPerComponent = 8;
159 RenderWidgetHostViewEfl::RenderWidgetHostViewEfl(RenderWidgetHost* widget,
160 WebContents& web_contents)
161 : host_(RenderWidgetHostImpl::From(widget)),
166 content_image_(NULL),
167 content_image_elm_host_(NULL),
168 evas_gl_initialized_(false),
169 device_scale_factor_(1.0f),
172 gesture_recognizer_(ui::GestureRecognizer::Create()),
173 current_orientation_(0),
176 evas_gl_context_(NULL),
177 evas_gl_surface_(NULL),
178 evas_gl_config_(NULL),
180 current_pixmap_id_(0),
184 is_modifier_key_(false),
185 touch_events_enabled_(false),
186 web_contents_(web_contents),
188 root_layer_(new ui::Layer(ui::LAYER_SOLID_COLOR)),
189 delegated_frame_host_(new DelegatedFrameHost(this)),
190 context_factory_(NULL) {
192 SetDoubleTapSupportEnabled(touch_events_enabled_);
194 device_scale_factor_ = gfx::Screen::GetNativeScreen()->
195 GetPrimaryDisplay().device_scale_factor();
197 host_->SetView(this);
199 set_layer_owner_delegate(delegated_frame_host_.get());
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;
210 gesture_recognizer_->AddGestureEventHelper(this);
213 void RenderWidgetHostViewEfl::InitAsChild(gfx::NativeView parent_view) {
215 parent_view_ = static_cast<Evas_Object*>(parent_view);
216 evas_ = evas_object_evas_get(parent_view_);
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);
224 Evas_Object* smart_parent = evas_object_smart_parent_get(parent_view_);
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);
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)
236 evas_object_image_size_set(content_image_, width, height);
237 evas_object_geometry_set(content_image_elm_host_, x, y, width, height);
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,
243 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_OUT,
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);
250 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
252 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_UP,
254 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
256 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
258 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_DOWN,
260 evas_object_event_callback_add(content_image_, EVAS_CALLBACK_KEY_UP,
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);
270 // IMContext calls evas() getter on 'this' so it needs to be
271 // initialized after evas_ is valid
272 im_context_ = IMContextEfl::Create(this);
274 selection_controller_.reset(new SelectionControllerEfl(
275 smart_parent_, web_contents_));
277 Init_EvasGL(width, height);
280 RenderWidgetHostViewEfl::~RenderWidgetHostViewEfl() {
284 evas_object_event_callback_del(parent_view_, EVAS_CALLBACK_RESIZE,
286 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_IN,
288 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_FOCUS_OUT,
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);
295 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_DOWN,
297 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_UP,
299 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_MOVE,
301 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MOUSE_WHEEL,
303 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_DOWN,
305 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_KEY_UP,
308 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_DOWN,
310 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_MOVE,
312 evas_object_event_callback_del(content_image_, EVAS_CALLBACK_MULTI_UP,
315 evas_object_del(content_image_elm_host_);
316 content_image_elm_host_ = NULL;
317 content_image_ = NULL;
323 if (context_factory_)
324 delete context_factory_;
327 gfx::Point RenderWidgetHostViewEfl::ConvertPointInViewPix(gfx::Point point) {
328 return gfx::ToFlooredPoint(gfx::ScalePoint(point, device_scale_factor_));
331 gfx::Rect RenderWidgetHostViewEfl::GetViewBoundsInPix() const {
333 evas_object_geometry_get(content_image_elm_host_, &x, &y, &w, &h);
334 return gfx::Rect(x, y, w, h);
337 static const char kVertexShaderSourceSimple[] =
338 "attribute vec4 a_position; \n"
339 "attribute vec2 a_texCoord; \n"
340 "varying vec2 v_texCoord; \n"
342 " gl_Position = a_position; \n"
343 " v_texCoord = a_texCoord; \n"
346 static const char kFragmentShaderSourceSimple[] =
347 "precision mediump float; \n"
348 "varying vec2 v_texCoord; \n"
349 "uniform sampler2D s_texture; \n"
351 " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
355 #define GL_CHECK_HELPER(code, msg) \
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))
364 #define GL_CHECK(code) GL_CHECK_HELPER(code, "")
365 #define GL_CHECK_STATUS(msg) GL_CHECK_HELPER(1, msg)
367 static void GLCheckProgramHelper(Evas_GL_API* api, GLuint program,
368 const char* file, int line) {
370 api->glGetProgramiv(program, GL_LINK_STATUS, &status);
372 const GLsizei buf_length = 2048;
373 scoped_ptr<GLchar[]> log(new GLchar[buf_length]);
375 api->glGetProgramInfoLog(program, buf_length, &length, log.get());
376 LOG(ERROR) << "GL program link failed in: " << file << ":" << line
377 << ": " << log.get();
381 #define GLCheckProgram(api, program) \
382 GLCheckProgramHelper(api, program, __FILE__, __LINE__)
384 static void GLCheckShaderHelper(
385 Evas_GL_API* api, GLuint shader, const char* file, int line) {
387 api->glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
389 const GLsizei buf_length = 2048;
390 scoped_ptr<GLchar[]> log(new GLchar[buf_length]);
392 api->glGetShaderInfoLog(shader, buf_length, &length, log.get());
393 LOG(ERROR) << "GL shader compile failed in " << file << ":" << line
394 << ": " << log.get();
398 #define GLCheckShader(api, shader) \
399 GLCheckShaderHelper((api), (shader), __FILE__, __LINE__)
401 void RenderWidgetHostViewEfl::initializeProgram() {
402 evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
404 GL_CHECK_STATUS("GL Error before program initialization");
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");
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};
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));
425 const GLushort index_attributes[] = {0, 1, 2, 0, 2, 3};
426 GL_CHECK(evas_gl_api_->glGenBuffers(1, &index_buffer_obj_));
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));
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_);
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" ));
450 #if defined(TIZEN_DISABLE_GPU_THREAD)
451 void RenderWidgetHostViewEfl::DoCompositeNow() {
452 evas_object_image_pixels_dirty_set(content_image_, true);
456 bool RenderWidgetHostViewEfl::MakeCurrent() {
457 return evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
460 void RenderWidgetHostViewEfl::PaintToSurface() {
461 Evas_GL_API* gl_api = evasGlApi();
463 Eina_Bool ret = evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
464 gfx::Rect bounds = GetViewBoundsInPix();
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));
470 if (BrowserGpuChannelHostFactory::instance()->GetGpuChannel())
471 compositor_->DoDraw();
475 void RenderWidgetHostViewEfl::PaintTextureToSurface(GLuint texture_id) {
476 Evas_GL_API* gl_api = evasGlApi();
479 evas_gl_make_current(evas_gl_, evas_gl_surface_, evas_gl_context_);
481 GL_CHECK_STATUS("GL error before texture paint.");
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_));
490 current_orientation_ = ecore_evas_rotation_get(ecore_evas_ecore_evas_get(evas_));
492 GL_CHECK(gl_api->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj_));
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_));
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));
512 GL_CHECK(gl_api->glBindTexture(GL_TEXTURE_2D, 0));
513 evas_gl_make_current(evas_gl_, 0, 0);
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();
524 if (rwhv_efl->texture_id_)
525 rwhv_efl->PaintTextureToSurface(rwhv_efl->texture_id_);
528 void RenderWidgetHostViewEfl::Init_EvasGL(int width, int height) {
529 CHECK(width > 0 && height > 0);
531 setenv("EVAS_GL_DIRECT_OVERRIDE", "1", 1);
532 setenv("EVAS_GL_DIRECT_MEM_OPT", "1",1);
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;
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";
547 if (width > MAX_SURFACE_WIDTH_EGL)
548 width = MAX_SURFACE_WIDTH_EGL;
550 if (height > MAX_SURFACE_HEIGHT_EGL)
551 height = MAX_SURFACE_HEIGHT_EGL;
553 CreateNativeSurface(width, height);
556 evas_gl_initialized_ = true;
558 context_factory_ = new ui::ContextFactoryEfl(this);
560 compositor_ = new ui::Compositor(context_factory_,
561 base::ThreadTaskRunnerHandle::Get());
563 #if defined(TIZEN_DISABLE_GPU_THREAD)
564 if (gpu_thread_disabled) {
565 compositor_->SetCompositorClient(this);
566 GLSharedContextEfl::SetDelegate(this);
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);
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));
582 void RenderWidgetHostViewEfl::CreateNativeSurface(int width, int height) {
583 if (width == 0 || height == 0) {
584 LOG(WARNING) << "Invalid surface size: " << width << "x" << height;
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_);
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";
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);
605 LOG(FATAL) << "Failed to get natvie surface";
609 void RenderWidgetHostViewEfl::SetEvasHandler(scoped_refptr<EvasEventHandler> evas_event_handler) {
610 evas_event_handler_ = evas_event_handler;
613 bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
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);
622 IPC_MESSAGE_UNHANDLED(handled = false)
623 IPC_END_MESSAGE_MAP()
627 bool RenderWidgetHostViewEfl::Send(IPC::Message* message) {
628 return host_->Send(message);
631 void RenderWidgetHostViewEfl::OnSnapshotDataReceived(
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());
641 ScreenshotCapturedCallback* callback = screen_capture_cb_map_.Lookup(snapshotId);
645 callback->Run(image);
646 screen_capture_cb_map_.Remove(snapshotId);
649 void RenderWidgetHostViewEfl::InitAsPopup(RenderWidgetHostView*, const gfx::Rect&) {
653 void RenderWidgetHostViewEfl::InitAsFullscreen(RenderWidgetHostView*) {
657 RenderWidgetHost* RenderWidgetHostViewEfl::GetRenderWidgetHost() const {
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);
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);
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);
682 ecore_x_window_resize(GetEcoreXWindow(), width, height);
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();
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);
699 void RenderWidgetHostViewEfl::SetBounds(const gfx::Rect& rect) {
701 delegated_frame_host_->WasResized();
704 gfx::Vector2dF RenderWidgetHostViewEfl::GetLastScrollOffset() const {
705 return last_scroll_offset_;
708 gfx::NativeView RenderWidgetHostViewEfl::GetNativeView() const {
709 return content_image_elm_host_;
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);
718 gfx::NativeViewAccessible RenderWidgetHostViewEfl::GetNativeViewAccessible() {
723 bool RenderWidgetHostViewEfl::IsSurfaceAvailableForCopy() const {
724 return delegated_frame_host_->CanCopyToBitmap();
727 void RenderWidgetHostViewEfl::Show() {
728 evas_object_show(content_image_elm_host_);
731 void RenderWidgetHostViewEfl::Hide() {
732 evas_object_hide(content_image_elm_host_);
735 bool RenderWidgetHostViewEfl::IsShowing() {
736 return evas_object_visible_get(content_image_);
739 gfx::Rect RenderWidgetHostViewEfl::GetViewBounds() const {
740 return gfx::ConvertRectToDIP(device_scale_factor_, GetViewBoundsInPix());
743 bool RenderWidgetHostViewEfl::LockMouse() {
748 void RenderWidgetHostViewEfl::UnlockMouse() {
752 void RenderWidgetHostViewEfl::Focus() {
753 elm_object_focus_set(content_image_elm_host_, EINA_TRUE);
754 evas_object_focus_set(content_image_, EINA_TRUE);
757 bool RenderWidgetHostViewEfl::HasFocus() const {
758 return evas_object_focus_get(content_image_);
761 void RenderWidgetHostViewEfl::OnDidHandleKeyEvent(
762 const blink::WebInputEvent* input_event, bool processed) {
766 if (input_event->type == blink::WebInputEvent::KeyDown)
767 im_context_->HandleKeyEvent(processed);
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);
775 if (i != plugin_window_to_widget_map_.end())
776 surface_window = i->second;
782 ecore_wl_window_hide(surface_window);
786 ecore_wl_window_show(surface_window);
788 if (!move.rects_valid)
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);
794 Ecore_X_Window surface_window = 0;
795 PluginWindowToWidgetMap::const_iterator i = plugin_window_to_widget_map_.find(move.window);
797 if (i != plugin_window_to_widget_map_.end())
798 surface_window = i->second;
804 ecore_x_window_hide(surface_window);
808 ecore_x_window_show(surface_window);
810 if (!move.rects_valid)
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());
818 void RenderWidgetHostViewEfl::MovePluginWindows(
819 const std::vector<WebPluginGeometry>& moves) {
820 for (size_t i = 0; i < moves.size(); i++)
821 MovePluginContainer(moves[i]);
824 void RenderWidgetHostViewEfl::UpdateCursor(const WebCursor& webcursor) {
826 // Setting native Loading cursor
827 #if defined(USE_WAYLAND)
828 ecore_wl_window_cursor_from_name_set(GetEcoreWlWindow(), "watch");
830 ecore_x_window_cursor_set(GetEcoreXWindow(), ecore_x_cursor_shape_get(ECORE_X_CURSOR_CLOCK));
833 WebCursor::CursorInfo cursor_info;
834 webcursor.GetCursorInfo(&cursor_info);
836 #if defined(USE_WAYLAND)
837 ecore_wl_window_cursor_from_name_set(
838 GetEcoreWlWindow(), GetCursorName(cursor_info.type));
840 int cursor_type = GetCursorType(cursor_info.type);
841 ecore_x_window_cursor_set(GetEcoreXWindow(), ecore_x_cursor_shape_get(cursor_type));
844 // Need to check for cursor visibility
845 //ecore_x_window_cursor_show(GetEcoreXWindow(), true);
849 void RenderWidgetHostViewEfl::SetIsLoading(bool is_loading) {
850 UpdateCursor(WebCursor());
851 if (disambiguation_popup_)
852 disambiguation_popup_->Dismiss();
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
863 void RenderWidgetHostViewEfl::OnTextInputStateChanged(
864 const ViewHostMsg_TextInputState_Params& params) {
865 if (GetSelectionController()) {
866 GetSelectionController()->SetSelectionEditable(
867 params.type != ui::TEXT_INPUT_TYPE_NONE);
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())
877 im_context_->UpdateInputMethodState(params.type, params.can_compose_inline,
878 params.show_ime_if_needed);
880 // The empty rect is not used as long as
881 // m_autoZoomFocusedNodeToLegibleScale in WebSettingsImpl
883 host_->ScrollFocusedEditableNodeIntoRect(gfx::Rect(0, 0, 0, 0));
887 void RenderWidgetHostViewEfl::OnTextInputInFormStateChanged(bool is_in_form_tag) {
889 im_context_->SetIsInFormTag(is_in_form_tag);
892 void RenderWidgetHostViewEfl::ImeCancelComposition() {
894 im_context_->CancelComposition();
897 void RenderWidgetHostViewEfl::ImeCompositionRangeChanged(
898 const gfx::Range& range,
899 const std::vector<gfx::Rect>& character_bounds) {
901 if (GetSelectionController()) {
902 GetSelectionController()->SetCaretSelectionStatus(false);
903 GetSelectionController()->HideHandleAndContextMenu();
907 void RenderWidgetHostViewEfl::FocusedNodeChanged(bool is_editable_node) {
908 if (GetSelectionController()) {
909 GetSelectionController()->SetCaretSelectionStatus(false);
910 GetSelectionController()->HideHandleAndContextMenu();
912 if (im_context_ && im_context_->IsShow() &&
913 ClipboardHelperEfl::GetInstance()->IsClipboardWindowOpened()) {
914 ClipboardHelperEfl::GetInstance()->CloseClipboardWindow();
918 void RenderWidgetHostViewEfl::Destroy() {
922 void RenderWidgetHostViewEfl::SetTooltipText(const base::string16& text) {
925 void RenderWidgetHostViewEfl::SelectionChanged(const base::string16& text,
927 const gfx::Range& range) {
928 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
930 if (!GetSelectionController())
933 base::string16 selectedText;
934 if (!text.empty() && !range.is_empty())
935 selectedText = GetSelectedText();
937 GetSelectionController()->UpdateSelectionData(selectedText);
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);
947 im_context_->UpdateCaretBounds(gfx::UnionRects(guest_params.anchor_rect, guest_params.focus_rect));
950 void RenderWidgetHostViewEfl::DidStopFlinging() {
951 EnsureEdgeEffect().Hide();
953 SelectionControllerEfl* controller = GetSelectionController();
957 // Unhide Selection UI when scrolling with fling gesture
958 if (controller->GetScrollStatus())
959 controller->SetScrollStatus(false);
961 controller->UpdateSelectionDataAndShow(
962 controller->GetLeftRect(),
963 controller->GetRightRect(),
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);
973 *view_x /= device_scale_factor_;
978 *view_y /= device_scale_factor_;
982 void RenderWidgetHostViewEfl::SelectClosestWord(const gfx::Point& touch_point) {
984 EvasToBlinkCords(touch_point.x(), touch_point.y(), &view_x, &view_y);
986 Send(new ViewMsg_SelectClosestWord(
987 host_->GetRoutingID(), view_x, view_y));
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));
994 disambiguation_popup_->Show(rect_pixels, zoomed_bitmap);
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);
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);
1011 bool RenderWidgetHostViewEfl::CanDispatchToConsumer(ui::GestureConsumer* consumer) {
1012 return this == consumer;
1015 void RenderWidgetHostViewEfl::DispatchCancelTouchEvent(ui::TouchEvent* event) {
1018 void RenderWidgetHostViewEfl::DispatchGestureEvent(ui::GestureEvent* event) {
1019 HandleGesture(event);
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);
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
1036 if (!IsDelegatedRendererEnabled())
1037 Send(new ViewMsg_GetSnapshotFromRender(host_->GetRoutingID(), snapshot_area, request_id));
1039 // TODO: Add alternative way after porting delegated rendering
1040 // http://107.108.218.239/bugzilla/show_bug.cgi?id=9858
1046 bool RenderWidgetHostViewEfl::RequestSnapshotAsync(const Eina_Rectangle rect,
1047 Screenshot_Captured_Callback callback,
1050 int height = rect.h;
1054 int device_x, device_y;
1057 evas_object_geometry_get(smart_parent(),
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;
1068 EvasToBlinkCords(x, y, &view_x, &view_y);
1070 width /= device_scale_factor_;
1071 height /= device_scale_factor_;
1073 ScreenshotCapturedCallback* cb =
1074 new ScreenshotCapturedCallback(callback, user_data);
1076 int cbId = screen_capture_cb_map_.Add(cb);
1078 GetSnapshotAsync(gfx::Rect(view_x, view_y, width, height), cbId);
1082 void RenderWidgetHostViewEfl::BeginFrameSubscription(
1083 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
1084 delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
1087 void RenderWidgetHostViewEfl::EndFrameSubscription() {
1088 delegated_frame_host_->EndFrameSubscription();
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;
1095 if (!touch_events_enabled_)
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");
1108 void RenderWidgetHostViewEfl::ReturnSubscriberTexture(
1109 base::WeakPtr<RenderWidgetHostViewEfl> rwhvefl,
1110 scoped_refptr<OwnedMailbox> subscriber_texture,
1111 uint32 sync_point) {
1112 if (!subscriber_texture.get())
1117 rwhvefl->active_frame_subscriber_textures_.count(subscriber_texture.get()),
1120 subscriber_texture->UpdateSyncPoint(sync_point);
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);
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,
1133 callback.Run(result);
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);
1143 ReturnSubscriberTexture(rwhvefl, subscriber_texture, sync_point);
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));
1158 if (result->IsEmpty())
1160 if (result->size().IsEmpty())
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
1169 gfx::Rect region_in_frame =
1170 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_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())
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());
1192 scaled_bitmap = *bitmap.get();
1196 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
1198 media::CopyRGBToVideoFrame(
1199 reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
1200 scaled_bitmap.rowBytes(),
1204 ignore_result(scoped_callback_runner.Release());
1209 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1210 GLHelper* gl_helper = factory->GetGLHelper();
1213 if (subscriber_texture.get() && !subscriber_texture->texture_id())
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())
1223 gfx::Rect result_rect(result->size());
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;
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;
1248 rwhvefl->yuv_readback_pipeline_.reset(
1249 gl_helper->CreateReadbackPipelineYUV(quality,
1252 video_frame->coded_size(),
1255 yuv_readback_pipeline = rwhvefl->yuv_readback_pipeline_.get();
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(),
1265 base::Passed(&release_callback));
1266 yuv_readback_pipeline->ReadbackYUV(
1267 texture_mailbox.mailbox(),
1268 texture_mailbox.sync_point(),
1270 video_frame->visible_rect().origin(),
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) {
1280 callback.Run(false);
1283 bool RenderWidgetHostViewEfl::CanCopyToVideoFrame() const {
1284 return delegated_frame_host_->CanCopyToVideoFrame();
1287 bool RenderWidgetHostViewEfl::HasAcceleratedSurface(const gfx::Size&) {
1291 void RenderWidgetHostViewEfl::GetScreenInfo(
1292 blink::WebScreenInfo* results) {
1293 RenderWidgetHostViewBase::GetDefaultScreenInfo(results);
1296 bool RenderWidgetHostViewEfl::GetScreenColorProfile(std::vector<char>* color_profile) {
1297 DCHECK(color_profile->empty());
1302 gfx::Rect RenderWidgetHostViewEfl::GetBoundsInRootWindow() {
1303 Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
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));
1311 void RenderWidgetHostViewEfl::RenderProcessGone(base::TerminationStatus, int error_code) {
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();
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())
1334 thiz->host_->SetActive(true);
1335 thiz->host_->GotFocus();
1336 thiz->host_->WasShown(ui::LatencyInfo());
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!";
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())
1353 thiz->host_->SetActive(false);
1354 thiz->host_->LostCapture();
1355 thiz->host_->Blur();
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);
1363 void RenderWidgetHostViewEfl::OnHostFocusIn(
1364 void* data, Evas_Object*, void*) {
1365 RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1369 void RenderWidgetHostViewEfl::OnHostFocusOut(
1370 void* data, Evas_Object*, void*) {
1371 RenderWidgetHostViewEfl* thiz = static_cast<RenderWidgetHostViewEfl*>(data);
1372 thiz->host_->Blur();
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)))
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);
1390 rwhv->ProcessTouchEvents();
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)))
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);
1407 rwhv->ProcessTouchEvents();
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)))
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);
1423 rwhv->ProcessTouchEvents();
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();
1434 void RenderWidgetHostViewEfl::OnKeyDown(
1435 void* data, Evas* evas, Evas_Object* obj, void* event_info) {
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)))
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))
1451 NativeWebKeyboardEvent n_event = MakeWebKeyboardEvent(
1452 true, static_cast<Evas_Event_Key_Down*>(event_info));
1454 if (!rwhv->im_context_) {
1455 rwhv->host_->ForwardKeyboardEvent(n_event);
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);
1468 rwhv->im_context_->PushToKeyDownEventQueue(n_event);
1469 rwhv->im_context_->PushToKeyUpEventQueue(n_event.windowsKeyCode);
1472 void RenderWidgetHostViewEfl::OnKeyUp(
1473 void* data, Evas* evas, Evas_Object* obj, void* event_info) {
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)))
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))
1489 rwhv->host_->ForwardKeyboardEvent(MakeWebKeyboardEvent(
1490 false, static_cast<Evas_Event_Key_Up*>(event_info)));
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)))
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);
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;
1522 unsigned count = evas_touch_point_list_count(evas_);
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);
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 << ").";
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);
1549 ui::TouchEvent touch_event = MakeTouchEvent(pt, state, id, content_image_);
1550 HandleTouchEvent(&touch_event);
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);
1563 void RenderWidgetHostViewEfl::SetTouchEventsEnabled(bool enabled) {
1564 touch_events_enabled_ = enabled;
1565 SetDoubleTapSupportEnabled(enabled);
1568 void RenderWidgetHostViewEfl::set_magnifier(bool status) {
1569 magnifier_ = status;
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,
1582 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
1585 return latency_info;
1588 void RenderWidgetHostViewEfl::SendGestureEvent(
1589 blink::WebGestureEvent& event) {
1590 HandleGesture(event);
1591 if (magnifier_ && event.type == blink::WebInputEvent::GestureScrollUpdate)
1593 if (host_ && event.type != blink::WebInputEvent::Undefined)
1594 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1597 void RenderWidgetHostViewEfl::HandleGestureBegin() {
1598 EnsureEdgeEffect().Enable();
1599 if (GetSelectionController()) {
1600 GetSelectionController()->HandleGestureBegin();
1604 void RenderWidgetHostViewEfl::HandleGestureEnd() {
1605 if (GetSelectionController())
1606 GetSelectionController()->HandleGestureEnd();
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();
1613 void RenderWidgetHostViewEfl::HandleGesture(
1614 blink::WebGestureEvent& event) {
1615 SelectionControllerEfl* controller = GetSelectionController();
1617 controller->HandleGesture(event);
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);
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_;
1633 event.data.tap.width = size;
1634 event.data.tap.height = size;
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();
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();
1666 const gfx::Point root_point = event->root_location();
1667 gesture.globalX = root_point.x();
1668 gesture.globalY = root_point.y();
1670 if (event->type() == ui::ET_GESTURE_BEGIN)
1671 HandleGestureBegin();
1672 else if (event->type() == ui::ET_GESTURE_END)
1675 SendGestureEvent(gesture);
1676 event->SetHandled();
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();
1686 // Update the touch event first.
1687 if (!pointer_state_.OnTouch(*event)) {
1688 event->StopPropagation();
1692 blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent(
1693 pointer_state_, event->may_cause_scrolling());
1694 pointer_state_.CleanupRemovedTouchPoints(*event);
1696 event->StopPropagation();
1697 host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
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;
1706 scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
1707 gestures.reset(gesture_recognizer_->AckTouchEvent(
1708 touch.event.uniqueTouchEventId, result, this));
1711 for (size_t j = 0; j < gestures->size(); ++j) {
1712 ui::GestureEvent* event = gestures->get().at(j);
1713 HandleGesture(event);
1718 EdgeEffect& RenderWidgetHostViewEfl::EnsureEdgeEffect() {
1720 edge_effect_ = make_scoped_ptr(new EdgeEffect(content_image_elm_host_));
1722 return *edge_effect_.get();
1725 void RenderWidgetHostViewEfl::OnOrientationChangeEvent(int orientation) {
1726 current_orientation_ = orientation;
1729 void RenderWidgetHostViewEfl::MoveCaret(const gfx::Point& point) {
1730 host_->MoveCaret(gfx::Point(point.x() / device_scale_factor_, point.y() / device_scale_factor_));
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);
1738 host_->ImeSetComposition(
1739 composition_text.text, underlines, composition_text.selection.start(),
1740 composition_text.selection.end());
1743 void RenderWidgetHostViewEfl::ConfirmComposition(base::string16& text) {
1744 host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
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);
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);
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;
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);
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();
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);
1790 LOG(ERROR) << "Frame produced without texture.";
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);
1806 // TODO(prashant.n): Check if ack should be sent after frame is drawn.
1807 host_->SendSwapCompositorFrameAck(host_->GetRoutingID(),
1809 host_->GetProcess()->GetID(),
1813 void RenderWidgetHostViewEfl::ClearCompositorFrame () {
1814 delegated_frame_host_->ClearDelegatedFrame();
1817 void RenderWidgetHostViewEfl::ScrollFocusedEditableNode() {
1818 host_->ScrollFocusedEditableNodeIntoRect(gfx::Rect(0, 0, 0, 0));
1821 bool RenderWidgetHostViewEfl::IsLastAvailableTextEmpty() const {
1822 return RenderWidgetHostViewBase::selection_text_.empty();
1825 bool RenderWidgetHostViewEfl::IsIMEShow() const {
1827 return im_context_->IsShow();
1832 gfx::Rect RenderWidgetHostViewEfl::GetIMERect() const {
1834 return im_context_->GetIMERect();
1839 ///////////////////////////////////////////////////////////////////////////
1840 // DelegatedFrameHost, public:
1842 ui::Layer* RenderWidgetHostViewEfl::DelegatedFrameHostGetLayer() const {
1843 return root_layer_.get();
1846 bool RenderWidgetHostViewEfl::DelegatedFrameHostIsVisible() const {
1847 return !host_->is_hidden();
1850 gfx::Size RenderWidgetHostViewEfl::DelegatedFrameHostDesiredSizeInDIP() const{
1851 gfx::Rect bounds = GetViewBoundsInPix();
1852 return bounds.size();
1855 bool RenderWidgetHostViewEfl::DelegatedFrameCanCreateResizeLock() const {
1856 // On Windows and Linux, holding pointer moves will not help throttling
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 .
1864 scoped_ptr<ResizeLock>
1865 RenderWidgetHostViewEfl::DelegatedFrameHostCreateResizeLock(
1866 bool defer_compositor_lock) {
1867 ResizeLock* lock = NULL;
1868 return scoped_ptr<ResizeLock>(lock);
1871 void RenderWidgetHostViewEfl::DelegatedFrameHostResizeLockWasReleased() {
1872 host_->WasResized();
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));
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));
1889 void RenderWidgetHostViewEfl::DelegatedFrameHostOnLostCompositorResources() {
1890 host_->ScheduleComposite();
1893 void RenderWidgetHostViewEfl::DelegatedFrameHostUpdateVSyncParameters(
1894 const base::TimeTicks& timebase,
1895 const base::TimeDelta& interval) {
1896 host_->UpdateVSyncParameters(timebase, interval);
1898 } // namespace content