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

@ -0,0 +1,78 @@
Index: web_contents_impl.cc
===================================================================
--- web_contents_impl.cc (revision 275973)
+++ web_contents_impl.cc (working copy)
@@ -1059,22 +1059,29 @@
params.browser_context, params.site_instance, params.routing_id,
params.main_frame_routing_id);
- WebContentsViewDelegate* delegate =
- GetContentClient()->browser()->GetWebContentsViewDelegate(this);
+ if (params.view && params.delegate_view) {
+ view_.reset(params.view);
+ render_view_host_delegate_view_ = params.delegate_view;
+ }
- if (browser_plugin_guest_) {
- scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
+ if (!view_) {
+ WebContentsViewDelegate* delegate =
+ GetContentClient()->browser()->GetWebContentsViewDelegate(this);
- WebContentsViewGuest* rv = new WebContentsViewGuest(
- this, browser_plugin_guest_.get(), platform_view.Pass(),
- render_view_host_delegate_view_);
- render_view_host_delegate_view_ = rv;
- view_.reset(rv);
- } else {
- // Regular WebContentsView.
- view_.reset(CreateWebContentsView(
- this, delegate, &render_view_host_delegate_view_));
+ if (browser_plugin_guest_) {
+ scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
+ this, delegate, &render_view_host_delegate_view_));
+
+ WebContentsViewGuest* rv = new WebContentsViewGuest(
+ this, browser_plugin_guest_.get(), platform_view.Pass(),
+ render_view_host_delegate_view_);
+ render_view_host_delegate_view_ = rv;
+ view_.reset(rv);
+ } else {
+ // Regular WebContentsView.
+ view_.reset(CreateWebContentsView(
+ this, delegate, &render_view_host_delegate_view_));
+ }
}
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
@@ -1381,6 +1388,9 @@
static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
+ content::WebContentsView* view = NULL;
+ content::RenderViewHostDelegateView* delegate_view = NULL;
+
if (delegate_ &&
!delegate_->ShouldCreateWebContents(this,
route_id,
@@ -1388,7 +1398,9 @@
params.frame_name,
params.target_url,
partition_id,
- session_storage_namespace)) {
+ session_storage_namespace,
+ &view,
+ &delegate_view)) {
if (route_id != MSG_ROUTING_NONE &&
!RenderViewHost::FromID(render_process_id, route_id)) {
// If the embedder didn't create a WebContents for this route, we need to
@@ -1408,6 +1420,8 @@
create_params.main_frame_routing_id = main_frame_route_id;
create_params.opener = this;
create_params.opener_suppressed = params.opener_suppressed;
+ create_params.view = view;
+ create_params.delegate_view = delegate_view;
if (params.disposition == NEW_BACKGROUND_TAB)
create_params.initially_hidden = true;

View File

@ -1,37 +0,0 @@
Index: content_browser_client.cc
===================================================================
--- content_browser_client.cc (revision 275973)
+++ content_browser_client.cc (working copy)
@@ -252,6 +252,10 @@
return true;
}
+SkColor ContentBrowserClient::GetBaseBackgroundColor(RenderViewHost* rvh) {
+ return SK_ColorWHITE;
+}
+
base::FilePath ContentBrowserClient::GetDefaultDownloadDirectory() {
return base::FilePath();
}
Index: content_browser_client.h
===================================================================
--- content_browser_client.h (revision 275973)
+++ content_browser_client.h (working copy)
@@ -23,6 +23,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/base/window_open_disposition.h"
#include "webkit/browser/fileapi/file_system_context.h"
@@ -533,6 +534,9 @@
// Clears browser cookies.
virtual void ClearCookies(RenderViewHost* rvh) {}
+ // Returns the base background color.
+ virtual SkColor GetBaseBackgroundColor(RenderViewHost* rvh);
+
// Returns the default download directory.
// This can be called on any thread.
virtual base::FilePath GetDefaultDownloadDirectory();

View File

@ -0,0 +1,132 @@
Index: content_browser_client.cc
===================================================================
--- content_browser_client.cc (revision 275973)
+++ content_browser_client.cc (working copy)
@@ -252,6 +252,10 @@
return true;
}
+SkColor ContentBrowserClient::GetBaseBackgroundColor(RenderViewHost* rvh) {
+ return SK_ColorWHITE;
+}
+
base::FilePath ContentBrowserClient::GetDefaultDownloadDirectory() {
return base::FilePath();
}
Index: content_browser_client.h
===================================================================
--- content_browser_client.h (revision 275973)
+++ content_browser_client.h (working copy)
@@ -23,6 +23,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
+#include "third_party/skia/include/core/SkColor.h"
#include "third_party/WebKit/public/web/WebNotificationPresenter.h"
#include "ui/base/window_open_disposition.h"
#include "webkit/browser/fileapi/file_system_context.h"
@@ -533,6 +534,9 @@
// Clears browser cookies.
virtual void ClearCookies(RenderViewHost* rvh) {}
+ // Returns the base background color.
+ virtual SkColor GetBaseBackgroundColor(RenderViewHost* rvh);
+
// Returns the default download directory.
// This can be called on any thread.
virtual base::FilePath GetDefaultDownloadDirectory();
Index: web_contents.cc
===================================================================
--- web_contents.cc (revision 275973)
+++ web_contents.cc (working copy)
@@ -17,7 +17,9 @@
main_frame_routing_id(MSG_ROUTING_NONE),
initially_hidden(false),
guest_instance_id(0),
- context(NULL) {}
+ context(NULL),
+ view(NULL),
+ delegate_view(NULL) {}
WebContents::CreateParams::CreateParams(
BrowserContext* context, SiteInstance* site)
@@ -29,7 +31,9 @@
main_frame_routing_id(MSG_ROUTING_NONE),
initially_hidden(false),
guest_instance_id(0),
- context(NULL) {}
+ context(NULL),
+ view(NULL),
+ delegate_view(NULL) {}
WebContents::CreateParams::~CreateParams() {
}
Index: web_contents.h
===================================================================
--- web_contents.h (revision 275973)
+++ web_contents.h (working copy)
@@ -50,9 +50,11 @@
class RenderFrameHost;
class RenderProcessHost;
class RenderViewHost;
+class RenderViewHostDelegateView;
class RenderWidgetHostView;
class SiteInstance;
class WebContentsDelegate;
+class WebContentsView;
struct CustomContextMenuContext;
struct DropData;
struct RendererPreferences;
@@ -120,6 +122,10 @@
// Used to specify the location context which display the new view should
// belong. This can be NULL if not needed.
gfx::NativeView context;
+
+ // Optionally specify the view and delegate view.
+ content::WebContentsView* view;
+ content::RenderViewHostDelegateView* delegate_view;
};
// Creates a new WebContents.
Index: web_contents_delegate.cc
===================================================================
--- web_contents_delegate.cc (revision 275973)
+++ web_contents_delegate.cc (working copy)
@@ -136,7 +136,9 @@
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
- SessionStorageNamespace* session_storage_namespace) {
+ SessionStorageNamespace* session_storage_namespace,
+ content::WebContentsView** view,
+ content::RenderViewHostDelegateView** delegate_view) {
return true;
}
Index: web_contents_delegate.h
===================================================================
--- web_contents_delegate.h (revision 275973)
+++ web_contents_delegate.h (working copy)
@@ -36,9 +36,11 @@
class JavaScriptDialogManager;
class PageState;
class RenderViewHost;
+class RenderViewHostDelegateView;
class SessionStorageNamespace;
class WebContents;
class WebContentsImpl;
+class WebContentsView;
struct ColorSuggestion;
struct ContextMenuParams;
struct DropData;
@@ -312,7 +314,9 @@
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
- SessionStorageNamespace* session_storage_namespace);
+ SessionStorageNamespace* session_storage_namespace,
+ content::WebContentsView** view,
+ content::RenderViewHostDelegateView** delegate_view);
// Notifies the delegate about the creation of a new WebContents. This
// typically happens when popups are created.

