Implement off-screen rendering support using delegated rendering (issue #1257).

This implementation supports both GPU compositing and software compositing (used when GPU is not supported or when passing `--disable-gpu --disable-gpu-compositing` command-line flags). GPU-accelerated features (WebGL and 3D CSS) that did not work with the previous off-screen rendering implementation do work with this implementation when GPU support is available.

Rendering now operates on a per-frame basis. The frame rate is configurable via CefBrowserSettings.windowless_frame_rate up to a maximum of 60fps (potentially limited by how fast the system can generate new frames). CEF generates a bitmap from the compositor backing and passes it to CefRenderHandler::OnPaint.

The previous CefRenderHandler/CefBrowserHost API for off-screen rendering has been restored mostly as-is with some minor changes:

- CefBrowserHost::Invalidate no longer accepts a CefRect region argument. Instead of invalidating a specific region it now triggers generation of a new frame.
- The |dirtyRects| argument to CefRenderHandler::OnPaint will now always be a single CefRect representing the whole view (frame) size. Previously, invalidated regions were listed separately.
- Linux: CefBrowserHost::SendKeyEvent now expects X11 event information instead of GTK event information. See cefclient for an example of converting GTK events to the necessary format.
- Sizes passed to the CefRenderHandler OnPaint and OnPopupSize methods are now already DPI scaled. Previously, the client had to perform DPI scaling.
- Includes drag&drop implementation from issue #1032.
- Includes unit test fixes from issue #1245.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1751 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2014-06-30 22:30:29 +00:00
parent 133317eeec
commit dea4daffd7
106 changed files with 13053 additions and 176 deletions

View File

@@ -39,6 +39,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_drag_data_capi.h"
#include "include/capi/cef_frame_capi.h"
#include "include/capi/cef_process_message_capi.h"
#include "include/capi/cef_request_context_capi.h"
@@ -357,6 +358,46 @@ typedef struct _cef_browser_host_t {
int (CEF_CALLBACK *is_mouse_cursor_change_disabled)(
struct _cef_browser_host_t* self);
///
// Returns true (1) if window rendering is disabled.
///
int (CEF_CALLBACK *is_window_rendering_disabled)(
struct _cef_browser_host_t* self);
///
// Notify the browser that the widget has been resized. The browser will first
// call cef_render_handler_t::GetViewRect to get the new size and then call
// cef_render_handler_t::OnPaint asynchronously with the updated regions. This
// function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *was_resized)(struct _cef_browser_host_t* self);
///
// Notify the browser that it has been hidden or shown. Layouting and
// cef_render_handler_t::OnPaint notification will stop when the browser is
// hidden. This function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *was_hidden)(struct _cef_browser_host_t* self, int hidden);
///
// Send a notification to the browser that the screen info has changed. The
// browser will then call cef_render_handler_t::GetScreenInfo to update the
// screen information with the new values. This simulates moving the webview
// window from one display to another, or changing the properties of the
// current display. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *notify_screen_info_changed)(
struct _cef_browser_host_t* self);
///
// Invalidate the view. The browser will call cef_render_handler_t::OnPaint
// asynchronously. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *invalidate)(struct _cef_browser_host_t* self,
cef_paint_element_type_t type);
///
// Send a key event to the browser.
///
@@ -382,6 +423,8 @@ typedef struct _cef_browser_host_t {
// Send a mouse wheel event to the browser. The |x| and |y| coordinates are
// relative to the upper-left corner of the view. The |deltaX| and |deltaY|
// values represent the movement delta in the X and Y directions respectively.
// In order to scroll inside select popups with window rendering disabled
// cef_render_handler_t::GetScreenPoint should be implemented properly.
///
void (CEF_CALLBACK *send_mouse_wheel_event)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event, int deltaX, int deltaY);
@@ -397,6 +440,90 @@ typedef struct _cef_browser_host_t {
///
void (CEF_CALLBACK *send_capture_lost_event)(
struct _cef_browser_host_t* self);
///
// Get the NSTextInputContext implementation for enabling IME on Mac when
// window rendering is disabled.
///
cef_text_input_context_t (CEF_CALLBACK *get_nstext_input_context)(
struct _cef_browser_host_t* self);
///
// Handles a keyDown event prior to passing it through the NSTextInputClient
// machinery.
///
void (CEF_CALLBACK *handle_key_event_before_text_input_client)(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent);
///
// Performs any additional actions after NSTextInputClient handles the event.
///
void (CEF_CALLBACK *handle_key_event_after_text_input_client)(
struct _cef_browser_host_t* self, cef_event_handle_t keyEvent);
///
// Call this function when the user drags the mouse into the web view (before
// calling DragTargetDragOver/DragTargetLeave/DragTargetDrop). |drag_data|
// should not contain file contents as this type of data is not allowed to be
// dragged into the web view. File contents can be removed using
// cef_drag_data_t::ResetFileContents (for example, if |drag_data| comes from
// cef_render_handler_t::StartDragging). This function is only used when
// window rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_enter)(struct _cef_browser_host_t* self,
struct _cef_drag_data_t* drag_data,
const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops);
///
// Call this function each time the mouse is moved across the web view during
// a drag operation (after calling DragTargetDragEnter and before calling
// DragTargetDragLeave/DragTargetDrop). This function is only used when window
// rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_over)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event,
cef_drag_operations_mask_t allowed_ops);
///
// Call this function when the user drags the mouse out of the web view (after
// calling DragTargetDragEnter). This function is only used when window
// rendering is disabled.
///
void (CEF_CALLBACK *drag_target_drag_leave)(struct _cef_browser_host_t* self);
///
// Call this function when the user completes the drag operation by dropping
// the object onto the web view (after calling DragTargetDragEnter). The
// object being dropped is |drag_data|, given as an argument to the previous
// DragTargetDragEnter call. This function is only used when window rendering
// is disabled.
///
void (CEF_CALLBACK *drag_target_drop)(struct _cef_browser_host_t* self,
const struct _cef_mouse_event_t* event);
///
// Call this function when the drag operation started by a
// cef_render_handler_t::StartDragging call has ended either in a drop or by
// being cancelled. |x| and |y| are mouse coordinates relative to the upper-
// left corner of the view. If the web view is both the drag source and the
// drag target then all DragTarget* functions should be called before
// DragSource* mthods. This function is only used when window rendering is
// disabled.
///
void (CEF_CALLBACK *drag_source_ended_at)(struct _cef_browser_host_t* self,
int x, int y, cef_drag_operations_mask_t op);
///
// Call this function when the drag operation started by a
// cef_render_handler_t::StartDragging call has completed. This function may
// be called immediately without first calling DragSourceEndedAt to cancel a
// drag operation. If the web view is both the drag source and the drag target
// then all DragTarget* functions should be called before DragSource* mthods.
// This function is only used when window rendering is disabled.
///
void (CEF_CALLBACK *drag_source_system_drag_ended)(
struct _cef_browser_host_t* self);
} cef_browser_host_t;

