mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-03-25 08:20:56 +01:00
Add support for shared texture and external BeginFrame in OSR mode (issue #1006)
- Add CefWindowInfo::shared_texture_enabled and CefRenderHandler::OnAcceleratedPaint for shared texture support. Currently only supported on Windows (D3D11). - Add CefWindowInfo::external_begin_frame_enabled and CefBrowserHost::SendExternalBeginFrame for external begin frame support.
This commit is contained in:
parent
09afa3a843
commit
713eebcafc
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=ff3ebc51ed5743aabac0be94caf2edeedbd413b7$
|
||||
// $hash=caba7ed3d6e19f7a4499fb48f627c2f5b40e46bc$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||
@ -571,6 +571,13 @@ typedef struct _cef_browser_host_t {
|
||||
void(CEF_CALLBACK* invalidate)(struct _cef_browser_host_t* self,
|
||||
cef_paint_element_type_t type);
|
||||
|
||||
///
|
||||
// Issue a BeginFrame request to Chromium. Only valid when
|
||||
// cef_window_tInfo::external_begin_frame_enabled is set to true (1).
|
||||
///
|
||||
void(CEF_CALLBACK* send_external_begin_frame)(
|
||||
struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
// Send a key event to the browser.
|
||||
///
|
||||
|
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=d259309846e69d866a834aa701bbf8c9562dd117$
|
||||
// $hash=ef8abd4a01fe1047abc0d2ab1c359704611a60ac$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
|
||||
@ -142,6 +142,18 @@ typedef struct _cef_render_handler_t {
|
||||
int width,
|
||||
int height);
|
||||
|
||||
///
|
||||
// Called when an view has been rendered to the given shared texture handle.
|
||||
// Currently, the shared handle represents a D3D11 Texture2D that can be
|
||||
// accessed with the OpenSharedResource function available from a ID3D11Device
|
||||
///
|
||||
void(CEF_CALLBACK* on_accelerated_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,
|
||||
void* shared_handle);
|
||||
|
||||
///
|
||||
// Called when the browser's cursor has changed. If |type| is CT_CUSTOM then
|
||||
// |custom_cursor_info| will be populated with the custom cursor information.
|
||||
|
@ -595,6 +595,13 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
||||
/*--cef()--*/
|
||||
virtual void Invalidate(PaintElementType type) = 0;
|
||||
|
||||
///
|
||||
// Issue a BeginFrame request to Chromium. Only valid when
|
||||
// CefWindowInfo::external_begin_frame_enabled is set to true.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void SendExternalBeginFrame() = 0;
|
||||
|
||||
///
|
||||
// Send a key event to the browser.
|
||||
///
|
||||
|
@ -135,7 +135,8 @@ class CefRenderHandler : public virtual CefBaseRefCounted {
|
||||
// contains the pixel data for the whole image. |dirtyRects| contains the set
|
||||
// of rectangles in pixel coordinates that need to be repainted. |buffer| will
|
||||
// be |width|*|height|*4 bytes in size and represents a BGRA image with an
|
||||
// upper-left origin.
|
||||
// upper-left origin. This method is only called when
|
||||
// CefWindowInfo::shared_texture_enabled is set to false.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
@ -145,6 +146,21 @@ class CefRenderHandler : public virtual CefBaseRefCounted {
|
||||
int width,
|
||||
int height) = 0;
|
||||
|
||||
///
|
||||
// Called when an element has been rendered to the shared texture handle.
|
||||
// |type| indicates whether the element is the view or the popup widget.
|
||||
// |dirtyRects| contains the set of rectangles in pixel coordinates that need
|
||||
// to be repainted. |shared_handle| is the handle for a D3D11 Texture2D that
|
||||
// can be accessed via ID3D11Device using the OpenSharedResource method. This
|
||||
// method is only called when CefWindowInfo::shared_texture_enabled is set to
|
||||
// true, and is currently only supported on Windows.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnAcceleratedPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
void* shared_handle) {}
|
||||
|
||||
///
|
||||
// Called when the browser's cursor has changed. If |type| is CT_CUSTOM then
|
||||
// |custom_cursor_info| will be populated with the custom cursor information.
|
||||
|
@ -82,6 +82,8 @@ struct CefWindowInfoTraits {
|
||||
target->height = src->height;
|
||||
target->parent_window = src->parent_window;
|
||||
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
|
||||
target->shared_texture_enabled = src->shared_texture_enabled;
|
||||
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
|
||||
target->window = src->window;
|
||||
}
|
||||
};
|
||||
|
@ -88,6 +88,8 @@ struct CefWindowInfoTraits {
|
||||
target->hidden = src->hidden;
|
||||
target->parent_view = src->parent_view;
|
||||
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
|
||||
target->shared_texture_enabled = src->shared_texture_enabled;
|
||||
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
|
||||
target->view = src->view;
|
||||
}
|
||||
};
|
||||
|
@ -96,6 +96,19 @@ typedef struct _cef_window_info_t {
|
||||
///
|
||||
int windowless_rendering_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable shared textures for windowless rendering. Only
|
||||
// valid if windowless_rendering_enabled above is also set to true. Currently
|
||||
// only supported on Windows (D3D11).
|
||||
///
|
||||
int shared_texture_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable the ability to issue BeginFrame requests from the
|
||||
// client application by calling CefBrowserHost::SendExternalBeginFrame.
|
||||
///
|
||||
int external_begin_frame_enabled;
|
||||
|
||||
///
|
||||
// Pointer for the new browser window. Only used with windowed rendering.
|
||||
///
|
||||
|
@ -106,6 +106,19 @@ typedef struct _cef_window_info_t {
|
||||
///
|
||||
int windowless_rendering_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable shared textures for windowless rendering. Only
|
||||
// valid if windowless_rendering_enabled above is also set to true. Currently
|
||||
// only supported on Windows (D3D11).
|
||||
///
|
||||
int shared_texture_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable the ability to issue BeginFrame from the client
|
||||
// application.
|
||||
///
|
||||
int external_begin_frame_enabled;
|
||||
|
||||
///
|
||||
// NSView pointer for the new browser view. Only used with windowed rendering.
|
||||
///
|
||||
|
@ -84,6 +84,19 @@ typedef struct _cef_window_info_t {
|
||||
///
|
||||
int windowless_rendering_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable shared textures for windowless rendering. Only
|
||||
// valid if windowless_rendering_enabled above is also set to true. Currently
|
||||
// only supported on Windows (D3D11).
|
||||
///
|
||||
int shared_texture_enabled;
|
||||
|
||||
///
|
||||
// Set to true (1) to enable the ability to issue BeginFrame requests from the
|
||||
// client application by calling CefBrowserHost::SendExternalBeginFrame.
|
||||
///
|
||||
int external_begin_frame_enabled;
|
||||
|
||||
///
|
||||
// Handle for the new browser window. Only used with windowed rendering.
|
||||
///
|
||||
|
@ -88,6 +88,8 @@ struct CefWindowInfoTraits {
|
||||
target->parent_window = src->parent_window;
|
||||
target->menu = src->menu;
|
||||
target->windowless_rendering_enabled = src->windowless_rendering_enabled;
|
||||
target->shared_texture_enabled = src->shared_texture_enabled;
|
||||
target->external_begin_frame_enabled = src->external_begin_frame_enabled;
|
||||
target->window = src->window;
|
||||
}
|
||||
};
|
||||
|
@ -1156,6 +1156,24 @@ void CefBrowserHostImpl::Invalidate(PaintElementType type) {
|
||||
platform_delegate_->Invalidate(type);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendExternalBeginFrame() {
|
||||
if (!IsWindowless()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT, base::Bind(&CefBrowserHostImpl::SendExternalBeginFrame, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents() || !platform_delegate_)
|
||||
return;
|
||||
|
||||
platform_delegate_->SendExternalBeginFrame();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostImpl::SendKeyEvent,
|
||||
|
@ -212,6 +212,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
void WasHidden(bool hidden) override;
|
||||
void NotifyScreenInfoChanged() override;
|
||||
void Invalidate(PaintElementType type) override;
|
||||
void SendExternalBeginFrame() override;
|
||||
void SendKeyEvent(const CefKeyEvent& event) override;
|
||||
void SendMouseClickEvent(const CefMouseEvent& event,
|
||||
MouseButtonType type,
|
||||
|
@ -121,6 +121,10 @@ void CefBrowserPlatformDelegate::Invalidate(cef_paint_element_type_t type) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::SendExternalBeginFrame() {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::SetWindowlessFrameRate(int frame_rate) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
@ -139,6 +139,9 @@ class CefBrowserPlatformDelegate {
|
||||
// enable transparency.
|
||||
virtual SkColor GetBackgroundColor() const = 0;
|
||||
|
||||
virtual bool CanUseSharedTexture() const = 0;
|
||||
virtual bool CanUseExternalBeginFrame() const = 0;
|
||||
|
||||
// Notify the window that it was resized.
|
||||
virtual void SynchronizeVisualProperties() = 0;
|
||||
|
||||
@ -227,6 +230,8 @@ class CefBrowserPlatformDelegate {
|
||||
// Invalidate the view. Only used with windowless rendering.
|
||||
virtual void Invalidate(cef_paint_element_type_t type);
|
||||
|
||||
virtual void SendExternalBeginFrame();
|
||||
|
||||
// Set the windowless frame rate. Only used with windowless rendering.
|
||||
virtual void SetWindowlessFrameRate(int frame_rate);
|
||||
|
||||
|
@ -34,10 +34,13 @@ namespace {
|
||||
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> CreateNativeDelegate(
|
||||
const CefWindowInfo& window_info,
|
||||
SkColor background_color) {
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame) {
|
||||
#if defined(OS_WIN)
|
||||
return std::make_unique<CefBrowserPlatformDelegateNativeWin>(
|
||||
window_info, background_color);
|
||||
window_info, background_color, use_shared_texture,
|
||||
use_external_begin_frame);
|
||||
#elif defined(OS_MACOSX)
|
||||
return std::make_unique<CefBrowserPlatformDelegateNativeMac>(
|
||||
window_info, background_color);
|
||||
@ -73,10 +76,22 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
const SkColor background_color = CefContext::Get()->GetBackgroundColor(
|
||||
&create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED);
|
||||
|
||||
bool use_shared_texture = false;
|
||||
bool use_external_begin_frame = false;
|
||||
|
||||
if (is_windowless) {
|
||||
use_shared_texture = create_params.window_info &&
|
||||
create_params.window_info->shared_texture_enabled;
|
||||
|
||||
use_external_begin_frame =
|
||||
create_params.window_info &&
|
||||
create_params.window_info->external_begin_frame_enabled;
|
||||
}
|
||||
|
||||
if (create_params.window_info) {
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(*create_params.window_info.get(),
|
||||
background_color);
|
||||
CreateNativeDelegate(*create_params.window_info.get(), background_color,
|
||||
use_shared_texture, use_external_begin_frame);
|
||||
if (is_windowless)
|
||||
return CreateOSRDelegate(std::move(native_delegate));
|
||||
return std::move(native_delegate);
|
||||
@ -84,7 +99,8 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
|
||||
// Creating a background extension host without a window.
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color);
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color,
|
||||
use_shared_texture, use_external_begin_frame);
|
||||
return std::make_unique<CefBrowserPlatformDelegateBackground>(
|
||||
std::move(native_delegate));
|
||||
}
|
||||
@ -92,7 +108,8 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
else {
|
||||
// CefWindowInfo is not used in this case.
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color);
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color,
|
||||
use_shared_texture, use_external_begin_frame);
|
||||
return std::make_unique<CefBrowserPlatformDelegateViews>(
|
||||
std::move(native_delegate),
|
||||
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
|
||||
|
@ -35,6 +35,14 @@ CefWindowHandle CefBrowserPlatformDelegateBackground::GetHostWindowHandle()
|
||||
return kNullWindowHandle;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateBackground::CanUseSharedTexture() const {
|
||||
return native_delegate_->CanUseSharedTexture();
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateBackground::CanUseExternalBeginFrame() const {
|
||||
return native_delegate_->CanUseExternalBeginFrame();
|
||||
}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateBackground::GetBackgroundColor() const {
|
||||
return native_delegate_->GetBackgroundColor();
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ class CefBrowserPlatformDelegateBackground
|
||||
void CloseHostWindow() override;
|
||||
CefWindowHandle GetHostWindowHandle() const override;
|
||||
SkColor GetBackgroundColor() const override;
|
||||
bool CanUseSharedTexture() const override;
|
||||
bool CanUseExternalBeginFrame() const override;
|
||||
void SynchronizeVisualProperties() override;
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
|
@ -42,8 +42,8 @@ void CefMimeHandlerViewGuestDelegate::OverrideWebContentsCreateParams(
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
|
||||
if (owner_browser->IsWindowless()) {
|
||||
CefWebContentsViewOSR* view_osr =
|
||||
new CefWebContentsViewOSR(owner_browser->GetBackgroundColor());
|
||||
CefWebContentsViewOSR* view_osr = new CefWebContentsViewOSR(
|
||||
owner_browser->GetBackgroundColor(), false, false);
|
||||
params->view = view_osr;
|
||||
params->delegate_view = view_osr;
|
||||
}
|
||||
|
341
libcef/browser/gpu/external_texture_manager.cc
Normal file
341
libcef/browser/gpu/external_texture_manager.cc
Normal file
@ -0,0 +1,341 @@
|
||||
// Copyright 2018 The Chromium Embedded Framework Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "cef/libcef/browser/gpu/external_texture_manager.h"
|
||||
|
||||
#include "gpu/command_buffer/service/service_utils.h"
|
||||
#include "third_party/khronos/EGL/egl.h"
|
||||
#include "third_party/khronos/EGL/eglext.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_context_egl.h"
|
||||
#include "ui/gl/gl_image.h"
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
#include "ui/gl/init/gl_factory.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <d3d11_1.h>
|
||||
#include "ui/gl/gl_angle_util_win.h"
|
||||
#include "ui/gl/gl_image_dxgi.h"
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_d3d_texture_client_buffer
|
||||
#define EGL_ANGLE_d3d_texture_client_buffer 1
|
||||
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
|
||||
#endif
|
||||
|
||||
namespace gpu {
|
||||
namespace gles2 {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
class GLImageDXGISharedHandle : public gl::GLImageDXGIBase {
|
||||
public:
|
||||
GLImageDXGISharedHandle(const gfx::Size& size)
|
||||
: GLImageDXGIBase(size),
|
||||
handle_((HANDLE)0),
|
||||
surface_(EGL_NO_SURFACE),
|
||||
texture_id_(0) {}
|
||||
|
||||
void* share_handle() const { return handle_; }
|
||||
|
||||
bool Initialize() {
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
|
||||
gl::QueryD3D11DeviceObjectFromANGLE();
|
||||
if (!d3d11_device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D11Device1> d3d11_device1;
|
||||
HRESULT hr = d3d11_device.As(&d3d11_device1);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC td = {0};
|
||||
td.ArraySize = 1;
|
||||
td.CPUAccessFlags = 0;
|
||||
td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
td.Width = GetSize().width();
|
||||
td.Height = GetSize().height();
|
||||
td.MipLevels = 1;
|
||||
td.SampleDesc.Count = 1;
|
||||
td.SampleDesc.Quality = 0;
|
||||
td.Usage = D3D11_USAGE_DEFAULT;
|
||||
td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
td.MiscFlags = 0;
|
||||
|
||||
hr = d3d11_device1->CreateTexture2D(&td, nullptr, texture_.GetAddressOf());
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a staging texture that will not be a render-target, but will be
|
||||
// shared. We could make the render target directly shareable, but the
|
||||
// staged copy is safer for synchronization and less problematic
|
||||
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
td.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
hr = d3d11_device1->CreateTexture2D(&td, nullptr,
|
||||
staging_texture_.GetAddressOf());
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If using a staging texture ... then we need the shared handle for that
|
||||
Microsoft::WRL::ComPtr<IDXGIResource> dxgi_res;
|
||||
if (staging_texture_.Get()) {
|
||||
hr = staging_texture_.As(&dxgi_res);
|
||||
} else {
|
||||
hr = texture_.As(&dxgi_res);
|
||||
}
|
||||
if (SUCCEEDED(hr)) {
|
||||
dxgi_res->GetSharedHandle(&handle_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Lock() {
|
||||
// In the future a keyed mutex could be utilized here.
|
||||
}
|
||||
|
||||
void Unlock() {
|
||||
if (staging_texture_.Get() && texture_.Get()) {
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device;
|
||||
staging_texture_->GetDevice(&d3d11_device);
|
||||
if (d3d11_device.Get()) {
|
||||
Microsoft::WRL::ComPtr<ID3D11DeviceContext> d3d11_ctx;
|
||||
d3d11_device->GetImmediateContext(&d3d11_ctx);
|
||||
if (d3d11_ctx.Get()) {
|
||||
d3d11_ctx->CopyResource(staging_texture_.Get(), texture_.Get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetSurface(EGLSurface surface, GLuint texture_id) {
|
||||
surface_ = surface;
|
||||
texture_id_ = texture_id;
|
||||
}
|
||||
|
||||
EGLSurface surface() const { return surface_; }
|
||||
|
||||
GLuint texture_id() const { return texture_id_; }
|
||||
|
||||
protected:
|
||||
~GLImageDXGISharedHandle() override {}
|
||||
|
||||
private:
|
||||
HANDLE handle_;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> staging_texture_;
|
||||
EGLSurface surface_;
|
||||
GLuint texture_id_;
|
||||
};
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
} // namespace
|
||||
|
||||
ExternalTextureManager::ExternalTextureManager() {}
|
||||
|
||||
ExternalTextureManager::~ExternalTextureManager() {}
|
||||
|
||||
void* ExternalTextureManager::CreateTexture(GLuint texture_id,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
TextureManager* tex_man) {
|
||||
void* share_handle = nullptr;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
|
||||
if (egl_display == EGL_NO_DISPLAY) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLContext curContext = eglGetCurrentContext();
|
||||
if (curContext == EGL_NO_CONTEXT) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::Size size(width, height);
|
||||
scoped_refptr<gl::GLImage> image;
|
||||
void* texture = nullptr;
|
||||
|
||||
GLImageDXGISharedHandle* dxgi_image = new GLImageDXGISharedHandle(size);
|
||||
if (!dxgi_image->Initialize()) {
|
||||
return nullptr;
|
||||
}
|
||||
image = dxgi_image;
|
||||
share_handle = dxgi_image->share_handle();
|
||||
texture = dxgi_image->texture().Get();
|
||||
|
||||
if (!image) { // this check seems unnecessary
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLint numConfigs = 0;
|
||||
EGLint configAttrs[] = {
|
||||
EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES3_BIT, // must remain in this position for ES2 fallback
|
||||
EGL_SURFACE_TYPE,
|
||||
EGL_PBUFFER_BIT,
|
||||
EGL_BUFFER_SIZE,
|
||||
32,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_DEPTH_SIZE,
|
||||
0,
|
||||
EGL_STENCIL_SIZE,
|
||||
0,
|
||||
EGL_SAMPLE_BUFFERS,
|
||||
0,
|
||||
EGL_NONE};
|
||||
|
||||
EGLConfig config = nullptr;
|
||||
if (eglChooseConfig(egl_display, configAttrs, &config, 1, &numConfigs) !=
|
||||
EGL_TRUE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
EGLint surfAttrs[] = {EGL_WIDTH,
|
||||
width,
|
||||
EGL_HEIGHT,
|
||||
height,
|
||||
EGL_TEXTURE_TARGET,
|
||||
EGL_TEXTURE_2D,
|
||||
EGL_TEXTURE_FORMAT,
|
||||
EGL_TEXTURE_RGBA,
|
||||
EGL_NONE};
|
||||
|
||||
surface = eglCreatePbufferFromClientBuffer(egl_display, EGL_D3D_TEXTURE_ANGLE,
|
||||
texture, config, surfAttrs);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
// fallback to ES2 - it could be that we're running on older hardware
|
||||
// and ES3 isn't available
|
||||
|
||||
// EGL_RENDERABLE_TYPE is the bit at configAttrs[0]
|
||||
configAttrs[1] = EGL_OPENGL_ES2_BIT;
|
||||
config = nullptr;
|
||||
if (eglChooseConfig(egl_display, configAttrs, &config, 1, &numConfigs) ==
|
||||
EGL_TRUE) {
|
||||
surface = eglCreatePbufferFromClientBuffer(
|
||||
egl_display, EGL_D3D_TEXTURE_ANGLE, texture, config, surfAttrs);
|
||||
}
|
||||
|
||||
// still no surface? we're done
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
dxgi_image->SetSurface(surface, texture_id);
|
||||
|
||||
surfaceMap_[share_handle] = image;
|
||||
|
||||
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
|
||||
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
|
||||
|
||||
eglMakeCurrent(egl_display, surface, surface, curContext);
|
||||
|
||||
if (eglBindTexImage(egl_display, surface, EGL_BACK_BUFFER)) {
|
||||
if (tex_man) {
|
||||
TextureRef* texture_ref = tex_man->GetTexture(texture_id);
|
||||
tex_man->SetLevelInfo(texture_ref, GL_TEXTURE_2D, 0, GL_BGRA_EXT, width,
|
||||
height, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
|
||||
gfx::Rect(size));
|
||||
tex_man->SetLevelImage(texture_ref, GL_TEXTURE_2D, 0, image.get(),
|
||||
Texture::BOUND);
|
||||
}
|
||||
}
|
||||
|
||||
eglMakeCurrent(egl_display, drawSurface, readSurface, curContext);
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
return share_handle;
|
||||
}
|
||||
|
||||
void ExternalTextureManager::LockTexture(void* handle) {
|
||||
#if defined(OS_WIN)
|
||||
auto const img = surfaceMap_.find(handle);
|
||||
if (img != surfaceMap_.end()) {
|
||||
GLImageDXGISharedHandle* dxgi_image =
|
||||
reinterpret_cast<GLImageDXGISharedHandle*>(img->second.get());
|
||||
dxgi_image->Lock();
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
}
|
||||
|
||||
void ExternalTextureManager::UnlockTexture(void* handle) {
|
||||
#if defined(OS_WIN)
|
||||
auto const img = surfaceMap_.find(handle);
|
||||
if (img != surfaceMap_.end()) {
|
||||
GLImageDXGISharedHandle* dxgi_image =
|
||||
reinterpret_cast<GLImageDXGISharedHandle*>(img->second.get());
|
||||
dxgi_image->Unlock();
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
}
|
||||
|
||||
void ExternalTextureManager::DeleteTexture(void* handle,
|
||||
TextureManager* tex_man) {
|
||||
#if defined(OS_WIN)
|
||||
EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
|
||||
if (egl_display == EGL_NO_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
auto const img = surfaceMap_.find(handle);
|
||||
if (img == surfaceMap_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
GLuint texture_id = 0;
|
||||
|
||||
GLImageDXGISharedHandle* dxgi_image =
|
||||
reinterpret_cast<GLImageDXGISharedHandle*>(img->second.get());
|
||||
surface = dxgi_image->surface();
|
||||
texture_id = dxgi_image->texture_id();
|
||||
|
||||
if (surface != EGL_NO_SURFACE) {
|
||||
EGLContext curContext = eglGetCurrentContext();
|
||||
if (curContext != EGL_NO_CONTEXT) {
|
||||
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
|
||||
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
|
||||
|
||||
eglMakeCurrent(egl_display, surface, surface, curContext);
|
||||
|
||||
TextureRef* texture_ref = nullptr;
|
||||
if (tex_man) {
|
||||
texture_ref = tex_man->GetTexture(texture_id);
|
||||
}
|
||||
|
||||
eglReleaseTexImage(egl_display, surface, EGL_BACK_BUFFER);
|
||||
|
||||
if (tex_man && texture_ref) {
|
||||
tex_man->SetLevelInfo(texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
|
||||
tex_man->SetLevelImage(texture_ref, GL_TEXTURE_2D, 0, nullptr,
|
||||
Texture::UNBOUND);
|
||||
}
|
||||
|
||||
eglMakeCurrent(egl_display, drawSurface, readSurface, curContext);
|
||||
|
||||
eglDestroySurface(egl_display, surface);
|
||||
}
|
||||
}
|
||||
surfaceMap_.erase(img);
|
||||
#endif // defined(OS_WIN)
|
||||
}
|
||||
|
||||
} // namespace gles2
|
||||
} // namespace gpu
|
46
libcef/browser/gpu/external_texture_manager.h
Normal file
46
libcef/browser/gpu/external_texture_manager.h
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2018 The Chromium Embedded Framework Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_GPU_EXTERNAL_TEXTURE_MANAGER_H_
|
||||
#define CEF_LIBCEF_BROWSER_GPU_EXTERNAL_TEXTURE_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "gpu/command_buffer/service/texture_manager.h"
|
||||
#include "gpu/gpu_export.h"
|
||||
#include "ui/gl/gl_image.h"
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
|
||||
namespace gl {
|
||||
class GLImage;
|
||||
}
|
||||
|
||||
namespace gpu {
|
||||
namespace gles2 {
|
||||
|
||||
class GPU_GLES2_EXPORT ExternalTextureManager {
|
||||
public:
|
||||
ExternalTextureManager();
|
||||
~ExternalTextureManager();
|
||||
|
||||
void* CreateTexture(GLuint texture_id,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
TextureManager* tex_man);
|
||||
|
||||
void LockTexture(void* handle);
|
||||
void UnlockTexture(void* handle);
|
||||
|
||||
void DeleteTexture(void* handle, TextureManager* tex_man);
|
||||
|
||||
private:
|
||||
typedef std::map<void*, scoped_refptr<gl::GLImage>> ExternalSurfaceMap;
|
||||
ExternalSurfaceMap surfaceMap_;
|
||||
};
|
||||
|
||||
} // namespace gles2
|
||||
} // namespace gpu
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_GPU_EXTERNAL_TEXTURE_MANAGER_H_
|
@ -11,15 +11,27 @@
|
||||
|
||||
CefBrowserPlatformDelegateNative::CefBrowserPlatformDelegateNative(
|
||||
const CefWindowInfo& window_info,
|
||||
SkColor background_color)
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame)
|
||||
: window_info_(window_info),
|
||||
background_color_(background_color),
|
||||
use_shared_texture_(use_shared_texture),
|
||||
use_external_begin_frame_(use_external_begin_frame),
|
||||
windowless_handler_(nullptr) {}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateNative::GetBackgroundColor() const {
|
||||
return background_color_;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateNative::CanUseSharedTexture() const {
|
||||
return use_shared_texture_;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateNative::CanUseExternalBeginFrame() const {
|
||||
return use_external_begin_frame_;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateNative::SynchronizeVisualProperties() {
|
||||
content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost();
|
||||
if (host)
|
||||
|
@ -25,6 +25,8 @@ class CefBrowserPlatformDelegateNative : public CefBrowserPlatformDelegate {
|
||||
};
|
||||
|
||||
// CefBrowserPlatformDelegate methods:
|
||||
bool CanUseSharedTexture() const override;
|
||||
bool CanUseExternalBeginFrame() const override;
|
||||
SkColor GetBackgroundColor() const override;
|
||||
void SynchronizeVisualProperties() override;
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
@ -41,10 +43,14 @@ class CefBrowserPlatformDelegateNative : public CefBrowserPlatformDelegate {
|
||||
|
||||
protected:
|
||||
CefBrowserPlatformDelegateNative(const CefWindowInfo& window_info,
|
||||
SkColor background_color);
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame);
|
||||
|
||||
CefWindowInfo window_info_;
|
||||
const SkColor background_color_;
|
||||
const bool use_shared_texture_;
|
||||
const bool use_external_begin_frame_;
|
||||
|
||||
WindowlessHandler* windowless_handler_; // Not owned by this object.
|
||||
};
|
||||
|
@ -41,7 +41,10 @@ long GetSystemUptime() {
|
||||
CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux(
|
||||
const CefWindowInfo& window_info,
|
||||
SkColor background_color)
|
||||
: CefBrowserPlatformDelegateNative(window_info, background_color),
|
||||
: CefBrowserPlatformDelegateNative(window_info,
|
||||
background_color,
|
||||
false,
|
||||
false),
|
||||
host_window_created_(false),
|
||||
window_widget_(nullptr),
|
||||
window_x11_(nullptr) {}
|
||||
|
@ -144,7 +144,10 @@ NSUInteger NativeModifiers(int cef_modifiers) {
|
||||
CefBrowserPlatformDelegateNativeMac::CefBrowserPlatformDelegateNativeMac(
|
||||
const CefWindowInfo& window_info,
|
||||
SkColor background_color)
|
||||
: CefBrowserPlatformDelegateNative(window_info, background_color),
|
||||
: CefBrowserPlatformDelegateNative(window_info,
|
||||
background_color,
|
||||
false,
|
||||
false),
|
||||
host_window_created_(false) {}
|
||||
|
||||
void CefBrowserPlatformDelegateNativeMac::BrowserDestroyed(
|
||||
|
@ -125,8 +125,13 @@ float GetWindowScaleFactor(HWND hwnd) {
|
||||
|
||||
CefBrowserPlatformDelegateNativeWin::CefBrowserPlatformDelegateNativeWin(
|
||||
const CefWindowInfo& window_info,
|
||||
SkColor background_color)
|
||||
: CefBrowserPlatformDelegateNative(window_info, background_color),
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame)
|
||||
: CefBrowserPlatformDelegateNative(window_info,
|
||||
background_color,
|
||||
use_shared_texture,
|
||||
use_external_begin_frame),
|
||||
host_window_created_(false),
|
||||
window_widget_(nullptr) {}
|
||||
|
||||
|
@ -14,7 +14,9 @@ class CefBrowserPlatformDelegateNativeWin
|
||||
: public CefBrowserPlatformDelegateNative {
|
||||
public:
|
||||
CefBrowserPlatformDelegateNativeWin(const CefWindowInfo& window_info,
|
||||
SkColor background_color);
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame);
|
||||
|
||||
// CefBrowserPlatformDelegate methods:
|
||||
void BrowserDestroyed(CefBrowserHostImpl* browser) override;
|
||||
|
@ -30,7 +30,8 @@ void CefBrowserPlatformDelegateOsr::CreateViewForWebContents(
|
||||
DCHECK(!view_osr_);
|
||||
|
||||
// Use the OSR view instead of the default platform view.
|
||||
view_osr_ = new CefWebContentsViewOSR(GetBackgroundColor());
|
||||
view_osr_ = new CefWebContentsViewOSR(
|
||||
GetBackgroundColor(), CanUseSharedTexture(), CanUseExternalBeginFrame());
|
||||
*view = view_osr_;
|
||||
*delegate_view = view_osr_;
|
||||
}
|
||||
@ -69,6 +70,14 @@ void CefBrowserPlatformDelegateOsr::BrowserDestroyed(
|
||||
view_osr_ = nullptr;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateOsr::CanUseSharedTexture() const {
|
||||
return native_delegate_->CanUseSharedTexture();
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateOsr::CanUseExternalBeginFrame() const {
|
||||
return native_delegate_->CanUseExternalBeginFrame();
|
||||
}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateOsr::GetBackgroundColor() const {
|
||||
return native_delegate_->GetBackgroundColor();
|
||||
}
|
||||
@ -215,6 +224,12 @@ void CefBrowserPlatformDelegateOsr::Invalidate(cef_paint_element_type_t type) {
|
||||
view->Invalidate(type);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::SendExternalBeginFrame() {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
view->SendExternalBeginFrame();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::SetWindowlessFrameRate(int frame_rate) {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
|
@ -28,7 +28,10 @@ class CefBrowserPlatformDelegateOsr
|
||||
void BrowserCreated(CefBrowserHostImpl* browser) override;
|
||||
void BrowserDestroyed(CefBrowserHostImpl* browser) override;
|
||||
SkColor GetBackgroundColor() const override;
|
||||
bool CanUseSharedTexture() const override;
|
||||
bool CanUseExternalBeginFrame() const override;
|
||||
void SynchronizeVisualProperties() override;
|
||||
void SendExternalBeginFrame() override;
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
|
@ -45,6 +45,10 @@
|
||||
|
||||
namespace {
|
||||
|
||||
// The maximum number of damage rects to cache for outstanding frame requests
|
||||
// (for OnAcceleratedPaint).
|
||||
const size_t kMaxDamageRects = 10;
|
||||
|
||||
const float kDefaultScaleFactor = 1.0;
|
||||
|
||||
// The maximum number of retry counts if frame capture fails.
|
||||
@ -65,6 +69,45 @@ static content::ScreenInfo ScreenInfoFrom(const CefScreenInfo& src) {
|
||||
return screenInfo;
|
||||
}
|
||||
|
||||
class CefCompositorFrameSinkClient
|
||||
: public viz::mojom::CompositorFrameSinkClient {
|
||||
public:
|
||||
CefCompositorFrameSinkClient(viz::mojom::CompositorFrameSinkClient* forward,
|
||||
CefRenderWidgetHostViewOSR* rwhv)
|
||||
: forward_(forward), render_widget_host_view_(rwhv) {}
|
||||
|
||||
void DidReceiveCompositorFrameAck(
|
||||
const std::vector<viz::ReturnedResource>& resources) override {
|
||||
forward_->DidReceiveCompositorFrameAck(resources);
|
||||
}
|
||||
|
||||
void DidPresentCompositorFrame(
|
||||
uint32_t presentation_token,
|
||||
const gfx::PresentationFeedback& feedback) override {
|
||||
forward_->DidPresentCompositorFrame(presentation_token, feedback);
|
||||
if (render_widget_host_view_) {
|
||||
render_widget_host_view_->OnPresentCompositorFrame(presentation_token);
|
||||
}
|
||||
}
|
||||
|
||||
void OnBeginFrame(const viz::BeginFrameArgs& args) override {
|
||||
forward_->OnBeginFrame(args);
|
||||
}
|
||||
|
||||
void OnBeginFramePausedChanged(bool paused) override {
|
||||
forward_->OnBeginFramePausedChanged(paused);
|
||||
}
|
||||
|
||||
void ReclaimResources(
|
||||
const std::vector<viz::ReturnedResource>& resources) override {
|
||||
forward_->ReclaimResources(resources);
|
||||
}
|
||||
|
||||
private:
|
||||
viz::mojom::CompositorFrameSinkClient* const forward_;
|
||||
CefRenderWidgetHostViewOSR* const render_widget_host_view_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Used for managing copy requests when GPU compositing is enabled. Based on
|
||||
@ -204,6 +247,8 @@ class CefBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||
|
||||
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame,
|
||||
content::RenderWidgetHost* widget,
|
||||
CefRenderWidgetHostViewOSR* parent_host_view,
|
||||
bool is_guest_view_hack)
|
||||
@ -257,6 +302,8 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
|
||||
GetRootLayer()->SetColor(background_color_);
|
||||
|
||||
external_begin_frame_enabled_ = use_external_begin_frame;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// On macOS the ui::Compositor is created/owned by the platform view.
|
||||
content::ImageTransportFactory* factory =
|
||||
@ -264,13 +311,22 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
ui::ContextFactoryPrivate* context_factory_private =
|
||||
factory->GetContextFactoryPrivate();
|
||||
// Matching the attributes from RecyclableCompositorMac.
|
||||
compositor_.reset(
|
||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(),
|
||||
features::IsSurfaceSynchronizationEnabled(),
|
||||
false /* enable_pixel_canvas */));
|
||||
compositor_.reset(new ui::Compositor(
|
||||
context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(),
|
||||
features::IsSurfaceSynchronizationEnabled(),
|
||||
false /* enable_pixel_canvas */, use_external_begin_frame));
|
||||
compositor_->SetAcceleratedWidget(compositor_widget_);
|
||||
|
||||
// Tell the compositor to use shared textures if the client can handle
|
||||
// OnAcceleratedPaint.
|
||||
compositor_->EnableSharedTexture(use_shared_texture);
|
||||
|
||||
if (use_external_begin_frame) {
|
||||
compositor_->SetExternalBeginFrameClient(this);
|
||||
}
|
||||
|
||||
compositor_->SetDelegate(this);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
@ -289,6 +345,13 @@ CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
|
||||
if (is_showing_)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
#else
|
||||
if (external_begin_frame_enabled_) {
|
||||
ui::Compositor* compositor = GetCompositor();
|
||||
if (compositor) {
|
||||
compositor->SetExternalBeginFrameClient(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
||||
// necessary to remove all connections to its old ui::Compositor.
|
||||
if (is_showing_)
|
||||
@ -468,19 +531,85 @@ void CefRenderWidgetHostViewOSR::TakeFallbackContentFrom(
|
||||
|
||||
void CefRenderWidgetHostViewOSR::DidCreateNewRendererCompositorFrameSink(
|
||||
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||
renderer_compositor_frame_sink_.reset(
|
||||
new CefCompositorFrameSinkClient(renderer_compositor_frame_sink, this));
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
renderer_compositor_frame_sink_.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnPresentCompositorFrame(
|
||||
uint32_t presentation_token) {
|
||||
// Is Chromium rendering to a shared texture?
|
||||
void* shared_texture = nullptr;
|
||||
ui::Compositor* compositor = GetCompositor();
|
||||
if (compositor) {
|
||||
shared_texture = compositor->GetSharedTexture();
|
||||
}
|
||||
|
||||
if (shared_texture) {
|
||||
CefRefPtr<CefRenderHandler> handler =
|
||||
browser_impl_->GetClient()->GetRenderHandler();
|
||||
CHECK(handler);
|
||||
|
||||
CefRenderHandler::RectList rcList;
|
||||
|
||||
{
|
||||
// Find the corresponding damage rect. If there isn't one pass the entire
|
||||
// view size for a full redraw.
|
||||
base::AutoLock lock_scope(damage_rect_lock_);
|
||||
|
||||
gfx::Rect damage;
|
||||
auto const i = damage_rects_.find(presentation_token);
|
||||
if (i != damage_rects_.end()) {
|
||||
damage = i->second;
|
||||
} else {
|
||||
damage = GetViewBounds();
|
||||
}
|
||||
rcList.push_back(
|
||||
CefRect(damage.x(), damage.y(), damage.width(), damage.height()));
|
||||
}
|
||||
|
||||
handler->OnAcceleratedPaint(browser_impl_.get(),
|
||||
IsPopupWidget() ? PET_POPUP : PET_VIEW, rcList,
|
||||
shared_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::AddDamageRect(uint32_t presentation_token,
|
||||
const gfx::Rect& rect) {
|
||||
// Associate the given damage rect with the presentation token.
|
||||
// For OnAcceleratedPaint we'll lookup the corresponding damage area based on
|
||||
// the frame token which is passed back to OnPresentCompositorFrame.
|
||||
base::AutoLock lock_scope(damage_rect_lock_);
|
||||
|
||||
// We assume our presentation_token is a counter. Since we're using an ordered
|
||||
// map we can enforce a max size and remove oldest from the front. Worst case,
|
||||
// if a damage rect isn't associated, we can simply pass the entire view size.
|
||||
while (damage_rects_.size() >= kMaxDamageRects) {
|
||||
damage_rects_.erase(damage_rects_.begin());
|
||||
}
|
||||
damage_rects_[presentation_token] = rect;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SubmitCompositorFrame(
|
||||
const viz::LocalSurfaceId& local_surface_id,
|
||||
viz::CompositorFrame frame,
|
||||
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
|
||||
TRACE_EVENT0("libcef", "CefRenderWidgetHostViewOSR::OnSwapCompositorFrame");
|
||||
|
||||
// Update the frame rate. At this point we should have a valid connection back
|
||||
// to the Synthetic Frame Source, which is important so we can actually modify
|
||||
// the frame rate to something other than the default of 60Hz.
|
||||
if (sync_frame_rate_) {
|
||||
if (frame_rate_threshold_us_ != 0) {
|
||||
GetCompositor()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
}
|
||||
sync_frame_rate_ = false;
|
||||
}
|
||||
|
||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
||||
|
||||
@ -510,31 +639,50 @@ void CefRenderWidgetHostViewOSR::SubmitCompositorFrame(
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
||||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
new CefCopyFrameGenerator(frame_rate_threshold_us_, this));
|
||||
}
|
||||
ui::Compositor* compositor = GetCompositor();
|
||||
if (!compositor)
|
||||
return;
|
||||
|
||||
// Determine the damage rectangle for the current frame. This is the same
|
||||
// calculation that SwapDelegatedFrame uses.
|
||||
// Will be nullptr if we're not using shared textures.
|
||||
const void* shared_texture = compositor->GetSharedTexture();
|
||||
|
||||
// Determine the damage rectangle for the current frame. This is the
|
||||
// same calculation that SwapDelegatedFrame uses.
|
||||
viz::RenderPass* root_pass = frame.render_pass_list.back().get();
|
||||
gfx::Size frame_size = root_pass->output_rect.size();
|
||||
gfx::Rect damage_rect =
|
||||
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
if (shared_texture) {
|
||||
// Indicate that we want feedback every frame.
|
||||
if (!++presentation_token_)
|
||||
++presentation_token_;
|
||||
|
||||
AddDamageRect(presentation_token_, damage_rect);
|
||||
|
||||
frame.metadata.frame_token = presentation_token_;
|
||||
frame.metadata.request_presentation_feedback = true;
|
||||
}
|
||||
|
||||
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
|
||||
// macOS, however it contains compositor resize logic that we don't want.
|
||||
// Consequently we instead call the SwapDelegatedFrame method directly.
|
||||
// macOS, however it contains compositor resize logic that we don't
|
||||
// want. Consequently we instead call the SwapDelegatedFrame method
|
||||
// directly.
|
||||
GetDelegatedFrameHost()->SubmitCompositorFrame(
|
||||
local_surface_id, std::move(frame), std::move(hit_test_region_list));
|
||||
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
copy_frame_generator_->GenerateCopyFrame(damage_rect);
|
||||
}
|
||||
if (!shared_texture) {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
new CefCopyFrameGenerator(frame_rate_threshold_us_, this));
|
||||
}
|
||||
|
||||
return;
|
||||
// Request a copy of the last compositor frame which will eventually
|
||||
// call OnPaint asynchronously.
|
||||
copy_frame_generator_->GenerateCopyFrame(damage_rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,7 +875,8 @@ void CefRenderWidgetHostViewOSR::GetScreenInfo(
|
||||
screen_info.available_rect.width == 0 ||
|
||||
screen_info.available_rect.height == 0) {
|
||||
// If a screen rectangle was not provided, try using the view rectangle
|
||||
// instead. Otherwise, popup views may be drawn incorrectly, or not at all.
|
||||
// instead. Otherwise, popup views may be drawn incorrectly, or not at
|
||||
// all.
|
||||
CefRect screenRect;
|
||||
handler->GetViewRect(browser_impl_.get(), screenRect);
|
||||
CHECK_GT(screenRect.width, 0);
|
||||
@ -879,8 +1028,11 @@ const viz::FrameSinkId& CefRenderWidgetHostViewOSR::GetFrameSinkId() const {
|
||||
void CefRenderWidgetHostViewOSR::SetNeedsBeginFrames(bool enabled) {
|
||||
SetFrameRate();
|
||||
|
||||
// Start/stop the timer that sends BeginFrame requests.
|
||||
begin_frame_timer_->SetActive(enabled);
|
||||
if (!external_begin_frame_enabled_) {
|
||||
// Start/stop the timer that sends BeginFrame requests.
|
||||
begin_frame_timer_->SetActive(enabled);
|
||||
}
|
||||
|
||||
if (software_output_device_) {
|
||||
// When the SoftwareOutputDevice is active it will call OnPaint for each
|
||||
// frame. If the SoftwareOutputDevice is deactivated while an invalidation
|
||||
@ -938,6 +1090,16 @@ void CefRenderWidgetHostViewOSR::DidNavigate() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnDisplayDidFinishFrame(
|
||||
const viz::BeginFrameAck& /*ack*/) {
|
||||
// TODO(cef): is there something we need to track with this notification?
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnNeedsExternalBeginFrames(
|
||||
bool needs_begin_frames) {
|
||||
needs_external_begin_frames_ = needs_begin_frames;
|
||||
}
|
||||
|
||||
std::unique_ptr<viz::SoftwareOutputDevice>
|
||||
CefRenderWidgetHostViewOSR::CreateSoftwareOutputDevice(
|
||||
ui::Compositor* compositor) {
|
||||
@ -1035,8 +1197,8 @@ void CefRenderWidgetHostViewOSR::OnScreenInfoChanged() {
|
||||
#endif
|
||||
|
||||
// We might want to change the cursor scale factor here as well - see the
|
||||
// cache for the current_cursor_, as passed by UpdateCursor from the renderer
|
||||
// in the rwhv_aura (current_cursor_.SetScaleFactor)
|
||||
// cache for the current_cursor_, as passed by UpdateCursor from the
|
||||
// renderer in the rwhv_aura (current_cursor_.SetScaleFactor)
|
||||
|
||||
// Notify the guest hosts if any.
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
@ -1056,6 +1218,31 @@ void CefRenderWidgetHostViewOSR::Invalidate(
|
||||
InvalidateInternal(gfx::Rect(GetCompositorViewportPixelSize()));
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendExternalBeginFrame() {
|
||||
DCHECK(external_begin_frame_enabled_);
|
||||
|
||||
base::TimeTicks frame_time = base::TimeTicks::Now();
|
||||
base::TimeTicks deadline = base::TimeTicks();
|
||||
base::TimeDelta interval = viz::BeginFrameArgs::DefaultInterval();
|
||||
|
||||
viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
|
||||
BEGINFRAME_FROM_HERE, begin_frame_source_.source_id(),
|
||||
begin_frame_number_, frame_time, deadline, interval,
|
||||
viz::BeginFrameArgs::NORMAL);
|
||||
|
||||
DCHECK(begin_frame_args.IsValid());
|
||||
begin_frame_number_++;
|
||||
|
||||
if (renderer_compositor_frame_sink_) {
|
||||
GetCompositor()->IssueExternalBeginFrame(begin_frame_args);
|
||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args);
|
||||
}
|
||||
|
||||
if (!IsPopupWidget() && popup_host_view_) {
|
||||
popup_host_view_->SendExternalBeginFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendKeyEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
TRACE_EVENT0("libcef", "CefRenderWidgetHostViewOSR::SendKeyEvent");
|
||||
@ -1155,8 +1342,8 @@ void CefRenderWidgetHostViewOSR::SendMouseWheelEvent(
|
||||
return;
|
||||
} else {
|
||||
// Scrolling outside of the popup widget so destroy it.
|
||||
// Execute asynchronously to avoid deleting the widget from inside some
|
||||
// other callback.
|
||||
// Execute asynchronously to avoid deleting the widget from inside
|
||||
// some other callback.
|
||||
CEF_POST_TASK(
|
||||
CEF_UIT,
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::CancelWidget,
|
||||
@ -1298,13 +1485,26 @@ void CefRenderWidgetHostViewOSR::SetFrameRate() {
|
||||
if (frame_rate_threshold_us_ != 0)
|
||||
return;
|
||||
|
||||
const int frame_rate =
|
||||
osr_util::ClampFrameRate(browser->settings().windowless_frame_rate);
|
||||
ui::Compositor* compositor = GetCompositor();
|
||||
|
||||
int frame_rate;
|
||||
if (compositor && compositor->shared_texture_enabled()) {
|
||||
// No upper-bound when using OnAcceleratedPaint.
|
||||
frame_rate = browser->settings().windowless_frame_rate;
|
||||
if (frame_rate <= 0) {
|
||||
frame_rate = 1;
|
||||
}
|
||||
sync_frame_rate_ = true;
|
||||
} else {
|
||||
frame_rate =
|
||||
osr_util::ClampFrameRate(browser->settings().windowless_frame_rate);
|
||||
}
|
||||
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate;
|
||||
|
||||
if (GetCompositor()) {
|
||||
if (compositor) {
|
||||
// Configure the VSync interval for the browser process.
|
||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
compositor->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
}
|
||||
|
||||
@ -1313,13 +1513,15 @@ void CefRenderWidgetHostViewOSR::SetFrameRate() {
|
||||
frame_rate_threshold_us_);
|
||||
}
|
||||
|
||||
if (begin_frame_timer_.get()) {
|
||||
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
||||
} else {
|
||||
begin_frame_timer_.reset(new CefBeginFrameTimer(
|
||||
frame_rate_threshold_us_,
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::OnBeginFrameTimerTick,
|
||||
weak_ptr_factory_.GetWeakPtr())));
|
||||
if (!external_begin_frame_enabled_) {
|
||||
if (begin_frame_timer_.get()) {
|
||||
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
|
||||
} else {
|
||||
begin_frame_timer_.reset(new CefBeginFrameTimer(
|
||||
frame_rate_threshold_us_,
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::OnBeginFrameTimerTick,
|
||||
weak_ptr_factory_.GetWeakPtr())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1459,8 +1661,8 @@ void CefRenderWidgetHostViewOSR::CancelWidget() {
|
||||
if (render_widget_host_ && !is_destroyed_) {
|
||||
is_destroyed_ = true;
|
||||
|
||||
// Don't delete the RWHI manually while owned by a scoped_ptr in RVHI. This
|
||||
// matches a CHECK() in RenderWidgetHostImpl::Destroy().
|
||||
// Don't delete the RWHI manually while owned by a scoped_ptr in RVHI.
|
||||
// This matches a CHECK() in RenderWidgetHostImpl::Destroy().
|
||||
const bool also_delete = !render_widget_host_->owner_delegate();
|
||||
|
||||
// Results in a call to Destroy().
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define CEF_LIBCEF_BROWSER_OSR_RENDER_WIDGET_HOST_VIEW_OSR_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
@ -21,6 +22,8 @@
|
||||
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/external_begin_frame_client.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "ui/base/x/x11_util.h"
|
||||
@ -90,6 +93,7 @@ class MacHelper;
|
||||
#endif
|
||||
|
||||
class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
public ui::ExternalBeginFrameClient,
|
||||
public ui::CompositorDelegate
|
||||
#if !defined(OS_MACOSX)
|
||||
,
|
||||
@ -98,6 +102,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
{
|
||||
public:
|
||||
CefRenderWidgetHostViewOSR(SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame,
|
||||
content::RenderWidgetHost* widget,
|
||||
CefRenderWidgetHostViewOSR* parent_host_view,
|
||||
bool is_guest_view_hack);
|
||||
@ -198,6 +204,10 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
|
||||
const viz::FrameSinkId& GetFrameSinkId() const override;
|
||||
|
||||
// ui::ExternalBeginFrameClient implementation:
|
||||
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
|
||||
void OnNeedsExternalBeginFrames(bool needs_begin_frames) override;
|
||||
|
||||
// ui::CompositorDelegate implementation.
|
||||
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
|
||||
ui::Compositor* compositor) override;
|
||||
@ -217,6 +227,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
void SynchronizeVisualProperties();
|
||||
void OnScreenInfoChanged();
|
||||
void Invalidate(CefBrowserHost::PaintElementType type);
|
||||
void SendExternalBeginFrame();
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event);
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event);
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event);
|
||||
@ -267,6 +278,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnPresentCompositorFrame(uint32_t presentation_token);
|
||||
|
||||
private:
|
||||
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
||||
|
||||
@ -299,6 +312,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
|
||||
viz::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
|
||||
|
||||
void AddDamageRect(uint32_t presentation_token, const gfx::Rect& rect);
|
||||
|
||||
// Applies background color without notifying the RenderWidget about
|
||||
// opaqueness changes.
|
||||
void UpdateBackgroundColorFromRenderer(SkColor color);
|
||||
@ -358,6 +373,10 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
viz::StubBeginFrameSource begin_frame_source_;
|
||||
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
|
||||
|
||||
bool sync_frame_rate_ = false;
|
||||
bool external_begin_frame_enabled_ = false;
|
||||
bool needs_external_begin_frames_ = false;
|
||||
|
||||
// Used for direct rendering from the compositor when GPU compositing is
|
||||
// disabled. This object is owned by the compositor.
|
||||
CefSoftwareOutputDeviceOSR* software_output_device_;
|
||||
@ -384,6 +403,9 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
bool is_showing_;
|
||||
bool is_destroyed_;
|
||||
gfx::Rect popup_position_;
|
||||
uint32_t presentation_token_ = 0;
|
||||
base::Lock damage_rect_lock_;
|
||||
std::map<uint32_t, gfx::Rect> damage_rects_;
|
||||
|
||||
// The last scroll offset of the view.
|
||||
gfx::Vector2dF last_scroll_offset_;
|
||||
@ -391,8 +413,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
|
||||
|
||||
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
|
||||
|
||||
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink_ =
|
||||
nullptr;
|
||||
std::unique_ptr<viz::mojom::CompositorFrameSinkClient>
|
||||
renderer_compositor_frame_sink_;
|
||||
|
||||
// Latest capture sequence number which is incremented when the caller
|
||||
// requests surfaces be synchronized via
|
||||
|
@ -15,8 +15,13 @@
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
|
||||
CefWebContentsViewOSR::CefWebContentsViewOSR(SkColor background_color)
|
||||
: background_color_(background_color), web_contents_(NULL) {}
|
||||
CefWebContentsViewOSR::CefWebContentsViewOSR(SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame)
|
||||
: background_color_(background_color),
|
||||
use_shared_texture_(use_shared_texture),
|
||||
use_external_begin_frame_(use_external_begin_frame),
|
||||
web_contents_(NULL) {}
|
||||
|
||||
CefWebContentsViewOSR::~CefWebContentsViewOSR() {}
|
||||
|
||||
@ -109,8 +114,9 @@ content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
|
||||
}
|
||||
|
||||
const bool is_guest_view_hack = !!embedder_render_widget_host;
|
||||
return new CefRenderWidgetHostViewOSR(background_color_, render_widget_host,
|
||||
embedder_host_view, is_guest_view_hack);
|
||||
return new CefRenderWidgetHostViewOSR(
|
||||
background_color_, use_shared_texture_, use_external_begin_frame_,
|
||||
render_widget_host, embedder_host_view, is_guest_view_hack);
|
||||
}
|
||||
|
||||
// Called for popup and fullscreen widgets.
|
||||
@ -120,8 +126,9 @@ CefWebContentsViewOSR::CreateViewForPopupWidget(
|
||||
CefRenderWidgetHostViewOSR* view = GetView();
|
||||
CHECK(view);
|
||||
|
||||
return new CefRenderWidgetHostViewOSR(background_color_, render_widget_host,
|
||||
view, false);
|
||||
return new CefRenderWidgetHostViewOSR(background_color_, use_shared_texture_,
|
||||
use_external_begin_frame_,
|
||||
render_widget_host, view, false);
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::SetPageTitle(const base::string16& title) {}
|
||||
|
@ -23,7 +23,9 @@ class CefRenderWidgetHostViewOSR;
|
||||
class CefWebContentsViewOSR : public content::WebContentsView,
|
||||
public content::RenderViewHostDelegateView {
|
||||
public:
|
||||
explicit CefWebContentsViewOSR(SkColor background_color);
|
||||
explicit CefWebContentsViewOSR(SkColor background_color,
|
||||
bool use_shared_texture,
|
||||
bool use_external_begin_frame);
|
||||
~CefWebContentsViewOSR() override;
|
||||
|
||||
void WebContentsCreated(content::WebContents* web_contents);
|
||||
@ -82,6 +84,8 @@ class CefWebContentsViewOSR : public content::WebContentsView,
|
||||
CefBrowserHostImpl* GetBrowser() const;
|
||||
|
||||
const SkColor background_color_;
|
||||
const bool use_shared_texture_;
|
||||
const bool use_external_begin_frame_;
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
|
||||
|
@ -165,6 +165,14 @@ void CefBrowserPlatformDelegateViews::PopupBrowserCreated(
|
||||
}
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateViews::CanUseSharedTexture() const {
|
||||
return native_delegate_->CanUseSharedTexture();
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateViews::CanUseExternalBeginFrame() const {
|
||||
return native_delegate_->CanUseExternalBeginFrame();
|
||||
}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateViews::GetBackgroundColor() const {
|
||||
return native_delegate_->GetBackgroundColor();
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ class CefBrowserPlatformDelegateViews
|
||||
bool is_devtools) override;
|
||||
void PopupBrowserCreated(CefBrowserHostImpl* new_browser,
|
||||
bool is_devtools) override;
|
||||
bool CanUseSharedTexture() const override;
|
||||
bool CanUseExternalBeginFrame() const override;
|
||||
SkColor GetBackgroundColor() const override;
|
||||
void SynchronizeVisualProperties() override;
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=099ec6c9deac65288a47cec317ab6b355e707179$
|
||||
// $hash=2357c186875d3086fa4931a3ac8346d866cab1e3$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||
@ -615,6 +615,18 @@ void CEF_CALLBACK browser_host_invalidate(struct _cef_browser_host_t* self,
|
||||
CefBrowserHostCppToC::Get(self)->Invalidate(type);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
browser_host_send_external_begin_frame(struct _cef_browser_host_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
// Execute
|
||||
CefBrowserHostCppToC::Get(self)->SendExternalBeginFrame();
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
browser_host_send_key_event(struct _cef_browser_host_t* self,
|
||||
const struct _cef_key_event_t* event) {
|
||||
@ -1111,6 +1123,8 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
|
||||
GetStruct()->notify_screen_info_changed =
|
||||
browser_host_notify_screen_info_changed;
|
||||
GetStruct()->invalidate = browser_host_invalidate;
|
||||
GetStruct()->send_external_begin_frame =
|
||||
browser_host_send_external_begin_frame;
|
||||
GetStruct()->send_key_event = browser_host_send_key_event;
|
||||
GetStruct()->send_mouse_click_event = browser_host_send_mouse_click_event;
|
||||
GetStruct()->send_mouse_move_event = browser_host_send_mouse_move_event;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=6cf6466ab2a1b87a1b57b5994aab64992b9f12dd$
|
||||
// $hash=8df4ed4bd6e80bd90fb9563a021a59848fc40ecc$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/render_handler_cpptoc.h"
|
||||
@ -266,6 +266,45 @@ void CEF_CALLBACK render_handler_on_paint(struct _cef_render_handler_t* self,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
render_handler_on_accelerated_paint(struct _cef_render_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_paint_element_type_t type,
|
||||
size_t dirtyRectsCount,
|
||||
cef_rect_t const* dirtyRects,
|
||||
void* shared_handle) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser)
|
||||
return;
|
||||
// Verify param: dirtyRects; type: simple_vec_byref_const
|
||||
DCHECK(dirtyRectsCount == 0 || dirtyRects);
|
||||
if (dirtyRectsCount > 0 && !dirtyRects)
|
||||
return;
|
||||
// Verify param: shared_handle; type: simple_byaddr
|
||||
DCHECK(shared_handle);
|
||||
if (!shared_handle)
|
||||
return;
|
||||
|
||||
// Translate param: dirtyRects; type: simple_vec_byref_const
|
||||
std::vector<CefRect> dirtyRectsList;
|
||||
if (dirtyRectsCount > 0) {
|
||||
for (size_t i = 0; i < dirtyRectsCount; ++i) {
|
||||
CefRect dirtyRectsVal = dirtyRects[i];
|
||||
dirtyRectsList.push_back(dirtyRectsVal);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefRenderHandlerCppToC::Get(self)->OnAcceleratedPaint(
|
||||
CefBrowserCToCpp::Wrap(browser), type, dirtyRectsList, shared_handle);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK render_handler_on_cursor_change(
|
||||
struct _cef_render_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
@ -444,6 +483,7 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC() {
|
||||
GetStruct()->on_popup_show = render_handler_on_popup_show;
|
||||
GetStruct()->on_popup_size = render_handler_on_popup_size;
|
||||
GetStruct()->on_paint = render_handler_on_paint;
|
||||
GetStruct()->on_accelerated_paint = render_handler_on_accelerated_paint;
|
||||
GetStruct()->on_cursor_change = render_handler_on_cursor_change;
|
||||
GetStruct()->start_dragging = render_handler_start_dragging;
|
||||
GetStruct()->update_drag_cursor = render_handler_update_drag_cursor;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=9a1691bbc0a509032dd60b463189dd1eb0f6cc4d$
|
||||
// $hash=5d699bfd2e9f2d689a5bca3372563b1578fa1ba1$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||
@ -557,6 +557,17 @@ void CefBrowserHostCToCpp::Invalidate(PaintElementType type) {
|
||||
_struct->invalidate(_struct, type);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") void CefBrowserHostCToCpp::SendExternalBeginFrame() {
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, send_external_begin_frame))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
_struct->send_external_begin_frame(_struct);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefBrowserHostCToCpp::SendKeyEvent(const CefKeyEvent& event) {
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=39ab8db08e667fac8e6dccffaa99935d8aa7d4b5$
|
||||
// $hash=0a61852aa1a8c8c808e9d2258e09a0fa341056e0$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||
@ -86,6 +86,7 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
|
||||
void WasHidden(bool hidden) OVERRIDE;
|
||||
void NotifyScreenInfoChanged() OVERRIDE;
|
||||
void Invalidate(PaintElementType type) OVERRIDE;
|
||||
void SendExternalBeginFrame() OVERRIDE;
|
||||
void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
||||
void SendMouseClickEvent(const CefMouseEvent& event,
|
||||
MouseButtonType type,
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=db89496c825cdc7fe1eaa4b7822d8492ae3a3f23$
|
||||
// $hash=3c149c932cf4ebd4b2b8c81102851ebd1d6c1d63$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/render_handler_ctocpp.h"
|
||||
@ -204,6 +204,48 @@ void CefRenderHandlerCToCpp::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
delete[] dirtyRectsList;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRenderHandlerCToCpp::OnAcceleratedPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
void* shared_handle) {
|
||||
cef_render_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_accelerated_paint))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get())
|
||||
return;
|
||||
// Verify param: shared_handle; type: simple_byaddr
|
||||
DCHECK(shared_handle);
|
||||
if (!shared_handle)
|
||||
return;
|
||||
|
||||
// Translate param: dirtyRects; type: simple_vec_byref_const
|
||||
const size_t dirtyRectsCount = dirtyRects.size();
|
||||
cef_rect_t* dirtyRectsList = NULL;
|
||||
if (dirtyRectsCount > 0) {
|
||||
dirtyRectsList = new cef_rect_t[dirtyRectsCount];
|
||||
DCHECK(dirtyRectsList);
|
||||
if (dirtyRectsList) {
|
||||
for (size_t i = 0; i < dirtyRectsCount; ++i) {
|
||||
dirtyRectsList[i] = dirtyRects[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->on_accelerated_paint(_struct, CefBrowserCppToC::Wrap(browser), type,
|
||||
dirtyRectsCount, dirtyRectsList, shared_handle);
|
||||
|
||||
// Restore param:dirtyRects; type: simple_vec_byref_const
|
||||
if (dirtyRectsList)
|
||||
delete[] dirtyRectsList;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefRenderHandlerCToCpp::OnCursorChange(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=46dd8560076264a776129a02ba11e2c2f56bf209$
|
||||
// $hash=2f19b04733f565830f873853695e9163086a8ee0$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
|
||||
@ -52,6 +52,10 @@ class CefRenderHandlerCToCpp
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) override;
|
||||
void OnAcceleratedPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
void* shared_handle) override;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
|
@ -103,11 +103,6 @@ patches = [
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1565
|
||||
'name': 'web_contents_1257_1565',
|
||||
},
|
||||
{
|
||||
# Allow creation of a custom SoftwareOutputDevice.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1368
|
||||
'name': 'compositor_1368',
|
||||
},
|
||||
{
|
||||
# Support custom RenderWidgetHostViewOSR for BrowserPluginGuest.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1565
|
||||
@ -365,6 +360,11 @@ patches = [
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=757974#c23
|
||||
'name': 'mac_gpu',
|
||||
},
|
||||
{
|
||||
# Support rendering to a hardware GL/D3D texture/surface provided by the client
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1006
|
||||
'name': 'external_textures_1006',
|
||||
},
|
||||
{
|
||||
# Fix crash in CookieMonsterChangeDispatcher::Subscription destructor.
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=729800#c48
|
||||
|
@ -1,76 +0,0 @@
|
||||
diff --git content/browser/compositor/gpu_process_transport_factory.cc content/browser/compositor/gpu_process_transport_factory.cc
|
||||
index 642fff3b4367..45faeed249c0 100644
|
||||
--- content/browser/compositor/gpu_process_transport_factory.cc
|
||||
+++ content/browser/compositor/gpu_process_transport_factory.cc
|
||||
@@ -493,10 +493,20 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
|
||||
// surfaces as they are not following the correct mode.
|
||||
DisableGpuCompositing(compositor.get());
|
||||
}
|
||||
+
|
||||
+ std::unique_ptr<viz::SoftwareOutputDevice> output_device;
|
||||
+ if (compositor->delegate()) {
|
||||
+ output_device = compositor->delegate()->CreateSoftwareOutputDevice(
|
||||
+ compositor.get());
|
||||
+ }
|
||||
+ if (!output_device) {
|
||||
+ output_device = CreateSoftwareOutputDevice(compositor->widget(),
|
||||
+ compositor->task_runner());
|
||||
+ }
|
||||
+
|
||||
display_output_surface =
|
||||
std::make_unique<SoftwareBrowserCompositorOutputSurface>(
|
||||
- CreateSoftwareOutputDevice(compositor->widget(),
|
||||
- compositor->task_runner()),
|
||||
+ std::move(output_device),
|
||||
std::move(vsync_callback));
|
||||
} else {
|
||||
DCHECK(context_provider);
|
||||
diff --git ui/compositor/compositor.h ui/compositor/compositor.h
|
||||
index a974ea654834..cfb3ff7f8a0c 100644
|
||||
--- ui/compositor/compositor.h
|
||||
+++ ui/compositor/compositor.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "components/viz/common/surfaces/frame_sink_id.h"
|
||||
#include "components/viz/common/surfaces/local_surface_id.h"
|
||||
#include "components/viz/host/host_frame_sink_client.h"
|
||||
+#include "components/viz/service/display/software_output_device.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "third_party/skia/include/core/SkMatrix44.h"
|
||||
#include "ui/compositor/compositor_animation_observer.h"
|
||||
@@ -200,6 +201,17 @@ class COMPOSITOR_EXPORT ContextFactory {
|
||||
virtual bool SyncTokensRequiredForDisplayCompositor() = 0;
|
||||
};
|
||||
|
||||
+class COMPOSITOR_EXPORT CompositorDelegate {
|
||||
+ public:
|
||||
+ virtual std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
|
||||
+ ui::Compositor* compositor) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ protected:
|
||||
+ virtual ~CompositorDelegate() {}
|
||||
+};
|
||||
+
|
||||
// Compositor object to take care of GPU painting.
|
||||
// A Browser compositor object is responsible for generating the final
|
||||
// displayable form of pixels comprising a single widget's contents. It draws an
|
||||
@@ -240,6 +252,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
||||
// Schedules a redraw of the layer tree associated with this compositor.
|
||||
void ScheduleDraw();
|
||||
|
||||
+ CompositorDelegate* delegate() const { return delegate_; }
|
||||
+ void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
|
||||
+
|
||||
// Sets the root of the layer tree drawn by this Compositor. The root layer
|
||||
// must have no parent. The compositor's root layer is reset if the root layer
|
||||
// is destroyed. NULL can be passed to reset the root layer, in which case the
|
||||
@@ -463,6 +478,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
|
||||
ui::ContextFactory* context_factory_;
|
||||
ui::ContextFactoryPrivate* context_factory_private_;
|
||||
|
||||
+ CompositorDelegate* delegate_ = nullptr;
|
||||
+
|
||||
// The root of the Layer tree drawn by this compositor.
|
||||
Layer* root_layer_ = nullptr;
|
||||
|
1324
patch/patches/external_textures_1006.patch
Normal file
1324
patch/patches/external_textures_1006.patch
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user