View File

@ -11,6 +11,20 @@ Index: desktop_aura/desktop_screen_win.cc
aura::WindowTreeHost* host = window->GetHost();
return host ? host->GetAcceleratedWidget() : NULL;
}
Index: desktop_aura/desktop_screen_x11.cc
===================================================================
--- desktop_aura/desktop_screen_x11.cc (revision 275973)
+++ desktop_aura/desktop_screen_x11.cc (working copy)
@@ -220,6 +220,9 @@
gfx::Display DesktopScreenX11::GetDisplayNearestWindow(
gfx::NativeView window) const {
+ if (!window)
+ return GetPrimaryDisplay();
+
// Getting screen bounds here safely is hard.
//
// You'd think we'd be able to just call window->GetBoundsInScreen(), but we
Index: desktop_aura/desktop_window_tree_host_win.cc
===================================================================
--- desktop_aura/desktop_window_tree_host_win.cc (revision 275973)

View File

@ -0,0 +1,76 @@
Index: public/web/WebView.h
===================================================================
--- public/web/WebView.h (revision 175829)
+++ public/web/WebView.h (working copy)
@@ -416,6 +416,7 @@
// Sets whether select popup menus should be rendered by the browser.
BLINK_EXPORT static void setUseExternalPopupMenus(bool);
+ virtual void setUseExternalPopupMenusThisInstance(bool) = 0;
// Hides any popup (suggestions, selects...) that might be showing.
virtual void hidePopups() = 0;
Index: Source/web/ChromeClientImpl.cpp
===================================================================
--- Source/web/ChromeClientImpl.cpp (revision 175829)
+++ Source/web/ChromeClientImpl.cpp (working copy)
@@ -729,7 +729,7 @@
PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(LocalFrame& frame, PopupMenuClient* client) const
{
- if (WebViewImpl::useExternalPopupMenus())
+ if (m_webView->useExternalPopupMenus())
return adoptRef(new ExternalPopupMenu(frame, client, *m_webView));
return adoptRef(new PopupMenuChromium(frame, client));
Index: Source/web/WebViewImpl.cpp
===================================================================
--- Source/web/WebViewImpl.cpp (revision 175829)
+++ Source/web/WebViewImpl.cpp (working copy)
@@ -365,6 +365,7 @@
, m_fakePageScaleAnimationPageScaleFactor(0)
, m_fakePageScaleAnimationUseAnchor(false)
, m_contextMenuAllowed(false)
+ , m_shouldUseExternalPopupMenus(shouldUseExternalPopupMenus)
, m_doingDragAndDrop(false)
, m_ignoreInputEvents(false)
, m_compositorDeviceScaleFactorOverride(0)
@@ -3628,9 +3629,14 @@
updateLayerTreeViewport();
}
+void WebViewImpl::setUseExternalPopupMenusThisInstance(bool useExternalPopupMenus)
+{
+ m_shouldUseExternalPopupMenus = useExternalPopupMenus;
+}
+
bool WebViewImpl::useExternalPopupMenus()
{
- return shouldUseExternalPopupMenus;
+ return m_shouldUseExternalPopupMenus;
}
void WebViewImpl::startDragging(LocalFrame* frame,
Index: Source/web/WebViewImpl.h
===================================================================
--- Source/web/WebViewImpl.h (revision 175829)
+++ Source/web/WebViewImpl.h (working copy)
@@ -352,7 +352,8 @@
// Returns true if popup menus should be rendered by the browser, false if
// they should be rendered by WebKit (which is the default).
- static bool useExternalPopupMenus();
+ void setUseExternalPopupMenusThisInstance(bool);
+ bool useExternalPopupMenus();
bool contextMenuAllowed() const
{
@@ -628,6 +629,8 @@
bool m_contextMenuAllowed;
+ bool m_shouldUseExternalPopupMenus;
+
bool m_doingDragAndDrop;
bool m_ignoreInputEvents;