View File

@@ -51,6 +51,7 @@
#include "include/capi/cef_life_span_handler_capi.h"
#include "include/capi/cef_load_handler_capi.h"
#include "include/capi/cef_process_message_capi.h"
#include "include/capi/cef_render_handler_capi.h"
#include "include/capi/cef_request_handler_capi.h"
#ifdef __cplusplus
@@ -138,6 +139,12 @@ typedef struct _cef_client_t {
struct _cef_load_handler_t* (CEF_CALLBACK *get_load_handler)(
struct _cef_client_t* self);
///
// Return the handler for off-screen rendering events.
///
struct _cef_render_handler_t* (CEF_CALLBACK *get_render_handler)(
struct _cef_client_t* self);
///
// Return the handler for browser request events.
///

View File

@@ -39,6 +39,7 @@
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_stream_capi.h"
#ifdef __cplusplus
extern "C" {
@@ -55,6 +56,16 @@ typedef struct _cef_drag_data_t {
///
cef_base_t base;
///
// Returns a copy of the current object.
///
struct _cef_drag_data_t* (CEF_CALLBACK *clone)(struct _cef_drag_data_t* self);
///
// Returns true (1) if this object is read-only.
///
int (CEF_CALLBACK *is_read_only)(struct _cef_drag_data_t* self);
///
// Returns true (1) if the drag data is a link.
///
@@ -120,15 +131,79 @@ typedef struct _cef_drag_data_t {
cef_string_userfree_t (CEF_CALLBACK *get_file_name)(
struct _cef_drag_data_t* self);
///
// Write the contents of the file being dragged out of the web view into
// |writer|. Returns the number of bytes sent to |writer|. If |writer| is NULL
// this function will return the size of the file contents in bytes. Call
// get_file_name() to get a suggested name for the file.
///
size_t (CEF_CALLBACK *get_file_contents)(struct _cef_drag_data_t* self,
struct _cef_stream_writer_t* writer);
///
// Retrieve the list of file names that are being dragged into the browser
// window.
///
int (CEF_CALLBACK *get_file_names)(struct _cef_drag_data_t* self,
cef_string_list_t names);
///
// Set the link URL that is being dragged.
///
void (CEF_CALLBACK *set_link_url)(struct _cef_drag_data_t* self,
const cef_string_t* url);
///
// Set the title associated with the link being dragged.
///
void (CEF_CALLBACK *set_link_title)(struct _cef_drag_data_t* self,
const cef_string_t* title);
///
// Set the metadata associated with the link being dragged.
///
void (CEF_CALLBACK *set_link_metadata)(struct _cef_drag_data_t* self,
const cef_string_t* data);
///
// Set the plain text fragment that is being dragged.
///
void (CEF_CALLBACK *set_fragment_text)(struct _cef_drag_data_t* self,
const cef_string_t* text);
///
// Set the text/html fragment that is being dragged.
///
void (CEF_CALLBACK *set_fragment_html)(struct _cef_drag_data_t* self,
const cef_string_t* html);
///
// Set the base URL that the fragment came from.
///
void (CEF_CALLBACK *set_fragment_base_url)(struct _cef_drag_data_t* self,
const cef_string_t* base_url);
///
// Reset the file contents. You should do this before calling
// cef_browser_host_t::DragTargetDragEnter as the web view does not allow us
// to drag in this kind of data.
///
void (CEF_CALLBACK *reset_file_contents)(struct _cef_drag_data_t* self);
///
// Add a file that is being dragged into the webview.
///
void (CEF_CALLBACK *add_file)(struct _cef_drag_data_t* self,
const cef_string_t* path, const cef_string_t* display_name);
} cef_drag_data_t;
///
// Create a new cef_drag_data_t object.
///
CEF_EXPORT cef_drag_data_t* cef_drag_data_create();
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,163 @@
// Copyright (c) 2014 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_drag_data_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Implement this structure to handle events when window rendering is disabled.
// The functions of this structure will be called on the UI thread.
///
typedef struct _cef_render_handler_t {
///
// Base structure.
///
cef_base_t base;
///
// Called to retrieve the root window rectangle in screen coordinates. Return
// true (1) if the rectangle was provided.
///
int (CEF_CALLBACK *get_root_screen_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the view rectangle which is relative to screen
// coordinates. Return true (1) if the rectangle was provided.
///
int (CEF_CALLBACK *get_view_rect)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_rect_t* rect);
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true (1) if the screen coordinates were provided.
///
int (CEF_CALLBACK *get_screen_point)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int viewX, int viewY, int* screenX,
int* screenY);
///
// Called to allow the client to fill in the CefScreenInfo object with
// appropriate values. Return true (1) if the |screen_info| structure has been
// modified.
//
// If the screen info rectangle is left NULL the rectangle from GetViewRect
// will be used. If the rectangle is still NULL or invalid popups may not be
// drawn correctly.
///
int (CEF_CALLBACK *get_screen_info)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, struct _cef_screen_info_t* screen_info);
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true (1) and hidden if |show| is false (0).
///
void (CEF_CALLBACK *on_popup_show)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, int show);
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size.
///
void (CEF_CALLBACK *on_popup_size)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, const cef_rect_t* rect);
///
// Called when an element should be painted. |type| indicates whether the
// element is the view or the popup widget. |buffer| contains the pixel data
// for the whole image. |dirtyRects| contains the set of rectangles that need
// to be repainted. On Windows |buffer| will be |width|*|height|*4 bytes in
// size and represents a BGRA image with an upper-left origin.
///
void (CEF_CALLBACK *on_paint)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_paint_element_type_t type,
size_t dirtyRectsCount, cef_rect_t const* dirtyRects, const void* buffer,
int width, int height);
///
// Called when the browser window's cursor has changed.
///
void (CEF_CALLBACK *on_cursor_change)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_cursor_handle_t cursor);
///
// Called when the user starts dragging content in the web view. Contextual
// information about the dragged content is supplied by |drag_data|. OS APIs
// that run a system message loop may be used within the StartDragging call.
//
// Return false (0) to abort the drag operation. Don't call any of
// cef_browser_host_t::DragSource*Ended* functions after returning false (0).
//
// Return true (1) to handle the drag operation. Call
// cef_browser_host_t::DragSourceEndedAt and DragSourceSystemDragEnded either
// synchronously or asynchronously to inform the web view that the drag
// operation has ended.
///
int (CEF_CALLBACK *start_dragging)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, struct _cef_drag_data_t* drag_data,
cef_drag_operations_mask_t allowed_ops, int x, int y);
///
// Called when the web view wants to update the mouse cursor during a drag &
// drop operation. |operation| describes the allowed operation (none, move,
// copy, link).
///
void (CEF_CALLBACK *update_drag_cursor)(struct _cef_render_handler_t* self,
struct _cef_browser_t* browser, cef_drag_operations_mask_t operation);
///
// Called when the scroll offset has changed.
///
void (CEF_CALLBACK *on_scroll_offset_changed)(
struct _cef_render_handler_t* self, struct _cef_browser_t* browser);
} cef_render_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_