mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
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:
@@ -268,10 +268,12 @@ bool CefBrowserImpl::SendProcessMessage(CefProcessId target_process,
|
||||
|
||||
CefBrowserImpl::CefBrowserImpl(content::RenderView* render_view,
|
||||
int browser_id,
|
||||
bool is_popup)
|
||||
bool is_popup,
|
||||
bool is_windowless)
|
||||
: content::RenderViewObserver(render_view),
|
||||
browser_id_(browser_id),
|
||||
is_popup_(is_popup),
|
||||
is_windowless_(is_windowless),
|
||||
last_focused_frame_id_(webkit_glue::kInvalidFrameId) {
|
||||
response_manager_.reset(new CefResponseManager);
|
||||
}
|
||||
|
@@ -75,7 +75,8 @@ class CefBrowserImpl : public CefBrowser,
|
||||
|
||||
CefBrowserImpl(content::RenderView* render_view,
|
||||
int browser_id,
|
||||
bool is_popup);
|
||||
bool is_popup,
|
||||
bool is_windowless);
|
||||
virtual ~CefBrowserImpl();
|
||||
|
||||
void LoadRequest(const CefMsg_LoadRequest_Params& params);
|
||||
@@ -95,6 +96,7 @@ class CefBrowserImpl : public CefBrowser,
|
||||
|
||||
int browser_id() const { return browser_id_; }
|
||||
bool is_popup() const { return is_popup_; }
|
||||
bool is_windowless() const { return is_windowless_; }
|
||||
content::RenderView* render_view() const {
|
||||
return content::RenderViewObserver::render_view();
|
||||
}
|
||||
@@ -137,6 +139,7 @@ class CefBrowserImpl : public CefBrowser,
|
||||
// same browser ID.
|
||||
int browser_id_;
|
||||
bool is_popup_;
|
||||
bool is_windowless_;
|
||||
|
||||
// Id of the last frame that had focus.
|
||||
int64 last_focused_frame_id_;
|
||||
|
@@ -54,6 +54,7 @@ MSVC_POP_WARNING();
|
||||
#include "third_party/WebKit/public/platform/WebWorkerRunLoop.h"
|
||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||
#include "third_party/WebKit/public/web/WebFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||
#include "third_party/WebKit/public/web/WebKit.h"
|
||||
#include "third_party/WebKit/public/web/WebPluginParams.h"
|
||||
#include "third_party/WebKit/public/web/WebPrerendererClient.h"
|
||||
@@ -434,6 +435,90 @@ void CefContentRendererClient::RenderViewCreated(
|
||||
BrowserCreated(render_view, render_view->GetMainRenderFrame());
|
||||
}
|
||||
|
||||
bool CefContentRendererClient::OverrideCreatePlugin(
|
||||
content::RenderFrame* render_frame,
|
||||
blink::WebLocalFrame* frame,
|
||||
const blink::WebPluginParams& params,
|
||||
blink::WebPlugin** plugin) {
|
||||
CefRefPtr<CefBrowserImpl> browser =
|
||||
CefBrowserImpl::GetBrowserForMainFrame(frame->top());
|
||||
if (!browser || !browser->is_windowless())
|
||||
return false;
|
||||
|
||||
#if defined(ENABLE_PLUGINS)
|
||||
if (base::UTF16ToASCII(params.mimeType) == content::kBrowserPluginMimeType)
|
||||
return false;
|
||||
|
||||
content::RenderFrameImpl* render_frame_impl =
|
||||
static_cast<content::RenderFrameImpl*>(render_frame);
|
||||
|
||||
content::WebPluginInfo info;
|
||||
std::string mime_type;
|
||||
bool found = false;
|
||||
render_frame_impl->Send(
|
||||
new FrameHostMsg_GetPluginInfo(
|
||||
render_frame_impl->GetRoutingID(),
|
||||
params.url,
|
||||
frame->top()->document().url(),
|
||||
params.mimeType.utf8(),
|
||||
&found,
|
||||
&info,
|
||||
&mime_type));
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
bool flash = LowerCaseEqualsASCII(mime_type,
|
||||
"application/x-shockwave-flash");
|
||||
bool silverlight = StartsWithASCII(mime_type,
|
||||
"application/x-silverlight", false);
|
||||
|
||||
if (flash) {
|
||||
// "wmode" values of "opaque" or "transparent" are allowed.
|
||||
size_t size = params.attributeNames.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
std::string name = params.attributeNames[i].utf8();
|
||||
if (name == "wmode") {
|
||||
std::string value = params.attributeValues[i].utf8();
|
||||
if (value == "opaque" || value == "transparent")
|
||||
flash = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flash || silverlight) {
|
||||
// Force Flash and Silverlight plugins to use windowless mode.
|
||||
blink::WebPluginParams params_to_use = params;
|
||||
params_to_use.mimeType = blink::WebString::fromUTF8(mime_type);
|
||||
|
||||
size_t size = params.attributeNames.size();
|
||||
blink::WebVector<blink::WebString> new_names(size+1),
|
||||
new_values(size+1);
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
new_names[i] = params.attributeNames[i];
|
||||
new_values[i] = params.attributeValues[i];
|
||||
}
|
||||
|
||||
if (flash) {
|
||||
new_names[size] = "wmode";
|
||||
new_values[size] = "opaque";
|
||||
} else if (silverlight) {
|
||||
new_names[size] = "windowless";
|
||||
new_values[size] = "true";
|
||||
}
|
||||
|
||||
params_to_use.attributeNames.swap(new_names);
|
||||
params_to_use.attributeValues.swap(new_values);
|
||||
|
||||
*plugin = render_frame_impl->CreatePlugin(frame, info, params_to_use);
|
||||
return true;
|
||||
}
|
||||
#endif // defined(ENABLE_PLUGINS)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefContentRendererClient::HandleNavigation(
|
||||
content::RenderFrame* render_frame,
|
||||
content::DocumentState* document_state,
|
||||
@@ -578,8 +663,18 @@ void CefContentRendererClient::BrowserCreated(
|
||||
if (GetBrowserForView(render_view))
|
||||
return;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// FIXME: It would be better if this API would be a callback from the
|
||||
// WebKit layer, or if it would be exposed as an WebView instance method; the
|
||||
// current implementation uses a static variable, and WebKit needs to be
|
||||
// patched in order to make it work for each WebView instance
|
||||
render_view->GetWebView()->setUseExternalPopupMenusThisInstance(
|
||||
!params.is_windowless);
|
||||
#endif
|
||||
|
||||
CefRefPtr<CefBrowserImpl> browser =
|
||||
new CefBrowserImpl(render_view, params.browser_id, params.is_popup);
|
||||
new CefBrowserImpl(render_view, params.browser_id, params.is_popup,
|
||||
params.is_windowless);
|
||||
browsers_.insert(std::make_pair(render_view, browser));
|
||||
|
||||
new CefPrerendererClient(render_view);
|
||||
|
@@ -76,6 +76,11 @@ class CefContentRendererClient : public content::ContentRendererClient,
|
||||
virtual void RenderThreadStarted() OVERRIDE;
|
||||
virtual void RenderFrameCreated(content::RenderFrame* render_frame) OVERRIDE;
|
||||
virtual void RenderViewCreated(content::RenderView* render_view) OVERRIDE;
|
||||
virtual bool OverrideCreatePlugin(
|
||||
content::RenderFrame* render_frame,
|
||||
blink::WebLocalFrame* frame,
|
||||
const blink::WebPluginParams& params,
|
||||
blink::WebPlugin** plugin) OVERRIDE;
|
||||
virtual bool HandleNavigation(content::RenderFrame* render_frame,
|
||||
content::DocumentState* document_state,
|
||||
int opener_id,
|
||||
|
Reference in New Issue
Block a user