cef/tests/cefclient/browser/main_context_impl.cc
reito 260dd0ca24 osr: Implement shared texture support (fixes #1006, fixes #2575)
Adds support for the OnAcceleratedPaint callback. Verified to work
on macOS and Windows. Linux support is present but not implemented
for cefclient, so it is not verified to work.

To test:
Run `cefclient --off-screen-rendering-enabled --shared-texture-enabled`
2024-04-23 13:03:56 -04:00

308 lines
9.5 KiB
C++

// Copyright (c) 2015 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 "tests/cefclient/browser/main_context_impl.h"
#include <algorithm>
#include <memory>
#include "include/cef_parser.h"
#include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/common/client_switches.h"
#include "tests/shared/common/string_util.h"
namespace client {
namespace {
// The default URL to load in a browser window.
const char kDefaultUrl[] = "https://www.google.com";
// Returns the ARGB value for |color|.
cef_color_t ParseColor(const std::string& color) {
const std::string& colorToLower = AsciiStrToLower(color);
if (colorToLower == "black") {
return CefColorSetARGB(255, 0, 0, 0);
} else if (colorToLower == "blue") {
return CefColorSetARGB(255, 0, 0, 255);
} else if (colorToLower == "green") {
return CefColorSetARGB(255, 0, 255, 0);
} else if (colorToLower == "red") {
return CefColorSetARGB(255, 255, 0, 0);
} else if (colorToLower == "white") {
return CefColorSetARGB(255, 255, 255, 255);
}
// Use the default color.
return 0;
}
} // namespace
MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
bool terminate_when_all_windows_closed)
: command_line_(command_line),
terminate_when_all_windows_closed_(terminate_when_all_windows_closed) {
DCHECK(command_line_.get());
// Whether windowless (off-screen) rendering will be used.
use_windowless_rendering_ =
command_line_->HasSwitch(switches::kOffScreenRenderingEnabled);
if (use_windowless_rendering_ &&
command_line_->HasSwitch(switches::kOffScreenFrameRate)) {
windowless_frame_rate_ =
atoi(command_line_->GetSwitchValue(switches::kOffScreenFrameRate)
.ToString()
.c_str());
}
// Whether transparent painting is used with windowless rendering.
const bool use_transparent_painting =
use_windowless_rendering_ &&
command_line_->HasSwitch(switches::kTransparentPaintingEnabled);
shared_texture_enabled_ =
use_windowless_rendering_ &&
command_line_->HasSwitch(switches::kSharedTextureEnabled);
external_begin_frame_enabled_ =
use_windowless_rendering_ &&
command_line_->HasSwitch(switches::kExternalBeginFrameEnabled);
if (windowless_frame_rate_ <= 0) {
windowless_frame_rate_ = shared_texture_enabled_ ? 60 : 30;
}
// Enable Chrome runtime bootstrap. See issue #2969 for details.
use_chrome_bootstrap_ =
command_line_->HasSwitch(switches::kEnableChromeRuntime);
// Whether the Views framework will be used.
use_views_ = command_line_->HasSwitch(switches::kUseViews);
if (use_windowless_rendering_ && use_views_) {
LOG(ERROR)
<< "Windowless rendering is not supported by the Views framework.";
use_views_ = false;
}
// Whether Alloy style will be used.
use_alloy_style_ = !use_chrome_bootstrap_ ||
command_line_->HasSwitch(switches::kUseAlloyStyle);
if (use_windowless_rendering_ && !use_alloy_style_) {
LOG(WARNING) << "Windowless rendering requires Alloy style.";
use_alloy_style_ = true;
}
// Whether to use a native parent window with Chrome runtime.
const bool use_chrome_native_parent =
use_chrome_bootstrap_ && command_line->HasSwitch(switches::kUseNative);
#if defined(OS_MAC)
if (use_chrome_native_parent && !use_alloy_style_) {
// MacOS does not support Chrome style with native parent. See issue #3294.
LOG(WARNING) << "Native parent on MacOS requires Alloy style";
use_alloy_style_ = true;
}
#endif
if (use_chrome_bootstrap_ && !use_views_ && !use_chrome_native_parent &&
!use_windowless_rendering_) {
LOG(WARNING) << "Chrome runtime defaults to the Views framework.";
use_views_ = true;
}
if (command_line_->HasSwitch(switches::kBackgroundColor)) {
// Parse the background color value.
background_color_ =
ParseColor(command_line_->GetSwitchValue(switches::kBackgroundColor));
}
if (background_color_ == 0 && !use_views_) {
// Set an explicit background color.
background_color_ = CefColorSetARGB(255, 255, 255, 255);
}
// |browser_background_color_| should remain 0 to enable transparent painting.
if (!use_transparent_painting) {
browser_background_color_ = background_color_;
}
// Log the current configuration.
LOG(WARNING) << "Using " << (use_chrome_bootstrap_ ? "Chrome" : "Alloy")
<< " bootstrap; " << (use_alloy_style_ ? "Alloy" : "Chrome")
<< " style; " << (use_views_ ? "Views" : "Native")
<< "-hosted window; "
<< (use_windowless_rendering_ ? "Windowless" : "Windowed")
<< " rendering (not a warning)";
}
MainContextImpl::~MainContextImpl() {
// The context must either not have been initialized, or it must have also
// been shut down.
DCHECK(!initialized_ || shutdown_);
}
CefRefPtr<CefCommandLine> MainContextImpl::GetCommandLine() {
return command_line_;
}
std::string MainContextImpl::GetConsoleLogPath() {
return GetAppWorkingDirectory() + "console.log";
}
std::string MainContextImpl::GetMainURL(
CefRefPtr<CefCommandLine> command_line) {
if (!command_line) {
command_line = command_line_;
}
std::string main_url = kDefaultUrl;
if (command_line->HasSwitch(switches::kUrl)) {
main_url = command_line->GetSwitchValue(switches::kUrl);
} else if (use_views_ && command_line->HasSwitch(switches::kHideFrame)) {
// Use the draggable regions test as the default URL for frameless windows.
main_url = test_runner::GetTestURL("draggable");
}
return main_url;
}
cef_color_t MainContextImpl::GetBackgroundColor() {
return background_color_;
}
bool MainContextImpl::UseChromeBootstrap() {
return use_chrome_bootstrap_;
}
bool MainContextImpl::UseViewsGlobal() {
return use_views_;
}
bool MainContextImpl::UseAlloyStyleGlobal() {
return use_alloy_style_;
}
bool MainContextImpl::TouchEventsEnabled() {
return command_line_->GetSwitchValue("touch-events") == "enabled";
}
bool MainContextImpl::UseDefaultPopup() {
return !use_windowless_rendering_ &&
command_line_->HasSwitch(switches::kUseDefaultPopup);
}
void MainContextImpl::PopulateSettings(CefSettings* settings) {
client::ClientAppBrowser::PopulateSettings(command_line_, *settings);
if (use_chrome_bootstrap_) {
settings->chrome_runtime = true;
}
CefString(&settings->cache_path) =
command_line_->GetSwitchValue(switches::kCachePath);
if (use_windowless_rendering_) {
settings->windowless_rendering_enabled = true;
}
if (browser_background_color_ != 0) {
settings->background_color = browser_background_color_;
}
if (command_line_->HasSwitch("lang")) {
// Use the same locale for the Accept-Language HTTP request header.
CefString(&settings->accept_language_list) =
command_line_->GetSwitchValue("lang");
}
if (command_line_->HasSwitch("enable-chrome-policy")) {
// Enable Chrome policy management via Platform and OS-user policies.
// Use the same configuration ID as Google Chrome for testing purposes.
// If Google Chrome is managed on this machine we'll show the same
// configured policies in chrome://policy/.
CefString(&settings->chrome_policy_id) =
#if defined(OS_WIN)
"SOFTWARE\\Policies\\Google\\Chrome";
#elif defined(OS_MAC)
"com.google.Chrome";
#elif defined(OS_LINUX)
"/etc/opt/chrome/policies";
#else
"";
#endif
}
}
void MainContextImpl::PopulateBrowserSettings(CefBrowserSettings* settings) {
settings->windowless_frame_rate = windowless_frame_rate_;
if (browser_background_color_ != 0) {
settings->background_color = browser_background_color_;
}
if (use_chrome_bootstrap_ &&
command_line_->HasSwitch(switches::kHideChromeBubbles)) {
settings->chrome_status_bubble = STATE_DISABLED;
settings->chrome_zoom_bubble = STATE_DISABLED;
}
}
void MainContextImpl::PopulateOsrSettings(OsrRendererSettings* settings) {
settings->show_update_rect =
command_line_->HasSwitch(switches::kShowUpdateRect);
settings->shared_texture_enabled = shared_texture_enabled_;
settings->external_begin_frame_enabled = external_begin_frame_enabled_;
settings->begin_frame_rate = windowless_frame_rate_;
if (browser_background_color_ != 0) {
settings->background_color = browser_background_color_;
}
}
RootWindowManager* MainContextImpl::GetRootWindowManager() {
DCHECK(InValidState());
return root_window_manager_.get();
}
bool MainContextImpl::Initialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application,
void* windows_sandbox_info) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!initialized_);
DCHECK(!shutdown_);
if (!CefInitialize(args, settings, application, windows_sandbox_info)) {
return false;
}
// Need to create the RootWindowManager after calling CefInitialize because
// TempWindowX11 uses cef_get_xdisplay().
root_window_manager_ =
std::make_unique<RootWindowManager>(terminate_when_all_windows_closed_);
initialized_ = true;
return true;
}
void MainContextImpl::Shutdown() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(initialized_);
DCHECK(!shutdown_);
root_window_manager_.reset();
CefShutdown();
shutdown_ = true;
}
} // namespace client